Add Views namespace

This commit is contained in:
Matt Nadareski
2021-07-12 15:49:43 -07:00
parent b11ccc48db
commit f2712d3238
7 changed files with 7 additions and 6 deletions

View File

@@ -0,0 +1,7 @@
<Window 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.MainWindow" Title="RedBookPlayer" SizeToContent="WidthAndHeight"
DragDrop.AllowDrop="True">
<ContentControl Name="Content" />
</Window>

View File

@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using RedBookPlayer.GUI.ViewModels;
namespace RedBookPlayer.GUI.Views
{
public class MainWindow : Window
{
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();
}
/// <summary>
/// Initialize the main window
/// </summary>
void InitializeComponent()
{
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);
}
#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
}
}

View File

@@ -0,0 +1,104 @@
<UserControl 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">
<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">
<Button Command="{Binding PlayCommand}" Width="100" Margin="0,0,16,0">Play</Button>
<Button Command="{Binding PauseCommand}" Width="100" Margin="0,0,16,0">Pause</Button>
<Button Command="{Binding StopCommand}" Width="100" Margin="0,0,16,0">Stop</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,16">
<Button Command="{Binding PreviousTrackCommand}" Width="100" Margin="0,0,16,0">Previous Track</Button>
<Button Command="{Binding NextTrackCommand}" Width="100" Margin="0,0,16,0">Next Track</Button>
<Button Command="{Binding PreviousIndexCommand}" Width="100" Margin="0,0,16,0">Previous Index</Button>
<Button Command="{Binding NextIndexCommand}" Width="100" Margin="0,0,16,0">Next Index</Button>
<RepeatButton Command="{Binding RewindCommand}" Width="100" Margin="0,0,16,0">Rewind</RepeatButton>
<RepeatButton Command="{Binding FastForwardCommand}" Width="100">Fast Forward</RepeatButton>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,16">
<StackPanel Margin="0,0,32,0">
<TextBlock Margin="0,0,0,4">TRACK</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="TrackDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TrackDigit2" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
<StackPanel Margin="0,0,32,0">
<TextBlock Margin="0,0,0,4">INDEX</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="IndexDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="IndexDigit2" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Margin="0,0,0,4">TIME</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="TimeDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TimeDigit2" Width="42" Height="51" Source="/Assets/-.png" />
<Image Width="11" Height="51" Source="/Assets/colon.png" />
<Image Name="TimeDigit3" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TimeDigit4" Width="42" Height="51" Source="/Assets/-.png" />
<Image Width="11" Height="51" Source="/Assets/colon.png" />
<Image Name="TimeDigit5" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TimeDigit6" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,16">
<StackPanel Margin="0,0,32,0">
<TextBlock Margin="0,0,0,4">TRACKS</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="TotalTracksDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TotalTracksDigit2" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
<StackPanel Margin="0,0,32,0">
<TextBlock Margin="0,0,0,4">INDEXES</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="TotalIndexesDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TotalIndexesDigit2" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
<StackPanel>
<TextBlock Margin="0,0,0,4">TOTAL</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Image Name="TotalTimeDigit1" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TotalTimeDigit2" Width="42" Height="51" Source="/Assets/-.png" />
<Image Width="11" Height="51" Source="/Assets/colon.png" />
<Image Name="TotalTimeDigit3" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TotalTimeDigit4" Width="42" Height="51" Source="/Assets/-.png" />
<Image Width="11" Height="51" Source="/Assets/colon.png" />
<Image Name="TotalTimeDigit5" Width="42" Height="51" Source="/Assets/-.png" />
<Image Name="TotalTimeDigit6" Width="42" Height="51" Source="/Assets/-.png" />
</StackPanel>
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,16">
<Button Command="{Binding EnableDeEmphasisCommand}" IsVisible="{Binding !ApplyDeEmphasis}" Width="200"
Margin="0,0,16,0">
Enable De-Emphasis
</Button>
<Button Command="{Binding DisableDeEmphasisCommand}" IsVisible="{Binding ApplyDeEmphasis}" Width="200"
Margin="0,0,16,0">
Disable De-Emphasis
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding IsDataTrack}">AUDIO</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding !IsDataTrack}">AUDIO</TextBlock>
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !IsDataTrack}">DATA</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding IsDataTrack}">DATA</TextBlock>
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !TrackHasEmphasis}">EMPHASIS</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding TrackHasEmphasis}">EMPHASIS</TextBlock>
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !CopyAllowed}">COPY</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding CopyAllowed}">COPY</TextBlock>
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !QuadChannel}">4CH</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding QuadChannel}">4CH</TextBlock>
<TextBlock Margin="0,0,16,0" Foreground="LightGray" IsVisible="{Binding !HiddenTrack}">HIDDEN</TextBlock>
<TextBlock Margin="0,0,16,0" IsVisible="{Binding HiddenTrack}">HIDDEN</TextBlock>
<TextBlock Margin="0,0,16,0" Text="{Binding Volume}"/>
</StackPanel>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,73 @@
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using RedBookPlayer.GUI.ViewModels;
namespace RedBookPlayer.GUI.Views
{
public class PlayerView : UserControl
{
/// <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
}
}

View File

@@ -0,0 +1,122 @@
<Window 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"
d:DesignHeight="450" x:Class="RedBookPlayer.GUI.Views.SettingsWindow" Title="Settings" SizeToContent="WidthAndHeight">
<StackPanel>
<TabControl>
<TabItem Header="UI Settings">
<DockPanel Margin="16">
<TextBlock DockPanel.Dock="Top" Margin="0,0,0,4">Themes</TextBlock>
<StackPanel DockPanel.Dock="Bottom">
<WrapPanel Margin="0,0,0,16">
<CheckBox IsChecked="{Binding AutoPlay}" Margin="0,0,8,0" />
<TextBlock VerticalAlignment="Center">Auto-play CD on load</TextBlock>
</WrapPanel>
<WrapPanel Margin="0,0,0,16">
<CheckBox IsChecked="{Binding IndexButtonChangeTrack}" Margin="0,0,8,0" />
<TextBlock VerticalAlignment="Center">Index navigation can change track</TextBlock>
</WrapPanel>
<WrapPanel Margin="0,0,0,16">
<CheckBox IsChecked="{Binding PlayHiddenTracks}" Margin="0,0,8,0" />
<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>
</WrapPanel>
<WrapPanel Margin="0,0,0,16">
<CheckBox IsChecked="{Binding GenerateMissingTOC}" Margin="0,0,8,0"/>
<TextBlock VerticalAlignment="Center">Generate a TOC if the disc is missing one</TextBlock>
</WrapPanel>
<DockPanel Margin="0,0,0,16">
<TextBlock VerticalAlignment="Center" Margin="0,0,8,0" DockPanel.Dock="Left">Default Volume</TextBlock>
<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" />
</DockPanel>
</StackPanel>
<ListBox Name="ThemeList" SelectionMode="Single" Margin="0,0,0,16" />
</DockPanel>
</TabItem>
<TabItem Header="Keyboard Bindings">
<Grid Margin="16">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
<!-- 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"/>
</Grid>
</TabItem>
</TabControl>
<Button Name="ApplyButton">Apply</Button>
</StackPanel>
</Window>

View File

@@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.IO;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
namespace RedBookPlayer.GUI.Views
{
public class SettingsWindow : Window
{
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));
}
}
}