mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-01 22:04:52 +00:00
Compare commits
15 Commits
1.8.5-alph
...
1.8.5-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4a3933743 | ||
|
|
d6445861f5 | ||
|
|
03b076c8eb | ||
|
|
7c58221acc | ||
|
|
14f7c27b33 | ||
|
|
9ea65883b7 | ||
|
|
9d0020d999 | ||
|
|
fb44a3b93c | ||
|
|
6b7c5c01f8 | ||
|
|
1a3eb9a546 | ||
|
|
44c171c8f4 | ||
|
|
ae9833ffaa | ||
|
|
e6f5142fc3 | ||
|
|
3c9ca1e527 | ||
|
|
e12a5e95bf |
@@ -72,7 +72,7 @@ namespace PepperDash.Essentials
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
foreach (var tl in TieLineCollection.Default)
|
||||
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
|
||||
CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl);
|
||||
},
|
||||
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
@@ -86,8 +86,8 @@ namespace PepperDash.Essentials
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(s =>
|
||||
{
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
|
||||
"System URL: {0}\r" +
|
||||
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
|
||||
"System URL: {0}\r\n" +
|
||||
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
|
||||
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);
|
||||
|
||||
|
||||
@@ -93,7 +93,8 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
if (prop.Name.ToLower() == "secret")
|
||||
{
|
||||
var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
|
||||
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>());
|
||||
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
|
||||
prop.Parent.Replace(secret);
|
||||
}
|
||||
var recurseProp = prop.Value as JObject;
|
||||
@@ -152,7 +153,9 @@ namespace PepperDash.Essentials.Core
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.Console(2, "Issue with getting device - {0}", ex.Message);
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
|
||||
|
||||
Debug.Console(2, "{0}", ex.StackTrace);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,25 +123,34 @@ namespace PepperDash.Essentials.Core
|
||||
// No direct tie? Run back out on the inputs' attached devices...
|
||||
// Only the ones that are routing devices
|
||||
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
|
||||
|
||||
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
|
||||
if (alreadyCheckedDevices == null)
|
||||
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
|
||||
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
|
||||
|
||||
foreach (var inputTieToTry in attachedMidpoints)
|
||||
{
|
||||
Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key);
|
||||
var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
|
||||
var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
|
||||
Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
|
||||
|
||||
// Check if this previous device has already been walked
|
||||
if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice)))
|
||||
{
|
||||
// haven't seen this device yet. Do it. Pass the output port to the next
|
||||
// level to enable switching on success
|
||||
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
||||
alreadyCheckedDevices, signalType, cycle, routeTable);
|
||||
if (upstreamRoutingSuccess)
|
||||
{
|
||||
Debug.Console(2, destination, "Upstream device route found");
|
||||
goodInputPort = inputTieToTry.DestinationPort;
|
||||
break; // Stop looping the inputs in this cycle
|
||||
}
|
||||
}
|
||||
if (alreadyCheckedDevices.Contains(upstreamRoutingDevice))
|
||||
{
|
||||
Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key);
|
||||
continue;
|
||||
}
|
||||
// haven't seen this device yet. Do it. Pass the output port to the next
|
||||
// level to enable switching on success
|
||||
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
|
||||
alreadyCheckedDevices, signalType, cycle, routeTable);
|
||||
if (upstreamRoutingSuccess)
|
||||
{
|
||||
Debug.Console(2, destination, "Upstream device route found");
|
||||
goodInputPort = inputTieToTry.DestinationPort;
|
||||
break; // Stop looping the inputs in this cycle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,10 +172,6 @@ namespace PepperDash.Essentials.Core
|
||||
//Debug.Console(2, destination, "Exiting cycle {0}", cycle);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(alreadyCheckedDevices == null)
|
||||
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
|
||||
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
|
||||
|
||||
Debug.Console(2, destination, "No route found to {0}", source.Key);
|
||||
return false;
|
||||
|
||||
@@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public string Key { get; set; }
|
||||
//Added for reference
|
||||
//private readonly bool _secureSupported;
|
||||
private static readonly bool SecureSupported;
|
||||
public CrestronSecretsProvider(string key)
|
||||
{
|
||||
Key = key;
|
||||
}
|
||||
|
||||
static CrestronSecretsProvider()
|
||||
{
|
||||
//Added for future encrypted reference
|
||||
//_secureSupported = CrestronSecureStorage.Supported;
|
||||
SecureSupported = CrestronSecureStorage.Supported;
|
||||
|
||||
//if (_secureSupported)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
CrestronDataStoreStatic.InitCrestronDataStore();
|
||||
|
||||
if (SecureSupported)
|
||||
{
|
||||
//doThingsFuture
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -30,23 +33,23 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
/// <param name="key">Secret Key</param>
|
||||
/// <param name="value">Secret Value</param>
|
||||
public void SetSecret(string key, object value)
|
||||
public bool SetSecret(string key, object value)
|
||||
{
|
||||
var secret = value as string;
|
||||
if (String.IsNullOrEmpty(secret))
|
||||
{
|
||||
Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
|
||||
switch (setErrorCode)
|
||||
{
|
||||
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
|
||||
Debug.Console(2, this,"Secret Successfully Set for {0}:{1}", Key, key);
|
||||
break;
|
||||
Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
|
||||
return true;
|
||||
default:
|
||||
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +71,7 @@ namespace PepperDash.Essentials.Core
|
||||
default:
|
||||
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
|
||||
Key, key, getErrorCode.ToString());
|
||||
return new CrestronSecret(key, String.Empty, this);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Core
|
||||
/// </summary>
|
||||
public interface ISecretProvider : IKeyed
|
||||
{
|
||||
void SetSecret(string key, object value);
|
||||
bool SetSecret(string key, object value);
|
||||
|
||||
ISecret GetSecret(string key);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Crestron.SimplSharp;
|
||||
using PepperDash.Core;
|
||||
|
||||
@@ -9,15 +8,16 @@ namespace PepperDash.Essentials.Core
|
||||
{
|
||||
public static class SecretsManager
|
||||
{
|
||||
public static List<ISecretProvider> Secrets { get; set; }
|
||||
public static Dictionary<string, ISecretProvider> Secrets { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the SecretsManager
|
||||
/// </summary>
|
||||
public static void Initialize()
|
||||
{
|
||||
Secrets = new List<ISecretProvider> {new CrestronSecretsProvider("default")};
|
||||
|
||||
|
||||
AddSecretProvider("default", new CrestronSecretsProvider("default"));
|
||||
|
||||
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
|
||||
"Adds secrets to secret provider",
|
||||
ConsoleAccessLevelEnum.AccessOperator);
|
||||
@@ -29,18 +29,24 @@ namespace PepperDash.Essentials.Core
|
||||
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
|
||||
"Deletes secrets in secret provider",
|
||||
ConsoleAccessLevelEnum.AccessAdministrator);
|
||||
|
||||
}
|
||||
|
||||
static SecretsManager()
|
||||
{
|
||||
Secrets = new Dictionary<string, ISecretProvider>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to return a ISecretProvider to Set, Get, and Delete Secrets
|
||||
/// Get Secret Provider from dictionary by key
|
||||
/// </summary>
|
||||
/// <param name="key">Secret Provider Key</param>
|
||||
/// <returns></returns>
|
||||
/// <param name="key">Dictionary Key for provider</param>
|
||||
/// <returns>ISecretProvider</returns>
|
||||
public static ISecretProvider GetSecretProviderByKey(string key)
|
||||
{
|
||||
var secret = Secrets.FirstOrDefault(o => o.Key == key);
|
||||
ISecretProvider secret;
|
||||
|
||||
Secrets.TryGetValue(key, out secret);
|
||||
|
||||
if (secret == null)
|
||||
{
|
||||
Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key);
|
||||
@@ -48,6 +54,44 @@ namespace PepperDash.Essentials.Core
|
||||
return secret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add secret provider to secrets dictionary
|
||||
/// </summary>
|
||||
/// <param name="key">Key of new entry</param>
|
||||
/// <param name="provider">New Provider Entry</param>
|
||||
public static void AddSecretProvider(string key, ISecretProvider provider)
|
||||
{
|
||||
if (!Secrets.ContainsKey(key))
|
||||
{
|
||||
Secrets.Add(key, provider);
|
||||
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add secret provider to secrets dictionary, with optional overwrite parameter
|
||||
/// </summary>
|
||||
/// <param name="key">Key of new entry</param>
|
||||
/// <param name="provider">New provider entry</param>
|
||||
/// <param name="overwrite">true to overwrite any existing providers in the dictionary</param>
|
||||
public static void AddSecretProvider(string key, ISecretProvider provider, bool overwrite)
|
||||
{
|
||||
if (!Secrets.ContainsKey(key))
|
||||
{
|
||||
Secrets.Add(key, provider);
|
||||
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
|
||||
|
||||
}
|
||||
if (overwrite)
|
||||
{
|
||||
Secrets.Add(key, provider);
|
||||
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key);
|
||||
|
||||
}
|
||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key);
|
||||
}
|
||||
|
||||
private static void SetSecretProcess(string cmd)
|
||||
{
|
||||
string response;
|
||||
@@ -76,7 +120,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
}
|
||||
|
||||
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||
var provider = GetSecretProviderByKey(args[0]);
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
@@ -92,11 +136,14 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
if (provider.GetSecret(key) == null)
|
||||
{
|
||||
provider.SetSecret(key, secret);
|
||||
response =
|
||||
String.Format(
|
||||
|
||||
response = provider.SetSecret(key, secret)
|
||||
? String.Format(
|
||||
"Secret successfully set for {0}:{1}",
|
||||
provider.Key, key);
|
||||
provider.Key, key)
|
||||
: String.Format(
|
||||
"Unable to set secret for {0}:{1}",
|
||||
provider.Key, key);
|
||||
CrestronConsole.ConsoleCommandResponse(response);
|
||||
return;
|
||||
}
|
||||
@@ -137,7 +184,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
}
|
||||
|
||||
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||
var provider = GetSecretProviderByKey(args[0]);
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
@@ -153,10 +200,12 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
if (provider.GetSecret(key) != null)
|
||||
{
|
||||
provider.SetSecret(key, secret);
|
||||
response =
|
||||
String.Format(
|
||||
"Secret successfully updated for {0}:{1}",
|
||||
response = provider.SetSecret(key, secret)
|
||||
? String.Format(
|
||||
"Secret successfully set for {0}:{1}",
|
||||
provider.Key, key)
|
||||
: String.Format(
|
||||
"Unable to set secret for {0}:{1}",
|
||||
provider.Key, key);
|
||||
CrestronConsole.ConsoleCommandResponse(response);
|
||||
return;
|
||||
@@ -199,7 +248,7 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
}
|
||||
|
||||
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||
var provider = GetSecretProviderByKey(args[0]);
|
||||
|
||||
if (provider == null)
|
||||
{
|
||||
@@ -214,11 +263,15 @@ namespace PepperDash.Essentials.Core
|
||||
|
||||
|
||||
provider.SetSecret(key, "");
|
||||
response =
|
||||
String.Format(
|
||||
response = provider.SetSecret(key, "")
|
||||
? String.Format(
|
||||
"Secret successfully deleted for {0}:{1}",
|
||||
provider.Key, key)
|
||||
: String.Format(
|
||||
"Unable to delete secret for {0}:{1}",
|
||||
provider.Key, key);
|
||||
CrestronConsole.ConsoleCommandResponse(response);
|
||||
return;
|
||||
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -176,6 +176,7 @@
|
||||
<Compile Include="VideoCodec\ZoomRoom\ResponseObjects.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoom.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomCamera.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomJoinMap.cs" />
|
||||
<Compile Include="VideoCodec\ZoomRoom\ZoomRoomPropertiesConfig.cs" />
|
||||
<None Include="Properties\ControlSystem.cfg" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -19,4 +19,32 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
void LocalLayoutToggleSingleProminent();
|
||||
void MinMaxLayoutToggle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the requirements for Zoom Room layout control
|
||||
/// </summary>
|
||||
public interface IHasZoomRoomLayouts : IHasCodecLayouts
|
||||
{
|
||||
event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
|
||||
|
||||
BoolFeedback LayoutViewIsOnFirstPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func
|
||||
BoolFeedback LayoutViewIsOnLastPageFeedback { get; } // TODO: #697 Consider modifying to report button visibility in func
|
||||
BoolFeedback CanSwapContentWithThumbnailFeedback { get; }
|
||||
BoolFeedback ContentSwappedWithThumbnailFeedback { get; }
|
||||
|
||||
ZoomRoom.zConfiguration.eLayoutStyle LastSelectedLayout { get; }
|
||||
ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; }
|
||||
|
||||
void GetAvailableLayouts(); // Mot sure this is necessary if we're already subscribed to zStatus Call Layout
|
||||
void SetLayout(ZoomRoom.zConfiguration.eLayoutStyle layoutStyle);
|
||||
void SwapContentWithThumbnail();
|
||||
|
||||
void LayoutTurnNextPage();
|
||||
void LayoutTurnPreviousPage();
|
||||
}
|
||||
|
||||
public class LayoutInfoChangedEventArgs : EventArgs
|
||||
{
|
||||
public ZoomRoom.zConfiguration.eLayoutStyle AvailableLayouts { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -271,6 +271,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
public abstract void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge);
|
||||
|
||||
/// <summary>
|
||||
/// Use this method when using a plain VideoCodecControllerJoinMap
|
||||
/// </summary>
|
||||
/// <param name="codec"></param>
|
||||
/// <param name="trilist"></param>
|
||||
/// <param name="joinStart"></param>
|
||||
/// <param name="joinMapKey"></param>
|
||||
/// <param name="bridge"></param>
|
||||
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, uint joinStart, string joinMapKey,
|
||||
EiscApiAdvanced bridge)
|
||||
{
|
||||
@@ -288,136 +296,145 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
||||
|
||||
|
||||
|
||||
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecContentSharingToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecPrivacyToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecVolumeToApi(trilist, joinMap);
|
||||
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecCameras)
|
||||
{
|
||||
LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecSelfView)
|
||||
{
|
||||
LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
|
||||
LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
|
||||
LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecLayouts)
|
||||
{
|
||||
LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasSelfviewPosition)
|
||||
{
|
||||
LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasDirectory)
|
||||
{
|
||||
LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasScheduleAwareness)
|
||||
{
|
||||
LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasParticipants)
|
||||
{
|
||||
LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasFarEndContentStatus)
|
||||
{
|
||||
(codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
if (codec is IHasDirectory)
|
||||
{
|
||||
(codec as IHasDirectory).SetCurrentDirectoryToRoot();
|
||||
}
|
||||
|
||||
if (codec is IHasScheduleAwareness)
|
||||
{
|
||||
(codec as IHasScheduleAwareness).GetSchedule();
|
||||
}
|
||||
|
||||
if (codec is IHasParticipants)
|
||||
{
|
||||
UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
|
||||
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCodecSelfView)
|
||||
{
|
||||
(codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
(codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
(codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
SharingContentIsOnFeedback.FireUpdate();
|
||||
|
||||
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
|
||||
|
||||
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
|
||||
};
|
||||
LinkVideoCodecToApi(codec, trilist, joinMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this method when you need to pass in a join map that extends VideoCodecControllerJoinMap
|
||||
/// </summary>
|
||||
/// <param name="codec"></param>
|
||||
/// <param name="trilist"></param>
|
||||
/// <param name="joinMap"></param>
|
||||
protected void LinkVideoCodecToApi(VideoCodecBase codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
Debug.Console(1, this, "Linking to Trilist {0}", trilist.ID.ToString("X"));
|
||||
|
||||
LinkVideoCodecDtmfToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecContentSharingToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecPrivacyToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecVolumeToApi(trilist, joinMap);
|
||||
|
||||
if (codec is ICommunicationMonitor)
|
||||
{
|
||||
LinkVideoCodecCommMonitorToApi(codec as ICommunicationMonitor, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecCameras)
|
||||
{
|
||||
LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecSelfView)
|
||||
{
|
||||
LinkVideoCodecSelfviewToApi(codec as IHasCodecSelfView, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, SupportsCameraAutoMode);
|
||||
LinkVideoCodecCameraModeToApi(codec as IHasCameraAutoMode, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsOffMode.JoinNumber, SupportsCameraOff);
|
||||
LinkVideoCodecCameraOffToApi(codec as IHasCameraOff, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasCodecLayouts)
|
||||
{
|
||||
LinkVideoCodecCameraLayoutsToApi(codec as IHasCodecLayouts, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasSelfviewPosition)
|
||||
{
|
||||
LinkVideoCodecSelfviewPositionToApi(codec as IHasSelfviewPosition, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasDirectory)
|
||||
{
|
||||
LinkVideoCodecDirectoryToApi(codec as IHasDirectory, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasScheduleAwareness)
|
||||
{
|
||||
LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasParticipants)
|
||||
{
|
||||
LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasFarEndContentStatus)
|
||||
{
|
||||
(codec as IHasFarEndContentStatus).ReceivingContent.LinkInputSig(trilist.BooleanInput[joinMap.RecievingContent.JoinNumber]);
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
LinkVideoCodecPhoneToApi(codec as IHasPhoneDialing, trilist, joinMap);
|
||||
}
|
||||
|
||||
trilist.OnlineStatusChange += (device, args) =>
|
||||
{
|
||||
if (!args.DeviceOnLine) return;
|
||||
|
||||
if (codec is IHasDirectory)
|
||||
{
|
||||
(codec as IHasDirectory).SetCurrentDirectoryToRoot();
|
||||
}
|
||||
|
||||
if (codec is IHasScheduleAwareness)
|
||||
{
|
||||
(codec as IHasScheduleAwareness).GetSchedule();
|
||||
}
|
||||
|
||||
if (codec is IHasParticipants)
|
||||
{
|
||||
UpdateParticipantsXSig((codec as IHasParticipants).Participants.CurrentParticipants);
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
trilist.SetBool(joinMap.CameraSupportsAutoMode.JoinNumber, true);
|
||||
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCodecSelfView)
|
||||
{
|
||||
(codec as IHasCodecSelfView).SelfviewIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCameraAutoMode)
|
||||
{
|
||||
(codec as IHasCameraAutoMode).CameraAutoModeIsOnFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasCameraOff)
|
||||
{
|
||||
(codec as IHasCameraOff).CameraIsOffFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
if (codec is IHasPhoneDialing)
|
||||
{
|
||||
(codec as IHasPhoneDialing).PhoneOffHookFeedback.FireUpdate();
|
||||
}
|
||||
|
||||
SharingContentIsOnFeedback.FireUpdate();
|
||||
|
||||
trilist.SetBool(joinMap.HookState.JoinNumber, IsInCall);
|
||||
|
||||
trilist.SetString(joinMap.CurrentCallData.JoinNumber, UpdateCallStatusXSig());
|
||||
};
|
||||
}
|
||||
|
||||
private void LinkVideoCodecPhoneToApi(IHasPhoneDialing codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
codec.PhoneOffHookFeedback.LinkInputSig(trilist.BooleanInput[joinMap.PhoneHookState.JoinNumber]);
|
||||
|
||||
@@ -551,18 +551,136 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
}
|
||||
|
||||
public class Layout
|
||||
public class Layout : NotifiableObject
|
||||
{
|
||||
// backer variables
|
||||
private bool _can_Switch_Speaker_View;
|
||||
private bool _can_Switch_Wall_View;
|
||||
private bool _can_Switch_Share_On_All_Screens;
|
||||
private bool _is_In_First_Page;
|
||||
private bool _is_In_Last_Page;
|
||||
private string _video_type;
|
||||
|
||||
|
||||
public bool can_Adjust_Floating_Video { get; set; }
|
||||
public bool can_Switch_Floating_Share_Content { get; set; }
|
||||
public bool can_Switch_Share_On_All_Screens { get; set; }
|
||||
public bool can_Switch_Speaker_View { get; set; }
|
||||
public bool can_Switch_Wall_View { get; set; }
|
||||
public bool is_In_First_Page { get; set; }
|
||||
public bool is_In_Last_Page { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [on/off] // Set to On if it is possible to invoke zConfiguration Call Layout Style: ShareAll, to switch to the ShareAll mode, where the content sharing is shown full screen on all monitors.
|
||||
/// </summary>
|
||||
[JsonProperty("can_Switch_Share_On_All_Screens")]
|
||||
public bool can_Switch_Share_On_All_Screens
|
||||
{
|
||||
get
|
||||
{
|
||||
return _can_Switch_Share_On_All_Screens;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _can_Switch_Share_On_All_Screens)
|
||||
{
|
||||
_can_Switch_Share_On_All_Screens = value;
|
||||
NotifyPropertyChanged("can_Switch_Share_On_All_Screens");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [on/off] // Set to On if it is possible to switch to Speaker view by invoking zConfiguration Call Layout Style: Speaker. The active speaker is shown full screen, and other video streams, like self-view, are shown in thumbnails.
|
||||
/// </summary>
|
||||
[JsonProperty("can_Switch_Speaker_View")]
|
||||
public bool can_Switch_Speaker_View
|
||||
{
|
||||
get
|
||||
{
|
||||
return _can_Switch_Speaker_View;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _can_Switch_Speaker_View)
|
||||
{
|
||||
_can_Switch_Speaker_View = value;
|
||||
NotifyPropertyChanged("can_Switch_Speaker_View");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [on/off] On if it is possible to invoke zConfiguration Call Layout Style: Gallery, to switch to the Gallery mode, showing video participants in tiled windows: The Zoom Room shows up to a 5x5 array of tiled windows per page.
|
||||
/// </summary>
|
||||
[JsonProperty("can_Switch_Wall_View")]
|
||||
public bool can_Switch_Wall_View
|
||||
{
|
||||
get
|
||||
{
|
||||
return _can_Switch_Wall_View;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _can_Switch_Wall_View)
|
||||
{
|
||||
_can_Switch_Wall_View = value;
|
||||
NotifyPropertyChanged("can_Switch_Wall_View");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("is_In_First_Page")]
|
||||
public bool is_In_First_Page
|
||||
{
|
||||
get
|
||||
{
|
||||
return _is_In_First_Page;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _is_In_First_Page)
|
||||
{
|
||||
_is_In_First_Page = value;
|
||||
NotifyPropertyChanged("is_In_First_Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("is_In_Last_Page")]
|
||||
public bool is_In_Last_Page
|
||||
{
|
||||
get
|
||||
{
|
||||
return _is_In_Last_Page;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _is_In_Last_Page)
|
||||
{
|
||||
_is_In_Last_Page = value;
|
||||
NotifyPropertyChanged("is_In_Last_Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool is_supported { get; set; }
|
||||
public int video_Count_In_Current_Page { get; set; }
|
||||
public string video_type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [Gallery | Strip] Indicates which mode applies: Strip or Gallery.
|
||||
/// </summary>
|
||||
[JsonProperty("video_type")]
|
||||
public string video_type
|
||||
{
|
||||
get
|
||||
{
|
||||
return _video_type;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _video_type)
|
||||
{
|
||||
_video_type = value;
|
||||
NotifyPropertyChanged("video_type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CallRecordInfo
|
||||
@@ -835,12 +953,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum eLayoutStyle
|
||||
{
|
||||
Gallery,
|
||||
Speaker,
|
||||
Strip,
|
||||
ShareAll
|
||||
None = 0,
|
||||
Gallery = 1,
|
||||
Speaker = 2,
|
||||
Strip = 4,
|
||||
ShareAll = 8,
|
||||
}
|
||||
|
||||
public enum eLayoutSize
|
||||
@@ -865,20 +985,64 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
DownLeft
|
||||
}
|
||||
|
||||
public class Layout:NotifiableObject
|
||||
public class Layout : NotifiableObject
|
||||
{
|
||||
public bool ShareThumb { get; set; }
|
||||
public eLayoutStyle Style { get; set; }
|
||||
public eLayoutSize Size { get; set; }
|
||||
|
||||
private bool _shareThumb;
|
||||
private eLayoutStyle _style;
|
||||
private eLayoutSize _size;
|
||||
private eLayoutPosition _position;
|
||||
public eLayoutPosition Position {
|
||||
|
||||
public bool ShareThumb
|
||||
{
|
||||
get { return _shareThumb; }
|
||||
set
|
||||
{
|
||||
if (value != _shareThumb)
|
||||
{
|
||||
_shareThumb = value;
|
||||
NotifyPropertyChanged("ShareThumb");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public eLayoutStyle Style
|
||||
{
|
||||
get { return _style; }
|
||||
set
|
||||
{
|
||||
if (value != _style)
|
||||
{
|
||||
_style = value;
|
||||
NotifyPropertyChanged("Style");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public eLayoutSize Size
|
||||
{
|
||||
get { return _size; }
|
||||
set
|
||||
{
|
||||
if (value != _size)
|
||||
{
|
||||
_size = value;
|
||||
NotifyPropertyChanged("Size");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public eLayoutPosition Position
|
||||
{
|
||||
get { return _position; }
|
||||
set
|
||||
{
|
||||
_position = value;
|
||||
NotifyPropertyChanged("Position");
|
||||
} }
|
||||
if (value != _position)
|
||||
{
|
||||
_position = value;
|
||||
NotifyPropertyChanged("Position");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Lock
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
||||
IRouting,
|
||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants, IHasCameraOff, IHasCameraMute, IHasCameraAutoMode,
|
||||
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing
|
||||
IHasFarEndContentStatus, IHasSelfviewPosition, IHasPhoneDialing, IHasZoomRoomLayouts
|
||||
{
|
||||
private const long MeetingRefreshTimer = 60000;
|
||||
private const uint DefaultMeetingDurationMin = 30;
|
||||
@@ -121,6 +121,17 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
PhoneOffHookFeedback = new BoolFeedback(PhoneOffHookFeedbackFunc);
|
||||
CallerIdNameFeedback = new StringFeedback(CallerIdNameFeedbackFunc);
|
||||
CallerIdNumberFeedback = new StringFeedback(CallerIdNumberFeedbackFunc);
|
||||
|
||||
LocalLayoutFeedback = new StringFeedback(LocalLayoutFeedbackFunc);
|
||||
|
||||
LayoutViewIsOnFirstPageFeedback = new BoolFeedback(LayoutViewIsOnFirstPageFeedbackFunc);
|
||||
|
||||
LayoutViewIsOnLastPageFeedback = new BoolFeedback(LayoutViewIsOnLastPageFeedbackFunc);
|
||||
|
||||
CanSwapContentWithThumbnailFeedback = new BoolFeedback(CanSwapContentWithThumbnailFeedbackFunc);
|
||||
|
||||
ContentSwappedWithThumbnailFeedback = new BoolFeedback(ContentSwappedWithThumbnailFeedbackFunc);
|
||||
|
||||
}
|
||||
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
@@ -216,11 +227,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
}
|
||||
|
||||
protected Func<string> LocalLayoutFeedbackFunc
|
||||
{
|
||||
get { return () => ""; }
|
||||
}
|
||||
|
||||
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
@@ -484,11 +490,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
Configuration.Call.Layout.PropertyChanged += (o, a) =>
|
||||
{
|
||||
if (a.PropertyName != "Position") return;
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "Position":
|
||||
{
|
||||
ComputeSelfviewPipStatus();
|
||||
|
||||
ComputeSelfviewPipStatus();
|
||||
SelfviewPipPositionFeedback.FireUpdate();
|
||||
|
||||
SelfviewPipPositionFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "ShareThumb":
|
||||
{
|
||||
ContentSwappedWithThumbnailFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "Style":
|
||||
{
|
||||
LocalLayoutFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
Status.Call.Sharing.PropertyChanged += (o, a) =>
|
||||
@@ -542,6 +565,39 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
Status.Layout.PropertyChanged += (o, a) =>
|
||||
{
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "can_Switch_Speaker_View":
|
||||
case "can_Switch_Wall_View":
|
||||
case "can_Switch_Share_On_All_Screens":
|
||||
{
|
||||
// #697 TODO: Calls the method to compute the available layouts and set the value of AvailableLayouts enum
|
||||
ComputeAvailableLayouts();
|
||||
break;
|
||||
}
|
||||
case "is_In_First_Page":
|
||||
{
|
||||
// TODO: #697 Fires appropriate feedback
|
||||
LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "is_In_Last_Page":
|
||||
{
|
||||
// TODO: #697 Fires appropriate feedback
|
||||
LayoutViewIsOnLastPageFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
//case "video_type":
|
||||
// {
|
||||
// // TODO: #697 It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
|
||||
// LocalLayoutFeedback.FireUpdate();
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void SetUpDirectory()
|
||||
@@ -1600,7 +1656,75 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public override void LinkToApi(BasicTriList trilist, uint joinStart, string joinMapKey, EiscApiAdvanced bridge)
|
||||
{
|
||||
LinkVideoCodecToApi(this, trilist, joinStart, joinMapKey, bridge);
|
||||
var joinMap = new ZoomRoomJoinMap(joinStart);
|
||||
|
||||
var customJoins = JoinMapHelper.TryGetJoinMapAdvancedForDevice(joinMapKey);
|
||||
|
||||
if (customJoins != null)
|
||||
{
|
||||
joinMap.SetCustomJoinData(customJoins);
|
||||
}
|
||||
|
||||
if (bridge != null)
|
||||
{
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
|
||||
LinkVideoCodecToApi(this, trilist, joinMap);
|
||||
|
||||
LinkZoomRoomToApi(trilist, joinMap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Links all the specific Zoom functionality to the API bridge
|
||||
/// </summary>
|
||||
/// <param name="trilist"></param>
|
||||
/// <param name="joinMap"></param>
|
||||
public void LinkZoomRoomToApi(BasicTriList trilist, ZoomRoomJoinMap joinMap)
|
||||
{
|
||||
var codec = this as IHasZoomRoomLayouts;
|
||||
|
||||
if (codec != null)
|
||||
{
|
||||
codec.AvailableLayoutsChanged += (o, a) =>
|
||||
{
|
||||
trilist.SetBool(joinMap.LayoutGalleryIsAvailable.JoinNumber, a.AvailableLayouts
|
||||
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Gallery));
|
||||
trilist.SetBool(joinMap.LayoutSpeakerIsAvailable.JoinNumber, a.AvailableLayouts
|
||||
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Speaker));
|
||||
trilist.SetBool(joinMap.LayoutStripIsAvailable.JoinNumber, a.AvailableLayouts
|
||||
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.Strip));
|
||||
trilist.SetBool(joinMap.LayoutShareAllIsAvailable.JoinNumber, a.AvailableLayouts
|
||||
== (a.AvailableLayouts & zConfiguration.eLayoutStyle.ShareAll));
|
||||
};
|
||||
|
||||
codec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
|
||||
trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => codec.SwapContentWithThumbnail());
|
||||
codec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
|
||||
|
||||
codec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]);
|
||||
codec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]);
|
||||
trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => codec.LayoutTurnNextPage() );
|
||||
trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => codec.LayoutTurnPreviousPage());
|
||||
|
||||
|
||||
trilist.SetStringSigAction(joinMap.GetSetCurrentLayout.JoinNumber, (s) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var style = (zConfiguration.eLayoutStyle)Enum.Parse(typeof(zConfiguration.eLayoutStyle), s, true);
|
||||
SetLayout(style);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Console(2, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e);
|
||||
}
|
||||
});
|
||||
|
||||
codec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteSwitch(object selector)
|
||||
@@ -1899,6 +2023,123 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasZoomRoomLayouts Members
|
||||
|
||||
public event EventHandler<LayoutInfoChangedEventArgs> AvailableLayoutsChanged;
|
||||
|
||||
private Func<bool> LayoutViewIsOnFirstPageFeedbackFunc {get {return () => Status.Layout.is_In_First_Page; } }
|
||||
private Func<bool> LayoutViewIsOnLastPageFeedbackFunc { get { return () => Status.Layout.is_In_Last_Page; } }
|
||||
private Func<bool> CanSwapContentWithThumbnailFeedbackFunc { get { return () => Status.Layout.can_Switch_Floating_Share_Content; } }
|
||||
private Func<bool> ContentSwappedWithThumbnailFeedbackFunc { get { return () => Configuration.Call.Layout.ShareThumb; } }
|
||||
|
||||
public BoolFeedback LayoutViewIsOnFirstPageFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback LayoutViewIsOnLastPageFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback CanSwapContentWithThumbnailFeedback { get; private set; }
|
||||
|
||||
public BoolFeedback ContentSwappedWithThumbnailFeedback { get; private set; }
|
||||
|
||||
|
||||
public zConfiguration.eLayoutStyle LastSelectedLayout { get; private set; }
|
||||
|
||||
public zConfiguration.eLayoutStyle AvailableLayouts { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Reads individual properties to determine if which layouts are avalailable
|
||||
/// </summary>
|
||||
private void ComputeAvailableLayouts()
|
||||
{
|
||||
zConfiguration.eLayoutStyle availableLayouts = zConfiguration.eLayoutStyle.None;
|
||||
//TODO: #697 Compute the avaialble layouts and set the value of AvailableLayouts
|
||||
if (Status.Layout.can_Switch_Wall_View)
|
||||
{
|
||||
availableLayouts |= zConfiguration.eLayoutStyle.Gallery;
|
||||
}
|
||||
|
||||
if (Status.Layout.can_Switch_Speaker_View)
|
||||
{
|
||||
availableLayouts |= zConfiguration.eLayoutStyle.Speaker;
|
||||
}
|
||||
|
||||
if (Status.Layout.can_Switch_Share_On_All_Screens)
|
||||
{
|
||||
availableLayouts |= zConfiguration.eLayoutStyle.ShareAll;
|
||||
}
|
||||
|
||||
// There is no property that directly reports if strip mode is valid, but API stipulates
|
||||
// that strip mode is available if the number of screens is 1
|
||||
if (Status.NumberOfScreens.NumOfScreens == 1)
|
||||
{
|
||||
availableLayouts |= zConfiguration.eLayoutStyle.Strip;
|
||||
}
|
||||
|
||||
var handler = AvailableLayoutsChanged;
|
||||
if (handler != null)
|
||||
{
|
||||
handler(this, new LayoutInfoChangedEventArgs() { AvailableLayouts = availableLayouts });
|
||||
}
|
||||
|
||||
AvailableLayouts = availableLayouts;
|
||||
}
|
||||
|
||||
public void GetAvailableLayouts()
|
||||
{
|
||||
SendText("zStatus Call Layout");
|
||||
}
|
||||
|
||||
public void SetLayout(zConfiguration.eLayoutStyle layoutStyle)
|
||||
{
|
||||
LastSelectedLayout = layoutStyle;
|
||||
SendText(String.Format("zConfiguration Call Layout Style: {0}", layoutStyle.ToString()));
|
||||
}
|
||||
|
||||
public void SwapContentWithThumbnail()
|
||||
{
|
||||
if (CanSwapContentWithThumbnailFeedback.BoolValue)
|
||||
{
|
||||
var oppositeValue = ContentSwappedWithThumbnailFeedback.BoolValue ? "on" : "off"; // Get the value based on the opposite of the current state
|
||||
// TODO: #697 Need to verify the ternary above and make sure that the correct on/off value is being send based on the true/false value of the feedback
|
||||
// to toggle the state
|
||||
SendText(String.Format("zConfiguration Call Layout ShareThumb: {0}", oppositeValue));
|
||||
}
|
||||
}
|
||||
|
||||
public void LayoutTurnNextPage()
|
||||
{
|
||||
SendText("zCommand Call Layout TurnPage Forward: On");
|
||||
}
|
||||
|
||||
public void LayoutTurnPreviousPage()
|
||||
{
|
||||
SendText("zCommand Call Layout TurnPage Forward: Off");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasCodecLayouts Members
|
||||
|
||||
private Func<string> LocalLayoutFeedbackFunc { get { return () => Configuration.Call.Layout.Style.ToString(); } }
|
||||
|
||||
public StringFeedback LocalLayoutFeedback { get; private set; }
|
||||
|
||||
public void LocalLayoutToggle()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void LocalLayoutToggleSingleProminent()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void MinMaxLayoutToggle()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using PepperDash.Essentials.Core;
|
||||
using PepperDash.Essentials.Core.Bridges.JoinMaps;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
public class ZoomRoomJoinMap : VideoCodecControllerJoinMap
|
||||
{
|
||||
// TODO: #697 Set join numbers
|
||||
|
||||
[JoinName("LayoutIsOnFirstPage")]
|
||||
public JoinDataComplete LayoutIsOnFirstPage =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Indicates if layout is on first page",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutIsOnLastPage")]
|
||||
public JoinDataComplete LayoutIsOnLastPage =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Indicates if layout is on first page",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutTurnToNextPage")]
|
||||
public JoinDataComplete LayoutTurnToNextPage =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Turns layout view to next page",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutTurnToPreviousPage")]
|
||||
public JoinDataComplete LayoutTurnToPreviousPage =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Turns layout view to previous page",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CanSwapContentWithThumbnail")]
|
||||
public JoinDataComplete CanSwapContentWithThumbnail =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if content can be swapped with thumbnail",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SwapContentWithThumbnail")]
|
||||
public JoinDataComplete SwapContentWithThumbnail =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Pulse to swap content with thumbnail. FB reports current state",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("GetSetCurrentLayout")]
|
||||
public JoinDataComplete GetSetCurrentLayout =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Sets and reports the current layout. Use the LayoutXXXXIsAvailable signals to determine valid layouts",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("GetAvailableLayouts")]
|
||||
public JoinDataComplete GetAvailableLayouts =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("LayoutGalleryIsAvailable")]
|
||||
public JoinDataComplete LayoutGalleryIsAvailable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if layout 'Gallery' is available",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutSpeakerIsAvailable")]
|
||||
public JoinDataComplete LayoutSpeakerIsAvailable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if layout 'Speaker' is available",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutStripIsAvailable")]
|
||||
public JoinDataComplete LayoutStripIsAvailable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if layout 'Strip' is available",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutShareAllIsAvailable")]
|
||||
public JoinDataComplete LayoutShareAllIsAvailable =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 999, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if layout 'ShareAll' is available",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
public ZoomRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(ZoomRoomJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
public ZoomRoomJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user