mirror of
https://github.com/jwetzell/qController.git
synced 2026-08-25 00:49:16 +00:00
Begin Custom Controls and Editable Cue Info
This commit is contained in:
@@ -5,16 +5,40 @@ namespace qController
|
|||||||
{
|
{
|
||||||
public class QButton : Button
|
public class QButton : Button
|
||||||
{
|
{
|
||||||
public string OSCCommand
|
public QCommand qCommand
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
public QButton(string text, string cmd)
|
|
||||||
{
|
|
||||||
Text = text;
|
|
||||||
OSCCommand = cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public QButton(QCommand command){
|
||||||
|
qCommand = command;
|
||||||
|
Text = qCommand.text;
|
||||||
|
TextColor = Color.Black;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace qController
|
||||||
|
{
|
||||||
|
public class QControlsBlock: Frame
|
||||||
|
{
|
||||||
|
Grid mainG;
|
||||||
|
QController qController;
|
||||||
|
|
||||||
|
|
||||||
|
public QControlsBlock(QController controller)
|
||||||
|
{
|
||||||
|
qController = controller;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Margin = new Thickness(10);
|
||||||
|
Padding = new Thickness(0);
|
||||||
|
IsVisible = true;
|
||||||
|
|
||||||
|
|
||||||
|
BackgroundColor = Color.FromHex("4A4A4A");
|
||||||
|
//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.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 < buttons.Count; i++)
|
||||||
|
{
|
||||||
|
QButton b = buttons[i];
|
||||||
|
b.Clicked += sendOSC;
|
||||||
|
mainG.Children.Add(b, column, row);
|
||||||
|
row++;
|
||||||
|
if (row == 3)
|
||||||
|
{
|
||||||
|
row = 0;
|
||||||
|
column = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QButton goButton = new QButton(QCommands.GO);
|
||||||
|
goButton.Clicked += sendOSC;
|
||||||
|
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 += sendOSC;
|
||||||
|
mainG.Children.Add(b, column, row);
|
||||||
|
row++;
|
||||||
|
if (row == 3)
|
||||||
|
{
|
||||||
|
row = 0;
|
||||||
|
column = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QButton goButton = new QButton(QCommands.GO);
|
||||||
|
goButton.Clicked += sendOSC;
|
||||||
|
mainG.Children.Add(goButton, 1, 0);
|
||||||
|
Grid.SetRowSpan(goButton, 3);
|
||||||
|
Content = mainG;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendOSC(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if(((QButton)sender).qCommand.type == "WORKSPACE"){
|
||||||
|
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
|
||||||
|
string command = workspace_prefix + ((QButton)sender).qCommand.osc;
|
||||||
|
qController.qClient.sendStringUDP(command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ namespace qController
|
|||||||
Padding = new Thickness(5);
|
Padding = new Thickness(5);
|
||||||
CornerRadius = 20;
|
CornerRadius = 20;
|
||||||
BackgroundColor = Color.FromHex("D8D8D8");
|
BackgroundColor = Color.FromHex("D8D8D8");
|
||||||
|
HeightRequest = App.HeightUnit * 25;
|
||||||
Grid mainG = new Grid
|
Grid mainG = new Grid
|
||||||
{
|
{
|
||||||
Padding = new Thickness(0),
|
Padding = new Thickness(0),
|
||||||
@@ -53,8 +54,8 @@ namespace qController
|
|||||||
Padding = new Thickness(0),
|
Padding = new Thickness(0),
|
||||||
RowDefinitions =
|
RowDefinitions =
|
||||||
{
|
{
|
||||||
new RowDefinition{Height = GridLength.Auto},
|
new RowDefinition{Height = new GridLength(1,GridUnitType.Star)},
|
||||||
new RowDefinition{Height = GridLength.Auto}
|
new RowDefinition{Height = new GridLength(2,GridUnitType.Star)}
|
||||||
},
|
},
|
||||||
ColumnDefinitions =
|
ColumnDefinitions =
|
||||||
{
|
{
|
||||||
@@ -69,8 +70,7 @@ namespace qController
|
|||||||
number = new Label {
|
number = new Label {
|
||||||
Text = "",
|
Text = "",
|
||||||
FontAttributes = FontAttributes.Bold,
|
FontAttributes = FontAttributes.Bold,
|
||||||
FontSize = App.HeightUnit * 5,
|
FontSize = App.HeightUnit * 5
|
||||||
Margin = new Thickness(5)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
name = new Label {
|
name = new Label {
|
||||||
@@ -86,16 +86,34 @@ namespace qController
|
|||||||
FontFamily = App.QFont,
|
FontFamily = App.QFont,
|
||||||
VerticalTextAlignment = TextAlignment.Center,
|
VerticalTextAlignment = TextAlignment.Center,
|
||||||
HorizontalTextAlignment = TextAlignment.End,
|
HorizontalTextAlignment = TextAlignment.End,
|
||||||
Margin = new Thickness(5),
|
|
||||||
FontSize = App.HeightUnit * 5
|
FontSize = App.HeightUnit * 5
|
||||||
};
|
};
|
||||||
|
|
||||||
notes = new Label {
|
notes = new Label {
|
||||||
Text = "Loading Cue Lists and Playhead Position",
|
Text = "Loading Cue Lists and Playhead Position",
|
||||||
HorizontalTextAlignment = TextAlignment.Center
|
HorizontalTextAlignment = TextAlignment.Center,
|
||||||
|
Margin = new Thickness(0,0,0,10)
|
||||||
};
|
};
|
||||||
notes.HorizontalTextAlignment = TextAlignment.Center;
|
notes.VerticalOptions = LayoutOptions.FillAndExpand;
|
||||||
notes.Margin = new Thickness(0, 0, 0, 10);
|
notes.HorizontalOptions = LayoutOptions.FillAndExpand;
|
||||||
|
|
||||||
|
|
||||||
|
notes.BackgroundColor = Color.FromHex("FF0000");
|
||||||
|
number.BackgroundColor = Color.Red;
|
||||||
|
name.BackgroundColor = Color.Red;
|
||||||
|
type.BackgroundColor = Color.Red;
|
||||||
|
|
||||||
|
var notesDoubleTap = new TapGestureRecognizer();
|
||||||
|
notesDoubleTap.NumberOfTapsRequired = 2;
|
||||||
|
notesDoubleTap.Tapped += (s, e) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("Notes double tapped");
|
||||||
|
};
|
||||||
|
|
||||||
|
number.GestureRecognizers.Add(notesDoubleTap);
|
||||||
|
type.GestureRecognizers.Add(notesDoubleTap);
|
||||||
|
name.GestureRecognizers.Add(notesDoubleTap);
|
||||||
|
notes.GestureRecognizers.Add(notesDoubleTap);
|
||||||
|
|
||||||
topGrid.Children.Add(number, 0, 0);
|
topGrid.Children.Add(number, 0, 0);
|
||||||
topGrid.Children.Add(type, 4, 0);
|
topGrid.Children.Add(type, 4, 0);
|
||||||
@@ -113,6 +131,8 @@ namespace qController
|
|||||||
mainG.Children.Add(bottomGrid, 0, 1);
|
mainG.Children.Add(bottomGrid, 0, 1);
|
||||||
Grid.SetColumnSpan(bottomGrid, 5);
|
Grid.SetColumnSpan(bottomGrid, 5);
|
||||||
|
|
||||||
|
topGrid.BackgroundColor = Color.FromHex("00FF00");
|
||||||
|
bottomGrid.BackgroundColor = Color.FromHex("00FF00");
|
||||||
Margin = new Thickness(10);
|
Margin = new Thickness(10);
|
||||||
Content = mainG;
|
Content = mainG;
|
||||||
}
|
}
|
||||||
@@ -124,6 +144,9 @@ namespace qController
|
|||||||
number.Text = cue.number;
|
number.Text = cue.number;
|
||||||
type.Text = cue.getIconString();
|
type.Text = cue.getIconString();
|
||||||
notes.Text = cue.notes;
|
notes.Text = cue.notes;
|
||||||
|
if(notes.Text == ""){
|
||||||
|
notes.Text = " ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ namespace qController
|
|||||||
QSelectedCueCell qCell;
|
QSelectedCueCell qCell;
|
||||||
QSelectedCueOptionsCell qSelectedCueOptions;
|
QSelectedCueOptionsCell qSelectedCueOptions;
|
||||||
Grid mainG;
|
Grid mainG;
|
||||||
|
QControlsBlock qControlsBlock;
|
||||||
public ControlPage(string name, string address)
|
public ControlPage(string name, string address)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -99,24 +99,13 @@ namespace qController
|
|||||||
|
|
||||||
|
|
||||||
qCell = new QSelectedCueCell();
|
qCell = new QSelectedCueCell();
|
||||||
qCell.HeightRequest = Math.Max(App.Height * .20, 125);
|
|
||||||
|
|
||||||
sLayout.Children.Add(qCell);
|
sLayout.Children.Add(qCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinishUI()
|
void FinishUI()
|
||||||
{
|
{
|
||||||
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
|
string workspace_prefix = "/workspace/" + qController.qWorkspace.workspace_id;
|
||||||
List <QButton> buttons = new List<QButton>();
|
|
||||||
|
|
||||||
buttons.Add(new QButton("Previous", workspace_prefix + "/select/previous"));
|
|
||||||
buttons.Add(new QButton("Panic", workspace_prefix + "/panic"));
|
|
||||||
buttons.Add(new QButton("Next", workspace_prefix + "/select/next"));
|
|
||||||
buttons.Add(new QButton("Preview", "/preview"));
|
|
||||||
buttons.Add(new QButton("Pause", "/pause"));
|
|
||||||
buttons.Add(new QButton("Resume", "/resume"));
|
|
||||||
|
|
||||||
|
|
||||||
qSelectedCueOptions = new QSelectedCueOptionsCell();
|
qSelectedCueOptions = new QSelectedCueOptionsCell();
|
||||||
|
|
||||||
qSelectedCueOptions.mainSlider.ValueChanged += (sender, args) =>
|
qSelectedCueOptions.mainSlider.ValueChanged += (sender, args) =>
|
||||||
@@ -132,62 +121,9 @@ namespace qController
|
|||||||
qController.qClient.sendArgs(workspace_prefix + "/cue_id/" + qSelectedCueOptions.activeCue + "/sliderLevel/2", (float)args.NewValue);
|
qController.qClient.sendArgs(workspace_prefix + "/cue_id/" + qSelectedCueOptions.activeCue + "/sliderLevel/2", (float)args.NewValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
qControlsBlock = new QControlsBlock(qController);
|
||||||
|
|
||||||
mainG = new Grid
|
sLayout.Children.Add(qControlsBlock);
|
||||||
{
|
|
||||||
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(10),
|
|
||||||
IsVisible = false
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
int column = 0;
|
|
||||||
foreach (var b in buttons)
|
|
||||||
{
|
|
||||||
b.Clicked += sendOSC;
|
|
||||||
if (b.Text == "Panic")
|
|
||||||
{
|
|
||||||
b.BackgroundColor = Color.IndianRed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
b.BackgroundColor = Color.FromHex("D8D8D8");
|
|
||||||
}
|
|
||||||
b.TextColor = Color.Black;
|
|
||||||
mainG.Children.Add(b, column, row);
|
|
||||||
row++;
|
|
||||||
if (row == 3)
|
|
||||||
{
|
|
||||||
row = 0;
|
|
||||||
column = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QButton goButton = new QButton("GO", workspace_prefix+"/go");
|
|
||||||
goButton.Clicked += sendOSC;
|
|
||||||
goButton.BackgroundColor = Color.SeaGreen;
|
|
||||||
goButton.TextColor = Color.Black;
|
|
||||||
mainG.Children.Add(goButton, 1, 0);
|
|
||||||
Grid.SetRowSpan(goButton, 3);
|
|
||||||
|
|
||||||
sLayout.Children.Add(mainG);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendOSC(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
qController.qClient.sendStringUDP(((QButton)sender).OSCCommand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowMenu(object sender, EventArgs e)
|
void ShowMenu(object sender, EventArgs e)
|
||||||
@@ -266,8 +202,8 @@ namespace qController
|
|||||||
else
|
else
|
||||||
sLayout.Children.Remove(qSelectedCueOptions);
|
sLayout.Children.Remove(qSelectedCueOptions);
|
||||||
qCell.UpdateSelectedCue(args.Cue);
|
qCell.UpdateSelectedCue(args.Cue);
|
||||||
if (!mainG.IsVisible)
|
//if (!mainG.IsVisible)
|
||||||
mainG.IsVisible = true;
|
// mainG.IsVisible = true;
|
||||||
if(qSelectedCueOptions != null)
|
if(qSelectedCueOptions != null)
|
||||||
{
|
{
|
||||||
qSelectedCueOptions.activeCue = args.Cue.uniqueID;
|
qSelectedCueOptions.activeCue = args.Cue.uniqueID;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace qController
|
|||||||
listView = new ListView
|
listView = new ListView
|
||||||
{
|
{
|
||||||
ItemsSource = items,
|
ItemsSource = items,
|
||||||
|
RowHeight = (int)(App.HeightUnit * 6),
|
||||||
ItemTemplate = new DataTemplate(() =>
|
ItemTemplate = new DataTemplate(() =>
|
||||||
{
|
{
|
||||||
var grid = new Grid { Padding = new Thickness(5, 10) };
|
var grid = new Grid { Padding = new Thickness(5, 10) };
|
||||||
@@ -52,16 +53,26 @@ namespace qController
|
|||||||
icon.SetBinding(Label.TextProperty, "Icon");
|
icon.SetBinding(Label.TextProperty, "Icon");
|
||||||
icon.HorizontalTextAlignment = TextAlignment.Center;
|
icon.HorizontalTextAlignment = TextAlignment.Center;
|
||||||
icon.VerticalTextAlignment = TextAlignment.Center;
|
icon.VerticalTextAlignment = TextAlignment.Center;
|
||||||
icon.FontSize = 20;
|
icon.FontSize = App.HeightUnit * 3;
|
||||||
var label = new Label { VerticalOptions = LayoutOptions.FillAndExpand };
|
var label = new Label { VerticalOptions = LayoutOptions.FillAndExpand };
|
||||||
label.SetBinding(Label.TextProperty, "Title");
|
label.SetBinding(Label.TextProperty, "Title");
|
||||||
if (label.Text == "Disconnect")
|
if (label.Text == "Disconnect")
|
||||||
{
|
{
|
||||||
label.TextColor = Color.DarkRed;
|
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(icon);
|
||||||
grid.Children.Add(label, 1, 0);
|
grid.Children.Add(label, 1, 0);
|
||||||
return new ViewCell { View = grid };
|
return new ViewCell {View = grid};
|
||||||
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
Content = new StackLayout
|
Content = new StackLayout
|
||||||
|
|||||||
Reference in New Issue
Block a user