Refine options window bindings

This commit is contained in:
Matt Nadareski
2023-10-07 22:40:51 -04:00
parent f14961061c
commit 46de589791
6 changed files with 117 additions and 59 deletions

View File

@@ -9,7 +9,7 @@ namespace MPF.Core.UI.ComboBoxItems
/// A generic combo box element
/// </summary>
/// <typeparam name="T">Enum type representing the possible values</typeparam>
public class Element<T> : IElement where T : struct, Enum
public class Element<T> : IEquatable<Element<T>>, IElement where T : struct, Enum
{
private readonly T Data;
@@ -47,5 +47,18 @@ namespace MPF.Core.UI.ComboBoxItems
.OfType<T>()
.Select(e => new Element<T>(e));
}
/// <inheritdoc/>
#if NET48
public bool Equals(Element<T> other)
#else
public bool Equals(Element<T>? other)
#endif
{
if (other == null)
return false;
return Name == other.Name;
}
}
}

View File

@@ -8,7 +8,7 @@ namespace MPF.Core.UI.ComboBoxItems
/// <summary>
/// Represents a single item in the System combo box
/// </summary>
public class RedumpSystemComboBoxItem : IElement
public class RedumpSystemComboBoxItem : IEquatable<RedumpSystemComboBoxItem>, IElement
{
#if NET48
private readonly object Data;
@@ -83,5 +83,18 @@ namespace MPF.Core.UI.ComboBoxItems
return systemsValues;
}
/// <inheritdoc/>
#if NET48
public bool Equals(RedumpSystemComboBoxItem other)
#else
public bool Equals(RedumpSystemComboBoxItem? other)
#endif
{
if (other == null)
return false;
return Value == other.Value;
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using System.Globalization;
using System.Windows.Data;
using MPF.Core.Data;
using MPF.Core.UI.ComboBoxItems;
using SabreTools.RedumpLib.Data;
namespace MPF.UI.Core
{
internal class ElementConverter: IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (value)
{
case InternalProgram internalProgram:
return new Element<InternalProgram>(internalProgram);
case RedumpSystem redumpSystem:
return new RedumpSystemComboBoxItem(redumpSystem);
// Null values are treated as a system value
default:
return new RedumpSystemComboBoxItem((RedumpSystem?)null);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// If it's an IElement but ends up null
var element = value as IElement;
if (element == null)
return null;
switch (element)
{
case Element<InternalProgram> ipElement:
return ipElement.Value;
case RedumpSystemComboBoxItem rsElement:
return rsElement.Value;
default: return null;
}
}
}
}

View File

