NYU AV Driver start

This commit is contained in:
Heath Volmer
2017-09-05 18:51:15 -06:00
parent f502432fcc
commit 9aad840a78
33 changed files with 3229 additions and 1013 deletions

View File

@@ -0,0 +1,231 @@
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Crestron.SimplSharp;
//using Crestron.SimplSharpPro;
//using Crestron.SimplSharpPro.DeviceSupport;
//using PepperDash.Core;
//using PepperDash.Essentials.Core;
//using PepperDash.Essentials.Core.SmartObjects;
//using PepperDash.Essentials.Core.PageManagers;
//namespace PepperDash.Essentials
//{
// public class DualDisplaySimpleOrAdvancedRouting : PanelDriverBase
// {
// EssentialsPresentationPanelAvFunctionsDriver Parent;
// /// <summary>
// /// Smart Object 3200
// /// </summary>
// SubpageReferenceList SourcesSrl;
// /// <summary>
// /// For tracking feedback on last selected
// /// </summary>
// BoolInputSig LastSelectedSourceSig;
// /// <summary>
// /// The source that has been selected and is awaiting assignment to a display
// /// </summary>
// SourceListItem PendingSource;
// bool IsSharingModeAdvanced;
// public DualDisplaySimpleOrAdvancedRouting(EssentialsPresentationPanelAvFunctionsDriver parent) : base(parent.TriList)
// {
// Parent = parent;
// SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
// TriList.SetSigFalseAction(UIBoolJoin.ToggleSharingModePress, ToggleSharingModePressed);
// TriList.SetSigFalseAction(UIBoolJoin.Display1AudioButtonPressAndFb, Display1AudioPress);
// TriList.SetSigFalseAction(UIBoolJoin.Display1ControlButtonPress, Display1ControlPress);
// TriList.SetSigTrueAction(UIBoolJoin.Display1SelectPressAndFb, Display1Press);
// TriList.SetSigFalseAction(UIBoolJoin.Display2AudioButtonPressAndFb, Display2AudioPress);
// TriList.SetSigFalseAction(UIBoolJoin.Display2ControlButtonPress, Display2ControlPress);
// TriList.SetSigTrueAction(UIBoolJoin.Display2SelectPressAndFb, Display2Press);
// }
// /// <summary>
// ///
// /// </summary>
// public override void Show()
// {
// TriList.BooleanInput[UIBoolJoin.ToggleSharingModeVisible].BoolValue = true;
// TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
// if(IsSharingModeAdvanced)
// TriList.BooleanInput[UIBoolJoin.DualDisplayPageVisible].BoolValue = true;
// else
// TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
// base.Show();
// }
// /// <summary>
// ///
// /// </summary>
// //public override void Hide()
// //{
// // TriList.BooleanInput[UIBoolJoin.ToggleSharingModeVisible].BoolValue = false;
// // TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
// // if(IsSharingModeAdvanced)
// // TriList.BooleanInput[UIBoolJoin.DualDisplayPageVisible].BoolValue = false;
// // else
// // TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
// // base.Hide();
// //}
// public void SetCurrentRoomFromParent()
// {
// if (IsSharingModeAdvanced)
// return; // add stuff here
// else
// SetupSourceListForSimpleRouting();
// }
// /// <summary>
// ///
// /// </summary>
// void SetupSourceListForSimpleRouting()
// {
// // get the source list config and set up the source list
// var config = ConfigReader.ConfigObject.SourceLists;
// if (config.ContainsKey(Parent.CurrentRoom.SourceListKey))
// {
// var srcList = config[Parent.CurrentRoom.SourceListKey]
// .Values.ToList().OrderBy(s => s.Order);
// // Setup sources list
// uint i = 1; // counter for UI list
// foreach (var srcConfig in srcList)
// {
// if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
// continue;
// var sourceKey = srcConfig.SourceKey;
// var actualSource = DeviceManager.GetDeviceForKey(sourceKey) as Device;
// if (actualSource == null)
// {
// Debug.Console(0, "Cannot assign missing source '{0}' to source UI list",
// srcConfig.SourceKey);
// continue;
// }
// var localSrcItem = srcConfig; // lambda scope below
// var localIndex = i;
// SourcesSrl.GetBoolFeedbackSig(i, 1).UserObject = new Action<bool>(b =>
// {
// if (IsSharingModeAdvanced)
// {
// if (LastSelectedSourceSig != null)
// LastSelectedSourceSig.BoolValue = false;
// SourceListButtonPress(localSrcItem);
// LastSelectedSourceSig = SourcesSrl.BoolInputSig(localIndex, 1);
// LastSelectedSourceSig.BoolValue = true;
// }
// else
// Parent.CurrentRoom.DoSourceToAllDestinationsRoute(localSrcItem);
// });
// SourcesSrl.StringInputSig(i, 1).StringValue = srcConfig.PreferredName;
// i++;
// //var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
// // b => { if (!b) UiSelectSource(localSrcConfig); });
// //SourcesSrl.AddItem(item); // add to the SRL
// //item.RegisterForSourceChange(Parent.CurrentRoom);
// }
// SourcesSrl.Count = (ushort)(i - 1);
// Parent.CurrentRoom.CurrentSingleSourceChange += CurrentRoom_CurrentSourceInfoChange;
// Parent.CurrentRoom.CurrentDisplay1SourceChange += CurrentRoom_CurrentDisplay1SourceChange;
// Parent.CurrentRoom.CurrentDisplay2SourceChange += CurrentRoom_CurrentDisplay2SourceChange;
// }
// }
// void SetupSourceListForAdvancedRouting()
// {
// }
// void CurrentRoom_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// }
// void CurrentRoom_CurrentDisplay1SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// TriList.StringInput[UIStringJoin.Display1SourceLabel].StringValue = PendingSource.PreferredName;
// }
// void CurrentRoom_CurrentDisplay2SourceChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
// {
// TriList.StringInput[UIStringJoin.Display2SourceLabel].StringValue = PendingSource.PreferredName;
// }
// /// <summary>
// ///
// /// </summary>
// void ToggleSharingModePressed()
// {
// Hide();
// IsSharingModeAdvanced = !IsSharingModeAdvanced;
// TriList.BooleanInput[UIBoolJoin.ToggleSharingModePress].BoolValue = IsSharingModeAdvanced;
// Show();
// }
// public void SourceListButtonPress(SourceListItem item)
// {
// // start the timer
// // show FB on potential source
// TriList.BooleanInput[UIBoolJoin.Display1AudioButtonEnable].BoolValue = false;
// TriList.BooleanInput[UIBoolJoin.Display1ControlButtonEnable].BoolValue = false;
// TriList.BooleanInput[UIBoolJoin.Display2AudioButtonEnable].BoolValue = false;
// TriList.BooleanInput[UIBoolJoin.Display2ControlButtonEnable].BoolValue = false;
// PendingSource = item;
// }
// void EnableAppropriateDisplayButtons()
// {
// TriList.BooleanInput[UIBoolJoin.Display1AudioButtonEnable].BoolValue = true;
// TriList.BooleanInput[UIBoolJoin.Display1ControlButtonEnable].BoolValue = true;
// TriList.BooleanInput[UIBoolJoin.Display2AudioButtonEnable].BoolValue = true;
// TriList.BooleanInput[UIBoolJoin.Display2ControlButtonEnable].BoolValue = true;
// if (LastSelectedSourceSig != null)
// LastSelectedSourceSig.BoolValue = false;
// }
// public void Display1Press()
// {
// EnableAppropriateDisplayButtons();
// Parent.CurrentRoom.SourceToDisplay1(PendingSource);
// // Enable end meeting
// }
// public void Display1AudioPress()
// {
// }
// public void Display1ControlPress()
// {
// }
// public void Display2Press()
// {
// EnableAppropriateDisplayButtons();
// Parent.CurrentRoom.SourceToDisplay2(PendingSource);
// }
// public void Display2AudioPress()
// {
// }
// public void Display2ControlPress()
// {
// }
// }
//}

View File

