mirror of
https://github.com/jwetzell/qController.git
synced 2026-08-18 21:54:17 +00:00
initial working maui migration with android only
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="qController.App">
|
||||
<Application.Resources>
|
||||
<!-- Application resource dictionary -->
|
||||
<OnPlatform x:Key="qfont" x:TypeArguments="x:String">
|
||||
<On Platform="Android" Value="qfont.ttf#qfont" />
|
||||
<On Platform="iOS" Value="qfont" />
|
||||
</OnPlatform>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,71 @@
|
||||
using Acr.UserDialogs;
|
||||
using qController.Communication;
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.Devices;
|
||||
|
||||
namespace qController
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
public static INavigation iNav;
|
||||
public static NavigationPage NavigationPage { get; private set; }
|
||||
public static RootPage rootPage;
|
||||
public static string QFont;
|
||||
public static DisplayInfo mainDisplayInfo;
|
||||
public static double Height;
|
||||
public static double Width;
|
||||
public static double HeightUnit;
|
||||
public static double WidthUnit;
|
||||
public static QController qControllerToResume;
|
||||
public static bool MenuIsPresented
|
||||
{
|
||||
get
|
||||
{
|
||||
return rootPage.IsPresented;
|
||||
}
|
||||
set
|
||||
{
|
||||
rootPage.IsPresented = value;
|
||||
}
|
||||
}
|
||||
|
||||
public App()
|
||||
{
|
||||
InitializeComponent();
|
||||
/*MainPage = new NavigationPage(new QConnectionPage());
|
||||
iNav = MainPage.Navigation;*/
|
||||
|
||||
mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
|
||||
|
||||
Height = mainDisplayInfo.Height / mainDisplayInfo.Density;
|
||||
Width = mainDisplayInfo.Width / mainDisplayInfo.Density;
|
||||
HeightUnit = Height / 100.0;
|
||||
WidthUnit = Width / 100.0;
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
switch (Device.RuntimePlatform)
|
||||
{
|
||||
case Device.iOS:
|
||||
QFont = "qfont";
|
||||
break;
|
||||
case Device.Android:
|
||||
QFont = "qfont.ttf#qfont";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
rootPage = new RootPage();
|
||||
rootPage.Detail = new NavigationPage(new QConnectionPage());
|
||||
MainPage = rootPage;
|
||||
}
|
||||
|
||||
public static void showToast(string message)
|
||||
{
|
||||
var toastConfig = new ToastConfig(message);
|
||||
toastConfig.SetDuration(3000);
|
||||
toastConfig.SetPosition(ToastPosition.Bottom);
|
||||
UserDialogs.Instance.Toast(toastConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="qController.ControlPage"
|
||||
BackgroundColor="#4A4A4A">
|
||||
<ContentPage.Content>
|
||||
<AbsoluteLayout x:Name="sLayout">
|
||||
<Grid x:Name="topBar" HorizontalOptions="FillAndExpand" AbsoluteLayout.LayoutBounds="0,0,1,.09" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#71AEFF">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="4*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label x:Name="menuButton" FontFamily = "{StaticResource qfont}" HorizontalOptions = "Start" VerticalOptions="End" Margin="20,10,20,10" Grid.Row="0" Grid.Column="0" FontSize="25" Text=""/>
|
||||
<Label x:Name="instanceName" HorizontalTextAlignment="End" HorizontalOptions = "FillAndExpand" VerticalOptions="End" Margin="20,10,20,10" Grid.Row="0" Grid.Column="1"/>
|
||||
</Grid>
|
||||
</AbsoluteLayout>
|
||||
</ContentPage.Content>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,400 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using Acr.UserDialogs;
|
||||
using qController.Dialogs;
|
||||
using qController.QItems;
|
||||
using qController.Cell;
|
||||
using qController.Communication;
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Layouts;
|
||||
|
||||
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.Contains("ok")) {
|
||||
if(args.Status.Contains(":") && !args.Status.Contains("view")) {
|
||||
workspacePrompt.promptWorkspacePasscode(args.WorkspaceId);
|
||||
return;
|
||||
}
|
||||
Device.BeginInvokeOnMainThread(() => {
|
||||
FinishUI();
|
||||
});
|
||||
} else if (args.Status.Contains("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;
|
||||
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutFlags(qCell, AbsoluteLayoutFlags.All);
|
||||
|
||||
instanceName.FontSize = App.HeightUnit * 3;
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
switch (Device.RuntimePlatform)
|
||||
{
|
||||
case Device.iOS:
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qCell, new Rect(0, 0.13, 1, 0.30));
|
||||
topBar.HeightRequest = App.Height * .09;
|
||||
menuButton.FontSize = App.Height * .04;
|
||||
break;
|
||||
case Device.Android:
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qCell, new Rect(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 += (s, e) =>
|
||||
{
|
||||
qLevelsCell.IsVisible = !qLevelsCell.IsVisible;
|
||||
};
|
||||
qControlsBlock = new QControlsBlock(SendOSCFromButton);
|
||||
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutFlags(qControlsBlock, AbsoluteLayoutFlags.All);
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutFlags(qLevelsCell, AbsoluteLayoutFlags.All);
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutFlags(showLevelsButton, AbsoluteLayoutFlags.PositionProportional);
|
||||
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
switch (Device.RuntimePlatform)
|
||||
{
|
||||
case Device.iOS:
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qControlsBlock, new Rect(0, 0.53, 1, 0.25));
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qLevelsCell, new Rect(0.9, 0.40, 0.8, 0.25));
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(showLevelsButton, new Rect(0.02, 0.34, App.HeightUnit * 8, App.HeightUnit * 8));
|
||||
break;
|
||||
case Device.Android:
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qControlsBlock, new Rect(0, 0.58, 1, 0.25));
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qLevelsCell, new Rect(0.9, 0.45, 0.8, 0.25));
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(showLevelsButton, new Rect(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.rootPage.Detail.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 == null)
|
||||
{
|
||||
Log.Debug("[ControlPage] Workspace Update contains null data.");
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
Log.Debug("before show levels button and cue.levels isnt null");
|
||||
showLevelsButton.IsVisible = true;
|
||||
Log.Debug("after show levels button and cue.levels isnt null");
|
||||
} 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;
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutFlags(qCueListCell, AbsoluteLayoutFlags.All);
|
||||
Microsoft.Maui.Controls.Compatibility.AbsoluteLayout.SetLayoutBounds(qCueListCell, new Rect(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);
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
Back();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="qController.MenuPage">
|
||||
<StackLayout>
|
||||
<ListView x:Name="listView">
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,139 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using qController.QItems;
|
||||
using System;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
|
||||
using Microsoft.Maui.Graphics;
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace qController
|
||||
{
|
||||
public partial class MenuPage : ContentPage
|
||||
{
|
||||
|
||||
public ObservableCollection<MenuPageItem> items { get; } = new ObservableCollection<MenuPageItem>();
|
||||
public MenuPage()
|
||||
{
|
||||
On<iOS>().SetUseSafeArea(true);
|
||||
Title = "Menu";
|
||||
InitializeComponent();
|
||||
|
||||
ChangeToHome();
|
||||
|
||||
listView.ItemsSource = items;
|
||||
listView.RowHeight = (int)(App.HeightUnit * 6);
|
||||
listView.ItemTemplate = new DataTemplate(() =>
|
||||
{
|
||||
var grid = new Microsoft.Maui.Controls.Compatibility.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");
|
||||
|
||||
var label = new Label {
|
||||
VerticalOptions = LayoutOptions.FillAndExpand
|
||||
};
|
||||
label.SetBinding(Label.TextProperty, "Title");
|
||||
|
||||
if (label.Text == "Disconnect")
|
||||
label.TextColor = Colors.DarkRed;
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
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(QWorkspace 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,5 @@
|
||||
<FlyoutPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="qController.RootPage">
|
||||
|
||||
</FlyoutPage>
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace qController
|
||||
{
|
||||
public class MenuEventArgs : EventArgs
|
||||
{
|
||||
public string Command
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class RootPage : FlyoutPage
|
||||
{
|
||||
public MenuPage MenuPage;
|
||||
public delegate void MenuItemSelectedHandler(object source, MenuEventArgs args);
|
||||
public event MenuItemSelectedHandler MenuItemSelected;
|
||||
|
||||
public RootPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
MenuPage = new MenuPage();
|
||||
MenuPage.setItemSelected(OnItemSelected);
|
||||
|
||||
Flyout = MenuPage;
|
||||
}
|
||||
|
||||
void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||
{
|
||||
var item = e.SelectedItem as MenuPageItem;
|
||||
if (item != null)
|
||||
{
|
||||
MenuPage.clearSelectedItem();
|
||||
IsPresented = false;
|
||||
MenuItemSelected?.Invoke(this, new MenuEventArgs { Command = item.Command });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:qController" x:Class="qController.QConnectionPage">
|
||||
<StackLayout x:Name="sLayout">
|
||||
<Grid x:Name="topBar" HorizontalOptions="FillAndExpand" BackgroundColor="#71AEFF">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label x:Name = "menuButton" FontFamily = "{StaticResource qfont}" HorizontalOptions = "Start" VerticalOptions="End" Margin="20,10,20,10" Grid.Row="0" Grid.Column="0" Text=""/>
|
||||
</Grid>
|
||||
<ListView x:Name="listView" HasUnevenRows="true" BackgroundColor="#4A4A4A" SeparatorVisibility="None"></ListView>
|
||||
</StackLayout>
|
||||
</ContentPage>
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using Acr.UserDialogs;
|
||||
using Zeroconf;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using qController.QItems;
|
||||
using qController.Dialogs;
|
||||
using qController.Cell;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration;
|
||||
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
|
||||
using Microsoft.Maui.Controls.Compatibility;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
|
||||
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()
|
||||
{
|
||||
Microsoft.Maui.Controls.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
|
||||
((Microsoft.Maui.Controls.ListView)sender).SelectedItem = null; // de-select the row
|
||||
};
|
||||
|
||||
//Platform Specific Setup
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
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.FromArgb("4A4A4A");
|
||||
|
||||
//MenuButton Setup
|
||||
var menuButtonGesture = new TapGestureRecognizer();
|
||||
menuButtonGesture.Tapped += 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._tcp.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!");
|
||||
}
|
||||
}
|
||||
|
||||
void showMenu(object sender, EventArgs e)
|
||||
{
|
||||
App.MenuIsPresented = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user