@@ -7,7 +7,6 @@ using System.Windows;
using System.Windows.Forms;
using MPF.Core.Data;
using MPF.Core.UI.ComboBoxItems;
using MPF.UI.Core.Windows;
using SabreTools.RedumpLib.Web;
using WPFCustomMessageBox;
@@ -25,7 +24,7 @@ namespace MPF.UI.Core.ViewModels
/// <summary>
/// Flag for if settings were saved or not
/// </summary>
public bool SavedSettings { get; private set; }
public bool SavedSettings { get; internal set; }
#endregion
@@ -51,34 +50,6 @@ namespace MPF.UI.Core.ViewModels
Options = new Options(baseOptions);
}
#region Load and Save
/// <summary>
/// Load any options-related elements
/// </summary>
/// TODO: Convert selected list item to binding
internal void Load(OptionsWindow parent)
{
parent.InternalProgramComboBox.SelectedIndex = InternalPrograms.FindIndex(r => r == Options.InternalProgram);
parent.DefaultSystemComboBox.SelectedIndex = Systems.FindIndex(r => r == Options.DefaultSystem);
}
/// <summary>
/// Save any options-related elements
/// </summary>
/// TODO: Convert selected list item to binding
internal void Save(OptionsWindow parent)
{
var selectedInternalProgram = parent.InternalProgramComboBox.SelectedItem as Element<InternalProgram>;
Options.InternalProgram = selectedInternalProgram?.Value ?? InternalProgram.DiscImageCreator;
var selectedDefaultSystem = parent.DefaultSystemComboBox.SelectedItem as RedumpSystemComboBoxItem;
Options.DefaultSystem = selectedDefaultSystem?.Value ?? null;
SavedSettings = true;
}
#endregion
#region Population
/// <summary>
@@ -158,24 +129,16 @@ namespace MPF.UI.Core.ViewModels
/// Test Redump login credentials
/// </summary>
#if NET48
public bool? TestRedumpLogin(Window parent, string username, string password)
public (bool?, string) TestRedumpLogin(Window parent, string username, string password)
#else
public async Task<bool?> TestRedumpLogin(Window parent, string username, string password)
public async Task<(bool?, string)> TestRedumpLogin(Window parent, string username, string password)
#endif
{
#if NET48
(bool? success, string message) = RedumpWebClient.ValidateCredentials(username, password);
return RedumpWebClient.ValidateCredentials(username, password);
#else
(bool? success, string message) = await RedumpHttpClient.ValidateCredentials(username, password);
return await RedumpHttpClient.ValidateCredentials(username, password);
#endif
if (success == true)
CustomMessageBox.Show(parent, message, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
else if (success == false)
CustomMessageBox.Show(parent, message, "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
else
CustomMessageBox.Show(parent, message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return success;
}
#endregion

View File

@@ -10,6 +10,9 @@
WindowStartupLocation="CenterOwner" ResizeMode="CanMinimize" SizeToContent="Height"
BorderBrush="DarkGray" BorderThickness="2">
<Window.Resources>
<core:ElementConverter x:Key="ElementConverter" />
</Window.Resources>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
</WindowChrome.WindowChrome>
@@ -99,26 +102,31 @@
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Aaru Path" />
<TextBox x:Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.AaruPath}" VerticalContentAlignment="Center" />
<TextBox x:Name="AaruPathTextBox" Grid.Row="0" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.AaruPath}" VerticalContentAlignment="Center" />
<Button x:Name="AaruPathButton" Grid.Row="0" Grid.Column="2" Height="22" Width="22" Content="..."
Style="{DynamicResource CustomButtonStyle}" />
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="DiscImageCreator Path" />
<TextBox x:Name="DiscImageCreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.DiscImageCreatorPath}" VerticalContentAlignment="Center" />
<TextBox x:Name="DiscImageCreatorPathTextBox" Grid.Row="1" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.DiscImageCreatorPath}" VerticalContentAlignment="Center" />
<Button x:Name="DiscImageCreatorPathButton" Grid.Row="1" Grid.Column="2" Height="22" Width="22" Content="..."
Style="{DynamicResource CustomButtonStyle}" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Redumper Path" />
<TextBox x:Name="RedumperPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.RedumperPath}" VerticalContentAlignment="Center" />
<TextBox x:Name="RedumperPathTextBox" Grid.Row="2" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.RedumperPath}" VerticalContentAlignment="Center" />
<Button x:Name="RedumperPathButton" Grid.Row="2" Grid.Column="2" Height="22" Width="22" Content="..."
Style="{DynamicResource CustomButtonStyle}" />
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Dumping Program" />
<ComboBox x:Name="InternalProgramComboBox" Grid.Row="3" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
ItemsSource="{Binding InternalPrograms}" Style="{DynamicResource CustomComboBoxStyle}" />
ItemsSource="{Binding InternalPrograms}" SelectedItem="{Binding Options.InternalProgram, Converter={StaticResource ElementConverter}, Mode=TwoWay}"
Style="{DynamicResource CustomComboBoxStyle}" />
<Label Grid.Row="4" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Right" Content="Default Output Path" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch" Text="{Binding Options.DefaultOutputPath}" VerticalContentAlignment="Center" />
<TextBox x:Name="DefaultOutputPathTextBox" Grid.Row="4" Grid.Column="1" Height="22" HorizontalAlignment="Stretch"
Text="{Binding Options.DefaultOutputPath}" VerticalContentAlignment="Center" />
<Button x:Name="DefaultOutputPathButton" Grid.Row="4" Grid.Column="2" Height="22" Width="22" Content="..."
Style="{DynamicResource CustomButtonStyle}" />
</Grid>
@@ -139,7 +147,9 @@
/>
<Label VerticalAlignment="Center" Content="Default System:" HorizontalAlignment="Right" />
<ComboBox x:Name="DefaultSystemComboBox" Height="22" Width="200" HorizontalAlignment="Left" ItemsSource="{Binding Systems}" SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
<ComboBox x:Name="DefaultSystemComboBox" Height="22" Width="200" HorizontalAlignment="Left"
ItemsSource="{Binding Systems}" SelectedItem="{Binding Options.DefaultSystem, Converter={StaticResource ElementConverter}, Mode=TwoWay}"
SelectedIndex="0" Style="{DynamicResource CustomComboBoxStyle}">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Style.Triggers>

View File

@@ -1,6 +1,8 @@
using System;
using System.Windows;
using MPF.Core.Data;
using MPF.UI.Core.ViewModels;
using WPFCustomMessageBox;
namespace MPF.UI.Core.Windows
{
@@ -34,9 +36,6 @@ namespace MPF.UI.Core.Windows
CancelButton.Click += OnCancelClick;
RedumpPasswordBox.PasswordChanged += OnPasswordChanged;
RedumpLoginTestButton.Click += OnRedumpTestClick;
// Update UI with new values
OptionsViewModel.Load(this);
}
#region Event Handlers
@@ -52,7 +51,7 @@ namespace MPF.UI.Core.Windows
/// </summary>
private void OnAcceptClick(object sender, EventArgs e)
{
OptionsViewModel.Save(this);
OptionsViewModel.SavedSettings = true;
Close();
}
@@ -60,7 +59,10 @@ namespace MPF.UI.Core.Windows
/// Handler for CancelButtom Click event
/// </summary>
private void OnCancelClick(object sender, EventArgs e)
=> Close();
{
OptionsViewModel.SavedSettings = false;
Close();
}
/// <summary>
/// Handler for
@@ -74,12 +76,24 @@ namespace MPF.UI.Core.Windows
/// Test Redump credentials for validity
/// </summary>
#if NET48
private void OnRedumpTestClick(object sender, EventArgs e) =>
OptionsViewModel.TestRedumpLogin(this, RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
private void OnRedumpTestClick(object sender, EventArgs e)
#else
private async void OnRedumpTestClick(object sender, EventArgs e) =>
_ = await OptionsViewModel.TestRedumpLogin(this, RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
private async void OnRedumpTestClick(object sender, EventArgs e)
#endif
{
#if NET48
(bool? success, string message) = OptionsViewModel.TestRedumpLogin(this, RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
#else
(bool? success, string message) = await OptionsViewModel.TestRedumpLogin(this, RedumpUsernameTextBox.Text, RedumpPasswordBox.Password);
#endif
if (success == true)
CustomMessageBox.Show(this, message, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
else if (success == false)
CustomMessageBox.Show(this, message, "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
else
CustomMessageBox.Show(this, message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
#endregion
}