Switch to only TCP Communication

- No more UDP
- Lots of random refactoring as well
This commit is contained in:
2020-06-06 12:12:23 -05:00
parent ac084bb343
commit fe8bd257d1
32 changed files with 323 additions and 177 deletions
@@ -0,0 +1,29 @@
using Xamarin.Forms;
namespace qController
{
public class QLevelsButton : ShadowButton
{
public Button button;
public QLevelsButton()
{
button = new Button
{
Text = QIcon.SLIDERS,
TextColor = Color.Black,
FontFamily = App.QFont,
FontSize = App.HeightUnit * 4,
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = App.HeightUnit * 8,
WidthRequest = App.HeightUnit * 8,
CornerRadius = (int)(App.HeightUnit * 4),
BackgroundColor = Color.LightBlue
};
HeightRequest = button.Height;
WidthRequest = button.Width;
CornerRadius = button.CornerRadius;
Content = button;
}
}
}
@@ -16,5 +16,13 @@ namespace qController
BorderColor = Color.Black; BorderColor = Color.Black;
IsVisible = false; IsVisible = false;
} }
public ShadowButton()
{
HasShadow = true;
BorderColor = Color.Black;
IsVisible = false;
Padding = new Thickness(0);
}
} }
} }
@@ -1,8 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Xamarin.Forms; using Xamarin.Forms;
using qController.Communication;
namespace qController namespace qController.Cell
{ {
public class QControlsBlock : Frame public class QControlsBlock : Frame
{ {
@@ -130,7 +131,7 @@ namespace qController
{ {
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id; string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
string command = workspace_prefix + ((QButton)sender).qCommand.osc; string command = workspace_prefix + ((QButton)sender).qCommand.osc;
qController.qClient.sendUDP(command); qController.qClient.sendTCP(command);
} }
} }
} }
@@ -1,8 +1,8 @@
using System; using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using Xamarin.Forms; using Xamarin.Forms;
using qController.QItems;
namespace qController namespace qController.Cell
{ {
public class QCueListCell : Frame public class QCueListCell : Frame
{ {
@@ -2,7 +2,7 @@
using Xamarin.Forms; using Xamarin.Forms;
using Serilog; using Serilog;
namespace qController namespace qController.Cell
{ {
public class QInstanceCell : ViewCell public class QInstanceCell : ViewCell
{ {
@@ -1,7 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using Xamarin.Forms; using Xamarin.Forms;
namespace qController namespace qController.Cell
{ {
public class QLevelsCell : Frame public class QLevelsCell : Frame
{ {
@@ -1,8 +1,9 @@
using System; using System;
using Acr.UserDialogs; using Acr.UserDialogs;
using qController.QItems;
using Xamarin.Forms; using Xamarin.Forms;
namespace qController namespace qController.Cell
{ {
public class CueEditArgs : EventArgs public class CueEditArgs : EventArgs
{ {
@@ -2,7 +2,7 @@
//IMPLEMENT A ISREACHABLE METHOD TO BE ABLE TO DISPLAY ONLINE QINSTANCES //IMPLEMENT A ISREACHABLE METHOD TO BE ABLE TO DISPLAY ONLINE QINSTANCES
using System.Net; using System.Net;
namespace qController namespace qController.Communication
{ {
public class IPHelper public class IPHelper
{ {
@@ -1,15 +1,15 @@
//Class used to facilitate communication with a QInstance //Class used to facilitate communication with a QInstance
//Listens for incoming messages via qReceiver (UDP) and tcpSender (TCP) //Listens for incoming messages via qReceiver (UDP) and tcpClient (TCP)
//TODO: WEIRD MESSAGE PARSING RULES NEED FIXED //TODO: WEIRD MESSAGE PARSING RULES NEED FIXED
using System; using System;
using SharpOSC; using SharpOSC;
using Serilog; using Serilog;
namespace qController namespace qController.Communication
{ {
public class QClient public class QClient
{ {
TCPSender tcpSender; TCPClient tcpClient;
UDPSender udpSender; UDPSender udpSender;
public QParser qParser; public QParser qParser;
public QReceiver qReceiver; public QReceiver qReceiver;
@@ -21,13 +21,13 @@ namespace qController
Address = address; Address = address;
Port = port; Port = port;
qParser = new QParser(); qParser = new QParser();
qReceiver = new QReceiver(Port + 1); //qReceiver = new QReceiver(Port + 1);
tcpSender = new TCPSender(Address, Port); tcpClient = new TCPClient(Address, Port);
tcpSender.Connect(); tcpClient.Connect();
udpSender = new UDPSender(Address, Port); //udpSender = new UDPSender(Address, Port);
tcpSender.MessageReceived += OnMessageReceived; tcpClient.MessageReceived += OnMessageReceived;
qReceiver.UpdateMessageReceived += OnMessageReceived; //qReceiver.UpdateMessageReceived += OnMessageReceived;
} }
@@ -51,26 +51,27 @@ namespace qController
ProcessUpdate(args.Message); ProcessUpdate(args.Message);
} }
public void sendUDP(string address) //public void sendUDP(string address)
{ //{
//Log.Debug($"QCLIENT - UDP Sent with address: {address}"); // //Log.Debug($"QCLIENT - UDP Sent with address: {address}");
udpSender = new UDPSender(Address,Port); // udpSender = new UDPSender(Address,Port);
udpSender.Send(new OscMessage(address)); // udpSender.Send(new OscMessage(address));
udpSender.Close(); // udpSender.Close();
} //}
public void sendUDP(string address, params object[] args) //public void sendUDP(string address, params object[] args)
{ //{
//Log.Debug($"QCLIENT - UDP Sent with address: {address}"); // //Log.Debug($"QCLIENT - UDP Sent with address: {address}");
udpSender = new UDPSender(Address, Port); // udpSender = new UDPSender(Address, Port);
udpSender.Send(new OscMessage(address, args)); // udpSender.Send(new OscMessage(address, args));
udpSender.Close(); // udpSender.Close();
} //}
public void sendTCP(string address) public void sendTCP(string address)
{ {
//Log.Debug($"QCLIENT - TCP Sent with address: {address}"); //Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try try
{ {
tcpSender.Send(new OscMessage(address)); tcpClient.Send(new OscMessage(address));
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -83,7 +84,7 @@ namespace qController
//Log.Debug($"QCLIENT - TCP Sent with address: {address}"); //Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try try
{ {
tcpSender.Send(new OscMessage(address, args)); tcpClient.Send(new OscMessage(address, args));
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -122,8 +123,7 @@ namespace qController
public void Close() public void Close()
{ {
udpSender.Close(); tcpClient.Close();
qReceiver.Close();
} }
} }
} }
@@ -2,10 +2,10 @@
//Contains all necessary items to facilitate communication (sending, receiving) to a QLab workspace //Contains all necessary items to facilitate communication (sending, receiving) to a QLab workspace
//Also contains the local QWorkspace object which stores all the information that is used in displaying //Also contains the local QWorkspace object which stores all the information that is used in displaying
//TODO: STILL NEED TO WORK ON PASSWORD PROTECTED WORKSPACES //TODO: STILL NEED TO WORK ON PASSWORD PROTECTED WORKSPACES
using System;
using Serilog; using Serilog;
using qController.QItems;
namespace qController namespace qController.Communication
{ {
public class QController public class QController
{ {
@@ -31,26 +31,38 @@ namespace qController
{ {
Log.Debug($"QCONTROLLER - Connect Called: {workspace_id}"); Log.Debug($"QCONTROLLER - Connect Called: {workspace_id}");
qWorkspace = new QWorkspace(workspace_id); qWorkspace = new QWorkspace(workspace_id);
qClient.sendUDP("/workspace/"+workspace_id+"/connect"); qClient.sendTCP("/workspace/"+workspace_id+"/connect");
} }
public void Connect(string workspace_id, string passcode) public void Connect(string workspace_id, string passcode)
{ {
Log.Debug($"QCONTROLLER - Connect with Passcode Called: {workspace_id}:{passcode}"); Log.Debug($"QCONTROLLER - Connect with Passcode Called: {workspace_id}:{passcode}");
qWorkspace = new QWorkspace(workspace_id); qWorkspace = new QWorkspace(workspace_id);
qClient.sendUDP("/workspace/" + workspace_id + "/connect", passcode);
qClient.sendTCP("/workspace/" + workspace_id + "/connect", passcode); qClient.sendTCP("/workspace/" + workspace_id + "/connect", passcode);
} }
public void Connect(QWorkspace workspace)
{
if(workspace.passcode != null)
{
Connect(workspace.workspace_id, workspace.passcode);
}
else
{
Connect(workspace.workspace_id);
}
}
public void KickOff() public void KickOff()
{ {
qClient.sendUDP("/workspaces"); qClient.sendTCP("/workspaces");
} }
public void Disconnect() public void Disconnect()
{ {
qClient.sendUDP("/workspace/"+qWorkspace.workspace_id+"/disconnect"); qClient.sendTCP("/workspace/"+qWorkspace.workspace_id+"/disconnect");
} }
public void Resume() public void Resume()
@@ -4,7 +4,7 @@ using Serilog;
using System.Collections.Generic; using System.Collections.Generic;
using Zeroconf; using Zeroconf;
namespace qController namespace qController.Communication
{ {
public class QFinder public class QFinder
{ {
@@ -3,9 +3,10 @@ using SharpOSC;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Collections.Generic; using System.Collections.Generic;
using qController.QItems;
using Serilog; using Serilog;
namespace qController namespace qController.Communication
{ {
public class CueEventArgs : EventArgs public class CueEventArgs : EventArgs
{ {
@@ -184,6 +185,7 @@ namespace qController
} }
catch (Exception ex) catch (Exception ex)
{ {
Log.Debug($"QPARSER - Workspace Load Error: {ex.ToString()}");
OnWorkspaceLoadError(id); OnWorkspaceLoadError(id);
} }
} }
@@ -3,9 +3,8 @@ using SharpOSC;
using System.Threading; using System.Threading;
using Serilog; using Serilog;
namespace qController namespace qController.Communication
{ {
public class QReceiver public class QReceiver
{ {
public delegate void UpdateMessageReceivedHandler(object source, MessageEventArgs args); public delegate void UpdateMessageReceivedHandler(object source, MessageEventArgs args);
@@ -5,14 +5,15 @@ using Serilog;
using Xamarin.Forms; using Xamarin.Forms;
using Serilog; using Serilog;
namespace qController namespace qController.Communication
{ {
public class QUpdater public class QUpdater
{ {
private bool active = true; private bool active = true;
private bool started = false;
private QController qController; private QController qController;
private Thread updateThread; private Thread updateThread;
public QUpdater(QController controller) public QUpdater(QController controller)
{ {
@@ -47,7 +48,15 @@ namespace qController
public void Start(){ public void Start(){
Log.Debug("QUPDATER - Start() method called"); Log.Debug("QUPDATER - Start() method called");
updateThread.Start(); try
{
//updateThread.Start();
Log.Debug("QUPDATER - updateThread started");
}
catch (ThreadStateException tSe)
{
Log.Debug("QUPDATER - updateThread already started");
}
} }
//Attempt at a "keep alive" message //Attempt at a "keep alive" message
@@ -67,7 +76,7 @@ namespace qController
if (args.Cue.type == "Group") if (args.Cue.type == "Group")
{ {
//Log.Debug("QUpdater/Updated cue was group cue, sending children request"); //Log.Debug("QUpdater/Updated cue was group cue, sending children request");
qController.qClient.sendUDP("/workspace/"+qController.qWorkspace.workspace_id+"/cue_id/" + args.Cue.uniqueID + "/children"); qController.qClient.sendTCP("/workspace/"+qController.qWorkspace.workspace_id+"/cue_id/" + args.Cue.uniqueID + "/children");
} }
} }
@@ -96,7 +105,7 @@ namespace qController
public void SendThump() public void SendThump()
{ {
qController.qClient.sendUDP("/workspace/" + qController.qWorkspace.workspace_id + "/thump"); qController.qClient.sendTCP("/workspace/" + qController.qWorkspace.workspace_id + "/thump");
} }
public void Kill(){ public void Kill(){
+1
View File
@@ -19,6 +19,7 @@ namespace SharpOSC
this.Value = value; this.Value = value;
} }
override
public string ToString() public string ToString()
{ {
return Value; return Value;
@@ -17,7 +17,7 @@ namespace SharpOSC
} }
} }
public class TCPSender public class TCPClient
{ {
public int Port public int Port
{ {
@@ -41,7 +41,7 @@ namespace SharpOSC
byte ESC_ESC = 0xDD; byte ESC_ESC = 0xDD;
public TCPSender(string address, int port) public TCPClient(string address, int port)
{ {
_port = port; _port = port;
_address = address; _address = address;
@@ -50,7 +50,7 @@ namespace SharpOSC
public void Connect() public void Connect()
{ {
client = new TcpClient(Address, Port); client = new TcpClient(Address, Port);
Log.Debug($"TCPSender - connect called for <{Address}:{Port}>"); Log.Debug($"TCPClient - connect called for <{Address}:{Port}>");
Thread receivingThread = new Thread(ReceiveLoop); Thread receivingThread = new Thread(ReceiveLoop);
receivingThread.Start(); receivingThread.Start();
} }
@@ -74,7 +74,7 @@ namespace SharpOSC
{ {
Receive(); Receive();
} }
Log.Debug("TCPSender - Receive Loop has exited for some reason"); Log.Debug("TCPClient - Receive Loop has exited for some reason");
} }
public void Receive() public void Receive()
@@ -88,19 +88,24 @@ namespace SharpOSC
List<byte> responseData = new List<byte>(); List<byte> responseData = new List<byte>();
if (netStream.CanRead) if (netStream.CanRead)
{ {
//var watch = System.Diagnostics.Stopwatch.StartNew();
byte[] buffer = new byte[256]; byte[] buffer = new byte[256];
int bytesRead = 0; int bytesRead = 0;
int reads = 0;
do do
{ {
bytesRead = netStream.Read(buffer, 0, buffer.Length); bytesRead = netStream.Read(buffer, 0, buffer.Length);
responseData.AddRange(buffer); responseData.AddRange(buffer);
Thread.Sleep(30); reads += 1;
Thread.Sleep(1);
//Log.Debug("Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer)); //Log.Debug("Thread " + num + ": Bytes read: " + bytesRead + " - " + Encoding.UTF8.GetString(buffer));
} while (netStream.DataAvailable); } while (netStream.DataAvailable);
//Log.Debug("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray())); //Log.Debug("Raw TCP In: " + System.Text.Encoding.UTF8.GetString(responseData.ToArray()));
OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray()); OscMessage response = (OscMessage)OscPacket.GetPacket(responseData.Skip(1).ToArray());
//watch.Stop();
//Log.Debug($"TCPCLient - message receive took {watch.ElapsedMilliseconds}ms and {reads} reads");
OnMessageReceived(response); OnMessageReceived(response);
} }
} catch(Exception e) } catch(Exception e)
@@ -0,0 +1,14 @@
using System;
using Acr.UserDialogs;
namespace qController.Dialogs
{
public class NoWorkspacesConfig : ConfirmConfig
{
public NoWorkspacesConfig()
{
Message = "QLab doesn't have any workspaces open?";
OkText = "Disconnect";
}
}
}
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using Acr.UserDialogs;
using qController.QItems;
using Serilog;
namespace qController.Dialogs
{
public class WorkspacePromptArgs : EventArgs
{
public QWorkspace SelectedWorkspace
{
get;
set;
}
}
public class WorkspacePrompt
{
public delegate void WorkspaceSelectedHandler(object source, WorkspacePromptArgs args);
public event WorkspaceSelectedHandler WorkspaceSelected;
public WorkspacePrompt()
{
}
public ActionSheetConfig getActionSheetConfigForWorkspaces(List<QWorkspaceInfo> workspaces)
{
ActionSheetConfig actionSheetConfig = new ActionSheetConfig();
actionSheetConfig.SetTitle("Select Workspace");
for (int i = 0; i < workspaces.Count; i++)
{
QWorkspaceInfo workspace = workspaces[i];
actionSheetConfig.Add(workspace.displayName, new Action(() => {
Log.Debug("CONTROLPAGE - Workspace Selected " + workspace.displayName);
if (!workspace.hasPasscode)
{
OnWorkspaceSelected(new QWorkspace(workspace.uniqueID));
}
else
{
promptWorkspacePasscode(workspace.uniqueID);
}
}));
}
return actionSheetConfig;
}
public void promptWorkspacePasscode(string workspace_id)
{
UserDialogs.Instance.Prompt(new PromptConfig
{
InputType = InputType.Number,
MaxLength = 4,
Title = "Enter Workspace Passcode",
OkText = "Connect",
IsCancellable = true,
OnAction = (resp) =>
{
if (resp.Ok)
{
OnWorkspaceSelected(new QWorkspace(workspace_id,resp.Value));
}
else
{
OnWorkspaceSelected(null);
}
}
});
}
protected virtual void OnWorkspaceSelected(QWorkspace workspace)
{
if (WorkspaceSelected != null)
WorkspaceSelected(this, new WorkspacePromptArgs() { SelectedWorkspace = workspace });
}
}
}
@@ -0,0 +1,14 @@
using System;
namespace qController.QItems
{
public class NoQCueSelected : QCue
{
public NoQCueSelected()
{
listName = "No Cue Selected";
type = "";
notes = "Workspace has loaded but no cue is selected";
number = "!";
}
}
}
@@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace qController namespace qController.QItems
{ {
public class QCue public class QCue
{ {
@@ -1,6 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace qController namespace qController.QItems
{ {
public class QCueList public class QCueList
{ {
@@ -1,8 +1,8 @@
using Xamarin.Forms; using Xamarin.Forms;
namespace qController namespace qController.QItems
{ {
public class QInstance : ViewCell public class QInstance
{ {
public string name { get; set; } public string name { get; set; }
public string address { get; set; } public string address { get; set; }
@@ -1,10 +1,8 @@
//Class pertains to the local copy of a workspace, with methods for fetching/updating information inside //Class pertains to the local copy of a workspace, with methods for fetching/updating information inside
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Serilog; using Serilog;
namespace qController namespace qController.QItems
{ {
public class QWorkspace public class QWorkspace
{ {
@@ -14,12 +12,25 @@ namespace qController
public string address { get; set; } public string address { get; set; }
public bool IsPopulated { get; set; } public bool IsPopulated { get; set; }
public string passcode { get; set; }
//ONLY FOR PASSING A WORKSPACE LOAD ERROR //ONLY FOR PASSING A WORKSPACE LOAD ERROR
public QWorkspace(string id) public QWorkspace(string id)
{ {
workspace_id = id; workspace_id = id;
} }
public QWorkspace(string id, string passcode)
{
workspace_id = id;
this.passcode = passcode;
}
public QWorkspace()
{
}
public QCue GetCue(string cue_id) public QCue GetCue(string cue_id)
{ {
foreach (var cueList in data) foreach (var cueList in data)
@@ -1,5 +1,5 @@
//General information about a QLab Workspace //General information about a QLab Workspace
namespace qController namespace qController.QItems
{ {
public class QWorkspaceInfo public class QWorkspaceInfo
{ {
@@ -1,6 +1,7 @@
using Serilog; using Serilog;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using Acr.Settings; using Acr.Settings;
using qController.QItems;
namespace qController namespace qController
{ {
+2
View File
@@ -1,6 +1,8 @@
using Acr.UserDialogs; using Acr.UserDialogs;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Essentials; using Xamarin.Essentials;
using qController.Communication;
namespace qController namespace qController
{ {
public partial class App : Application public partial class App : Application
+52 -108
View File
@@ -3,6 +3,11 @@ using System.Collections.Generic;
using Xamarin.Forms; using Xamarin.Forms;
using Serilog; using Serilog;
using Acr.UserDialogs; using Acr.UserDialogs;
using qController.Dialogs;
using qController.QItems;
using qController.Cell;
using qController.Communication;
namespace qController namespace qController
{ {
public partial class ControlPage : ContentPage public partial class ControlPage : ContentPage
@@ -11,8 +16,9 @@ namespace qController
QSelectedCueCell qCell; QSelectedCueCell qCell;
QLevelsCell qLevelsCell; QLevelsCell qLevelsCell;
QCueListCell qCueListCell; QCueListCell qCueListCell;
ShadowButton showLevelsButton; QLevelsButton showLevelsButton;
QControlsBlock qControlsBlock; QControlsBlock qControlsBlock;
WorkspacePrompt workspacePrompt = new WorkspacePrompt();
public ControlPage(string name, string address) public ControlPage(string name, string address)
{ {
@@ -26,16 +32,30 @@ namespace qController
qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged; qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged;
qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived; qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived;
qController.qClient.qParser.ChildrenUpdated += OnChildrenUpdated; qController.qClient.qParser.ChildrenUpdated += OnChildrenUpdated;
workspacePrompt.WorkspaceSelected += OnWorkspaceSelected;
App.rootPage.MenuItemSelected += OnMenuItemSelected; App.rootPage.MenuItemSelected += OnMenuItemSelected;
instanceName.Text = name; instanceName.Text = name;
InitGUI(); InitGUI();
qController.KickOff(); qController.KickOff();
} }
private void OnWorkspaceSelected(object source, WorkspacePromptArgs args)
{
if (args.SelectedWorkspace != null)
{
qController.Connect(args.SelectedWorkspace);
}
else
{
Log.Debug("CONTROLPAGE - No Workspace selected backing out");
Back();
}
}
private void OnConnectionStatusChanged(object source, ConnectEventArgs args) private void OnConnectionStatusChanged(object source, ConnectEventArgs args)
{ {
Log.Debug($"CONTROLPAGE - Connection Status Changed: {args.WorkspaceId} : {args.Status}"); Log.Debug($"CONTROLPAGE - Connection Status Changed: {args.WorkspaceId} : {args.Status}");
@@ -48,13 +68,13 @@ namespace qController
} }
else if (args.Status.Equals("badpass")) else if (args.Status.Equals("badpass"))
{ {
promptWorkspacePasscode(args.WorkspaceId); workspacePrompt.promptWorkspacePasscode(args.WorkspaceId);
} }
} }
private void WorkspaceInfoReceived(object source, WorkspaceInfoArgs args) private void WorkspaceInfoReceived(object source, WorkspaceInfoArgs args)
{ {
if(args.WorkspaceInfo.Count > 1) if (args.WorkspaceInfo.Count > 1)
{ {
Log.Debug("CONTROLPAGE - MULTIPLE WORKSPACES ON SELECTED COMPUTER"); Log.Debug("CONTROLPAGE - MULTIPLE WORKSPACES ON SELECTED COMPUTER");
PromptForWorkspace(args.WorkspaceInfo); PromptForWorkspace(args.WorkspaceInfo);
@@ -65,51 +85,31 @@ namespace qController
if (!args.WorkspaceInfo[0].hasPasscode) if (!args.WorkspaceInfo[0].hasPasscode)
{ {
qController.Connect(args.WorkspaceInfo[0].uniqueID); qController.Connect(args.WorkspaceInfo[0].uniqueID);
} }
else else
{ {
promptWorkspacePasscode(args.WorkspaceInfo[0].uniqueID); workspacePrompt.promptWorkspacePasscode(args.WorkspaceInfo[0].uniqueID);
} }
} }
else else
{ {
UserDialogs.Instance.Confirm(new ConfirmConfig NoWorkspacesConfig noWorkspacesConfig = new NoWorkspacesConfig();
noWorkspacesConfig.OnAction = (resp) =>
{ {
Message = "QLab doesn't have any workspaces open?", if (resp)
OkText = "Disconnect", Back();
OnAction = (resp) => };
{
if (resp) UserDialogs.Instance.Confirm(noWorkspacesConfig);
Back();
}
});
} }
} }
private void PromptForWorkspace(List<QWorkspaceInfo> workspaces) private void PromptForWorkspace(List<QWorkspaceInfo> workspaces)
{ {
ActionSheetConfig config = new ActionSheetConfig();
config.SetTitle("Select Workspace"); UserDialogs.Instance.ActionSheet(workspacePrompt.getActionSheetConfigForWorkspaces(workspaces));
for (int i = 0; i < workspaces.Count; i++)
{
QWorkspaceInfo workspace = workspaces[i];
config.Add(workspace.displayName, new Action(() => {
Log.Debug("CONTROLPAGE - Workspace Selected " + workspace.displayName);
if (!workspace.hasPasscode)
{
qController.Connect(workspace.uniqueID);
}
else
{
promptWorkspacePasscode(workspace.uniqueID);
}
}));
}
UserDialogs.Instance.ActionSheet(config);
} }
private void InitGUI() private void InitGUI()
@@ -121,11 +121,11 @@ namespace qController
qCell = new QSelectedCueCell(); qCell = new QSelectedCueCell();
qCell.SelectedCueEdited += OnSelectedCueEdited; qCell.SelectedCueEdited += OnSelectedCueEdited;
AbsoluteLayout.SetLayoutFlags(qCell, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutFlags(qCell, AbsoluteLayoutFlags.All);
instanceName.FontSize = App.HeightUnit * 3; instanceName.FontSize = App.HeightUnit * 3;
switch (Device.RuntimePlatform) switch (Device.RuntimePlatform)
{ {
case Device.iOS: case Device.iOS:
@@ -146,54 +146,41 @@ namespace qController
menuButtonGesture.Tapped += ShowMenu; menuButtonGesture.Tapped += ShowMenu;
menuButton.GestureRecognizers.Add(menuButtonGesture); menuButton.GestureRecognizers.Add(menuButtonGesture);
menuButton.Margin = new Thickness(App.WidthUnit * 2, 0, 0, App.WidthUnit * 2); menuButton.Margin = new Thickness(App.WidthUnit * 2, 0, 0, App.WidthUnit * 2);
sLayout.Children.Add(qCell); sLayout.Children.Add(qCell);
} }
private void OnSelectedCueEdited(object source, CueEditArgs args) private void OnSelectedCueEdited(object source, CueEditArgs args)
{ {
string address = "/workspace/" + qController.qWorkspace.workspace_id + "/cue_id/" + args.CueID + "/" + args.Property; string address = "/workspace/" + qController.qWorkspace.workspace_id + "/cue_id/" + args.CueID + "/" + args.Property;
qController.qClient.sendUDP(address, args.NewValue); qController.qClient.sendTCP(address, args.NewValue);
} }
void FinishUI() void FinishUI()
{ {
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id; string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
qLevelsCell = new QLevelsCell(); qLevelsCell = new QLevelsCell();
qLevelsCell.mainSlider.ValueChanged += (sender, args) => qLevelsCell.mainSlider.ValueChanged += (sender, args) =>
{ {
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/0", (float)args.NewValue); qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/0", (float)args.NewValue);
}; };
qLevelsCell.leftSlider.ValueChanged += (sender, args) => qLevelsCell.leftSlider.ValueChanged += (sender, args) =>
{ {
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/1", (float)args.NewValue); qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/1", (float)args.NewValue);
}; };
qLevelsCell.rightSlider.ValueChanged += (sender, args) => qLevelsCell.rightSlider.ValueChanged += (sender, args) =>
{ {
qController.qClient.sendUDP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/2", (float)args.NewValue); qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/2", (float)args.NewValue);
}; };
Button showLevelsInnerButton = new Button
{ showLevelsButton = new QLevelsButton();
Text = QIcon.SLIDERS, showLevelsButton.button.Clicked += (s, e) =>
TextColor = Color.Black,
FontFamily = App.QFont,
FontSize = App.HeightUnit * 4,
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = App.HeightUnit * 8,
WidthRequest = App.HeightUnit * 8,
CornerRadius = (int)(App.HeightUnit * 4),
BackgroundColor = Color.LightBlue
};
showLevelsInnerButton.Clicked += (s, e) =>
{ {
qLevelsCell.IsVisible = !qLevelsCell.IsVisible; qLevelsCell.IsVisible = !qLevelsCell.IsVisible;
}; };
showLevelsButton = new ShadowButton(showLevelsInnerButton);
qControlsBlock = new QControlsBlock(qController); qControlsBlock = new QControlsBlock(qController);
AbsoluteLayout.SetLayoutFlags(qControlsBlock, AbsoluteLayoutFlags.All); AbsoluteLayout.SetLayoutFlags(qControlsBlock, AbsoluteLayoutFlags.All);
@@ -205,7 +192,7 @@ namespace qController
{ {
case Device.iOS: case Device.iOS:
AbsoluteLayout.SetLayoutBounds(qControlsBlock, new Rectangle(0, 0.53, 1, 0.25)); AbsoluteLayout.SetLayoutBounds(qControlsBlock, new Rectangle(0, 0.53, 1, 0.25));
AbsoluteLayout.SetLayoutBounds(qLevelsCell, new Rectangle(0.9,0.40,0.8,0.25)); AbsoluteLayout.SetLayoutBounds(qLevelsCell, new Rectangle(0.9, 0.40, 0.8, 0.25));
AbsoluteLayout.SetLayoutBounds(showLevelsButton, new Rectangle(0.02, 0.34, App.HeightUnit * 8, App.HeightUnit * 8)); AbsoluteLayout.SetLayoutBounds(showLevelsButton, new Rectangle(0.02, 0.34, App.HeightUnit * 8, App.HeightUnit * 8));
break; break;
case Device.Android: case Device.Android:
@@ -222,6 +209,7 @@ namespace qController
void ShowMenu(object sender, EventArgs e) void ShowMenu(object sender, EventArgs e)
{ {
App.MenuIsPresented = true; App.MenuIsPresented = true;
} }
@@ -257,12 +245,7 @@ namespace qController
if (qCell.activeCue == null) if (qCell.activeCue == null)
{ {
Device.BeginInvokeOnMainThread(() => { Device.BeginInvokeOnMainThread(() => {
QCue noSelect = new QCue(); qCell.UpdateSelectedCue(new NoQCueSelected());
noSelect.listName = "No Cue Selected";
noSelect.type = "";
noSelect.notes = "Workspace has loaded but no cue is selected";
noSelect.number = "!";
qCell.UpdateSelectedCue(noSelect);
}); });
Log.Debug("CONTROLPAGE - Update Selected Cue Called because of Inital Workspace Load"); Log.Debug("CONTROLPAGE - Update Selected Cue Called because of Inital Workspace Load");
qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id); qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id);
@@ -347,7 +330,7 @@ namespace qController
{ {
if (args.Command.Contains("/")) if (args.Command.Contains("/"))
{ {
qController.qClient.sendUDP(args.Command); qController.qClient.sendTCP(args.Command);
} }
else if (args.Command == "disconnect") else if (args.Command == "disconnect")
{ {
@@ -370,36 +353,7 @@ namespace qController
} }
} }
private void promptWorkspacePasscode(string workspace_id)
{
UserDialogs.Instance.Prompt(new PromptConfig
{
InputType = InputType.Number,
MaxLength = 4,
Title = "Enter Workspace Passcode",
OkText = "Connect",
IsCancellable = true,
OnAction = (resp) =>
{
if (resp.Ok)
{
qController.Connect(workspace_id, resp.Value);
}
else
{
Back();
}
}
});
}
private void CloseCueList(object sender, EventArgs e) private void CloseCueList(object sender, EventArgs e)
{
CloseCueList();
}
private void CloseCueList()
{ {
Device.BeginInvokeOnMainThread(() => Device.BeginInvokeOnMainThread(() =>
{ {
@@ -411,19 +365,9 @@ namespace qController
{ {
OSCListItem cue = (OSCListItem)e.SelectedItem; OSCListItem cue = (OSCListItem)e.SelectedItem;
string selectCueOSC = "/workspace/" + qController.qWorkspace.workspace_id + cue.Command; string selectCueOSC = "/workspace/" + qController.qWorkspace.workspace_id + cue.Command;
qController.qClient.sendUDP(selectCueOSC); qController.qClient.sendTCP(selectCueOSC);
CloseCueList(); CloseCueList(sender,e);
} }
protected override bool OnBackButtonPressed()
{
qController.Kill();
App.rootPage.MenuItemSelected -= OnMenuItemSelected;
Device.BeginInvokeOnMainThread(() =>
{
App.rootPage.MenuPage.ChangeToHome();
});
return base.OnBackButtonPressed();
}
} }
} }
+2 -2
View File
@@ -1,6 +1,6 @@
using System; using System.Collections.ObjectModel;
using System.Collections.ObjectModel;
using Xamarin.Forms; using Xamarin.Forms;
using qController.QItems;
namespace qController namespace qController
{ {
@@ -4,6 +4,10 @@ using Acr.UserDialogs;
using Zeroconf; using Zeroconf;
using System.Collections.Generic; using System.Collections.Generic;
using Serilog; using Serilog;
using qController.QItems;
using qController.Communication;
using qController.Cell;
using Xamarin.Essentials;
namespace qController namespace qController
{ {
@@ -29,7 +33,7 @@ namespace qController
} }
else if (args.Command == "feedback") else if (args.Command == "feedback")
{ {
Device.OpenUri(new Uri("mailto:jwetzell1996@gmail.com")); Launcher.OpenAsync(new Uri("mailto:feedback@jwetzell.com?subject=qController%20feedback"));
} }
else if(args.Command == "support") else if(args.Command == "support")
{ {
@@ -41,7 +45,7 @@ namespace qController
OnAction = (response) => OnAction = (response) =>
{ {
if (response) if (response)
Device.OpenUri(new Uri("https://linktr.ee/JoelWetzell")); Launcher.OpenAsync(new Uri("https://linktr.ee/JoelWetzell"));
} }
}); });
} }
+3 -1
View File
@@ -83,10 +83,12 @@
<ItemGroup> <ItemGroup>
<Folder Include="Classes\" /> <Folder Include="Classes\" />
<Folder Include="Pages\" /> <Folder Include="Pages\" />
<Folder Include="Classes\Cues\" /> <Folder Include="Classes\QItems\" />
<Folder Include="Classes\Cell\" /> <Folder Include="Classes\Cell\" />
<Folder Include="Classes\Communication\" /> <Folder Include="Classes\Communication\" />
<Folder Include="Classes\Settings\" /> <Folder Include="Classes\Settings\" />
<Folder Include="Classes\Dialogs\" />
<Folder Include="Classes\Buttons\" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Remove="Pages\RootPageMaster.xaml" /> <EmbeddedResource Remove="Pages\RootPageMaster.xaml" />