Clean up legacy control classes and code

This commit is contained in:
2021-03-28 15:37:35 -05:00
parent 2bca5c8a13
commit ce64f24b4b
39 changed files with 47 additions and 2392 deletions
@@ -1,72 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using qController.QItems;
namespace qController.Communication
{
public class CueEventArgs : EventArgs
{
public QCue Cue
{
get;
set;
}
}
public class WorkspaceEventArgs : EventArgs
{
public QOldWorkspace UpdatedWorkspace
{
get;
set;
}
}
public class PlaybackPositionArgs : EventArgs
{
public string PlaybackPosition
{
get;
set;
}
}
public class ConnectEventArgs : EventArgs
{
public string Status
{
get;
set;
}
public string WorkspaceId
{
get;
set;
}
}
public class WorkspaceInfoArgs : EventArgs
{
public List<QControlKit.QWorkspaceInfo> WorkspaceInfo
{
get;
set;
}
}
public class ChildrenEventArgs : EventArgs
{
public string cue_id
{
get;
set;
}
public List<QCue> children
{
get;
set;
}
}
}
@@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace qController.Communication
{
public delegate void SelectedCueUpdatedHandler(object source, CueEventArgs args);
public delegate void WorkspaceUpdatedHandler(object source, WorkspaceEventArgs args);
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 delegate void WorkspaceDisconnectHandler(object source, EventArgs args);
public delegate void WorkspaceInfoHandler(object source, WorkspaceInfoArgs args);
public delegate void WorkspaceLoadErrorHandler(object source, WorkspaceEventArgs args);
}
@@ -1,109 +0,0 @@
//Class used to facilitate communication with a QInstance
//Listens for incoming messages via qReceiver (UDP) and tcpClient (TCP)
//TODO: WEIRD MESSAGE PARSING RULES NEED FIXED
using System;
using SharpOSC;
using Serilog;
namespace qController.Communication
{
public class QClient
{
private TCPClient tcpClient;
public QParser qParser;
string Address;
int Port;
public bool connected;
public QClient(string address, int port)
{
Address = address;
Port = port;
qParser = new QParser();
tcpClient = new TCPClient(Address, Port);
connected = tcpClient.Connect();
tcpClient.MessageReceived += OnMessageReceived;
}
//one method for messages received whether from TCP or UDP (SAME MSG FORMAT)
private void OnMessageReceived(object source, MessageEventArgs args)
{
Log.Debug("QCLIENT - Message Received: " + args.Message.Address);
//TODO: find a better filtering process
if (!args.Message.Address.Contains("update"))
qParser.ParseMessage(args.Message);
else if (args.Message.Address.Contains("playbackPosition") || args.Message.Address.Contains("cueList") || args.Message.Address.Contains("dashboard"))
qParser.ParseMessage(args.Message);
else if (args.Message.Address.Contains("cue_id"))
{
var parts = args.Message.Address.Split('/');
UpdateSpecificCue(parts[3], parts[5]);
}
else
ProcessUpdate(args.Message);
}
public void sendTCP(string address)
{
//Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try
{
tcpClient.Send(new OscMessage(address));
}
catch (Exception ex)
{
Log.Debug("QCLIENT - Send and Receive Exception: " + ex.Message);
}
}
public void sendTCP(string address, params object[] args)
{
//Log.Debug($"QCLIENT - TCP Sent with address: {address}");
try
{
tcpClient.Send(new OscMessage(address, args));
}
catch (Exception ex)
{
Log.Debug("QCLIENT - Send and Receive w/Args Exception: " + ex.Message);
}
}
public void ProcessUpdate(OscMessage msg)
{
Log.Debug("QCLIENT - Process Update: " + msg.Address);
if (msg.Address.Contains("workspace"))
{
UpdateWorkspace("not yet implemented");
}
}
public void UpdateSpecificCue(string workspace_id,string cue_id)
{
string valuesForKeys = "[\"number\",\"uniqueID\",\"flagged\",\"listName\",\"type\",\"colorName\",\"name\",\"armed\",\"displayName\",\"isBroken\",\"isLoaded\",\"isPaused\",\"isRunning\",\"preWait\",\"duration\",\"postWait\",\"translationX\",\"translationY\",\"opacity\",\"scaleX\",\"scaleY\",\"notes\",\"levels\"]";
string address = "/workspace/" + workspace_id + "/cue_id/" + cue_id + "/valuesForKeys";
sendTCP(address, valuesForKeys);
}
public void UpdateSelectedCue(string workspace_id)
{
string valuesForKeys = "[\"number\",\"uniqueID\",\"flagged\",\"listName\",\"type\",\"colorName\",\"name\",\"armed\",\"displayName\",\"isBroken\",\"isLoaded\",\"isPaused\",\"isRunning\",\"preWait\",\"duration\",\"postWait\",\"translationX\",\"translationY\",\"opacity\",\"scaleX\",\"scaleY\",\"notes\",\"levels\"]";
string address = "/workspace/" + workspace_id + "/cue/selected/valuesForKeys";
sendTCP(address, valuesForKeys);
}
public void UpdateWorkspace(string ws_id)
{
Log.Debug("QCLIENT - Workspace needs to be updated: " + ws_id);
}
public void Close()
{
tcpClient.Close();
}
}
}
@@ -1,81 +0,0 @@
//Class used for overall Workspace control (ONLY REPRESENTS ONE 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
//TODO: STILL NEED TO WORK ON PASSWORD PROTECTED WORKSPACES
using Serilog;
using qController.QItems;
namespace qController.Communication
{
public class QController
{
public QUpdater qUpdater;
public QClient qClient;
public QOldWorkspace qWorkspace;
public string playbackPosition;
private string ipAddress;
private int port;
public QController(string address, int port)
{
this.port = port;
this.ipAddress = address;
qClient = new QClient(ipAddress, port);
qUpdater = new QUpdater(this);
}
public void Connect(string workspace_id)
{
Log.Debug($"QCONTROLLER - Connect Called: {workspace_id}");
qWorkspace = new QOldWorkspace(workspace_id);
qClient.sendTCP("/workspace/"+workspace_id+"/connect");
}
public void Connect(string workspace_id, string passcode)
{
Log.Debug($"QCONTROLLER - Connect with Passcode Called: {workspace_id}:{passcode}");
qWorkspace = new QOldWorkspace(workspace_id);
qClient.sendTCP("/workspace/" + workspace_id + "/connect", passcode);
}
public void Connect(QOldWorkspace workspace)
{
if(workspace.passcode != null)
Connect(workspace.workspace_id, workspace.passcode);
else
Connect(workspace.workspace_id);
}
public void KickOff()
{
Log.Debug($"QCONTROLLER - Searching for workspaces on: {ipAddress}");
qClient.sendTCP("/workspaces");
}
public void Disconnect()
{
Log.Debug($"QCONTROLLER - Disconnecting from: {qWorkspace.workspace_id}");
qClient.sendTCP("/workspace/"+qWorkspace.workspace_id+"/disconnect");
}
public void Resume()
{
//qClient = new QClient(ipAddress, port);
//qUpdater = new QUpdater(this);
if(qWorkspace != null)
{
Log.Debug($"QCONTROLLER - Resuming: {qWorkspace.workspace_id}");
}
}
public void Kill(){
Log.Debug("QCONTROLLER - Killing");
if (qClient != null)
qClient.Close();
}
}
}
@@ -1,23 +0,0 @@
//Currently unused would like to reimplement eventually
//Currently being done in qConnectionPage.xaml.cs Scan() method
//TODO: Implement this along with a way of getting active Instances and # of workspaces for an instance
using Serilog;
using System.Collections.Generic;
using Zeroconf;
namespace qController.Communication
{
public class QFinder
{
public QFinder()
{
}
public async void SearchForWorkspaces()
{
Log.Debug("QFINDER - Scanning Started");
IReadOnlyList<IZeroconfHost> results = await ZeroconfResolver.ResolveAsync("_qlab._udp.local.");
Log.Debug("QFINDER - Scanning Done");
}
}
}
@@ -1,184 +0,0 @@
using System;
using SharpOSC;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using qController.QItems;
using Serilog;
namespace qController.Communication
{
public class QParser
{
public QParser()
{
}
public event WorkspaceLoadErrorHandler WorkspaceLoadError;
public event WorkspaceInfoHandler WorkspaceInfoReceived;
public event WorkspaceDisconnectHandler WorkspaceDisconnect;
public event ChildrenUpdateHandler ChildrenUpdated;
public event ConnectionStatusHandler ConnectionStatusChanged;
public event SelectedCueUpdatedHandler SelectedCueUpdated;
public event WorkspaceUpdatedHandler WorkspaceUpdated;
public event CueInfoUpdatedHandler CueInfoUpdated;
public event PlaybackPositionUpdatedHandler PlaybackPositionUpdated;
public void ParseMessage(OscMessage msg){
if (!msg.Address.Contains("null"))
{
if (msg.Address.Contains("valuesForKeys"))
{
ParseCueUpdateInfo(msg);
}
else if (msg.Address.Contains("cueLists"))
ParseWorkspaceInfo(msg);
else if (msg.Address.Contains("playbackPosition"))
ParsePositionUpdateInfo(msg);
else if (msg.Address.Contains("thump"))
Log.Debug("QPARSER - Heartbeat Received");
else if (msg.Address.Contains("disconnect"))
OnWorkspaceDisconnect();
else if (msg.Address.Contains("connect"))
ParseConnectInfo(msg);
else if (msg.Address.Contains("children"))
ParseChildrenInfo(msg);
else if (msg.Address.Contains("workspaces"))
ParseQInfo(msg);
else
{
Log.Debug("QPARSER - Unkown message type: " + msg.Address);
foreach (var item in msg.Arguments)
{
Log.Debug(item.ToString());
}
}
}
}
public void ParseConnectInfo(OscMessage msg)
{
if (msg.Arguments.Count > 0)
{
JToken connectStatus = OSC2JSON(msg);
;
OnConnectionStatusChanged(connectStatus.ToString(), msg.Address.Split('/')[3]);
}
}
public void ParsePositionUpdateInfo(OscMessage msg)
{
if(msg.Arguments.Count > 0)
{
OnPlaybackPositionUpdated(msg.Arguments[0].ToString());
}
}
public void ParseCueUpdateInfo(OscMessage msg)
{
JToken cueUpdate = OSC2JSON(msg);
QCue cue = JsonConvert.DeserializeObject<QCue>(cueUpdate.ToString());
OnCueInfoUpdated(cue);
}
public void ParseSelectedCueInfo(OscMessage msg){
JToken selectedCue = OSC2JSON(msg);
QCue cue = JsonConvert.DeserializeObject<QCue>(selectedCue.ToString());
OnSelectedCueUpdated(cue);
}
public void ParseQInfo(OscMessage msg)
{
JToken qInfo = OSC2JSON(msg);
List<QControlKit.QWorkspaceInfo> qWorkspaceInfo = JsonConvert.DeserializeObject<List<QControlKit.QWorkspaceInfo>>(qInfo.ToString());
OnWorkspaceInfoReceived(qWorkspaceInfo);
}
public void ParseWorkspaceInfo(OscMessage msg)
{
if (msg.Arguments.Count > 0)
{
var parts = msg.Address.Split('/');
string id = parts[3];
if (msg.Arguments[0].ToString() != "")
{
try
{
QOldWorkspace workspace = JsonConvert.DeserializeObject<QOldWorkspace>(msg.Arguments[0].ToString());
OnWorkspaceUpdated(workspace);
}
catch (Exception ex)
{
Log.Debug($"QPARSER - Workspace Load Error: {ex.ToString()}");
OnWorkspaceLoadError(id);
}
}
else
{
OnWorkspaceLoadError(id);
}
}
}
public void ParseChildrenInfo(OscMessage msg)
{
if (msg.Arguments.Count > 0)
{
string cue_id = msg.Address.Split('/')[3];
JToken children_obj = OSC2JSON(msg);
List<QCue> children = JsonConvert.DeserializeObject<List<QCue>>(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");
}
protected virtual void OnWorkspaceUpdated(QOldWorkspace workspace)
{
WorkspaceUpdated?.Invoke(this, new WorkspaceEventArgs() { UpdatedWorkspace = workspace });
}
protected virtual void OnSelectedCueUpdated(QCue cue)
{
SelectedCueUpdated?.Invoke(this, new CueEventArgs() { Cue = cue });
}
protected virtual void OnCueInfoUpdated(QCue cue)
{
CueInfoUpdated?.Invoke(this, new CueEventArgs() { Cue = cue });
}
protected virtual void OnPlaybackPositionUpdated(string id)
{
PlaybackPositionUpdated?.Invoke(this, new PlaybackPositionArgs() { PlaybackPosition = id });
}
protected virtual void OnConnectionStatusChanged(string status, string workspace_id)
{
ConnectionStatusChanged?.Invoke(this, new ConnectEventArgs() { Status = status, WorkspaceId = workspace_id });
}
protected virtual void OnChildrenUpdated(string id, List<QCue> cues)
{
ChildrenUpdated?.Invoke(this, new ChildrenEventArgs() { cue_id = id, children = cues });
}
protected virtual void OnWorkspaceDisconnect()
{
WorkspaceDisconnect?.Invoke(this, new EventArgs());
}
protected virtual void OnWorkspaceInfoReceived(List<QControlKit.QWorkspaceInfo> workspaces)
{
WorkspaceInfoReceived?.Invoke(this, new WorkspaceInfoArgs() { WorkspaceInfo = workspaces });
}
protected virtual void OnWorkspaceLoadError(string id)
{
WorkspaceLoadError?.Invoke(this, new WorkspaceEventArgs { UpdatedWorkspace = new QOldWorkspace(id) });
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Net;
using SharpOSC;
namespace qController
{
public class QSender
{
TCPSender tcpSender;
public QSender(string address, int port)
{
tcpSender = new TCPSender(address, port);
tcpSender.MessageReceived += OnMessageReceived;
}
void OnMessageReceived(object source, MessageEventArgs args)
{
Console.WriteLine("New Message Received");
}
public void sendString(string address) {
tcpSender.Send(new OscMessage(address));
}
public void sendArgs(string address, object args){
tcpSender.Send(new OscMessage(address, args));
}
}
}
@@ -1,69 +0,0 @@
//Class used for updating local "copy" of workspace info, cue-lists, cues, etc.
using Serilog;
namespace qController.Communication
{
public class QUpdater
{
private QController qController;
public QUpdater(QController controller)
{
qController = controller;
qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived;
qController.qClient.qParser.WorkspaceUpdated += OnWorkspaceUpdated;
qController.qClient.qParser.PlaybackPositionUpdated += OnPlaybackPositionUpdated;
qController.qClient.qParser.WorkspaceLoadError += OnWorkspaceLoadError;
qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged;
}
private void OnConnectionStatusChanged(object source, ConnectEventArgs args)
{
Log.Debug("QUPDATER - Connection Status Changed: " + args.Status);
if (args.Status == "ok")
{
qController.qClient.sendTCP("/workspace/" + qController.qWorkspace.workspace_id + "/updates", 1);
qController.qClient.sendTCP("/workspace/" + qController.qWorkspace.workspace_id + "/cueLists");
}
}
private void OnWorkspaceLoadError(object source, WorkspaceEventArgs args)
{
Log.Debug("QUPDATER - Loading cuelists has failed for some reason retrying");
}
public void OnCueUpdateReceived(object source, CueEventArgs args)
{
qController.qWorkspace.UpdateCue(args.Cue);
if (args.Cue.type == "Group")
{
//Log.Debug("QUpdater/Updated cue was group cue, sending children request");
qController.qClient.sendTCP("/workspace/"+qController.qWorkspace.workspace_id+"/cue_id/" + args.Cue.uniqueID + "/children");
}
}
public void OnWorkspaceUpdated(object source, WorkspaceEventArgs args)
{
qController.qWorkspace = args.UpdatedWorkspace;
qController.playbackPosition = null;
qController.qWorkspace.CheckPopulated();
if (qController.qWorkspace.IsPopulated)
{
Log.Debug("QUPDATER - Workspace group cues are already populated");
App.showToast("Workspace cues have been loaded....");
//get selected cue
qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id);
return;
}
}
public void OnPlaybackPositionUpdated(object source, PlaybackPositionArgs args)
{
qController.playbackPosition = args.PlaybackPosition;
Log.Debug("QUPDATER - Update Specific Cue Called because of Playback Position Updated");
qController.qClient.UpdateSpecificCue(qController.qWorkspace.workspace_id,args.PlaybackPosition);
}
}
}
@@ -2,7 +2,7 @@
//IMPLEMENT A ISREACHABLE METHOD TO BE ABLE TO DISPLAY ONLINE QINSTANCES
using System.Net;
namespace qController.Communication
namespace qController.Helpers
{
public class IPHelper
{
@@ -1,51 +0,0 @@
using System.Collections.Generic;
namespace qController.QItems
{
public class QCue
{
//info loaded from "/cueLists"
public string number { get; set; }
public string uniqueID { get; set; }
public bool flagged { get; set; }
public string listName { get; set; }
public string type { get; set; }
public string colorName { get; set; }
public string name { get; set; }
public bool armed { get; set; }
//info loaded from "/valuesForKeys
public decimal translationX { get; set; }
public bool isRunning { get; set; }
public decimal scaleX { get; set; }
public bool isPaused { 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<List<double>> levels { get; set; }
//info loaded from /children
public List<QCue> cues { get; set; }
//get string for icon font from cue type
public string getIconString()
{
return QIcon.GetIconFromType(type);
}
public string IconText
{
get
{
return QIcon.GetIconFromType(type);
}
}
}
}
@@ -1,26 +0,0 @@
using System.Collections.Generic;
using qController.Helpers;
namespace qController.QItems
{
public class QCueList
{
public string number { get; set; }
public string uniqueID { get; set; }
public List<QCue> cues { get; set; }
public bool flagged { get; set; }
public string listName { get; set; }
public string type { get; set; }
public string colorName { get; set; }
public string name { get; set; }
public bool armed { get; set; }
public string IconText
{
get
{
return IconConstants.FormatListBulleted;
}
}
}
}
@@ -1,10 +0,0 @@
using System;
namespace qController.Classes.Cues
{
public class QDefinitions
{
public QDefinitions()
{
}
}
}
@@ -1,120 +0,0 @@
//Class pertains to the local copy of a workspace, with methods for fetching/updating information inside
using System.Collections.Generic;
using Serilog;
namespace qController.QItems
{
public class QOldWorkspace
{
public string status { get; set; }
public List<QCueList> data { get; set; }
public string workspace_id { get; set; }
public string address { get; set; }
public bool IsPopulated { get; set; }
public string passcode { get; set; }
//ONLY FOR PASSING A WORKSPACE LOAD ERROR
public QOldWorkspace(string id)
{
workspace_id = id;
}
public QOldWorkspace(string id, string passcode)
{
workspace_id = id;
this.passcode = passcode;
}
public QOldWorkspace()
{
}
public QCue GetCue(string cue_id)
{
foreach (var cueList in data)
{
foreach (var cue in cueList.cues)
{
if(cue.uniqueID == cue_id)
{
return cue;
}
}
}
return null;
}
public QCueList GetCueList(string id)
{
foreach (var cueList in data)
{
if(cueList.uniqueID == id)
{
return cueList;
}
}
return null;
}
public void UpdateCue(QCue cue)
{
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.uniqueID)
{
//Log.Debug("Cue found and updated in workspace: " + cue.uniqueID);
data[i].cues[j] = cue;
return;
}
}
}
}
public void UpdateChildren(string cue_id, List<QCue> 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;
return;
}
}
}
}
}
public bool CheckPopulated()
{
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)
{
IsPopulated = false;
return false;
}
}
}
IsPopulated = true;
return true;
}
public void PrintStats()
{
foreach (var cueList in data)
{
Log.Debug(cueList.listName + "("+ cueList.cues.Count + " cues)");
}
}
}
}
@@ -1,15 +0,0 @@
using qController.QItems;
namespace qController
{
public class NoQCueSelected : QCue
{
public NoQCueSelected()
{
listName = "No Cue Selected";
type = "";
notes = "Workspace has loaded but no cue is selected";
number = "!";
}
}
}
@@ -1,11 +0,0 @@
namespace qController
{
public class OSCListItem
{
public string Text { get; set; }
public string Icon { get; set; }
public string Command { get; set; }
}
}
@@ -1,17 +0,0 @@
namespace qController
{
public class QCommand
{
public string osc;
public string text;
public string type;
public QCommand(string display, string cmd, string command_type)
{
text = display;
osc = cmd;
type = command_type;
}
}
}
@@ -1,17 +0,0 @@
namespace qController
{
public static class QCommands
{
public static QCommand GO = new QCommand("GO", "/go","WORKSPACE");
public static QCommand PANIC = new QCommand("Panic", "/panic","WORKSPACE");
public static QCommand PAUSE = new QCommand("Pause", "/pause","WORKSPACE");
public static QCommand PREVIEW = new QCommand("Preview", "/preview","WORKSPACE");
public static QCommand RESUME = new QCommand("Resume", "/resume","WORKSPACE");
public static QCommand PREVIOUS = new QCommand("Previous","/select/previous","WORKSPACE");
public static QCommand NEXT = new QCommand("Next", "/select/next","WORKSPACE");
public static QCommand RESET = new QCommand("Reset","/reset","WORKSPACE");
public static QCommand STOP = new QCommand("Stop","/stop","WORKSPACE");
public static QCommand HARDSTOP = new QCommand("Hard Stop", "/hardStop","WORKSPACE");
}
}
@@ -1,5 +1,4 @@
using Xamarin.Forms;
//Legacy but needed incase there are still instances stored in this way
namespace qController.QItems
{
public class QInstance
@@ -17,7 +16,7 @@ namespace qController.QItems
}
public bool IsReachable()
{
return qController.Communication.IPHelper.IsReachable(address);
return qController.Helpers.IPHelper.IsReachable(address);
}
}
}
@@ -9,18 +9,43 @@ namespace qController
public class QStorage
{
public static ObservableCollection<QInstance> qInstances;
public static ObservableCollection<QServerInfo> qStoredServers;
public static QRecentWorkspaceInfo recentWorkspaceInfo;
static QStorage(){
qInstances = (ObservableCollection<QInstance>)CrossSettings.Current.GetValue(new ObservableCollection<QInstance>().GetType(), "qInstances", null);
qStoredServers = (ObservableCollection<QServerInfo>)CrossSettings.Current.GetValue(new ObservableCollection<QInstance>().GetType(), "qStoredServers", null);
recentWorkspaceInfo = (QRecentWorkspaceInfo)CrossSettings.Current.GetValue(typeof (QRecentWorkspaceInfo),"recentWorkspaceInfo",null);
if (qInstances == null)
{
Log.Debug("QSTORAGE - No qInstance exists creating one");
Log.Debug("[QStorage] No qInstances exists creating one");
qInstances = new ObservableCollection<QInstance>();
UpdateStorage();
}
if (qStoredServers == null)
{
Log.Debug("[QStorage] No qStoredServers exists creating one");
qStoredServers = new ObservableCollection<QServerInfo>();
UpdateStorage();
}
if (qInstances != null)
{
Log.Debug("[QStorage] qInstances exists though so load in those instances as servers");
foreach (QInstance instance in qInstances)
{
QServerInfo serverInfo = new QServerInfo();
serverInfo.host = instance.address.ToString();
//TODO: port?
qStoredServers.Add(serverInfo);
}
UpdateStorage();
}
}
public static void UpdateRecentWorkspace(QRecentWorkspaceInfo packagedInfo)
@@ -59,6 +84,7 @@ namespace qController
private static void UpdateStorage(){
CrossSettings.Current.SetValue("qInstances", qInstances);
CrossSettings.Current.SetValue("qStoredServers", qStoredServers);
}
public static bool Contains(string name, string address){
@@ -1,45 +0,0 @@
using Xamarin.Forms;
namespace qController.UI.Buttons
{
public class QButton : Button
{
public QCommand qCommand
{
get;
set;
}
public QButton(QCommand command)
{
qCommand = command;
Text = qCommand.text;
TextColor = Color.Black;
FontSize = App.HeightUnit * 2.5;
if (qCommand.osc.Contains("go"))
{
BackgroundColor = Color.SeaGreen;
switch (Device.RuntimePlatform)
{
case Device.iOS:
FontSize = App.HeightUnit * 4;
FontAttributes = FontAttributes.Bold;
break;
case Device.Android:
FontSize = App.HeightUnit * 4;
FontAttributes = FontAttributes.Bold;
break;
}
}
else if (qCommand.osc.Contains("panic"))
{
BackgroundColor = Color.IndianRed;
}
else
{
BackgroundColor = Color.FromHex("D8D8D8");
}
}
}
}
@@ -1,29 +0,0 @@
using Xamarin.Forms;
namespace qController.UI.Buttons
{
public class QLevelsButton : ShadowButton
{
public Button button;
public QLevelsButton()
{
button = new Button
{
Text = QIcon.SLIDERS,
TextColor = Color.Black,
FontFamily = (OnPlatform<string>)Application.Current.Resources["QFontFamily"],
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;
}
}
}
@@ -1,128 +0,0 @@
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using qController.UI.Buttons;
namespace qController.UI.Cells
{
public class QControlsBlock : Frame
{
Grid mainG;
EventHandler callback;
public QControlsBlock(EventHandler callback)
{
this.callback = callback;
Margin = new Thickness(10);
Padding = new Thickness(0);
IsVisible = true;
BackgroundColor = Color.Transparent;
//highlight Button Grid
//BackgroundColor = Color.FromHex("FF0000");
List<QCommand> commands = new List<QCommand>();
commands.Add(QCommands.PREVIOUS);
commands.Add(QCommands.PAUSE);
commands.Add(QCommands.NEXT);
commands.Add(QCommands.PREVIEW);
commands.Add(QCommands.PANIC);
commands.Add(QCommands.RESUME);
//setCustomButtons(commands);
setDefaultButtons();
}
void setDefaultButtons()
{
List<QButton> buttons = new List<QButton>();
buttons.Add(new QButton(QCommands.PREVIOUS));
buttons.Add(new QButton(QCommands.PANIC));
buttons.Add(new QButton(QCommands.NEXT));
buttons.Add(new QButton(QCommands.PREVIEW));
buttons.Add(new QButton(QCommands.PAUSE));
buttons.Add(new QButton(QCommands.RESUME));
mainG = new Grid
{
Padding = new Thickness(0),
RowDefinitions = {
new RowDefinition{Height = GridLength.Star},
new RowDefinition{Height = GridLength.Star},
new RowDefinition{Height = GridLength.Star}
},
ColumnDefinitions = {
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
},
Margin = new Thickness(0)
};
int row = 0;
int column = 0;
for (int i = 0; i < buttons.Count; i++)
{
QButton b = buttons[i];
b.Clicked += callback;
mainG.Children.Add(b, column, row);
row++;
if (row == 3)
{
row = 0;
column = 2;
}
}
QButton goButton = new QButton(QCommands.GO);
goButton.Clicked += callback;
mainG.Children.Add(goButton, 1, 0);
Grid.SetRowSpan(goButton, 3);
Content = mainG;
}
public void setCustomButtons(List<QCommand> commands)
{
mainG = new Grid
{
Padding = new Thickness(0),
RowDefinitions = {
new RowDefinition{Height = GridLength.Auto},
new RowDefinition{Height = GridLength.Auto},
new RowDefinition{Height = GridLength.Auto}
},
ColumnDefinitions = {
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
},
Margin = new Thickness(0)
};
int row = 0;
int column = 0;
for (int i = 0; i < commands.Count; i++)
{
QButton b = new QButton(commands[i]);
b.Clicked += callback;
mainG.Children.Add(b, column, row);
row++;
if (row == 3)
{
row = 0;
column = 2;
}
}
QButton goButton = new QButton(QCommands.GO);
goButton.Clicked += callback;
mainG.Children.Add(goButton, 1, 0);
Grid.SetRowSpan(goButton, 3);
Content = mainG;
}
}
}
@@ -1,122 +0,0 @@
using System.Collections.ObjectModel;
using Xamarin.Forms;
using qController.QItems;
namespace qController.UI.Cells
{
public class QCueListCell : Frame
{
public ListView cueListView;
public Button closeButton;
public ObservableCollection<OSCListItem> items;
public QCueListCell(QCueList qCueList)
{
Margin = new Thickness(10);
Padding = new Thickness(10);
items = new ObservableCollection<OSCListItem>();
cueListView = new ListView
{
ItemsSource = items,
RowHeight = (int)(App.HeightUnit * 6),
ItemTemplate = new DataTemplate(() =>
{
var grid = new Grid { Padding = new Thickness(5, 10) };
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
var icon = new Label();
icon.FontFamily = (OnPlatform<string>)Application.Current.Resources["QFontFamily"];
icon.SetBinding(Label.TextProperty, "Icon");
icon.HorizontalTextAlignment = TextAlignment.Center;
icon.VerticalTextAlignment = TextAlignment.Center;
icon.FontSize = App.HeightUnit * 3;
var label = new Label { VerticalOptions = LayoutOptions.FillAndExpand };
label.SetBinding(Label.TextProperty, "Text");
if (label.Text == "Disconnect")
{
label.TextColor = Color.DarkRed;
}
switch (Device.RuntimePlatform)
{
case Device.iOS:
label.FontSize = App.HeightUnit * 3;
break;
case Device.Android:
label.FontSize = App.HeightUnit * 2.2;
break;
}
grid.Children.Add(icon);
grid.Children.Add(label, 1, 0);
return new ViewCell { View = grid };
})
};
StackLayout layout = new StackLayout();
closeButton = new Button
{
BackgroundColor = Color.Gray,
Text = "Close",
TextColor = Color.White
};
layout.Children.Add(closeButton);
layout.Children.Add(cueListView);
Content = layout;
for(int j=0; j < qCueList.cues.Count; j++)
{
var cue = qCueList.cues[j];
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 OSCListItem
{
Text = cueTitle,
Icon = cueIcon,
Command = "/select_id/" + cue.uniqueID
});
//uncomment to load nested group cues
for (int i = 0; i < cue.cues.Count; i++)
{
var sub_cue = cue.cues[i];
AddSubCues(sub_cue, level + 1);
}
}
else
{
items.Add(new OSCListItem
{
Text = cueTitle,
Icon = cueIcon,
Command = "/select_id/" + cue.uniqueID
});
}
}
}
}
@@ -1,121 +0,0 @@
using System;
using Xamarin.Forms;
using Serilog;
using qController.Helpers;
namespace qController.UI.Cells
{
public class QInstanceCell : ViewCell
{
public QInstanceCell()
{
Label nameLabel = new Label();
Label addressLabel = new Label();
Label connectLabel = new Label();
Label deleteLabel = new Label();
var connectTapGesture = new TapGestureRecognizer();
var deleteTapGesture = new TapGestureRecognizer();
connectTapGesture.Tapped += Connect;
connectLabel.GestureRecognizers.Add(connectTapGesture);
deleteTapGesture.Tapped += Delete;
deleteLabel.GestureRecognizers.Add(deleteTapGesture);
InitItems();
//SET BINDINGS
nameLabel.SetBinding(Label.TextProperty, new Binding("name"));
addressLabel.SetBinding(Label.TextProperty,new Binding("address"));
Grid mainG = new Grid
{
//Padding = new Thickness(10),
RowDefinitions = {
new RowDefinition{Height = GridLength.Auto},
new RowDefinition{Height = GridLength.Auto}
},
ColumnDefinitions = {
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(4,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
}
};
mainG.Children.Add(nameLabel, 1, 0);
mainG.Children.Add(addressLabel,1,1);
mainG.Children.Add(connectLabel,2,0);
Grid.SetRowSpan(connectLabel,2);
mainG.Children.Add(deleteLabel, 0, 0);
Grid.SetRowSpan(deleteLabel,2);
Frame f = new Frame
{
Content = mainG,
BorderColor = Color.Black,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Padding = 0,
Margin = new Thickness(10,10,10,10),
CornerRadius=20
};
f.SetDynamicResource(Frame.BackgroundColorProperty, "WorkspaceCellBackgroundColor");
View = f;
void InitItems()
{
nameLabel.HorizontalTextAlignment = TextAlignment.Center;
nameLabel.VerticalTextAlignment = TextAlignment.End;
nameLabel.FontAttributes = FontAttributes.Bold;
nameLabel.FontSize = App.HeightUnit * 3;
nameLabel.Margin = new Thickness(0, 20, 0, 0);
nameLabel.SetDynamicResource(Label.TextColorProperty, "PrimaryTextColor");
addressLabel.HorizontalTextAlignment = TextAlignment.Center;
addressLabel.VerticalTextAlignment = TextAlignment.Start;
addressLabel.FontSize = App.HeightUnit * 2.5;
addressLabel.Margin = new Thickness(0, 0, 0, 20);
addressLabel.SetDynamicResource(Label.TextColorProperty, "PrimaryTextColor");
connectLabel.HorizontalOptions = LayoutOptions.StartAndExpand;
connectLabel.VerticalOptions = LayoutOptions.CenterAndExpand;
connectLabel.Text = IconConstants.Wifi;
connectLabel.FontSize = App.HeightUnit * 5;
connectLabel.TextColor = Color.LimeGreen;
deleteLabel.HorizontalOptions = LayoutOptions.CenterAndExpand;
deleteLabel.VerticalOptions = LayoutOptions.CenterAndExpand;
deleteLabel.Text = IconConstants.Delete;
deleteLabel.FontSize = App.HeightUnit * 5;
deleteLabel.TextColor = Color.Red;
connectLabel.FontFamily = (OnPlatform<string>)Application.Current.Resources["MaterialFontFamily"];
deleteLabel.FontFamily = (OnPlatform<string>)Application.Current.Resources["MaterialFontFamily"];
}
void Delete(object sender, EventArgs e)
{
Log.Debug("QINSTANCECELL - Delete " + nameLabel.Text + "," + addressLabel.Text + " Pressed");
QStorage.RemoveInstance(nameLabel.Text,addressLabel.Text);
}
void Connect(object sender, EventArgs e)
{
App.NavigationPage.Navigation.PushAsync(new ControlPage(nameLabel.Text,addressLabel.Text));
Log.Debug("QINSTANCECELL - Connect To " + nameLabel.Text + " Pressed");
}
}
}
}
@@ -1,222 +0,0 @@
//NEEDS migrated to QSelectedCueGrid
using System;
using Acr.UserDialogs;
using Xamarin.Forms;
using qController.QItems;
using qController.Events;
namespace qController.UI.Cells
{
public class QSelectedCueCell : Frame
{
public event SelectedCueEditedHandler SelectedCueEdited;
Label name;
Label number;
Label type;
public Label notes;
public QCue activeCue;
public QSelectedCueCell()
{
Grid mainG = new Grid
{
Padding = new Thickness(0),
RowDefinitions =
{
new RowDefinition{Height = GridLength.Star},
new RowDefinition{Height = new GridLength(2, GridUnitType.Star)}
},
ColumnDefinitions =
{
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
}
};
Grid topGrid = new Grid
{
Padding = new Thickness(0),
RowDefinitions =
{
new RowDefinition{Height = GridLength.Auto}
},
ColumnDefinitions =
{
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
}
};
Grid bottomGrid = new Grid
{
Padding = new Thickness(0),
RowDefinitions =
{
new RowDefinition{Height = new GridLength(1,GridUnitType.Star)},
new RowDefinition{Height = new GridLength(2,GridUnitType.Star)}
},
ColumnDefinitions =
{
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)},
new ColumnDefinition{Width = new GridLength(1,GridUnitType.Star)}
}
};
number = new Label {
Text = "",
FontAttributes = FontAttributes.Bold,
FontSize = App.HeightUnit * 5
};
name = new Label {
Text = "Loading Workspace....",
FontAttributes = FontAttributes.Bold,
HorizontalTextAlignment = TextAlignment.Center,
FontSize = App.HeightUnit * 3.5,
Margin = new Thickness(0)
};
type = new Label {
Text = QIcon.SPIN3,
FontFamily = (OnPlatform<string>)Application.Current.Resources["QFontFamily"],
VerticalTextAlignment = TextAlignment.Center,
HorizontalTextAlignment = TextAlignment.End,
FontSize = App.HeightUnit * 5
};
notes = new Label {
Text = "Loading Cue Lists and Playhead Position",
HorizontalTextAlignment = TextAlignment.Center,
Margin = new Thickness(0,0,0,10),
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand
};
//BACKGROUND COLORS FOR TESTING ONLY
//notes.BackgroundColor = Color.Red;
//number.BackgroundColor = Color.Red;
//name.BackgroundColor = Color.Red;
//type.BackgroundColor = Color.Red;
//topGrid.BackgroundColor = Color.Green;
//bottomGrid.BackgroundColor = Color.Green;
topGrid.Children.Add(number, 0, 0);
topGrid.Children.Add(type, 4, 0);
Grid.SetColumnSpan(number, 3);
Grid.SetColumnSpan(type, 1);
bottomGrid.Children.Add(name, 0, 0);
bottomGrid.Children.Add(notes, 0, 1);
Grid.SetColumnSpan(name, 5);
Grid.SetColumnSpan(notes,5);
mainG.Children.Add(topGrid, 0, 0);
Grid.SetColumnSpan(topGrid, 5);
mainG.Children.Add(bottomGrid, 0, 1);
Grid.SetColumnSpan(bottomGrid, 5);
CornerRadius = 20;
BackgroundColor = Color.FromHex("D8D8D8");
HeightRequest = App.HeightUnit * 25;
Margin = new Thickness(10);
Content = mainG;
SetupDoubleTapEdit();
}
void SetupDoubleTapEdit()
{
var notesDoubleTap = new TapGestureRecognizer();
var nameDoubleTap = new TapGestureRecognizer();
var numberDoubleTap = new TapGestureRecognizer();
notesDoubleTap.NumberOfTapsRequired = 2;
nameDoubleTap.NumberOfTapsRequired = 2;
numberDoubleTap.NumberOfTapsRequired = 2;
notesDoubleTap.Tapped += (s, e) =>
{
UserDialogs.Instance.Prompt(new PromptConfig
{
Title = "Update Notes",
Message = "Changes notes to update",
OkText = "Update",
Text = notes.Text,
OnAction = (qNotes) =>
{
if (!qNotes.Ok)
return;
OnSelectedCueEdited("notes", qNotes.Text);
}
});
};
nameDoubleTap.Tapped += (s, e) =>
{
UserDialogs.Instance.Prompt(new PromptConfig
{
Title = "Update Name",
Message = "Change name to update",
OkText = "Update",
Text = name.Text,
OnAction = (qName) =>
{
if (!qName.Ok)
return;
OnSelectedCueEdited("name", qName.Text);
}
});
};
numberDoubleTap.Tapped += (s, e) =>
{
UserDialogs.Instance.Prompt(new PromptConfig
{
Title = "Update Number",
Message = "Change number to update",
OkText = "Update",
Text = number.Text,
OnAction = (qNumber) =>
{
if (!qNumber.Ok)
return;
OnSelectedCueEdited("number", qNumber.Text);
}
});
};
notes.GestureRecognizers.Add(notesDoubleTap);
name.GestureRecognizers.Add(nameDoubleTap);
number.GestureRecognizers.Add(numberDoubleTap);
}
public void UpdateSelectedCue(QCue cue)
{
activeCue = cue;
name.Text = cue.listName;
number.Text = cue.number;
type.Text = cue.getIconString();
notes.Text = cue.notes;
}
protected virtual void OnSelectedCueEdited(string prop, string value)
{
if (SelectedCueEdited != null)
SelectedCueEdited(this, new CueEditArgs() { CueID = activeCue.uniqueID, Property = prop, NewValue = value }) ;
}
}
}
@@ -1,5 +1,5 @@
using Acr.UserDialogs;
using qController.Communication;
using qController.Helpers;
namespace qController.UI.Dialogs
{
@@ -1,15 +0,0 @@
using System;
using Acr.UserDialogs;
namespace qController.UI.Dialogs
{
public class NoWorkspacesConfig : ConfirmConfig
{
public NoWorkspacesConfig(Action<bool> action)
{
Message = "QLab doesn't have any workspaces open?";
OkText = "Disconnect";
OnAction = action;
}
}
}
@@ -1,88 +0,0 @@
using System;
using System.Collections.Generic;
using Acr.UserDialogs;
using qController.QItems;
using Serilog;
using QControlKit;
namespace qController.UI.Dialogs
{
public class WorkspacePromptArgs : EventArgs
{
public QOldWorkspace 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("WorkspacePrompt - Workspace Selected " + workspace.displayName);
if (!workspace.hasPasscode)
{
OnWorkspaceSelected(new QOldWorkspace(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 QOldWorkspace(workspace_id,resp.Value));
}
else
{
OnWorkspaceSelected(null);
}
}
});
}
protected virtual void OnWorkspaceSelected(QOldWorkspace workspace)
{
if (WorkspaceSelected != null)
WorkspaceSelected(this, new WorkspacePromptArgs() { SelectedWorkspace = workspace });
}
}
}
@@ -1,7 +1,5 @@
using Acr.UserDialogs;
using qController.Helpers;
using qController.ViewModels;
using Serilog;
using Xamarin.Forms;
namespace qController.UI
@@ -1,140 +0,0 @@
using Acr.UserDialogs;
using qController.ViewModels;
using Xamarin.Forms;
namespace qController.UI
{
public class QSelectedCueGrid : Grid
{
public QSelectedCueGrid()
{
RowSpacing = 0;
ColumnSpacing = 0;
BackgroundColor = Color.FromHex("#D8D8D8");
RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
RowDefinitions.Add(new RowDefinition { Height = GridLength.Star });
ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Star });
Frame border = new Frame
{
BorderColor = Color.Black,
BackgroundColor = Color.Transparent
};
Children.Add(border);
SetRowSpan(border, 3);
SetColumnSpan(border, 5);
Label number = new Label
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
Margin = 0,
Padding = 0,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
};
number.SetBinding(Label.TextProperty, "number", BindingMode.OneWay);
Children.Add(number,0,0);
Label type = new Label
{
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalTextAlignment = TextAlignment.Center,
HorizontalTextAlignment = TextAlignment.Center,
Margin = 0,
Padding = 0,
FontSize = App.HeightUnit * 4,
FontFamily = (OnPlatform<string>)Application.Current.Resources["QFontFamily"]
};
type.SetBinding(Label.TextProperty, "type", BindingMode.OneWay);
Children.Add(type, 4, 0);
Label name = new Label
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
BackgroundColor = Color.Transparent,
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
};
name.SetBinding(Label.TextProperty, "name", BindingMode.TwoWay);
Children.Add(name, 0, 1);
SetColumnSpan(name, 5);
Editor notes = new Editor
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Margin = 5,
BackgroundColor = Color.Transparent,
FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Editor))
};
notes.SetBinding(Editor.TextProperty, "notes", BindingMode.TwoWay);
Children.Add(notes, 0, 2);
SetColumnSpan(notes, 5);
//Double tap to edit name/number
var nameDoubleTap = new TapGestureRecognizer();
nameDoubleTap.NumberOfTapsRequired = 2;
nameDoubleTap.Tapped += (s, e) =>
{
UserDialogs.Instance.Prompt(new PromptConfig
{
Title = "Update Name",
Message = "Change name to update",
OkText = "Update",
Text = name.Text,
OnAction = (qName) =>
{
if (!qName.Ok)
return;
name.Text = qName.Text;
}
});
};
name.GestureRecognizers.Add(nameDoubleTap);
var numberDoubleTap = new TapGestureRecognizer();
numberDoubleTap.NumberOfTapsRequired = 2;
numberDoubleTap.Tapped += (s, e) =>
{
UserDialogs.Instance.Prompt(new PromptConfig
{
Title = "Update Number",
Message = "Change number to update",
OkText = "Update",
Text = number.Text,
OnAction = (qNumber) =>
{
if (!qNumber.Ok)
return;
//This bypasses the label .Text property because the number might not be valid (no duplicates)
((QCueViewModel)BindingContext).number = qNumber.Text;
}
});
};
number.GestureRecognizers.Add(numberDoubleTap);
}
}
}