Ionite
1 year ago
9 changed files with 967 additions and 341 deletions
@ -0,0 +1,408 @@
|
||||
// Modified from https://github.com/AvaloniaUI/AvaloniaAutoGrid |
||||
/*The MIT License (MIT) |
||||
|
||||
Copyright (c) 2013 Charles Brown (carbonrobot) |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of |
||||
this software and associated documentation files (the "Software"), to deal in |
||||
the Software without restriction, including without limitation the rights to |
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
||||
the Software, and to permit persons to whom the Software is furnished to do so, |
||||
subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/ |
||||
|
||||
using System; |
||||
using System.ComponentModel; |
||||
using System.Diagnostics.CodeAnalysis; |
||||
using System.Linq; |
||||
using Avalonia; |
||||
using Avalonia.Controls; |
||||
using Avalonia.Data; |
||||
using Avalonia.Layout; |
||||
|
||||
namespace StabilityMatrix.Avalonia.Controls; |
||||
|
||||
/// <summary> |
||||
/// Defines a flexible grid area that consists of columns and rows. |
||||
/// Depending on the orientation, either the rows or the columns are auto-generated, |
||||
/// and the children's position is set according to their index. |
||||
/// </summary> |
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] |
||||
public class AutoGrid : Grid |
||||
{ |
||||
/// <summary> |
||||
/// Gets or sets the child horizontal alignment. |
||||
/// </summary> |
||||
/// <value>The child horizontal alignment.</value> |
||||
[Category("Layout"), Description("Presets the horizontal alignment of all child controls")] |
||||
public HorizontalAlignment? ChildHorizontalAlignment |
||||
{ |
||||
get => (HorizontalAlignment?)GetValue(ChildHorizontalAlignmentProperty); |
||||
set => SetValue(ChildHorizontalAlignmentProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the child margin. |
||||
/// </summary> |
||||
/// <value>The child margin.</value> |
||||
[Category("Layout"), Description("Presets the margin of all child controls")] |
||||
public Thickness? ChildMargin |
||||
{ |
||||
get => (Thickness?)GetValue(ChildMarginProperty); |
||||
set => SetValue(ChildMarginProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the child vertical alignment. |
||||
/// </summary> |
||||
/// <value>The child vertical alignment.</value> |
||||
[Category("Layout"), Description("Presets the vertical alignment of all child controls")] |
||||
public VerticalAlignment? ChildVerticalAlignment |
||||
{ |
||||
get => (VerticalAlignment?)GetValue(ChildVerticalAlignmentProperty); |
||||
set => SetValue(ChildVerticalAlignmentProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the column count |
||||
/// </summary> |
||||
[Category("Layout"), Description("Defines a set number of columns")] |
||||
public int ColumnCount |
||||
{ |
||||
get => (int)GetValue(ColumnCountProperty)!; |
||||
set => SetValue(ColumnCountProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the fixed column width |
||||
/// </summary> |
||||
[Category("Layout"), Description("Presets the width of all columns set using the ColumnCount property")] |
||||
|
||||
public GridLength ColumnWidth |
||||
{ |
||||
get => (GridLength)GetValue(ColumnWidthProperty)!; |
||||
set => SetValue(ColumnWidthProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets a value indicating whether the children are automatically indexed. |
||||
/// <remarks> |
||||
/// The default is <c>true</c>. |
||||
/// Note that if children are already indexed, setting this property to <c>false</c> will not remove their indices. |
||||
/// </remarks> |
||||
/// </summary> |
||||
[Category("Layout"), Description("Set to false to disable the auto layout functionality")] |
||||
public bool IsAutoIndexing |
||||
{ |
||||
get => (bool)GetValue(IsAutoIndexingProperty)!; |
||||
set => SetValue(IsAutoIndexingProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the orientation. |
||||
/// <remarks>The default is Vertical.</remarks> |
||||
/// </summary> |
||||
/// <value>The orientation.</value> |
||||
[Category("Layout"), Description("Defines the directionality of the autolayout. Use vertical for a column first layout, horizontal for a row first layout.")] |
||||
public Orientation Orientation |
||||
{ |
||||
get => (Orientation)GetValue(OrientationProperty)!; |
||||
set => SetValue(OrientationProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the number of rows |
||||
/// </summary> |
||||
[Category("Layout"), Description("Defines a set number of rows")] |
||||
public int RowCount |
||||
{ |
||||
get => (int)GetValue(RowCountProperty)!; |
||||
set => SetValue(RowCountProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Gets or sets the fixed row height |
||||
/// </summary> |
||||
[Category("Layout"), Description("Presets the height of all rows set using the RowCount property")] |
||||
public GridLength RowHeight |
||||
{ |
||||
get => (GridLength)GetValue(RowHeightProperty)!; |
||||
set => SetValue(RowHeightProperty, value); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles the column count changed event |
||||
/// </summary> |
||||
public static void ColumnCountChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
if ((int)e.NewValue! < 0) |
||||
return; |
||||
|
||||
var grid = (AutoGrid)e.Sender; |
||||
|
||||
|
||||
// look for an existing column definition for the height |
||||
var width = grid.ColumnWidth; |
||||
if (!grid.IsSet(ColumnWidthProperty) && grid.ColumnDefinitions.Count > 0) |
||||
width = grid.ColumnDefinitions[0].Width; |
||||
|
||||
// clear and rebuild |
||||
grid.ColumnDefinitions.Clear(); |
||||
for (var i = 0; i < (int)e.NewValue; i++) |
||||
grid.ColumnDefinitions.Add( |
||||
new ColumnDefinition() { Width = width }); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handle the fixed column width changed event |
||||
/// </summary> |
||||
public static void FixedColumnWidthChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
var grid = (AutoGrid)e.Sender; |
||||
|
||||
// add a default column if missing |
||||
if (grid.ColumnDefinitions.Count == 0) |
||||
grid.ColumnDefinitions.Add(new ColumnDefinition()); |
||||
|
||||
// set all existing columns to this width |
||||
foreach (var t in grid.ColumnDefinitions) |
||||
t.Width = (GridLength)e.NewValue!; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handle the fixed row height changed event |
||||
/// </summary> |
||||
public static void FixedRowHeightChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
var grid = (AutoGrid)e.Sender; |
||||
|
||||
// add a default row if missing |
||||
if (grid.RowDefinitions.Count == 0) |
||||
grid.RowDefinitions.Add(new RowDefinition()); |
||||
|
||||
// set all existing rows to this height |
||||
foreach (var t in grid.RowDefinitions) |
||||
t.Height = (GridLength)e.NewValue!; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Handles the row count changed event |
||||
/// </summary> |
||||
public static void RowCountChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
if ((int)e.NewValue! < 0) |
||||
return; |
||||
|
||||
var grid = (AutoGrid)e.Sender; |
||||
|
||||
// look for an existing row to get the height |
||||
var height = grid.RowHeight; |
||||
if (!grid.IsSet(RowHeightProperty) && grid.RowDefinitions.Count > 0) |
||||
height = grid.RowDefinitions[0].Height; |
||||
|
||||
// clear and rebuild |
||||
grid.RowDefinitions.Clear(); |
||||
for (var i = 0; i < (int)e.NewValue; i++) |
||||
grid.RowDefinitions.Add( |
||||
new RowDefinition() { Height = height }); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Called when [child horizontal alignment changed]. |
||||
/// </summary> |
||||
private static void OnChildHorizontalAlignmentChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
var grid = (AutoGrid)e.Sender; |
||||
foreach (var child in grid.Children) |
||||
{ |
||||
child.SetValue(HorizontalAlignmentProperty, |
||||
grid.ChildHorizontalAlignment ?? AvaloniaProperty.UnsetValue); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Called when [child layout changed]. |
||||
/// </summary> |
||||
private static void OnChildMarginChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
var grid = (AutoGrid)e.Sender; |
||||
foreach (var child in grid.Children) |
||||
{ |
||||
child.SetValue(MarginProperty, grid.ChildMargin ?? AvaloniaProperty.UnsetValue); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Called when [child vertical alignment changed]. |
||||
/// </summary> |
||||
private static void OnChildVerticalAlignmentChanged(AvaloniaPropertyChangedEventArgs e) |
||||
{ |
||||
var grid = (AutoGrid)e.Sender; |
||||
foreach (var child in grid.Children) |
||||
{ |
||||
child.SetValue(VerticalAlignmentProperty, grid.ChildVerticalAlignment ?? AvaloniaProperty.UnsetValue); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Apply child margins and layout effects such as alignment |
||||
/// </summary> |
||||
private void ApplyChildLayout(Control child) |
||||
{ |
||||
if (ChildMargin != null) |
||||
{ |
||||
child.SetValue(MarginProperty, ChildMargin.Value, BindingPriority.Template); |
||||
} |
||||
if (ChildHorizontalAlignment != null) |
||||
{ |
||||
child.SetValue(HorizontalAlignmentProperty, ChildHorizontalAlignment.Value, BindingPriority.Template); |
||||
} |
||||
if (ChildVerticalAlignment != null) |
||||
{ |
||||
child.SetValue(VerticalAlignmentProperty, ChildVerticalAlignment.Value, BindingPriority.Template); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Clamp a value to its maximum. |
||||
/// </summary> |
||||
private int Clamp(int value, int max) |
||||
{ |
||||
return (value > max) ? max : value; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Perform the grid layout of row and column indexes |
||||
/// </summary> |
||||
private void PerformLayout() |
||||
{ |
||||
var fillRowFirst = Orientation == Orientation.Horizontal; |
||||
var rowCount = RowDefinitions.Count; |
||||
var colCount = ColumnDefinitions.Count; |
||||
|
||||
if (rowCount == 0 || colCount == 0) |
||||
return; |
||||
|
||||
var position = 0; |
||||
var skip = new bool[rowCount, colCount]; |
||||
foreach (var child in Children.OfType<Control>()) |
||||
{ |
||||
var childIsCollapsed = !child.IsVisible; |
||||
if (IsAutoIndexing && !childIsCollapsed) |
||||
{ |
||||
if (fillRowFirst) |
||||
{ |
||||
var row = Clamp(position / colCount, rowCount - 1); |
||||
var col = Clamp(position % colCount, colCount - 1); |
||||
if (skip[row, col]) |
||||
{ |
||||
position++; |
||||
row = (position / colCount); |
||||
col = (position % colCount); |
||||
} |
||||
|
||||
SetRow(child, row); |
||||
SetColumn(child, col); |
||||
position += GetColumnSpan(child); |
||||
|
||||
var offset = GetRowSpan(child) - 1; |
||||
while (offset > 0) |
||||
{ |
||||
skip[row + offset--, col] = true; |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
var row = Clamp(position % rowCount, rowCount - 1); |
||||
var col = Clamp(position / rowCount, colCount - 1); |
||||
if (skip[row, col]) |
||||
{ |
||||
position++; |
||||
row = position % rowCount; |
||||
col = position / rowCount; |
||||
} |
||||
|
||||
SetRow(child, row); |
||||
SetColumn(child, col); |
||||
position += GetRowSpan(child); |
||||
|
||||
var offset = GetColumnSpan(child) - 1; |
||||
while (offset > 0) |
||||
{ |
||||
skip[row, col + offset--] = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
ApplyChildLayout(child); |
||||
} |
||||
} |
||||
|
||||
public static readonly AvaloniaProperty<HorizontalAlignment?> ChildHorizontalAlignmentProperty = |
||||
AvaloniaProperty.Register<AutoGrid, HorizontalAlignment?>("ChildHorizontalAlignment"); |
||||
|
||||
public static readonly AvaloniaProperty<Thickness?> ChildMarginProperty = |
||||
AvaloniaProperty.Register<AutoGrid, Thickness?>("ChildMargin"); |
||||
|
||||
public static readonly AvaloniaProperty<VerticalAlignment?> ChildVerticalAlignmentProperty = |
||||
AvaloniaProperty.Register<AutoGrid, VerticalAlignment?>("ChildVerticalAlignment"); |
||||
|
||||
public static readonly AvaloniaProperty<int> ColumnCountProperty = |
||||
AvaloniaProperty.RegisterAttached<Control, int>("ColumnCount", typeof(AutoGrid), 1); |
||||
|
||||
public static readonly AvaloniaProperty<GridLength> ColumnWidthProperty = |
||||
AvaloniaProperty.RegisterAttached<Control, GridLength>("ColumnWidth", typeof(AutoGrid), GridLength.Auto); |
||||
|
||||
public static readonly AvaloniaProperty<bool> IsAutoIndexingProperty = |
||||
AvaloniaProperty.Register<AutoGrid, bool>("IsAutoIndexing", true); |
||||
|
||||
public static readonly AvaloniaProperty<Orientation> OrientationProperty = |
||||
AvaloniaProperty.Register<AutoGrid, Orientation>("Orientation", Orientation.Vertical); |
||||
|
||||
public static readonly AvaloniaProperty<int> RowCountProperty = |
||||
AvaloniaProperty.RegisterAttached<Control, int>("RowCount", typeof(AutoGrid), 1); |
||||
|
||||
public static readonly AvaloniaProperty<GridLength> RowHeightProperty = |
||||
AvaloniaProperty.RegisterAttached<Control, GridLength>("RowHeight", typeof(AutoGrid), GridLength.Auto); |
||||
|
||||
static AutoGrid() |
||||
{ |
||||
AffectsMeasure<AutoGrid>(ChildHorizontalAlignmentProperty, ChildMarginProperty, |
||||
ChildVerticalAlignmentProperty, ColumnCountProperty, ColumnWidthProperty, IsAutoIndexingProperty, OrientationProperty, |
||||
RowHeightProperty); |
||||
|
||||
ChildHorizontalAlignmentProperty.Changed.Subscribe(OnChildHorizontalAlignmentChanged); |
||||
ChildMarginProperty.Changed.Subscribe(OnChildMarginChanged); |
||||
ChildVerticalAlignmentProperty.Changed.Subscribe(OnChildVerticalAlignmentChanged); |
||||
ColumnCountProperty.Changed.Subscribe(ColumnCountChanged); |
||||
RowCountProperty.Changed.Subscribe(RowCountChanged); |
||||
ColumnWidthProperty.Changed.Subscribe(FixedColumnWidthChanged); |
||||
RowHeightProperty.Changed.Subscribe(FixedRowHeightChanged); |
||||
} |
||||
|
||||
#region Overrides |
||||
|
||||
/// <summary> |
||||
/// Measures the children of a <see cref="T:System.Windows.Controls.Grid"/> in anticipation of arranging them during the <see cref="M:ArrangeOverride"/> pass. |
||||
/// </summary> |
||||
/// <param name="constraint">Indicates an upper limit size that should not be exceeded.</param> |
||||
/// <returns> |
||||
/// <see cref="Size"/> that represents the required size to arrange child content. |
||||
/// </returns> |
||||
protected override Size MeasureOverride(Size constraint) |
||||
{ |
||||
PerformLayout(); |
||||
return base.MeasureOverride(constraint); |
||||
} |
||||
|
||||
#endregion Overrides |
||||
} |
@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic; |
||||
using System.Collections.Immutable; |
||||
using System.Diagnostics.CodeAnalysis; |
||||
using System.Globalization; |
||||
|
||||
namespace StabilityMatrix.Avalonia.Languages; |
||||
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] |
||||
public static class Cultures |
||||
{ |
||||
public static CultureInfo Default { get; } = new("en-US"); |
||||
|
||||
public static CultureInfo Current => Resources.Culture; |
||||
|
||||
public static readonly Dictionary<string, CultureInfo> SupportedCulturesByCode = |
||||
new Dictionary<string, CultureInfo> |
||||
{ |
||||
["en-US"] = Default, |
||||
["ja-JP"] = new("ja-JP") |
||||
}; |
||||
|
||||
public static IReadOnlyList<CultureInfo> SupportedCultures |
||||
=> SupportedCulturesByCode.Values.ToImmutableList(); |
||||
|
||||
public static CultureInfo GetSupportedCultureOrDefault(string? cultureCode) |
||||
{ |
||||
if (cultureCode is null |
||||
|| !SupportedCulturesByCode.TryGetValue(cultureCode, out var culture)) |
||||
{ |
||||
return Default; |
||||
} |
||||
|
||||
return culture; |
||||
} |
||||
|
||||
public static bool TrySetSupportedCulture(string? cultureCode) |
||||
{ |
||||
if (cultureCode is null |
||||
|| !SupportedCulturesByCode.TryGetValue(cultureCode, out var culture)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
Resources.Culture = culture; |
||||
return true; |
||||
} |
||||
|
||||
public static bool TrySetSupportedCulture(CultureInfo? cultureInfo) |
||||
{ |
||||
return cultureInfo is not null && TrySetSupportedCulture(cultureInfo.Name); |
||||
} |
||||
} |
@ -0,0 +1,23 @@
|
||||
<root> |
||||
<resheader name="resmimetype"> |
||||
<value>text/microsoft-resx</value> |
||||
</resheader> |
||||
<resheader name="version"> |
||||
<value>1.3</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<data name="Action_Save" xml:space="preserve"> |
||||
<value>保存</value> |
||||
</data> |
||||
<data name="Action_Cancel" xml:space="preserve"> |
||||
<value>戻る</value> |
||||
</data> |
||||
<data name="Label_Language" xml:space="preserve"> |
||||
<value>言語</value> |
||||
</data> |
||||
</root> |
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?> |
||||
|
||||
<root> |
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
||||
</xsd:element> |
||||
</xsd:schema> |
||||
<resheader name="resmimetype"> |
||||
<value>text/microsoft-resx</value> |
||||
</resheader> |
||||
<resheader name="version"> |
||||
<value>1.3</value> |
||||
</resheader> |
||||
<resheader name="reader"> |
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<resheader name="writer"> |
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
</resheader> |
||||
<data name="Action_Launch" xml:space="preserve"> |
||||
<value>Launch</value> |
||||
</data> |
||||
<data name="Action_Quit" xml:space="preserve"> |
||||
<value>Quit</value> |
||||
</data> |
||||
<data name="Action_Save" xml:space="preserve"> |
||||
<value>Save</value> |
||||
</data> |
||||
<data name="Action_Cancel" xml:space="preserve"> |
||||
<value>Cancel</value> |
||||
</data> |
||||
<data name="Label_Language" xml:space="preserve"> |
||||
<value>Language</value> |
||||
</data> |
||||
<data name="Text_RelaunchRequiredToApplyLanguage" xml:space="preserve"> |
||||
<value>Relaunch is required for new language option to take effect</value> |
||||
</data> |
||||
<data name="Action_Relaunch" xml:space="preserve"> |
||||
<value>Relaunch</value> |
||||
</data> |
||||
<data name="Action_RelaunchLater" xml:space="preserve"> |
||||
<value>Relaunch Later</value> |
||||
</data> |
||||
<data name="Label_RelaunchRequired" xml:space="preserve"> |
||||
<value>Relaunch Required</value> |
||||
</data> |
||||
</root> |
@ -1,342 +1,368 @@
|
||||
<controls:UserControlBase xmlns="https://github.com/avaloniaui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels" |
||||
xmlns:ui="using:FluentAvalonia.UI.Controls" |
||||
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" |
||||
xmlns:avalonia="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia" |
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="700" |
||||
x:DataType="vm:SettingsViewModel" |
||||
x:CompileBindings="True" |
||||
d:DataContext="{x:Static mocks:DesignData.SettingsViewModel}" |
||||
x:Class="StabilityMatrix.Avalonia.Views.SettingsPage"> |
||||
|
||||
<Grid> |
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"> |
||||
<Grid RowDefinitions="Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto" |
||||
Margin="8, 16"> |
||||
<!-- Theme --> |
||||
<Grid Grid.Row="0" RowDefinitions="auto,*"> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="Appearance" |
||||
Margin="0,0,0,8" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Header="Theme" |
||||
IconSource="WeatherMoon" |
||||
Margin="8,0,8,4"> |
||||
<ui:SettingsExpander.Footer> |
||||
<ComboBox |
||||
ItemsSource="{Binding AvailableThemes}" |
||||
SelectedItem="{Binding SelectedTheme}" |
||||
MinWidth="100"/> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- TODO: Text2Image host port settings --> |
||||
|
||||
<!-- Checkpoints Manager Options --> |
||||
<Grid Grid.Row="1" Margin="0,8,0,0" RowDefinitions="auto,*,Auto"> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="Checkpoint Manager" |
||||
Margin="0,0,0,8" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
IconSource="Folder" |
||||
Header="Remove shared checkpoints directory symbolic links on shutdown" |
||||
Description="Select this option if you're having problems moving Stability Matrix to another drive" |
||||
Margin="8,0"> |
||||
<ui:SettingsExpander.Footer> |
||||
<CheckBox Margin="8" |
||||
IsChecked="{Binding RemoveSymlinksOnShutdown}"/> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
<ui:SettingsExpander |
||||
Grid.Row="2" |
||||
IconSource="Refresh" |
||||
Header="Reset Checkpoints Cache" |
||||
Description="Rebuilds the installed checkpoints cache. Use if checkpoints are incorrectly labeled in the Model Browser." |
||||
Margin="8, 4"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Command="{Binding ResetCheckpointCache}" |
||||
Content="Reset Checkpoints Cache"/> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- Environment Options --> |
||||
<Grid Grid.Row="2" Margin="0,8,0,0" RowDefinitions="Auto, Auto, Auto"> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="Package Environment" |
||||
Margin="0,0,0,8" /> |
||||
|
||||
<ui:SettingsExpander Grid.Row="1" |
||||
Header="Environment Variables" |
||||
IconSource="OtherUser" |
||||
Margin="8,0"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Content="Edit" |
||||
Command="{Binding OpenEnvVarsDialogCommand}"/> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
|
||||
<ui:SettingsExpander Grid.Row="2" |
||||
Header="Embedded Python" |
||||
Margin="8,4"> |
||||
<ui:SettingsExpander.IconSource> |
||||
<controls:FASymbolIconSource Symbol="fa-brands fa-python"/> |
||||
</ui:SettingsExpander.IconSource> |
||||
<ui:SettingsExpander.Footer> |
||||
<StackPanel Orientation="Horizontal" Spacing="16"> |
||||
<controls:ProgressRing |
||||
IsEnabled="{Binding CheckPythonVersionCommand.IsRunning}" |
||||
IsVisible="{Binding CheckPythonVersionCommand.IsRunning}" |
||||
IsIndeterminate="True" |
||||
BorderThickness="3"/> |
||||
<Button Content="Check Version" Command="{Binding CheckPythonVersionCommand}"/> |
||||
</StackPanel> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- Integrations --> |
||||
<Grid Grid.Row="3" Margin="0,8,0,0" RowDefinitions="auto,*"> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="Integrations" |
||||
Margin="0,0,0,8" /> |
||||
<ui:SettingsExpander Grid.Row="1" |
||||
Header="Discord Rich Presence" |
||||
Margin="8,0,8,4"> |
||||
<ui:SettingsExpander.IconSource> |
||||
<controls:FASymbolIconSource Symbol="fa-brands fa-discord"/> |
||||
</ui:SettingsExpander.IconSource> |
||||
<ui:SettingsExpander.Footer> |
||||
<ToggleSwitch |
||||
IsChecked="{Binding IsDiscordRichPresenceEnabled}" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- System Options --> |
||||
<Grid Grid.Row="4" Margin="0,8,0,0" RowDefinitions="auto, auto, auto"> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="System" |
||||
Margin="0,0,0,8" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
ToolTip.Tip="{OnPlatform Default='Only available on Windows', Windows={x:Null}}" |
||||
Header="Add Stability Matrix to the Start Menu" |
||||
Description="Uses the current app location, you can run this again if you move the app" |
||||
IconSource="StarAdd" |
||||
Margin="8,0,8,4"> |
||||
<ui:SettingsExpander.Footer> |
||||
<StackPanel Orientation="Horizontal" Spacing="8"> |
||||
<controls:ProgressRing |
||||
IsIndeterminate="True" |
||||
IsEnabled="{Binding IsVisible, RelativeSource={RelativeSource Self}}" |
||||
BorderThickness="3"> |
||||
<controls:ProgressRing.IsVisible> |
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}"> |
||||
<Binding Path="AddToStartMenuCommand.IsRunning"/> |
||||
<Binding Path="AddToGlobalStartMenuCommand.IsRunning"/> |
||||
</MultiBinding> |
||||
</controls:ProgressRing.IsVisible> |
||||
</controls:ProgressRing> |
||||
|
||||
<SplitButton |
||||
Command="{Binding AddToStartMenuCommand}" |
||||
IsEnabled="{OnPlatform Default=False, Windows=True}" |
||||
Content="Add for Current User"> |
||||
<SplitButton.Flyout> |
||||
<ui:FAMenuFlyout Placement="Bottom"> |
||||
<ui:MenuFlyoutItem |
||||
Command="{Binding AddToGlobalStartMenuCommand}" |
||||
IconSource="Admin" |
||||
Text="Add for All Users"/> |
||||
</ui:FAMenuFlyout> |
||||
</SplitButton.Flyout> |
||||
</SplitButton> |
||||
</StackPanel> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
<ui:SettingsExpander Grid.Row="2" |
||||
Header="Select New Data Directory" |
||||
Description="Does not move existing data" |
||||
IconSource="MoveToFolder" |
||||
Margin="8,0"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Command="{Binding PickNewDataDirectory}"> |
||||
<Grid ColumnDefinitions="Auto, Auto"> |
||||
<avalonia:Icon Grid.Row="0" Value="fa-solid fa-folder-open" |
||||
Margin="0,0,8,0" |
||||
VerticalAlignment="Center" /> |
||||
<TextBlock Grid.Column="1" |
||||
VerticalAlignment="Center" |
||||
Text="Select Directory"/> |
||||
</Grid> |
||||
</Button> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- Debug Options --> |
||||
<Grid Grid.Row="5" RowDefinitions="auto,*" |
||||
Margin="0,8,0,0" |
||||
IsVisible="{Binding SharedState.IsDebugMode}" > |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Text="Debug Options" |
||||
Margin="0,0,0,8" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
IconSource="Code" |
||||
Command="{Binding LoadDebugInfo}" |
||||
Header="Debug Options" |
||||
Margin="8, 0,8,0"> |
||||
|
||||
<ui:SettingsExpanderItem Description="Paths" IconSource="Folder" |
||||
Margin="4, 0"> |
||||
<SelectableTextBlock Text="{Binding DebugPaths}" |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
<controls:UserControlBase |
||||
x:Class="StabilityMatrix.Avalonia.Views.SettingsPage" |
||||
xmlns="https://github.com/avaloniaui" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:avalonia="clr-namespace:Projektanker.Icons.Avalonia;assembly=Projektanker.Icons.Avalonia" |
||||
xmlns:controls="clr-namespace:StabilityMatrix.Avalonia.Controls" |
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||
xmlns:mocks="clr-namespace:StabilityMatrix.Avalonia.DesignData" |
||||
xmlns:ui="using:FluentAvalonia.UI.Controls" |
||||
xmlns:vm="clr-namespace:StabilityMatrix.Avalonia.ViewModels" |
||||
xmlns:lang="clr-namespace:StabilityMatrix.Avalonia.Languages" |
||||
d:DataContext="{x:Static mocks:DesignData.SettingsViewModel}" |
||||
d:DesignHeight="700" |
||||
d:DesignWidth="800" |
||||
x:CompileBindings="True" |
||||
x:DataType="vm:SettingsViewModel" |
||||
mc:Ignorable="d"> |
||||
|
||||
<ui:SettingsExpanderItem Description="Compat Info" IconSource="StarFilled" |
||||
Margin="4,0"> |
||||
<SelectableTextBlock Text="{Binding DebugCompatInfo}" |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem Description="GPU Info" IconSource="FullScreenMaximize" |
||||
Margin="4,0"> |
||||
<SelectableTextBlock Text="{Binding DebugGpuInfo}" |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
<ScrollViewer VerticalScrollBarVisibility="Auto"> |
||||
<StackPanel Margin="8,16" Spacing="8"> |
||||
<!-- Theme --> |
||||
<Grid RowDefinitions="Auto,*,*"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="Appearance" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0,8,4" |
||||
Header="Theme" |
||||
IconSource="WeatherMoon"> |
||||
<ui:SettingsExpander.Footer> |
||||
<ComboBox |
||||
MinWidth="100" |
||||
ItemsSource="{Binding AvailableThemes}" |
||||
SelectedItem="{Binding SelectedTheme}" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
<ui:SettingsExpander |
||||
Grid.Row="2" |
||||
IsVisible="{Binding SharedState.IsDebugMode}" |
||||
Margin="8,0,8,4" |
||||
Header="{x:Static lang:Resources.Label_Language}" |
||||
IconSource="Character"> |
||||
<ui:SettingsExpander.Footer> |
||||
<ComboBox |
||||
MinWidth="100" |
||||
ItemsSource="{Binding AvailableLanguages}" |
||||
DisplayMemberBinding="{Binding NativeName}" |
||||
SelectedItem="{Binding SelectedLanguage}" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<ui:SettingsExpanderItem Content="Animation Scale" IconSource="Clock" |
||||
Description="Lower values = faster animations. 0x means animations are instant." |
||||
Margin="4,0"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<ComboBox ItemsSource="{Binding AnimationScaleOptions}" |
||||
SelectedItem="{Binding SelectedAnimationScale}"> |
||||
<ComboBox.ItemTemplate> |
||||
<DataTemplate> |
||||
<TextBlock> |
||||
<Run Text="{Binding }"/><Run Text="x"/> |
||||
</TextBlock> |
||||
</DataTemplate> |
||||
</ComboBox.ItemTemplate> |
||||
</ComboBox> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem Content="Notification" IconSource="CommentAdd" |
||||
Margin="4,0"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button |
||||
Command="{Binding DebugNotificationCommand}" |
||||
Content="New Notification"/> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem Content="Content Dialog" IconSource="NewWindow" |
||||
Margin="4,0"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button |
||||
Command="{Binding DebugContentDialogCommand}" |
||||
Content="Show Dialog"/> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem Content="Exceptions" IconSource="Flag" |
||||
Margin="4,0"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button |
||||
Command="{Binding DebugThrowExceptionCommand}" |
||||
Content="Unhandled Exception"/> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem Content="Download Manager tests" IconSource="Flag" |
||||
Margin="4,0,4,4"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button |
||||
Margin="0, 8" |
||||
Command="{Binding DebugTrackedDownloadCommand}" |
||||
Content="Add Tracked Download"/> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- TODO: Python card --> |
||||
|
||||
<!-- TODO: Debug card --> |
||||
|
||||
<!-- TODO: Directories card --> |
||||
|
||||
<Grid Grid.Row="6" RowDefinitions="auto,*" Margin="0,4,0,0"> |
||||
<StackPanel |
||||
Grid.Row="1" |
||||
HorizontalAlignment="Left" |
||||
Orientation="Vertical"> |
||||
<TextBlock |
||||
FontSize="15" |
||||
FontWeight="Bold" |
||||
Margin="0,8" |
||||
Text="About" /> |
||||
<Image |
||||
Height="112" |
||||
HorizontalAlignment="Left" |
||||
Margin="8" |
||||
Source="/Assets/Icon.png" |
||||
Width="112" /> |
||||
<TextBlock |
||||
FontWeight="Medium" |
||||
Margin="8" |
||||
Text="Stability Matrix" /> |
||||
<Panel> |
||||
<Button |
||||
Name="VersionButton" |
||||
Command="{Binding OnVersionClick}" |
||||
Classes="transparent" |
||||
BorderThickness="0" |
||||
Content="{Binding AppVersion}" |
||||
Margin="8,0,8,8" |
||||
Padding="2,0,2,0"/> |
||||
<ui:TeachingTip |
||||
PreferredPlacement="RightTop" |
||||
Target="{Binding #VersionButton}" |
||||
IsOpen="{Binding IsVersionTapTeachingTipOpen}" |
||||
Title="{Binding VersionFlyoutText}"/> |
||||
</Panel> |
||||
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal"> |
||||
<Button |
||||
Content="License and Open Source Notices" |
||||
Command="{Binding ShowLicensesDialogCommand}" |
||||
HorizontalAlignment="Left" |
||||
Margin="8" /> |
||||
</StackPanel> |
||||
<!-- Checkpoints Manager Options --> |
||||
<Grid RowDefinitions="auto,*,Auto"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="Checkpoint Manager" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0" |
||||
Description="Select this option if you're having problems moving Stability Matrix to another drive" |
||||
Header="Remove shared checkpoints directory symbolic links on shutdown" |
||||
IconSource="Folder"> |
||||
<ui:SettingsExpander.Footer> |
||||
<CheckBox Margin="8" IsChecked="{Binding RemoveSymlinksOnShutdown}" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
<ui:SettingsExpander |
||||
Grid.Row="2" |
||||
Margin="8,4" |
||||
Description="Rebuilds the installed checkpoints cache. Use if checkpoints are incorrectly labeled in the Model Browser." |
||||
Header="Reset Checkpoints Cache" |
||||
IconSource="Refresh"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Command="{Binding ResetCheckpointCache}" Content="Reset Checkpoints Cache" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- Environment Options --> |
||||
<Grid RowDefinitions="Auto, Auto, Auto"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="Package Environment" /> |
||||
|
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0" |
||||
Header="Environment Variables" |
||||
IconSource="OtherUser"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Command="{Binding OpenEnvVarsDialogCommand}" Content="Edit" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
|
||||
<ui:SettingsExpander |
||||
Grid.Row="2" |
||||
Margin="8,4" |
||||
Header="Embedded Python"> |
||||
<ui:SettingsExpander.IconSource> |
||||
<controls:FASymbolIconSource Symbol="fa-brands fa-python" /> |
||||
</ui:SettingsExpander.IconSource> |
||||
<ui:SettingsExpander.Footer> |
||||
<StackPanel Orientation="Horizontal" Spacing="16"> |
||||
<controls:ProgressRing |
||||
BorderThickness="3" |
||||
IsEnabled="{Binding CheckPythonVersionCommand.IsRunning}" |
||||
IsIndeterminate="True" |
||||
IsVisible="{Binding CheckPythonVersionCommand.IsRunning}" /> |
||||
<Button Command="{Binding CheckPythonVersionCommand}" Content="Check Version" /> |
||||
</StackPanel> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- Integrations --> |
||||
<Grid RowDefinitions="auto,*"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="Integrations" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0,8,4" |
||||
Header="Discord Rich Presence"> |
||||
<ui:SettingsExpander.IconSource> |
||||
<controls:FASymbolIconSource Symbol="fa-brands fa-discord" /> |
||||
</ui:SettingsExpander.IconSource> |
||||
<ui:SettingsExpander.Footer> |
||||
<ToggleSwitch IsChecked="{Binding IsDiscordRichPresenceEnabled}" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- System Options --> |
||||
<Grid RowDefinitions="auto, auto, auto"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="System" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0,8,4" |
||||
Description="Uses the current app location, you can run this again if you move the app" |
||||
Header="Add Stability Matrix to the Start Menu" |
||||
IconSource="StarAdd" |
||||
ToolTip.Tip="{OnPlatform Default='Only available on Windows', |
||||
Windows={x:Null}}"> |
||||
<ui:SettingsExpander.Footer> |
||||
<StackPanel Orientation="Horizontal" Spacing="8"> |
||||
<controls:ProgressRing |
||||
BorderThickness="3" |
||||
IsEnabled="{Binding IsVisible, RelativeSource={RelativeSource Self}}" |
||||
IsIndeterminate="True"> |
||||
<controls:ProgressRing.IsVisible> |
||||
<MultiBinding Converter="{x:Static BoolConverters.Or}"> |
||||
<Binding Path="AddToStartMenuCommand.IsRunning" /> |
||||
<Binding Path="AddToGlobalStartMenuCommand.IsRunning" /> |
||||
</MultiBinding> |
||||
</controls:ProgressRing.IsVisible> |
||||
</controls:ProgressRing> |
||||
|
||||
<SplitButton |
||||
Command="{Binding AddToStartMenuCommand}" |
||||
Content="Add for Current User" |
||||
IsEnabled="{OnPlatform Default=False, |
||||
Windows=True}"> |
||||
<SplitButton.Flyout> |
||||
<ui:FAMenuFlyout Placement="Bottom"> |
||||
<ui:MenuFlyoutItem |
||||
Command="{Binding AddToGlobalStartMenuCommand}" |
||||
IconSource="Admin" |
||||
Text="Add for All Users" /> |
||||
</ui:FAMenuFlyout> |
||||
</SplitButton.Flyout> |
||||
</SplitButton> |
||||
</StackPanel> |
||||
</Grid> |
||||
|
||||
<!-- Extra space at the bottom --> |
||||
<Panel Grid.Row="7" Margin="0,0,0,16" /> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
<ui:SettingsExpander |
||||
Grid.Row="2" |
||||
Margin="8,0" |
||||
Description="Does not move existing data" |
||||
Header="Select New Data Directory" |
||||
IconSource="MoveToFolder"> |
||||
<ui:SettingsExpander.Footer> |
||||
<Button Command="{Binding PickNewDataDirectory}"> |
||||
<Grid ColumnDefinitions="Auto, Auto"> |
||||
<avalonia:Icon |
||||
Grid.Row="0" |
||||
Margin="0,0,8,0" |
||||
VerticalAlignment="Center" |
||||
Value="fa-solid fa-folder-open" /> |
||||
<TextBlock |
||||
Grid.Column="1" |
||||
VerticalAlignment="Center" |
||||
Text="Select Directory" /> |
||||
</Grid> |
||||
</Button> |
||||
</ui:SettingsExpander.Footer> |
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
</ScrollViewer> |
||||
</Grid> |
||||
|
||||
|
||||
|
||||
<!-- Debug Options --> |
||||
<Grid |
||||
IsVisible="{Binding SharedState.IsDebugMode}" |
||||
RowDefinitions="auto,*"> |
||||
<TextBlock |
||||
Margin="0,0,0,8" |
||||
FontWeight="Medium" |
||||
Text="Debug Options" /> |
||||
<ui:SettingsExpander |
||||
Grid.Row="1" |
||||
Margin="8,0,8,0" |
||||
Command="{Binding LoadDebugInfo}" |
||||
Header="Debug Options" |
||||
IconSource="Code"> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Description="Paths" |
||||
IconSource="Folder"> |
||||
<SelectableTextBlock |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
Text="{Binding DebugPaths}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Description="Compat Info" |
||||
IconSource="StarFilled"> |
||||
<SelectableTextBlock |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
Text="{Binding DebugCompatInfo}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Description="GPU Info" |
||||
IconSource="FullScreenMaximize"> |
||||
<SelectableTextBlock |
||||
Foreground="{DynamicResource TextControlPlaceholderForeground}" |
||||
Text="{Binding DebugGpuInfo}" |
||||
TextWrapping="WrapWithOverflow" /> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Content="Animation Scale" |
||||
Description="Lower values = faster animations. 0x means animations are instant." |
||||
IconSource="Clock"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<ComboBox ItemsSource="{Binding AnimationScaleOptions}" SelectedItem="{Binding SelectedAnimationScale}"> |
||||
<ComboBox.ItemTemplate> |
||||
<DataTemplate> |
||||
<TextBlock> |
||||
<Run Text="{Binding}" /><Run Text="x" /> |
||||
</TextBlock> |
||||
</DataTemplate> |
||||
</ComboBox.ItemTemplate> |
||||
</ComboBox> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Content="Notification" |
||||
IconSource="CommentAdd"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button Command="{Binding DebugNotificationCommand}" Content="New Notification" /> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Content="Content Dialog" |
||||
IconSource="NewWindow"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button Command="{Binding DebugContentDialogCommand}" Content="Show Dialog" /> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0" |
||||
Content="Exceptions" |
||||
IconSource="Flag"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button Command="{Binding DebugThrowExceptionCommand}" Content="Unhandled Exception" /> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
<ui:SettingsExpanderItem |
||||
Margin="4,0,4,4" |
||||
Content="Download Manager tests" |
||||
IconSource="Flag"> |
||||
<ui:SettingsExpanderItem.Footer> |
||||
<Button |
||||
Margin="0,8" |
||||
Command="{Binding DebugTrackedDownloadCommand}" |
||||
Content="Add Tracked Download" /> |
||||
</ui:SettingsExpanderItem.Footer> |
||||
</ui:SettingsExpanderItem> |
||||
|
||||
</ui:SettingsExpander> |
||||
</Grid> |
||||
|
||||
<!-- TODO: Directories card --> |
||||
|
||||
<Grid RowDefinitions="auto,*"> |
||||
<StackPanel |
||||
Grid.Row="1" |
||||
HorizontalAlignment="Left" |
||||
Orientation="Vertical"> |
||||
<TextBlock |
||||
Margin="0,8" |
||||
FontSize="15" |
||||
FontWeight="Bold" |
||||
Text="About" /> |
||||
<Image |
||||
Width="112" |
||||
Height="112" |
||||
Margin="8" |
||||
HorizontalAlignment="Left" |
||||
Source="/Assets/Icon.png" /> |
||||
<TextBlock |
||||
Margin="8" |
||||
FontWeight="Medium" |
||||
Text="Stability Matrix" /> |
||||
<Panel> |
||||
<Button |
||||
Name="VersionButton" |
||||
Margin="8,0,8,8" |
||||
Padding="2,0,2,0" |
||||
BorderThickness="0" |
||||
Classes="transparent" |
||||
Command="{Binding OnVersionClick}" |
||||
Content="{Binding AppVersion}" /> |
||||
<ui:TeachingTip |
||||
Title="{Binding VersionFlyoutText}" |
||||
IsOpen="{Binding IsVersionTapTeachingTipOpen}" |
||||
PreferredPlacement="RightTop" |
||||
Target="{Binding #VersionButton}" /> |
||||
</Panel> |
||||
|
||||
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal"> |
||||
<Button |
||||
Margin="8" |
||||
HorizontalAlignment="Left" |
||||
Command="{Binding ShowLicensesDialogCommand}" |
||||
Content="License and Open Source Notices" /> |
||||
</StackPanel> |
||||
</StackPanel> |
||||
</Grid> |
||||
|
||||
<!-- Extra space at the bottom --> |
||||
<Panel Margin="0,0,0,16" /> |
||||
</StackPanel> |
||||
</ScrollViewer> |
||||
|
||||
|
||||
</controls:UserControlBase> |
||||
|
Loading…
Reference in new issue