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 { /// /// 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. /// /// public class EssentialsVideoCodecUiDriver : PanelDriverBase { IAVDriver Parent; /// /// /// VideoCodecBase Codec; /// /// To drive UI elements outside of this driver that may be dependent on this. /// BoolFeedback InCall; BoolFeedback LocalPrivacyIsMuted; /// /// For the subpages above the bar /// JoinedSigInterlock VCControlsInterlock; /// /// For the different staging bars: Active, inactive /// JoinedSigInterlock StagingBarsInterlock; /// /// For the staging button feedbacks /// 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; /// /// /// /// /// 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(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 } /// /// /// /// /// void Codec_IsReady() { TriList.SetString(UIStringJoin.RoomPhoneText, Codec.CodecInfo.PhoneNumber); TriList.SetString(UIStringJoin.RoomSipText, Codec.CodecInfo.SipUri); } /// /// Handles status changes for calls /// /// /// 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); } /// /// Redraws the calls list on the header /// 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; } /// /// /// 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; }); } /// /// /// public override void Show() { VCControlsInterlock.Show(); StagingBarsInterlock.Show(); DialStringFeedback.FireUpdate(); base.Show(); } /// /// /// public override void Hide() { VCControlsInterlock.Hide(); StagingBarsInterlock.Hide(); base.Hide(); } /// /// Builds the call stage /// 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(); }); } /// /// /// 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); } /// /// /// 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(); } } /// /// /// 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; } } /// /// /// 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); } } } /// /// /// 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(dir_DirectoryResultReturned); if (codec.PhonebookSyncState.InitialSyncComplete) SetCurrentDirectoryToRoot(); else { codec.PhonebookSyncState.InitialSyncCompleted += new EventHandler(PhonebookSyncState_InitialSyncCompleted); } // If there is something here now, show it otherwise wait for the event if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0) { RefreshDirectory(); } } } } /// /// Sets the current directory resutls to the DirectorRoot and updates Back Button visibiltiy /// void SetCurrentDirectoryToRoot() { LastFolderRequestedParentFolderId = string.Empty; CurrentDirectoryResult = (Codec as IHasDirectory).DirectoryRoot; DirectoryBackButtonVisibleFeedback.FireUpdate(); RefreshDirectory(); } /// /// Setup the Directory list when notified that the initial phonebook sync is completed /// /// /// void PhonebookSyncState_InitialSyncCompleted(object sender, EventArgs e) { var codec = Codec as IHasDirectory; SetCurrentDirectoryToRoot(); if (CurrentDirectoryResult != null && codec.DirectoryRoot.DirectoryResults.Count > 0) { RefreshDirectory(); } } /// /// /// /// /// void dir_DirectoryResultReturned(object sender, DirectoryEventArgs e) { CurrentDirectoryResult = e.Directory; DirectoryBackButtonVisibleFeedback.FireUpdate(); RefreshDirectory(); } /// /// Helper method to retrieve directory folder contents and store last requested folder id /// /// void GetDirectoryFolderContents(DirectoryFolder folder) { if (!string.IsNullOrEmpty(folder.ParentFolderId)) LastFolderRequestedParentFolderId = folder.ParentFolderId; else LastFolderRequestedParentFolderId = string.Empty; (Codec as IHasDirectory).GetDirectoryFolderContents(folder.FolderId); } /// /// Request the parent folder contents or sets back to the root if no parent folder /// void GetDirectoryParentFolderContents() { var codec = Codec as IHasDirectory; if (!string.IsNullOrEmpty(LastFolderRequestedParentFolderId)) codec.GetDirectoryFolderContents(LastFolderRequestedParentFolderId); else { SetCurrentDirectoryToRoot(); } } /// /// /// /// 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; } /// /// /// 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]); } } /// /// /// void RevealKeyboard() { if (VCControlsInterlock.CurrentJoin == UIBoolJoin.VCKeypadVisible && KeypadMode == eKeypadMode.Dial) { var kb = Parent.Keyboard; kb.KeyPress += new EventHandler(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(); } } /// /// /// 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; } /// /// Shows the camera controls subpage /// void ShowCameraControls() { VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCCameraVisible); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingCameraPress); } /// /// shows the directory subpage /// void ShowDirectory() { // populate directory VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCDirectoryVisible); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingDirectoryPress); } /// /// shows the appropriate keypad depending on mode /// void ShowKeypad() { if(CodecHasFavorites) VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadWithFavoritesVisible); else VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCKeypadVisible); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingKeypadPress); } /// /// Shows the self-view layout controls subpage /// void ShowSelfViewLayout() { VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCSelfViewLayoutVisible); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingSelfViewLayoutPress); } /// /// Shows the recents subpage /// void ShowRecents() { //populate recents VCControlsInterlock.ShowInterlocked(UIBoolJoin.VCRecentsVisible); StagingButtonsFeedbackInterlock.ShowInterlocked(UIBoolJoin.VCStagingRecentsPress); } /// /// Connect call button /// void ConnectPress() { Codec.Dial(DialStringBuilder.ToString()); } /// /// /// /// 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! } } /// /// /// void DialKeypadBackspacePress() { DialStringBuilder.Remove(DialStringBuilder.Length - 1, 1); DialStringFeedback.FireUpdate(); DialStringKeypadCheckEnables(); } /// /// Clears the dial keypad /// void DialKeypadClear() { DialStringBuilder.Remove(0, DialStringBuilder.Length); DialStringFeedback.FireUpdate(); DialStringKeypadCheckEnables(); } /// /// Checks the enabled states of various elements around the keypad /// 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(); } /// /// /// void SearchKeypadBackspacePress() { SearchStringBuilder.Remove(SearchStringBuilder.Length - 1, 1); if (SearchStringBuilder.Length == 0) SetCurrentDirectoryToRoot(); SearchStringFeedback.FireUpdate(); SearchStringKeypadCheckEnables(); } /// /// Clears the Search keypad /// void SearchKeypadClear() { SearchStringBuilder.Remove(0, SearchStringBuilder.Length); SearchStringFeedback.FireUpdate(); SearchStringKeypadCheckEnables(); SetCurrentDirectoryToRoot(); } /// /// Checks the enabled states of various elements around the keypad /// void SearchStringKeypadCheckEnables() { var textIsEntered = SearchStringBuilder.Length > 0; TriList.SetBool(UIBoolJoin.VCDirectoryBackspaceVisible, textIsEntered); if (textIsEntered) Parent.Keyboard.EnableGoButton(); else Parent.Keyboard.DisableGoButton(); } /// /// /// /// 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 } } }