Base data editing page in GTK client.
This commit is contained in:
@@ -83,7 +83,7 @@ namespace EstusShots.Gtk.Controls
|
|||||||
throw new TypeLoadException(
|
throw new TypeLoadException(
|
||||||
$"Property '{column.PropertyName}' does not exist on Type '{item.GetType()}'");
|
$"Property '{column.PropertyName}' does not exist on Type '{item.GetType()}'");
|
||||||
var val = prop.GetValue(item);
|
var val = prop.GetValue(item);
|
||||||
if (column.Format != null) val = column.Format(val);
|
if (column.DisplayConverter != null) val = column.DisplayConverter(val);
|
||||||
row.Add(val);
|
row.Add(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,34 +129,11 @@ namespace EstusShots.Gtk.Controls
|
|||||||
{
|
{
|
||||||
// Offset by one, because the first column in the data store is fixed to the key value of the row
|
// Offset by one, because the first column in the data store is fixed to the key value of the row
|
||||||
var valueIndex = Columns.IndexOf(dataColumn) + 1;
|
var valueIndex = Columns.IndexOf(dataColumn) + 1;
|
||||||
var cell = GetRenderer(dataColumn);
|
dataColumn.AddAttribute(dataColumn.Cell, dataColumn.ValueAttribute, valueIndex);
|
||||||
var attr = GetAttribute(dataColumn);
|
|
||||||
dataColumn.PackStart(cell, true);
|
|
||||||
dataColumn.AddAttribute(cell, attr, valueIndex);
|
|
||||||
TreeView.AppendColumn(dataColumn);
|
TreeView.AppendColumn(dataColumn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CellRenderer GetRenderer(DataColumn column)
|
|
||||||
{
|
|
||||||
var property = typeof(T).GetProperty(column.PropertyName);
|
|
||||||
return property?.PropertyType.Name switch
|
|
||||||
{
|
|
||||||
nameof(Boolean) => new CellRendererToggle(),
|
|
||||||
_ => new CellRendererText()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetAttribute(DataColumn column)
|
|
||||||
{
|
|
||||||
var property = typeof(T).GetProperty(column.PropertyName);
|
|
||||||
return property?.PropertyType.Name switch
|
|
||||||
{
|
|
||||||
nameof(Boolean) => "active",
|
|
||||||
_ => "text"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitListStore()
|
private void InitListStore()
|
||||||
{
|
{
|
||||||
var types = Columns
|
var types = Columns
|
||||||
|
|||||||
@@ -3,19 +3,18 @@ using Gtk;
|
|||||||
|
|
||||||
namespace EstusShots.Gtk.Controls
|
namespace EstusShots.Gtk.Controls
|
||||||
{
|
{
|
||||||
public class DataColumn : TreeViewColumn
|
public abstract class DataColumn : TreeViewColumn
|
||||||
{
|
{
|
||||||
public DataColumn()
|
protected DataColumn(string propertyName)
|
||||||
{
|
{
|
||||||
|
PropertyName = propertyName;
|
||||||
|
Title = propertyName;
|
||||||
|
|
||||||
Resizable = true;
|
Resizable = true;
|
||||||
Reorderable = true;
|
Reorderable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataColumn(string propertyName) : this()
|
public abstract string ValueAttribute { get; }
|
||||||
{
|
|
||||||
PropertyName = propertyName;
|
|
||||||
Title = propertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the property in the data source, that should be show nin the view
|
/// The name of the property in the data source, that should be show nin the view
|
||||||
@@ -26,6 +25,64 @@ namespace EstusShots.Gtk.Controls
|
|||||||
/// Applies the given transformation on each item in the column.
|
/// Applies the given transformation on each item in the column.
|
||||||
/// This changes only the display of the value.
|
/// This changes only the display of the value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<object, string> Format { get; set; }
|
public abstract Func<object, string> DisplayConverter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cell renderer for rows in the column
|
||||||
|
/// </summary>
|
||||||
|
public abstract CellRenderer Cell { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DataColumnText : DataColumn
|
||||||
|
{
|
||||||
|
public DataColumnText(string propertyName) : base(propertyName)
|
||||||
|
{
|
||||||
|
ValueAttribute = "text";
|
||||||
|
Cell = new CellRendererText();
|
||||||
|
PackStart(Cell, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override string ValueAttribute { get; }
|
||||||
|
|
||||||
|
public override Func<object, string> DisplayConverter { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cell renderer for rows in the column
|
||||||
|
/// </summary>
|
||||||
|
public sealed override CellRenderer Cell { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DataColumnBool : DataColumn
|
||||||
|
{
|
||||||
|
public DataColumnBool(string propertyName) : base(propertyName)
|
||||||
|
{
|
||||||
|
ValueAttribute = "active";
|
||||||
|
Cell = new CellRendererToggle();
|
||||||
|
PackStart(Cell, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ValueAttribute { get; }
|
||||||
|
public override Func<object, string> DisplayConverter { get; set; }
|
||||||
|
public sealed override CellRenderer Cell { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DataColumnDouble : DataColumn
|
||||||
|
{
|
||||||
|
public DataColumnDouble(string propertyName) : base(propertyName)
|
||||||
|
{
|
||||||
|
ValueAttribute = "text";
|
||||||
|
Cell = new CellRendererSpin();
|
||||||
|
PackStart(Cell, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Digits
|
||||||
|
{
|
||||||
|
set => SetAttributes(Cell, "digits", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ValueAttribute { get; }
|
||||||
|
public override Func<object, string> DisplayConverter { get; set; }
|
||||||
|
public sealed override CellRenderer Cell { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,14 +2,144 @@
|
|||||||
<!-- Generated with glade 3.22.1 -->
|
<!-- Generated with glade 3.22.1 -->
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk+" version="3.20"/>
|
<requires lib="gtk+" version="3.20"/>
|
||||||
<object class="GtkDialog" id="PlayerEditorDialog">
|
<object class="GtkAdjustment" id="DrinkVolAdjustment">
|
||||||
|
<property name="upper">100</property>
|
||||||
|
<property name="step_increment">0.10000000000000001</property>
|
||||||
|
<property name="page_increment">10</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkDialog" id="DrinkEditorDialog">
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Drink</property>
|
||||||
|
<property name="resizable">False</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<property name="window_position">center-on-parent</property>
|
||||||
|
<property name="destroy_with_parent">True</property>
|
||||||
|
<property name="type_hint">dialog</property>
|
||||||
|
<property name="gravity">center</property>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child internal-child="vbox">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">2</property>
|
||||||
|
<child internal-child="action_area">
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">end</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="SaveDrinkButton">
|
||||||
|
<property name="label">gtk-save</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
<accelerator key="Return" signal="clicked"/>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="CancelDrinkEditorButton">
|
||||||
|
<property name="label">gtk-cancel</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<property name="use_stock">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_top">10</property>
|
||||||
|
<property name="margin_bottom">10</property>
|
||||||
|
<property name="row_spacing">5</property>
|
||||||
|
<property name="column_spacing">7</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Name</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="label" translatable="yes">Vol. Alcohol</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">0</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="DrinkNameEntry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinButton" id="DinkVolEntry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="placeholder_text" translatable="yes">%</property>
|
||||||
|
<property name="input_purpose">number</property>
|
||||||
|
<property name="adjustment">DrinkVolAdjustment</property>
|
||||||
|
<property name="climb_rate">0.10000000000000001</property>
|
||||||
|
<property name="digits">1</property>
|
||||||
|
<property name="numeric">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<object class="GtkDialog" id="PlayerEditorDialog">
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="title" translatable="yes">Player</property>
|
||||||
<property name="resizable">False</property>
|
<property name="resizable">False</property>
|
||||||
<property name="modal">True</property>
|
<property name="modal">True</property>
|
||||||
<property name="window_position">center-on-parent</property>
|
<property name="window_position">center-on-parent</property>
|
||||||
<property name="destroy_with_parent">True</property>
|
<property name="destroy_with_parent">True</property>
|
||||||
<property name="type_hint">dialog</property>
|
<property name="type_hint">dialog</property>
|
||||||
<property name="deletable">False</property>
|
|
||||||
<property name="gravity">center</property>
|
<property name="gravity">center</property>
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
@@ -76,7 +206,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="label" translatable="yes">Name:</property>
|
<property name="label" translatable="yes">Name</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
@@ -88,7 +218,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="label" translatable="yes">Alias:</property>
|
<property name="label" translatable="yes">Alias</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
@@ -133,7 +263,7 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="halign">end</property>
|
<property name="halign">end</property>
|
||||||
<property name="label" translatable="yes">Hex ID:</property>
|
<property name="label" translatable="yes">Hex ID</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">0</property>
|
<property name="left_attach">0</property>
|
||||||
|
|||||||
63
EstusShots.Gtk/Dialogs/DrinkEditor.cs
Normal file
63
EstusShots.Gtk/Dialogs/DrinkEditor.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using EstusShots.Shared.Dto;
|
||||||
|
using Gtk;
|
||||||
|
using UI = Gtk.Builder.ObjectAttribute;
|
||||||
|
|
||||||
|
namespace EstusShots.Gtk.Dialogs
|
||||||
|
{
|
||||||
|
public class DrinkEditor
|
||||||
|
{
|
||||||
|
[UI] private readonly Dialog DrinkEditorDialog = null;
|
||||||
|
[UI] private readonly Entry DrinkNameEntry = null;
|
||||||
|
[UI] private readonly Adjustment DrinkVolAdjustment = null;
|
||||||
|
[UI] private readonly Button SaveDrinkButton = null;
|
||||||
|
[UI] private readonly Button CancelDrinkEditorButton = null;
|
||||||
|
|
||||||
|
private readonly Drink _drink;
|
||||||
|
|
||||||
|
public event DialogClosedEventHandler OnDialogClosed;
|
||||||
|
|
||||||
|
public DrinkEditor(Window parent, Drink drink)
|
||||||
|
{
|
||||||
|
_drink = drink;
|
||||||
|
|
||||||
|
var builder = new Builder("Dialogs.glade");
|
||||||
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
|
SaveDrinkButton.Clicked += SaveDrinkButtonOnClicked;
|
||||||
|
CancelDrinkEditorButton.Clicked += (sender, args) =>
|
||||||
|
{
|
||||||
|
OnDialogClosed?.Invoke(this, new DialogClosedEventArgs(false, null));
|
||||||
|
DrinkEditorDialog.Dispose();
|
||||||
|
};
|
||||||
|
|
||||||
|
ReadFromModel();
|
||||||
|
|
||||||
|
DrinkEditorDialog.TransientFor = parent;
|
||||||
|
DrinkEditorDialog.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events
|
||||||
|
|
||||||
|
private void SaveDrinkButtonOnClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ReadToModel();
|
||||||
|
OnDialogClosed?.Invoke(this, new DialogClosedEventArgs(true, _drink));
|
||||||
|
DrinkEditorDialog.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods
|
||||||
|
|
||||||
|
private void ReadToModel()
|
||||||
|
{
|
||||||
|
_drink.Name = DrinkNameEntry.Text;
|
||||||
|
_drink.Vol = DrinkVolAdjustment.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReadFromModel()
|
||||||
|
{
|
||||||
|
DrinkNameEntry.Text = _drink.Name;
|
||||||
|
DrinkVolAdjustment.Value = _drink.Vol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,11 +20,9 @@ namespace EstusShots.Gtk.Dialogs
|
|||||||
|
|
||||||
public class PlayerEditor
|
public class PlayerEditor
|
||||||
{
|
{
|
||||||
private Builder _builder;
|
private readonly Player _player;
|
||||||
private Player _player;
|
|
||||||
|
|
||||||
[UI] private readonly Dialog PlayerEditorDialog = null;
|
[UI] private readonly Dialog PlayerEditorDialog = null;
|
||||||
[UI] private readonly Overlay PlayerEditorOverlay = null;
|
|
||||||
[UI] private readonly Entry PlayerNameEntry = null;
|
[UI] private readonly Entry PlayerNameEntry = null;
|
||||||
[UI] private readonly Entry PlayerAliasEntry = null;
|
[UI] private readonly Entry PlayerAliasEntry = null;
|
||||||
[UI] private readonly Entry PlayerHexIdEntry = null;
|
[UI] private readonly Entry PlayerHexIdEntry = null;
|
||||||
@@ -38,8 +36,8 @@ namespace EstusShots.Gtk.Dialogs
|
|||||||
{
|
{
|
||||||
_player = player;
|
_player = player;
|
||||||
|
|
||||||
_builder = new Builder("Dialogs.glade");
|
var builder = new Builder("Dialogs.glade");
|
||||||
_builder.Autoconnect(this);
|
builder.Autoconnect(this);
|
||||||
|
|
||||||
SavePlayerButton.Clicked += SavePlayerButtonOnClicked;
|
SavePlayerButton.Clicked += SavePlayerButtonOnClicked;
|
||||||
CancelPlayerEditorButton.Clicked += (sender, args) =>
|
CancelPlayerEditorButton.Clicked += (sender, args) =>
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EstusShots.Client;
|
using EstusShots.Client;
|
||||||
using EstusShots.Gtk.Controls;
|
|
||||||
using EstusShots.Gtk.Dialogs;
|
using EstusShots.Gtk.Dialogs;
|
||||||
using EstusShots.Shared.Dto;
|
|
||||||
using EstusShots.Shared.Models;
|
|
||||||
using Gdk;
|
using Gdk;
|
||||||
using GLib;
|
using GLib;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
@@ -25,10 +21,7 @@ namespace EstusShots.Gtk
|
|||||||
[UI] public readonly Box LoadingSpinner = null;
|
[UI] public readonly Box LoadingSpinner = null;
|
||||||
[UI] public readonly Notebook Navigation = null;
|
[UI] public readonly Notebook Navigation = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private EstusShotsClient Client { get; }
|
private EstusShotsClient Client { get; }
|
||||||
private BindableListControl<Episode> EpisodesControl { get; set; }
|
|
||||||
|
|
||||||
public MainWindow() : this(new Builder("MainWindow.glade"))
|
public MainWindow() : this(new Builder("MainWindow.glade"))
|
||||||
{
|
{
|
||||||
@@ -48,17 +41,23 @@ namespace EstusShots.Gtk
|
|||||||
// Call initialization code of each page
|
// Call initialization code of each page
|
||||||
InitSeasonsPage();
|
InitSeasonsPage();
|
||||||
InitEpisodesPage();
|
InitEpisodesPage();
|
||||||
InitPlayersPage();
|
InitBaseDataPage();
|
||||||
|
|
||||||
CreateEpisodesControl();
|
|
||||||
|
|
||||||
// The episodes page is not shown, as long as no season is selected
|
// The episodes page is not shown, as long as no season is selected
|
||||||
EpisodesPage.Hide();
|
EpisodesPage.Hide();
|
||||||
|
|
||||||
|
Navigation.SwitchPage += NavigationOnSwitchPage;
|
||||||
|
|
||||||
Info("Application Started");
|
Info("Application Started");
|
||||||
UpdateTitle();
|
UpdateTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void NavigationOnSwitchPage(object o, SwitchPageArgs args)
|
||||||
|
{
|
||||||
|
if (!(args.Page is Box appPage)) return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void ExceptionManagerOnUnhandledException(UnhandledExceptionArgs args)
|
private void ExceptionManagerOnUnhandledException(UnhandledExceptionArgs args)
|
||||||
{
|
{
|
||||||
Console.WriteLine(args.ExceptionObject);
|
Console.WriteLine(args.ExceptionObject);
|
||||||
|
|||||||
@@ -136,6 +136,9 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="tab_expand">True</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child type="tab">
|
<child type="tab">
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
@@ -217,6 +220,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
|
<property name="tab_expand">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child type="tab">
|
<child type="tab">
|
||||||
@@ -231,7 +235,7 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox" id="EnemiesPage">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
@@ -256,6 +260,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
|
<property name="tab_expand">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child type="tab">
|
<child type="tab">
|
||||||
@@ -270,30 +275,105 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="PlayersPage">
|
<object class="GtkBox" id="BaseDataPage">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="margin_left">5</property>
|
||||||
|
<property name="margin_right">5</property>
|
||||||
|
<property name="margin_top">5</property>
|
||||||
|
<property name="margin_bottom">5</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkOverlay" id="PlayersOverlay">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="shadow_type">in</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkTreeView" id="PlayersTreeView">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">False</property>
|
||||||
<child internal-child="selection">
|
<property name="label" translatable="yes">Players:</property>
|
||||||
<object class="GtkTreeSelection"/>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
|
<property name="layout_style">start</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="NewPlayerButton">
|
||||||
|
<property name="label" translatable="yes">New Player</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="index">-1</property>
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkOverlay" id="PlayersOverlay">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="PlayersTreeView">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="enable_grid_lines">horizontal</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection"/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="index">-1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
@@ -303,18 +383,71 @@
|
|||||||
<property name="position">0</property>
|
<property name="position">0</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparator">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkBox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="margin_top">5</property>
|
<child>
|
||||||
<property name="margin_bottom">5</property>
|
<object class="GtkLabel">
|
||||||
<property name="label" translatable="yes">Edit Player</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="label" translatable="yes">Drinks:</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButtonBox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="layout_style">start</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="NewDrinkButton">
|
||||||
|
<property name="label" translatable="yes">New Drink</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="position">0</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -323,12 +456,28 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="PlayerEditorContainer">
|
<object class="GtkOverlay" id="DrinksOverlay">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="orientation">vertical</property>
|
|
||||||
<child>
|
<child>
|
||||||
<placeholder/>
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="DrinksTreeView">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="enable_grid_lines">horizontal</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection"/>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="index">-1</property>
|
||||||
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -337,55 +486,24 @@
|
|||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<object class="GtkButtonBox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="spacing">5</property>
|
|
||||||
<property name="layout_style">start</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="NewPlayerButton">
|
|
||||||
<property name="label" translatable="yes">New Player</property>
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="receives_default">True</property>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">True</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">0</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<placeholder/>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
<packing>
|
|
||||||
<property name="expand">False</property>
|
|
||||||
<property name="fill">True</property>
|
|
||||||
<property name="position">2</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">True</property>
|
||||||
<property name="fill">True</property>
|
<property name="fill">True</property>
|
||||||
<property name="position">1</property>
|
<property name="position">2</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
|
<property name="tab_expand">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child type="tab">
|
<child type="tab">
|
||||||
<object class="GtkLabel">
|
<object class="GtkLabel">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="label" translatable="yes">Players</property>
|
<property name="label" translatable="yes">Drinks & Players</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">3</property>
|
||||||
|
|||||||
141
EstusShots.Gtk/Pages/BaseDataPage.cs
Normal file
141
EstusShots.Gtk/Pages/BaseDataPage.cs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using EstusShots.Gtk.Controls;
|
||||||
|
using EstusShots.Gtk.Dialogs;
|
||||||
|
using EstusShots.Shared.Dto;
|
||||||
|
using EstusShots.Shared.Models.Parameters;
|
||||||
|
using Gtk;
|
||||||
|
using UI = Gtk.Builder.ObjectAttribute;
|
||||||
|
|
||||||
|
namespace EstusShots.Gtk
|
||||||
|
{
|
||||||
|
internal partial class MainWindow
|
||||||
|
{
|
||||||
|
[UI] public readonly Box BaseDataPage = null;
|
||||||
|
[UI] public readonly TreeView PlayersTreeView = null;
|
||||||
|
[UI] public readonly Button NewPlayerButton = null;
|
||||||
|
[UI] public readonly Button NewDrinkButton = null;
|
||||||
|
|
||||||
|
[UI] public readonly TreeView DrinksTreeView = null;
|
||||||
|
|
||||||
|
private BindableListControl<Player> _playersControl;
|
||||||
|
private BindableListControl<Drink> _drinksControl;
|
||||||
|
|
||||||
|
private void InitBaseDataPage()
|
||||||
|
{
|
||||||
|
NewPlayerButton.Clicked += NewPlayerButtonOnClicked;
|
||||||
|
NewDrinkButton.Clicked += NewDrinkButtonOnClicked;
|
||||||
|
|
||||||
|
var playerColumns = new List<DataColumn>
|
||||||
|
{
|
||||||
|
new DataColumnText(nameof(Player.Name)),
|
||||||
|
new DataColumnText(nameof(Player.Alias)),
|
||||||
|
new DataColumnBool(nameof(Player.Anonymous)) {Title = "Is Anonymous?", FixedWidth = 120},
|
||||||
|
new DataColumnText(nameof(Player.HexId)) {Title = "Hex ID"},
|
||||||
|
};
|
||||||
|
_playersControl = new BindableListControl<Player>(playerColumns, nameof(Player.PlayerId), PlayersTreeView);
|
||||||
|
_playersControl.OnSelectionChanged += PlayersControlOnOnSelectionChanged;
|
||||||
|
|
||||||
|
|
||||||
|
var drinkColumns = new List<DataColumn>
|
||||||
|
{
|
||||||
|
new DataColumnText(nameof(Drink.Name)),
|
||||||
|
new DataColumnDouble(nameof(Drink.Vol)) {Title = "%"}
|
||||||
|
};
|
||||||
|
_drinksControl = new BindableListControl<Drink>(drinkColumns, nameof(Drink.DrinkId), DrinksTreeView);
|
||||||
|
|
||||||
|
// TODO Only Load when navigated to
|
||||||
|
Task _;
|
||||||
|
_ = ReloadPlayers();
|
||||||
|
_ = ReloadDrinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Events
|
||||||
|
|
||||||
|
private void PlayersControlOnOnSelectionChanged(object o, SelectionChangedEventArgs args)
|
||||||
|
{
|
||||||
|
if (!(args.Selection is Player player)) return;
|
||||||
|
var dialog = new PlayerEditor(this, player);
|
||||||
|
dialog.OnDialogClosed += PlayerEditorClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewPlayerButtonOnClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var dialog = new PlayerEditor(this, new Player());
|
||||||
|
dialog.OnDialogClosed += PlayerEditorClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NewDrinkButtonOnClicked(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var dialog = new DrinkEditor(this, new Drink());
|
||||||
|
dialog.OnDialogClosed += DialogOnOnDialogClosed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void DialogOnOnDialogClosed(object o, DialogClosedEventArgs args)
|
||||||
|
{
|
||||||
|
if (!args.Ok || !(args.Model is Drink drink)) return;
|
||||||
|
|
||||||
|
var res = await Task.Factory.StartNew(()
|
||||||
|
=> Client.Drinks.SaveDrink(new SaveDrinkParameter(drink)).Result);
|
||||||
|
|
||||||
|
if (!res.OperationResult.Success)
|
||||||
|
{
|
||||||
|
Info($"Unable to save: {res.OperationResult.ShortMessage}");
|
||||||
|
ErrorDialog.Show(res.OperationResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ReloadDrinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void PlayerEditorClosed(object o, DialogClosedEventArgs args)
|
||||||
|
{
|
||||||
|
if (!args.Ok || !(args.Model is Player player)) return;
|
||||||
|
var res = await Task.Factory.StartNew(()
|
||||||
|
=> Client.Players.SavePlayer(new SavePlayerParameter(player)).Result);
|
||||||
|
if (!res.OperationResult.Success)
|
||||||
|
{
|
||||||
|
Info($"Unable to save: {res.OperationResult.ShortMessage}");
|
||||||
|
ErrorDialog.Show(res.OperationResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await ReloadPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods
|
||||||
|
|
||||||
|
private async Task ReloadPlayers()
|
||||||
|
{
|
||||||
|
var res = await Task.Factory.StartNew(()
|
||||||
|
=> Client.Players.GetPlayers(new GetPlayersParameter()).Result);
|
||||||
|
if (!res.OperationResult.Success)
|
||||||
|
{
|
||||||
|
InfoLabel.Text = $"Refresh failed: {res.OperationResult.ShortMessage}";
|
||||||
|
ErrorDialog.Show(res.OperationResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_playersControl.Items = res.Data.Players;
|
||||||
|
_playersControl.DataBind();
|
||||||
|
Info("Player list refreshed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ReloadDrinks()
|
||||||
|
{
|
||||||
|
var res = await Task.Factory.StartNew(()
|
||||||
|
=> Client.Drinks.GetDrinks(new GetDrinksParameter()).Result);
|
||||||
|
if (!res.OperationResult.Success)
|
||||||
|
{
|
||||||
|
InfoLabel.Text = $"Refresh failed: {res.OperationResult.ShortMessage}";
|
||||||
|
ErrorDialog.Show(res.OperationResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_drinksControl.Items = res.Data.Drinks;
|
||||||
|
_drinksControl.DataBind();
|
||||||
|
Info("Drink list refreshed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,16 +14,20 @@ namespace EstusShots.Gtk
|
|||||||
{
|
{
|
||||||
[UI] public readonly Box EpisodesPage = null;
|
[UI] public readonly Box EpisodesPage = null;
|
||||||
[UI] public readonly Button AddEpisodeButton = null;
|
[UI] public readonly Button AddEpisodeButton = null;
|
||||||
[UI] public readonly Overlay EpisodesOverlay = null;
|
|
||||||
[UI] public readonly TreeView EpisodesTreeView = null;
|
[UI] public readonly TreeView EpisodesTreeView = null;
|
||||||
|
|
||||||
|
private BindableListControl<Episode> EpisodesControl { get; set; }
|
||||||
|
|
||||||
|
|
||||||
private void InitEpisodesPage()
|
private void InitEpisodesPage()
|
||||||
{
|
{
|
||||||
AddEpisodeButton.Clicked += AddEpisodeButtonOnClicked;
|
AddEpisodeButton.Clicked += AddEpisodeButtonOnClicked;
|
||||||
|
|
||||||
|
CreateEpisodesControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eevents
|
// Events
|
||||||
|
|
||||||
private async void AddEpisodeButtonOnClicked(object sender, EventArgs e)
|
private async void AddEpisodeButtonOnClicked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (SeasonsControl.SelectedItem == null) return;
|
if (SeasonsControl.SelectedItem == null) return;
|
||||||
@@ -64,9 +68,9 @@ namespace EstusShots.Gtk
|
|||||||
|
|
||||||
await ReloadEpisodes();
|
await ReloadEpisodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private Methods
|
// Private Methods
|
||||||
|
|
||||||
private async Task ReloadEpisodes()
|
private async Task ReloadEpisodes()
|
||||||
{
|
{
|
||||||
var seasonId = SeasonsControl.SelectedItem.SeasonId;
|
var seasonId = SeasonsControl.SelectedItem.SeasonId;
|
||||||
@@ -82,27 +86,27 @@ namespace EstusShots.Gtk
|
|||||||
EpisodesControl.DataBind();
|
EpisodesControl.DataBind();
|
||||||
Info("Episodes Refreshed");
|
Info("Episodes Refreshed");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateEpisodesControl()
|
private void CreateEpisodesControl()
|
||||||
{
|
{
|
||||||
var columns = new List<DataColumn>
|
var columns = new List<DataColumn>
|
||||||
{
|
{
|
||||||
new DataColumn(nameof(Episode.DisplayName)) {Title = "Name"},
|
new DataColumnText(nameof(Episode.DisplayName)) {Title = "Name"},
|
||||||
new DataColumn(nameof(Episode.Title)) {Title = "Title"},
|
new DataColumnText(nameof(Episode.Title)) {Title = "Title"},
|
||||||
new DataColumn(nameof(Episode.Date))
|
new DataColumnText(nameof(Episode.Date))
|
||||||
{
|
{
|
||||||
Title = "Date",
|
Title = "Date",
|
||||||
Format = d => (d as DateTime?)?.ToString("dd.MM.yyyy")
|
DisplayConverter = d => (d as DateTime?)?.ToString("dd.MM.yyyy")
|
||||||
},
|
},
|
||||||
new DataColumn(nameof(Episode.Start))
|
new DataColumnText(nameof(Episode.Start))
|
||||||
{
|
{
|
||||||
Title = "Start",
|
Title = "Start",
|
||||||
Format = d => (d as DateTime?)?.ToString("HH:mm")
|
DisplayConverter = d => (d as DateTime?)?.ToString("HH:mm")
|
||||||
},
|
},
|
||||||
new DataColumn(nameof(Episode.End))
|
new DataColumnText(nameof(Episode.End))
|
||||||
{
|
{
|
||||||
Title = "End",
|
Title = "End",
|
||||||
Format = d => (d as DateTime?)?.ToString("HH:mm") ?? "Ongoing"
|
DisplayConverter = d => (d as DateTime?)?.ToString("HH:mm") ?? "Ongoing"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
EpisodesControl = new BindableListControl<Episode>(columns, nameof(Episode.EpisodeId), EpisodesTreeView);
|
EpisodesControl = new BindableListControl<Episode>(columns, nameof(Episode.EpisodeId), EpisodesTreeView);
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using EstusShots.Gtk.Controls;
|
|
||||||
using EstusShots.Gtk.Dialogs;
|
|
||||||
using EstusShots.Shared.Dto;
|
|
||||||
using EstusShots.Shared.Models.Parameters;
|
|
||||||
using Gtk;
|
|
||||||
using UI = Gtk.Builder.ObjectAttribute;
|
|
||||||
|
|
||||||
namespace EstusShots.Gtk
|
|
||||||
{
|
|
||||||
internal partial class MainWindow
|
|
||||||
{
|
|
||||||
[UI] public readonly Box PlayersPage = null;
|
|
||||||
[UI] public readonly Overlay PlayersOverlay = null;
|
|
||||||
[UI] public readonly TreeView PlayersTreeView = null;
|
|
||||||
[UI] public readonly Button NewPlayerButton = null;
|
|
||||||
[UI] public readonly Box PlayerEditorContainer = null;
|
|
||||||
|
|
||||||
private BindableListControl<Player> PlayersControl;
|
|
||||||
|
|
||||||
private void InitPlayersPage()
|
|
||||||
{
|
|
||||||
NewPlayerButton.Clicked += NewPlayerButtonOnClicked;
|
|
||||||
|
|
||||||
var columns = new List<DataColumn>
|
|
||||||
{
|
|
||||||
new DataColumn(nameof(Player.Name)),
|
|
||||||
new DataColumn(nameof(Player.Alias)),
|
|
||||||
new DataColumn(nameof(Player.Anonymous)) {Title = "Is Anonymous?", FixedWidth = 120},
|
|
||||||
new DataColumn(nameof(Player.HexId)) {Title = "Hex ID"},
|
|
||||||
};
|
|
||||||
PlayersControl = new BindableListControl<Player>(columns, nameof(Player.PlayerId), PlayersTreeView);
|
|
||||||
PlayersControl.OnSelectionChanged += PlayersControlOnOnSelectionChanged;
|
|
||||||
|
|
||||||
Task.Factory.StartNew(ReloadPlayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Events
|
|
||||||
|
|
||||||
private void PlayersControlOnOnSelectionChanged(object o, SelectionChangedEventArgs args)
|
|
||||||
{
|
|
||||||
if (!(args.Selection is Player player)) return;
|
|
||||||
var dialog = new PlayerEditor(this, player);
|
|
||||||
dialog.OnDialogClosed += PlayerEditorClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void NewPlayerButtonOnClicked(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
var dialog = new PlayerEditor(this, new Player());
|
|
||||||
dialog.OnDialogClosed += PlayerEditorClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void PlayerEditorClosed(object o, DialogClosedEventArgs args)
|
|
||||||
{
|
|
||||||
if (!args.Ok || !(args.Model is Player player)) return;
|
|
||||||
var res = await Task.Factory.StartNew(()
|
|
||||||
=> Client.Players.SavePlayer(new SavePlayerParameter(player)).Result);
|
|
||||||
if (!res.OperationResult.Success)
|
|
||||||
{
|
|
||||||
Info($"Unable to save: {res.OperationResult.ShortMessage}");
|
|
||||||
ErrorDialog.Show(res.OperationResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await ReloadPlayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
private async Task ReloadPlayers()
|
|
||||||
{
|
|
||||||
var res = await Task.Factory.StartNew(()
|
|
||||||
=> Client.Players.GetPlayers(new GetPlayersParameter()).Result);
|
|
||||||
if (!res.OperationResult.Success)
|
|
||||||
{
|
|
||||||
InfoLabel.Text = $"Refresh failed: {res.OperationResult.ShortMessage}";
|
|
||||||
ErrorDialog.Show(res.OperationResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayersControl.Items = res.Data.Players;
|
|
||||||
PlayersControl.DataBind();
|
|
||||||
Info("Player list refreshed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,7 @@ namespace EstusShots.Gtk
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
private async void LoadButtonClicked(object sender, EventArgs a)
|
private async void LoadButtonClicked(object sender, EventArgs a)
|
||||||
{
|
{
|
||||||
using var _ = new LoadingMode(this);
|
using var _ = new LoadingMode(this);
|
||||||
@@ -63,7 +63,7 @@ namespace EstusShots.Gtk
|
|||||||
await ReloadSeasons();
|
await ReloadSeasons();
|
||||||
Info("Created new Season");
|
Info("Created new Season");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SeasonsControlOnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
private async void SeasonsControlOnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!(e.Selection is Season season)) return;
|
if (!(e.Selection is Season season)) return;
|
||||||
@@ -82,7 +82,7 @@ namespace EstusShots.Gtk
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Private Methods
|
// Private Methods
|
||||||
|
|
||||||
private async Task ReloadSeasons()
|
private async Task ReloadSeasons()
|
||||||
{
|
{
|
||||||
var res = await Task.Factory.StartNew(
|
var res = await Task.Factory.StartNew(
|
||||||
@@ -103,22 +103,19 @@ namespace EstusShots.Gtk
|
|||||||
{
|
{
|
||||||
var columns = new List<DataColumn>
|
var columns = new List<DataColumn>
|
||||||
{
|
{
|
||||||
new DataColumn(nameof(Season.DisplayName)) {Title = "Name"},
|
new DataColumnText(nameof(Season.DisplayName)) {Title = "Name"},
|
||||||
new DataColumn(nameof(Season.Description)) {Title = "Description"},
|
new DataColumnText(nameof(Season.Description)),
|
||||||
new DataColumn(nameof(Season.Start))
|
new DataColumnText(nameof(Season.Start))
|
||||||
{
|
{
|
||||||
Title = "Start",
|
DisplayConverter = date => (date as DateTime?)?.ToString("dd.MM.yyyy")
|
||||||
Format = date => (date as DateTime?)?.ToString("dd.MM.yyyy")
|
|
||||||
},
|
},
|
||||||
new DataColumn(nameof(Season.End))
|
new DataColumnText(nameof(Season.End))
|
||||||
{
|
{
|
||||||
Title = "End",
|
DisplayConverter = date => (date as DateTime?)?.ToString("dd.MM.yyyy") ?? "Ongoing"
|
||||||
Format = date => (date as DateTime?)?.ToString("dd.MM.yyyy") ?? "Ongoing"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
SeasonsControl = new BindableListControl<Season>(columns, nameof(Season.SeasonId), SeasonsView);
|
SeasonsControl = new BindableListControl<Season>(columns, nameof(Season.SeasonId), SeasonsView);
|
||||||
SeasonsControl.OnSelectionChanged += SeasonsControlOnSelectionChanged;
|
SeasonsControl.OnSelectionChanged += SeasonsControlOnSelectionChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace EstusShots.Server.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ApiResponse<DeletePlayerResponse>> DeletePlayers(DeletePlayerParameter parameter)
|
public Task<ApiResponse<DeletePlayerResponse>> DeletePlayers(DeletePlayerParameter parameter)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user