@@ -0,0 +1,973 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.UI;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.PageManagers;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class EssentialsHuddlePanelAvFunctionsDriver : PanelDriverBase
{
CrestronTouchpanelPropertiesConfig Config;
public enum UiDisplayMode
{
PresentationMode, AudioSetup
}
/// <summary>
/// Whether volume ramping from this panel will show the volume
/// gauge popup.
/// </summary>
public bool ShowVolumeGauge { get; set; }
/// <summary>
/// The amount of time that the volume buttons stays on screen, in ms
/// </summary>
public uint VolumeButtonPopupTimeout
{
get { return VolumeButtonsPopupFeedback.TimeoutMs; }
set { VolumeButtonsPopupFeedback.TimeoutMs = value; }
}
/// <summary>
/// The amount of time that the volume gauge stays on screen, in ms
/// </summary>
public uint VolumeGaugePopupTimeout
{
get { return VolumeGaugeFeedback.TimeoutMs; }
set { VolumeGaugeFeedback.TimeoutMs = value; }
}
/// <summary>
///
/// </summary>
public uint PowerOffTimeout { get; set; }
/// <summary>
///
/// </summary>
public string DefaultRoomKey
{
get { return _DefaultRoomKey; }
set
{
_DefaultRoomKey = value;
//CurrentRoom = DeviceManager.GetDeviceForKey(value) as EssentialsHuddleSpaceRoom;
}
}
string _DefaultRoomKey;
/// <summary>
///
/// </summary>
public EssentialsHuddleSpaceRoom CurrentRoom
{
get { return _CurrentRoom; }
set
{
SetCurrentRoom(value);
}
}
EssentialsHuddleSpaceRoom _CurrentRoom;
/// <summary>
///
/// </summary>
//uint CurrentInterlockedModalJoin;
/// <summary>
/// For hitting feedback
/// </summary>
BoolInputSig ShareButtonSig;
BoolInputSig EndMeetingButtonSig;
/// <summary>
/// Controls the extended period that the volume gauge shows on-screen,
/// as triggered by Volume up/down operations
/// </summary>
BoolFeedbackPulseExtender VolumeGaugeFeedback;
/// <summary>
/// Controls the period that the volume buttons show on non-hard-button
/// interfaces
/// </summary>
BoolFeedbackPulseExtender VolumeButtonsPopupFeedback;
/// <summary>
/// The parent driver for this
/// </summary>
PanelDriverBase Parent;
/// <summary>
/// All children attached to this driver. For hiding and showing as a group.
/// </summary>
List<PanelDriverBase> ChildDrivers = new List<PanelDriverBase>();
List<BoolInputSig> CurrentDisplayModeSigsInUse = new List<BoolInputSig>();
//// Important smart objects
/// <summary>
/// Smart Object 3200
/// </summary>
SubpageReferenceList SourcesSrl;
/// <summary>
/// Smart Object 15022
/// </summary>
SubpageReferenceList ActivityFooterSrl;
/// <summary>
/// Tracks which audio page group the UI is in
/// </summary>
UiDisplayMode CurrentDisplayMode;
/// <summary>
/// The AV page mangagers that have been used, to keep them alive for later
/// </summary>
Dictionary<object, PageManager> PageManagers = new Dictionary<object, PageManager>();
/// <summary>
/// Current page manager running for a source
/// </summary>
PageManager CurrentSourcePageManager;
/// <summary>
/// Will auto-timeout a power off
/// </summary>
CTimer PowerOffTimer;
ModalDialog PowerDownModal;
ModalDialog WarmingCoolingModal;
JoinedSigInterlock PopupInterlock;
/// <summary>
/// Constructor
/// </summary>
public EssentialsHuddlePanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
: base(parent.TriList)
{
Config = config;
Parent = parent;
PopupInterlock = new JoinedSigInterlock(TriList);
SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
ActivityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
ShareButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
SetupActivityFooterWhenRoomOff();
ShowVolumeGauge = true;
// One-second pulse extender for volume gauge
VolumeGaugeFeedback = new BoolFeedbackPulseExtender(1500);
VolumeGaugeFeedback.Feedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeGaugePopupVisible]);
VolumeButtonsPopupFeedback = new BoolFeedbackPulseExtender(4000);
VolumeButtonsPopupFeedback.Feedback
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VolumeButtonPopupVisible]);
PowerOffTimeout = 30000;
TriList.StringInput[UIStringJoin.StartActivityText].StringValue =
"Tap Share to begin";
}
/// <summary>
///
/// </summary>
public override void Show()
{
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true;
// Default to showing rooms/sources now.
ShowMode(UiDisplayMode.PresentationMode);
// Attach actions
TriList.SetSigFalseAction(UIBoolJoin.VolumeButtonPopupPress, VolumeButtonsTogglePress);
//Interlocked modals
TriList.SetSigFalseAction(UIBoolJoin.InterlockedModalClosePress, PopupInterlock.HideAndClear);// HideCurrentInterlockedModal);
TriList.SetSigFalseAction(UIBoolJoin.HelpPress, () =>
{
string message = null;
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
as EssentialsHuddleSpaceRoom;
if (room != null)
message = room.Config.HelpMessage;
else
message = "Sorry, no help message available. No room connected.";
TriList.StringInput[UIStringJoin.HelpMessage].StringValue = message;
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HelpPageVisible); // ShowInterlockedModal(UIBoolJoin.HelpPageVisible);
});
//TriList.SetSigFalseAction(UIBoolJoin.RoomHeaderButtonPress, () =>
// ShowInterlockedModal(UIBoolJoin.RoomHeaderPageVisible));
// Setup button
TriList.SetSigHeldAction(UIBoolJoin.GearHeaderButtonPress, 2000,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.TechPanelSetupVisible));// ShowInterlockedModal(UIBoolJoin.TechPanelSetupVisible));
TriList.SetSigFalseAction(UIBoolJoin.TechPagesExitButton, () =>
PopupInterlock.HideAndClear()); // HideCurrentInterlockedModal());
#warning This gets overridden by config after NYU demo
if(TriList is CrestronApp)
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
else
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = true;
// power-related functions
// Note: some of these are not directly-related to the huddle space UI, but are held over
// in case
TriList.SetSigFalseAction(UIBoolJoin.ShowPowerOffPress, PowerButtonPressed);
TriList.SetSigFalseAction(UIBoolJoin.PowerOffMorePress, () =>
{
CancelPowerOffTimer();
TriList.BooleanInput[UIBoolJoin.PowerOffStep1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.PowerOffStep2Visible].BoolValue = true;
});
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
base.Show();
}
/// <summary>
///
/// </summary>
public override void Hide()
{
HideAndClearCurrentDisplayModeSigsInUse();
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
//TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
VolumeButtonsPopupFeedback.ClearNow();
//CancelPowerOff();
base.Hide();
}
/// <summary>
/// Shows the various "modes" that this driver controls. Presentation, Setup page
/// </summary>
/// <param name="mode"></param>
public void ShowMode(UiDisplayMode mode)
{
//Clear whatever is showing now.
HideAndClearCurrentDisplayModeSigsInUse();
CurrentDisplayMode = mode;
switch (mode)
{
case UiDisplayMode.PresentationMode:
// show start page or staging...
if (CurrentRoom.OnFeedback.BoolValue)
{
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
}
else
{
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
}
// Date/time
if (Config.ShowDate && Config.ShowTime)
{
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = false;
}
else
{
TriList.BooleanInput[UIBoolJoin.DateAndTimeVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.DateOnlyVisible].BoolValue = Config.ShowDate;
TriList.BooleanInput[UIBoolJoin.TimeOnlyVisible].BoolValue = Config.ShowTime;
}
ShowCurrentDisplayModeSigsInUse();
break;
}
}
/// <summary>
/// When the room is off, set the footer SRL
/// </summary>
void SetupActivityFooterWhenRoomOff()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 0,
b => { if (!b) ShareButtonPressed(); }));
ActivityFooterSrl.Count = 1;
TriList.UShortInput[UIUshortJoin.PresentationListCaretMode].UShortValue = 0;
ShareButtonSig.BoolValue = false;
}
/// <summary>
/// Sets up the footer SRL for when the room is on
/// </summary>
void SetupActivityFooterWhenRoomOn()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl,
0, null));
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl,
3, b => { if (!b) PowerButtonPressed(); }));
ActivityFooterSrl.Count = 2;
TriList.UShortInput[UIUshortJoin.PresentationListCaretMode].UShortValue = 1;
EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(2, 1);
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
}
/// <summary>
/// Attached to activity list share button
/// </summary>
void ShareButtonPressed()
{
ShareButtonSig.BoolValue = true;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
// Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue)
CurrentRoom.RunDefaultRoute();
}
/// <summary>
/// Hides a current modal if showing and then shows a new.
/// </summary>
/// <param name="join"></param>
//void ShowInterlockedModal(uint join)
//{
// if (CurrentInterlockedModalJoin == join)
// HideCurrentInterlockedModal();
// else
// {
// // sets the sig true if the join is right
// TriList.BooleanInput[UIBoolJoin.HelpPageVisible].BoolValue = join == UIBoolJoin.HelpPageVisible;
// TriList.BooleanInput[UIBoolJoin.RoomHeaderPageVisible].BoolValue = join == UIBoolJoin.RoomHeaderPageVisible;
// TriList.BooleanInput[UIBoolJoin.VolumesPageVisible].BoolValue = join == UIBoolJoin.VolumesPageVisible;
// TriList.BooleanInput[UIBoolJoin.TechPanelSetupVisible].BoolValue = join == UIBoolJoin.TechPanelSetupVisible;
// CurrentInterlockedModalJoin = join;
// }
//}
///// <summary>
///// Helper to hide the current interlocked modal
///// </summary>
//void HideCurrentInterlockedModal()
//{
// TriList.BooleanInput[CurrentInterlockedModalJoin].BoolValue = false;
// CurrentInterlockedModalJoin = 0;
//}
/// <summary>
/// Shows all sigs that are in CurrentDisplayModeSigsInUse
/// </summary>
void ShowCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
sig.BoolValue = true;
}
/// <summary>
/// Hides all CurrentDisplayModeSigsInUse sigs and clears the array
/// </summary>
void HideAndClearCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
sig.BoolValue = false;
CurrentDisplayModeSigsInUse.Clear();
}
/// <summary>
/// Send the UI back depending on location, not used in huddle UI
/// </summary>
public override void BackButtonPressed()
{
switch (CurrentDisplayMode)
{
case UiDisplayMode.PresentationMode:
//CancelReturnToSourceTimer();
BackToHome();
break;
}
}
/// <summary>
///
/// </summary>
void BackToHome()
{
Hide();
Parent.Show();
}
/// <summary>
/// Loads the appropriate Sigs into CurrentDisplayModeSigsInUse and shows them
/// </summary>
void ShowCurrentSource()
{
if (CurrentRoom.CurrentSourceInfo == null)
return;
var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo;
PageManager pm = null;
// If we need a page manager, get an appropriate one
if (uiDev != null)
{
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
// Got an existing page manager, get it
if (PageManagers.ContainsKey(uiDev))
pm = PageManagers[uiDev];
// Otherwise make an apporiate one
else if (uiDev is ISetTopBoxControls)
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
else if (uiDev is IDiscPlayerControls)
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
else
pm = new DefaultPageManager(uiDev, TriList);
PageManagers[uiDev] = pm;
CurrentSourcePageManager = pm;
pm.Show();
}
}
/// <summary>
/// Called from button presses on source, where We can assume we want
/// to change to the proper screen.
/// </summary>
/// <param name="key">The key name of the route to run</param>
void UiSelectSource(string key)
{
// Run the route and when it calls back, show the source
CurrentRoom.RunRouteAction(key, null);
}
/// <summary>
///
/// </summary>
public void PowerButtonPressed()
{
if (!CurrentRoom.OnFeedback.BoolValue
|| CurrentRoom.ShutdownPromptTimer.IsRunningFeedback.BoolValue)
return;
CurrentRoom.StartShutdown(ShutdownType.Manual);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
{
// Do we need to check where the UI is? No?
var timer = CurrentRoom.ShutdownPromptTimer;
EndMeetingButtonSig.BoolValue = true;
ShareButtonSig.BoolValue = false;
if (CurrentRoom.ShutdownType == ShutdownType.Manual)
{
PowerDownModal = new ModalDialog(TriList);
var message = string.Format("Meeting will end in {0} seconds", CurrentRoom.ShutdownPromptSeconds);
//// figure out a cleaner way to update gauge
//var gauge = CurrentRoom.ShutdownPromptTimer.PercentFeedback;
//EventHandler<EventArgs> gaugeHandler = null;
//gaugeHandler = (o, a) => TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue =
// (ushort)(gauge.UShortValue * 65535 / 100);
//gauge.OutputChange += gaugeHandler;
// Attach timer things to modal
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange += ShutdownPromptTimer_PercentFeedback_OutputChange;
// respond to offs by cancelling dialog
var onFb = CurrentRoom.OnFeedback;
EventHandler<EventArgs> offHandler = null;
offHandler = (o, a) =>
{
if (!onFb.BoolValue)
{
EndMeetingButtonSig.BoolValue = false;
PowerDownModal.HideDialog();
onFb.OutputChange -= offHandler;
//gauge.OutputChange -= gaugeHandler;
}
};
onFb.OutputChange += offHandler;
PowerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
but =>
{
if (but != 2) // any button except for End cancels
timer.Cancel();
else
timer.Finish();
});
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
//Debug.Console(2, "*#*UI shutdown prompt finished");
EndMeetingButtonSig.BoolValue = false;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
{
//Debug.Console(2, "*#*UI shutdown prompt cancelled");
if (PowerDownModal != null)
PowerDownModal.HideDialog();
EndMeetingButtonSig.BoolValue = false;
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
}
void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e)
{
var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue);
TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message;
}
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
{
var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100);
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
}
/// <summary>
///
/// </summary>
void CancelPowerOffTimer()
{
if (PowerOffTimer != null)
{
PowerOffTimer.Stop();
PowerOffTimer = null;
}
}
/// <summary>
///
/// </summary>
void VolumeButtonsTogglePress()
{
if (VolumeButtonsPopupFeedback.BoolValue)
VolumeButtonsPopupFeedback.ClearNow();
else
{
// Trigger the popup
VolumeButtonsPopupFeedback.BoolValue = true;
VolumeButtonsPopupFeedback.BoolValue = false;
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void VolumeUpPress(bool state)
{
// extend timeouts
if (ShowVolumeGauge)
VolumeGaugeFeedback.BoolValue = state;
VolumeButtonsPopupFeedback.BoolValue = state;
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeUp(state);
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void VolumeDownPress(bool state)
{
// extend timeouts
if (ShowVolumeGauge)
VolumeGaugeFeedback.BoolValue = state;
VolumeButtonsPopupFeedback.BoolValue = state;
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeDown(state);
}
/// <summary>
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
/// </summary>
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
{
if (_CurrentRoom == room) return;
// Disconnect current (probably never called)
if (_CurrentRoom != null)
{
// Disconnect current room
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
ClearAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange -= this.CurrentRoom_SourceInfoChange;
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
}
_CurrentRoom = room;
if (_CurrentRoom != null)
{
// get the source list config and set up the source list
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey];
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
continue;
var actualSource = DeviceManager.GetDeviceForKey(srcConfig.SourceKey) as Device;
if (actualSource == null)
{
Debug.Console(1, "Cannot assign missing source '{0}' to source UI list",
srcConfig.SourceKey);
continue;
}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourcesSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourcesSrl.Count = (ushort)(i - 1);
}
// Name and logo
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
if (_CurrentRoom.LogoUrl == null)
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false;
}
else
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true;
TriList.StringInput[UIStringJoin.LogoUrl].StringValue = _CurrentRoom.LogoUrl;
}
// Shutdown timer
_CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
// Link up all the change events from the room
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
CurrentRoom_SyncOnFeedback();
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange += CurrentRoom_SourceInfoChange;
RefreshSourceInfo();
}
else
{
// Clear sigs that need to be
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = "Select a room";
}
}
/// <summary>
/// For room on/off changes
/// </summary>
void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e)
{
CurrentRoom_SyncOnFeedback();
}
void CurrentRoom_SyncOnFeedback()
{
var value = _CurrentRoom.OnFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: Is on event={0}", value);
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
if (value) //ON
{
SetupActivityFooterWhenRoomOn();
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = true;
}
else
{
SetupActivityFooterWhenRoomOff();
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
}
}
/// <summary>
///
/// </summary>
void CurrentRoom_IsWarmingFeedback_OutputChange(object sender, EventArgs e)
{
var value = CurrentRoom.IsWarmingUpFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: WARMING event={0}", value);
if (value)
{
WarmingCoolingModal = new ModalDialog(TriList);
WarmingCoolingModal.PresentModalDialog(0, "Powering Up", "Power", "<p>Room is powering up</p><p>Please wait</p>",
"", "", false, false, null);
}
else
{
if (WarmingCoolingModal != null)
WarmingCoolingModal.CancelDialog();
}
}
void IsCoolingDownFeedback_OutputChange(object sender, EventArgs e)
{
var value = CurrentRoom.IsCoolingDownFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: Cooldown event={0}", value);
if (value)
{
WarmingCoolingModal = new ModalDialog(TriList);
WarmingCoolingModal.PresentModalDialog(0, "Shut Down", "Power", "<p>Room is shutting down</p><p>Please wait</p>",
"", "", false, false, null);
}
else
{
if (WarmingCoolingModal != null)
WarmingCoolingModal.CancelDialog();
}
}
/// <summary>
/// Hides source for provided source info
/// </summary>
/// <param name="previousInfo"></param>
void DisconnectSource(SourceListItem previousInfo)
{
if (previousInfo == null) return;
// Hide whatever is showing
if (IsVisible)
{
if (CurrentSourcePageManager != null)
{
CurrentSourcePageManager.Hide();
CurrentSourcePageManager = null;
}
}
if (previousInfo == null) return;
var previousDev = previousInfo.SourceDevice;
// device type interfaces
if (previousDev is ISetTopBoxControls)
(previousDev as ISetTopBoxControls).UnlinkButtons(TriList);
// common interfaces
if (previousDev is IChannel)
(previousDev as IChannel).UnlinkButtons(TriList);
if (previousDev is IColor)
(previousDev as IColor).UnlinkButtons(TriList);
if (previousDev is IDPad)
(previousDev as IDPad).UnlinkButtons(TriList);
if (previousDev is IDvr)
(previousDev as IDvr).UnlinkButtons(TriList);
if (previousDev is INumericKeypad)
(previousDev as INumericKeypad).UnlinkButtons(TriList);
if (previousDev is IPower)
(previousDev as IPower).UnlinkButtons(TriList);
if (previousDev is ITransport)
(previousDev as ITransport).UnlinkButtons(TriList);
//if (previousDev is IRadio)
// (previousDev as IRadio).UnlinkButtons(this);
}
/// <summary>
/// Refreshes and shows the room's current source
/// </summary>
void RefreshSourceInfo()
{
var routeInfo = CurrentRoom.CurrentSourceInfo;
// This will show off popup too
if (this.IsVisible)
ShowCurrentSource();
if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue)
{
// Check for power off and insert "Room is off"
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "Room is off";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Power";
this.Hide();
Parent.Show();
return;
}
else if (CurrentRoom.CurrentSourceInfo != null)
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
}
else
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
}
// Connect controls
if (routeInfo.SourceDevice != null)
ConnectControlDeviceMethods(routeInfo.SourceDevice);
}
/// <summary>
/// Attach the source to the buttons and things
/// </summary>
void ConnectControlDeviceMethods(Device dev)
{
if(dev is ISetTopBoxControls)
(dev as ISetTopBoxControls).LinkButtons(TriList);
if (dev is IChannel)
(dev as IChannel).LinkButtons(TriList);
if (dev is IColor)
(dev as IColor).LinkButtons(TriList);
if (dev is IDPad)
(dev as IDPad).LinkButtons(TriList);
if (dev is IDvr)
(dev as IDvr).LinkButtons(TriList);
if (dev is INumericKeypad)
(dev as INumericKeypad).LinkButtons(TriList);
if (dev is IPower)
(dev as IPower).LinkButtons(TriList);
if (dev is ITransport)
(dev as ITransport).LinkButtons(TriList);
//if (dev is IRadio)
// (dev as IRadio).LinkButtons(this); // +++++++++++++ Make part of this into page manager
//if (dev is ICustomFunctions)
//{
// var custBridge = (dev as ICustomFunctions).GetCustomBridge();
// custBridge.Link(this.Remote);
}
/// <summary>
/// Detaches the buttons and feedback from the room's current audio device
/// </summary>
void ClearAudioDeviceConnections()
{
TriList.ClearBoolSigAction(UIBoolJoin.VolumeUpPress);
TriList.ClearBoolSigAction(UIBoolJoin.VolumeDownPress);
TriList.ClearBoolSigAction(UIBoolJoin.Volume1ProgramMutePressAndFB);
var fDev = CurrentRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (fDev != null)
{
TriList.ClearUShortSigAction(UIUshortJoin.VolumeSlider1Value);
fDev.VolumeLevelFeedback.UnlinkInputSig(
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value]);
}
}
/// <summary>
/// Attaches the buttons and feedback to the room's current audio device
/// </summary>
void RefreshAudioDeviceConnections()
{
var dev = CurrentRoom.CurrentVolumeControls;
if (dev != null) // connect buttons
{
TriList.SetBoolSigAction(UIBoolJoin.VolumeUpPress, VolumeUpPress);
TriList.SetBoolSigAction(UIBoolJoin.VolumeDownPress, VolumeDownPress);
TriList.SetSigFalseAction(UIBoolJoin.Volume1ProgramMutePressAndFB, dev.MuteToggle);
}
var fbDev = dev as IBasicVolumeWithFeedback;
if (fbDev == null) // this should catch both IBasicVolume and IBasicVolumeWithFeeback
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value].UShortValue = 0;
else
{
// slider
TriList.SetUShortSigAction(UIUshortJoin.VolumeSlider1Value, fbDev.SetVolume);
// feedbacks
fbDev.MuteFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.Volume1ProgramMutePressAndFB]);
fbDev.VolumeLevelFeedback.LinkInputSig(
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value]);
}
}
/// <summary>
/// Handler for when the room's volume control device changes
/// </summary>
void CurrentRoom_CurrentAudioDeviceChange(object sender, VolumeDeviceChangeEventArgs args)
{
if (args.Type == ChangeType.WillChange)
ClearAudioDeviceConnections();
else // did change
RefreshAudioDeviceConnections();
}
/// <summary>
/// Handles source change
/// </summary>
void CurrentRoom_SourceInfoChange(EssentialsRoomBase room,
SourceListItem info, ChangeType change)
{
if (change == ChangeType.WillChange)
DisconnectSource(info);
else
RefreshSourceInfo();
}
}
}

