mirror of
https://github.com/aaru-dps/RedBookPlayer.git
synced 2025-12-16 19:24:41 +00:00
Port only MVVM work and related fixes
This commit is contained in:
@@ -1,7 +1,17 @@
|
||||
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
<ReactiveWindow 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" mc:Ignorable="d"
|
||||
xmlns:rxui="clr-namespace:Avalonia;assembly=Avalonia.ReactiveUI"
|
||||
xmlns:viewModels="clr-namespace:RedBookPlayer.GUI.ViewModels;assembly=RedBookPlayer.GUI"
|
||||
xmlns:views="clr-namespace:RedBookPlayer.GUI.Views;assembly=RedBookPlayer.GUI"
|
||||
x:Class="RedBookPlayer.GUI.Views.MainWindow" Title="RedBookPlayer" SizeToContent="WidthAndHeight"
|
||||
DragDrop.AllowDrop="True">
|
||||
<ContentControl Name="Content" />
|
||||
</Window>
|
||||
CanResize="False" DragDrop.AllowDrop="True">
|
||||
<ReactiveWindow.ViewModel>
|
||||
<viewModels:MainViewModel/>
|
||||
</ReactiveWindow.ViewModel>
|
||||
<ContentControl Name="Content">
|
||||
<ContentControl.Content>
|
||||
<views:PlayerView/>
|
||||
</ContentControl.Content>
|
||||
</ContentControl>
|
||||
</ReactiveWindow>
|
||||
@@ -1,73 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using RedBookPlayer.GUI.ViewModels;
|
||||
|
||||
namespace RedBookPlayer.GUI.Views
|
||||
{
|
||||
public class MainWindow : Window
|
||||
public class MainWindow : ReactiveWindow<MainViewModel>
|
||||
{
|
||||
public static MainWindow Instance;
|
||||
public ContentControl ContentControl;
|
||||
public Window settingsWindow;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
Instance = this;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Apply a custom theme to the player
|
||||
/// </summary>
|
||||
/// <param name="theme">Path to the theme under the themes directory</param>
|
||||
public static void ApplyTheme(string theme)
|
||||
{
|
||||
// If no theme path is provided, we can ignore
|
||||
if(string.IsNullOrWhiteSpace(theme))
|
||||
return;
|
||||
|
||||
// If we already have a view, cache the view model
|
||||
PlayerViewModel pvm = ((PlayerView)Instance.ContentControl.Content).PlayerViewModel;
|
||||
|
||||
// If the theme name is "default", we assume the internal theme is used
|
||||
if(theme.Equals("default", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
Instance.ContentControl.Content = new PlayerView(pvm);
|
||||
}
|
||||
else
|
||||
{
|
||||
string themeDirectory = $"{Directory.GetCurrentDirectory()}/themes/{theme}";
|
||||
string xamlPath = $"{themeDirectory}/view.xaml";
|
||||
|
||||
if(!File.Exists(xamlPath))
|
||||
{
|
||||
Console.WriteLine("Warning: specified theme doesn't exist, reverting to default");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string xaml = File.ReadAllText(xamlPath);
|
||||
xaml = xaml.Replace("Source=\"", $"Source=\"file://{themeDirectory}/");
|
||||
Instance.ContentControl.Content = new PlayerView(xaml, pvm);
|
||||
}
|
||||
catch(XmlException ex)
|
||||
{
|
||||
Console.WriteLine($"Error: invalid theme XAML ({ex.Message}), reverting to default");
|
||||
Instance.ContentControl.Content = new PlayerView(pvm);
|
||||
}
|
||||
}
|
||||
|
||||
Instance.Width = ((PlayerView)Instance.ContentControl.Content).Width;
|
||||
Instance.Height = ((PlayerView)Instance.ContentControl.Content).Height;
|
||||
|
||||
pvm.InitializeDigits();
|
||||
}
|
||||
public MainWindow() => InitializeComponent();
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the main window
|
||||
@@ -76,162 +16,10 @@ namespace RedBookPlayer.GUI.Views
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
ContentControl = this.FindControl<ContentControl>("Content");
|
||||
ContentControl.Content = new PlayerView();
|
||||
|
||||
Instance.MaxWidth = ((PlayerView)Instance.ContentControl.Content).Width;
|
||||
Instance.MaxHeight = ((PlayerView)Instance.ContentControl.Content).Height;
|
||||
|
||||
ContentControl.Content = new PlayerView();
|
||||
|
||||
((PlayerView)ContentControl.Content).PlayerViewModel.InitializeDigits();
|
||||
|
||||
CanResize = false;
|
||||
|
||||
KeyDown += OnKeyDown;
|
||||
|
||||
Closing += (s, e) =>
|
||||
{
|
||||
settingsWindow?.Close();
|
||||
settingsWindow = null;
|
||||
};
|
||||
|
||||
Closing += (e, f) =>
|
||||
{
|
||||
((PlayerView)ContentControl.Content).PlayerViewModel.ExecuteStop();
|
||||
};
|
||||
|
||||
AddHandler(DragDrop.DropEvent, MainWindow_Drop);
|
||||
// Add handlers
|
||||
Closing += ViewModel.ExecuteStop;
|
||||
AddHandler(DragDrop.DropEvent, ViewModel.ExecuteLoadDragDrop);
|
||||
KeyDown += ViewModel.ExecuteKeyPress;
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
public async void MainWindow_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
PlayerView playerView = ContentControl.Content as PlayerView;
|
||||
if(playerView == null)
|
||||
return;
|
||||
|
||||
IEnumerable<string> fileNames = e.Data.GetFileNames();
|
||||
foreach(string filename in fileNames)
|
||||
{
|
||||
bool loaded = await playerView?.PlayerViewModel?.LoadImage(filename);
|
||||
if(loaded)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
PlayerView playerView = ContentControl.Content as PlayerView;
|
||||
|
||||
// Open settings window
|
||||
if(e.Key == App.Settings.OpenSettingsKey)
|
||||
{
|
||||
settingsWindow = new SettingsWindow(App.Settings);
|
||||
settingsWindow.Closed += OnSettingsClosed;
|
||||
settingsWindow.Show();
|
||||
}
|
||||
|
||||
// Load image
|
||||
else if (e.Key == App.Settings.LoadImageKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteLoad();
|
||||
}
|
||||
|
||||
// Toggle playback
|
||||
else if(e.Key == App.Settings.TogglePlaybackKey || e.Key == Key.MediaPlayPause)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteTogglePlayPause();
|
||||
}
|
||||
|
||||
// Stop playback
|
||||
else if(e.Key == App.Settings.StopPlaybackKey || e.Key == Key.MediaStop)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteStop();
|
||||
}
|
||||
|
||||
// Next Track
|
||||
else if(e.Key == App.Settings.NextTrackKey || e.Key == Key.MediaNextTrack)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteNextTrack();
|
||||
}
|
||||
|
||||
// Previous Track
|
||||
else if(e.Key == App.Settings.PreviousTrackKey || e.Key == Key.MediaPreviousTrack)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecutePreviousTrack();
|
||||
}
|
||||
|
||||
// Next Index
|
||||
else if(e.Key == App.Settings.NextIndexKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteNextIndex();
|
||||
}
|
||||
|
||||
// Previous Index
|
||||
else if(e.Key == App.Settings.PreviousIndexKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecutePreviousIndex();
|
||||
}
|
||||
|
||||
// Fast Foward
|
||||
else if(e.Key == App.Settings.FastForwardPlaybackKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteFastForward();
|
||||
}
|
||||
|
||||
// Rewind
|
||||
else if(e.Key == App.Settings.RewindPlaybackKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteRewind();
|
||||
}
|
||||
|
||||
// Volume Up
|
||||
else if(e.Key == App.Settings.VolumeUpKey || e.Key == Key.VolumeUp)
|
||||
{
|
||||
int increment = 1;
|
||||
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||
increment *= 2;
|
||||
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
||||
increment *= 5;
|
||||
|
||||
if(playerView?.PlayerViewModel?.Volume != null)
|
||||
playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume + increment);
|
||||
}
|
||||
|
||||
// Volume Down
|
||||
else if(e.Key == App.Settings.VolumeDownKey || e.Key == Key.VolumeDown)
|
||||
{
|
||||
int decrement = 1;
|
||||
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
||||
decrement *= 2;
|
||||
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
||||
decrement *= 5;
|
||||
|
||||
if (playerView?.PlayerViewModel?.Volume != null)
|
||||
playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume - decrement);
|
||||
}
|
||||
|
||||
// Mute Toggle
|
||||
else if(e.Key == App.Settings.ToggleMuteKey || e.Key == Key.VolumeMute)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteToggleMute();
|
||||
}
|
||||
|
||||
// Emphasis Toggle
|
||||
else if(e.Key == App.Settings.ToggleDeEmphasisKey)
|
||||
{
|
||||
playerView?.PlayerViewModel?.ExecuteToggleDeEmphasis();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSettingsClosed(object sender, EventArgs e)
|
||||
{
|
||||
PlayerView playerView = ContentControl.Content as PlayerView;
|
||||
playerView?.UpdateViewModel();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
<ReactiveUserControl 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" mc:Ignorable="d"
|
||||
x:Class="RedBookPlayer.GUI.Views.PlayerView" Width="900" Height="400">
|
||||
xmlns:rxui="clr-namespace:Avalonia;assembly=Avalonia.ReactiveUI"
|
||||
xmlns:viewModels="clr-namespace:RedBookPlayer.GUI.ViewModels;assembly=RedBookPlayer.GUI"
|
||||
x:Class="RedBookPlayer.GUI.Views.PlayerView" Width="900" Height="400" Background="White">
|
||||
<ReactiveUserControl.ViewModel>
|
||||
<viewModels:PlayerViewModel/>
|
||||
</ReactiveUserControl.ViewModel>
|
||||
<StackPanel Margin="16" VerticalAlignment="Center">
|
||||
<Button Command="{Binding LoadCommand}" Margin="32,0,32,16">Load</Button>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,16">
|
||||
@@ -101,4 +106,4 @@
|
||||
<TextBlock Margin="0,0,16,0" Text="{Binding Volume}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
</ReactiveUserControl>
|
||||
@@ -1,73 +1,9 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using RedBookPlayer.GUI.ViewModels;
|
||||
|
||||
namespace RedBookPlayer.GUI.Views
|
||||
{
|
||||
public class PlayerView : UserControl
|
||||
public class PlayerView : ReactiveUserControl<PlayerViewModel>
|
||||
{
|
||||
/// <summary>
|
||||
/// Read-only access to the view model
|
||||
/// </summary>
|
||||
public PlayerViewModel PlayerViewModel => DataContext as PlayerViewModel;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the UI based on the default theme
|
||||
/// </summary>
|
||||
public PlayerView() : this(null, null) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the UI based on the default theme with an existing view model
|
||||
/// </summary>
|
||||
/// <param name="xaml">XAML data representing the theme, null for default</param>
|
||||
/// <param name="playerViewModel">Existing PlayerViewModel to load in instead of creating a new one</param>
|
||||
public PlayerView(PlayerViewModel playerViewModel) : this(null, playerViewModel) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the UI based on the currently selected theme
|
||||
/// </summary>
|
||||
/// <param name="xaml">XAML data representing the theme, null for default</param>
|
||||
/// <param name="playerViewModel">Existing PlayerViewModel to load in instead of creating a new one</param>
|
||||
public PlayerView(string xaml, PlayerViewModel playerViewModel)
|
||||
{
|
||||
LoadTheme(xaml);
|
||||
|
||||
if(playerViewModel != null)
|
||||
DataContext = playerViewModel;
|
||||
else
|
||||
DataContext = new PlayerViewModel();
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Update the view model with new settings
|
||||
/// </summary>
|
||||
public void UpdateViewModel()
|
||||
{
|
||||
PlayerViewModel.SetLoadDataTracks(App.Settings.PlayDataTracks);
|
||||
PlayerViewModel.SetLoadHiddenTracks(App.Settings.PlayHiddenTracks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the theme from a XAML, if possible
|
||||
/// </summary>
|
||||
/// <param name="xaml">XAML data representing the theme, null for default</param>
|
||||
private void LoadTheme(string xaml)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(xaml != null)
|
||||
new AvaloniaXamlLoader().Load(xaml, null, this);
|
||||
else
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
catch
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
<Window xmlns="https://github.com/avaloniaui" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
<ReactiveWindow 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" mc:Ignorable="d" d:DesignWidth="800"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
|
||||
xmlns:rxui="clr-namespace:Avalonia;assembly=Avalonia.ReactiveUI" d:DesignWidth="800"
|
||||
xmlns:viewModels="clr-namespace:RedBookPlayer.GUI.ViewModels;assembly=RedBookPlayer.GUI"
|
||||
d:DesignHeight="450" x:Class="RedBookPlayer.GUI.Views.SettingsWindow" Title="Settings" SizeToContent="WidthAndHeight">
|
||||
<ReactiveWindow.ViewModel>
|
||||
<viewModels:SettingsViewModel/>
|
||||
</ReactiveWindow.ViewModel>
|
||||
<StackPanel>
|
||||
<TabControl>
|
||||
<TabItem Header="UI Settings">
|
||||
@@ -21,8 +26,9 @@
|
||||
<TextBlock VerticalAlignment="Center">Play hidden tracks</TextBlock>
|
||||
</WrapPanel>
|
||||
<WrapPanel Margin="0,0,0,16">
|
||||
<CheckBox IsChecked="{Binding PlayDataTracks}" Margin="0,0,8,0"/>
|
||||
<TextBlock VerticalAlignment="Center">Play data tracks like old, non-compliant players</TextBlock>
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Width="120">Data Track Playback</TextBlock>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" Name="DataPlayback" Margin="8,0,0,0" Width="120"
|
||||
Items="{Binding DataPlaybackValues}" SelectedItem="{Binding DataPlayback, Mode=TwoWay}" />
|
||||
</WrapPanel>
|
||||
<WrapPanel Margin="0,0,0,16">
|
||||
<CheckBox IsChecked="{Binding GenerateMissingTOC}" Margin="0,0,8,0"/>
|
||||
@@ -33,11 +39,12 @@
|
||||
<TextBlock VerticalAlignment="Center" DockPanel.Dock="Right" Text="%" />
|
||||
<TextBlock VerticalAlignment="Center" Margin="8,0,0,0" DockPanel.Dock="Right" Text="{Binding Volume}"
|
||||
Name="VolumeLabel" />
|
||||
<Slider Minimum="0" Maximum="100" SmallChange="1" LargeChange="10" Value="{Binding Volume}"
|
||||
Name="VolumeSlider" />
|
||||
<Slider Minimum="0" Maximum="100" SmallChange="1" LargeChange="10" Value="{Binding Volume, Mode=TwoWay}"
|
||||
Name="VolumeSlider"/>
|
||||
</DockPanel>
|
||||
</StackPanel>
|
||||
<ListBox Name="ThemeList" SelectionMode="Single" Margin="0,0,0,16" />
|
||||
<ListBox Name="ThemeList" SelectionMode="Single" Margin="0,0,0,16"
|
||||
Items="{Binding ThemeValues}" SelectedItem="{Binding SelectedTheme, Mode=TwoWay}"/>
|
||||
</DockPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="Keyboard Bindings">
|
||||
@@ -61,62 +68,96 @@
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Load Image-->
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Width="120">Load Image</TextBlock>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Name="LoadImageKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<ComboBox Grid.Row="0" Grid.Column="1" Name="LoadImageKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding LoadImageKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Toggle Play/Pause -->
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Width="120">Toggle Play/Pause</TextBlock>
|
||||
<ComboBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Name="TogglePlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Width="120">Toggle Play/Pause</TextBlock>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" Name="TogglePlaybackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding TogglePlaybackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Stop Playback-->
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Width="120">Stop Playback</TextBlock>
|
||||
<ComboBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" Name="StopPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Width="120">Stop Playback</TextBlock>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" Name="StopPlaybackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding StopPlaybackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Eject Disc-->
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Width="120">Eject Disc</TextBlock>
|
||||
<ComboBox Grid.Row="4" Grid.Column="1" Name="EjectKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding EjectKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Next Track -->
|
||||
<TextBlock Grid.Row="3" Grid.Column="0" Width="120">Next Track</TextBlock>
|
||||
<ComboBox Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" Name="NextTrackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Width="120">Next Track</TextBlock>
|
||||
<ComboBox Grid.Row="5" Grid.Column="1" Name="NextTrackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding NextTrackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Previous Track -->
|
||||
<TextBlock Grid.Row="4" Grid.Column="0" Width="120">Previous Track</TextBlock>
|
||||
<ComboBox Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right" Name="PreviousTrackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Width="120">Previous Track</TextBlock>
|
||||
<ComboBox Grid.Row="6" Grid.Column="1" Name="PreviousTrackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding PreviousTrackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Next Index -->
|
||||
<TextBlock Grid.Row="5" Grid.Column="0" Width="120">Next Index</TextBlock>
|
||||
<ComboBox Grid.Row="5" Grid.Column="1" HorizontalAlignment="Right" Name="NextIndexKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Width="120">Next Index</TextBlock>
|
||||
<ComboBox Grid.Row="7" Grid.Column="1" Name="NextIndexKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding NextIndexKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Previous Index -->
|
||||
<TextBlock Grid.Row="6" Grid.Column="0" Width="120">Previous Index</TextBlock>
|
||||
<ComboBox Grid.Row="6" Grid.Column="1" HorizontalAlignment="Right" Name="PreviousIndexKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Width="120">Previous Index</TextBlock>
|
||||
<ComboBox Grid.Row="8" Grid.Column="1" Name="PreviousIndexKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding PreviousIndexKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Fast Forward -->
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Width="120">Fast-Forward</TextBlock>
|
||||
<ComboBox Grid.Row="7" Grid.Column="1" HorizontalAlignment="Right" Name="FastForwardPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Width="120">Fast-Forward</TextBlock>
|
||||
<ComboBox Grid.Row="9" Grid.Column="1" Name="FastForwardPlaybackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding FastForwardPlaybackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Rewind -->
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Width="120">Rewind</TextBlock>
|
||||
<ComboBox Grid.Row="8" Grid.Column="1" HorizontalAlignment="Right" Name="RewindPlaybackKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Width="120">Rewind</TextBlock>
|
||||
<ComboBox Grid.Row="10" Grid.Column="1" Name="RewindPlaybackKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding RewindPlaybackKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Volume Up -->
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Width="120">Volume Up</TextBlock>
|
||||
<ComboBox Grid.Row="9" Grid.Column="1" HorizontalAlignment="Right" Name="VolumeUpKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Width="120">Volume Up</TextBlock>
|
||||
<ComboBox Grid.Row="11" Grid.Column="1" Name="VolumeUpKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding VolumeUpKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Volume Down -->
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Width="120">Volume Down</TextBlock>
|
||||
<ComboBox Grid.Row="10" Grid.Column="1" HorizontalAlignment="Right" Name="VolumeDownKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Width="120">Volume Down</TextBlock>
|
||||
<ComboBox Grid.Row="12" Grid.Column="1" Name="VolumeDownKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding VolumeDownKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- Mute Toggle -->
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Width="120">Toggle Mute</TextBlock>
|
||||
<ComboBox Grid.Row="11" Grid.Column="1" HorizontalAlignment="Right" Name="ToggleMuteKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Width="120">Toggle Mute</TextBlock>
|
||||
<ComboBox Grid.Row="13" Grid.Column="1" Name="ToggleMuteKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding ToggleMuteKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
|
||||
<!-- De-Emphasis Toggle -->
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Width="120">Toggle De-Emphasis</TextBlock>
|
||||
<ComboBox Grid.Row="12" Grid.Column="1" HorizontalAlignment="Right" Name="ToggleDeEmphasisKeyBind" Margin="8,0,0,0" Width="120"/>
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Width="120">Toggle De-Emphasis</TextBlock>
|
||||
<ComboBox Grid.Row="14" Grid.Column="1" Name="ToggleDeEmphasisKeyBind"
|
||||
Items="{Binding KeyboardList}" SelectedItem="{Binding ToggleDeEmphasisKey, Mode=TwoWay}"
|
||||
HorizontalAlignment="Right" Margin="8,0,0,0" Width="120"/>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
<Button Name="ApplyButton">Apply</Button>
|
||||
<Button Name="ApplyButton" Command="{Binding ApplySettingsCommand}">Apply</Button>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
</ReactiveWindow>
|
||||
@@ -1,186 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using RedBookPlayer.GUI.ViewModels;
|
||||
|
||||
namespace RedBookPlayer.GUI.Views
|
||||
{
|
||||
public class SettingsWindow : Window
|
||||
public class SettingsWindow : ReactiveWindow<SettingsViewModel>
|
||||
{
|
||||
private readonly Settings _settings;
|
||||
private string _selectedTheme;
|
||||
private ListBox _themeList;
|
||||
|
||||
public SettingsWindow() {}
|
||||
|
||||
public SettingsWindow(Settings settings)
|
||||
{
|
||||
DataContext = _settings = settings;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void ThemeList_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (e.AddedItems.Count == 0)
|
||||
return;
|
||||
|
||||
_selectedTheme = (string)e.AddedItems[0];
|
||||
}
|
||||
|
||||
public void ApplySettings(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(_selectedTheme))
|
||||
{
|
||||
_settings.SelectedTheme = _selectedTheme;
|
||||
MainWindow.ApplyTheme(_selectedTheme);
|
||||
}
|
||||
|
||||
SaveKeyboardList();
|
||||
_settings.Save();
|
||||
}
|
||||
|
||||
public void UpdateView() => this.FindControl<TextBlock>("VolumeLabel").Text = _settings.Volume.ToString();
|
||||
|
||||
void InitializeComponent()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
PopulateThemes();
|
||||
PopulateKeyboardList();
|
||||
|
||||
this.FindControl<Button>("ApplyButton").Click += ApplySettings;
|
||||
this.FindControl<Slider>("VolumeSlider").PropertyChanged += (s, e) => UpdateView();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate the list of themes
|
||||
/// </summary>
|
||||
private void PopulateThemes()
|
||||
{
|
||||
// Get a reference to the theme list
|
||||
_themeList = this.FindControl<ListBox>("ThemeList");
|
||||
_themeList.SelectionChanged += ThemeList_SelectionChanged;
|
||||
|
||||
// Create a list of all found themes
|
||||
List<string> items = new List<string>();
|
||||
items.Add("default");
|
||||
|
||||
// Ensure the theme directory exists
|
||||
if(!Directory.Exists("themes/"))
|
||||
Directory.CreateDirectory("themes/");
|
||||
|
||||
// Add all theme directories if they're valid
|
||||
foreach(string dir in Directory.EnumerateDirectories("themes/"))
|
||||
{
|
||||
string themeName = dir.Split('/')[1];
|
||||
|
||||
if(!File.Exists($"themes/{themeName}/view.xaml"))
|
||||
continue;
|
||||
|
||||
items.Add(themeName);
|
||||
}
|
||||
|
||||
_themeList.Items = items;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populate all of the keyboard bindings
|
||||
/// </summary>
|
||||
private void PopulateKeyboardList()
|
||||
{
|
||||
// Access all of the combo boxes
|
||||
ComboBox loadImageKeyBind = this.FindControl<ComboBox>("LoadImageKeyBind");
|
||||
ComboBox togglePlaybackKeyBind = this.FindControl<ComboBox>("TogglePlaybackKeyBind");
|
||||
ComboBox stopPlaybackKeyBind = this.FindControl<ComboBox>("StopPlaybackKeyBind");
|
||||
ComboBox nextTrackKeyBind = this.FindControl<ComboBox>("NextTrackKeyBind");
|
||||
ComboBox previousTrackKeyBind = this.FindControl<ComboBox>("PreviousTrackKeyBind");
|
||||
ComboBox nextIndexKeyBind = this.FindControl<ComboBox>("NextIndexKeyBind");
|
||||
ComboBox previousIndexKeyBind = this.FindControl<ComboBox>("PreviousIndexKeyBind");
|
||||
ComboBox fastForwardPlaybackKeyBind = this.FindControl<ComboBox>("FastForwardPlaybackKeyBind");
|
||||
ComboBox rewindPlaybackKeyBind = this.FindControl<ComboBox>("RewindPlaybackKeyBind");
|
||||
ComboBox volumeUpKeyBind = this.FindControl<ComboBox>("VolumeUpKeyBind");
|
||||
ComboBox volumeDownKeyBind = this.FindControl<ComboBox>("VolumeDownKeyBind");
|
||||
ComboBox toggleMuteKeyBind = this.FindControl<ComboBox>("ToggleMuteKeyBind");
|
||||
ComboBox toggleDeEmphasisKeyBind = this.FindControl<ComboBox>("ToggleDeEmphasisKeyBind");
|
||||
|
||||
// Assign the list of values to all of them
|
||||
Array keyboardList = GenerateKeyboardList();
|
||||
loadImageKeyBind.Items = keyboardList;
|
||||
togglePlaybackKeyBind.Items = keyboardList;
|
||||
stopPlaybackKeyBind.Items = keyboardList;
|
||||
nextTrackKeyBind.Items = keyboardList;
|
||||
previousTrackKeyBind.Items = keyboardList;
|
||||
nextIndexKeyBind.Items = keyboardList;
|
||||
previousIndexKeyBind.Items = keyboardList;
|
||||
fastForwardPlaybackKeyBind.Items = keyboardList;
|
||||
rewindPlaybackKeyBind.Items = keyboardList;
|
||||
volumeUpKeyBind.Items = keyboardList;
|
||||
volumeDownKeyBind.Items = keyboardList;
|
||||
toggleMuteKeyBind.Items = keyboardList;
|
||||
toggleDeEmphasisKeyBind.Items = keyboardList;
|
||||
|
||||
// Set all of the currently selected items
|
||||
loadImageKeyBind.SelectedItem = _settings.LoadImageKey;
|
||||
togglePlaybackKeyBind.SelectedItem = _settings.TogglePlaybackKey;
|
||||
stopPlaybackKeyBind.SelectedItem = _settings.StopPlaybackKey;
|
||||
nextTrackKeyBind.SelectedItem = _settings.NextTrackKey;
|
||||
previousTrackKeyBind.SelectedItem = _settings.PreviousTrackKey;
|
||||
nextIndexKeyBind.SelectedItem = _settings.NextIndexKey;
|
||||
previousIndexKeyBind.SelectedItem = _settings.PreviousIndexKey;
|
||||
fastForwardPlaybackKeyBind.SelectedItem = _settings.FastForwardPlaybackKey;
|
||||
rewindPlaybackKeyBind.SelectedItem = _settings.RewindPlaybackKey;
|
||||
volumeUpKeyBind.SelectedItem = _settings.VolumeUpKey;
|
||||
volumeDownKeyBind.SelectedItem = _settings.VolumeDownKey;
|
||||
toggleMuteKeyBind.SelectedItem = _settings.ToggleMuteKey;
|
||||
toggleDeEmphasisKeyBind.SelectedItem = _settings.ToggleDeEmphasisKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save back all values from keyboard bindings
|
||||
/// </summary>
|
||||
private void SaveKeyboardList()
|
||||
{
|
||||
// Access all of the combo boxes
|
||||
ComboBox loadImageKeyBind = this.FindControl<ComboBox>("LoadImageKeyBind");
|
||||
ComboBox togglePlaybackKeyBind = this.FindControl<ComboBox>("TogglePlaybackKeyBind");
|
||||
ComboBox stopPlaybackKeyBind = this.FindControl<ComboBox>("StopPlaybackKeyBind");
|
||||
ComboBox nextTrackKeyBind = this.FindControl<ComboBox>("NextTrackKeyBind");
|
||||
ComboBox previousTrackKeyBind = this.FindControl<ComboBox>("PreviousTrackKeyBind");
|
||||
ComboBox nextIndexKeyBind = this.FindControl<ComboBox>("NextIndexKeyBind");
|
||||
ComboBox previousIndexKeyBind = this.FindControl<ComboBox>("PreviousIndexKeyBind");
|
||||
ComboBox fastForwardPlaybackKeyBind = this.FindControl<ComboBox>("FastForwardPlaybackKeyBind");
|
||||
ComboBox rewindPlaybackKeyBind = this.FindControl<ComboBox>("RewindPlaybackKeyBind");
|
||||
ComboBox volumeUpKeyBind = this.FindControl<ComboBox>("VolumeUpKeyBind");
|
||||
ComboBox volumeDownKeyBind = this.FindControl<ComboBox>("VolumeDownKeyBind");
|
||||
ComboBox toggleMuteKeyBind = this.FindControl<ComboBox>("ToggleMuteKeyBind");
|
||||
ComboBox toggleDeEmphasisKeyBind = this.FindControl<ComboBox>("ToggleDeEmphasisKeyBind");
|
||||
|
||||
// Set all of the currently selected items
|
||||
_settings.LoadImageKey = (Key)loadImageKeyBind.SelectedItem;
|
||||
_settings.TogglePlaybackKey = (Key)togglePlaybackKeyBind.SelectedItem;
|
||||
_settings.StopPlaybackKey = (Key)stopPlaybackKeyBind.SelectedItem;
|
||||
_settings.NextTrackKey = (Key)nextTrackKeyBind.SelectedItem;
|
||||
_settings.PreviousTrackKey = (Key)previousTrackKeyBind.SelectedItem;
|
||||
_settings.NextIndexKey = (Key)nextIndexKeyBind.SelectedItem;
|
||||
_settings.PreviousIndexKey = (Key)previousIndexKeyBind.SelectedItem;
|
||||
_settings.FastForwardPlaybackKey = (Key)fastForwardPlaybackKeyBind.SelectedItem;
|
||||
_settings.RewindPlaybackKey = (Key)rewindPlaybackKeyBind.SelectedItem;
|
||||
_settings.VolumeUpKey = (Key)volumeUpKeyBind.SelectedItem;
|
||||
_settings.VolumeDownKey = (Key)volumeDownKeyBind.SelectedItem;
|
||||
_settings.ToggleMuteKey = (Key)toggleMuteKeyBind.SelectedItem;
|
||||
_settings.ToggleDeEmphasisKey = (Key)toggleDeEmphasisKeyBind.SelectedItem;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a list of keyboard keys for mapping
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private Array GenerateKeyboardList()
|
||||
{
|
||||
return Enum.GetValues(typeof(Key));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user