Move View Files

This commit is contained in:
2020-10-18 18:53:35 -05:00
parent cc92703b33
commit 1dd29edf62
9 changed files with 1052 additions and 0 deletions
@@ -0,0 +1,394 @@
using System;
using System.Collections.Generic;
using Xamarin.Forms;
using Serilog;
using Acr.UserDialogs;
using qController.Dialogs;
using qController.QItems;
using qController.Cell;
using qController.Communication;
using qController.Events;
namespace qController
{
public partial class ControlPage : ContentPage
{
QController qController;
QSelectedCueCell qCell;
QLevelsCell qLevelsCell;
QCueListCell qCueListCell;
QLevelsButton showLevelsButton;
QControlsBlock qControlsBlock;
WorkspacePrompt workspacePrompt = new WorkspacePrompt();
public ControlPage(string name, string address)
{
InitializeComponent();
qController = new QController(address, 53000);
qController.qClient.qParser.WorkspaceInfoReceived += WorkspaceInfoReceived;
qController.qClient.qParser.WorkspaceUpdated += WorkspaceUpdated;
qController.qClient.qParser.WorkspaceDisconnect += WorkspaceDisconnected;
qController.qClient.qParser.PlaybackPositionUpdated += PlaybackPositionUpdated;
qController.qClient.qParser.ConnectionStatusChanged += OnConnectionStatusChanged;
qController.qClient.qParser.CueInfoUpdated += OnCueUpdateReceived;
qController.qClient.qParser.ChildrenUpdated += OnChildrenUpdated;
workspacePrompt.WorkspaceSelected += OnWorkspaceSelected;
App.rootPage.MenuItemSelected += OnMenuItemSelected;
instanceName.Text = name;
InitGUI();
if (!qController.qClient.connected)
{
App.showToast("Error connecting...make sure QLab is running");
Back();
}
else
{
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)
{
Log.Debug($"CONTROLPAGE - Connection Status Changed: {args.WorkspaceId} : {args.Status}");
if (args.Status.Equals("ok"))
{
Device.BeginInvokeOnMainThread(() => {
FinishUI();
});
}
else if (args.Status.Equals("badpass"))
{
workspacePrompt.promptWorkspacePasscode(args.WorkspaceId);
}
}
private void WorkspaceInfoReceived(object source, WorkspaceInfoArgs args)
{
if (args.WorkspaceInfo.Count > 1)
{
Log.Debug("CONTROLPAGE - MULTIPLE WORKSPACES ON SELECTED COMPUTER");
PromptForWorkspace(args.WorkspaceInfo);
}
else if (args.WorkspaceInfo.Count == 1)
{
Log.Debug("CONTROLPAGE - ONLY ONE WORKSPACE ON SELECTED COMPUTER");
if (!args.WorkspaceInfo[0].hasPasscode)
{
qController.Connect(args.WorkspaceInfo[0].uniqueID);
}
else
{
workspacePrompt.promptWorkspacePasscode(args.WorkspaceInfo[0].uniqueID);
}
}
else
{
NoWorkspacesConfig noWorkspacesConfig = new NoWorkspacesConfig(NoWorkspaceDetected);
UserDialogs.Instance.Confirm(noWorkspacesConfig);
}
}
private void PromptForWorkspace(List<QWorkspaceInfo> workspaces)
{
UserDialogs.Instance.ActionSheet(workspacePrompt.getActionSheetConfigForWorkspaces(workspaces));
}
private void InitGUI()
{
App.rootPage.MenuPage.ChangeToControl();
NavigationPage.SetHasNavigationBar(this, false);
qCell = new QSelectedCueCell();
qCell.SelectedCueEdited += OnSelectedCueEdited;
AbsoluteLayout.SetLayoutFlags(qCell, AbsoluteLayoutFlags.All);
instanceName.FontSize = App.HeightUnit * 3;
switch (Device.RuntimePlatform)
{
case Device.iOS:
AbsoluteLayout.SetLayoutBounds(qCell, new Rectangle(0, 0.13, 1, 0.30));
topBar.HeightRequest = App.Height * .09;
menuButton.FontSize = App.Height * .04;
break;
case Device.Android:
AbsoluteLayout.SetLayoutBounds(qCell, new Rectangle(0, 0.13, 1, 0.35));
topBar.HeightRequest = App.Height * .06;
menuButton.FontSize = App.Height * .05;
break;
}
//Menu Button Setup
var menuButtonGesture = new TapGestureRecognizer();
menuButtonGesture.Tapped += ShowMenu;
menuButton.GestureRecognizers.Add(menuButtonGesture);
menuButton.Margin = new Thickness(App.WidthUnit * 2, 0, 0, App.WidthUnit * 2);
sLayout.Children.Add(qCell);
}
private void SendOSCFromButton(object sender, EventArgs args)
{
if (((QButton)sender).qCommand.type == "WORKSPACE")
{
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
string command = workspace_prefix + ((QButton)sender).qCommand.osc;
qController.qClient.sendTCP(command);
}
}
private void OnSelectedCueEdited(object source, CueEditArgs args)
{
string address = "/workspace/" + qController.qWorkspace.workspace_id + "/cue_id/" + args.CueID + "/" + args.Property;
qController.qClient.sendTCP(address, args.NewValue);
}
void FinishUI()
{
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
qLevelsCell = new QLevelsCell();
qLevelsCell.mainSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/0", (float)args.NewValue);
};
qLevelsCell.leftSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/1", (float)args.NewValue);
};
qLevelsCell.rightSlider.ValueChanged += (sender, args) =>
{
qController.qClient.sendTCP(workspace_prefix + "/cue_id/" + qLevelsCell.activeCue + "/sliderLevel/2", (float)args.NewValue);
};
showLevelsButton = new QLevelsButton();
showLevelsButton.button.Clicked += ToggeQLevelsCellVisiblity;
qControlsBlock = new QControlsBlock(SendOSCFromButton);
AbsoluteLayout.SetLayoutFlags(qControlsBlock, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutFlags(qLevelsCell, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutFlags(showLevelsButton, AbsoluteLayoutFlags.PositionProportional);
switch (Device.RuntimePlatform)
{
case Device.iOS:
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(showLevelsButton, new Rectangle(0.02, 0.34, App.HeightUnit * 8, App.HeightUnit * 8));
break;
case Device.Android:
AbsoluteLayout.SetLayoutBounds(qControlsBlock, new Rectangle(0, 0.58, 1, 0.25));
AbsoluteLayout.SetLayoutBounds(qLevelsCell, new Rectangle(0.9, 0.45, 0.8, 0.25));
AbsoluteLayout.SetLayoutBounds(showLevelsButton, new Rectangle(0.02, 0.39, App.HeightUnit * 8, App.HeightUnit * 8));
break;
}
sLayout.Children.Add(qControlsBlock);
sLayout.Children.Add(qLevelsCell);
sLayout.Children.Add(showLevelsButton);
}
private void ToggeQLevelsCellVisiblity(object sender, EventArgs e)
{
qLevelsCell.IsVisible = !qLevelsCell.IsVisible;
}
void ShowMenu(object sender, EventArgs e)
{
App.MenuIsPresented = true;
}
void Back()
{
if(qController.qClient.connected)
qController.Kill();
App.rootPage.MenuItemSelected -= OnMenuItemSelected;
Device.BeginInvokeOnMainThread(() =>
{
App.rootPage.MenuPage.ChangeToHome();
App.NavigationPage.Navigation.PopAsync();
});
}
public void NoWorkspaceDetected(bool resp)
{
if (resp)
Back();
}
public void WorkspaceDisconnected(object sender, EventArgs e)
{
Back();
}
public void WorkspaceUpdated(object sender, WorkspaceEventArgs e)
{
if(e.UpdatedWorkspace.data.Count > 0)
{
qController.qWorkspace = e.UpdatedWorkspace;
qController.qWorkspace.CheckPopulated();
if (qController.qWorkspace.IsPopulated)
{
Device.BeginInvokeOnMainThread(() =>
{
App.rootPage.MenuPage.ChangeToWorkspace(e.UpdatedWorkspace);
});
if (qCell.activeCue == null)
{
Device.BeginInvokeOnMainThread(() => {
qCell.UpdateSelectedCue(new NoQCueSelected());
});
Log.Debug("CONTROLPAGE - Update Selected Cue Called because of Inital Workspace Load");
qController.qClient.UpdateSelectedCue(qController.qWorkspace.workspace_id);
}
Log.Debug("CONTROLPAGE - Workspace Updated " + qController.qWorkspace.workspace_id);
}
}
}
public void PlaybackPositionUpdated(object sender, PlaybackPositionArgs e)
{
qController.playbackPosition = e.PlaybackPosition;
Log.Debug("CONTROLPAGE - Playback Position Updated " + qController.playbackPosition);
QCue cue = qController.qWorkspace.GetCue(qController.playbackPosition);
if(cue != null)
{
Device.BeginInvokeOnMainThread(() => {
if (cue.levels != null)
showLevelsButton.IsVisible = true;
else
{
showLevelsButton.IsVisible = false;
qLevelsCell.IsVisible = false;
}
qCell.UpdateSelectedCue(cue);
});
}
}
public void OnCueUpdateReceived(object sender, CueEventArgs args)
{
if(qController != null)
{
if(qController.qWorkspace != null)
{
qController.qWorkspace.UpdateCue(args.Cue);
if (qController.playbackPosition == null)
{
qController.playbackPosition = args.Cue.uniqueID;
}
if (args.Cue.uniqueID == qController.playbackPosition)
{
Device.BeginInvokeOnMainThread(() =>
{
Log.Debug("CONTROLPAGE - Refreshing Currently Displayed Cue");
if (args.Cue.levels != null)
showLevelsButton.IsVisible = true;
else
{
showLevelsButton.IsVisible = false;
qLevelsCell.IsVisible = false;
}
qCell.UpdateSelectedCue(args.Cue);
if(qLevelsCell != null)
{
qLevelsCell.activeCue = args.Cue.uniqueID;
if (args.Cue.levels != null)
{
qLevelsCell.UpdateLevels(args.Cue.levels[0]);
}
}
});
}
}
}
}
private void OnChildrenUpdated(object source, ChildrenEventArgs args)
{
if(qController != null)
{
if(qController.qWorkspace != null)
{
qController.qWorkspace.UpdateChildren(args.cue_id, args.children);
}
}
}
private void OnMenuItemSelected(object source, MenuEventArgs args)
{
if (args.Command.Contains("/"))
{
qController.qClient.sendTCP(args.Command);
}
else if (args.Command == "disconnect")
{
Back();
}else if (args.Command.Contains("cueList"))
{
var parts = args.Command.Split(' ');
if(parts.Length > 1)
{
Device.BeginInvokeOnMainThread(() =>
{
qCueListCell = new QCueListCell(qController.qWorkspace.GetCueList(parts[1]));
qCueListCell.closeButton.Clicked += CloseCueList;
qCueListCell.cueListView.ItemSelected += OnCueListItemSelected;
AbsoluteLayout.SetLayoutFlags(qCueListCell, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(qCueListCell, new Rectangle(0, 0.2, 1, 0.9));
sLayout.Children.Add(qCueListCell);
});
}
}
}
private void CloseCueList(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
sLayout.Children.Remove(qCueListCell);
});
}
private void OnCueListItemSelected(object sender, SelectedItemChangedEventArgs e)
{
OSCListItem cue = (OSCListItem)e.SelectedItem;
string selectCueOSC = "/workspace/" + qController.qWorkspace.workspace_id + cue.Command;
qController.qClient.sendTCP(selectCueOSC);
CloseCueList(sender,e);
}
}
}
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace qController
{
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
}
}
+135
View File
@@ -0,0 +1,135 @@
using System.Collections.ObjectModel;
using Xamarin.Forms;
using qController.QItems;
using System;
namespace qController
{
public partial class MenuPage : ContentPage
{
public ObservableCollection<MenuPageItem> items { get; } = new ObservableCollection<MenuPageItem>();
public MenuPage()
{
Title = "Menu";
InitializeComponent();
ChangeToHome();
listView.ItemsSource = items;
listView.RowHeight = (int)(App.HeightUnit * 6);
listView.ItemTemplate = new DataTemplate(() =>
{
var grid = new Grid {
Padding = new Thickness(5, 10),
ColumnDefinitions =
{
new ColumnDefinition{Width = new GridLength(30)},
new ColumnDefinition { Width = GridLength.Star }
}
};
var icon = new Label {
FontFamily = App.QFont,
HorizontalTextAlignment = TextAlignment.Center,
VerticalTextAlignment = TextAlignment.Center,
FontSize = App.HeightUnit * 3
};
icon.SetBinding(Label.TextProperty, "Icon");
icon.SetDynamicResource(Label.TextColorProperty, "IconTextColor");
var label = new Label {
VerticalOptions = LayoutOptions.FillAndExpand
};
label.SetBinding(Label.TextProperty, "Title");
label.SetDynamicResource(Label.TextColorProperty, "PrimaryTextColor");
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 };
});
}
public void setItemSelected(EventHandler<SelectedItemChangedEventArgs> ItemSelected){
listView.ItemSelected += ItemSelected;
}
public void clearSelectedItem()
{
listView.SelectedItem = null;
}
public void ChangeToControl()
{
items.Clear();
items.Add(new MenuPageItem
{
Title = "Disconnect",
Icon = QIcon.CANCEL,
Command = "disconnect"
});
}
public void ChangeToWorkspace(QOldWorkspace workspace)
{
for(int i = 0; i < workspace.data.Count; i++)
{
var cueList = workspace.data[i];
items.Add(new MenuPageItem
{
Title = cueList.listName,
Icon = cueList.IconText,
Command = "cueList " + cueList.uniqueID
});
}
}
public void ChangeToHome()
{
items.Clear();
items.Add(new MenuPageItem
{
Title = "Scan Network",
Icon = "\uE800",
Command = "scan"
});
items.Add(new MenuPageItem
{
Title = "Add Manually",
Icon = "\uE801",
Command = "add"
});
items.Add(new MenuPageItem
{
Title = "Send Feedback",
Icon = QIcon.MAIL,
Command = "feedback"
});
items.Add(new MenuPageItem
{
Title = "Support Project",
Icon = QIcon.DOLLAR,
Command = "support"
});
}
}
}
@@ -0,0 +1,103 @@
using QControlKit;
using Xamarin.Forms;
using Serilog;
using qController.Cell;
using Acr.UserDialogs;
using qController.Dialogs;
using Xamarin.Essentials;
using System;
using qController.ViewModels;
namespace qController.Pages
{
public partial class QBrowserPage : ContentPage
{
public QBrowserPage()
{
InitializeComponent();
SetupTopBar();
serverListView.BindingContext = new QBrowserViewModel(new QBrowser());
serverListView.ItemSelected += QWorkspaceSelected;
storageListView.ItemsSource = QStorage.qInstances;
storageListView.ItemTemplate = new DataTemplate(typeof(QInstanceCell));
storageListView.ItemTapped += (object sender, ItemTappedEventArgs e) =>
{
// don't do anything if we just de-selected the row
if (e.Item == null) return;
// do something with e.SelectedItem
((ListView)sender).SelectedItem = null; // de-select the row
};
}
private void SetupTopBar()
{
NavigationPage.SetHasNavigationBar(this, false);
App.rootPage.MenuItemSelected += OnMenuItemSelected;
}
async void QWorkspaceSelected(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
return;
QWorkspace selectedWorkspace = (e.SelectedItem as QWorkspaceViewModel).workspace;
Log.Debug($"[demo] workspace: {selectedWorkspace.nameWithoutPathExtension} has been selected");
((ListView)sender).SelectedItem = null;
if (selectedWorkspace.hasPasscode)
{
UserDialogs.Instance.Prompt(new PromptConfig
{
InputType = InputType.Number,
MaxLength = 4,
Title = "Workspace Requires Passcode",
OkText = "Connect",
IsCancellable = true,
OnTextChanged = args =>
{
args.IsValid = args.Value != null && !args.Value.Equals("") && args.Value.Length == 4;
},
OnAction = async (resp) =>
{
if (resp.Ok)
{
Console.WriteLine($"Passcode is null: {resp.Value == null}");
await Navigation.PushAsync(new WorkspacePage(selectedWorkspace, resp.Value));
}
}
});
}
else
{
await Navigation.PushAsync(new WorkspacePage(selectedWorkspace));
}
}
void AddWorkspace()
{
UserDialogs.Instance.Prompt(new AddInstancePrompt());
}
private void OnMenuItemSelected(object source, MenuEventArgs args)
{
if (args.Command == "add")
{
AddWorkspace();
}
else if (args.Command == "feedback")
{
Launcher.OpenAsync(new Uri("mailto:feedback@jwetzell.com?subject=qController%20feedback"));
}
else if (args.Command == "support")
{
UserDialogs.Instance.Confirm(new DonatePrompt());
}
}
}
}
@@ -0,0 +1,46 @@
using System;
using Xamarin.Forms;
namespace qController
{
public class MenuEventArgs : EventArgs
{
public string Command
{
get;
set;
}
}
public partial class RootPage : MasterDetailPage
{
public MenuPage MenuPage;
public delegate void MenuItemSelectedHandler(object source, MenuEventArgs args);
public event MenuItemSelectedHandler MenuItemSelected;
public RootPage()
{
InitializeComponent();
}
public void Init()
{
MenuPage = (MenuPage)Master;
MenuPage.setItemSelected(OnItemSelected);
}
void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = e.SelectedItem as MenuPageItem;
if (item != null)
{
MenuPage.clearSelectedItem();
IsPresented = false;
if (MenuItemSelected != null)
MenuItemSelected(this, new MenuEventArgs { Command = item.Command });
}
}
}
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace qController.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPageDetail : ContentPage
{
public RootPageDetail()
{
InitializeComponent();
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace qController.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RootPageMaster : ContentPage
{
public ListView ListView;
public RootPageMaster()
{
InitializeComponent();
BindingContext = new RootPageMasterViewModel();
ListView = MenuItemsListView;
}
class RootPageMasterViewModel : INotifyPropertyChanged
{
public ObservableCollection<RootPageMenuItem> MenuItems { get; set; }
public RootPageMasterViewModel()
{
MenuItems = new ObservableCollection<RootPageMenuItem>(new[]
{
new RootPageMenuItem { Id = 0, Title = "Page 1" },
new RootPageMenuItem { Id = 1, Title = "Page 2" },
new RootPageMenuItem { Id = 2, Title = "Page 3" },
new RootPageMenuItem { Id = 3, Title = "Page 4" },
new RootPageMenuItem { Id = 4, Title = "Page 5" },
});
}
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged == null)
return;
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
}
@@ -0,0 +1,169 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Serilog;
using Xamarin.Essentials;
using Xamarin.Forms;
using Acr.UserDialogs;
using qController.ViewModels;
using qController.UI;
using QControlKit;
using QControlKit.Events;
using QControlKit.Constants;
namespace qController
{
public partial class WorkspacePage : ContentPage
{
private QWorkspace connectedWorkspace;
private Dictionary<string, Grid> cueGridDict = new Dictionary<string, Grid>();
public WorkspacePage(QWorkspace workspace, string passcode = null)
{
InitializeComponent();
connectedWorkspace = workspace;
SetupTopBar();
connectedWorkspace.WorkspaceUpdated += Workspace_WorkspaceUpdated;
connectedWorkspace.WorkspaceConnectionError += ConnectedWorkspace_WorkspaceConnectionError;
connectedWorkspace.defaultSendUpdatesOSC = true;
connectedWorkspace.CueListChangedPlaybackPosition += ConnectedWorkspace_CueListChangedPlaybackPosition;
connectedWorkspace.connect(passcode);
}
private void SetupTopBar()
{
NavigationPage.SetHasNavigationBar(this, false);
App.rootPage.MenuPage.ChangeToControl();
App.rootPage.MenuItemSelected += OnMenuItemSelected;
qNavBar.instanceName.Text = connectedWorkspace.serverName;
}
private void ConnectedWorkspace_WorkspaceConnectionError(object source, QWorkspaceConnectionErrorArgs connectionErrorArgs)
{
System.Console.WriteLine("WorkspaceConnectionError Called");
if (connectionErrorArgs.status.Equals("badpass"))
{
UserDialogs.Instance.Prompt(new PromptConfig
{
InputType = InputType.Number,
MaxLength = 4,
Title = "Incorrect Passcode!",
OkText = "Connect",
IsCancellable = true,
OnTextChanged = args =>
{
args.IsValid = args.Value != null && !args.Value.Equals("") && args.Value.Length == 4;
},
OnAction = (resp) =>
{
if (resp.Ok)
{
connectedWorkspace.connect(resp.Value);
}
}
});
}
}
void ConnectedWorkspace_CueListChangedPlaybackPosition(object source, QCueListChangedPlaybackPositionArgs args)
{
Device.BeginInvokeOnMainThread(() =>
{
QCue selectedCue = connectedWorkspace.cueWithID(args.cueID);
connectedWorkspace.fetchDefaultPropertiesForCue(selectedCue);
selectedCueFrame.BindingContext = new QCueViewModel(selectedCue, false);
if (cueGridDict.ContainsKey(args.cueID))
{
var cueGrid = cueGridDict[args.cueID]; //element to scroll to
cueListScrollView.ScrollToAsync(cueGrid, ScrollToPosition.Center, true);
}
});
}
void Workspace_WorkspaceUpdated(object source, QWorkspaceUpdatedArgs args)
{
Log.Debug("[workspacepage] Workspace Updated");
foreach (var cue in connectedWorkspace.cueLists)
{
if (cue.cues.Count > 0)
{
List<Task> cueAddTasks = new List<Task>();
foreach (var aCue in cue.cues)
{
QCueGrid cueGrid = cueToGrid(aCue);
cueGridDict.Add(aCue.uid, cueGrid);
MainThread.InvokeOnMainThreadAsync(() =>
{
cueListsGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
cueListsGrid.Children.Add(cueGrid, 0, aCue.sortIndex);
}).Wait();
}
connectedWorkspace.valueForKey(cue, QOSCKey.PlaybackPositionId); //fetch playback position for cueList once all cue loading is done.
break; //only load first cue list with cues.
}
}
}
protected override void OnDisappearing()
{
base.OnDisappearing();
}
QCueGrid cueToGrid(QCue cue)
{
QCueGrid cueGrid = new QCueGrid(cue);
if (cue.cues.Count > 0)
{
foreach (var aCue in cue.cues)
{
cueGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
var aCueGrid = cueToGrid(aCue);
cueGridDict.Add(aCue.uid, aCueGrid);
aCueGrid.Margin = new Thickness(10, 0, 0, 0);
cueGrid.Children.Add(aCueGrid, 0, aCue.sortIndex + 1);
}
}
return cueGrid;
}
void Back()
{
if (connectedWorkspace.connected)
connectedWorkspace.disconnect(); //TODO: This might not be implemented?
//unsubscribe from events
App.rootPage.MenuItemSelected -= OnMenuItemSelected;
connectedWorkspace.WorkspaceUpdated -= Workspace_WorkspaceUpdated;
connectedWorkspace.CueListChangedPlaybackPosition -= ConnectedWorkspace_CueListChangedPlaybackPosition;
connectedWorkspace.WorkspaceConnectionError -= ConnectedWorkspace_WorkspaceConnectionError;
Device.BeginInvokeOnMainThread(() =>
{
App.rootPage.MenuPage.ChangeToHome();
App.NavigationPage.Navigation.PopAsync();
});
}
private void OnMenuItemSelected(object source, MenuEventArgs args)
{
if (args.Command == "disconnect")
{
Back();
}
}
}
}
@@ -0,0 +1,114 @@
using Xamarin.Forms;
using System;
using Acr.UserDialogs;
using Zeroconf;
using System.Collections.Generic;
using Serilog;
using qController.QItems;
using qController.Dialogs;
using qController.Cell;
using Xamarin.Essentials;
namespace qController
{
public partial class QConnectionPage : ContentPage
{
public QConnectionPage()
{
InitializeComponent();
InitGUI();
App.rootPage.MenuItemSelected += OnMenuItemSelected;
}
private void OnMenuItemSelected(object source, MenuEventArgs args)
{
if(args.Command == "scan")
{
Scan();
}
else if(args.Command == "add")
{
AddWorkspace();
}
else if (args.Command == "feedback")
{
Launcher.OpenAsync(new Uri("mailto:feedback@jwetzell.com?subject=qController%20feedback"));
}
else if(args.Command == "support")
{
UserDialogs.Instance.Confirm(new DonatePrompt());
}
}
private void InitGUI()
{
NavigationPage.SetHasNavigationBar(this, false);
//ListView Setup
listView.ItemsSource = QStorage.qInstances;
listView.ItemTemplate = new DataTemplate(typeof(QInstanceCell));
listView.ItemTapped += (object sender, ItemTappedEventArgs e) =>
{
// don't do anything if we just de-selected the row
if (e.Item == null) return;
// do something with e.SelectedItem
((ListView)sender).SelectedItem = null; // de-select the row
};
//Platform Specific Setup
switch (Device.RuntimePlatform)
{
case Device.iOS:
topBar.HeightRequest = App.Height * .09;
menuButton.FontSize = App.Height * .04;
menuButton.Margin = new Thickness(App.WidthUnit * 2, 0, 0, App.WidthUnit * 2);
break;
case Device.Android:
topBar.HeightRequest = App.Height * .09;
menuButton.FontSize = App.Height * .05;
menuButton.Margin = new Thickness(App.WidthUnit * 2, 0, 0, App.WidthUnit * 2);
break;
}
BackgroundColor = Color.FromHex("4A4A4A");
//MenuButton Setup
var menuButtonGesture = new TapGestureRecognizer();
menuButtonGesture.Tapped += App.ShowMenu;
menuButton.GestureRecognizers.Add(menuButtonGesture);
}
void AddWorkspace(){
UserDialogs.Instance.Prompt(new AddInstancePrompt());
}
async void Scan(){
bool workspacesFound = false;
App.showToast("Scanning for Instances...");
Log.Debug("QCONNECTIONPAGE - Begin Scanning");
IReadOnlyList<IZeroconfHost> results = await ZeroconfResolver.ResolveAsync("_qlab._udp.local.",TimeSpan.FromSeconds(3));
if(results != null){
foreach (var result in results)
{
if (result != null)
{
QInstance instance = new QInstance(result.DisplayName, result.IPAddress);
if(QStorage.AddInstance(instance)){
Log.Debug($"QCONNECTIONPAGE - {result.DisplayName} @ {result.IPAddress} added");
workspacesFound = true;
}
}
}
}
if(workspacesFound){
App.showToast("Instance Found and Added!");
}else{
App.showToast("No New Instances Found!");
}
}
}
}