mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-11 19:44:52 +00:00
NYU AV Driver start
This commit is contained in:
@@ -64,13 +64,20 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Sets an action to a held sig
|
||||
/// </summary>
|
||||
/// <param name="tl"></param>
|
||||
/// <param name="sigNum"></param>
|
||||
/// <param name="heldAction"></param>
|
||||
/// <returns></returns>
|
||||
/// <returns>The sig</returns>
|
||||
public static BoolOutputSig SetSigHeldAction(this BasicTriList tl, uint sigNum, uint heldMs, Action heldAction)
|
||||
{
|
||||
return SetSigHeldAction(tl, sigNum, heldMs, heldAction, null);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets an action to a held sig as well as a released-without-hold action
|
||||
/// </summary>
|
||||
/// <returns>The sig</returns>
|
||||
public static BoolOutputSig SetSigHeldAction(this BasicTriList tl, uint sigNum, uint heldMs, Action heldAction, Action releaseAction)
|
||||
{
|
||||
CTimer heldTimer = null;
|
||||
return tl.SetBoolSigAction(sigNum, press =>
|
||||
@@ -87,10 +94,12 @@ namespace PepperDash.Essentials.Core
|
||||
heldAction();
|
||||
}, heldMs);
|
||||
}
|
||||
|
||||
else if (heldTimer != null) // released
|
||||
{
|
||||
heldTimer.Stop();
|
||||
// could also revise this else to fire a released action as well as cancel the timer
|
||||
if (releaseAction != null)
|
||||
releaseAction();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,5 +152,13 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
return ClearSigAction(tl.StringOutput[sigNum]) as StringOutputSig;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to set the value of a bool Sig on tri list
|
||||
/// </summary>
|
||||
public static void SetBool(this BasicTriList tl, uint sigNum, bool value)
|
||||
{
|
||||
tl.BooleanInput[sigNum].BoolValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,10 +41,10 @@ namespace PepperDash.Essentials.Fusion
|
||||
StringSigData CurrentRoomSourceNameSig;
|
||||
|
||||
#region System Info Sigs
|
||||
StringSigData SystemName;
|
||||
StringSigData Model;
|
||||
StringSigData SerialNumber;
|
||||
StringSigData Uptime;
|
||||
//StringSigData SystemName;
|
||||
//StringSigData Model;
|
||||
//StringSigData SerialNumber;
|
||||
//StringSigData Uptime;
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -966,13 +966,13 @@ namespace PepperDash.Essentials.Fusion
|
||||
}
|
||||
// add xpanel here
|
||||
|
||||
if (dev is Crestron.SimplSharpPro.UI.XpanelForSmartGraphics)
|
||||
{
|
||||
if (attrNum > 10)
|
||||
continue;
|
||||
attrName = "Online - XPanel " + attrNum;
|
||||
attrNum += 160;
|
||||
}
|
||||
//if (dev is Crestron.SimplSharpPro.UI.XpanelForSmartGraphics)
|
||||
//{
|
||||
// if (attrNum > 10)
|
||||
// continue;
|
||||
// attrName = "Online - XPanel " + attrNum;
|
||||
// attrNum += 160;
|
||||
//}
|
||||
|
||||
//else
|
||||
if (dev is DisplayBase)
|
||||
|
||||
@@ -160,19 +160,21 @@
|
||||
<Compile Include="FOR REFERENCE UI\PageControllers\PageControllerLargeSetTopBoxGeneric.cs" />
|
||||
<Compile Include="FOR REFERENCE UI\PageControllers\LargeTouchpanelControllerBase.cs" />
|
||||
<Compile Include="FOR REFERENCE UI\Panels\SmartGraphicsTouchpanelControllerBase.cs" />
|
||||
<Compile Include="UI Drivers\VolumeAndSourceChangeArgs.cs" />
|
||||
<Compile Include="UI Drivers\UISmartObjectJoin.cs" />
|
||||
<Compile Include="UI Drivers\UIStringlJoin.cs" />
|
||||
<Compile Include="UI Drivers\UIUshortJoin.cs" />
|
||||
<Compile Include="UI Drivers\DualDisplayRouting.cs" />
|
||||
<Compile Include="UI Drivers\EssentialsPresentationPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UI Drivers\SingleSubpageModalDriver.cs" />
|
||||
<Compile Include="UI Drivers\EssentialsPanelMainInterfaceDriver.cs" />
|
||||
<Compile Include="UI Drivers\enums and base.cs" />
|
||||
<Compile Include="UI Drivers\EssentialsHuddlePanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UI Drivers\SingleSubpageModalAndBackDriver.cs" />
|
||||
<Compile Include="UI Drivers\SmartObjectRoomsList.cs" />
|
||||
<Compile Include="UI Drivers\UIBoolJoin.cs" />
|
||||
<Compile Include="UIDrivers\JoinedSigInterlock.cs" />
|
||||
<Compile Include="UIDrivers\NYU\NyuHuddleVTCPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\VolumeAndSourceChangeArgs.cs" />
|
||||
<Compile Include="UIDrivers\UISmartObjectJoin.cs" />
|
||||
<Compile Include="UIDrivers\UIStringlJoin.cs" />
|
||||
<Compile Include="UIDrivers\UIUshortJoin.cs" />
|
||||
<Compile Include="UIDrivers\DualDisplayRouting.cs" />
|
||||
<Compile Include="UIDrivers\Essentials\EssentialsPresentationPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\Page Drivers\SingleSubpageModalDriver.cs" />
|
||||
<Compile Include="UIDrivers\Essentials\EssentialsPanelMainInterfaceDriver.cs" />
|
||||
<Compile Include="UIDrivers\enums and base.cs" />
|
||||
<Compile Include="UIDrivers\Essentials\EssentialsHuddlePanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\Page Drivers\SingleSubpageModalAndBackDriver.cs" />
|
||||
<Compile Include="UIDrivers\SmartObjectRoomsList.cs" />
|
||||
<Compile Include="UIDrivers\UIBoolJoin.cs" />
|
||||
<Compile Include="Room\Cotija\CotijaSystemController.cs" />
|
||||
<Compile Include="Room\UI\DualDisplaySourceSRLController.cs" />
|
||||
<Compile Include="Room\UI\SubpageReferenceListActivityItem.cs" />
|
||||
@@ -187,6 +189,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="OTHER\" />
|
||||
<Folder Include="Room\Nyu\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class CrestronTouchpanelPropertiesConfig
|
||||
{
|
||||
public string IpId { get; set; }
|
||||
public string DefaultRoomKey { get; set; }
|
||||
public string RoomListKey { get; set; }
|
||||
public string SgdFile { get; set; }
|
||||
public string ProjectName { get; set; }
|
||||
public bool ShowVolumeGauge { get; set; }
|
||||
public bool UsesSplashPage { get; set; }
|
||||
public bool ShowDate { get; set; }
|
||||
public bool ShowTime { get; set; }
|
||||
public UiSetupPropertiesConfig Setup { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The count of sources that will trigger the "additional" arrows to show on the SRL.
|
||||
/// Defaults to 5
|
||||
/// </summary>
|
||||
public int SourcesOverflowCount { get; set; }
|
||||
|
||||
public CrestronTouchpanelPropertiesConfig()
|
||||
{
|
||||
SourcesOverflowCount = 5;
|
||||
}
|
||||
}
|
||||
|
||||
public class UiSetupPropertiesConfig
|
||||
{
|
||||
public bool IsVisible { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//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;
|
||||
|
||||
//namespace PepperDash.Essentials
|
||||
//{
|
||||
// public class DualDisplaySourceSRLController : SubpageReferenceList
|
||||
// {
|
||||
// public DualDisplaySourceSRLController(BasicTriListWithSmartObject triList,
|
||||
// uint smartObjectId, EssentialsPresentationRoom room)
|
||||
// : base(triList, smartObjectId, 3, 3, 3)
|
||||
// {
|
||||
// var srcList = room.s items.Values.ToList().OrderBy(s => s.Order);
|
||||
// foreach (var item in srcList)
|
||||
// {
|
||||
// GetBoolFeedbackSig(index, 1).UserObject = new Action<bool>(routeAction);
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTouchpanelController : Device
|
||||
{
|
||||
public BasicTriListWithSmartObject Panel { get; private set; }
|
||||
|
||||
public PanelDriverBase PanelDriver { get; private set; }
|
||||
|
||||
CTimer BacklightTransitionedOnTimer;
|
||||
|
||||
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
|
||||
string projectName, string sgdPath)
|
||||
: base(key, name)
|
||||
{
|
||||
Panel = tsw;
|
||||
tsw.LoadSmartObjects(sgdPath);
|
||||
tsw.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Tsw_SigChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config constructor
|
||||
/// </summary>
|
||||
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
|
||||
: base(key, name)
|
||||
{
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
Debug.Console(0, this, "post-activation linking");
|
||||
type = type.ToLower();
|
||||
try
|
||||
{
|
||||
if (type == "crestronapp")
|
||||
{
|
||||
var app = new CrestronApp(id, Global.ControlSystem);
|
||||
app.ParameterProjectName.Value = props.ProjectName;
|
||||
Panel = app;
|
||||
}
|
||||
else if (type == "tsw560")
|
||||
Panel = new Tsw560(id, Global.ControlSystem);
|
||||
else if (type == "tsw752")
|
||||
Panel = new Tsw752(id, Global.ControlSystem);
|
||||
else if (type == "tsw1052")
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserved sigs
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
tsw.ExtenderSystemReservedSigs.Use();
|
||||
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
|
||||
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
|
||||
}
|
||||
|
||||
new CTimer(o =>
|
||||
{
|
||||
var regSuccess = Panel.Register();
|
||||
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
|
||||
|
||||
// Give up cleanly if SGD is not present.
|
||||
var sgdName = @"\NVRAM\Program" + InitialParametersClass.ApplicationNumber
|
||||
+ @"\sgd\" + props.SgdFile;
|
||||
if (!File.Exists(sgdName))
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Smart object file '{0}' not present. Exiting TSW load", sgdName);
|
||||
return;
|
||||
}
|
||||
|
||||
Panel.LoadSmartObjects(sgdName);
|
||||
Panel.SigChange += Tsw_SigChange;
|
||||
|
||||
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, props);
|
||||
// Then the AV driver
|
||||
|
||||
// spin up different room drivers depending on room type
|
||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding huddle space driver");
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else if (room is EssentialsPresentationRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding presentation room driver");
|
||||
var avDriver = new EssentialsPresentationPanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsPresentationRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver);
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadAndShowDriver(PanelDriverBase driver)
|
||||
{
|
||||
PanelDriver = driver;
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
void HomePressed()
|
||||
{
|
||||
if (BacklightTransitionedOnTimer == null)
|
||||
PanelDriver.BackButtonPressed();
|
||||
}
|
||||
|
||||
|
||||
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||
{
|
||||
// If the sig is transitioning on, mark it in case it was home button that transitioned it
|
||||
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
|
||||
if (args.Sig == blOnSig && blOnSig.BoolValue)
|
||||
{
|
||||
BacklightTransitionedOnTimer = new CTimer(o =>
|
||||
{
|
||||
BacklightTransitionedOnTimer = null;
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
public void PulseBool(uint join)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<bool>;
|
||||
if (act != null)
|
||||
{
|
||||
act(true);
|
||||
act(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBoolSig(uint join, bool value)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<bool>;
|
||||
if (act != null)
|
||||
act(value);
|
||||
}
|
||||
|
||||
public void SetIntSig(uint join, ushort value)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<ushort>;
|
||||
if (act != null)
|
||||
{
|
||||
act(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Tsw_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
var uo = args.Sig.UserObject;
|
||||
if (uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||
else if (uo is Action<ushort>)
|
||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||
else if (uo is Action<string>)
|
||||
(uo as Action<string>)(args.Sig.StringValue);
|
||||
}
|
||||
|
||||
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
||||
{
|
||||
var uo = args.Button.UserObject;
|
||||
if(uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class SubpageReferenceListActivityItem : SubpageReferenceListItem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="owner"></param>
|
||||
/// <param name="buttonMode">0=Share, 1=Phone Call, 2=Video Call, 3=End Meeting</param>
|
||||
/// <param name="pressAction"></param>
|
||||
public SubpageReferenceListActivityItem(uint index, SubpageReferenceList owner,
|
||||
ushort buttonMode, Action<bool> pressAction)
|
||||
: base(index, owner)
|
||||
{
|
||||
Owner.GetBoolFeedbackSig(Index, 1).UserObject = pressAction;
|
||||
Owner.UShortInputSig(Index, 1).UShortValue = buttonMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by SRL to release all referenced objects
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).UserObject = null;
|
||||
Owner.UShortInputSig(Index, 1).UShortValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class SubpageReferenceListSourceItem : SubpageReferenceListItem
|
||||
{
|
||||
public SourceListItem SourceItem { get; private set; }
|
||||
|
||||
public SubpageReferenceListSourceItem(uint index, SubpageReferenceList owner,
|
||||
SourceListItem sourceItem, Action<bool> routeAction)
|
||||
: base(index, owner)
|
||||
{
|
||||
SourceItem = sourceItem;
|
||||
owner.GetBoolFeedbackSig(index, 1).UserObject = new Action<bool>(routeAction);
|
||||
owner.StringInputSig(index, 1).StringValue = SourceItem.PreferredName;
|
||||
}
|
||||
|
||||
public void RegisterForSourceChange(IHasCurrentSourceInfoChange room)
|
||||
{
|
||||
room.CurrentSingleSourceChange -= room_CurrentSourceInfoChange;
|
||||
room.CurrentSingleSourceChange += room_CurrentSourceInfoChange;
|
||||
}
|
||||
|
||||
void room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
{
|
||||
if (type == ChangeType.WillChange && info == SourceItem)
|
||||
ClearFeedback();
|
||||
else if (type == ChangeType.DidChange && info == SourceItem)
|
||||
SetFeedback();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by SRL to release all referenced objects
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).UserObject = null;
|
||||
Owner.StringInputSig(Index, 1).StringValue = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the selected feedback on the button
|
||||
/// </summary>
|
||||
public void SetFeedback()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).BoolValue = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the selected feedback on the button
|
||||
/// </summary>
|
||||
public void ClearFeedback()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).BoolValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,19 +34,6 @@ namespace PepperDash.Essentials
|
||||
/// 3813
|
||||
/// </summary>
|
||||
public const uint Volume1ProgramMutePressAndFB = 3813;
|
||||
/// <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>
|
||||
/// 3821
|
||||
/// </summary>
|
||||
@@ -113,6 +100,22 @@ namespace PepperDash.Essentials
|
||||
/// </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;
|
||||
@@ -0,0 +1,98 @@
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{225C9CD0-1AA9-464C-A3A2-2117EE45A87E}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>EssentialsHuddleWorkflow</RootNamespace>
|
||||
<AssemblyName>EssentialsHuddleWorkflow</AssemblyName>
|
||||
<ProjectTypeGuids>{0B4745B0-194B-4BB6-8E21-E9057CA92300};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PlatformFamilyName>WindowsCE</PlatformFamilyName>
|
||||
<PlatformID>E2BECB1F-8C8C-41ba-B736-9BE7D946A398</PlatformID>
|
||||
<OSVersion>5.0</OSVersion>
|
||||
<DeployDirSuffix>SmartDeviceProject1</DeployDirSuffix>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<NativePlatformName>Windows CE</NativePlatformName>
|
||||
<FormFactorID>
|
||||
</FormFactorID>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<AllowedReferenceRelatedFileExtensions>.allowedReferenceRelatedFileExtensions</AllowedReferenceRelatedFileExtensions>
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<NoStdLib>true</NoStdLib>
|
||||
<NoConfig>true</NoConfig>
|
||||
<GenerateSerializationAssemblies>off</GenerateSerializationAssemblies>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="mscorlib" />
|
||||
<Reference Include="PepperDashEssentials, Version=1.0.0.17548, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\Essentials\PepperDashEssentials\bin\PepperDashEssentials.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PepperDash_Core, Version=1.0.1.13851, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\pepperdash-simplsharp-core\Pepperdash Core\CLZ Builds\PepperDash_Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PepperDash_Essentials_Core, Version=1.0.0.19088, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\Essentials Core\PepperDashEssentialsBase\bin\PepperDash_Essentials_Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpCustomAttributesInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpHelperInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="SimplSharpPro, Version=1.5.3.17, Culture=neutral, PublicKeyToken=1099c178b3b54c3b, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Room\EssentialsHuddleSpaceRoom.cs" />
|
||||
<Compile Include="UI\DualDisplaySourceSRLController.cs" />
|
||||
<Compile Include="UI\EssentialsTouchpanelController.cs" />
|
||||
<Compile Include="UI\SubpageReferenceListActivityItem.cs" />
|
||||
<Compile Include="UI\SubpageReferenceListSourceItem.cs" />
|
||||
<None Include="Properties\ControlSystem.cfg" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Config\" />
|
||||
<Folder Include="Initialize\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>rem S# Pro preparation will execute after these operations</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyTitle("EssentialsHuddleWorkflow")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("EssentialsHuddleWorkflow")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyVersion("1.0.0.*")]
|
||||
|
||||
@@ -0,0 +1,420 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.EssentialsHuddleWorkflow
|
||||
{
|
||||
public class EssentialsHuddleSpaceRoom : EssentialsRoomBase, IHasCurrentSourceInfoChange
|
||||
{
|
||||
public event EventHandler<VolumeDeviceChangeEventArgs> CurrentVolumeDeviceChange;
|
||||
public event SourceInfoChangeHandler CurrentSingleSourceChange;
|
||||
|
||||
protected override Func<bool> OnFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
var val = CurrentSourceInfo != null
|
||||
&& CurrentSourceInfo.Type == eSourceListItemType.Route
|
||||
&& disp != null
|
||||
&& disp.PowerIsOnFeedback.BoolValue;
|
||||
return val;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsWarmingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsWarmingUpFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected override Func<bool> IsCoolingFeedbackFunc
|
||||
{
|
||||
get
|
||||
{
|
||||
return () =>
|
||||
{
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
return disp.IsCoolingDownFeedback.BoolValue;
|
||||
else
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public EssentialsRoomPropertiesConfig Config { get; private set; }
|
||||
|
||||
public IRoutingSinkWithSwitching DefaultDisplay { get; private set; }
|
||||
public IRoutingSinkNoSwitching DefaultAudioDevice { get; private set; }
|
||||
public IBasicVolumeControls DefaultVolumeControls { get; private set; }
|
||||
|
||||
public bool ExcludeFromGlobalFunctions { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The config name of the source list
|
||||
/// </summary>
|
||||
public string SourceListKey { get; set; }
|
||||
|
||||
public string DefaultSourceItem { get; set; }
|
||||
|
||||
public ushort DefaultVolume { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If room is off, enables power on to last source. Default true
|
||||
/// </summary>
|
||||
public bool EnablePowerOnToLastSource { get; set; }
|
||||
string LastSourceKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public IBasicVolumeControls CurrentVolumeControls
|
||||
{
|
||||
get { return _CurrentAudioDevice; }
|
||||
set
|
||||
{
|
||||
if (value == _CurrentAudioDevice) return;
|
||||
|
||||
var oldDev = _CurrentAudioDevice;
|
||||
// derigister this room from the device, if it can
|
||||
if (oldDev is IInUseTracking)
|
||||
(oldDev as IInUseTracking).InUseTracker.RemoveUser(this, "audio");
|
||||
var handler = CurrentVolumeDeviceChange;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.WillChange));
|
||||
_CurrentAudioDevice = value;
|
||||
if (handler != null)
|
||||
CurrentVolumeDeviceChange(this, new VolumeDeviceChangeEventArgs(oldDev, value, ChangeType.DidChange));
|
||||
// register this room with new device, if it can
|
||||
if (_CurrentAudioDevice is IInUseTracking)
|
||||
(_CurrentAudioDevice as IInUseTracking).InUseTracker.AddUser(this, "audio");
|
||||
}
|
||||
}
|
||||
IBasicVolumeControls _CurrentAudioDevice;
|
||||
|
||||
/// <summary>
|
||||
/// The SourceListItem last run - containing names and icons
|
||||
/// </summary>
|
||||
public SourceListItem CurrentSourceInfo
|
||||
{
|
||||
get { return _CurrentSourceInfo; }
|
||||
private set
|
||||
{
|
||||
if (value == _CurrentSourceInfo) return;
|
||||
|
||||
var handler = CurrentSingleSourceChange;
|
||||
// remove from in-use tracker, if so equipped
|
||||
if(_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.RemoveUser(this, "control");
|
||||
|
||||
if (handler != null)
|
||||
handler(this, _CurrentSourceInfo, ChangeType.WillChange);
|
||||
|
||||
_CurrentSourceInfo = value;
|
||||
|
||||
// add to in-use tracking
|
||||
if (_CurrentSourceInfo != null && _CurrentSourceInfo.SourceDevice is IInUseTracking)
|
||||
(_CurrentSourceInfo.SourceDevice as IInUseTracking).InUseTracker.AddUser(this, "control");
|
||||
if (handler != null)
|
||||
handler(this, _CurrentSourceInfo, ChangeType.DidChange);
|
||||
}
|
||||
}
|
||||
SourceListItem _CurrentSourceInfo;
|
||||
|
||||
public string CurrentSourceInfoKey { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="name"></param>
|
||||
public EssentialsHuddleSpaceRoom(string key, string name, IRoutingSinkWithSwitching defaultDisplay,
|
||||
IRoutingSinkNoSwitching defaultAudio, EssentialsRoomPropertiesConfig config)
|
||||
: base(key, name)
|
||||
{
|
||||
Config = config;
|
||||
DefaultDisplay = defaultDisplay;
|
||||
DefaultAudioDevice = defaultAudio;
|
||||
if (defaultAudio is IBasicVolumeControls)
|
||||
DefaultVolumeControls = defaultAudio as IBasicVolumeControls;
|
||||
else if (defaultAudio is IHasVolumeDevice)
|
||||
DefaultVolumeControls = (defaultAudio as IHasVolumeDevice).VolumeDevice;
|
||||
CurrentVolumeControls = DefaultVolumeControls;
|
||||
|
||||
var disp = DefaultDisplay as DisplayBase;
|
||||
if (disp != null)
|
||||
{
|
||||
// Link power, warming, cooling to display
|
||||
disp.PowerIsOnFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
if (disp.PowerIsOnFeedback.BoolValue != OnFeedback.BoolValue)
|
||||
{
|
||||
if (!disp.PowerIsOnFeedback.BoolValue)
|
||||
CurrentSourceInfo = null;
|
||||
OnFeedback.FireUpdate();
|
||||
}
|
||||
};
|
||||
|
||||
disp.IsWarmingUpFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsWarmingUpFeedback.FireUpdate();
|
||||
if (!IsWarmingUpFeedback.BoolValue)
|
||||
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
disp.IsCoolingDownFeedback.OutputChange += (o, a) =>
|
||||
{
|
||||
IsCoolingDownFeedback.FireUpdate();
|
||||
if (IsCoolingDownFeedback.BoolValue)
|
||||
(DefaultDisplay as IBasicVolumeWithFeedback).SetVolume(DefaultVolume);
|
||||
};
|
||||
}
|
||||
|
||||
SourceListKey = "default";
|
||||
EnablePowerOnToLastSource = true;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Shutdown()
|
||||
{
|
||||
RunRouteAction("roomOff");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Routes the default source item, if any
|
||||
/// </summary>
|
||||
public void RunDefaultRoute()
|
||||
{
|
||||
if (DefaultSourceItem != null)
|
||||
RunRouteAction(DefaultSourceItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="routeKey"></param>
|
||||
public void RunRouteAction(string routeKey)
|
||||
{
|
||||
RunRouteAction(routeKey, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a source from config list SourceListKey and dynamically build and executes the
|
||||
/// route or commands
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public void RunRouteAction(string routeKey, Action successCallback)
|
||||
{
|
||||
// Run this on a separate thread
|
||||
new CTimer(o =>
|
||||
{
|
||||
Debug.Console(1, this, "Run route action '{0}'", routeKey);
|
||||
var dict = ConfigReader.ConfigObject.GetSourceListForKey(SourceListKey);
|
||||
if(dict == null)
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: Config source list '{0}' not found", SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to get the list item by it's string key
|
||||
if (!dict.ContainsKey(routeKey))
|
||||
{
|
||||
Debug.Console(1, this, "WARNING: No item '{0}' found on config list '{1}'",
|
||||
routeKey, SourceListKey);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = dict[routeKey];
|
||||
//Debug.Console(2, this, "Action {0} has {1} steps",
|
||||
// item.SourceKey, item.RouteList.Count);
|
||||
|
||||
// End usage timer on last source
|
||||
if (!string.IsNullOrEmpty(LastSourceKey))
|
||||
{
|
||||
var lastSource = dict[LastSourceKey].SourceDevice;
|
||||
|
||||
try
|
||||
{
|
||||
if (lastSource != null && lastSource is IUsageTracking)
|
||||
(lastSource as IUsageTracking).UsageTracker.EndDeviceUsage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(1, this, "*#* EXCEPTION in end usage tracking (257):\r{0}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Let's run it
|
||||
if (routeKey.ToLower() != "roomoff")
|
||||
{
|
||||
LastSourceKey = routeKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentSourceInfoKey = null;
|
||||
}
|
||||
|
||||
foreach (var route in item.RouteList)
|
||||
{
|
||||
// if there is a $defaultAll on route, run two separate
|
||||
if (route.DestinationKey.Equals("$defaultAll", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// Going to assume a single-path route for now
|
||||
var tempVideo = new SourceRouteListItem
|
||||
{
|
||||
DestinationKey = "$defaultDisplay",
|
||||
SourceKey = route.SourceKey,
|
||||
Type = eRoutingSignalType.Video
|
||||
};
|
||||
DoRoute(tempVideo);
|
||||
|
||||
//var tempAudio = new SourceRouteListItem
|
||||
//{
|
||||
// DestinationKey = "$defaultAudio",
|
||||
// SourceKey = route.SourceKey,
|
||||
// Type = eRoutingSignalType.Audio
|
||||
//};
|
||||
//DoRoute(tempAudio);
|
||||
//continue; -- not sure why this was here
|
||||
}
|
||||
else
|
||||
DoRoute(route);
|
||||
}
|
||||
|
||||
// Start usage timer on routed source
|
||||
if (item.SourceDevice is IUsageTracking)
|
||||
{
|
||||
(item.SourceDevice as IUsageTracking).UsageTracker.StartDeviceUsage();
|
||||
}
|
||||
|
||||
|
||||
// Set volume control on room, using default if non provided
|
||||
IBasicVolumeControls volDev = null;
|
||||
// Handle special cases for volume control
|
||||
if (string.IsNullOrEmpty(item.VolumeControlKey)
|
||||
|| item.VolumeControlKey.Equals("$defaultAudio", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultVolumeControls;
|
||||
else if (item.VolumeControlKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
volDev = DefaultDisplay as IBasicVolumeControls;
|
||||
// Or a specific device, probably rarely used.
|
||||
else
|
||||
{
|
||||
var dev = DeviceManager.GetDeviceForKey(item.VolumeControlKey);
|
||||
if (dev is IBasicVolumeControls)
|
||||
volDev = dev as IBasicVolumeControls;
|
||||
else if (dev is IHasVolumeDevice)
|
||||
volDev = (dev as IHasVolumeDevice).VolumeDevice;
|
||||
}
|
||||
CurrentVolumeControls = volDev;
|
||||
|
||||
// store the name and UI info for routes
|
||||
if (item.SourceKey == "$off")
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = null;
|
||||
}
|
||||
else if (item.SourceKey != null)
|
||||
{
|
||||
CurrentSourceInfoKey = routeKey;
|
||||
CurrentSourceInfo = item;
|
||||
}
|
||||
// And finally, set the "control". This will trigger event
|
||||
//CurrentControlDevice = DeviceManager.GetDeviceForKey(item.SourceKey) as Device;
|
||||
|
||||
OnFeedback.FireUpdate();
|
||||
|
||||
// report back when done
|
||||
if (successCallback != null)
|
||||
successCallback();
|
||||
|
||||
}, 0); // end of CTimer
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will power the room on with the last-used source
|
||||
/// </summary>
|
||||
public void PowerOnToDefaultOrLastSource()
|
||||
{
|
||||
if (!EnablePowerOnToLastSource || LastSourceKey == null)
|
||||
return;
|
||||
RunRouteAction(LastSourceKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="route"></param>
|
||||
/// <returns></returns>
|
||||
bool DoRoute(SourceRouteListItem route)
|
||||
{
|
||||
IRoutingSinkNoSwitching dest = null;
|
||||
|
||||
if (route.DestinationKey.Equals("$defaultaudio", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultAudioDevice;
|
||||
else if (route.DestinationKey.Equals("$defaultDisplay", StringComparison.OrdinalIgnoreCase))
|
||||
dest = DefaultDisplay;
|
||||
else
|
||||
dest = DeviceManager.GetDeviceForKey(route.DestinationKey) as IRoutingSinkNoSwitching;
|
||||
|
||||
if (dest == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route, unknown destination '{0}'", route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (route.SourceKey.Equals("$off", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
dest.ReleaseRoute();
|
||||
if (dest is IPower)
|
||||
(dest as IPower).PowerOff();
|
||||
}
|
||||
else
|
||||
{
|
||||
var source = DeviceManager.GetDeviceForKey(route.SourceKey) as IRoutingOutputs;
|
||||
if (source == null)
|
||||
{
|
||||
Debug.Console(1, this, "Cannot route unknown source '{0}' to {1}", route.SourceKey, route.DestinationKey);
|
||||
return false;
|
||||
}
|
||||
dest.ReleaseAndMakeRoute(source, route.Type);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs "roomOff" action on all rooms not set to ExcludeFromGlobalFunctions
|
||||
/// </summary>
|
||||
public static void AllRoomsOff()
|
||||
{
|
||||
var allRooms = DeviceManager.AllDevices.Where(d =>
|
||||
d is EssentialsHuddleSpaceRoom && !(d as EssentialsHuddleSpaceRoom).ExcludeFromGlobalFunctions);
|
||||
foreach (var room in allRooms)
|
||||
(room as EssentialsHuddleSpaceRoom).RunRouteAction("roomOff");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
//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;
|
||||
|
||||
//namespace PepperDash.Essentials
|
||||
//{
|
||||
// public class DualDisplaySourceSRLController : SubpageReferenceList
|
||||
// {
|
||||
// public DualDisplaySourceSRLController(BasicTriListWithSmartObject triList,
|
||||
// uint smartObjectId, EssentialsPresentationRoom room)
|
||||
// : base(triList, smartObjectId, 3, 3, 3)
|
||||
// {
|
||||
// var srcList = room.s items.Values.ToList().OrderBy(s => s.Order);
|
||||
// foreach (var item in srcList)
|
||||
// {
|
||||
// GetBoolFeedbackSig(index, 1).UserObject = new Action<bool>(routeAction);
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharp.CrestronIO;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
using PepperDash.Core;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.PageManagers;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class EssentialsTouchpanelController : Device
|
||||
{
|
||||
public BasicTriListWithSmartObject Panel { get; private set; }
|
||||
|
||||
public PanelDriverBase PanelDriver { get; private set; }
|
||||
|
||||
CTimer BacklightTransitionedOnTimer;
|
||||
|
||||
public EssentialsTouchpanelController(string key, string name, Tswx52ButtonVoiceControl tsw,
|
||||
string projectName, string sgdPath)
|
||||
: base(key, name)
|
||||
{
|
||||
Panel = tsw;
|
||||
tsw.LoadSmartObjects(sgdPath);
|
||||
tsw.SigChange += new Crestron.SimplSharpPro.DeviceSupport.SigEventHandler(Tsw_SigChange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Config constructor
|
||||
/// </summary>
|
||||
public EssentialsTouchpanelController(string key, string name, string type, CrestronTouchpanelPropertiesConfig props, uint id)
|
||||
: base(key, name)
|
||||
{
|
||||
AddPostActivationAction(() =>
|
||||
{
|
||||
Debug.Console(0, this, "post-activation linking");
|
||||
type = type.ToLower();
|
||||
try
|
||||
{
|
||||
if (type == "crestronapp")
|
||||
{
|
||||
var app = new CrestronApp(id, Global.ControlSystem);
|
||||
app.ParameterProjectName.Value = props.ProjectName;
|
||||
Panel = app;
|
||||
}
|
||||
else if (type == "tsw560")
|
||||
Panel = new Tsw560(id, Global.ControlSystem);
|
||||
else if (type == "tsw752")
|
||||
Panel = new Tsw752(id, Global.ControlSystem);
|
||||
else if (type == "tsw1052")
|
||||
Panel = new Tsw1052(id, Global.ControlSystem);
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW controller with type '{0}'", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Cannot create TSW base class. Panel will not function: {0}", e.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserved sigs
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
tsw.ExtenderSystemReservedSigs.Use();
|
||||
tsw.ExtenderSystemReservedSigs.DeviceExtenderSigChange
|
||||
+= ExtenderSystemReservedSigs_DeviceExtenderSigChange;
|
||||
}
|
||||
|
||||
new CTimer(o =>
|
||||
{
|
||||
var regSuccess = Panel.Register();
|
||||
if (regSuccess != eDeviceRegistrationUnRegistrationResponse.Success)
|
||||
Debug.Console(0, this, "WARNING: Registration failed. Continuing, but panel may not function: {0}", regSuccess);
|
||||
|
||||
// Give up cleanly if SGD is not present.
|
||||
var sgdName = @"\NVRAM\Program" + InitialParametersClass.ApplicationNumber
|
||||
+ @"\sgd\" + props.SgdFile;
|
||||
if (!File.Exists(sgdName))
|
||||
{
|
||||
Debug.Console(0, this, "WARNING: Smart object file '{0}' not present. Exiting TSW load", sgdName);
|
||||
return;
|
||||
}
|
||||
|
||||
Panel.LoadSmartObjects(sgdName);
|
||||
Panel.SigChange += Tsw_SigChange;
|
||||
|
||||
var mainDriver = new EssentialsPanelMainInterfaceDriver(Panel, props);
|
||||
// Then the AV driver
|
||||
|
||||
// spin up different room drivers depending on room type
|
||||
var room = DeviceManager.GetDeviceForKey(props.DefaultRoomKey);
|
||||
if (room is EssentialsHuddleSpaceRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding huddle space driver");
|
||||
var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver); // This is a little convoluted.
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else if (room is EssentialsPresentationRoom)
|
||||
{
|
||||
Debug.Console(0, this, "Adding presentation room driver");
|
||||
var avDriver = new EssentialsPresentationPanelAvFunctionsDriver(mainDriver, props);
|
||||
avDriver.CurrentRoom = room as EssentialsPresentationRoom;
|
||||
avDriver.DefaultRoomKey = props.DefaultRoomKey;
|
||||
mainDriver.AvDriver = avDriver;
|
||||
LoadAndShowDriver(mainDriver);
|
||||
|
||||
if (Panel is TswFt5ButtonSystem)
|
||||
{
|
||||
var tsw = Panel as TswFt5ButtonSystem;
|
||||
// Wire up hard keys
|
||||
tsw.Power.UserObject = new Action<bool>(b => { if (!b) avDriver.PowerButtonPressed(); });
|
||||
//tsw.Home.UserObject = new Action<bool>(b => { if (!b) HomePressed(); });
|
||||
tsw.Up.UserObject = new Action<bool>(avDriver.VolumeUpPress);
|
||||
tsw.Down.UserObject = new Action<bool>(avDriver.VolumeDownPress);
|
||||
tsw.ButtonStateChange += new ButtonEventHandler(Tsw_ButtonStateChange);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Console(0, this, "ERROR: Cannot load AvFunctionsDriver for room '{0}'", props.DefaultRoomKey);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
public void LoadAndShowDriver(PanelDriverBase driver)
|
||||
{
|
||||
PanelDriver = driver;
|
||||
driver.Show();
|
||||
}
|
||||
|
||||
void HomePressed()
|
||||
{
|
||||
if (BacklightTransitionedOnTimer == null)
|
||||
PanelDriver.BackButtonPressed();
|
||||
}
|
||||
|
||||
|
||||
void ExtenderSystemReservedSigs_DeviceExtenderSigChange(DeviceExtender currentDeviceExtender, SigEventArgs args)
|
||||
{
|
||||
// If the sig is transitioning on, mark it in case it was home button that transitioned it
|
||||
var blOnSig = (Panel as TswFt5ButtonSystem).ExtenderSystemReservedSigs.BacklightOnFeedback;
|
||||
if (args.Sig == blOnSig && blOnSig.BoolValue)
|
||||
{
|
||||
BacklightTransitionedOnTimer = new CTimer(o =>
|
||||
{
|
||||
BacklightTransitionedOnTimer = null;
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
|
||||
public void PulseBool(uint join)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<bool>;
|
||||
if (act != null)
|
||||
{
|
||||
act(true);
|
||||
act(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBoolSig(uint join, bool value)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<bool>;
|
||||
if (act != null)
|
||||
act(value);
|
||||
}
|
||||
|
||||
public void SetIntSig(uint join, ushort value)
|
||||
{
|
||||
var act = Panel.BooleanInput[join].UserObject as Action<ushort>;
|
||||
if (act != null)
|
||||
{
|
||||
act(value);
|
||||
}
|
||||
}
|
||||
|
||||
void Tsw_SigChange(object currentDevice, Crestron.SimplSharpPro.SigEventArgs args)
|
||||
{
|
||||
if (Debug.Level == 2)
|
||||
Debug.Console(2, this, "Sig change: {0} {1}={2}", args.Sig.Type, args.Sig.Number, args.Sig.StringValue);
|
||||
var uo = args.Sig.UserObject;
|
||||
if (uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Sig.BoolValue);
|
||||
else if (uo is Action<ushort>)
|
||||
(uo as Action<ushort>)(args.Sig.UShortValue);
|
||||
else if (uo is Action<string>)
|
||||
(uo as Action<string>)(args.Sig.StringValue);
|
||||
}
|
||||
|
||||
void Tsw_ButtonStateChange(GenericBase device, ButtonEventArgs args)
|
||||
{
|
||||
var uo = args.Button.UserObject;
|
||||
if(uo is Action<bool>)
|
||||
(uo as Action<bool>)(args.Button.State == eButtonState.Pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class SubpageReferenceListActivityItem : SubpageReferenceListItem
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="owner"></param>
|
||||
/// <param name="buttonMode">0=Share, 1=Phone Call, 2=Video Call, 3=End Meeting</param>
|
||||
/// <param name="pressAction"></param>
|
||||
public SubpageReferenceListActivityItem(uint index, SubpageReferenceList owner,
|
||||
ushort buttonMode, Action<bool> pressAction)
|
||||
: base(index, owner)
|
||||
{
|
||||
Owner.GetBoolFeedbackSig(Index, 1).UserObject = pressAction;
|
||||
Owner.UShortInputSig(Index, 1).UShortValue = buttonMode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by SRL to release all referenced objects
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).UserObject = null;
|
||||
Owner.UShortInputSig(Index, 1).UShortValue = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro;
|
||||
using Crestron.SimplSharpPro.UI;
|
||||
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
public class SubpageReferenceListSourceItem : SubpageReferenceListItem
|
||||
{
|
||||
public SourceListItem SourceItem { get; private set; }
|
||||
|
||||
public SubpageReferenceListSourceItem(uint index, SubpageReferenceList owner,
|
||||
SourceListItem sourceItem, Action<bool> routeAction)
|
||||
: base(index, owner)
|
||||
{
|
||||
SourceItem = sourceItem;
|
||||
owner.GetBoolFeedbackSig(index, 1).UserObject = new Action<bool>(routeAction);
|
||||
owner.StringInputSig(index, 1).StringValue = SourceItem.PreferredName;
|
||||
}
|
||||
|
||||
public void RegisterForSourceChange(IHasCurrentSourceInfoChange room)
|
||||
{
|
||||
room.CurrentSingleSourceChange -= room_CurrentSourceInfoChange;
|
||||
room.CurrentSingleSourceChange += room_CurrentSourceInfoChange;
|
||||
}
|
||||
|
||||
void room_CurrentSourceInfoChange(EssentialsRoomBase room, SourceListItem info, ChangeType type)
|
||||
{
|
||||
if (type == ChangeType.WillChange && info == SourceItem)
|
||||
ClearFeedback();
|
||||
else if (type == ChangeType.DidChange && info == SourceItem)
|
||||
SetFeedback();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called by SRL to release all referenced objects
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).UserObject = null;
|
||||
Owner.StringInputSig(Index, 1).StringValue = "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the selected feedback on the button
|
||||
/// </summary>
|
||||
public void SetFeedback()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).BoolValue = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the selected feedback on the button
|
||||
/// </summary>
|
||||
public void ClearFeedback()
|
||||
{
|
||||
Owner.BoolInputSig(Index, 1).BoolValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user