View File

@@ -0,0 +1,62 @@
using System;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.UI;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class EssentialsPanelMainInterfaceDriver : PanelDriverBase
{
/// <summary>
/// Assign the appropriate A/V driver.
/// Want to keep the AvDriver alive, because it may hold states
/// </summary>
public PanelDriverBase AvDriver { get; set; }
public PanelDriverBase CurrentChildDriver { get; private set; }
CrestronTouchpanelPropertiesConfig Config;
public EssentialsPanelMainInterfaceDriver(BasicTriListWithSmartObject trilist,
CrestronTouchpanelPropertiesConfig config)
: base(trilist)
{
Config = config;
}
public override void Show()
{
CurrentChildDriver = null;
ShowSubDriver(AvDriver);
base.Show();
}
public override void Hide()
{
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
base.Hide();
}
void ShowSubDriver(PanelDriverBase driver)
{
CurrentChildDriver = driver;
if (driver == null)
return;
this.Hide();
driver.Show();
}
/// <summary>
///
/// </summary>
public override void BackButtonPressed()
{
if(CurrentChildDriver != null)
CurrentChildDriver.BackButtonPressed();
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials
{
public class JoinedSigInterlock
{
public uint CurrentJoin { get; private set; }
BasicTriList TriList;
public JoinedSigInterlock(BasicTriList triList)
{
TriList = triList;
}
/// <summary>
/// Hides CurrentJoin and shows join
/// </summary>
public void ShowInterlocked(uint join)
{
if (CurrentJoin > 0)
TriList.BooleanInput[CurrentJoin].BoolValue = false;
CurrentJoin = join;
TriList.BooleanInput[CurrentJoin].BoolValue = true;
}
/// <summary>
///
/// </summary>
/// <param name="join"></param>
public void ShowInterlockedWithToggle(uint join)
{
if (CurrentJoin == join)
HideAndClear();
else
{
if (CurrentJoin > 0)
TriList.BooleanInput[CurrentJoin].BoolValue = false;
CurrentJoin = join;
TriList.BooleanInput[CurrentJoin].BoolValue = true;
}
}
/// <summary>
/// Hides current join and clears CurrentJoin
/// </summary>
public void HideAndClear()
{
Hide();
CurrentJoin = 0;
}
/// <summary>
/// Hides the current join but does not clear the selected join in case
/// it needs to be reshown
/// </summary>
public void Hide()
{
if (CurrentJoin > 0)
TriList.BooleanInput[CurrentJoin].BoolValue = false;
}
/// <summary>
/// If CurrentJoin is set, it restores that join
/// </summary>
public void Show()
{
if (CurrentJoin > 0)
TriList.BooleanInput[CurrentJoin].BoolValue = true;
}
}
}

View File

@@ -0,0 +1,848 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.UI;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
using PepperDash.Essentials.Core.PageManagers;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class NyuHuddleVtcPanelAvFunctionsDriver : PanelDriverBase
{
CrestronTouchpanelPropertiesConfig Config;
public enum UiDisplayMode
{
PresentationMode, AudioSetup
}
/// <summary>
/// Whether volume ramping from this panel will show the volume
/// gauge popup.
/// </summary>
public bool ShowVolumeGauge { get; set; }
/// <summary>
///
/// </summary>
public uint PowerOffTimeout { get; set; }
/// <summary>
///
/// </summary>
public string DefaultRoomKey { get; set; }
//{
// get { return _DefaultRoomKey; }
// set
// {
// _DefaultRoomKey = value;
// }
//}
//string _DefaultRoomKey;
/// <summary>
///
/// </summary>
public EssentialsHuddleSpaceRoom CurrentRoom
{
get { return _CurrentRoom; }
set
{
SetCurrentRoom(value);
}
}
EssentialsHuddleSpaceRoom _CurrentRoom;
/// <summary>
///
/// </summary>
//uint CurrentInterlockedModalJoin;
/// <summary>
/// For hitting feedback
/// </summary>
BoolInputSig CallButtonSig;
BoolInputSig ShareButtonSig;
BoolInputSig EndMeetingButtonSig;
/// <summary>
/// The parent driver for this
/// </summary>
PanelDriverBase Parent;
/// <summary>
/// All children attached to this driver. For hiding and showing as a group.
/// </summary>
List<PanelDriverBase> ChildDrivers = new List<PanelDriverBase>();
List<BoolInputSig> CurrentDisplayModeSigsInUse = new List<BoolInputSig>();
//// Important smart objects
/// <summary>
/// Smart Object 3200
/// </summary>
SubpageReferenceList SourcesSrl;
/// <summary>
/// Smart Object 15022
/// </summary>
SubpageReferenceList ActivityFooterSrl;
/// <summary>
/// Tracks which audio page group the UI is in
/// </summary>
UiDisplayMode CurrentDisplayMode;
/// <summary>
/// The AV page mangagers that have been used, to keep them alive for later
/// </summary>
Dictionary<object, PageManager> PageManagers = new Dictionary<object, PageManager>();
/// <summary>
/// Current page manager running for a source
/// </summary>
PageManager CurrentSourcePageManager;
/// <summary>
/// Will auto-timeout a power off
/// </summary>
CTimer PowerOffTimer;
/// <summary>
///
/// </summary>
ModalDialog PowerDownModal;
/// <summary>
///
/// </summary>
ModalDialog WarmingCoolingModal;
/// <summary>
/// Represents
/// </summary>
JoinedSigInterlock PopupInterlock;
/// <summary>
/// Constructor
/// </summary>
public NyuHuddleVtcPanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
: base(parent.TriList)
{
Config = config;
Parent = parent;
PopupInterlock = new JoinedSigInterlock(TriList);
SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
ActivityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
CallButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
ShareButtonSig = ActivityFooterSrl.BoolInputSig(2, 1);
SetupActivityFooterWhenRoomOff();
ShowVolumeGauge = true;
PowerOffTimeout = 30000;
TriList.StringInput[UIStringJoin.StartActivityText].StringValue =
"Tap Share to begin";
}
/// <summary>
///
/// </summary>
public override void Show()
{
TriList.SetBool(UIBoolJoin.DateAndTimeVisible, Config.ShowDate && Config.ShowTime);
TriList.SetBool(UIBoolJoin.DateOnlyVisible, Config.ShowDate && !Config.ShowTime);
TriList.SetBool(UIBoolJoin.TimeOnlyVisible, !Config.ShowDate && Config.ShowTime);
TriList.SetBool(UIBoolJoin.TopBarVisible, true);
TriList.SetBool(UIBoolJoin.ActivityFooterVisible, true);
// Default to showing rooms/sources now.
//ShowMode(UiDisplayMode.PresentationMode);
if (CurrentRoom.OnFeedback.BoolValue)
{
TriList.SetBool(UIBoolJoin.StagingPageVisible, true);
TriList.SetBool(UIBoolJoin.TapToBeginVisible, false);
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
}
else
{
TriList.SetBool(UIBoolJoin.StartPageVisible, true);
TriList.SetBool(UIBoolJoin.TapToBeginVisible, true);
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
}
ShowCurrentDisplayModeSigsInUse();
// *** Header Buttons ***
// Generic "close" button for these modals
TriList.SetSigFalseAction(UIBoolJoin.InterlockedModalClosePress, PopupInterlock.HideAndClear);
// Help button
TriList.SetSigFalseAction(UIBoolJoin.HelpPress, () =>
{
string message = null;
var room = DeviceManager.GetDeviceForKey(Config.DefaultRoomKey)
as EssentialsHuddleSpaceRoom;
if (room != null)
message = room.Config.HelpMessage;
else
message = "Sorry, no help message available. No room connected.";
TriList.StringInput[UIStringJoin.HelpMessage].StringValue = message;
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HelpPageVisible);
});
// Lights button
TriList.SetSigFalseAction(UIBoolJoin.LightsHeaderButtonPress, () =>
{ });
// Call header button
TriList.SetSigFalseAction(UIBoolJoin.CallHeaderButtonPress, () =>
{ });
// Room name button
//TriList.SetSigFalseAction(UIBoolJoin.RoomHeaderButtonPress, () =>
// ShowInterlockedModal(UIBoolJoin.RoomHeaderPageVisible));
// Setup button - shows volumes with default button OR hold for tech page
TriList.SetSigHeldAction(UIBoolJoin.GearHeaderButtonPress, 2000,
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.TechPanelSetupVisible),
() => PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible));
TriList.SetSigFalseAction(UIBoolJoin.TechPagesExitButton, () =>
PopupInterlock.HideAndClear());
// Default Volume button
TriList.SetSigFalseAction(UIBoolJoin.VolumeDefaultPress, () => // Set default volume method on room
{ });
if (TriList is CrestronApp)
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = false;
else
TriList.BooleanInput[UIBoolJoin.GearButtonVisible].BoolValue = true;
// power-related functions
// Note: some of these are not directly-related to the huddle space UI, but are held over
// in case
TriList.SetSigFalseAction(UIBoolJoin.ShowPowerOffPress, PowerButtonPressed);
TriList.SetSigFalseAction(UIBoolJoin.DisplayPowerTogglePress, () =>
{
if (CurrentRoom != null && CurrentRoom.DefaultDisplay is IPower)
(CurrentRoom.DefaultDisplay as IPower).PowerToggle();
});
base.Show();
}
/// <summary>
///
/// </summary>
public override void Hide()
{
HideAndClearCurrentDisplayModeSigsInUse();
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
base.Hide();
}
/// <summary>
/// When the room is off, set the footer SRL
/// </summary>
void SetupActivityFooterWhenRoomOff()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 1,
b => { if (!b) CallButtonPressed(); }));
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 0,
b => { if (!b) ShareButtonPressed(); }));
ActivityFooterSrl.Count = 2;
TriList.UShortInput[UIUshortJoin.PresentationListCaretMode].UShortValue = 0;
ShareButtonSig.BoolValue = false;
}
/// <summary>
/// Sets up the footer SRL for when the room is on
/// </summary>
void SetupActivityFooterWhenRoomOn()
{
ActivityFooterSrl.Clear();
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl,
1, null));
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl,
0, null));
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, ActivityFooterSrl,
3, b => { if (!b) PowerButtonPressed(); }));
ActivityFooterSrl.Count = 2;
TriList.UShortInput[UIUshortJoin.PresentationListCaretMode].UShortValue = 1;
EndMeetingButtonSig = ActivityFooterSrl.BoolInputSig(3, 1);
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
}
void CallButtonPressed()
{
CallButtonSig.BoolValue = true;
TriList.SetBool(UIBoolJoin.StartPageVisible, false);
TriList.SetBool(UIBoolJoin.StagingPageVisible, false);
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
// Call "page"? Or separate UI driver?
}
/// <summary>
/// Attached to activity list share button
/// </summary>
void ShareButtonPressed()
{
ShareButtonSig.BoolValue = true;
TriList.SetBool(UIBoolJoin.StartPageVisible, false);
TriList.SetBool(UIBoolJoin.StagingPageVisible, true);
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
// Run default source when room is off and share is pressed
if (!CurrentRoom.OnFeedback.BoolValue)
CurrentRoom.RunDefaultRoute();
}
/// <summary>
/// Shows all sigs that are in CurrentDisplayModeSigsInUse
/// </summary>
void ShowCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
sig.BoolValue = true;
}
/// <summary>
/// Hides all CurrentDisplayModeSigsInUse sigs and clears the array
/// </summary>
void HideAndClearCurrentDisplayModeSigsInUse()
{
foreach (var sig in CurrentDisplayModeSigsInUse)
sig.BoolValue = false;
CurrentDisplayModeSigsInUse.Clear();
}
/// <summary>
/// Loads the appropriate Sigs into CurrentDisplayModeSigsInUse and shows them
/// </summary>
void ShowCurrentSource()
{
if (CurrentRoom.CurrentSourceInfo == null)
return;
var uiDev = CurrentRoom.CurrentSourceInfo.SourceDevice as IUiDisplayInfo;
PageManager pm = null;
// If we need a page manager, get an appropriate one
if (uiDev != null)
{
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
// Got an existing page manager, get it
if (PageManagers.ContainsKey(uiDev))
pm = PageManagers[uiDev];
// Otherwise make an apporiate one
else if (uiDev is ISetTopBoxControls)
//pm = new SetTopBoxMediumPageManager(uiDev as ISetTopBoxControls, TriList);
pm = new SetTopBoxThreePanelPageManager(uiDev as ISetTopBoxControls, TriList);
else if (uiDev is IDiscPlayerControls)
pm = new DiscPlayerMediumPageManager(uiDev as IDiscPlayerControls, TriList);
else
pm = new DefaultPageManager(uiDev, TriList);
PageManagers[uiDev] = pm;
CurrentSourcePageManager = pm;
pm.Show();
}
}
/// <summary>
/// Called from button presses on source, where We can assume we want
/// to change to the proper screen.
/// </summary>
/// <param name="key">The key name of the route to run</param>
void UiSelectSource(string key)
{
// Run the route and when it calls back, show the source
CurrentRoom.RunRouteAction(key, null);
}
/// <summary>
///
/// </summary>
public void PowerButtonPressed()
{
if (!CurrentRoom.OnFeedback.BoolValue
|| CurrentRoom.ShutdownPromptTimer.IsRunningFeedback.BoolValue)
return;
CurrentRoom.StartShutdown(ShutdownType.Manual);
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasStarted(object sender, EventArgs e)
{
// Do we need to check where the UI is? No?
var timer = CurrentRoom.ShutdownPromptTimer;
EndMeetingButtonSig.BoolValue = true;
ShareButtonSig.BoolValue = false;
if (CurrentRoom.ShutdownType == ShutdownType.Manual)
{
PowerDownModal = new ModalDialog(TriList);
var message = string.Format("Meeting will end in {0} seconds", CurrentRoom.ShutdownPromptSeconds);
// Attach timer things to modal
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange += ShutdownPromptTimer_PercentFeedback_OutputChange;
// respond to offs by cancelling dialog
var onFb = CurrentRoom.OnFeedback;
EventHandler<EventArgs> offHandler = null;
offHandler = (o, a) =>
{
if (!onFb.BoolValue)
{
EndMeetingButtonSig.BoolValue = false;
PowerDownModal.HideDialog();
onFb.OutputChange -= offHandler;
}
};
onFb.OutputChange += offHandler;
PowerDownModal.PresentModalDialog(2, "End Meeting", "Power", message, "Cancel", "End Meeting Now", true, true,
but =>
{
if (but != 2) // any button except for End cancels
timer.Cancel();
else
timer.Finish();
});
}
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_HasFinished(object sender, EventArgs e)
{
//Debug.Console(2, "*#*UI shutdown prompt finished");
EndMeetingButtonSig.BoolValue = false;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange -= ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ShutdownPromptTimer_WasCancelled(object sender, EventArgs e)
{
//Debug.Console(2, "*#*UI shutdown prompt cancelled");
if (PowerDownModal != null)
PowerDownModal.HideDialog();
EndMeetingButtonSig.BoolValue = false;
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
CurrentRoom.ShutdownPromptTimer.TimeRemainingFeedback.OutputChange += ShutdownPromptTimer_TimeRemainingFeedback_OutputChange;
CurrentRoom.ShutdownPromptTimer.PercentFeedback.OutputChange -= ShutdownPromptTimer_PercentFeedback_OutputChange;
}
void ShutdownPromptTimer_TimeRemainingFeedback_OutputChange(object sender, EventArgs e)
{
var message = string.Format("Meeting will end in {0} seconds", (sender as StringFeedback).StringValue);
TriList.StringInput[ModalDialog.MessageTextJoin].StringValue = message;
}
void ShutdownPromptTimer_PercentFeedback_OutputChange(object sender, EventArgs e)
{
var value = (ushort)((sender as IntFeedback).UShortValue * 65535 / 100);
TriList.UShortInput[ModalDialog.TimerGaugeJoin].UShortValue = value;
}
/// <summary>
///
/// </summary>
void CancelPowerOffTimer()
{
if (PowerOffTimer != null)
{
PowerOffTimer.Stop();
PowerOffTimer = null;
}
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void VolumeUpPress(bool state)
{
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeUp(state);
}
/// <summary>
///
/// </summary>
/// <param name="state"></param>
public void VolumeDownPress(bool state)
{
if (CurrentRoom.CurrentVolumeControls != null)
CurrentRoom.CurrentVolumeControls.VolumeDown(state);
}
/// <summary>
/// Helper for property setter. Sets the panel to the given room, latching up all functionality
/// </summary>
void SetCurrentRoom(EssentialsHuddleSpaceRoom room)
{
if (_CurrentRoom == room) return;
// Disconnect current (probably never called)
if (_CurrentRoom != null)
{
// Disconnect current room
_CurrentRoom.CurrentVolumeDeviceChange -= this.CurrentRoom_CurrentAudioDeviceChange;
ClearAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange -= this.CurrentRoom_SourceInfoChange;
DisconnectSource(_CurrentRoom.CurrentSourceInfo);
_CurrentRoom.ShutdownPromptTimer.HasStarted -= ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished -= ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled -= ShutdownPromptTimer_WasCancelled;
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
_CurrentRoom.IsWarmingUpFeedback.OutputChange -= CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange -= IsCoolingDownFeedback_OutputChange;
}
_CurrentRoom = room;
if (_CurrentRoom != null)
{
// get the source list config and set up the source list
var config = ConfigReader.ConfigObject.SourceLists;
if (config.ContainsKey(_CurrentRoom.SourceListKey))
{
var srcList = config[_CurrentRoom.SourceListKey];
// Setup sources list
uint i = 1; // counter for UI list
foreach (var kvp in srcList)
{
var srcConfig = kvp.Value;
if (!srcConfig.IncludeInSourceList) // Skip sources marked this way
continue;
var actualSource = DeviceManager.GetDeviceForKey(srcConfig.SourceKey) as Device;
if (actualSource == null)
{
Debug.Console(1, "Cannot assign missing source '{0}' to source UI list",
srcConfig.SourceKey);
continue;
}
var routeKey = kvp.Key;
var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
b => { if (!b) UiSelectSource(routeKey); });
SourcesSrl.AddItem(item); // add to the SRL
item.RegisterForSourceChange(_CurrentRoom);
}
SourcesSrl.Count = (ushort)(i - 1);
}
// Name and logo
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = _CurrentRoom.Name;
if (_CurrentRoom.LogoUrl == null)
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = false;
}
else
{
TriList.BooleanInput[UIBoolJoin.LogoDefaultVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.LogoUrlVisible].BoolValue = true;
TriList.StringInput[UIStringJoin.LogoUrl].StringValue = _CurrentRoom.LogoUrl;
}
// Shutdown timer
_CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
_CurrentRoom.ShutdownPromptTimer.HasFinished += ShutdownPromptTimer_HasFinished;
_CurrentRoom.ShutdownPromptTimer.WasCancelled += ShutdownPromptTimer_WasCancelled;
// Link up all the change events from the room
_CurrentRoom.OnFeedback.OutputChange += CurrentRoom_OnFeedback_OutputChange;
CurrentRoom_SyncOnFeedback();
_CurrentRoom.IsWarmingUpFeedback.OutputChange += CurrentRoom_IsWarmingFeedback_OutputChange;
_CurrentRoom.IsCoolingDownFeedback.OutputChange += IsCoolingDownFeedback_OutputChange;
_CurrentRoom.CurrentVolumeDeviceChange += CurrentRoom_CurrentAudioDeviceChange;
RefreshAudioDeviceConnections();
_CurrentRoom.CurrentSingleSourceChange += CurrentRoom_SourceInfoChange;
RefreshSourceInfo();
}
else
{
// Clear sigs that need to be
TriList.StringInput[UIStringJoin.CurrentRoomName].StringValue = "Select a room";
}
}
/// <summary>
/// For room on/off changes
/// </summary>
void CurrentRoom_OnFeedback_OutputChange(object sender, EventArgs e)
{
CurrentRoom_SyncOnFeedback();
}
void CurrentRoom_SyncOnFeedback()
{
var value = _CurrentRoom.OnFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: Is on event={0}", value);
TriList.BooleanInput[UIBoolJoin.RoomIsOn].BoolValue = value;
if (value) //ON
{
SetupActivityFooterWhenRoomOn();
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = true;
}
else
{
SetupActivityFooterWhenRoomOff();
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true;
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
}
}
/// <summary>
///
/// </summary>
void CurrentRoom_IsWarmingFeedback_OutputChange(object sender, EventArgs e)
{
var value = CurrentRoom.IsWarmingUpFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: WARMING event={0}", value);
if (value)
{
WarmingCoolingModal = new ModalDialog(TriList);
WarmingCoolingModal.PresentModalDialog(0, "Powering Up", "Power", "<p>Room is powering up</p><p>Please wait</p>",
"", "", false, false, null);
}
else
{
if (WarmingCoolingModal != null)
WarmingCoolingModal.CancelDialog();
}
}
void IsCoolingDownFeedback_OutputChange(object sender, EventArgs e)
{
var value = CurrentRoom.IsCoolingDownFeedback.BoolValue;
//Debug.Console(2, CurrentRoom, "UI: Cooldown event={0}", value);
if (value)
{
WarmingCoolingModal = new ModalDialog(TriList);
WarmingCoolingModal.PresentModalDialog(0, "Shut Down", "Power", "<p>Room is shutting down</p><p>Please wait</p>",
"", "", false, false, null);
}
else
{
if (WarmingCoolingModal != null)
WarmingCoolingModal.CancelDialog();
}
}
/// <summary>
/// Hides source for provided source info
/// </summary>
/// <param name="previousInfo"></param>
void DisconnectSource(SourceListItem previousInfo)
{
if (previousInfo == null) return;
// Hide whatever is showing
if (IsVisible)
{
if (CurrentSourcePageManager != null)
{
CurrentSourcePageManager.Hide();
CurrentSourcePageManager = null;
}
}
if (previousInfo == null) return;
var previousDev = previousInfo.SourceDevice;
// device type interfaces
if (previousDev is ISetTopBoxControls)
(previousDev as ISetTopBoxControls).UnlinkButtons(TriList);
// common interfaces
if (previousDev is IChannel)
(previousDev as IChannel).UnlinkButtons(TriList);
if (previousDev is IColor)
(previousDev as IColor).UnlinkButtons(TriList);
if (previousDev is IDPad)
(previousDev as IDPad).UnlinkButtons(TriList);
if (previousDev is IDvr)
(previousDev as IDvr).UnlinkButtons(TriList);
if (previousDev is INumericKeypad)
(previousDev as INumericKeypad).UnlinkButtons(TriList);
if (previousDev is IPower)
(previousDev as IPower).UnlinkButtons(TriList);
if (previousDev is ITransport)
(previousDev as ITransport).UnlinkButtons(TriList);
//if (previousDev is IRadio)
// (previousDev as IRadio).UnlinkButtons(this);
}
/// <summary>
/// Refreshes and shows the room's current source
/// </summary>
void RefreshSourceInfo()
{
var routeInfo = CurrentRoom.CurrentSourceInfo;
// This will show off popup too
if (this.IsVisible)
ShowCurrentSource();
if (routeInfo == null)// || !CurrentRoom.OnFeedback.BoolValue)
{
// Check for power off and insert "Room is off"
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "Room is off";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Power";
this.Hide();
Parent.Show();
return;
}
else if (CurrentRoom.CurrentSourceInfo != null)
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = routeInfo.PreferredName;
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = routeInfo.Icon; // defaults to "blank"
}
else
{
TriList.StringInput[UIStringJoin.CurrentSourceName].StringValue = "---";
TriList.StringInput[UIStringJoin.CurrentSourceIcon].StringValue = "Blank";
}
// Connect controls
if (routeInfo.SourceDevice != null)
ConnectControlDeviceMethods(routeInfo.SourceDevice);
}
/// <summary>
/// Attach the source to the buttons and things
/// </summary>
void ConnectControlDeviceMethods(Device dev)
{
if (dev is ISetTopBoxControls)
(dev as ISetTopBoxControls).LinkButtons(TriList);
if (dev is IChannel)
(dev as IChannel).LinkButtons(TriList);
if (dev is IColor)
(dev as IColor).LinkButtons(TriList);
if (dev is IDPad)
(dev as IDPad).LinkButtons(TriList);
if (dev is IDvr)
(dev as IDvr).LinkButtons(TriList);
if (dev is INumericKeypad)
(dev as INumericKeypad).LinkButtons(TriList);
if (dev is IPower)
(dev as IPower).LinkButtons(TriList);
if (dev is ITransport)
(dev as ITransport).LinkButtons(TriList);
}
/// <summary>
/// Detaches the buttons and feedback from the room's current audio device
/// </summary>
void ClearAudioDeviceConnections()
{
TriList.ClearBoolSigAction(UIBoolJoin.VolumeUpPress);
TriList.ClearBoolSigAction(UIBoolJoin.VolumeDownPress);
TriList.ClearBoolSigAction(UIBoolJoin.Volume1ProgramMutePressAndFB);
var fDev = CurrentRoom.CurrentVolumeControls as IBasicVolumeWithFeedback;
if (fDev != null)
{
TriList.ClearUShortSigAction(UIUshortJoin.VolumeSlider1Value);
fDev.VolumeLevelFeedback.UnlinkInputSig(
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value]);
}
}
/// <summary>
/// Attaches the buttons and feedback to the room's current audio device
/// </summary>
void RefreshAudioDeviceConnections()
{
var dev = CurrentRoom.CurrentVolumeControls;
if (dev != null) // connect buttons
{
TriList.SetBoolSigAction(UIBoolJoin.VolumeUpPress, VolumeUpPress);
TriList.SetBoolSigAction(UIBoolJoin.VolumeDownPress, VolumeDownPress);
TriList.SetSigFalseAction(UIBoolJoin.Volume1ProgramMutePressAndFB, dev.MuteToggle);
}
var fbDev = dev as IBasicVolumeWithFeedback;
if (fbDev == null) // this should catch both IBasicVolume and IBasicVolumeWithFeeback
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value].UShortValue = 0;
else
{
// slider
TriList.SetUShortSigAction(UIUshortJoin.VolumeSlider1Value, fbDev.SetVolume);
// feedbacks
fbDev.MuteFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.Volume1ProgramMutePressAndFB]);
fbDev.VolumeLevelFeedback.LinkInputSig(
TriList.UShortInput[UIUshortJoin.VolumeSlider1Value]);
}
}
/// <summary>
/// Handler for when the room's volume control device changes
/// </summary>
void CurrentRoom_CurrentAudioDeviceChange(object sender, VolumeDeviceChangeEventArgs args)
{
if (args.Type == ChangeType.WillChange)
ClearAudioDeviceConnections();
else // did change
RefreshAudioDeviceConnections();
}
/// <summary>
/// Handles source change
/// </summary>
void CurrentRoom_SourceInfoChange(EssentialsRoomBase room,
SourceListItem info, ChangeType change)
{
if (change == ChangeType.WillChange)
DisconnectSource(info);
else
RefreshSourceInfo();
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.UI;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials
{
/// <summary>
/// Very basic show/hide manager for weather page. Basic functionality is useful on any
/// size of interface
/// </summary>
public class SingleSubpageModalAndBackDriver : PanelDriverBase
{
BoolInputSig SubpageSig;
PanelDriverBase Parent;
public SingleSubpageModalAndBackDriver(PanelDriverBase parent, uint subpageJoin) : base(parent.TriList)
{
Parent = parent;
SubpageSig = Parent.TriList.BooleanInput[subpageJoin];
}
/// <summary>
/// This shows the driver.
/// Not sure I like this approach. Hides this and shows it's parent. Not really a navigation-stack type thing.
/// The parent is always the home page driver
/// </summary>
public override void Show()
{
SubpageSig.BoolValue = true;
base.Show();
}
public override void Hide()
{
SubpageSig.BoolValue = false;
base.Hide();
}
public override void BackButtonPressed()
{
Hide();
Parent.Show();
}
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.UI;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials
{
/// <summary>
/// Very basic show/hide manager for weather page. Basic functionality is useful on any
/// size of interface
/// </summary>
public class SingleSubpageModalDriver : PanelDriverBase
{
BoolInputSig SubpageSig;
public SingleSubpageModalDriver(PanelDriverBase parent, uint subpageJoin, uint closeJoin)
: base(parent.TriList)
{
SubpageSig = parent.TriList.BooleanInput[subpageJoin];
parent.TriList.SetSigFalseAction(closeJoin, Hide);
}
public override void Show()
{
SubpageSig.BoolValue = true;
base.Show();
}
public override void Hide()
{
SubpageSig.BoolValue = false;
base.Hide();
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.SmartObjects;
namespace PepperDash.Essentials
{
public class SmartObjectRoomsList : SmartObjectDynamicList
{
public uint StatusSigOffset { get; private set; }
List<SmartObjectRoomsListItem> Items;
public SmartObjectRoomsList(SmartObject so, uint nameSigOffset, uint statusSigOffset)
: base(so, true, nameSigOffset)
{
StatusSigOffset = statusSigOffset;
Items = new List<SmartObjectRoomsListItem>();
}
public void AddRoomItem(SmartObjectRoomsListItem item)
{
Items.Add(item);
}
public void SetItemStatusText(uint index, string text)
{
if (index > MaxCount) return;
// The list item template defines CIPS tags that refer to standard joins
(SmartObject.Device as BasicTriList).StringInput[StatusSigOffset + index].StringValue = text;
}
/// <summary>
/// Sets feedback for the given room
/// </summary>
public void SetFeedbackForRoom(EssentialsHuddleSpaceRoom room)
{
var itemToSet = Items.FirstOrDefault(i => i.Room == room);
if (itemToSet != null)
SetFeedback(itemToSet.Index, true);
}
}
public class SmartObjectRoomsListItem
{
public EssentialsHuddleSpaceRoom Room { get; private set; }
SmartObjectRoomsList Parent;
public uint Index { get; private set; }
public SmartObjectRoomsListItem(EssentialsHuddleSpaceRoom room, uint index, SmartObjectRoomsList parent,
Action<bool> buttonAction)
{
Room = room;
Parent = parent;
Index = index;
if (room == null) return;
// Set "now" states
parent.SetItemMainText(index, room.Name);
UpdateItem(room.CurrentSourceInfo);
// Watch for later changes
room.CurrentSingleSourceChange += new SourceInfoChangeHandler(room_CurrentSourceInfoChange);
parent.SetItemButtonAction(index, buttonAction);
}
void room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
{
UpdateItem(info);
}
/// <summary>
/// Helper to handle source events and startup syncing with room's current source
/// </summary>
/// <param name="info"></param>
void UpdateItem(SourceListItem info)
{
if (info == null || info.Type == eSourceListItemType.Off)
{
Parent.SetItemStatusText(Index, "");
Parent.SetItemIcon(Index, "Blank");
}
else
{
Parent.SetItemStatusText(Index, info.PreferredName);
Parent.SetItemIcon(Index, info.AltIcon);
}
}
}
}

View File

@@ -0,0 +1,381 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials
{
/// <summary>
/// Where all UI element common joins are defined
/// </summary>
public class UIBoolJoin
{
/// <summary>
/// 901
/// </summary>
public const uint VolumeUpPress = 901;
/// <summary>
/// 902
/// </summary>
public const uint VolumeDownPress = 902;
/// <summary>
/// 3811
/// </summary>
public const uint VolumeSingleMute1Visible = 3811;
/// <summary>
/// 3812
/// </summary>
public const uint VolumeSlider1Press = 3812;
/// <summary>
/// 3813
/// </summary>
public const uint Volume1ProgramMutePressAndFB = 3813;
/// <summary>
/// 3821
/// </summary>
public const uint Volume2Visible = 3821;
/// <summary>
/// 3822
/// </summary>
public const uint VolumeSlider2Press = 3822;
/// <summary>
/// 3823
/// </summary>
public const uint Volume2MutePressAndFB = 3823;
/// <summary>
/// 3831
/// </summary>
public const uint Volume3Visible = 3831;
/// <summary>
/// 3832
/// </summary>
public const uint VolumeSlider3Press = 3832;
/// <summary>
/// 3833
/// </summary>
public const uint Volume3MutePressAndFB = 3833;
/// <summary>
/// 3841
/// </summary>
public const uint Volume4Visible = 3841;
/// <summary>
/// 3842
/// </summary>
public const uint VolumeSlider4Press = 3842;
/// <summary>
/// 3843
/// </summary>
public const uint Volume4MutePressAndFB = 3843;
/// <summary>
/// 3851
/// </summary>
public const uint Volume5Visible = 3851;
/// <summary>
/// 3852
/// </summary>
public const uint VolumeSlider5Press = 3852;
/// <summary>
/// 3853
/// </summary>
public const uint Volume5MutePressAndFB = 3853;
/// <summary>
/// 3861
/// </summary>
public const uint Volume6Visible = 3861;
/// <summary>
/// 3862
/// </summary>
public const uint VolumeSlider6Press = 3862;
/// <summary>
/// 3863
/// </summary>
public const uint Volume6MutePressAndFB = 3863;
/// <summary>
/// 3870
/// </summary>
public const uint VolumesPageVisible = 3870;
/// <summary>
/// 3871
/// </summary>
public const uint VolumeDualMute1Visible = 3871;
/// <summary>
/// 3874
/// </summary>
public const uint Volume1SpeechMutePressAndFB = 3874;
/// <summary>
/// 3875
/// </summary>
public const uint Volume1BackerVisibility = 3875;
/// <summary>
/// 3891
/// </summary>
public const uint VolumeDefaultPress = 3891;
/// <summary>
/// 3901
/// </summary>
public const uint TechPagesExitButton = 3901;
/// <summary>
/// 3902
/// </summary>
public const uint TechPanelSetupVisible = 3902;
/// <summary>
/// 3999
/// </summary>
public const uint GenericModalVisible = 3999;
/// <summary>
/// 12345
/// </summary>
public const uint AvNoControlsSubVisible = 12345;
/// <summary>
/// 15001
/// </summary>
public const uint StartPageVisible = 15001;
/// <summary>
/// 15002 Shows the start page in the source controls area of the screen
/// </summary>
public const uint TapToBeginVisible = 15002;
/// <summary>
/// 15003 Message text when no source is showing
/// </summary>
public const uint SelectASourceVisible = 15003;
/// <summary>
/// 15004
/// </summary>
public const uint RoomIsOn = 15004;
/// <summary>
/// 15005 Shows always-on volume control subpage with only audio mute
/// </summary>
public const uint VolumeControlsSingleMuteVisible = 15005;
/// <summary>
/// 15006 Shows always-on volume control subpage with mic and audio mutes
/// </summary>
public const uint VolumeControlsDualMuteVisible = 15006;
/// <summary>
/// 15010
/// </summary>
public const uint ShowPanelSetupPress = 15010;
/// <summary>
/// 15011
/// </summary>
public const uint TopBarVisible = 15011;
/// <summary>
/// 15012
/// </summary>
public const uint StagingPageVisible = 15012;
/// <summary>
/// 15013
/// </summary>
public const uint PowerOffStep1Visible = 15013;
/// <summary>
/// 15014
/// </summary>
public const uint PowerOffStep2Visible = 15014;
/// <summary>
/// 15015
/// </summary>
public const uint ShowPowerOffPress = 15015;
/// <summary>
/// 15016
/// </summary>
public const uint PowerOffMorePress = 15016;
/// <summary>
/// 15017
/// </summary>
public const uint StagingPageAdditionalArrowsVisible = 15017;
/// <summary>
/// 15020
/// </summary>
public const uint PanelSetupVisible = 15020;
/// <summary>
/// 15021
/// </summary>
public const uint SourceWaitOverlayVisible = 15021;
/// <summary>
/// 15022
/// </summary>
public const uint ActivityFooterVisible = 15022;
/// <summary>
/// 15023
/// </summary>
public const uint LightsHeaderButtonVisible = 15023;
/// <summary>
/// 15024
/// </summary>
public const uint CallRightHeaderButtonVisible = 15024;
/// <summary>
/// 15025
/// </summary>
public const uint CallLeftHeaderButtonVisible = 15025;
/// <summary>
/// 15026
/// </summary>
public const uint LightsHeaderButtonPress = 15026;
/// <summary>
/// 15027
/// </summary>
public const uint CallHeaderButtonPress = 15027;
/// <summary>
/// 15028 The gear button in header
/// </summary>
public const uint GearHeaderButtonPress = 15028;
/// <summary>
/// 15029 the room button in header
/// </summary>
public const uint RoomHeaderButtonPress = 15029;
/// <summary>
/// 15030 Visibility for room data popup
/// </summary>
public const uint RoomHeaderPageVisible = 15030;
/// <summary>
/// 15031
/// </summary>
public const uint AllRoomsOffPress = 15031;
/// <summary>
/// 15032
/// </summary>
public const uint DisplayPowerTogglePress = 15032;
/// <summary>
/// 15033
/// </summary>
public const uint PowerOffCancelPress = 15033;
/// <summary>
/// 15034
/// </summary>
public const uint PowerOffConfirmPress = 15034;
/// <summary>
/// 15035
/// </summary>
public const uint VolumeButtonPopupPress = 15035;
/// <summary>
/// 15035
/// </summary>
public const uint VolumeButtonPopupVisible = 15035;
/// <summary>
/// 15036
/// </summary>
public const uint VolumeGaugePopupVisible = 15036;
/// <summary>
/// 15037
/// </summary>
public const uint GearButtonVisible = 15037;
/// <summary>
/// 15040
/// </summary>
public const uint CallStatusPageVisible = 15040;
/// <summary>
/// 15041
/// </summary>
public const uint LightsPageVisible = 15041;
/// <summary>
/// 15042 Closes whichever interlocked modal is open
/// </summary>
public const uint InterlockedModalClosePress = 15042;
/// <summary>
/// 15043 Vis for modal backer for full-screen source
/// </summary>
public const uint SourceBackgroundOverlayVisible = 15043;
/// <summary>
/// 15044 Close button for source modal overlay
/// </summary>
public const uint SourceBackgroundOverlayClosePress = 15044;
/// <summary>
/// 15051
/// </summary>
public const uint Display1SelectPressAndFb = 15051;
/// <summary>
/// 15052
/// </summary>
public const uint Display1ControlButtonEnable = 15052;
/// <summary>
/// 15053
/// </summary>
public const uint Display1ControlButtonPress = 15053;
/// <summary>
/// 15054
/// </summary>
public const uint Display1AudioButtonEnable = 15054;
/// <summary>
/// 15055
/// </summary>
public const uint Display1AudioButtonPressAndFb = 15055;
/// <summary>
/// 15056
/// </summary>
public const uint Display2SelectPressAndFb = 15056;
/// <summary>
/// 15057
/// </summary>
public const uint Display2ControlButtonEnable = 15057;
/// <summary>
/// 15058
/// </summary>
public const uint Display2ControlButtonPress = 15058;
/// <summary>
/// 15059
/// </summary>
public const uint Display2AudioButtonEnable = 15059;
/// <summary>
/// 15060
/// </summary>
public const uint Display2AudioButtonPressAndFb = 15060;
/// <summary>
/// 15061 Reveals the dual-display subpage
/// </summary>
public const uint DualDisplayPageVisible = 15061;
/// <summary>
/// 15062 Reveals the toggle switch for the sharing mode
/// </summary>
public const uint ToggleSharingModeVisible = 15062;
/// <summary>
/// 15063 Press for the toggle mode switch
/// </summary>
public const uint ToggleSharingModePress = 15063;
/// <summary>
/// 15064
/// </summary>
public const uint LogoDefaultVisible = 15064;
/// <summary>
/// 15065
/// </summary>
public const uint LogoUrlVisible = 15065;
/// <summary>
/// 15085 Visibility join for help subpage
/// </summary>
public const uint HelpPageVisible = 15085;
/// <summary>
/// 15086 Press for help header button
/// </summary>
public const uint HelpPress = 15086;
/// <summary>
/// 15088
/// </summary>
public const uint DateOnlyVisible = 15088;
/// <summary>
/// 15089
/// </summary>
public const uint TimeOnlyVisible = 15089;
/// <summary>
/// 15090
/// </summary>
public const uint DateAndTimeVisible = 15090;
/// <summary>
/// 15091
/// </summary>
public const uint SetupFullDistrib = 15091;
}
}

View File

@@ -0,0 +1,14 @@
namespace PepperDash.Essentials
{
public class UISmartObjectJoin
{
/// <summary>
/// 3200 The staging, source-select list
/// </summary>
public const uint StagingListSRL = 3200;
/// <summary>
/// 15022 The main activity footer
/// </summary>
public const uint ActivityFooterSRL = 15022;
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.DeviceSupport;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class UIStringJoin
{
/// <summary>
/// 3812
/// </summary>
public const uint AdvancedVolumeSlider1Text = 3812;
/// <summary>
/// 3822
/// </summary>
public const uint AdvancedVolumeSlider2Text = 3822;
/// <summary>
/// 3832
/// </summary>
public const uint AdvancedVolumeSlider3Text = 3832;
/// <summary>
/// 3842
/// </summary>
public const uint AdvancedVolumeSlider4Text = 3842;
/// <summary>
/// 3852
/// </summary>
public const uint AdvancedVolumeSlider5Text = 3852;
/// <summary>
/// 3862
/// </summary>
public const uint AdvancedVolumeSlider6Text = 3862;
/// <summary>
/// 3901
/// </summary>
public const uint CurrentRoomName = 3901;
/// <summary>
/// 3902
/// </summary>
public const uint CurrentSourceName = 3902;
/// <summary>
/// 3903
/// </summary>
public const uint CurrentSourceIcon = 3903;
/// <summary>
/// 3911
/// </summary>
public const uint PowerOffMessage = 3911;
/// <summary>
/// 3912
/// </summary>
public const uint StartPageMessage = 3912;
/// <summary>
/// 3913
/// </summary>
public const uint StartActivityText = 3913;
/// <summary>
/// 3914 Title bar label for source overlay
/// </summary>
public const uint SourceBackgroundOverlayTitle = 3914;
/// <summary>
/// 3922
/// </summary>
public const uint HelpMessage = 3922;
/// <summary>
/// 3923
/// </summary>
public const uint LogoUrl = 3923;
/// <summary>
/// 3961 Name of source on display 1
/// </summary>
public const uint Display1SourceLabel = 3961;
/// <summary>
/// 3962 Title above display 1
/// </summary>
public const uint Display1TitleLabel = 3962;
/// <summary>
/// 3964 Name of source on display 2
/// </summary>
public const uint Display2SourceLabel = 3964;
/// <summary>
/// 3965 Title above display 2
/// </summary>
public const uint Display2TitleLabel = 3965;
}
}

View File

@@ -0,0 +1,38 @@
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class UIUshortJoin
{
/// <summary>
/// 3812
/// </summary>
public const uint VolumeSlider1Value = 3812;
/// <summary>
/// 3822
/// </summary>
public const uint VolumeSlider2Value = 3822;
/// <summary>
/// 3832
/// </summary>
public const uint VolumeSlider3Value = 3832;
/// <summary>
/// 3842
/// </summary>
public const uint VolumeSlider4Value = 3842;
/// <summary>
/// 3852
/// </summary>
public const uint VolumeSlider5Value = 3852;
/// <summary>
/// 3862
/// </summary>
public const uint VolumeSlider6Value = 3862;
/// <summary>
/// 3922
/// </summary>
public const uint PresentationListCaretMode = 3922;
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
/// <summary>
///
/// </summary>
public class VolumeDeviceChangeEventArgs : EventArgs
{
public IBasicVolumeControls OldDev { get; private set; }
public IBasicVolumeControls NewDev { get; private set; }
public ChangeType Type { get; private set; }
public VolumeDeviceChangeEventArgs(IBasicVolumeControls oldDev, IBasicVolumeControls newDev, ChangeType type)
{
OldDev = oldDev;
NewDev = newDev;
Type = type;
}
}
/// <summary>
/// The handler type for a Room's SourceInfoChange
/// </summary>
public delegate void SourceInfoChangeHandler(EssentialsRoomBase room, SourceListItem info, ChangeType type);
/// <summary>
///
/// </summary>
public enum ChangeType
{
WillChange, DidChange
}
}

View File

@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using Crestron.SimplSharpPro.DeviceSupport;
using PepperDash.Essentials.Core;
namespace PepperDash.Essentials
{
public enum eAvSubpageType
{
NoControls,
PowerOff,
SetupFullDistributed,
SourceWaitOverlay,
TopBar,
VolumePopup,
ZoneSource
}
public enum eAvSourceSubpageType
{
AppleTv,
Radio,
Roku
}
public enum eCommonSubpageType
{
GenericModal,
Home,
PanelSetup,
Weather
}
public enum eAvSmartObjects
{
RoomList,
SourceList
}
public enum eCommonSmartObjects
{
HomePageList
}
/// <summary>
///
/// </summary>
public abstract class PanelDriverBase
{
/// <summary>
///
/// </summary>
public bool IsVisible { get; private set; }
public bool WasVisibleWhenHidden { get; private set; }
/// <summary>
/// Makes sure you call this.
/// Sets IsVisible and attaches back/home buttons to BackButtonPressed
/// </summary>
public virtual void Show()
{
IsVisible = true;
TriList.SetSigFalseAction(15002, BackButtonPressed);
}
/// <summary>
/// Will show if this was visible when Hide was called (for group hiding/showing)
/// </summary>
public void Restore()
{
if (WasVisibleWhenHidden)
Show();
}
/// <summary>
/// Only sets IsVisible
/// </summary>
public virtual void Hide()
{
WasVisibleWhenHidden = IsVisible;
IsVisible = false;
}
/// <summary>
/// Toggles visibility of this driver
/// </summary>
public void Toggle()
{
if (IsVisible)
Hide();
else
Show();
}
/// <summary>
/// Override with specific back button behavior. Default is empty
/// </summary>
public virtual void BackButtonPressed()
{
}
public PanelDriverBase(BasicTriListWithSmartObject triList)
{
TriList = triList;
}
#region IBasicTriListWithSmartObject Members
/// <summary>
///
/// </summary>
public void AddSmartObjectHelper(uint id, object controller)
{
SmartObjectControllers.Add(id, controller);
}
/// <summary>
///
/// </summary>
public void RemoveSmartObjectHelper(uint id)
{
SmartObjectControllers.Remove(id);
}
Dictionary<uint, object> SmartObjectControllers = new Dictionary<uint, object>();
/// <summary>
/// The trilist object for the Crestron TP device
/// </summary>
public BasicTriListWithSmartObject TriList { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool ContainsSmartObjectHelper(uint id)
{
return SmartObjectControllers.ContainsKey(id);
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public object GetSmartObjectHelper(uint id)
{
if (SmartObjectControllers.ContainsKey(id))
return SmartObjectControllers[id];
else
return null;
}
#endregion
}
}