mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-26 19:04:47 +00:00
959 lines
35 KiB
C#
959 lines
35 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using Crestron.SimplSharp;
|
|
using Crestron.SimplSharpPro.DeviceSupport;
|
|
|
|
using PepperDash.Core;
|
|
using PepperDash.Essentials;
|
|
using PepperDash.Essentials.Core;
|
|
using PepperDash.Essentials.Core.SmartObjects;
|
|
using PepperDash.Essentials.Core.Touchpanels.Keyboards;
|
|
using PepperDash.Essentials.Devices.Common.Codec;
|
|
using PepperDash.Essentials.Devices.Common.VideoCodec;
|
|
|
|
namespace PepperDash.Essentials.UIDrivers.VC
|
|
{
|
|
/// <summary>
|
|
/// This fella will likely need to interact with the room's source, although that is routed via the spark...
|
|
/// Probably needs event or FB to feed AV driver - to show two-mute volume when appropriate.
|
|
///
|
|
/// </summary>
|
|
public class EssentialsVideoCodecUiDriver : PanelDriverBase
|
|
{
|
|
IAVDriver Parent;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
VideoCodecBase Codec;
|
|
|
|
/// <summary>
|
|
/// To drive UI elements outside of this driver that may be dependent on this.
|
|
/// </summary>
|
|
BoolFeedback InCall;
|
|
BoolFeedback LocalPrivacyIsMuted;
|
|
|
|
/// <summary>
|
|
/// For the subpages above the bar
|
|
/// </summary>
|
|
JoinedSigInterlock VCControlsInterlock;
|
|
|
|
/// <summary>
|
|
/// For the different staging bars: Active, inactive
|
|
/// </summary>
|
|
JoinedSigInterlock StagingBarsInterlock;
|
|
|
|
/// <summary>
|
|
/// For the staging button feedbacks
|
|
/// </summary>
|
|
JoinedSigInterlock StagingButtonsFeedbackInterlock;
|
|
|
|
SmartObjectNumeric DialKeypad;
|
|
|
|
SubpageReferenceList ActiveCallsSRL;
|
|
|
|
SmartObjectDynamicList RecentCallsList;
|
|
|
|
SmartObjectDynamicList DirectoryList;
|
|
|
|
CodecDirectory CurrentDirectoryResult;
|
|
|
|
string LastFolderRequestedParentFolderId;
|
|
|
|
BoolFeedback DirectoryBackButtonVisibleFeedback;
|
|
|
|
// These are likely temp until we get a keyboard built
|
|
StringFeedback DialStringFeedback;
|
|
StringBuilder DialStringBuilder = new StringBuilder();
|
|
BoolFeedback DialStringBackspaceVisibleFeedback;
|
|
|
|
StringFeedback SearchStringFeedback;
|
|
StringBuilder SearchStringBuilder = new StringBuilder();
|
|
BoolFeedback SearchStringBackspaceVisibleFeedback;
|
|
|
|
ModalDialog IncomingCallModal;
|
|
|
|
eKeypadMode KeypadMode;
|
|
|
|
bool CodecHasFavorites;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="triList"></param>
|
|
/// <param name="codec"></param>
|
|
public EssentialsVideoCodecUiDriver(BasicTriListWithSmartObject triList, IAVDriver parent, VideoCodecBase codec)
|
|
: base(triList)
|
|
{
|
|
if (codec == null)
|
|
throw new ArgumentNullException("Codec cannot be null");
|
|
Codec = codec;
|
|
Parent = parent;
|
|
SetupCallStagingPopover();
|
|
SetupDialKeypad();
|
|
ActiveCallsSRL = new SubpageReferenceList(TriList, UISmartObjectJoin.CodecActiveCallsHeaderList, 3, 3, 3);
|
|
SetupDirectoryList();
|
|
SetupRecentCallsList();
|
|
SetupFavorites();
|
|
SetupSelfViewControls();
|
|
|
|
codec.CallStatusChange += new EventHandler<CodecCallStatusItemChangeEventArgs>(Codec_CallStatusChange);
|
|
|
|
// If the codec is ready, then get the values we want, otherwise wait
|
|
if (Codec.IsReady)
|
|
Codec_IsReady();
|
|
else
|
|
codec.IsReadyChange += (o, a) => Codec_IsReady();
|
|
|
|
InCall = new BoolFeedback(() => false);
|
|
LocalPrivacyIsMuted = new BoolFeedback(() => false);
|
|
|
|
VCControlsInterlock = new JoinedSigInterlock(triList);
|
|
if(CodecHasFavorites)
|
|
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadWithFavoritesVisible);
|
|
else
|
|
VCControlsInterlock.SetButDontShow(UIBoolJoin.VCKeypadVisible);
|
|
|
|
StagingBarsInterlock = new JoinedSigInterlock(triList);
|
|
StagingBarsInterlock.SetButDontShow(UIBoolJoin.VCStagingInactivePopoverVisible);
|
|
|
|
StagingButtonsFeedbackInterlock = new JoinedSigInterlock(triList);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
|
|
|
// Return formatted when dialing, straight digits when in call
|
|
DialStringFeedback = new StringFeedback(() =>
|
|
{
|
|
if (KeypadMode == eKeypadMode.Dial)
|
|
return GetFormattedDialString(DialStringBuilder.ToString());
|
|
else
|
|
return DialStringBuilder.ToString();
|
|
|
|
});
|
|
DialStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecAddressEntryText]);
|
|
|
|
DialStringBackspaceVisibleFeedback = new BoolFeedback(() => DialStringBuilder.Length > 0);
|
|
DialStringBackspaceVisibleFeedback
|
|
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCKeypadBackspaceVisible]);
|
|
|
|
SearchStringFeedback = new StringFeedback(() =>
|
|
{
|
|
if (SearchStringBuilder.Length > 0)
|
|
{
|
|
Parent.Keyboard.EnableGoButton();
|
|
return SearchStringBuilder.ToString();
|
|
}
|
|
else
|
|
{
|
|
Parent.Keyboard.DisableGoButton();
|
|
return "Touch to Search";
|
|
}
|
|
});
|
|
SearchStringFeedback.LinkInputSig(triList.StringInput[UIStringJoin.CodecDirectorySearchEntryText]);
|
|
|
|
SearchStringBackspaceVisibleFeedback = new BoolFeedback(() => SearchStringBuilder.Length > 0);
|
|
SearchStringBackspaceVisibleFeedback.LinkInputSig(triList.BooleanInput[UIBoolJoin.VCDirectoryBackspaceVisible]);
|
|
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCDirectoryBackPress, GetDirectoryParentFolderContents);
|
|
|
|
DirectoryBackButtonVisibleFeedback = new BoolFeedback(() => CurrentDirectoryResult != (codec as IHasDirectory).DirectoryRoot);
|
|
DirectoryBackButtonVisibleFeedback
|
|
.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCDirectoryBackVisible]);
|
|
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCKeypadTextPress, RevealKeyboard);
|
|
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCDirectorySearchTextPress, RevealKeyboard);
|
|
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCDirectoryBackspacePress, SearchKeypadBackspacePress);
|
|
|
|
// Address and number
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void Codec_IsReady()
|
|
{
|
|
TriList.SetString(UIStringJoin.RoomPhoneText, Codec.CodecInfo.PhoneNumber);
|
|
TriList.SetString(UIStringJoin.RoomSipText, Codec.CodecInfo.SipUri);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles status changes for calls
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void Codec_CallStatusChange(object sender, CodecCallStatusItemChangeEventArgs e)
|
|
{
|
|
var call = e.CallItem;
|
|
switch (e.NewStatus)
|
|
{
|
|
case eCodecCallStatus.Connected:
|
|
// fire at SRL item
|
|
KeypadMode = eKeypadMode.DTMF;
|
|
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
|
DialStringFeedback.FireUpdate();
|
|
TriList.SetBool(UIBoolJoin.VCKeypadVisible, false);
|
|
Parent.ShowNotificationRibbon("Connected", 2000);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible);
|
|
break;
|
|
case eCodecCallStatus.Connecting:
|
|
// fire at SRL item
|
|
Parent.ShowNotificationRibbon("Connecting", 0);
|
|
break;
|
|
case eCodecCallStatus.Dialing:
|
|
Parent.ShowNotificationRibbon("Dialing", 0);
|
|
break;
|
|
case eCodecCallStatus.Disconnected:
|
|
if (!Codec.IsInCall)
|
|
{
|
|
KeypadMode = eKeypadMode.Dial;
|
|
ShowKeypad();
|
|
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
|
DialStringFeedback.FireUpdate();
|
|
Parent.ShowNotificationRibbon("Disonnected", 2000);
|
|
}
|
|
break;
|
|
case eCodecCallStatus.Disconnecting:
|
|
break;
|
|
case eCodecCallStatus.EarlyMedia:
|
|
break;
|
|
case eCodecCallStatus.Idle:
|
|
break;
|
|
case eCodecCallStatus.OnHold:
|
|
break;
|
|
case eCodecCallStatus.Preserved:
|
|
break;
|
|
case eCodecCallStatus.RemotePreserved:
|
|
break;
|
|
case eCodecCallStatus.Ringing:
|
|
{
|
|
// fire up a modal
|
|
if( !Codec.CodecInfo.AutoAnswerEnabled && call.Direction == eCodecCallDirection.Incoming)
|
|
ShowIncomingModal(call);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
TriList.UShortInput[UIUshortJoin.VCStagingConnectButtonMode].UShortValue = (ushort)(Codec.IsInCall ? 1 : 0);
|
|
StagingBarsInterlock.ShowInterlocked(Codec.IsInCall ?
|
|
UIBoolJoin.VCStagingActivePopoverVisible : UIBoolJoin.VCStagingInactivePopoverVisible);
|
|
|
|
// Set mode of header button
|
|
if (!Codec.IsInCall)
|
|
Parent.HeaderCallButton.SetIcon(HeaderListButton.OnHook);
|
|
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 0);
|
|
else if (Codec.ActiveCalls.Any(c => c.Type == eCodecCallType.Video))
|
|
Parent.HeaderCallButton.SetIcon(HeaderListButton.Camera);
|
|
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 2);
|
|
else
|
|
Parent.HeaderCallButton.SetIcon(HeaderListButton.Phone);
|
|
//TriList.SetUshort(UIUshortJoin.CallHeaderButtonMode, 1);
|
|
|
|
// Update list of calls
|
|
UpdateCallsHeaderList(call);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Redraws the calls list on the header
|
|
/// </summary>
|
|
void UpdateCallsHeaderList(CodecActiveCallItem call)
|
|
{
|
|
var activeList = Codec.ActiveCalls.Where(c => c.IsActiveCall).ToList();
|
|
ActiveCallsSRL.Clear();
|
|
ushort i = 1;
|
|
foreach (var c in activeList)
|
|
{
|
|
//var item = new SubpageReferenceListItem(1, ActiveCallsSRL);
|
|
ActiveCallsSRL.StringInputSig(i, 1).StringValue = c.Name;
|
|
ActiveCallsSRL.StringInputSig(i, 2).StringValue = c.Number;
|
|
ActiveCallsSRL.StringInputSig(i, 3).StringValue = c.Status.ToString();
|
|
ActiveCallsSRL.UShortInputSig(i, 1).UShortValue = (ushort)(c.Type == eCodecCallType.Video ? 2 : 1);
|
|
var cc = c; // for scope in lambda
|
|
ActiveCallsSRL.GetBoolFeedbackSig(i, 1).SetSigFalseAction(() => Codec.EndCall(cc));
|
|
i++;
|
|
}
|
|
ActiveCallsSRL.Count = (ushort)activeList.Count;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void ShowIncomingModal(CodecActiveCallItem call)
|
|
{
|
|
IncomingCallModal = new ModalDialog(TriList);
|
|
string msg;
|
|
string icon;
|
|
if (call.Type == eCodecCallType.Audio)
|
|
{
|
|
icon = "Phone";
|
|
msg = string.Format("Incoming phone call from: {0}", call.Name);
|
|
}
|
|
else
|
|
{
|
|
icon = "Camera";
|
|
msg = string.Format("Incoming video call from: {0}", call.Name);
|
|
}
|
|
IncomingCallModal.PresentModalDialog(2, "Incoming Call", icon, msg,
|
|
"Ignore", "Accept", false, false, b =>
|
|
{
|
|
if (b == 1)
|
|
Codec.RejectCall(call);
|
|
else //2
|
|
Codec.AcceptCall(call);
|
|
IncomingCallModal = null;
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override void Show()
|
|
{
|
|
VCControlsInterlock.Show();
|
|
StagingBarsInterlock.Show();
|
|
DialStringFeedback.FireUpdate();
|
|
base.Show();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public override void Hide()
|
|
{
|
|
VCControlsInterlock.Hide();
|
|
StagingBarsInterlock.Hide();
|
|
base.Hide();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Builds the call stage
|
|
/// </summary>
|
|
void SetupCallStagingPopover()
|
|
{
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCStagingDirectoryPress, ShowDirectory);
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCStagingKeypadPress, ShowKeypad);
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCStagingRecentsPress, ShowRecents);
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCStagingConnectPress, ConnectPress);
|
|
TriList.SetSigFalseAction(UIBoolJoin.CallEndPress, () =>
|
|
{
|
|
if (Codec.ActiveCalls.Count > 1)
|
|
{
|
|
Parent.PopupInterlock.ShowInterlocked(UIBoolJoin.HeaderActiveCallsListVisible);
|
|
}
|
|
else
|
|
Codec.EndAllCalls();
|
|
});
|
|
TriList.SetSigFalseAction(UIBoolJoin.CallEndAllConfirmPress, () =>
|
|
{
|
|
Parent.PopupInterlock.HideAndClear();
|
|
Codec.EndAllCalls();
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SetupDialKeypad()
|
|
{
|
|
if(TriList.SmartObjects.Contains(UISmartObjectJoin.VCDialKeypad))
|
|
{
|
|
DialKeypad = new SmartObjectNumeric(TriList.SmartObjects[UISmartObjectJoin.VCDialKeypad], true);
|
|
DialKeypad.Digit0.SetSigFalseAction(() => DialKeypadPress("0"));
|
|
DialKeypad.Digit1.SetSigFalseAction(() => DialKeypadPress("1"));
|
|
DialKeypad.Digit2.SetSigFalseAction(() => DialKeypadPress("2"));
|
|
DialKeypad.Digit3.SetSigFalseAction(() => DialKeypadPress("3"));
|
|
DialKeypad.Digit4.SetSigFalseAction(() => DialKeypadPress("4"));
|
|
DialKeypad.Digit5.SetSigFalseAction(() => DialKeypadPress("5"));
|
|
DialKeypad.Digit6.SetSigFalseAction(() => DialKeypadPress("6"));
|
|
DialKeypad.Digit7.SetSigFalseAction(() => DialKeypadPress("7"));
|
|
DialKeypad.Digit8.SetSigFalseAction(() => DialKeypadPress("8"));
|
|
DialKeypad.Digit9.SetSigFalseAction(() => DialKeypadPress("9"));
|
|
DialKeypad.Misc1SigName = "*";
|
|
DialKeypad.Misc1.SetSigFalseAction(() => DialKeypadPress("*"));
|
|
DialKeypad.Misc2SigName = "#";
|
|
DialKeypad.Misc2.SetSigFalseAction(() => DialKeypadPress("#"));
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCKeypadBackspacePress, DialKeypadBackspacePress);
|
|
}
|
|
else
|
|
Debug.Console(0, "Trilist {0:x2}, VC dial keypad object {1} not found. Check SGD file or VTP",
|
|
TriList.ID, UISmartObjectJoin.VCDialKeypad);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SetupRecentCallsList()
|
|
{
|
|
var codec = Codec as IHasCallHistory;
|
|
if (codec != null)
|
|
{
|
|
codec.CallHistory.RecentCallsListHasChanged += (o, a) => RefreshRecentCallsList();
|
|
// EVENT??????????????? Pointed at refresh
|
|
RecentCallsList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCRecentsList], true, 1200);
|
|
RefreshRecentCallsList();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void RefreshRecentCallsList()
|
|
{
|
|
var codec = Codec as IHasCallHistory;
|
|
uint textOffset = 1200;
|
|
uint timeTextOffset = 1230;
|
|
if (codec != null)
|
|
{
|
|
ushort i = 0;
|
|
foreach (var c in codec.CallHistory.RecentCalls)
|
|
{
|
|
i++;
|
|
TriList.SetString(textOffset + i, c.Name);
|
|
// if it's today, show a simpler string
|
|
string timeText = null;
|
|
if (c.StartTime.Date == DateTime.Now.Date)
|
|
timeText = c.StartTime.ToShortTimeString();
|
|
else
|
|
timeText = c.StartTime.ToString();
|
|
TriList.SetString(timeTextOffset + i, timeText);
|
|
|
|
string iconName = null;
|
|
if (c.OccurenceType == eCodecOccurrenceType.Received)
|
|
iconName = "Misc-18_Light";
|
|
else if (c.OccurenceType == eCodecOccurrenceType.Placed)
|
|
iconName = "Misc-17_Light";
|
|
else
|
|
iconName = "Help";
|
|
RecentCallsList.SetItemIcon(i, iconName);
|
|
|
|
var call = c; // for lambda scope
|
|
RecentCallsList.SetItemButtonAction(i, b => { if(!b) Codec.Dial(call.Number); });
|
|
}
|
|
RecentCallsList.Count = i;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SetupFavorites()
|
|
{
|
|
var c = Codec as IHasCallFavorites;
|
|
if (c != null && c.CallFavorites != null)
|
|
{
|
|
CodecHasFavorites = true;
|
|
var favs = c.CallFavorites.Favorites;
|
|
for (uint i = 0; i <= 3; i++)
|
|
{
|
|
if (i < favs.Count)
|
|
{
|
|
var fav = favs[(int)i];
|
|
TriList.SetString(1411 + i, fav.Name);
|
|
TriList.SetBool(1221 + i, true);
|
|
TriList.SetSigFalseAction(1211 + i, () =>
|
|
{
|
|
Codec.Dial(fav.Number);
|
|
});
|
|
}
|
|
else
|
|
TriList.SetBool(1221 + i, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SetupDirectoryList()
|
|
{
|
|
var codec = Codec as IHasDirectory;
|
|
if (codec != null)
|
|
{
|
|
if (codec != null)
|
|
{
|
|
DirectoryList = new SmartObjectDynamicList(TriList.SmartObjects[UISmartObjectJoin.VCDirectoryList],
|
|
true, 1300);
|
|
codec.DirectoryResultReturned += new EventHandler<DirectoryEventArgs>(dir_DirectoryResultReturned);
|
|
|
|
if (codec.PhonebookSyncState.InitialSyncComplete)
|
|
SetCurrentDirectoryToRoot();
|
|
else
|
|
{
|
|
codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler<EventArgs>(PhonebookSyncState_InitialSyncCompleted);
|
|
}
|
|
|
|
|
|
// If there is something here now, show it otherwise wait for the event
|
|
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
|
|
{
|
|
RefreshDirectory();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the current directory resutls to the DirectorRoot and updates Back Button visibiltiy
|
|
/// </summary>
|
|
void SetCurrentDirectoryToRoot()
|
|
{
|
|
LastFolderRequestedParentFolderId = string.Empty;
|
|
|
|
CurrentDirectoryResult = (Codec as IHasDirectory).DirectoryRoot;
|
|
|
|
DirectoryBackButtonVisibleFeedback.FireUpdate();
|
|
|
|
RefreshDirectory();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Setup the Directory list when notified that the initial phonebook sync is completed
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void PhonebookSyncState_InitialSyncCompleted(object sender, EventArgs e)
|
|
{
|
|
var codec = Codec as IHasDirectory;
|
|
|
|
SetCurrentDirectoryToRoot();
|
|
|
|
if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0)
|
|
{
|
|
RefreshDirectory();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="sender"></param>
|
|
/// <param name="e"></param>
|
|
void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e)
|
|
{
|
|
CurrentDirectoryResult = e.Directory;
|
|
DirectoryBackButtonVisibleFeedback.FireUpdate();
|
|
RefreshDirectory();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper method to retrieve directory folder contents and store last requested folder id
|
|
/// </summary>
|
|
/// <param name="folderId"></param>
|
|
void GetDirectoryFolderContents(DirectoryFolder folder)
|
|
{
|
|
if (!string.IsNullOrEmpty(folder.ParentFolderId))
|
|
LastFolderRequestedParentFolderId = folder.ParentFolderId;
|
|
else
|
|
LastFolderRequestedParentFolderId = string.Empty;
|
|
|
|
(Codec as IHasDirectory).GetDirectoryFolderContents(folder.FolderId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Request the parent folder contents or sets back to the root if no parent folder
|
|
/// </summary>
|
|
void GetDirectoryParentFolderContents()
|
|
{
|
|
var codec = Codec as IHasDirectory;
|
|
|
|
if (!string.IsNullOrEmpty(LastFolderRequestedParentFolderId))
|
|
codec.GetDirectoryFolderContents(LastFolderRequestedParentFolderId);
|
|
else
|
|
{
|
|
SetCurrentDirectoryToRoot();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="dir"></param>
|
|
void RefreshDirectory()
|
|
{
|
|
Debug.Console(0, "****** RefreshDirectory!");
|
|
|
|
ushort i = 0;
|
|
foreach (var r in CurrentDirectoryResult.DirectoryResults)
|
|
{
|
|
if (i == DirectoryList.MaxCount)
|
|
{
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
|
|
if(r is DirectoryContact)
|
|
{
|
|
DirectoryList.SetItemMainText(i, r.Name);
|
|
|
|
var dc = r as DirectoryContact;
|
|
|
|
DirectoryList.SetItemButtonAction(i, b =>
|
|
{
|
|
if (!b)
|
|
{
|
|
// Refresh the contact methods list
|
|
RefreshContactMethodsModalList(dc);
|
|
Parent.PopupInterlock.ShowInterlockedWithToggle(UIBoolJoin.MeetingsOrContacMethodsListVisible);
|
|
}
|
|
});
|
|
|
|
}
|
|
else // is DirectoryFolder
|
|
{
|
|
DirectoryList.SetItemMainText(i, string.Format("[+] {0}", r.Name));
|
|
|
|
var df = r as DirectoryFolder;
|
|
|
|
DirectoryList.SetItemButtonAction(i, b =>
|
|
{
|
|
if (!b)
|
|
{
|
|
GetDirectoryFolderContents(df);
|
|
// will later call event handler after folder contents retrieved
|
|
}
|
|
});
|
|
}
|
|
}
|
|
DirectoryList.Count = i;
|
|
}
|
|
|
|
void RefreshContactMethodsModalList(DirectoryContact contact)
|
|
{
|
|
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListIcon, "Users");
|
|
TriList.SetString(UIStringJoin.MeetingsOrContactMethodListTitleText, "Contact Methods");
|
|
|
|
ushort i = 0;
|
|
foreach (var c in contact.ContactMethods)
|
|
{
|
|
i++;
|
|
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 1).StringValue = c.Device.ToString();
|
|
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 2).StringValue = c.CallType.ToString();
|
|
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 3).StringValue = c.Number;
|
|
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 4).StringValue = "";
|
|
Parent.MeetingOrContactMethodModalSrl.StringInputSig(i, 5).StringValue = "Connect";
|
|
Parent.MeetingOrContactMethodModalSrl.BoolInputSig(i, 2).BoolValue = true;
|
|
var cc = c; // lambda scope
|
|
Parent.MeetingOrContactMethodModalSrl.GetBoolFeedbackSig(i, 1).SetSigFalseAction(() =>
|
|
{
|
|
Parent.PopupInterlock.Hide();
|
|
var codec = Codec as VideoCodecBase;
|
|
if (codec != null)
|
|
codec.Dial(c.Number);
|
|
});
|
|
}
|
|
Parent.MeetingOrContactMethodModalSrl.Count = i;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SetupSelfViewControls()
|
|
{
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCStagingSelfViewLayoutPress, this.ShowSelfViewLayout);
|
|
var svc = Codec as IHasCodecSelfview;
|
|
if (svc != null)
|
|
{
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCSelfViewTogglePress, svc.SelfviewModeToggle);
|
|
svc.SelfviewIsOnFeedback.LinkInputSig(TriList.BooleanInput[UIBoolJoin.VCSelfViewTogglePress]);
|
|
|
|
//TriList.SetSigFalseAction(UIBoolJoin.VCSelfViewPipTogglePress, () => { });
|
|
}
|
|
var lc = Codec as IHasCodecLayouts;
|
|
if (lc != null)
|
|
{
|
|
TriList.SetSigFalseAction(UIBoolJoin.VCRemoteViewTogglePress, lc.LocalLayoutToggle);
|
|
lc.LocalLayoutFeedback.LinkInputSig(TriList.StringInput[UIStringJoin.VCLayoutModeText]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void RevealKeyboard()
|
|
{
|
|
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadVisible && KeypadMode == eKeypadMode.Dial)
|
|
{
|
|
var kb = Parent.Keyboard;
|
|
kb.KeyPress += new EventHandler<PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs>(Keyboard_KeyPress);
|
|
kb.HideAction = this.DetachKeyboard;
|
|
kb.GoButtonText = "Connect";
|
|
kb.GoButtonVisible = true;
|
|
DialStringKeypadCheckEnables();
|
|
kb.Show();
|
|
}
|
|
else if(VCControlsInterlock.CurrentJoin == UIBoolJoin.VCDirectoryVisible)
|
|
{
|
|
var kb = Parent.Keyboard;
|
|
kb.KeyPress += Keyboard_KeyPress;
|
|
kb.HideAction = this.DetachKeyboard;
|
|
kb.GoButtonText = "Search";
|
|
kb.GoButtonVisible = true;
|
|
SearchStringKeypadCheckEnables();
|
|
kb.Show();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void Keyboard_KeyPress(object sender, PepperDash.Essentials.Core.Touchpanels.Keyboards.KeyboardControllerPressEventArgs e)
|
|
{
|
|
if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadVisible)
|
|
{
|
|
if (KeypadMode == eKeypadMode.Dial)
|
|
if (e.Text != null)
|
|
DialStringBuilder.Append(e.Text);
|
|
else
|
|
{
|
|
if (e.SpecialKey == KeyboardSpecialKey.Backspace)
|
|
DialKeypadBackspacePress();
|
|
else if (e.SpecialKey == KeyboardSpecialKey.Clear)
|
|
DialKeypadClear();
|
|
else if (e.SpecialKey == KeyboardSpecialKey.GoButton)
|
|
{
|
|
ConnectPress();
|
|
Parent.Keyboard.Hide();
|
|
}
|
|
}
|
|
DialStringFeedback.FireUpdate();
|
|
DialStringKeypadCheckEnables();
|
|
}
|
|
else if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCDirectoryVisible)
|
|
{
|
|
if (e.Text != null)
|
|
SearchStringBuilder.Append(e.Text);
|
|
else
|
|
{
|
|
if (e.SpecialKey == KeyboardSpecialKey.Backspace)
|
|
SearchKeypadBackspacePress();
|
|
else if (e.SpecialKey == KeyboardSpecialKey.Clear)
|
|
SearchKeypadClear();
|
|
else if (e.SpecialKey == KeyboardSpecialKey.GoButton)
|
|
{
|
|
SearchPress();
|
|
Parent.Keyboard.Hide();
|
|
}
|
|
}
|
|
SearchStringFeedback.FireUpdate();
|
|
SearchStringKeypadCheckEnables();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void DetachKeyboard()
|
|
{
|
|
Parent.Keyboard.KeyPress -= Keyboard_KeyPress;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the camera controls subpage
|
|
/// </summary>
|
|
void ShowCameraControls()
|
|
{
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraVisible);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingCameraPress);
|
|
}
|
|
|
|
/// <summary>
|
|
/// shows the directory subpage
|
|
/// </summary>
|
|
void ShowDirectory()
|
|
{
|
|
// populate directory
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCDirectoryVisible);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingDirectoryPress);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// shows the appropriate keypad depending on mode
|
|
/// </summary>
|
|
void ShowKeypad()
|
|
{
|
|
if(CodecHasFavorites)
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadWithFavoritesVisible);
|
|
else
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the self-view layout controls subpage
|
|
/// </summary>
|
|
void ShowSelfViewLayout()
|
|
{
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCSelfViewLayoutVisible);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingSelfViewLayoutPress);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Shows the recents subpage
|
|
/// </summary>
|
|
void ShowRecents()
|
|
{
|
|
//populate recents
|
|
VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCRecentsVisible);
|
|
StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Connect call button
|
|
/// </summary>
|
|
void ConnectPress()
|
|
{
|
|
Codec.Dial(DialStringBuilder.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="i"></param>
|
|
void DialKeypadPress(string i)
|
|
{
|
|
if (KeypadMode == eKeypadMode.Dial)
|
|
{
|
|
DialStringBuilder.Append(i);
|
|
DialStringFeedback.FireUpdate();
|
|
DialStringKeypadCheckEnables();
|
|
}
|
|
else
|
|
{
|
|
Codec.SendDtmf(i);
|
|
DialStringBuilder.Append(i);
|
|
DialStringFeedback.FireUpdate();
|
|
// no delete key in this mode!
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void DialKeypadBackspacePress()
|
|
{
|
|
DialStringBuilder.Remove(DialStringBuilder.Length - 1, 1);
|
|
DialStringFeedback.FireUpdate();
|
|
DialStringKeypadCheckEnables();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the dial keypad
|
|
/// </summary>
|
|
void DialKeypadClear()
|
|
{
|
|
DialStringBuilder.Remove(0, DialStringBuilder.Length);
|
|
DialStringFeedback.FireUpdate();
|
|
DialStringKeypadCheckEnables();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the enabled states of various elements around the keypad
|
|
/// </summary>
|
|
void DialStringKeypadCheckEnables()
|
|
{
|
|
var textIsEntered = DialStringBuilder.Length > 0;
|
|
TriList.SetBool(UIBoolJoin.VCKeypadBackspaceVisible, textIsEntered);
|
|
TriList.SetBool(UIBoolJoin.VCStagingConnectEnable, textIsEntered);
|
|
if (textIsEntered)
|
|
Parent.Keyboard.EnableGoButton();
|
|
else
|
|
Parent.Keyboard.DisableGoButton();
|
|
}
|
|
|
|
|
|
void SearchPress()
|
|
{
|
|
(Codec as IHasDirectory).SearchDirectory(SearchStringBuilder.ToString());
|
|
}
|
|
|
|
void SearchKeypadPress(string i)
|
|
{
|
|
SearchStringBuilder.Append(i);
|
|
SearchStringFeedback.FireUpdate();
|
|
SearchStringKeypadCheckEnables();
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void SearchKeypadBackspacePress()
|
|
{
|
|
SearchStringBuilder.Remove(SearchStringBuilder.Length - 1, 1);
|
|
|
|
if (SearchStringBuilder.Length == 0)
|
|
SetCurrentDirectoryToRoot();
|
|
|
|
SearchStringFeedback.FireUpdate();
|
|
SearchStringKeypadCheckEnables();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the Search keypad
|
|
/// </summary>
|
|
void SearchKeypadClear()
|
|
{
|
|
SearchStringBuilder.Remove(0, SearchStringBuilder.Length);
|
|
SearchStringFeedback.FireUpdate();
|
|
SearchStringKeypadCheckEnables();
|
|
|
|
SetCurrentDirectoryToRoot();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks the enabled states of various elements around the keypad
|
|
/// </summary>
|
|
void SearchStringKeypadCheckEnables()
|
|
{
|
|
var textIsEntered = SearchStringBuilder.Length > 0;
|
|
TriList.SetBool(UIBoolJoin.VCDirectoryBackspaceVisible, textIsEntered);
|
|
if (textIsEntered)
|
|
Parent.Keyboard.EnableGoButton();
|
|
else
|
|
Parent.Keyboard.DisableGoButton();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
string GetFormattedDialString(string ds)
|
|
{
|
|
if (DialStringBuilder.Length == 0 && !Codec.IsInCall)
|
|
{
|
|
return "Dial or touch to enter address";
|
|
}
|
|
if(Regex.Match(ds, @"^\d{4,7}$").Success) // 456-7890
|
|
return string.Format("{0}-{1}", ds.Substring(0, 3), ds.Substring(3));
|
|
if (Regex.Match(ds, @"^9\d{4,7}$").Success) // 456-7890
|
|
return string.Format("9 {0}-{1}", ds.Substring(1, 3), ds.Substring(4));
|
|
if (Regex.Match(ds, @"^\d{8,10}$").Success) // 123-456-78
|
|
return string.Format("({0}) {1}-{2}", ds.Substring(0, 3), ds.Substring(3, 3), ds.Substring(6));
|
|
if (Regex.Match(ds, @"^\d{10}$").Success) // 123-456-7890 full
|
|
return string.Format("({0}) {1}-{2}", ds.Substring(0, 3), ds.Substring(3, 3), ds.Substring(6));
|
|
if (Regex.Match(ds, @"^1\d{10}$").Success)
|
|
return string.Format("+1 ({0}) {1}-{2}", ds.Substring(1, 3), ds.Substring(4, 3), ds.Substring(7));
|
|
if (Regex.Match(ds, @"^9\d{10}$").Success)
|
|
return string.Format("9 ({0}) {1}-{2}", ds.Substring(1, 3), ds.Substring(4, 3), ds.Substring(7));
|
|
if (Regex.Match(ds, @"^91\d{10}$").Success)
|
|
return string.Format("9 +1 ({0}) {1}-{2}", ds.Substring(2, 3), ds.Substring(5, 3), ds.Substring(8));
|
|
return ds;
|
|
}
|
|
|
|
enum eKeypadMode
|
|
{
|
|
Dial, DTMF
|
|
}
|
|
}
|
|
} |