mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-01 22:04:52 +00:00
PageDriver for VtcHuddle AV funcs; PageDriver for Spark
This commit is contained in:
@@ -53,7 +53,7 @@ namespace PepperDash.Essentials.Core
|
||||
// Fail cleanly if not defined
|
||||
if (triList.SmartObjects == null || triList.SmartObjects.Count == 0)
|
||||
{
|
||||
Debug.Console(0, "TriList {0:X2} Smart objects not loaded", triList.ID, smartObjectId);
|
||||
Debug.Console(0, "TriList {0:X2} Smart objects have not been loaded", triList.ID, smartObjectId);
|
||||
return;
|
||||
}
|
||||
if (triList.SmartObjects.TryGetValue(smartObjectId, out obj))
|
||||
@@ -74,7 +74,8 @@ namespace PepperDash.Essentials.Core
|
||||
SRL.SigChange += new SmartObjectSigChangeEventHandler(SRL_SigChange);
|
||||
}
|
||||
else
|
||||
Debug.Console(0, "TriList 0x{0:X2} Cannot load smart object {1}", triList.ID, smartObjectId);
|
||||
Debug.Console(0, "ERROR: TriList 0x{0:X2} Cannot load smart object {1}. Verify correct SGD file is loaded",
|
||||
triList.ID, smartObjectId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -154,11 +154,19 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to set the value of a bool Sig on tri list
|
||||
/// Helper method to set the value of a bool Sig on TriList
|
||||
/// </summary>
|
||||
public static void SetBool(this BasicTriList tl, uint sigNum, bool value)
|
||||
{
|
||||
tl.BooleanInput[sigNum].BoolValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to set the value of a string Sig on TriList
|
||||
/// </summary>
|
||||
public static void SetString(this BasicTriList tl, uint sigNum, string value)
|
||||
{
|
||||
tl.StringInput[sigNum].StringValue = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,8 +160,10 @@
|
||||
<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="Room\UI\SubpageReferenceListCallStagingItem.cs" />
|
||||
<Compile Include="UIDrivers\EssentialsCiscoSpark\EssentialsCiscoSparkUiDriver.cs" />
|
||||
<Compile Include="UIDrivers\JoinedSigInterlock.cs" />
|
||||
<Compile Include="UIDrivers\NYU\NyuHuddleVTCPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\EssentialsHuddleVTC\HuddleVTCPanelAvFunctionsDriver.cs" />
|
||||
<Compile Include="UIDrivers\VolumeAndSourceChangeArgs.cs" />
|
||||
<Compile Include="UIDrivers\UISmartObjectJoin.cs" />
|
||||
<Compile Include="UIDrivers\UIStringlJoin.cs" />
|
||||
|
||||
@@ -67,12 +67,50 @@ namespace PepperDash.Essentials
|
||||
public string Description { get; set; }
|
||||
public int ShutdownVacancySeconds { get; set; }
|
||||
public int ShutdownPromptSeconds { get; set; }
|
||||
public EssentialsHelpPropertiesConfig Help { get; set; }
|
||||
public EssentialsOneButtonMeetingPropertiesConfig OneButtonMeeting { get; set; }
|
||||
public EssentialsRoomAddressPropertiesConfig Addresses { get; set; }
|
||||
public EssentialsRoomOccSensorConfig OccupancySensors { get; set; }
|
||||
public EssentialsLogoPropertiesConfig Logo { get; set; }
|
||||
public EssentialsRoomVolumesConfig Volumes { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Properties for the help text box
|
||||
/// </summary>
|
||||
public class EssentialsHelpPropertiesConfig
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public bool ShowCallButton { get; set; }
|
||||
/// <summary>
|
||||
/// Defaults to "Call Help Desk"
|
||||
/// </summary>
|
||||
public string CallButtonText { get; set; }
|
||||
|
||||
public EssentialsHelpPropertiesConfig()
|
||||
{
|
||||
CallButtonText = "Call Help Desk";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsOneButtonMeetingPropertiesConfig
|
||||
{
|
||||
public bool Enable { get; set; }
|
||||
}
|
||||
|
||||
public class EssentialsRoomAddressPropertiesConfig
|
||||
{
|
||||
public string PhoneNumber { get; set; }
|
||||
public string SipAddress { get; set; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Properties for the room's logo on panels
|
||||
/// </summary>
|
||||
public class EssentialsLogoPropertiesConfig
|
||||
{
|
||||
public string Type { get; set; }
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
public bool ShowDate { get; set; }
|
||||
public bool ShowTime { get; set; }
|
||||
public UiSetupPropertiesConfig Setup { get; set; }
|
||||
public UiHeaderStyle HeaderStyle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The count of sources that will trigger the "additional" arrows to show on the SRL.
|
||||
@@ -22,12 +23,25 @@
|
||||
public CrestronTouchpanelPropertiesConfig()
|
||||
{
|
||||
SourcesOverflowCount = 5;
|
||||
HeaderStyle = UiHeaderStyle.Habanero;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class UiSetupPropertiesConfig
|
||||
{
|
||||
public bool IsVisible { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum UiHeaderStyle
|
||||
{
|
||||
Habanero,
|
||||
Verbose
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 SubpageReferenceListButtonAndModeItem : 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 SubpageReferenceListButtonAndModeItem(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,7 +190,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarHabaneroVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true;
|
||||
|
||||
// Default to showing rooms/sources now.
|
||||
@@ -253,7 +253,7 @@ namespace PepperDash.Essentials
|
||||
public override void Hide()
|
||||
{
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarHabaneroVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
@@ -280,7 +280,7 @@ namespace PepperDash.Essentials
|
||||
// show start page or staging...
|
||||
if (CurrentRoom.OnFeedback.BoolValue)
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
}
|
||||
@@ -345,7 +345,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
ShareButtonSig.BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = true;
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
@@ -740,7 +740,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
SetupActivityFooterWhenRoomOn();
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = true;
|
||||
|
||||
@@ -750,7 +750,7 @@ namespace PepperDash.Essentials
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarHabaneroVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = true;
|
||||
|
||||
// Default to showing rooms/sources now.
|
||||
@@ -266,12 +266,12 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var tl = TriList.BooleanInput;
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
tl[UIBoolJoin.TopBarVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.TopBarHabaneroVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.ToggleSharingModeVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
if (IsSharingModeAdvanced)
|
||||
tl[UIBoolJoin.DualDisplayPageVisible].BoolValue = false;
|
||||
else
|
||||
@@ -290,7 +290,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var tlb = TriList.BooleanInput;
|
||||
tlb[UIBoolJoin.ToggleSharingModeVisible].BoolValue = true;
|
||||
tlb[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
tlb[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
if (IsSharingModeAdvanced)
|
||||
{
|
||||
tlb[UIBoolJoin.DualDisplayPageVisible].BoolValue = true;
|
||||
@@ -310,7 +310,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
var tl = TriList.BooleanInput;
|
||||
tl[UIBoolJoin.ToggleSharingModeVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.DualDisplayPageVisible].BoolValue = false;
|
||||
tl[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Crestron.SimplSharp;
|
||||
using Crestron.SimplSharpPro.DeviceSupport;
|
||||
using PepperDash.Essentials;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.SmartObjects;
|
||||
|
||||
namespace PepperDash.Essentials.UIDrivers.EssentialsCiscoSpark
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This fella will likely need to interact with the room's source, although that is routed via the spark...
|
||||
/// Probably needs event or FB to feed AV driver - to show two-mute volume when appropriate.
|
||||
///
|
||||
/// </summary>
|
||||
public class EssentialsCiscoSparkUiDriver : PanelDriverBase
|
||||
{
|
||||
object Codec;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SubpageReferenceList CallStagingSrl;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SmartObjectDynamicList CallQuickDialList;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SubpageReferenceList DirectorySrl; // ***************** SRL ???
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// To drive UI elements outside of this driver that may be dependent on this.
|
||||
/// </summary>
|
||||
BoolFeedback InCall;
|
||||
BoolFeedback LocalPrivacyIsMuted;
|
||||
|
||||
|
||||
public EssentialsCiscoSparkUiDriver(BasicTriListWithSmartObject triList, object codec)
|
||||
: base(triList)
|
||||
{
|
||||
Codec = codec;
|
||||
SetupCallStagingSrl();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
base.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Hide()
|
||||
{
|
||||
base.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the call stage
|
||||
/// </summary>
|
||||
void SetupCallStagingSrl()
|
||||
{
|
||||
CallStagingSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.CallStagingSrl, 3, 3, 3);
|
||||
var c = CallStagingSrl;
|
||||
c.AddItem(new SubpageReferenceListButtonAndModeItem(1, c, 1, b => { if (!b) { } })); //************ Camera
|
||||
c.AddItem(new SubpageReferenceListButtonAndModeItem(2, c, 2, b => { if (!b) { } })); //************ Directory
|
||||
c.AddItem(new SubpageReferenceListButtonAndModeItem(3, c, 3, b => { if (!b) { } })); //************ Keypad
|
||||
c.AddItem(new SubpageReferenceListButtonAndModeItem(4, c, 4, b => { if (!b) { } })); //************ End Call
|
||||
c.Count = 3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void ShowCameraControls()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShowKeypad()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShowDirectory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CallHasStarted()
|
||||
{
|
||||
// Header icon
|
||||
// Add end call button to stage
|
||||
// Volume bar needs to have mic mute
|
||||
}
|
||||
|
||||
void CallHasEnded()
|
||||
{
|
||||
// Header icon
|
||||
// Remove end call
|
||||
// Volume bar no mic mute (or hidden if no source?)
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class BoolJoin
|
||||
{
|
||||
public const uint CameraControlsVisible = 3001;
|
||||
|
||||
public const uint KeypadVisbile = 3002;
|
||||
|
||||
public const uint DirectoryVisible = 3003;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,13 +14,13 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class NyuHuddleVtcPanelAvFunctionsDriver : PanelDriverBase
|
||||
public class HuddleVtcPanelAvFunctionsDriver : PanelDriverBase
|
||||
{
|
||||
CrestronTouchpanelPropertiesConfig Config;
|
||||
|
||||
public enum UiDisplayMode
|
||||
{
|
||||
PresentationMode, AudioSetup
|
||||
Presentation, AudioSetup, Call, Start
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -38,14 +38,6 @@ namespace PepperDash.Essentials
|
||||
///
|
||||
/// </summary>
|
||||
public string DefaultRoomKey { get; set; }
|
||||
//{
|
||||
// get { return _DefaultRoomKey; }
|
||||
// set
|
||||
// {
|
||||
// _DefaultRoomKey = value;
|
||||
// }
|
||||
//}
|
||||
//string _DefaultRoomKey;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
@@ -60,11 +52,6 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
EssentialsHuddleSpaceRoom _CurrentRoom;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
//uint CurrentInterlockedModalJoin;
|
||||
|
||||
/// <summary>
|
||||
/// For hitting feedback
|
||||
/// </summary>
|
||||
@@ -89,13 +76,19 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Smart Object 3200
|
||||
/// </summary>
|
||||
SubpageReferenceList SourcesSrl;
|
||||
SubpageReferenceList SourceStagingSrl;
|
||||
|
||||
/// <summary>
|
||||
/// Smart Object 15022
|
||||
/// </summary>
|
||||
SubpageReferenceList ActivityFooterSrl;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
SubpageReferenceList CallStagingSrl;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Tracks which audio page group the UI is in
|
||||
/// </summary>
|
||||
@@ -131,29 +124,39 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
JoinedSigInterlock PopupInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// Interlock for various source, camera, call control bars. The bar above the activity footer. This is also
|
||||
/// used to show start page
|
||||
/// </summary>
|
||||
JoinedSigInterlock StagingBarInterlock;
|
||||
|
||||
JoinedSigInterlock CallPagesInterlock;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public NyuHuddleVtcPanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
|
||||
public HuddleVtcPanelAvFunctionsDriver(PanelDriverBase parent, CrestronTouchpanelPropertiesConfig config)
|
||||
: base(parent.TriList)
|
||||
{
|
||||
Config = config;
|
||||
Parent = parent;
|
||||
PopupInterlock = new JoinedSigInterlock(TriList);
|
||||
StagingBarInterlock = new JoinedSigInterlock(TriList);
|
||||
CallPagesInterlock = new JoinedSigInterlock(TriList);
|
||||
|
||||
SourcesSrl = new SubpageReferenceList(TriList, 3200, 3, 3, 3);
|
||||
SourceStagingSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.SourceStagingSRL, 3, 3, 3);
|
||||
|
||||
ActivityFooterSrl = new SubpageReferenceList(TriList, 15022, 3, 3, 3);
|
||||
ActivityFooterSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.ActivityFooterSRL, 3, 3, 3);
|
||||
CallButtonSig = ActivityFooterSrl.BoolInputSig(1, 1);
|
||||
ShareButtonSig = ActivityFooterSrl.BoolInputSig(2, 1);
|
||||
|
||||
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
|
||||
ShowVolumeGauge = true;
|
||||
PowerOffTimeout = 30000;
|
||||
//PowerOffTimeout = 30000;
|
||||
|
||||
TriList.StringInput[UIStringJoin.StartActivityText].StringValue =
|
||||
"Tap Share to begin";
|
||||
//TriList.StringInput[UIStringJoin.StartActivityText].StringValue = "Tap an activity below";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,17 +164,46 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public override void Show()
|
||||
{
|
||||
if (CurrentRoom == null)
|
||||
{
|
||||
Debug.Console(1, "ERROR: AVUIFunctionsDriver, Cannot show. No room assigned");
|
||||
return;
|
||||
}
|
||||
|
||||
var roomConf = CurrentRoom.Config;
|
||||
|
||||
if (Config.HeaderStyle == null || Config.HeaderStyle == UiHeaderStyle.Habanero)
|
||||
{
|
||||
TriList.SetString(UIStringJoin.CurrentRoomName, CurrentRoom.Name);
|
||||
TriList.SetSigFalseAction(UIBoolJoin.RoomHeaderButtonPress, () =>
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.RoomHeaderPageVisible));
|
||||
}
|
||||
else if (Config.HeaderStyle == UiHeaderStyle.Verbose)
|
||||
{
|
||||
// room name on join 1, concat phone and sip on join 2, no button method
|
||||
TriList.SetString(UIStringJoin.CurrentRoomName, CurrentRoom.Name);
|
||||
var addr = roomConf.Addresses;
|
||||
if (addr == null) // protect from missing values by using default empties
|
||||
addr = new EssentialsRoomAddressPropertiesConfig();
|
||||
// empty string when either missing, pipe when both showing
|
||||
TriList.SetString(UIStringJoin.RoomAddressPipeText,
|
||||
(string.IsNullOrEmpty(addr.PhoneNumber.Trim())
|
||||
|| string.IsNullOrEmpty(addr.SipAddress.Trim())) ? "" : " | ");
|
||||
TriList.SetString(UIStringJoin.RoomPhoneText, addr.PhoneNumber);
|
||||
TriList.SetString(UIStringJoin.RoomSipText, addr.SipAddress);
|
||||
}
|
||||
|
||||
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.TopBarHabaneroVisible, 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.SourceStagingBarVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.TapToBeginVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
}
|
||||
@@ -188,7 +220,24 @@ namespace PepperDash.Essentials
|
||||
// Generic "close" button for these modals
|
||||
TriList.SetSigFalseAction(UIBoolJoin.InterlockedModalClosePress, PopupInterlock.HideAndClear);
|
||||
|
||||
// Help button
|
||||
// Help button and popup
|
||||
if (CurrentRoom.Config.Help != null)
|
||||
{
|
||||
TriList.SetString(UIStringJoin.HelpMessage, roomConf.Help.Message);
|
||||
TriList.SetBool(UIBoolJoin.HelpPageShowCallButtonVisible, roomConf.Help.ShowCallButton);
|
||||
TriList.SetString(UIStringJoin.HelpPageCallButtonText, roomConf.Help.CallButtonText);
|
||||
if(roomConf.Help.ShowCallButton)
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HelpPageShowCallButtonPress, () => { }); // ************ FILL IN
|
||||
else
|
||||
TriList.ClearBoolSigAction(UIBoolJoin.HelpPageShowCallButtonPress);
|
||||
}
|
||||
else // older config
|
||||
{
|
||||
TriList.SetString(UIStringJoin.HelpMessage, CurrentRoom.Config.HelpMessage);
|
||||
TriList.SetBool(UIBoolJoin.HelpPageShowCallButtonVisible, false);
|
||||
TriList.SetString(UIStringJoin.HelpPageCallButtonText, null);
|
||||
TriList.ClearBoolSigAction(UIBoolJoin.HelpPageShowCallButtonPress);
|
||||
}
|
||||
TriList.SetSigFalseAction(UIBoolJoin.HelpPress, () =>
|
||||
{
|
||||
string message = null;
|
||||
@@ -198,22 +247,22 @@ namespace PepperDash.Essentials
|
||||
message = room.Config.HelpMessage;
|
||||
else
|
||||
message = "Sorry, no help message available. No room connected.";
|
||||
TriList.StringInput[UIStringJoin.HelpMessage].StringValue = message;
|
||||
//TriList.StringInput[UIStringJoin.HelpMessage].StringValue = message;
|
||||
PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HelpPageVisible);
|
||||
});
|
||||
|
||||
// Lights button
|
||||
TriList.SetSigFalseAction(UIBoolJoin.LightsHeaderButtonPress, () =>
|
||||
TriList.SetSigFalseAction(UIBoolJoin.LightsHeaderButtonPress, () => // ******************** FILL IN
|
||||
{ });
|
||||
|
||||
// Call header button
|
||||
TriList.SetSigFalseAction(UIBoolJoin.CallHeaderButtonPress, () =>
|
||||
if(roomConf.OneButtonMeeting != null && roomConf.OneButtonMeeting.Enable)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.CalendarHeaderButtonVisible, true);
|
||||
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),
|
||||
@@ -245,13 +294,59 @@ namespace PepperDash.Essentials
|
||||
base.Show();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Puts the UI into the "start" mode. System is off. Logo shows. Activity SRL is clear
|
||||
/// </summary>
|
||||
void ShowStartMode()
|
||||
{
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
|
||||
ShareButtonSig.BoolValue = false;
|
||||
CallButtonSig.BoolValue = false;
|
||||
ShowLogo();
|
||||
StagingBarInterlock.ShowInterlocked(UIBoolJoin.StartPageVisible);
|
||||
StagingBarInterlock.HideAndClear();
|
||||
}
|
||||
|
||||
void ShowShareMode()
|
||||
{
|
||||
ShareButtonSig.BoolValue = true;
|
||||
CallButtonSig.BoolValue = false;
|
||||
StagingBarInterlock.ShowInterlocked(UIBoolJoin.SourceStagingBarVisible);
|
||||
}
|
||||
|
||||
void ShowVideoCallMode()
|
||||
{
|
||||
ShareButtonSig.BoolValue = false;
|
||||
CallButtonSig.BoolValue = true;
|
||||
StagingBarInterlock.ShowInterlocked(UIBoolJoin.CallStagingBarVisible);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void ShowLogo()
|
||||
{
|
||||
if (CurrentRoom.LogoUrl == null)
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.LogoDefaultVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.LogoUrlVisible, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TriList.SetBool(UIBoolJoin.LogoDefaultVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.LogoUrlVisible, true);
|
||||
TriList.SetString(UIStringJoin.LogoUrl, _CurrentRoom.LogoUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public override void Hide()
|
||||
{
|
||||
HideAndClearCurrentDisplayModeSigsInUse();
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.TopBarHabaneroVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.ActivityFooterVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.TapToBeginVisible].BoolValue = false;
|
||||
@@ -266,9 +361,9 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
ActivityFooterSrl.Clear();
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 1,
|
||||
b => { if (!b) CallButtonPressed(); }));
|
||||
b => { if (!b) ActivityCallButtonPressed(); }));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 0,
|
||||
b => { if (!b) ShareButtonPressed(); }));
|
||||
b => { if (!b) ActivityShareButtonPressed(); }));
|
||||
ActivityFooterSrl.Count = 2;
|
||||
TriList.UShortInput[UIUshortJoin.PresentationListCaretMode].UShortValue = 0;
|
||||
ShareButtonSig.BoolValue = false;
|
||||
@@ -280,10 +375,10 @@ namespace PepperDash.Essentials
|
||||
void SetupActivityFooterWhenRoomOn()
|
||||
{
|
||||
ActivityFooterSrl.Clear();
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl,
|
||||
1, null));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl,
|
||||
0, null));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(1, ActivityFooterSrl, 1,
|
||||
b => { if (!b) ActivityCallButtonPressed(); }));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(2, ActivityFooterSrl, 0,
|
||||
b => { if (!b) ActivityShareButtonPressed(); }));
|
||||
ActivityFooterSrl.AddItem(new SubpageReferenceListActivityItem(3, ActivityFooterSrl,
|
||||
3, b => { if (!b) PowerButtonPressed(); }));
|
||||
ActivityFooterSrl.Count = 2;
|
||||
@@ -293,11 +388,45 @@ namespace PepperDash.Essentials
|
||||
ShareButtonSig.BoolValue = CurrentRoom.OnFeedback.BoolValue;
|
||||
}
|
||||
|
||||
void CallButtonPressed()
|
||||
///// <summary>
|
||||
///// Builds the call stage
|
||||
///// </summary>
|
||||
//void SetupCallStagingSrl()
|
||||
//{
|
||||
// CallStagingSrl = new SubpageReferenceList(TriList, UISmartObjectJoin.CallStagingSrl, 3, 3, 3);
|
||||
// var c = CallStagingSrl;
|
||||
// c.AddItem(new SubpageReferenceListButtonAndModeItem(1, c, 1, b => { if (!b) { } })); //************ Camera
|
||||
// c.AddItem(new SubpageReferenceListButtonAndModeItem(2, c, 2, b => { if (!b) { } })); //************ Directory
|
||||
// c.AddItem(new SubpageReferenceListButtonAndModeItem(3, c, 3, b => { if (!b) { } })); //************ Keypad
|
||||
// c.AddItem(new SubpageReferenceListButtonAndModeItem(4, c, 4, b => { if (!b) { } })); //************ End Call
|
||||
// c.Count = 3;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// This may need to be part of an event handler routine from codec feedback.
|
||||
/// Adds End Call to Call Staging list
|
||||
/// </summary>
|
||||
void SetupEndCall()
|
||||
{
|
||||
CallStagingSrl.Count = 4;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Part of event handler? Removes End Call from Call Staging
|
||||
/// </summary>
|
||||
void HideEndCall()
|
||||
{
|
||||
CallStagingSrl.Count = 3;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
void ActivityCallButtonPressed()
|
||||
{
|
||||
CallButtonSig.BoolValue = true;
|
||||
TriList.SetBool(UIBoolJoin.StartPageVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.StagingPageVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, false);
|
||||
// Call "page"? Or separate UI driver?
|
||||
}
|
||||
@@ -305,11 +434,11 @@ namespace PepperDash.Essentials
|
||||
/// <summary>
|
||||
/// Attached to activity list share button
|
||||
/// </summary>
|
||||
void ShareButtonPressed()
|
||||
void ActivityShareButtonPressed()
|
||||
{
|
||||
ShareButtonSig.BoolValue = true;
|
||||
TriList.SetBool(UIBoolJoin.StartPageVisible, false);
|
||||
TriList.SetBool(UIBoolJoin.StagingPageVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.SourceStagingBarVisible, true);
|
||||
TriList.SetBool(UIBoolJoin.SelectASourceVisible, true);
|
||||
// Run default source when room is off and share is pressed
|
||||
if (!CurrentRoom.OnFeedback.BoolValue)
|
||||
@@ -355,7 +484,6 @@ namespace PepperDash.Essentials
|
||||
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);
|
||||
@@ -560,26 +688,16 @@ namespace PepperDash.Essentials
|
||||
continue;
|
||||
}
|
||||
var routeKey = kvp.Key;
|
||||
var item = new SubpageReferenceListSourceItem(i++, SourcesSrl, srcConfig,
|
||||
var item = new SubpageReferenceListSourceItem(i++, SourceStagingSrl, srcConfig,
|
||||
b => { if (!b) UiSelectSource(routeKey); });
|
||||
SourcesSrl.AddItem(item); // add to the SRL
|
||||
SourceStagingSrl.AddItem(item); // add to the SRL
|
||||
item.RegisterForSourceChange(_CurrentRoom);
|
||||
}
|
||||
SourcesSrl.Count = (ushort)(i - 1);
|
||||
SourceStagingSrl.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;
|
||||
}
|
||||
ShowLogo();
|
||||
|
||||
// Shutdown timer
|
||||
_CurrentRoom.ShutdownPromptTimer.HasStarted += ShutdownPromptTimer_HasStarted;
|
||||
@@ -622,7 +740,7 @@ namespace PepperDash.Essentials
|
||||
{
|
||||
SetupActivityFooterWhenRoomOn();
|
||||
TriList.BooleanInput[UIBoolJoin.SelectASourceVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = true;
|
||||
|
||||
@@ -632,7 +750,7 @@ namespace PepperDash.Essentials
|
||||
SetupActivityFooterWhenRoomOff();
|
||||
TriList.BooleanInput[UIBoolJoin.StartPageVisible].BoolValue = true;
|
||||
TriList.BooleanInput[UIBoolJoin.VolumeSingleMute1Visible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.StagingPageVisible].BoolValue = false;
|
||||
TriList.BooleanInput[UIBoolJoin.SourceStagingBarVisible].BoolValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,12 @@ namespace PepperDash.Essentials
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hides CurrentJoin and shows join
|
||||
/// Hides CurrentJoin and shows join. Does nothing when resending CurrentJoin
|
||||
/// </summary>
|
||||
public void ShowInterlocked(uint join)
|
||||
{
|
||||
if (CurrentJoin == join)
|
||||
return;
|
||||
if (CurrentJoin > 0)
|
||||
TriList.BooleanInput[CurrentJoin].BoolValue = false;
|
||||
CurrentJoin = join;
|
||||
|
||||
@@ -160,13 +160,13 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint ShowPanelSetupPress = 15010;
|
||||
/// <summary>
|
||||
/// 15011
|
||||
/// 15011 - Top bar with room name and button that pops up dialog with room data
|
||||
/// </summary>
|
||||
public const uint TopBarVisible = 15011;
|
||||
public const uint TopBarHabaneroVisible = 15011;
|
||||
/// <summary>
|
||||
/// 15012
|
||||
/// </summary>
|
||||
public const uint StagingPageVisible = 15012;
|
||||
public const uint SourceStagingBarVisible = 15012;
|
||||
/// <summary>
|
||||
/// 15013
|
||||
/// </summary>
|
||||
@@ -215,7 +215,7 @@ namespace PepperDash.Essentials
|
||||
/// 15026
|
||||
/// </summary>
|
||||
public const uint LightsHeaderButtonPress = 15026;
|
||||
/// <summary>
|
||||
/// <summary>[-
|
||||
/// 15027
|
||||
/// </summary>
|
||||
public const uint CallHeaderButtonPress = 15027;
|
||||
@@ -264,6 +264,14 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint GearButtonVisible = 15037;
|
||||
/// <summary>
|
||||
/// 15038
|
||||
/// </summary>
|
||||
public const uint CalendarHeaderButtonVisible = 15038;
|
||||
/// <summary>
|
||||
/// 15039
|
||||
/// </summary>
|
||||
public const uint CalendarHeaderButtonPress = 15039;
|
||||
/// <summary>
|
||||
/// 15040
|
||||
/// </summary>
|
||||
public const uint CallStatusPageVisible = 15040;
|
||||
@@ -283,8 +291,10 @@ namespace PepperDash.Essentials
|
||||
/// 15044 Close button for source modal overlay
|
||||
/// </summary>
|
||||
public const uint SourceBackgroundOverlayClosePress = 15044;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 15045 - Visibility for the bar containing call navigation button list
|
||||
/// </summary>
|
||||
public const uint CallStagingBarVisible = 15045;
|
||||
/// <summary>
|
||||
/// 15051
|
||||
/// </summary>
|
||||
@@ -350,17 +360,22 @@ namespace PepperDash.Essentials
|
||||
/// 15065
|
||||
/// </summary>
|
||||
public const uint LogoUrlVisible = 15065;
|
||||
|
||||
/// <summary>
|
||||
/// 15083 - Press for Call help desk on AC/VC
|
||||
/// </summary>
|
||||
public const uint HelpPageShowCallButtonPress = 15083;
|
||||
/// <summary>
|
||||
/// 15084 - Show the "call help desk" button on help page
|
||||
/// </summary>
|
||||
public const uint HelpPageShowCallButtonVisible = 15084;
|
||||
/// <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>
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
/// <summary>
|
||||
/// 3200 The staging, source-select list
|
||||
/// </summary>
|
||||
public const uint StagingListSRL = 3200;
|
||||
public const uint SourceStagingSRL = 3200;
|
||||
/// <summary>
|
||||
/// 15022 The main activity footer
|
||||
/// </summary>
|
||||
public const uint ActivityFooterSRL = 15022;
|
||||
|
||||
/// <summary>
|
||||
/// 15045
|
||||
/// </summary>
|
||||
public const uint CallStagingSrl = 15045;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ using Crestron.SimplSharpPro.DeviceSupport;
|
||||
namespace PepperDash.Essentials
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// Common string join number constants
|
||||
/// </summary>
|
||||
public class UIStringJoin
|
||||
{
|
||||
@@ -51,6 +51,18 @@ namespace PepperDash.Essentials
|
||||
/// </summary>
|
||||
public const uint CurrentSourceIcon = 3903;
|
||||
/// <summary>
|
||||
/// 3904 - Phone number for room header
|
||||
/// </summary>
|
||||
public const uint RoomPhoneText = 3904;
|
||||
/// <summary>
|
||||
/// 3905 - SIP address for room header
|
||||
/// </summary>
|
||||
public const uint RoomSipText = 3905;
|
||||
/// <summary>
|
||||
/// 3906 - The separator for verbose-header text on addresses
|
||||
/// </summary>
|
||||
public const uint RoomAddressPipeText = 3906;
|
||||
/// <summary>
|
||||
/// 3911
|
||||
/// </summary>
|
||||
public const uint PowerOffMessage = 3911;
|
||||
@@ -71,11 +83,14 @@ namespace PepperDash.Essentials
|
||||
/// 3922
|
||||
/// </summary>
|
||||
public const uint HelpMessage = 3922;
|
||||
|
||||
/// <summary>
|
||||
/// 3923
|
||||
/// </summary>
|
||||
public const uint LogoUrl = 3923;
|
||||
/// <summary>
|
||||
/// 3924 - the text on the "call help desk" button
|
||||
/// </summary>
|
||||
public const uint HelpPageCallButtonText = 3924;
|
||||
|
||||
/// <summary>
|
||||
/// 3961 Name of source on display 1
|
||||
|
||||
Reference in New Issue
Block a user