mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-02 22:34:57 +00:00
Compare commits
13 Commits
1.8.5-pr69
...
1.8.5-alph
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116abbf962 | ||
|
|
604f4ca22d | ||
|
|
2d7ad8ba2a | ||
|
|
e4a3933743 | ||
|
|
d6445861f5 | ||
|
|
03b076c8eb | ||
|
|
7c58221acc | ||
|
|
14f7c27b33 | ||
|
|
9ea65883b7 | ||
|
|
9d0020d999 | ||
|
|
fb44a3b93c | ||
|
|
6b7c5c01f8 | ||
|
|
44c171c8f4 |
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using PepperDash.Essentials.Core;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes a device that has call participants
|
||||
/// </summary>
|
||||
public interface IHasParticipants
|
||||
{
|
||||
CodecParticipants Participants { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's video in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantVideoMute:IHasParticipants
|
||||
{
|
||||
void MuteVideoForParticipant(int userId);
|
||||
@@ -15,13 +22,29 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
void ToggleVideoForParticipant(int userId);
|
||||
}
|
||||
|
||||
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
|
||||
/// <summary>
|
||||
/// Describes the ability to mute and unmute a participant's audio in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantAudioMute : IHasParticipantVideoMute
|
||||
{
|
||||
void MuteAudioForParticipant(int userId);
|
||||
void UnmuteAudioForParticipant(int userId);
|
||||
void ToggleAudioForParticipant(int userId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the ability to pin and unpin a participant in a meeting
|
||||
/// </summary>
|
||||
public interface IHasParticipantPinUnpin : IHasParticipants
|
||||
{
|
||||
IntFeedback NumberOfScreensFeedback { get; }
|
||||
int ScreenIndexToPinUserTo { get; }
|
||||
|
||||
void PinParticipant(int userId, int screenIndex);
|
||||
void UnPinParticipant(int userId);
|
||||
void ToggleParticipantPinState(int userId, int screenIndex);
|
||||
}
|
||||
|
||||
public class CodecParticipants
|
||||
{
|
||||
private List<Participant> _currentParticipants;
|
||||
@@ -31,11 +54,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
set
|
||||
{
|
||||
_currentParticipants = value;
|
||||
var handler = ParticipantsListHasChanged;
|
||||
|
||||
if(handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
OnParticipantsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,15 +64,31 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
{
|
||||
_currentParticipants = new List<Participant>();
|
||||
}
|
||||
|
||||
public void OnParticipantsChanged()
|
||||
{
|
||||
var handler = ParticipantsListHasChanged;
|
||||
|
||||
if (handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a call participant
|
||||
/// </summary>
|
||||
public class Participant
|
||||
{
|
||||
public int UserId { get; set; }
|
||||
public bool IsHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool CanMuteVideo { get; set; }
|
||||
public bool CanUnmuteVideo { get; set; }
|
||||
public bool VideoMuteFb { get; set; }
|
||||
public bool AudioMuteFb { get; set; }
|
||||
public bool HandIsRaisedFb { get; set; }
|
||||
public bool IsPinnedFb { get; set; }
|
||||
public int ScreenIndexIsPinnedToFb { 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,10 +296,19 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
bridge.AddJoinMap(Key, joinMap);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -530,16 +547,22 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
|
||||
};
|
||||
|
||||
// TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL
|
||||
// add method here to decode the xsig info and trigger actions
|
||||
//trilist.SetStringSigAction(joinMap.CurrentParticipants.JoinNumber, DecodeParticipantsXSig);
|
||||
}
|
||||
|
||||
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
||||
{
|
||||
const int maxParticipants = 50;
|
||||
const int maxDigitals = 5;
|
||||
const int maxDigitals = 7;
|
||||
const int maxStrings = 1;
|
||||
const int offset = maxDigitals + maxStrings;
|
||||
var digitalIndex = maxStrings * maxParticipants; //15
|
||||
const int maxAnalogs = 1;
|
||||
const int offset = maxDigitals + maxStrings + maxAnalogs;
|
||||
var digitalIndex = maxStrings + maxAnalogs * maxParticipants; //15
|
||||
var stringIndex = 0;
|
||||
var analogIndex = 0;
|
||||
var meetingIndex = 0;
|
||||
|
||||
var tokenArray = new XSigToken[maxParticipants * offset];
|
||||
@@ -554,34 +577,88 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
||||
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, participant.HandIsRaisedFb);
|
||||
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, participant.IsPinnedFb);
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
||||
|
||||
//analogs
|
||||
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, (ushort)participant.ScreenIndexIsPinnedToFb);
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
analogIndex += maxAnalogs;
|
||||
}
|
||||
|
||||
while (meetingIndex < maxParticipants * offset)
|
||||
{
|
||||
//digitals
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, false);
|
||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, false);
|
||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, false);
|
||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, false);
|
||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, false);
|
||||
tokenArray[digitalIndex + 5] = new XSigDigitalToken(digitalIndex + 6, false);
|
||||
tokenArray[digitalIndex + 6] = new XSigDigitalToken(digitalIndex + 7, false);
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, String.Empty);
|
||||
|
||||
//analogs
|
||||
tokenArray[analogIndex] = new XSigAnalogToken(analogIndex + 1, 0);
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
analogIndex += maxAnalogs;
|
||||
}
|
||||
|
||||
return GetXSigString(tokenArray);
|
||||
}
|
||||
|
||||
// TODO: #698 [ ] Figure out how to decode xsig data and trigger actions based on values from SIMPL
|
||||
private void DecodeParticipantsXSig(string xsigData)
|
||||
{
|
||||
if (string.IsNullOrEmpty(xsigData)) return;
|
||||
var bytes = Encoding.GetEncoding(XSigEncoding).GetBytes(xsigData);
|
||||
using (var xsigStream = new XSigTokenStreamReader(new MemoryStream(bytes)))
|
||||
{
|
||||
XSigToken token = null;
|
||||
while ((token = xsigStream.ReadXSigToken()) != null)
|
||||
{
|
||||
switch (token.TokenType)
|
||||
{
|
||||
case XSigTokenType.Digital:
|
||||
{
|
||||
var data = token as XSigDigitalToken;
|
||||
if (data == null) return;
|
||||
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}",
|
||||
data.TokenType, data.Index, data.Value.ToString());
|
||||
break;
|
||||
}
|
||||
case XSigTokenType.Analog:
|
||||
{
|
||||
var data = token as XSigAnalogToken;
|
||||
if (data == null) return;
|
||||
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}",
|
||||
data.TokenType, data.Index, data.Value);
|
||||
break;
|
||||
}
|
||||
case XSigTokenType.Serial:
|
||||
{
|
||||
var data = token as XSigSerialToken;
|
||||
if (data == null) return;
|
||||
Debug.Console(1, this, "xSig Data TokenType: {0} | Index: {1} | Value: {2}", data.TokenType, data.Index,
|
||||
data.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]);
|
||||
@@ -847,7 +924,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
Debug.Console(1, this, "Call Direction: {0}", args.CallItem.Direction);
|
||||
Debug.Console(1, this, "Call is incoming: {0}", args.CallItem.Direction == eCodecCallDirection.Incoming);
|
||||
trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing);
|
||||
trilist.SetBool(joinMap.IncomingCall.JoinNumber, args.CallItem.Direction == eCodecCallDirection.Incoming && args.CallItem.Status == eCodecCallStatus.Ringing);
|
||||
|
||||
if (args.CallItem.Direction == eCodecCallDirection.Incoming)
|
||||
{
|
||||
|
||||
@@ -480,12 +480,28 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
public string wifiName { get; set; }
|
||||
}
|
||||
|
||||
public class NumberOfScreens
|
||||
public class NumberOfScreens : NotifiableObject
|
||||
{
|
||||
private int _numOfScreens;
|
||||
|
||||
[JsonProperty("NumberOfCECScreens")]
|
||||
public int NumOfCECScreens { get; set; }
|
||||
[JsonProperty("NumberOfScreens")]
|
||||
public int NumOfScreens { get; set; }
|
||||
public int NumOfScreens
|
||||
{
|
||||
get
|
||||
{
|
||||
return _numOfScreens;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != _numOfScreens)
|
||||
{
|
||||
_numOfScreens = value;
|
||||
NotifyPropertyChanged("NumberOfScreens");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -551,18 +567,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
|
||||
@@ -685,6 +819,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public class PinStatusOfScreenNotification
|
||||
{
|
||||
|
||||
|
||||
[JsonProperty("can_be_pinned")]
|
||||
public bool CanBePinned { get; set; }
|
||||
[JsonProperty("can_pin_share")]
|
||||
@@ -835,12 +971,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 +1003,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
|
||||
@@ -1137,8 +1319,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
[JsonProperty("is_raise_hand")]
|
||||
public bool IsRaiseHand { get; set; }
|
||||
[JsonProperty("optimize_vis_validideo_sharing")]
|
||||
public string IsValid { get; set; }
|
||||
[JsonProperty("is_valid")]
|
||||
public bool IsValid { get; set; }
|
||||
[JsonProperty("time_stamp")]
|
||||
public string TimeStamp { get; set; }
|
||||
}
|
||||
@@ -1213,12 +1395,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
p =>
|
||||
new Participant
|
||||
{
|
||||
UserId = p.UserId,
|
||||
Name = p.UserName,
|
||||
IsHost = p.IsHost,
|
||||
CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||
VideoMuteFb = p.VideoStatusIsSending
|
||||
VideoMuteFb = p.VideoStatusIsSending,
|
||||
HandIsRaisedFb = p.HandStatus.IsValid && p.HandStatus.IsRaiseHand,
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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, IHasParticipantPinUnpin, IHasParticipantAudioMute
|
||||
{
|
||||
private const long MeetingRefreshTimer = 60000;
|
||||
private const uint DefaultMeetingDurationMin = 30;
|
||||
@@ -121,6 +121,16 @@ 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);
|
||||
|
||||
NumberOfScreensFeedback = new IntFeedback(NumberOfScreensFeedbackFunc);
|
||||
|
||||
}
|
||||
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
@@ -216,11 +226,6 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
}
|
||||
}
|
||||
|
||||
protected Func<string> LocalLayoutFeedbackFunc
|
||||
{
|
||||
get { return () => ""; }
|
||||
}
|
||||
|
||||
protected Func<bool> LocalLayoutIsProminentFeedbackFunc
|
||||
{
|
||||
get { return () => false; }
|
||||
@@ -484,11 +489,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 +564,48 @@ 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":
|
||||
{
|
||||
ComputeAvailableLayouts();
|
||||
break;
|
||||
}
|
||||
case "is_In_First_Page":
|
||||
{
|
||||
LayoutViewIsOnFirstPageFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
case "is_In_Last_Page":
|
||||
{
|
||||
LayoutViewIsOnLastPageFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
//case "video_type":
|
||||
// {
|
||||
// It appears as though the actual value we want to watch is Configuration.Call.Layout.Style
|
||||
// LocalLayoutFeedback.FireUpdate();
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
};
|
||||
|
||||
Status.NumberOfScreens.PropertyChanged += (o, a) =>
|
||||
{
|
||||
switch (a.PropertyName)
|
||||
{
|
||||
case "NumberOfScreens":
|
||||
{
|
||||
NumberOfScreensFeedback.FireUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void SetUpDirectory()
|
||||
@@ -1222,6 +1286,38 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
JsonConvert.PopulateObject(responseObj.ToString(), Status.PhoneCall);
|
||||
break;
|
||||
}
|
||||
case "pinstatusofscreennotification":
|
||||
{
|
||||
var status = responseObj.ToObject<zEvent.PinStatusOfScreenNotification>();
|
||||
|
||||
var participant = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(status.PinnedUserId));
|
||||
|
||||
if (participant != null)
|
||||
{
|
||||
participant.IsPinnedFb = true;
|
||||
participant.ScreenIndexIsPinnedToFb = status.ScreenIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
participant = Participants.CurrentParticipants.FirstOrDefault(p => p.ScreenIndexIsPinnedToFb.Equals(status.ScreenIndex));
|
||||
|
||||
if (participant == null)
|
||||
{
|
||||
Debug.Console(2, this, "no matching participant found by pinned_user_id: {0} or screen_index: {1}", status.PinnedUserId, status.ScreenIndex);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
participant.IsPinnedFb = false;
|
||||
participant.ScreenIndexIsPinnedToFb = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// fire the event as we've modified the participants list
|
||||
Participants.OnParticipantsChanged();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
@@ -1600,7 +1696,81 @@ 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 layoutsCodec = this as IHasZoomRoomLayouts;
|
||||
if (layoutsCodec != null)
|
||||
{
|
||||
layoutsCodec.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));
|
||||
};
|
||||
|
||||
layoutsCodec.CanSwapContentWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.CanSwapContentWithThumbnail.JoinNumber]);
|
||||
trilist.SetSigFalseAction(joinMap.SwapContentWithThumbnail.JoinNumber, () => layoutsCodec.SwapContentWithThumbnail());
|
||||
layoutsCodec.ContentSwappedWithThumbnailFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SwapContentWithThumbnail.JoinNumber]);
|
||||
|
||||
layoutsCodec.LayoutViewIsOnFirstPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnFirstPage.JoinNumber]);
|
||||
layoutsCodec.LayoutViewIsOnLastPageFeedback.LinkInputSig(trilist.BooleanInput[joinMap.LayoutIsOnLastPage.JoinNumber]);
|
||||
trilist.SetSigFalseAction(joinMap.LayoutTurnToNextPage.JoinNumber, () => layoutsCodec.LayoutTurnNextPage());
|
||||
trilist.SetSigFalseAction(joinMap.LayoutTurnToPreviousPage.JoinNumber, () => layoutsCodec.LayoutTurnPreviousPage());
|
||||
trilist.SetSigFalseAction(joinMap.GetAvailableLayouts.JoinNumber, () => layoutsCodec.GetAvailableLayouts());
|
||||
|
||||
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(1, this, "Unable to parse '{0}' to zConfiguration.eLayoutStyle: {1}", s, e);
|
||||
}
|
||||
});
|
||||
|
||||
layoutsCodec.LocalLayoutFeedback.LinkInputSig(trilist.StringInput[joinMap.GetSetCurrentLayout.JoinNumber]);
|
||||
}
|
||||
|
||||
var pinCodec = this as IHasParticipantPinUnpin;
|
||||
if (pinCodec != null)
|
||||
{
|
||||
pinCodec.NumberOfScreensFeedback.LinkInputSig(trilist.UShortInput[joinMap.NumberOfScreens.JoinNumber]);
|
||||
|
||||
// Set the value of the local property to be used when pinning a participant
|
||||
trilist.SetUShortSigAction(joinMap.ScreenIndexToPinUserTo.JoinNumber, (u) => ScreenIndexToPinUserTo = u);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExecuteSwitch(object selector)
|
||||
@@ -1770,6 +1940,114 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasParticipantAudioMute Members
|
||||
|
||||
public void MuteAudioForParticipant(int userId)
|
||||
{
|
||||
SendText(string.Format("zCommand Call MuteParticipant Mute: on Id: {0}", userId));
|
||||
}
|
||||
|
||||
public void UnmuteAudioForParticipant(int userId)
|
||||
{
|
||||
SendText(string.Format("zCommand Call MuteParticipant Mute: off Id: {0}", userId));
|
||||
}
|
||||
|
||||
public void ToggleAudioForParticipant(int userId)
|
||||
{
|
||||
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.AudioMuteFb)
|
||||
{
|
||||
UnmuteAudioForParticipant(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
MuteAudioForParticipant(userId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasParticipantVideoMute Members
|
||||
|
||||
public void MuteVideoForParticipant(int userId)
|
||||
{
|
||||
SendText(string.Format("zCommand Call MuteParticipantVideo Mute: on Id: {0}", userId));
|
||||
}
|
||||
|
||||
public void UnmuteVideoForParticipant(int userId)
|
||||
{
|
||||
SendText(string.Format("zCommand Call MuteParticipantVideo Mute: off Id: {0}", userId));
|
||||
}
|
||||
|
||||
public void ToggleVideoForParticipant(int userId)
|
||||
{
|
||||
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.VideoMuteFb)
|
||||
{
|
||||
UnmuteVideoForParticipant(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
MuteVideoForParticipant(userId);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IHasParticipantPinUnpin Members
|
||||
|
||||
private Func<int> NumberOfScreensFeedbackFunc { get { return () => Status.NumberOfScreens.NumOfScreens; } }
|
||||
|
||||
public IntFeedback NumberOfScreensFeedback { get; private set; }
|
||||
|
||||
public int ScreenIndexToPinUserTo { get; private set; }
|
||||
|
||||
public void PinParticipant(int userId, int screenIndex)
|
||||
{
|
||||
SendText(string.Format("zCommand Call Pin Id: {0} Enable: on Screen: {1}", userId, screenIndex));
|
||||
}
|
||||
|
||||
public void UnPinParticipant(int userId)
|
||||
{
|
||||
SendText(string.Format("zCommand Call Pin Id: {0} Enable: off", userId));
|
||||
}
|
||||
|
||||
public void ToggleParticipantPinState(int userId, int screenIndex)
|
||||
{
|
||||
var user = Participants.CurrentParticipants.FirstOrDefault(p => p.UserId.Equals(userId));
|
||||
|
||||
if(user == null)
|
||||
{
|
||||
Debug.Console(2, this, "Unable to find user with id: {0}", userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (user.IsPinnedFb)
|
||||
{
|
||||
UnPinParticipant(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
PinParticipant(userId, screenIndex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IHasCameraOff
|
||||
|
||||
public BoolFeedback CameraIsOffFeedback { get; private set; }
|
||||
@@ -1899,6 +2177,125 @@ 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
|
||||
// Will need to test and confirm that this logic evaluates correctly
|
||||
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,273 @@
|
||||
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 [X] Set join numbers
|
||||
|
||||
#region Digital
|
||||
|
||||
[JoinName("CanSwapContentWithThumbnail")]
|
||||
public JoinDataComplete CanSwapContentWithThumbnail = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 206,
|
||||
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 = 206,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Pulse to swap content with thumbnail. FB reports current state",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("GetAvailableLayouts")]
|
||||
public JoinDataComplete GetAvailableLayouts = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 215,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Gets the available layouts. Will update the LayoutXXXXXIsAvailbale signals.",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutIsOnFirstPage")]
|
||||
public JoinDataComplete LayoutIsOnFirstPage = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 216,
|
||||
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 = 217,
|
||||
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 = 216,
|
||||
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 = 217,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Turns layout view to previous page",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("LayoutGalleryIsAvailable")]
|
||||
public JoinDataComplete LayoutGalleryIsAvailable = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 221,
|
||||
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 = 222,
|
||||
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 = 223,
|
||||
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 = 224,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "FB Indicates if layout 'ShareAll' is available",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ParticipantAudioMuteToggleStart")]
|
||||
public JoinDataComplete ParticipantAudioMuteToggleStart = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 500,
|
||||
JoinSpan = 100
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Toggles the participant's audio mute status",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ParticipantVideoMuteToggleStart")]
|
||||
public JoinDataComplete ParticipantVideoMuteToggleStart = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 800,
|
||||
JoinSpan = 100
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Toggles the participant's video mute status",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("ParticipantPinToggleStart")]
|
||||
public JoinDataComplete ParticipantPinToggleStart = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 1100,
|
||||
JoinSpan = 100
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Toggles the participant's pin status",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Analog
|
||||
|
||||
[JoinName("NumberOfScreens")]
|
||||
public JoinDataComplete NumberOfScreens = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 11,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Reports the number of screens connected",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
[JoinName("ScreenIndexToPinUserTo")]
|
||||
public JoinDataComplete ScreenIndexToPinUserTo = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 11,
|
||||
JoinSpan = 1
|
||||
},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Specifies the screen index a participant should be pinned to",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Serials
|
||||
|
||||
[JoinName("GetSetCurrentLayout")]
|
||||
public JoinDataComplete GetSetCurrentLayout = new JoinDataComplete(
|
||||
new JoinData
|
||||
{
|
||||
JoinNumber = 215,
|
||||
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
|
||||
});
|
||||
|
||||
#endregion
|
||||
|
||||
public ZoomRoomJoinMap(uint joinStart)
|
||||
: base(joinStart, typeof(ZoomRoomJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
public ZoomRoomJoinMap(uint joinStart, Type type)
|
||||
: base(joinStart, type)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user