diff --git a/.gitmodules b/.gitmodules index d33ae772..2ae0902f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "essentials-framework"] path = essentials-framework - url = https://hvolmer@bitbucket.org/Pepperdash_Products/essentials-framework.git + url = https://bitbucket.org/Pepperdash_Products/essentials-framework.git diff --git a/PepperDashEssentials/ControlSystem.cs b/PepperDashEssentials/ControlSystem.cs index 99db69d9..06c63c05 100644 --- a/PepperDashEssentials/ControlSystem.cs +++ b/PepperDashEssentials/ControlSystem.cs @@ -1,359 +1,369 @@ -using System; -using System.Linq; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.CrestronThread; -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Devices.Common; -using PepperDash.Essentials.DM; -using PepperDash.Essentials.Fusion; -using PepperDash.Essentials.Room.Cotija; - -namespace PepperDash.Essentials -{ - public class ControlSystem : CrestronControlSystem - { - HttpLogoServer LogoServer; - - public ControlSystem() - : base() - { - Thread.MaxNumberOfUserThreads = 400; - Global.ControlSystem = this; - DeviceManager.Initialize(this); - } - - /// - /// Git 'er goin' - /// - public override void InitializeSystem() - { - DeterminePlatform(); - - //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file", - // ConsoleAccessLevelEnum.AccessOperator); - - CrestronConsole.AddNewConsoleCommand(s => - { - foreach (var tl in TieLineCollection.Default) - CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); - }, - "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); - - CrestronConsole.AddNewConsoleCommand(s => - { - CrestronConsole.ConsoleCommandResponse - ("Current running configuration. This is the merged system and template configuration"); - CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject - (ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented)); - }, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator); - - CrestronConsole.AddNewConsoleCommand(s => - { - CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" + - "System URL: {0}\r" + - "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); - }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); - - GoWithLoad(); - } - - /// - /// Determines if the program is running on a processor (appliance) or server (XiO Edge). - /// - /// Sets Global.FilePathPrefix based on platform - /// - public void DeterminePlatform() - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform...."); - - string filePathPrefix; - - var dirSeparator = Global.DirectorySeparator; - - var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version; - - var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); - - string directoryPrefix; - - //directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory(); -#warning ^ For use with beta Include4.dat for XiO Edge - directoryPrefix = ""; - - if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) - { - filePathPrefix = directoryPrefix + dirSeparator + "NVRAM" - + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString); - } - else - { - filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator; - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on XiO Edge Server", versionString); - } - - Global.SetFilePathPrefix(filePathPrefix); - } - - /// - /// Do it, yo - /// - public void GoWithLoad() - { - try - { - CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync", - ConsoleAccessLevelEnum.AccessOperator); - - //PortalSync = new PepperDashPortalSyncClient(); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); - - var filesReady = SetupFilesystem(); - if (filesReady) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); - if (!ConfigReader.LoadConfig2()) - return; - - Load(); - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r" + - "-------------------------------------------------------------"); - } - else - { - Debug.Console(0, - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "Essentials file structure setup completed.\r" + - "Please load config, sgd and ir files and\r" + - "restart program.\r" + - "------------------------------------------------\r" + - "------------------------------------------------\r" + - "------------------------------------------------"); - } - } - catch (Exception e) - { - Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); - } - - } - - /// - /// Verifies filesystem is set up. IR, SGD, and program1 folders - /// - bool SetupFilesystem() - { - Debug.Console(0, "Verifying and/or creating folder structure"); - var configDir = Global.FilePathPrefix; - var configExists = Directory.Exists(configDir); - if (!configExists) - Directory.Create(configDir); - - var irDir = Global.FilePathPrefix + "ir"; - if (!Directory.Exists(irDir)) - Directory.Create(irDir); - - var sgdDir = Global.FilePathPrefix + "sgd"; - if (!Directory.Exists(sgdDir)) - Directory.Create(sgdDir); - - return configExists; - } - - public void EnablePortalSync(string s) - { - if (s.ToLower() == "enable") - { - CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); - } - } - - public void TearDown() - { - Debug.Console(0, "Tearing down existing system"); - DeviceManager.DeactivateAll(); - - TieLineCollection.Default.Clear(); - - foreach (var key in DeviceManager.GetDevices()) - DeviceManager.RemoveDevice(key); - - Debug.Console(0, "Tear down COMPLETE"); - } - - /// - /// - /// - void Load() - { - LoadDevices(); - LoadTieLines(); - LoadRooms(); - LoadLogoServer(); - - DeviceManager.ActivateAll(); - } - - - /// - /// Reads all devices from config and adds them to DeviceManager - /// - public void LoadDevices() - { - foreach (var devConf in ConfigReader.ConfigObject.Devices) - { - - try - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}'", devConf.Key); - // Skip this to prevent unnecessary warnings - if (devConf.Key == "processor") - continue; - - // Try local factory first - var newDev = DeviceFactory.GetDevice(devConf); - - // Then associated library factories - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); - if (newDev == null) - newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); - - if (newDev != null) - DeviceManager.AddDevice(newDev); - else - Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); - } - catch (Exception e) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e); - } - } - Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); - - } - - /// - /// Helper method to load tie lines. This should run after devices have loaded - /// - public void LoadTieLines() - { - // In the future, we can't necessarily just clear here because devices - // might be making their own internal sources/tie lines - - var tlc = TieLineCollection.Default; - //tlc.Clear(); - if (ConfigReader.ConfigObject.TieLines == null) - { - return; - } - - foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines) - { - var newTL = tieLineConfig.GetTieLine(); - if (newTL != null) - tlc.Add(newTL); - } - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded."); - - } - - /// - /// Reads all rooms from config and adds them to DeviceManager - /// - public void LoadRooms() - { - if (ConfigReader.ConfigObject.Rooms == null) - { - Debug.Console(0, Debug.ErrorLogLevel.Warning, "WARNING: Configuration contains no rooms"); - return; - } - - foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) - { - var room = roomConfig.GetRoomObject(); - if (room != null) - { - if (room is EssentialsHuddleSpaceRoom) - { - DeviceManager.AddDevice(room); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1)); - - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge..."); - // Cotija bridge - var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom); - AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present - DeviceManager.AddDevice(bridge); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Cotija Bridge Added..."); - } - else if (room is EssentialsHuddleVtc1Room) - { - DeviceManager.AddDevice(room); - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); - DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); - } - else - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion"); - DeviceManager.AddDevice(room); - } - - } - else - Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key); - } - - Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded."); - - } - - /// - /// Helps add the post activation steps that link bridges to main controller - /// - /// - void AddBridgePostActivationHelper(CotijaBridgeBase bridge) - { - bridge.AddPostActivationAction(() => - { - var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController; - if (parent == null) - { - Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present"); - } - Debug.Console(0, bridge, "Linking to parent controller"); - bridge.AddParent(parent); - parent.AddBridge(bridge); - }); - } - - /// - /// Fires up a logo server if not already running - /// - void LoadLogoServer() - { - try - { - LogoServer = new HttpLogoServer(8080, Global.FilePathPrefix + "html" + Global.DirectorySeparator + "logo"); - } - catch (Exception) - { - Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program"); - } - } - } -} +using System; +using System.Linq; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.CrestronThread; +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common; +using PepperDash.Essentials.DM; +using PepperDash.Essentials.Fusion; +using PepperDash.Essentials.Room.Cotija; + +namespace PepperDash.Essentials +{ + public class ControlSystem : CrestronControlSystem + { + HttpLogoServer LogoServer; + + public ControlSystem() + : base() + { + Thread.MaxNumberOfUserThreads = 400; + Global.ControlSystem = this; + DeviceManager.Initialize(this); + } + + /// + /// Git 'er goin' + /// + public override void InitializeSystem() + { + DeterminePlatform(); + + //CrestronConsole.AddNewConsoleCommand(s => GoWithLoad(), "go", "Loads configuration file", + // ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + foreach (var tl in TieLineCollection.Default) + CrestronConsole.ConsoleCommandResponse(" {0}\r", tl); + }, + "listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + CrestronConsole.ConsoleCommandResponse + ("Current running configuration. This is the merged system and template configuration"); + CrestronConsole.ConsoleCommandResponse(Newtonsoft.Json.JsonConvert.SerializeObject + (ConfigReader.ConfigObject, Newtonsoft.Json.Formatting.Indented)); + }, "showconfig", "Shows the current running merged config", ConsoleAccessLevelEnum.AccessOperator); + + CrestronConsole.AddNewConsoleCommand(s => + { + CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" + + "System URL: {0}\r" + + "Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl); + }, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator); + + GoWithLoad(); + } + + /// + /// Determines if the program is running on a processor (appliance) or server (XiO Edge). + /// + /// Sets Global.FilePathPrefix based on platform + /// + public void DeterminePlatform() + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Determining Platform...."); + + string filePathPrefix; + + var dirSeparator = Global.DirectorySeparator; + + var version = Crestron.SimplSharp.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + + var versionString = string.Format("{0}.{1}.{2}", version.Major, version.Minor, version.Build); + + string directoryPrefix; + + directoryPrefix = Crestron.SimplSharp.CrestronIO.Directory.GetApplicationRootDirectory(); + + //directoryPrefix = ""; + + if (CrestronEnvironment.DevicePlatform != eDevicePlatform.Server) + { + filePathPrefix = directoryPrefix + dirSeparator + "NVRAM" + + dirSeparator + string.Format("program{0}", InitialParametersClass.ApplicationNumber) + dirSeparator; + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on 3-series Appliance", versionString); + } + else + { + filePathPrefix = directoryPrefix + dirSeparator + "User" + dirSeparator; + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials v{0} on XiO Edge Server", versionString); + } + + Global.SetFilePathPrefix(filePathPrefix); + } + + /// + /// Do it, yo + /// + public void GoWithLoad() + { + try + { + CrestronConsole.AddNewConsoleCommand(EnablePortalSync, "portalsync", "Loads Portal Sync", + ConsoleAccessLevelEnum.AccessOperator); + + //PortalSync = new PepperDashPortalSyncClient(); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Starting Essentials load from configuration"); + + var filesReady = SetupFilesystem(); + if (filesReady) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Folder structure verified. Loading config..."); + if (!ConfigReader.LoadConfig2()) + return; + + Load(); + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Essentials load complete\r" + + "-------------------------------------------------------------"); + } + else + { + Debug.Console(0, + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "Essentials file structure setup completed.\r" + + "Please load config, sgd and ir files and\r" + + "restart program.\r" + + "------------------------------------------------\r" + + "------------------------------------------------\r" + + "------------------------------------------------"); + } + } + catch (Exception e) + { + Debug.Console(0, "FATAL INITIALIZE ERROR. System is in an inconsistent state:\r{0}", e); + } + + } + + /// + /// Verifies filesystem is set up. IR, SGD, and program1 folders + /// + bool SetupFilesystem() + { + Debug.Console(0, "Verifying and/or creating folder structure"); + var configDir = Global.FilePathPrefix; + var configExists = Directory.Exists(configDir); + if (!configExists) + Directory.Create(configDir); + + var irDir = Global.FilePathPrefix + "ir"; + if (!Directory.Exists(irDir)) + Directory.Create(irDir); + + var sgdDir = Global.FilePathPrefix + "sgd"; + if (!Directory.Exists(sgdDir)) + Directory.Create(sgdDir); + + return configExists; + } + + public void EnablePortalSync(string s) + { + if (s.ToLower() == "enable") + { + CrestronConsole.ConsoleCommandResponse("Portal Sync features enabled"); + } + } + + public void TearDown() + { + Debug.Console(0, "Tearing down existing system"); + DeviceManager.DeactivateAll(); + + TieLineCollection.Default.Clear(); + + foreach (var key in DeviceManager.GetDevices()) + DeviceManager.RemoveDevice(key); + + Debug.Console(0, "Tear down COMPLETE"); + } + + /// + /// + /// + void Load() + { + LoadDevices(); + LoadTieLines(); + LoadRooms(); + LoadLogoServer(); + + DeviceManager.ActivateAll(); + } + + + /// + /// Reads all devices from config and adds them to DeviceManager + /// + public void LoadDevices() + { + // Build the processor wrapper class + DeviceManager.AddDevice(new PepperDash.Essentials.Core.Devices.CrestronProcessor("processor")); + + foreach (var devConf in ConfigReader.ConfigObject.Devices) + { + + try + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Creating device '{0}'", devConf.Key); + // Skip this to prevent unnecessary warnings + if (devConf.Key == "processor") + { + if (devConf.Type.ToLower() != Global.ControlSystem.ControllerPrompt.ToLower()) + Debug.Console(0, + "WARNING: Config file defines processor type as '{0}' but actual processor is '{1}'! Some ports may not be available", + devConf.Type.ToUpper(), Global.ControlSystem.ControllerPrompt.ToUpper()); + + continue; + } + + // Try local factory first + var newDev = DeviceFactory.GetDevice(devConf); + + // Then associated library factories + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Common.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.DM.DeviceFactory.GetDevice(devConf); + if (newDev == null) + newDev = PepperDash.Essentials.Devices.Displays.DisplayDeviceFactory.GetDevice(devConf); + + if (newDev != null) + DeviceManager.AddDevice(newDev); + else + Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Cannot load unknown device type '{0}', key '{1}'.", devConf.Type, devConf.Key); + } + catch (Exception e) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "ERROR: Creating device {0}. Skipping device. \r{1}", devConf.Key, e); + } + } + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Devices Loaded."); + + } + + /// + /// Helper method to load tie lines. This should run after devices have loaded + /// + public void LoadTieLines() + { + // In the future, we can't necessarily just clear here because devices + // might be making their own internal sources/tie lines + + var tlc = TieLineCollection.Default; + //tlc.Clear(); + if (ConfigReader.ConfigObject.TieLines == null) + { + return; + } + + foreach (var tieLineConfig in ConfigReader.ConfigObject.TieLines) + { + var newTL = tieLineConfig.GetTieLine(); + if (newTL != null) + tlc.Add(newTL); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Tie Lines Loaded."); + + } + + /// + /// Reads all rooms from config and adds them to DeviceManager + /// + public void LoadRooms() + { + if (ConfigReader.ConfigObject.Rooms == null) + { + Debug.Console(0, Debug.ErrorLogLevel.Warning, "WARNING: Configuration contains no rooms"); + return; + } + + foreach (var roomConfig in ConfigReader.ConfigObject.Rooms) + { + var room = roomConfig.GetRoomObject(); + if (room != null) + { + if (room is EssentialsHuddleSpaceRoom) + { + DeviceManager.AddDevice(room); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleSpaceRoom, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleSpaceFusionSystemControllerBase((EssentialsHuddleSpaceRoom)room, 0xf1)); + + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to build Cotija Bridge..."); + // Cotija bridge + var bridge = new CotijaEssentialsHuddleSpaceRoomBridge(room as EssentialsHuddleSpaceRoom); + AddBridgePostActivationHelper(bridge); // Lets things happen later when all devices are present + DeviceManager.AddDevice(bridge); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Cotija Bridge Added..."); + } + else if (room is EssentialsHuddleVtc1Room) + { + DeviceManager.AddDevice(room); + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is EssentialsHuddleVtc1Room, attempting to add to DeviceManager with Fusion"); + DeviceManager.AddDevice(new EssentialsHuddleVtc1FusionController((EssentialsHuddleVtc1Room)room, 0xf1)); + } + else + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "Room is NOT EssentialsHuddleSpaceRoom, attempting to add to DeviceManager w/o Fusion"); + DeviceManager.AddDevice(room); + } + + } + else + Debug.Console(0, Debug.ErrorLogLevel.Notice, "WARNING: Cannot create room from config, key '{0}'", roomConfig.Key); + } + + Debug.Console(0, Debug.ErrorLogLevel.Notice, "All Rooms Loaded."); + + } + + /// + /// Helps add the post activation steps that link bridges to main controller + /// + /// + void AddBridgePostActivationHelper(CotijaBridgeBase bridge) + { + bridge.AddPostActivationAction(() => + { + var parent = DeviceManager.AllDevices.FirstOrDefault(d => d.Key == "appServer") as CotijaSystemController; + if (parent == null) + { + Debug.Console(0, bridge, "ERROR: Cannot connect bridge. System controller not present"); + } + Debug.Console(0, bridge, "Linking to parent controller"); + bridge.AddParent(parent); + parent.AddBridge(bridge); + }); + } + + /// + /// Fires up a logo server if not already running + /// + void LoadLogoServer() + { + try + { + LogoServer = new HttpLogoServer(8080, Global.DirectorySeparator + "html" + Global.DirectorySeparator + "logo"); + } + catch (Exception) + { + Debug.Console(0, Debug.ErrorLogLevel.Notice, "NOTICE: Logo server cannot be started. Likely already running in another program"); + } + } + } +} diff --git a/PepperDashEssentials/Factory/UiDeviceFactory.cs b/PepperDashEssentials/Factory/UiDeviceFactory.cs index 8638b0ab..a4387d1a 100644 --- a/PepperDashEssentials/Factory/UiDeviceFactory.cs +++ b/PepperDashEssentials/Factory/UiDeviceFactory.cs @@ -44,10 +44,10 @@ namespace PepperDash.Essentials // AV Driver Debug.Console(0, panelController, "Adding huddle space AV driver"); var avDriver = new EssentialsHuddlePanelAvFunctionsDriver(mainDriver, props); - avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; - + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as EssentialsHuddleSpaceRoom; + // Environment Driver if (avDriver.CurrentRoom.Config.Environment != null && avDriver.CurrentRoom.Config.Environment.DeviceKeys.Count > 0) { @@ -113,9 +113,9 @@ namespace PepperDash.Essentials var codecDriver = new PepperDash.Essentials.UIDrivers.VC.EssentialsVideoCodecUiDriver(panelController.Panel, avDriver, (room as EssentialsHuddleVtc1Room).VideoCodec, mainDriver.HeaderDriver); avDriver.SetVideoCodecDriver(codecDriver); - avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; avDriver.DefaultRoomKey = props.DefaultRoomKey; - mainDriver.AvDriver = avDriver; + mainDriver.AvDriver = avDriver; + avDriver.CurrentRoom = room as EssentialsHuddleVtc1Room; // Environment Driver if (avDriver.CurrentRoom.Config.Environment != null && avDriver.CurrentRoom.Config.Environment.DeviceKeys.Count > 0) diff --git a/PepperDashEssentials/PepperDashEssentials.csproj b/PepperDashEssentials/PepperDashEssentials.csproj index ef7284cf..b4bfc66a 100644 --- a/PepperDashEssentials/PepperDashEssentials.csproj +++ b/PepperDashEssentials/PepperDashEssentials.csproj @@ -1,227 +1,227 @@ - - - Release - AnyCPU - 9.0.30729 - 2.0 - {1BED5BA9-88C4-4365-9362-6F4B128071D3} - Library - Properties - PepperDash.Essentials - PepperDashEssentials - {0B4745B0-194B-4BB6-8E21-E9057CA92230};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - WindowsCE - E2BECB1F-8C8C-41ba-B736-9BE7D946A398 - 5.0 - SmartDeviceProject1 - v3.5 - Windows CE - - - - - .allowedReferenceRelatedFileExtensions - true - full - false - bin\ - DEBUG;TRACE; - prompt - 4 - 512 - true - true - off - - - .allowedReferenceRelatedFileExtensions - none - true - bin\ - prompt - 4 - 512 - true - true - off - - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll - - - - False - ..\essentials-framework\references\PepperDash_Core.dll - - - False - ..\essentials-framework\Essentials DM\Essentials_DM\bin\PepperDash_Essentials_DM.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe - - - False - ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} - PepperDash_Essentials_Core - - - {892B761C-E479-44CE-BD74-243E9214AF13} - Essentials Devices Common - - - - - - - - - rem S# Pro preparation will execute after these operations - + + + Release + AnyCPU + 9.0.30729 + 2.0 + {1BED5BA9-88C4-4365-9362-6F4B128071D3} + Library + Properties + PepperDash.Essentials + PepperDashEssentials + {0B4745B0-194B-4BB6-8E21-E9057CA92230};{4D628B5B-2FBC-4AA6-8C16-197242AEB884};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + WindowsCE + E2BECB1F-8C8C-41ba-B736-9BE7D946A398 + 5.0 + SmartDeviceProject1 + v3.5 + Windows CE + + + + + .allowedReferenceRelatedFileExtensions + true + full + false + bin\ + DEBUG;TRACE; + prompt + 4 + 512 + true + true + off + + + .allowedReferenceRelatedFileExtensions + none + true + bin\ + prompt + 4 + 512 + true + true + off + + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DeviceSupport.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.DM.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.EthernetCommunications.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Fusion.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.Remotes.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SSPDevices\Crestron.SimplSharpPro.UI.dll + + + + False + ..\essentials-framework\references\PepperDash_Core.dll + + + False + ..\essentials-framework\Essentials DM\Essentials_DM\bin\PepperDash_Essentials_DM.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpCustomAttributesInterface.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpHelperInterface.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpNewtonsoft.dll + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpPro.exe + + + False + ..\..\..\..\..\..\..\ProgramData\Crestron\SDK\SimplSharpReflectionInterface.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {A49AD6C8-FC0A-4CC0-9089-DFB4CF92D2B5} + PepperDash_Essentials_Core + + + {892B761C-E479-44CE-BD74-243E9214AF13} + Essentials Devices Common + + + + + + + + + rem S# Pro preparation will execute after these operations + \ No newline at end of file diff --git a/PepperDashEssentials/Properties/AssemblyInfo.cs b/PepperDashEssentials/Properties/AssemblyInfo.cs index 848e4f30..7541bd8a 100644 --- a/PepperDashEssentials/Properties/AssemblyInfo.cs +++ b/PepperDashEssentials/Properties/AssemblyInfo.cs @@ -4,5 +4,5 @@ [assembly: AssemblyCompany("PepperDash Technology Corp")] [assembly: AssemblyProduct("PepperDashEssentials")] [assembly: AssemblyCopyright("Copyright © PepperDash Technology Corp 2017")] -[assembly: AssemblyVersion("1.2.0.*")] +[assembly: AssemblyVersion("1.2.4.*")] diff --git a/PepperDashEssentials/UI/HttpLogoServer.cs b/PepperDashEssentials/UI/HttpLogoServer.cs index f04f6872..3bebbfd8 100644 --- a/PepperDashEssentials/UI/HttpLogoServer.cs +++ b/PepperDashEssentials/UI/HttpLogoServer.cs @@ -1,108 +1,118 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronIO; -using Crestron.SimplSharp.Net.Http; - -using PepperDash.Core; - -namespace PepperDash.Essentials -{ - public class HttpLogoServer - { - /// - /// - /// - HttpServer Server; - - /// - /// - /// - string FileDirectory; - - /// - /// - /// - public static Dictionary ExtensionContentTypes; - - /// - /// - /// - /// - /// - public HttpLogoServer(int port, string directory) - { - ExtensionContentTypes = new Dictionary - { - //{ ".css", "text/css" }, - //{ ".htm", "text/html" }, - //{ ".html", "text/html" }, - { ".jpg", "image/jpeg" }, - { ".jpeg", "image/jpeg" }, - //{ ".js", "application/javascript" }, - //{ ".json", "application/json" }, - //{ ".map", "application/x-navimap" }, - { ".pdf", "application.pdf" }, - { ".png", "image/png" }, - //{ ".txt", "text/plain" }, - }; - - Server = new HttpServer(); - Server.Port = port; - FileDirectory = directory; - Server.OnHttpRequest += new OnHttpRequestHandler(Server_OnHttpRequest); - Server.Open(); - - CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); - } - - /// - /// - /// - void Server_OnHttpRequest(object sender, OnHttpRequestArgs args) - { - var path = args.Request.Path; - if (File.Exists(FileDirectory + @"\" + path)) - { - string filePath = path.Replace('/', '\\'); - string localPath = string.Format(@"{0}{1}", FileDirectory, filePath); - if (File.Exists(localPath)) - { - args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension); - args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read); - } - else - { - args.Response.ContentString = string.Format("Not found: '{0}'", filePath); - args.Response.Code = 404; - } - } - } - - /// - /// - /// - void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) - { - if (programEventType == eProgramStatusEventType.Stopping) - Server.Close(); - } - - /// - /// - /// - /// - /// - public static string GetContentType(string extension) - { - string type; - if (ExtensionContentTypes.ContainsKey(extension)) - type = ExtensionContentTypes[extension]; - else - type = "text/plain"; - return type; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronIO; +using Crestron.SimplSharp.Net.Http; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials +{ + public class HttpLogoServer + { + /// + /// + /// + HttpServer Server; + + /// + /// + /// + string FileDirectory; + + /// + /// + /// + public static Dictionary ExtensionContentTypes; + + /// + /// + /// + /// + /// + public HttpLogoServer(int port, string directory) + { + ExtensionContentTypes = new Dictionary + { + //{ ".css", "text/css" }, + //{ ".htm", "text/html" }, + //{ ".html", "text/html" }, + { ".jpg", "image/jpeg" }, + { ".jpeg", "image/jpeg" }, + //{ ".js", "application/javascript" }, + //{ ".json", "application/json" }, + //{ ".map", "application/x-navimap" }, + { ".pdf", "application.pdf" }, + { ".png", "image/png" }, + //{ ".txt", "text/plain" }, + }; + + Server = new HttpServer(); + Server.Port = port; + FileDirectory = directory; + Server.OnHttpRequest += new OnHttpRequestHandler(Server_OnHttpRequest); + Server.Open(); + + CrestronEnvironment.ProgramStatusEventHandler += new ProgramStatusEventHandler(CrestronEnvironment_ProgramStatusEventHandler); + } + + /// + /// + /// + void Server_OnHttpRequest(object sender, OnHttpRequestArgs args) + { + var path = args.Request.Path; + Debug.Console(2, "HTTP Request with path: '{0}'", args.Request.Path); + + if (File.Exists(FileDirectory + path)) + { + string filePath = path.Replace('/', '\\'); + string localPath = string.Format(@"{0}{1}", FileDirectory, filePath); + + Debug.Console(2, "HTTP Logo Server attempting to find file: '{0}'", localPath); + if (File.Exists(localPath)) + { + args.Response.Header.ContentType = GetContentType(new FileInfo(localPath).Extension); + args.Response.ContentStream = new FileStream(localPath, FileMode.Open, FileAccess.Read); + } + else + { + Debug.Console(2, "HTTP Logo Server Cannot find file '{0}'", localPath); + args.Response.ContentString = string.Format("Not found: '{0}'", filePath); + args.Response.Code = 404; + } + } + else + { + Debug.Console(2, "HTTP Logo Server: '{0}' does not exist", FileDirectory + path); + } + } + + /// + /// + /// + void CrestronEnvironment_ProgramStatusEventHandler(eProgramStatusEventType programEventType) + { + if (programEventType == eProgramStatusEventType.Stopping) + Server.Close(); + } + + /// + /// + /// + /// + /// + public static string GetContentType(string extension) + { + string type; + if (ExtensionContentTypes.ContainsKey(extension)) + type = ExtensionContentTypes[extension]; + else + type = "text/plain"; + return type; + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs index c52f6b44..f5a16578 100644 --- a/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs +++ b/PepperDashEssentials/UI/JoinConstants/UIBoolJoin.cs @@ -485,7 +485,31 @@ namespace PepperDash.Essentials /// /// 3955 /// - public const uint HeaderIcon5Press = 3955; + public const uint HeaderIcon5Press = 3955; + + /// 3960 + /// + public const uint HeaderPopupCaretsSubpageVisibile = 3960; + /// + /// 3961 + /// + public const uint HeaderCaret1Visible = 3961; + /// + /// 3962 + /// + public const uint HeaderCaret2Visible = 3962; + /// + /// 3963 + /// + public const uint HeaderCaret3Visible = 3963; + /// + /// 3964 + /// + public const uint HeaderCaret4Visible = 3964; + /// + /// 3965 + /// + public const uint HeaderCaret5Visible = 3965; /// /// 3999 diff --git a/PepperDashEssentials/UIDrivers/Environment Drivers/EssentialsEnvironmentDriver.cs b/PepperDashEssentials/UIDrivers/Environment Drivers/EssentialsEnvironmentDriver.cs index bb931ce9..6b908739 100644 --- a/PepperDashEssentials/UIDrivers/Environment Drivers/EssentialsEnvironmentDriver.cs +++ b/PepperDashEssentials/UIDrivers/Environment Drivers/EssentialsEnvironmentDriver.cs @@ -1,251 +1,256 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.Config; -using PepperDash.Essentials.Core.Shades; -using PepperDash.Essentials.Core.Lighting; - -namespace PepperDash.Essentials -{ - public class EssentialsEnvironmentDriver : PanelDriverBase - { - /// - /// Do I need this here? - /// - CrestronTouchpanelPropertiesConfig Config; - - /// - /// The list of devices this driver is responsible for controlling - /// - public List Devices { get; private set; } - - /// - /// The parent driver for this - /// - EssentialsPanelMainInterfaceDriver Parent; - - /// - /// The list of sub drivers for the devices - /// - public List DeviceSubDrivers { get; private set; } - - public uint BackgroundSubpageJoin { get; private set; } - - public EssentialsEnvironmentDriver(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) - : base(parent.TriList) - { - Config = config; - Parent = parent; - - Devices = new List(); - DeviceSubDrivers = new List(); - - Parent.AvDriver.PopupInterlock.IsShownFeedback.OutputChange += IsShownFeedback_OutputChange; - - // Calculate the join offests for each device page and assign join actions for each button - } - - void IsShownFeedback_OutputChange(object sender, EventArgs e) - { - // Hide this driver and all sub drivers if popup interlock is not shown - if (Parent.AvDriver.PopupInterlock.IsShownFeedback.BoolValue == false) - { - foreach (var driver in DeviceSubDrivers) - { - driver.Hide(); - } - - base.Hide(); - } - } - - /// - /// Shows this driver and all sub drivers - /// - public override void Show() - { - Parent.AvDriver.PopupInterlock.ShowInterlockedWithToggle(BackgroundSubpageJoin); - - foreach (var driver in DeviceSubDrivers) - { - driver.Show(); - } - - base.Show(); - } - - /// - /// Hides this driver and all sub drivers - /// - public override void Hide() - { - Parent.AvDriver.PopupInterlock.HideAndClear(); - - foreach (var driver in DeviceSubDrivers) - { - driver.Hide(); - } - - base.Hide(); - } - - public override void Toggle() - { - if (IsVisible) - Hide(); - else - Show(); - } - - - /// - /// Reads the device keys from the config and gets the devices by key - /// - public void GetDevicesFromConfig(Room.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig) - { - if (EnvironmentPropertiesConfig != null) - { - Devices.Clear(); - DeviceSubDrivers.Clear(); - - uint column = 1; - - foreach (var dKey in EnvironmentPropertiesConfig.DeviceKeys) - { - var device = DeviceManager.GetDeviceForKey(dKey); - - if (device != null) - { - // Build the driver - var devicePanelDriver = GetPanelDriverForDevice(device, column); - - // Add new PanelDriverBase SubDriver - if (devicePanelDriver != null) - { - Devices.Add(device); - DeviceSubDrivers.Add(devicePanelDriver); - - Debug.Console(1, "Adding '{0}' to Environment Devices", device.Key); - - column++; - - - // Quit if device count is exceeded - if (column > 4) - break; - } - else - Debug.Console(1, "Unable to build environment driver for device: '{0}'", device.Key); - - } - - } - - SetupEnvironmentUiJoins(); - } - else - { - Debug.Console(1, "Unable to get devices from config. No EnvironmentPropertiesConfig object in room config"); - } - } - - /// - /// Returns the appropriate panel driver for the device - /// - /// - /// - /// - PanelDriverBase GetPanelDriverForDevice(IKeyed device, uint column) - { - PanelDriverBase panelDriver = null; - - uint buttonPressJoinBase = 0; - uint buttonVisibleJoinBase = 0; - uint stringJoinBase = 0; - uint shadeTypeVisibleBase = 0; - uint lightingTypeVisibleBase = 0; - - switch (column) - { - case 1: - { - buttonPressJoinBase = UIBoolJoin.EnvironmentColumnOneButtonPressBase; - buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnOneButtonVisibleBase; - stringJoinBase = UIStringJoin.EnvironmentColumnOneLabelBase; - shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnOneShadingTypeVisibleBase; - lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnOneLightingTypeVisibleBase; - break; - } - case 2: - { - buttonPressJoinBase = UIBoolJoin.EnvironmentColumnTwoButtonPressBase; - buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnTwoButtonVisibleBase; - stringJoinBase = UIStringJoin.EnvironmentColumnTwoLabelBase; - shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnTwoShadingTypeVisibleBase; - lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnTwoLightingTypeVisibleBase; - break; - } - case 3: - { - buttonPressJoinBase = UIBoolJoin.EnvironmentColumnThreeButtonPressBase; - buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnThreeButtonVisibleBase; - stringJoinBase = UIStringJoin.EnvironmentColumnThreeLabelBase; - shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnThreeShadingTypeVisibleBase; - lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnThreeLightingTypeVisibleBase; - break; - } - case 4: - { - buttonPressJoinBase = UIBoolJoin.EnvironmentColumnFourButtonPressBase; - buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnFourButtonVisibleBase; - stringJoinBase = UIStringJoin.EnvironmentColumnFourLabelBase; - shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnFourShadingTypeVisibleBase; - lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnFourLightingTypeVisibleBase; - break; - } - default: - { - Debug.Console(1, "Environment Driver: Invalid column number specified"); - break; - } - } - - // Determine if device is a shade or lighting type and construct the appropriate driver - if (device is ShadeBase) - { - panelDriver = new EssentialsShadeDriver(this, device.Key, buttonPressJoinBase, stringJoinBase, shadeTypeVisibleBase); - } - else if (device is LightingBase) - { - panelDriver = new EssentialsLightingDriver(this, device.Key, buttonPressJoinBase, buttonVisibleJoinBase, stringJoinBase, lightingTypeVisibleBase); - } - - // Return the driver - - return panelDriver; - } - - /// - /// Determines the join values for the generic environment subpages - /// - void SetupEnvironmentUiJoins() - { - // Calculate which background subpage join to use - BackgroundSubpageJoin = UIBoolJoin.EnvironmentBackgroundSubpageVisibleBase + (uint)DeviceSubDrivers.Count; - - - } - - } - - public interface IEnvironmentSubdriver - { - uint SubpageVisibleJoin { get; } - } - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.Config; +using PepperDash.Essentials.Core.Shades; +using PepperDash.Essentials.Core.Lighting; + +namespace PepperDash.Essentials +{ + public class EssentialsEnvironmentDriver : PanelDriverBase + { + /// + /// Do I need this here? + /// + CrestronTouchpanelPropertiesConfig Config; + + /// + /// The list of devices this driver is responsible for controlling + /// + public List Devices { get; private set; } + + /// + /// The parent driver for this + /// + EssentialsPanelMainInterfaceDriver Parent; + + /// + /// The list of sub drivers for the devices + /// + public List DeviceSubDrivers { get; private set; } + + public uint BackgroundSubpageJoin { get; private set; } + + public EssentialsEnvironmentDriver(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) + : base(parent.TriList) + { + Config = config; + Parent = parent; + + Devices = new List(); + DeviceSubDrivers = new List(); + + Parent.AvDriver.PopupInterlock.StatusChanged += new EventHandler(PopupInterlock_CurrentJoinChanged); + + // Calculate the join offests for each device page and assign join actions for each button + } + + void PopupInterlock_CurrentJoinChanged(object sender, StatusChangedEventArgs e) + { + // Hide this driver and all sub drivers if popup interlock is not shown + if (!e.IsShown || e.NewJoin != BackgroundSubpageJoin) + { + foreach (var driver in DeviceSubDrivers) + { + driver.Hide(); + } + + base.Hide(); + } + } + + void IsShownFeedback_OutputChange(object sender, EventArgs e) + { + + } + + /// + /// Shows this driver and all sub drivers + /// + public override void Show() + { + Parent.AvDriver.PopupInterlock.ShowInterlocked(BackgroundSubpageJoin); + + foreach (var driver in DeviceSubDrivers) + { + driver.Show(); + } + + base.Show(); + } + + /// + /// Hides this driver and all sub drivers + /// + public override void Hide() + { + Parent.AvDriver.PopupInterlock.HideAndClear(); + + foreach (var driver in DeviceSubDrivers) + { + driver.Hide(); + } + + base.Hide(); + } + + public override void Toggle() + { + if (IsVisible) + Hide(); + else + Show(); + } + + + /// + /// Reads the device keys from the config and gets the devices by key + /// + public void GetDevicesFromConfig(Room.Config.EssentialsEnvironmentPropertiesConfig EnvironmentPropertiesConfig) + { + if (EnvironmentPropertiesConfig != null) + { + Devices.Clear(); + DeviceSubDrivers.Clear(); + + uint column = 1; + + foreach (var dKey in EnvironmentPropertiesConfig.DeviceKeys) + { + var device = DeviceManager.GetDeviceForKey(dKey); + + if (device != null) + { + // Build the driver + var devicePanelDriver = GetPanelDriverForDevice(device, column); + + // Add new PanelDriverBase SubDriver + if (devicePanelDriver != null) + { + Devices.Add(device); + DeviceSubDrivers.Add(devicePanelDriver); + + Debug.Console(1, "Adding '{0}' to Environment Devices", device.Key); + + column++; + + + // Quit if device count is exceeded + if (column > 4) + break; + } + else + Debug.Console(1, "Unable to build environment driver for device: '{0}'", device.Key); + + } + + } + + SetupEnvironmentUiJoins(); + } + else + { + Debug.Console(1, "Unable to get devices from config. No EnvironmentPropertiesConfig object in room config"); + } + } + + /// + /// Returns the appropriate panel driver for the device + /// + /// + /// + /// + PanelDriverBase GetPanelDriverForDevice(IKeyed device, uint column) + { + PanelDriverBase panelDriver = null; + + uint buttonPressJoinBase = 0; + uint buttonVisibleJoinBase = 0; + uint stringJoinBase = 0; + uint shadeTypeVisibleBase = 0; + uint lightingTypeVisibleBase = 0; + + switch (column) + { + case 1: + { + buttonPressJoinBase = UIBoolJoin.EnvironmentColumnOneButtonPressBase; + buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnOneButtonVisibleBase; + stringJoinBase = UIStringJoin.EnvironmentColumnOneLabelBase; + shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnOneShadingTypeVisibleBase; + lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnOneLightingTypeVisibleBase; + break; + } + case 2: + { + buttonPressJoinBase = UIBoolJoin.EnvironmentColumnTwoButtonPressBase; + buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnTwoButtonVisibleBase; + stringJoinBase = UIStringJoin.EnvironmentColumnTwoLabelBase; + shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnTwoShadingTypeVisibleBase; + lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnTwoLightingTypeVisibleBase; + break; + } + case 3: + { + buttonPressJoinBase = UIBoolJoin.EnvironmentColumnThreeButtonPressBase; + buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnThreeButtonVisibleBase; + stringJoinBase = UIStringJoin.EnvironmentColumnThreeLabelBase; + shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnThreeShadingTypeVisibleBase; + lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnThreeLightingTypeVisibleBase; + break; + } + case 4: + { + buttonPressJoinBase = UIBoolJoin.EnvironmentColumnFourButtonPressBase; + buttonVisibleJoinBase = UIBoolJoin.EnvironmentColumnFourButtonVisibleBase; + stringJoinBase = UIStringJoin.EnvironmentColumnFourLabelBase; + shadeTypeVisibleBase = UIBoolJoin.EnvironmentColumnFourShadingTypeVisibleBase; + lightingTypeVisibleBase = UIBoolJoin.EnvironmentColumnFourLightingTypeVisibleBase; + break; + } + default: + { + Debug.Console(1, "Environment Driver: Invalid column number specified"); + break; + } + } + + // Determine if device is a shade or lighting type and construct the appropriate driver + if (device is ShadeBase) + { + panelDriver = new EssentialsShadeDriver(this, device.Key, buttonPressJoinBase, stringJoinBase, shadeTypeVisibleBase); + } + else if (device is LightingBase) + { + panelDriver = new EssentialsLightingDriver(this, device.Key, buttonPressJoinBase, buttonVisibleJoinBase, stringJoinBase, lightingTypeVisibleBase); + } + + // Return the driver + + return panelDriver; + } + + /// + /// Determines the join values for the generic environment subpages + /// + void SetupEnvironmentUiJoins() + { + // Calculate which background subpage join to use + BackgroundSubpageJoin = UIBoolJoin.EnvironmentBackgroundSubpageVisibleBase + (uint)DeviceSubDrivers.Count; + + + } + + } + + public interface IEnvironmentSubdriver + { + uint SubpageVisibleJoin { get; } + } + } \ No newline at end of file diff --git a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs index 4be934bb..1a51fb44 100644 --- a/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs +++ b/PepperDashEssentials/UIDrivers/Essentials/EssentialsHeaderDriver.cs @@ -1,266 +1,371 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro; -using Crestron.SimplSharpPro.UI; -using Crestron.SimplSharpPro.DeviceSupport; - - -using PepperDash.Core; -using PepperDash.Essentials.Core; -using PepperDash.Essentials.Core.SmartObjects; -using PepperDash.Essentials.Core.PageManagers; -using PepperDash.Essentials.Room.Config; -using PepperDash.Essentials.Devices.Common.Codec; -using PepperDash.Essentials.Devices.Common.VideoCodec; - - -namespace PepperDash.Essentials -{ - /// - /// - /// - public class EssentialsHeaderDriver : PanelDriverBase - { - CrestronTouchpanelPropertiesConfig Config; - - /// - /// The parent driver for this - /// - EssentialsPanelMainInterfaceDriver Parent; - - /// - /// Indicates that the SetHeaderButtons method has completed successfully - /// - public bool HeaderButtonsAreSetUp { get; private set; } - - StringInputSig HeaderCallButtonIconSig; - - public EssentialsHeaderDriver(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) - : base(parent.TriList) - { - Config = config; - Parent = parent; - } - - void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom) - { - // Gear - TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear"); - TriList.SetSigHeldAction(UIBoolJoin.HeaderIcon5Press, 2000, - avDriver.ShowTech, - null, - () => - { - if (currentRoom.OnFeedback.BoolValue) - avDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible); - else - avDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPagePowerOffVisible); - }); - TriList.SetSigFalseAction(UIBoolJoin.TechExitButton, () => - avDriver.PopupInterlock.HideAndClear()); - } - - void SetUpHelpButton(EssentialsRoomPropertiesConfig roomConf) - { - // Help roomConf and popup - if (roomConf.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, roomConf.HelpMessage); - TriList.SetBool(UIBoolJoin.HelpPageShowCallButtonVisible, false); - TriList.SetString(UIStringJoin.HelpPageCallButtonText, null); - TriList.ClearBoolSigAction(UIBoolJoin.HelpPageShowCallButtonPress); - } - TriList.SetString(UIStringJoin.HeaderButtonIcon4, "Help"); - TriList.SetSigFalseAction(UIBoolJoin.HeaderIcon4Press, () => - { - 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; - Parent.AvDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HelpPageVisible); - }); - } - - uint SetUpEnvironmentButton(EssentialsEnvironmentDriver environmentDriver, uint nextJoin) - { - if (environmentDriver != null) - { - TriList.SetString(nextJoin, "Lights"); - TriList.SetSigFalseAction(nextJoin, environmentDriver.Toggle); - nextJoin--; - return nextJoin; - } - else - return nextJoin; - } - - uint SetUpCalendarButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin) - { - // Calendar button - if (avDriver.CurrentRoom.ScheduleSource != null) - { - TriList.SetString(nextJoin, "Calendar"); - TriList.SetSigFalseAction(nextJoin, avDriver.CalendarPress); - - nextJoin--; - return nextJoin; - } - else - return nextJoin; - } - - uint SetUpCallButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin) - { - // Call button - TriList.SetString(nextJoin, "DND"); - TriList.SetSigFalseAction(nextJoin, avDriver.ShowActiveCallsList); - HeaderCallButtonIconSig = TriList.StringInput[nextJoin]; - - nextJoin--; - return nextJoin; - } - - /// - /// Evaluates the call status and sets the icon mode and text label - /// - public void ComputeHeaderCallStatus(VideoCodecBase codec) - { - if (codec == null) - { - Debug.Console(1, "ComputeHeaderCallStatus() cannot execute. codec is null"); - return; - } - - if (HeaderCallButtonIconSig == null) - { - Debug.Console(1, "ComputeHeaderCallStatus() cannot execute. HeaderCallButtonIconSig is null"); - return; - } - - // Set mode of header button - if (!codec.IsInCall) - { - HeaderCallButtonIconSig.StringValue = "DND"; - //HeaderCallButton.SetIcon(HeaderListButton.OnHook); - } - else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video)) - HeaderCallButtonIconSig.StringValue = "Misc-06_Dark"; - //HeaderCallButton.SetIcon(HeaderListButton.Camera); - //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2); - else - HeaderCallButtonIconSig.StringValue = "Misc-09_Dark"; - //HeaderCallButton.SetIcon(HeaderListButton.Phone); - //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1); - - // Set the call status text - if (codec.ActiveCalls.Count > 0) - { - if (codec.ActiveCalls.Count == 1) - TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "1 Active Call"); - else if (codec.ActiveCalls.Count > 1) - TriList.SetString(UIStringJoin.HeaderCallStatusLabel, string.Format("{0} Active Calls", codec.ActiveCalls.Count)); - } - else - TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "No Active Calls"); - } - - /// - /// Sets up Header Buttons for the EssentialsHuddleVtc1Room type - /// - public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom) - { - HeaderButtonsAreSetUp = false; - - TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); - - var roomConf = currentRoom.Config; - - SetUpGear(avDriver, currentRoom); - - SetUpHelpButton(roomConf); - - uint nextJoin = 3953; - - nextJoin = SetUpEnvironmentButton(Parent.EnvironmentDriver, nextJoin); - - nextJoin = SetUpCalendarButton(avDriver, nextJoin); - - nextJoin = SetUpCallButton(avDriver, nextJoin); - - // blank any that remain - for (var i = nextJoin; i > 3950; i--) - { - TriList.SetString(i, "Blank"); - TriList.SetSigFalseAction(i, () => { }); - } - - TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress, avDriver.ShowActiveCallsList); - - // Set Call Status Subpage Position - - if (nextJoin == 3951) - { - // Set to right position - TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, false); - TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, true); - } - else if (nextJoin == 3950) - { - // Set to left position - TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, true); - TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, false); - } - - HeaderButtonsAreSetUp = true; - - ComputeHeaderCallStatus(currentRoom.VideoCodec); - } - - /// - /// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type - /// - public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom) - { - HeaderButtonsAreSetUp = false; - - TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); - - var roomConf = currentRoom.Config; - - SetUpGear(avDriver, currentRoom); - - SetUpHelpButton(roomConf); - - uint nextJoin = 3953; - - nextJoin = SetUpEnvironmentButton(Parent.EnvironmentDriver, nextJoin); - - // blank any that remain - for (var i = nextJoin; i > 3950; i--) - { - TriList.SetString(i, "Blank"); - TriList.SetSigFalseAction(i, () => { }); - } - - HeaderButtonsAreSetUp = true; - } - - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro; +using Crestron.SimplSharpPro.UI; +using Crestron.SimplSharpPro.DeviceSupport; + + +using PepperDash.Core; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Core.SmartObjects; +using PepperDash.Essentials.Core.PageManagers; +using PepperDash.Essentials.Room.Config; +using PepperDash.Essentials.Devices.Common.Codec; +using PepperDash.Essentials.Devices.Common.VideoCodec; + + +namespace PepperDash.Essentials +{ + /// + /// + /// + public class EssentialsHeaderDriver : PanelDriverBase + { + uint EnvironmentCaretVisible; + uint CalendarCaretVisible; + uint CallCaretVisible; + + JoinedSigInterlock CaretInterlock; + + CrestronTouchpanelPropertiesConfig Config; + + /// + /// The parent driver for this + /// + EssentialsPanelMainInterfaceDriver Parent; + + /// + /// Indicates that the SetHeaderButtons method has completed successfully + /// + public bool HeaderButtonsAreSetUp { get; private set; } + + StringInputSig HeaderCallButtonIconSig; + + public EssentialsHeaderDriver(EssentialsPanelMainInterfaceDriver parent, CrestronTouchpanelPropertiesConfig config) + : base(parent.TriList) + { + Config = config; + Parent = parent; + CaretInterlock = new JoinedSigInterlock(TriList); + } + + void SetUpGear(IAVDriver avDriver, EssentialsRoomBase currentRoom) + { + // Gear + TriList.SetString(UIStringJoin.HeaderButtonIcon5, "Gear"); + TriList.SetSigHeldAction(UIBoolJoin.HeaderIcon5Press, 2000, + avDriver.ShowTech, + null, + () => + { + if (currentRoom.OnFeedback.BoolValue) + { + avDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPageVisible); + CaretInterlock.ShowInterlocked(UIBoolJoin.HeaderCaret5Visible); + } + else + { + avDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.VolumesPagePowerOffVisible); + CaretInterlock.ShowInterlocked(UIBoolJoin.HeaderCaret5Visible); + } + }); + TriList.SetSigFalseAction(UIBoolJoin.TechExitButton, () => + avDriver.PopupInterlock.HideAndClear()); + } + + void SetUpHelpButton(EssentialsRoomPropertiesConfig roomConf) + { + // Help roomConf and popup + if (roomConf.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, roomConf.HelpMessage); + TriList.SetBool(UIBoolJoin.HelpPageShowCallButtonVisible, false); + TriList.SetString(UIStringJoin.HelpPageCallButtonText, null); + TriList.ClearBoolSigAction(UIBoolJoin.HelpPageShowCallButtonPress); + } + TriList.SetString(UIStringJoin.HeaderButtonIcon4, "Help"); + TriList.SetSigFalseAction(UIBoolJoin.HeaderIcon4Press, () => + { + 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; + Parent.AvDriver.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.HelpPageVisible); + CaretInterlock.ShowInterlocked(UIBoolJoin.HeaderCaret4Visible); + }); + } + + uint SetUpEnvironmentButton(EssentialsEnvironmentDriver environmentDriver, uint nextJoin) + { + if (environmentDriver != null) + { + var tempJoin = nextJoin; + TriList.SetString(tempJoin, "Lights"); + EnvironmentCaretVisible = tempJoin + 10; + TriList.SetSigFalseAction(tempJoin, () => + { + environmentDriver.Toggle(); + CaretInterlock.ShowInterlocked(EnvironmentCaretVisible); + }); + nextJoin--; + return nextJoin; + } + else + return nextJoin; + } + + uint SetUpCalendarButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin) + { + // Calendar button + if (avDriver.CurrentRoom.ScheduleSource != null) + { + var tempJoin = nextJoin; + TriList.SetString(tempJoin, "Calendar"); + CalendarCaretVisible = tempJoin + 10; + TriList.SetSigFalseAction(tempJoin, () => + { + avDriver.CalendarPress(); + CaretInterlock.ShowInterlocked(CalendarCaretVisible); + }); + + nextJoin--; + return nextJoin; + } + else + return nextJoin; + } + + uint SetUpCallButton(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, uint nextJoin) + { + // Call button + var tempJoin = nextJoin; + TriList.SetString(tempJoin, "DND"); + CallCaretVisible = tempJoin + 10; + TriList.SetSigFalseAction(tempJoin, () => + { + avDriver.ShowActiveCallsList(); + if(avDriver.CurrentRoom.InCallFeedback.BoolValue) + CaretInterlock.ShowInterlocked(CallCaretVisible); + }); + HeaderCallButtonIconSig = TriList.StringInput[tempJoin]; + + nextJoin--; + return nextJoin; + } + + /// + /// Evaluates the call status and sets the icon mode and text label + /// + public void ComputeHeaderCallStatus(VideoCodecBase codec) + { + if (codec == null) + { + Debug.Console(1, "ComputeHeaderCallStatus() cannot execute. codec is null"); + return; + } + + if (HeaderCallButtonIconSig == null) + { + Debug.Console(1, "ComputeHeaderCallStatus() cannot execute. HeaderCallButtonIconSig is null"); + return; + } + + // Set mode of header button + if (!codec.IsInCall) + { + HeaderCallButtonIconSig.StringValue = "DND"; + //HeaderCallButton.SetIcon(HeaderListButton.OnHook); + } + else if (codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video)) + HeaderCallButtonIconSig.StringValue = "Misc-06_Dark"; + //HeaderCallButton.SetIcon(HeaderListButton.Camera); + //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2); + else + HeaderCallButtonIconSig.StringValue = "Misc-09_Dark"; + //HeaderCallButton.SetIcon(HeaderListButton.Phone); + //TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1); + + // Set the call status text + if (codec.ActiveCalls.Count > 0) + { + if (codec.ActiveCalls.Count == 1) + TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "1 Active Call"); + else if (codec.ActiveCalls.Count > 1) + TriList.SetString(UIStringJoin.HeaderCallStatusLabel, string.Format("{0} Active Calls", codec.ActiveCalls.Count)); + } + else + TriList.SetString(UIStringJoin.HeaderCallStatusLabel, "No Active Calls"); + } + + /// + /// Sets up Header Buttons for the EssentialsHuddleVtc1Room type + /// + public void SetupHeaderButtons(EssentialsHuddleVtc1PanelAvFunctionsDriver avDriver, EssentialsHuddleVtc1Room currentRoom) + { + HeaderButtonsAreSetUp = false; + + TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); + + var roomConf = currentRoom.Config; + + // Register for the PopupInterlock IsShowsFeedback event to tie the header carets subpage visiblity to it + Parent.AvDriver.PopupInterlock.StatusChanged -= PopupInterlock_StatusChanged; + Parent.AvDriver.PopupInterlock.StatusChanged += PopupInterlock_StatusChanged; + + SetUpGear(avDriver, currentRoom); + + SetUpHelpButton(roomConf); + + uint nextJoin = 3953; + + nextJoin = SetUpEnvironmentButton(Parent.EnvironmentDriver, nextJoin); + + nextJoin = SetUpCalendarButton(avDriver, nextJoin); + + nextJoin = SetUpCallButton(avDriver, nextJoin); + + // blank any that remain + for (var i = nextJoin; i > 3950; i--) + { + TriList.SetString(i, "Blank"); + TriList.SetSigFalseAction(i, () => { }); + } + + TriList.SetSigFalseAction(UIBoolJoin.HeaderCallStatusLabelPress, + () => + { + avDriver.ShowActiveCallsList(); + if (avDriver.CurrentRoom.InCallFeedback.BoolValue) + CaretInterlock.ShowInterlocked(CallCaretVisible); + }); + + // Set Call Status Subpage Position + + if (nextJoin == 3951) + { + // Set to right position + TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, false); + TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, true); + } + else if (nextJoin == 3950) + { + // Set to left position + TriList.SetBool(UIBoolJoin.HeaderCallStatusLeftPositionVisible, true); + TriList.SetBool(UIBoolJoin.HeaderCallStatusRightPositionVisible, false); + } + + HeaderButtonsAreSetUp = true; + + ComputeHeaderCallStatus(currentRoom.VideoCodec); + } + + /// + /// Sets up Header Buttons for the EssentialsHuddleSpaceRoom type + /// + public void SetupHeaderButtons(EssentialsHuddlePanelAvFunctionsDriver avDriver, EssentialsHuddleSpaceRoom currentRoom) + { + HeaderButtonsAreSetUp = false; + + TriList.SetBool(UIBoolJoin.TopBarHabaneroDynamicVisible, true); + + var roomConf = currentRoom.Config; + + // Register for the PopupInterlock IsShowsFeedback event to tie the header carets subpage visiblity to it + Parent.AvDriver.PopupInterlock.StatusChanged -= PopupInterlock_StatusChanged; + Parent.AvDriver.PopupInterlock.StatusChanged += PopupInterlock_StatusChanged; + + SetUpGear(avDriver, currentRoom); + + SetUpHelpButton(roomConf); + + uint nextJoin = 3953; + + nextJoin = SetUpEnvironmentButton(Parent.EnvironmentDriver, nextJoin); + + // blank any that remain + for (var i = nextJoin; i > 3950; i--) + { + TriList.SetString(i, "Blank"); + TriList.SetSigFalseAction(i, () => { }); + } + + HeaderButtonsAreSetUp = true; + } + + ///// + ///// Whenever a popup is shown/hidden, show/hide the header carets subpage and set the visibility of the correct caret + ///// + ///// + ///// + //void IsShownFeedback_OutputChange(object sender, EventArgs e) + //{ + // var popupInterlockIsShown = Parent.AvDriver.PopupInterlock.IsShown; + // // Set the visible state for the HeaderPopupCaretsSubpage to match that of the PopupInterlock state + // TriList.SetBool(UIBoolJoin.HeaderPopupCaretsSubpageVisibile, popupInterlockIsShown); + + // // Clear all caret visibility + // for (uint i = UIBoolJoin.HeaderCaret5Visible; i >= UIBoolJoin.HeaderCaret1Visible; i--) + // { + // TriList.SetBool(i, false); + // } + + // // Set the current caret visible if the popup is still shown + // if (popupInterlockIsShown) + // TriList.SetBool(NextCaretVisible, true); + //} + + /// + /// Whenever a popup is shown/hidden, show/hide the header carets subpage and set the visibility of the correct caret + /// + /// + /// + void PopupInterlock_StatusChanged(object sender, StatusChangedEventArgs e) + { + // Set the visible state for the HeaderPopupCaretsSubpage to match that of the PopupInterlock state + + bool headerPopupShown = false; + + // Check if the popup interlock is shown, and if one of the header popups is current, then show the carets subpage + if (e.IsShown) + { + if (e.NewJoin == Parent.EnvironmentDriver.BackgroundSubpageJoin) + headerPopupShown = true; + else if (e.NewJoin == UIBoolJoin.HeaderActiveCallsListVisible) + headerPopupShown = true; + else if (e.NewJoin == UIBoolJoin.HelpPageVisible) + headerPopupShown = true; + else if (e.NewJoin == UIBoolJoin.MeetingsOrContacMethodsListVisible) + headerPopupShown = true; + else if (e.NewJoin == UIBoolJoin.VolumesPagePowerOffVisible || e.NewJoin == UIBoolJoin.VolumesPageVisible) + headerPopupShown = true; + } + + // Set the carets subpage visibility + TriList.SetBool(UIBoolJoin.HeaderPopupCaretsSubpageVisibile, headerPopupShown); + + if (!e.IsShown) + CaretInterlock.HideAndClear(); + } + } } \ No newline at end of file diff --git a/PepperDashEssentials/UIDrivers/JoinedSigInterlock.cs b/PepperDashEssentials/UIDrivers/JoinedSigInterlock.cs index 18651e5f..04e01eb0 100644 --- a/PepperDashEssentials/UIDrivers/JoinedSigInterlock.cs +++ b/PepperDashEssentials/UIDrivers/JoinedSigInterlock.cs @@ -1,129 +1,175 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Crestron.SimplSharp; -using Crestron.SimplSharpPro.DeviceSupport; - -using PepperDash.Core; -using PepperDash.Essentials.Core; - -namespace PepperDash.Essentials -{ - public class JoinedSigInterlock - { - public uint CurrentJoin { get; private set; } - - BasicTriList TriList; - - public BoolFeedback IsShownFeedback; - - bool _IsShown; - - public bool IsShown - { - get - { - return _IsShown; - } - private set - { - _IsShown = value; - IsShownFeedback.FireUpdate(); - } - } - - //public BoolFeedback ShownFeedback { get; private set; } - - public JoinedSigInterlock(BasicTriList triList) - { - TriList = triList; - - IsShownFeedback = new BoolFeedback(new Func( () => _IsShown)); - } - - /// - /// Hides CurrentJoin and shows join. Will check and re-set signal if join - /// equals CurrentJoin - /// - public void ShowInterlocked(uint join) - { - Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join); - if (CurrentJoin == join && TriList.BooleanInput[join].BoolValue) - return; - SetButDontShow(join); - TriList.SetBool(CurrentJoin, true); - IsShown = true; - } - - /// - /// - /// - /// - public void ShowInterlockedWithToggle(uint join) - { - Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join); - if (CurrentJoin == join) - HideAndClear(); - else - { - if (CurrentJoin > 0) - TriList.BooleanInput[CurrentJoin].BoolValue = false; - CurrentJoin = join; - TriList.BooleanInput[CurrentJoin].BoolValue = true; - IsShown = true; - } - } - /// - /// Hides current join and clears CurrentJoin - /// - public void HideAndClear() - { - Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin); - Hide(); - CurrentJoin = 0; - } - - /// - /// Hides the current join but does not clear the selected join in case - /// it needs to be reshown - /// - public void Hide() - { - Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin); - if (CurrentJoin > 0) - { - TriList.BooleanInput[CurrentJoin].BoolValue = false; - IsShown = false; - } - } - - /// - /// If CurrentJoin is set, it restores that join - /// - public void Show() - { - Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin); - if (CurrentJoin > 0) - { - TriList.BooleanInput[CurrentJoin].BoolValue = true; - IsShown = true; - } - } - - /// - /// Useful for pre-setting the interlock but not enabling it. Sets CurrentJoin - /// - /// - public void SetButDontShow(uint join) - { - if (CurrentJoin > 0) - { - TriList.BooleanInput[CurrentJoin].BoolValue = false; - IsShown = false; - } - CurrentJoin = join; - } - - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; +using Crestron.SimplSharpPro.DeviceSupport; + +using PepperDash.Core; +using PepperDash.Essentials.Core; + +namespace PepperDash.Essentials +{ + public class JoinedSigInterlock + { + public uint CurrentJoin { get; private set; } + + BasicTriList TriList; + + public BoolFeedback IsShownFeedback; + + public event EventHandler StatusChanged; + + bool _IsShown; + + public bool IsShown + { + get + { + return _IsShown; + } + private set + { + _IsShown = value; + IsShownFeedback.FireUpdate(); + } + } + + //public BoolFeedback ShownFeedback { get; private set; } + + public JoinedSigInterlock(BasicTriList triList) + { + TriList = triList; + + IsShownFeedback = new BoolFeedback(new Func( () => _IsShown)); + } + + /// + /// Hides CurrentJoin and shows join. Will check and re-set signal if join + /// equals CurrentJoin + /// + public void ShowInterlocked(uint join) + { + var prevJoin = CurrentJoin; + var wasShown = _IsShown; + Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join); + if (CurrentJoin == join && TriList.BooleanInput[join].BoolValue) + return; + SetButDontShow(join); + TriList.SetBool(CurrentJoin, true); + IsShown = true; + + OnStatusChange(prevJoin, CurrentJoin, wasShown, IsShown); + } + + /// + /// + /// + /// + public void ShowInterlockedWithToggle(uint join) + { + var prevJoin = CurrentJoin; + var wasShown = IsShown; + + Debug.Console(2, "Trilist {0:X2}, interlock swapping {1} for {2}", TriList.ID, CurrentJoin, join); + if (CurrentJoin == join) + HideAndClear(); + else + { + if (CurrentJoin > 0) + TriList.BooleanInput[CurrentJoin].BoolValue = false; + CurrentJoin = join; + TriList.BooleanInput[CurrentJoin].BoolValue = true; + IsShown = true; + + OnStatusChange(prevJoin, CurrentJoin, wasShown, IsShown); + } + } + /// + /// Hides current join and clears CurrentJoin + /// + public void HideAndClear() + { + var prevJoin = CurrentJoin; + var wasShown = IsShown; + Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin); + Hide(); + CurrentJoin = 0; + + OnStatusChange(prevJoin, CurrentJoin, wasShown, IsShown); + } + + /// + /// Hides the current join but does not clear the selected join in case + /// it needs to be reshown + /// + public void Hide() + { + var prevJoin = CurrentJoin; + var wasShown = IsShown; + + Debug.Console(2, "Trilist {0:X2}, interlock hiding {1}", TriList.ID, CurrentJoin); + if (CurrentJoin > 0) + { + TriList.BooleanInput[CurrentJoin].BoolValue = false; + IsShown = false; + OnStatusChange(prevJoin, CurrentJoin, wasShown, IsShown); + } + } + + /// + /// If CurrentJoin is set, it restores that join + /// + public void Show() + { + var prevJoin = CurrentJoin; + var wasShown = IsShown; + + Debug.Console(2, "Trilist {0:X2}, interlock showing {1}", TriList.ID, CurrentJoin); + if (CurrentJoin > 0) + { + TriList.BooleanInput[CurrentJoin].BoolValue = true; + IsShown = true; + + OnStatusChange(prevJoin, CurrentJoin, wasShown, IsShown); + } + } + + /// + /// Useful for pre-setting the interlock but not enabling it. Sets CurrentJoin + /// + /// + public void SetButDontShow(uint join) + { + if (CurrentJoin > 0) + { + TriList.BooleanInput[CurrentJoin].BoolValue = false; + IsShown = false; + } + CurrentJoin = join; + } + + void OnStatusChange(uint prevJoin, uint newJoin, bool wasShown, bool isShown) + { + var handler = StatusChanged; + if (handler != null) + handler(this, new StatusChangedEventArgs(prevJoin, newJoin, wasShown, isShown)); + } + } + + public class StatusChangedEventArgs : EventArgs + { + public uint PreviousJoin { get; set; } + public uint NewJoin { get; set; } + public bool WasShown { get; set; } + public bool IsShown { get; set; } + + public StatusChangedEventArgs(uint prevJoin, uint newJoin, bool wasShown, bool isShown) + { + PreviousJoin = prevJoin; + NewJoin = newJoin; + WasShown = wasShown; + IsShown = isShown; + } + } } \ No newline at end of file diff --git a/essentials-framework b/essentials-framework index 8dbb67fd..570eda3f 160000 --- a/essentials-framework +++ b/essentials-framework @@ -1 +1 @@ -Subproject commit 8dbb67fda753e126de3f99e8814153410f8834bb +Subproject commit 570eda3fbd2bd8f8b40c112d065b2932573acc1e