From bceaf80be3890fb9e7a1211b175fff043fa336af Mon Sep 17 00:00:00 2001 From: jwetzell Date: Fri, 19 Apr 2019 13:51:07 -0500 Subject: [PATCH] Start work on Group Cue children loading --- Droid/Properties/AndroidManifest.xml | 4 +- qController.Standard/App.xaml | 2 +- .../Classes/Cell/QSelectedCueCell.cs | 2 +- .../Classes/Communication/QClient.cs | 2 - .../Classes/Communication/QController.cs | 48 ++++++++++++-- .../Classes/Communication/QParser.cs | 38 ++++++++++- qController.Standard/Classes/Cues/QCue.cs | 17 ++--- .../Classes/Cues/QWorkSpace.cs | 33 +++++++++- .../Pages/ControlPage.xaml.cs | 39 ++++++++---- qController.Standard/Pages/MenuPage.xaml.cs | 63 +++++++++++++------ .../Pages/qConnectionPage.xaml.cs | 5 +- 11 files changed, 198 insertions(+), 55 deletions(-) diff --git a/Droid/Properties/AndroidManifest.xml b/Droid/Properties/AndroidManifest.xml index cb67ee0..2acc5dc 100644 --- a/Droid/Properties/AndroidManifest.xml +++ b/Droid/Properties/AndroidManifest.xml @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/qController.Standard/App.xaml b/qController.Standard/App.xaml index b1b4df3..01d0fc9 100644 --- a/qController.Standard/App.xaml +++ b/qController.Standard/App.xaml @@ -3,7 +3,7 @@ - + diff --git a/qController.Standard/Classes/Cell/QSelectedCueCell.cs b/qController.Standard/Classes/Cell/QSelectedCueCell.cs index 6d579b7..0cb95aa 100644 --- a/qController.Standard/Classes/Cell/QSelectedCueCell.cs +++ b/qController.Standard/Classes/Cell/QSelectedCueCell.cs @@ -115,7 +115,7 @@ namespace qController public void UpdateSelectedCue(QCue cue) { - name.Text = cue.name; + name.Text = cue.listName; number.Text = cue.number; type.Text = cue.getIconString(); notes.Text = cue.notes; diff --git a/qController.Standard/Classes/Communication/QClient.cs b/qController.Standard/Classes/Communication/QClient.cs index e8b9594..8f7ed5f 100644 --- a/qController.Standard/Classes/Communication/QClient.cs +++ b/qController.Standard/Classes/Communication/QClient.cs @@ -93,8 +93,6 @@ namespace qController { UpdateWorkspace("not yet implemented"); } - - } public void UpdateSpecificCue(string cue_id) diff --git a/qController.Standard/Classes/Communication/QController.cs b/qController.Standard/Classes/Communication/QController.cs index dbcbe2e..c9a61ee 100644 --- a/qController.Standard/Classes/Communication/QController.cs +++ b/qController.Standard/Classes/Communication/QController.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Diagnostics; using Xamarin.Forms; namespace qController @@ -13,6 +14,7 @@ namespace qController public QClient qClient; public QWorkSpace qWorkspace; public string playbackPosition; + public Stopwatch sw; public QController(string address, int port) { qClient = new QClient(address, port); @@ -23,18 +25,40 @@ namespace qController qClient.qParser.PlaybackPositionUpdated += this.OnPlaybackPositionUpdated; qClient.qParser.CueInfoUpdated += this.OnCueUpdateReceived; qClient.qParser.AudioLevelsUpdated += this.OnAudioLevelsUpdated; + qClient.qParser.ChildrenUpdated += this.OnChildrenUpdated; qClient.sendArgsUDP("/updates", 1); qClient.sendArgsUDP("/updates", 1); qClient.sendAndReceiveString("/cueLists"); } + private void OnChildrenUpdated(object source, ChildrenEventArgs args) + { + Console.WriteLine("Children Updated in QController: " + args.cue_id); + qWorkspace.UpdateChildren(args.cue_id, args.children); + + foreach (var cueList in qWorkspace.data) + { + foreach (var cue in cueList.cues) + { + if (cue.type == "Group") + { + if (cue.cues == null) + { + Console.WriteLine("Next Group Cue Found"); + qClient.sendStringUDP("/cue_id/" + cue.uniqueID + "/children"); + break; + } + } + } + } + } + private void OnAudioLevelsUpdated(object source, AudioLevelArgs args) { if(qWorkspace != null) qWorkspace.UpdateLevels(args.cue_id, args.levels); } - public void Connect() { qClient.sendStringUDP("/connect"); @@ -50,14 +74,28 @@ namespace qController qClient.sendArgsUDP("/connect", pass); } - public void sendCommand(string cmd){ - qClient.sendString(cmd); - } - public void updateCueValue(QCue cue, string property, object newValue){ //qClient.sendArgs("/cue_id/"+cue.uniqueID+"/"+property, newValue); } + public void RefreshGroupCues() + { + if (qWorkspace.ChildrenPopulated()) + return; + foreach (var cueList in qWorkspace.data) + { + foreach (var cue in cueList.cues) + { + if (cue.type == "Group") + { + Console.WriteLine("First Group Cue Found"); + qClient.sendStringUDP("/cue_id/" + cue.uniqueID + "/children"); + break; + } + } + } + } + public void OnSelectedCueUpdated(object source, CueEventArgs args) { selectedCue = args.Cue; diff --git a/qController.Standard/Classes/Communication/QParser.cs b/qController.Standard/Classes/Communication/QParser.cs index 8aa8229..3866cec 100644 --- a/qController.Standard/Classes/Communication/QParser.cs +++ b/qController.Standard/Classes/Communication/QParser.cs @@ -52,6 +52,19 @@ namespace qController set; } } + public class ChildrenEventArgs : EventArgs + { + public string cue_id + { + get; + set; + } + public List children + { + get; + set; + } + } public class QParser { public QParser() @@ -65,6 +78,8 @@ namespace qController public delegate void CueInfoUpdatedHandler(object source, CueEventArgs args); public delegate void PlaybackPositionUpdatedHandler(object source, PlaybackPositionArgs args); public delegate void ConnectionStatusHandler(object source, ConnectEventArgs args); + public delegate void ChildrenUpdateHandler(object source, ChildrenEventArgs args); + public event ChildrenUpdateHandler ChildrenUpdated; public event ConnectionStatusHandler ConnectionStatusChanged; public event SelectedCueUpdatedHandler SelectedCueUpdated; public event AudioLevelsUpdatedHandler AudioLevelsUpdated; @@ -94,6 +109,8 @@ namespace qController Console.WriteLine("Heartbeat Received"); else if (msg.Address.Contains("connect")) ParseConnectInfo(msg); + else if (msg.Address.Contains("children")) + ParseChildrenInfo(msg); else { Console.WriteLine("Unknown message type"); @@ -103,10 +120,9 @@ namespace qController Console.WriteLine(item); } } - } } - + public void ParseConnectInfo(OscMessage msg) { JToken connectStatus = OSC2JSON(msg); @@ -130,7 +146,6 @@ namespace qController public void ParseSelectedCueInfo(OscMessage msg){ JToken selectedCue = OSC2JSON(msg); - Console.WriteLine("Selected Cue Updated"); QCue cue = JsonConvert.DeserializeObject(selectedCue.ToString()); OnSelectedCueUpdated(cue); } @@ -154,6 +169,17 @@ namespace qController } } + public void ParseChildrenInfo(OscMessage msg) + { + if (msg.Arguments.Count > 0) + { + string cue_id = msg.Address.Split('/')[3]; + JToken children_obj = OSC2JSON(msg); + List children = JsonConvert.DeserializeObject>(children_obj.ToString()); + OnChildrenUpdated(cue_id, children); + } + } + public JToken OSC2JSON(OscMessage Msg){ JObject json = JObject.Parse(Msg.Arguments.ToArray()[0].ToString()); return json.GetValue("data"); @@ -191,5 +217,11 @@ namespace qController if (ConnectionStatusChanged != null) ConnectionStatusChanged(this, new ConnectEventArgs() { Status = status }); } + protected virtual void OnChildrenUpdated(string id, List cues) + { + if (ChildrenUpdated != null) + ChildrenUpdated(this, new ChildrenEventArgs() { cue_id = id, children = cues }); + } + } } diff --git a/qController.Standard/Classes/Cues/QCue.cs b/qController.Standard/Classes/Cues/QCue.cs index 9df1879..a227024 100644 --- a/qController.Standard/Classes/Cues/QCue.cs +++ b/qController.Standard/Classes/Cues/QCue.cs @@ -13,21 +13,22 @@ namespace qController public string colorName { get; set; } public string name { get; set; } public bool armed { get; set; } - public int translationX { get; set; } + public decimal translationX { get; set; } public bool isRunning { get; set; } - public int scaleX { get; set; } + public decimal scaleX { get; set; } public bool isPaused { get; set; } - public int translationY { get; set; } - public int preWait { get; set; } - public int opacity { get; set; } - public int scaleY { get; set; } - public int duration { get; set; } - public int postWait { get; set; } + public decimal translationY { get; set; } + public decimal preWait { get; set; } + public decimal opacity { get; set; } + public decimal scaleY { get; set; } + public decimal duration { get; set; } + public decimal postWait { get; set; } public bool isBroken { get; set; } public string displayName { get; set; } public bool isLoaded { get; set; } public string notes { get; set; } public List levels { get; set; } + public List cues { get; set; } public string getIconString() { switch (type) diff --git a/qController.Standard/Classes/Cues/QWorkSpace.cs b/qController.Standard/Classes/Cues/QWorkSpace.cs index 827e348..9857a7e 100644 --- a/qController.Standard/Classes/Cues/QWorkSpace.cs +++ b/qController.Standard/Classes/Cues/QWorkSpace.cs @@ -9,7 +9,6 @@ namespace qController public List data { get; set; } public string workspace_id { get; set; } public string address { get; set; } - public QCue GetCue(string cue_id) { QCue returnCue = null; @@ -40,6 +39,23 @@ namespace qController } } + public void UpdateChildren(string cue_id, List children) + { + for (int i = 0; i < data.Count; i++) + { + for (int j = 0; j < data[i].cues.Count; j++) + { + if (data[i].cues[j].uniqueID == cue_id) + { + if(data[i].cues[j].type == "Group") + { + data[i].cues[j].cues = children; + } + } + } + } + } + public void UpdateLevels(string cue_id, List levels) { for (int i = 0; i < data.Count; i++) @@ -55,6 +71,21 @@ namespace qController } } + public bool ChildrenPopulated() + { + for (int i = 0; i < data.Count; i++) + { + for (int j = 0; j < data[i].cues.Count; j++) + { + if (data[i].cues[j].type == "Group" && data[i].cues[j].cues == null) + { + return false; + } + } + } + return true; + } + public void PrintStats() { foreach (var cueList in data) diff --git a/qController.Standard/Pages/ControlPage.xaml.cs b/qController.Standard/Pages/ControlPage.xaml.cs index 38b4880..c248a5b 100644 --- a/qController.Standard/Pages/ControlPage.xaml.cs +++ b/qController.Standard/Pages/ControlPage.xaml.cs @@ -23,6 +23,7 @@ namespace qController qController.qClient.qParser.PlaybackPositionUpdated += PlaybackPositionUpdated; qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived; qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged; + qController.qClient.qParser.ChildrenUpdated += OnChildrenUpdated; instanceName.Text = name; App.rootPage.MenuItemSelected += OnMenuItemSelected; qController.Connect(); @@ -30,6 +31,30 @@ namespace qController } + private void OnChildrenUpdated(object source, ChildrenEventArgs args) + { + Console.WriteLine("Children Updated in ControlPage: " + args.cue_id); + qController.qWorkspace.UpdateChildren(args.cue_id, args.children); + if (qController.qWorkspace.ChildrenPopulated()) + { + Device.BeginInvokeOnMainThread(() => + { + if (App.MenuIsPresented) + { + //App.MenuIsPresented = false; + App.rootPage.MenuPage.ChangeToWorkspace(qController.qWorkspace); + //App.MenuIsPresented = true; + } + else + { + App.rootPage.MenuPage.ChangeToWorkspace(qController.qWorkspace); + + } + }); + qController.qClient.UpdateSelectedCue(); + } + } + private void OnConnectionStatusChanged(object source, ConnectEventArgs args) { if (args.Status == "ok") @@ -149,7 +174,6 @@ namespace qController sLayout.Children.Add(mainG); - } void sendOSC(object sender, EventArgs e) @@ -193,6 +217,7 @@ namespace qController App.rootPage.MenuPage.ChangeToWorkspace(e.UpdatedWorkspace); qController.qWorkspace = e.UpdatedWorkspace; + //qController.RefreshGroupCues(); Console.WriteLine("Workspace updated in ControlPage: " + qController.qWorkspace.workspace_id); } } @@ -206,15 +231,9 @@ namespace qController { Device.BeginInvokeOnMainThread(() => { if (cue.type.Equals("Audio")) - { - //Console.WriteLine("CUE IS AN AUDIO CUE"); sLayout.Children.Add(qSelectedCueOptions); - } else - { - //Console.WriteLine("CUE IS NOT AN AUDIO CUE"); sLayout.Children.Remove(qSelectedCueOptions); - } qCell.UpdateSelectedCue(cue); }); } @@ -230,15 +249,9 @@ namespace qController Device.BeginInvokeOnMainThread(() => { if (args.Cue.type.Equals("Audio")) - { - //Console.WriteLine("CUE IS AN AUDIO CUE"); sLayout.Children.Add(qSelectedCueOptions); - } else - { - //Console.WriteLine("CUE IS NOT AN AUDIO CUE"); sLayout.Children.Remove(qSelectedCueOptions); - } qCell.UpdateSelectedCue(args.Cue); }); } diff --git a/qController.Standard/Pages/MenuPage.xaml.cs b/qController.Standard/Pages/MenuPage.xaml.cs index 1fb7f15..d4271eb 100644 --- a/qController.Standard/Pages/MenuPage.xaml.cs +++ b/qController.Standard/Pages/MenuPage.xaml.cs @@ -10,6 +10,7 @@ namespace qController public ListView listView; public ObservableCollection items; + int subLevel = 0; public MenuPage() { Title = "Menu"; @@ -88,29 +89,55 @@ namespace qController }); foreach (var cue in cueList.cues) { - var cueIcon = cue.getIconString(); - var cueTitle = ""; - - if(cue.number != "") - { - cueTitle = "\t" + cue.number + " - " + cue.listName; - } - else - { - cueTitle = "\t" + cue.listName; - } - - items.Add(new MenuPageItem - { - Title = cueTitle, - Icon = cueIcon, - Command = "/select_id/" + cue.uniqueID - }); + AddSubCues(cue, 0); } } } + public void AddSubCues(QCue cue, int level) + { + var cueIcon = cue.getIconString(); + var cueTitle = ""; + for (int i = 0; i < level; i++) + { + cueTitle += " "; + } + if (cue.number != "") + { + cueTitle += cue.number + " - " + cue.listName; + } + else + { + cueTitle += cue.listName; + } + + if (cue.cues != null ) + { + items.Add(new MenuPageItem + { + Title = cueTitle, + Icon = cueIcon, + Command = "/select_id/" + cue.uniqueID + }); + + //uncomment to load nested group cues + /*foreach (var sub_cue in cue.cues) + { + AddSubCues(sub_cue,level + 1); + }*/ + } + else + { + items.Add(new MenuPageItem + { + Title = cueTitle, + Icon = cueIcon, + Command = "/select_id/" + cue.uniqueID + }); + } + } + public void ChangeToHome() { items.Clear(); diff --git a/qController.Standard/Pages/qConnectionPage.xaml.cs b/qController.Standard/Pages/qConnectionPage.xaml.cs index 253cee4..2c31b95 100644 --- a/qController.Standard/Pages/qConnectionPage.xaml.cs +++ b/qController.Standard/Pages/qConnectionPage.xaml.cs @@ -55,7 +55,10 @@ namespace qController case Device.iOS: menuButton.Margin = new Thickness(20, 35, 20, 10); break; - + case Device.Android: + topBar.HeightRequest = 50; + menuButton.Margin = new Thickness(20, 10, 20, 10); + break; } menuButton.Text = "\uF0C9";