2021-03-24 17:34:04 -03:00
|
|
|
using System;
|
2021-06-29 21:00:34 -07:00
|
|
|
using System.Collections.Generic;
|
2021-03-24 17:34:04 -03:00
|
|
|
using System.IO;
|
2021-06-06 20:28:36 +01:00
|
|
|
using System.Xml;
|
|
|
|
|
using Avalonia.Controls;
|
|
|
|
|
using Avalonia.Input;
|
|
|
|
|
using Avalonia.Markup.Xaml;
|
2021-07-12 10:41:11 -07:00
|
|
|
using RedBookPlayer.GUI.ViewModels;
|
2021-03-19 17:07:27 -03:00
|
|
|
|
2021-07-12 15:49:43 -07:00
|
|
|
namespace RedBookPlayer.GUI.Views
|
2021-03-19 17:07:27 -03:00
|
|
|
{
|
|
|
|
|
public class MainWindow : Window
|
|
|
|
|
{
|
2021-06-06 20:28:36 +01:00
|
|
|
public static MainWindow Instance;
|
|
|
|
|
public ContentControl ContentControl;
|
|
|
|
|
public Window settingsWindow;
|
2021-03-19 17:07:27 -03:00
|
|
|
|
|
|
|
|
public MainWindow()
|
|
|
|
|
{
|
|
|
|
|
Instance = this;
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 21:39:05 -07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Apply a custom theme to the player
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="theme">Path to the theme under the themes directory</param>
|
2021-03-24 17:34:04 -03:00
|
|
|
public static void ApplyTheme(string theme)
|
|
|
|
|
{
|
2021-06-06 21:39:05 -07:00
|
|
|
// If no theme path is provided, we can ignore
|
|
|
|
|
if(string.IsNullOrWhiteSpace(theme))
|
2021-03-24 17:34:04 -03:00
|
|
|
return;
|
|
|
|
|
|
2021-07-05 23:09:22 -07:00
|
|
|
// If we already have a view, cache the view model
|
|
|
|
|
PlayerViewModel pvm = ((PlayerView)Instance.ContentControl.Content).PlayerViewModel;
|
|
|
|
|
|
2021-06-06 21:39:05 -07:00
|
|
|
// If the theme name is "default", we assume the internal theme is used
|
2021-06-07 09:08:10 -07:00
|
|
|
if(theme.Equals("default", StringComparison.CurrentCultureIgnoreCase))
|
2021-03-24 17:34:04 -03:00
|
|
|
{
|
2021-07-05 23:09:22 -07:00
|
|
|
Instance.ContentControl.Content = new PlayerView(pvm);
|
2021-03-24 17:34:04 -03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-06-06 21:39:05 -07:00
|
|
|
string themeDirectory = $"{Directory.GetCurrentDirectory()}/themes/{theme}";
|
|
|
|
|
string xamlPath = $"{themeDirectory}/view.xaml";
|
2021-03-24 17:34:04 -03:00
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
if(!File.Exists(xamlPath))
|
2021-03-24 17:34:04 -03:00
|
|
|
{
|
2021-06-06 20:28:36 +01:00
|
|
|
Console.WriteLine("Warning: specified theme doesn't exist, reverting to default");
|
2021-03-24 17:34:04 -03:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
2021-06-06 21:39:05 -07:00
|
|
|
string xaml = File.ReadAllText(xamlPath);
|
|
|
|
|
xaml = xaml.Replace("Source=\"", $"Source=\"file://{themeDirectory}/");
|
2021-07-05 23:09:22 -07:00
|
|
|
Instance.ContentControl.Content = new PlayerView(xaml, pvm);
|
2021-03-24 17:34:04 -03:00
|
|
|
}
|
2021-06-06 20:28:36 +01:00
|
|
|
catch(XmlException ex)
|
2021-03-24 17:34:04 -03:00
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Error: invalid theme XAML ({ex.Message}), reverting to default");
|
2021-07-05 23:09:22 -07:00
|
|
|
Instance.ContentControl.Content = new PlayerView(pvm);
|
2021-03-24 17:34:04 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
Instance.Width = ((PlayerView)Instance.ContentControl.Content).Width;
|
|
|
|
|
Instance.Height = ((PlayerView)Instance.ContentControl.Content).Height;
|
2021-07-12 15:40:56 -07:00
|
|
|
|
|
|
|
|
pvm.InitializeDigits();
|
2021-03-24 17:34:04 -03:00
|
|
|
}
|
|
|
|
|
|
2021-06-29 21:00:34 -07:00
|
|
|
/// <summary>
|
|
|
|
|
/// Initialize the main window
|
|
|
|
|
/// </summary>
|
2021-06-06 20:28:36 +01:00
|
|
|
void InitializeComponent()
|
2021-03-19 17:07:27 -03:00
|
|
|
{
|
|
|
|
|
AvaloniaXamlLoader.Load(this);
|
|
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
ContentControl = this.FindControl<ContentControl>("Content");
|
2021-03-19 17:07:27 -03:00
|
|
|
ContentControl.Content = new PlayerView();
|
|
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
Instance.MaxWidth = ((PlayerView)Instance.ContentControl.Content).Width;
|
|
|
|
|
Instance.MaxHeight = ((PlayerView)Instance.ContentControl.Content).Height;
|
2021-03-19 17:07:27 -03:00
|
|
|
|
|
|
|
|
ContentControl.Content = new PlayerView();
|
|
|
|
|
|
2021-07-12 15:40:56 -07:00
|
|
|
((PlayerView)ContentControl.Content).PlayerViewModel.InitializeDigits();
|
|
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
CanResize = false;
|
|
|
|
|
|
|
|
|
|
KeyDown += OnKeyDown;
|
2021-03-19 17:07:27 -03:00
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
Closing += (s, e) =>
|
2021-03-19 17:07:27 -03:00
|
|
|
{
|
2021-03-23 19:58:25 -03:00
|
|
|
settingsWindow?.Close();
|
|
|
|
|
settingsWindow = null;
|
2021-03-19 17:07:27 -03:00
|
|
|
};
|
|
|
|
|
|
2021-06-06 20:28:36 +01:00
|
|
|
Closing += (e, f) =>
|
2021-03-19 17:07:27 -03:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
((PlayerView)ContentControl.Content).PlayerViewModel.ExecuteStop();
|
2021-03-19 17:07:27 -03:00
|
|
|
};
|
2021-06-29 21:00:34 -07:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2021-07-12 12:38:33 -07:00
|
|
|
bool loaded = await playerView?.PlayerViewModel?.LoadImage(filename);
|
2021-06-29 21:00:34 -07:00
|
|
|
if(loaded)
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-03-19 17:07:27 -03:00
|
|
|
}
|
2021-06-29 21:00:34 -07:00
|
|
|
|
|
|
|
|
public void OnKeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
2021-06-30 13:55:49 -07:00
|
|
|
PlayerView playerView = ContentControl.Content as PlayerView;
|
|
|
|
|
|
|
|
|
|
// Open settings window
|
2021-06-30 16:16:49 -07:00
|
|
|
if(e.Key == App.Settings.OpenSettingsKey)
|
2021-06-29 21:00:34 -07:00
|
|
|
{
|
|
|
|
|
settingsWindow = new SettingsWindow(App.Settings);
|
2021-07-05 11:55:36 -07:00
|
|
|
settingsWindow.Closed += OnSettingsClosed;
|
2021-06-29 21:00:34 -07:00
|
|
|
settingsWindow.Show();
|
|
|
|
|
}
|
2021-06-30 13:55:49 -07:00
|
|
|
|
|
|
|
|
// Load image
|
2021-06-30 16:16:49 -07:00
|
|
|
else if (e.Key == App.Settings.LoadImageKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 12:38:33 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteLoad();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Toggle playback
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.TogglePlaybackKey || e.Key == Key.MediaPlayPause)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteTogglePlayPause();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Stop playback
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.StopPlaybackKey || e.Key == Key.MediaStop)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteStop();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Next Track
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.NextTrackKey || e.Key == Key.MediaNextTrack)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteNextTrack();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Previous Track
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.PreviousTrackKey || e.Key == Key.MediaPreviousTrack)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecutePreviousTrack();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Next Index
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.NextIndexKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteNextIndex();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Previous Index
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.PreviousIndexKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecutePreviousIndex();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fast Foward
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.FastForwardPlaybackKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteFastForward();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Rewind
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.RewindPlaybackKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteRewind();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-01 10:19:25 -07:00
|
|
|
// Volume Up
|
|
|
|
|
else if(e.Key == App.Settings.VolumeUpKey || e.Key == Key.VolumeUp)
|
|
|
|
|
{
|
2021-07-01 15:18:59 -07:00
|
|
|
int increment = 1;
|
|
|
|
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
|
|
|
|
increment *= 2;
|
|
|
|
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
|
|
|
|
increment *= 5;
|
2021-07-03 16:04:18 -07:00
|
|
|
|
|
|
|
|
if(playerView?.PlayerViewModel?.Volume != null)
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume + increment);
|
2021-07-01 10:19:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Volume Down
|
|
|
|
|
else if(e.Key == App.Settings.VolumeDownKey || e.Key == Key.VolumeDown)
|
|
|
|
|
{
|
2021-07-01 15:18:59 -07:00
|
|
|
int decrement = 1;
|
|
|
|
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Control))
|
|
|
|
|
decrement *= 2;
|
|
|
|
|
if(e.KeyModifiers.HasFlag(KeyModifiers.Shift))
|
|
|
|
|
decrement *= 5;
|
|
|
|
|
|
2021-07-03 16:04:18 -07:00
|
|
|
if (playerView?.PlayerViewModel?.Volume != null)
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView.PlayerViewModel.ExecuteSetVolume(playerView.PlayerViewModel.Volume - decrement);
|
2021-07-01 10:19:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Mute Toggle
|
|
|
|
|
else if(e.Key == App.Settings.ToggleMuteKey || e.Key == Key.VolumeMute)
|
|
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteToggleMute();
|
2021-07-01 10:19:25 -07:00
|
|
|
}
|
|
|
|
|
|
2021-06-30 13:55:49 -07:00
|
|
|
// Emphasis Toggle
|
2021-06-30 16:16:49 -07:00
|
|
|
else if(e.Key == App.Settings.ToggleDeEmphasisKey)
|
2021-06-30 13:55:49 -07:00
|
|
|
{
|
2021-07-12 10:41:11 -07:00
|
|
|
playerView?.PlayerViewModel?.ExecuteToggleDeEmphasis();
|
2021-06-30 13:55:49 -07:00
|
|
|
}
|
2021-06-29 21:00:34 -07:00
|
|
|
}
|
|
|
|
|
|
2021-07-05 11:55:36 -07:00
|
|
|
public void OnSettingsClosed(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
PlayerView playerView = ContentControl.Content as PlayerView;
|
|
|
|
|
playerView?.UpdateViewModel();
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-29 21:00:34 -07:00
|
|
|
#endregion
|
2021-03-19 17:07:27 -03:00
|
|
|
}
|
|
|
|
|
}
|