mirror of
https://github.com/Royce551/FRESHMusicPlayer.git
synced 2025-01-22 10:51:52 -05:00
first round of design adjustments
This commit is contained in:
parent
b882cce628
commit
d5284a8bc6
14 changed files with 950 additions and 761 deletions
|
@ -136,6 +136,8 @@
|
|||
<Compile Include="Handlers\Notifications\Notification.cs" />
|
||||
<Compile Include="Handlers\PlaytimeTrackingHandler.cs" />
|
||||
<Compile Include="Handlers\UpdateHandler.cs" />
|
||||
<Compile Include="MainWindow_Controls.xaml.cs" />
|
||||
<Compile Include="MainWindow_Logic.xaml.cs" />
|
||||
<Compile Include="Pages\FullscreenPage.xaml.cs">
|
||||
<DependentUpon>FullscreenPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
|
|
@ -20,8 +20,8 @@ namespace FRESHMusicPlayer.Forms.Playlists
|
|||
|
||||
private readonly GUILibrary library;
|
||||
private readonly PlaylistManagement window;
|
||||
private readonly Menu selectedMenu;
|
||||
public PlaylistEntry(string playlist, string path, GUILibrary library, PlaylistManagement window, Menu selectedMenu)
|
||||
private readonly Tab selectedMenu;
|
||||
public PlaylistEntry(string playlist, string path, GUILibrary library, PlaylistManagement window, Tab selectedMenu)
|
||||
{
|
||||
this.library = library;
|
||||
this.window = window;
|
||||
|
@ -30,7 +30,7 @@ namespace FRESHMusicPlayer.Forms.Playlists
|
|||
if (path is null) trackExists = false;
|
||||
TitleLabel.Text = playlist;
|
||||
|
||||
if (selectedMenu == Menu.Artists) AddThingButton.Content = $"+ {Properties.Resources.TAGEDITOR_ARTIST}";
|
||||
if (selectedMenu == Tab.Artists) AddThingButton.Content = $"+ {Properties.Resources.TAGEDITOR_ARTIST}";
|
||||
else AddThingButton.Content = $"+ {Properties.Resources.TRACKINFO_ALBUM}";
|
||||
|
||||
this.playlist = playlist;
|
||||
|
@ -57,7 +57,7 @@ namespace FRESHMusicPlayer.Forms.Playlists
|
|||
if (trackExists)
|
||||
{
|
||||
AddButton.Visibility = RemoveButton.Visibility = Visibility.Visible;
|
||||
if (selectedMenu == Menu.Artists || selectedMenu == Menu.Albums)
|
||||
if (selectedMenu == Tab.Artists || selectedMenu == Tab.Albums)
|
||||
AddThingButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ namespace FRESHMusicPlayer.Forms.Playlists
|
|||
private void AddThingButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
List<DatabaseTrack> things;
|
||||
if (selectedMenu == Menu.Artists)
|
||||
if (selectedMenu == Tab.Artists)
|
||||
things = library.ReadTracksForArtist(library.GetFallbackTrack(path).Artist);
|
||||
else
|
||||
things = library.ReadTracksForAlbum(library.GetFallbackTrack(path).Album);
|
||||
|
|
|
@ -18,8 +18,8 @@ namespace FRESHMusicPlayer.Forms.Playlists
|
|||
|
||||
private readonly GUILibrary library;
|
||||
private readonly NotificationHandler notificationHandler;
|
||||
private readonly Menu selectedMenu;
|
||||
public PlaylistManagement(GUILibrary library, NotificationHandler notificationHandler, Menu selectedMenu, string track = null)
|
||||
private readonly Tab selectedMenu;
|
||||
public PlaylistManagement(GUILibrary library, NotificationHandler notificationHandler, Tab selectedMenu, string track = null)
|
||||
{
|
||||
this.library = library;
|
||||
this.notificationHandler = notificationHandler;
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace FRESHMusicPlayer.Handlers.Configuration
|
|||
/// <summary>
|
||||
/// The last menu FMP was on before closing
|
||||
/// </summary>
|
||||
public Menu CurrentMenu { get; set; } = Menu.Import;
|
||||
public Tab CurrentMenu { get; set; } = Tab.Import;
|
||||
public List<string> AutoImportPaths { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
</Image.ToolTip>
|
||||
</Image>
|
||||
<TextBlock x:Name="TitleLabel" HorizontalAlignment="Stretch" Margin="5,5,40,0" TextWrapping="NoWrap" Text="{x:Static resx:Resources.MAINWINDOW_NOTHINGPLAYING}" VerticalAlignment="Top" FontWeight="Bold" FontSize="22" Grid.Column="1" Height="30" Foreground="{StaticResource PrimaryTextColor}" TextTrimming="CharacterEllipsis" MouseLeftButtonDown="TrackTitle_MouseLeftButtonDown" MouseRightButtonDown="TrackTitle_MouseRightButtonDown" Cursor="Hand" Grid.ColumnSpan="2" Panel.ZIndex="0"/>
|
||||
<Slider x:Name="ProgressBar" Grid.Column="1" HorizontalAlignment="Stretch" Margin="37,54,45,0" VerticalAlignment="Top" Height="21" Style="{StaticResource Progress_Slider}" Value="9.8" Thumb.DragStarted="ProgressBar_DragStarted" Thumb.DragCompleted="ProgressBar_DragCompleted" ValueChanged="ProgressBar_ValueChanged" IsMoveToPointEnabled="True" MouseLeftButtonUp="ProgressBar_MouseLeftButtonUp"/>
|
||||
<Slider x:Name="ProgressBar" Grid.Column="1" HorizontalAlignment="Stretch" Margin="37,54,45,0" VerticalAlignment="Top" Height="21" Style="{StaticResource Progress_Slider}" Value="9.8" Thumb.DragStarted="ProgressBar_DragStarted" Thumb.DragCompleted="ProgressBar_DragCompleted" ValueChanged="ProgressBar_ValueChanged" IsMoveToPointEnabled="True" MouseLeftButtonUp="ProgressBar_MouseLeftButtonUp" Cursor="Hand"/>
|
||||
<TextBlock x:Name="ProgressIndicator1" Grid.Column="1" Margin="5,56,0,0" TextWrapping="NoWrap" Text="10:00" Foreground="{StaticResource SecondaryTextColor}" Height="15" VerticalAlignment="Top" HorizontalAlignment="Left" Width="28"/>
|
||||
<TextBlock x:Name="ProgressIndicator2" Grid.Column="1" Margin="0,0,0,13" TextWrapping="NoWrap" Text="10:00" Foreground="{StaticResource SecondaryTextColor}" Height="15" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="40" MouseLeftButtonDown="ProgressIndicator2_MouseLeftButtonDown"/>
|
||||
<TextBlock x:Name="ArtistLabel" HorizontalAlignment="Stretch" Margin="5,35,10,0" TextWrapping="NoWrap" Text="{x:Static resx:Resources.MAINWINDOW_NOTHINGPLAYING}" VerticalAlignment="Top" Grid.Column="1" Height="20" Foreground="{StaticResource SecondaryTextColor}" TextTrimming="CharacterEllipsis"/>
|
||||
|
|
|
@ -27,39 +27,21 @@ using WinForms = System.Windows.Forms;
|
|||
|
||||
namespace FRESHMusicPlayer
|
||||
{
|
||||
public enum Menu
|
||||
{
|
||||
Tracks,
|
||||
Artists,
|
||||
Albums,
|
||||
Playlists,
|
||||
Import,
|
||||
Fullscreen,
|
||||
Other
|
||||
}
|
||||
public enum AuxiliaryPane
|
||||
{
|
||||
None,
|
||||
Settings,
|
||||
QueueManagement,
|
||||
Search,
|
||||
Notifications,
|
||||
TrackInfo,
|
||||
Lyrics
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
// Initialization stuff
|
||||
// _Logic - Main window, player, systemwide logic
|
||||
// _Controls - Event handlers and other doo dads
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public Menu SelectedMenu = Menu.Tracks;
|
||||
public AuxiliaryPane SelectedAuxiliaryPane = AuxiliaryPane.None;
|
||||
public Player Player;
|
||||
public NotificationHandler NotificationHandler = new NotificationHandler();
|
||||
public GUILibrary Library;
|
||||
public IMetadataProvider CurrentTrack;
|
||||
|
||||
public const string WindowName = "FRESHMusicPlayer [Blueprint 11 b.10.02.2021; Not stable!]";
|
||||
public const string WindowName = "FRESHMusicPlayer [Blueprint 11 b.10.10.2021; Not stable!]";
|
||||
|
||||
public PlaytimeTrackingHandler TrackingHandler;
|
||||
public bool PauseAfterCurrentTrack = false;
|
||||
|
@ -140,660 +122,6 @@ namespace FRESHMusicPlayer
|
|||
}
|
||||
}
|
||||
|
||||
#region Controls
|
||||
public void PlayPauseMethod()
|
||||
{
|
||||
if (!Player.FileLoaded) return;
|
||||
if (Player.Paused)
|
||||
{
|
||||
Player.Resume();
|
||||
SetIntegrations(PlaybackStatus.Playing);
|
||||
ProgressTimer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Pause();
|
||||
SetIntegrations(PlaybackStatus.Paused);
|
||||
ProgressTimer.Stop();
|
||||
}
|
||||
UpdatePlayButtonState();
|
||||
}
|
||||
public void StopMethod()
|
||||
{
|
||||
Player.Queue.Clear();
|
||||
Player.Stop();
|
||||
}
|
||||
public async void NextTrackMethod() => await Player.NextAsync();
|
||||
public async void PreviousTrackMethod()
|
||||
{
|
||||
if (!Player.FileLoaded) return;
|
||||
if (Player.CurrentTime.TotalSeconds <= 5) await Player.PreviousAsync();
|
||||
else
|
||||
{
|
||||
Player.CurrentTime = TimeSpan.FromSeconds(0);
|
||||
ProgressTimer.Start(); // to resync the progress timer
|
||||
}
|
||||
}
|
||||
public void ShuffleMethod()
|
||||
{
|
||||
if (Player.Queue.Shuffle)
|
||||
{
|
||||
Player.Queue.Shuffle = false;
|
||||
ShuffleButton.Fill = (Brush)FindResource("PrimaryTextColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Queue.Shuffle = true;
|
||||
ShuffleButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
}
|
||||
public void RepeatOneMethod()
|
||||
{
|
||||
if (Player.Queue.RepeatMode == RepeatMode.None)
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.RepeatAll;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatAllIcon");
|
||||
RepeatOneButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
else if (Player.Queue.RepeatMode == RepeatMode.RepeatAll)
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.RepeatOne;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatOneIcon");
|
||||
RepeatOneButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.None;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatAllIcon");
|
||||
RepeatOneButton.Fill = (Brush)FindResource("PrimaryTextColor");
|
||||
}
|
||||
}
|
||||
public void UpdatePlayButtonState()
|
||||
{
|
||||
if (!Player.Paused) PlayPauseButton.Data = (Geometry)FindResource("PauseIcon");
|
||||
else PlayPauseButton.Data = (Geometry)FindResource("PlayIcon");
|
||||
if (PauseAfterCurrentTrack) ProgressIndicator2.Foreground = new SolidColorBrush(Color.FromRgb(212, 70, 63));
|
||||
else ProgressIndicator2.Foreground = (Brush)FindResource("SecondaryTextColor");
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Logic
|
||||
|
||||
public void SetCoverArtVisibility(bool mode)
|
||||
{
|
||||
if (!mode) CoverArtArea.Width = new GridLength(5);
|
||||
else CoverArtArea.Width = new GridLength(75);
|
||||
}
|
||||
public async void ShowAuxilliaryPane(AuxiliaryPane pane, int width = 235, bool openleft = false)
|
||||
{
|
||||
LoggingHandler.Log($"Showing pane --> {pane}");
|
||||
if (SelectedAuxiliaryPane == pane)
|
||||
{
|
||||
await HideAuxilliaryPane();
|
||||
return;
|
||||
}
|
||||
if (SelectedAuxiliaryPane != AuxiliaryPane.None) await HideAuxilliaryPane(true);
|
||||
switch (pane)
|
||||
{
|
||||
case AuxiliaryPane.Settings:
|
||||
RightFrame.Content = new SettingsPage(this);
|
||||
break;
|
||||
case AuxiliaryPane.QueueManagement:
|
||||
RightFrame.Content = new QueueManagement(this);
|
||||
break;
|
||||
case AuxiliaryPane.Search:
|
||||
RightFrame.Content = new SearchPage(this);
|
||||
break;
|
||||
case AuxiliaryPane.Notifications:
|
||||
RightFrame.Content = new NotificationPage(this);
|
||||
break;
|
||||
case AuxiliaryPane.TrackInfo:
|
||||
RightFrame.Content = new TrackInfoPage(this);
|
||||
break;
|
||||
case AuxiliaryPane.Lyrics:
|
||||
RightFrame.Content = new LyricsPage(this);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (!openleft) DockPanel.SetDock(RightFrame, Dock.Right); else DockPanel.SetDock(RightFrame, Dock.Left);
|
||||
RightFrame.Visibility = Visibility.Visible;
|
||||
RightFrame.Width = width;
|
||||
|
||||
var sb = InterfaceUtils.GetThicknessAnimation(
|
||||
openleft ? new Thickness(width * -1 /*negate*/, 0, 0, 0) : new Thickness(0, 0, width * -1 /*negate*/, 0),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(120),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseOut, Exponent = 3 });
|
||||
|
||||
sb.Begin(RightFrame);
|
||||
|
||||
SelectedAuxiliaryPane = pane;
|
||||
}
|
||||
public async Task HideAuxilliaryPane(bool animate = true)
|
||||
{
|
||||
var sb = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
DockPanel.GetDock(RightFrame) == Dock.Left ? new Thickness(RightFrame.Width * -1, 0, 0, 0) : new Thickness(0, 0, RightFrame.Width * -1, 0),
|
||||
TimeSpan.FromMilliseconds(120),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
|
||||
if (animate) await sb.BeginStoryboardAsync(RightFrame);
|
||||
RightFrame.Visibility = Visibility.Collapsed;
|
||||
RightFrame.Content = null;
|
||||
SelectedAuxiliaryPane = AuxiliaryPane.None;
|
||||
}
|
||||
public bool IsControlsBoxVisible { get; private set; } = false;
|
||||
public async void ShowControlsBox()
|
||||
{
|
||||
|
||||
var navBarStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0, -25, 0, 0),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
var controlsBoxStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0, 0, 0, -84),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
navBarStoryboard.Begin(MainBar);
|
||||
await controlsBoxStoryboard.BeginStoryboardAsync(ControlsBoxBorder);
|
||||
IsControlsBoxVisible = true;
|
||||
}
|
||||
public async void HideControlsBox()
|
||||
{
|
||||
|
||||
var navBarStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
new Thickness(0, -25, 0, 0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
var controlsBoxStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
new Thickness(0, 0, 0, -84),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
navBarStoryboard.Begin(MainBar);
|
||||
await controlsBoxStoryboard.BeginStoryboardAsync(ControlsBoxBorder);
|
||||
IsControlsBoxVisible = false;
|
||||
}
|
||||
|
||||
public void ProcessSettings(bool initialize = false)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
VolumeBar.Value = App.Config.Volume;
|
||||
ChangeTabs(App.Config.CurrentMenu);
|
||||
}
|
||||
if (App.Config.PlaybackTracking) TrackingHandler = new PlaytimeTrackingHandler(this);
|
||||
else if (TrackingHandler != null)
|
||||
{
|
||||
TrackingHandler?.Close();
|
||||
TrackingHandler = null;
|
||||
}
|
||||
}
|
||||
public async void HandlePersistence()
|
||||
{
|
||||
var persistenceFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence");
|
||||
if (File.Exists(persistenceFilePath))
|
||||
{
|
||||
var fields = File.ReadAllText(persistenceFilePath).Split(';');
|
||||
|
||||
var top = double.Parse(fields[2]);
|
||||
var left = double.Parse(fields[3]);
|
||||
var height = double.Parse(fields[4]);
|
||||
var width = double.Parse(fields[5]);
|
||||
var rect = new System.Drawing.Rectangle((int)left, (int)top, (int)width, (int)height);
|
||||
if (WinForms.Screen.AllScreens.Any(y => y.WorkingArea.IntersectsWith(rect)))
|
||||
{
|
||||
Top = top;
|
||||
Left = left;
|
||||
Height = height;
|
||||
Width = width;
|
||||
}
|
||||
if (fields[0] != string.Empty)
|
||||
{
|
||||
await Player.PlayAsync(fields[0]);
|
||||
Player.RepositionMusic(int.Parse(fields[1]));
|
||||
PlayPauseMethod();
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void WritePersistence()
|
||||
{
|
||||
if (Player.FileLoaded) // TODO: make this less shitty
|
||||
{
|
||||
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence"),
|
||||
$"{Player.FilePath};{(int)Player.CurrentBackend.CurrentTime.TotalSeconds};{Top};{Left};{Height};{Width}");
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence"),
|
||||
$";;{Top};{Left};{Height};{Width}");
|
||||
}
|
||||
}
|
||||
public MemoryStream GetCoverArtFromDirectory()
|
||||
{
|
||||
if (File.Exists(Player.FilePath))
|
||||
{
|
||||
var currentDirectory = Path.GetDirectoryName(Player.FilePath);
|
||||
foreach (var file in Directory.EnumerateFiles(currentDirectory))
|
||||
{
|
||||
if (Path.GetFileNameWithoutExtension(file).ToUpper() == "COVER" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "ARTWORK" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "FRONT" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "BACK" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == Player.FilePath)
|
||||
{
|
||||
if (Path.GetExtension(file) == ".png" || Path.GetExtension(file) == ".jpg" || Path.GetExtension(file) == ".jpeg")
|
||||
{
|
||||
return new MemoryStream(File.ReadAllBytes(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void UpdateIntegrations()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 10 && App.Config.IntegrateSMTC)
|
||||
{
|
||||
smtcIntegration = new SMTCIntegration(this);
|
||||
}
|
||||
else smtcIntegration = null;
|
||||
if (App.Config.IntegrateDiscordRPC) discordIntegration = new DiscordIntegration();
|
||||
else
|
||||
{
|
||||
discordIntegration?.Close();
|
||||
discordIntegration = null;
|
||||
}
|
||||
}
|
||||
public void SetIntegrations(PlaybackStatus status)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 10 && App.Config.IntegrateSMTC)
|
||||
{
|
||||
smtcIntegration?.Update(CurrentTrack, status);
|
||||
}
|
||||
if (App.Config.IntegrateDiscordRPC)
|
||||
{
|
||||
discordIntegration?.Update(CurrentTrack, status);
|
||||
}
|
||||
}
|
||||
public void ChangeTabs(Menu tab, string search = null)
|
||||
{
|
||||
LoggingHandler.Log($"Changing tabs -> {tab}");
|
||||
|
||||
var previousMenu = SelectedMenu;
|
||||
SelectedMenu = tab;
|
||||
TextBlock tabLabel;
|
||||
switch (SelectedMenu)
|
||||
{
|
||||
case Menu.Tracks:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = TracksTab;
|
||||
break;
|
||||
case Menu.Artists:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = ArtistsTab;
|
||||
break;
|
||||
case Menu.Albums:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = AlbumsTab;
|
||||
break;
|
||||
case Menu.Playlists:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = PlaylistsTab;
|
||||
break;
|
||||
case Menu.Import:
|
||||
ContentFrame.Content = new ImportPage(this);
|
||||
tabLabel = ImportTab;
|
||||
break;
|
||||
case Menu.Fullscreen:
|
||||
ContentFrame.Content = new FullscreenPage(this, previousMenu);
|
||||
tabLabel = ImportTab;
|
||||
break;
|
||||
default:
|
||||
tabLabel = null;
|
||||
break;
|
||||
}
|
||||
//TabChanged?.Invoke(null, search);
|
||||
TracksTab.FontWeight = ArtistsTab.FontWeight = AlbumsTab.FontWeight = PlaylistsTab.FontWeight = ImportTab.FontWeight = FontWeights.Normal;
|
||||
tabLabel.FontWeight = FontWeights.Bold;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
#region Player
|
||||
private void Player_SongStopped(object sender, EventArgs e)
|
||||
{
|
||||
Title = WindowName;
|
||||
TitleLabel.Text = ArtistLabel.Text = Properties.Resources.MAINWINDOW_NOTHINGPLAYING;
|
||||
ProgressTimer.Stop();
|
||||
CoverArtBox.Source = null;
|
||||
SetIntegrations(PlaybackStatus.Stopped);
|
||||
SetCoverArtVisibility(false);
|
||||
|
||||
LoggingHandler.Log("Stopping!");
|
||||
}
|
||||
|
||||
private void Player_SongLoading(object sender, EventArgs e) => Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
|
||||
private void Player_SongChanged(object sender, EventArgs e)
|
||||
{
|
||||
Mouse.OverrideCursor = null;
|
||||
CurrentTrack = Player.CurrentBackend.Metadata;
|
||||
Title = $"{string.Join(", ", CurrentTrack.Artists)} - {CurrentTrack.Title} | {WindowName}";
|
||||
TitleLabel.Text = CurrentTrack.Title;
|
||||
ArtistLabel.Text = string.Join(", ", CurrentTrack.Artists) == "" ? Properties.Resources.MAINWINDOW_NOARTIST : string.Join(", ", CurrentTrack.Artists);
|
||||
ProgressBar.Maximum = Player.CurrentBackend.TotalTime.TotalSeconds;
|
||||
if (Player.CurrentBackend.TotalTime.TotalSeconds != 0) ProgressIndicator2.Text = Player.CurrentBackend.TotalTime.ToString(@"mm\:ss");
|
||||
else ProgressIndicator2.Text = "∞";
|
||||
SetIntegrations(PlaybackStatus.Playing);
|
||||
UpdatePlayButtonState();
|
||||
if (CurrentTrack.CoverArt is null)
|
||||
{
|
||||
var file = GetCoverArtFromDirectory();
|
||||
if (file != null)
|
||||
{
|
||||
CoverArtBox.Source = BitmapFrame.Create(file, BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
SetCoverArtVisibility(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverArtBox.Source = null;
|
||||
SetCoverArtVisibility(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverArtBox.Source = BitmapFrame.Create(new MemoryStream(CurrentTrack.CoverArt), BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
SetCoverArtVisibility(true);
|
||||
}
|
||||
ProgressTimer.Start();
|
||||
if (PauseAfterCurrentTrack && !Player.Paused)
|
||||
{
|
||||
PlayPauseMethod();
|
||||
PauseAfterCurrentTrack = false;
|
||||
}
|
||||
|
||||
LoggingHandler.Log("Changing tracks");
|
||||
}
|
||||
private async void Player_SongException(object sender, PlaybackExceptionEventArgs e)
|
||||
{
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ContentText = string.Format(Properties.Resources.MAINWINDOW_PLAYBACK_ERROR_DETAILS, e.Details),
|
||||
IsImportant = true,
|
||||
DisplayAsToast = true,
|
||||
Type = NotificationType.Failure
|
||||
});
|
||||
await Player.NextAsync();
|
||||
}
|
||||
#endregion
|
||||
#region ControlsBox
|
||||
private void ShuffleButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ShuffleMethod();
|
||||
private void RepeatOneButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => RepeatOneMethod();
|
||||
private void PreviousButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => PreviousTrackMethod();
|
||||
private void PlayPauseButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => PlayPauseMethod();
|
||||
private void NextTrackButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => NextTrackMethod();
|
||||
private bool isDragging = false;
|
||||
private void ProgressBar_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
|
||||
{
|
||||
isDragging = true;
|
||||
ProgressTimer.Stop();
|
||||
}
|
||||
private void ProgressBar_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded)
|
||||
{
|
||||
ProgressTimer.Start();
|
||||
}
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
private void ProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (isDragging && Player.FileLoaded)
|
||||
{
|
||||
Player.RepositionMusic((int)ProgressBar.Value);
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
private void ProgressBar_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded && !isDragging)
|
||||
{
|
||||
Player.RepositionMusic((int)ProgressBar.Value);
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
private void VolumeBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
Player.Volume = (float)(VolumeBar.Value / 100);
|
||||
}
|
||||
private void ProgressTimer_Tick(object sender, EventArgs e) => ProgressTick();
|
||||
private void ProgressTick()
|
||||
{
|
||||
var time = Player.CurrentTime;
|
||||
ProgressIndicator1.Text = time.ToString(@"mm\:ss");
|
||||
if (App.Config.ShowRemainingProgress) ProgressIndicator2.Text
|
||||
= $"-{TimeSpan.FromSeconds(time.TotalSeconds - Math.Floor(Player.CurrentBackend.TotalTime.TotalSeconds)):mm\\:ss}";
|
||||
if (App.Config.ShowTimeInWindow) Title = $"{time:mm\\:ss}/{Player.CurrentBackend.TotalTime:mm\\:ss} | {WindowName}";
|
||||
if (!isDragging) ProgressBar.Value = time.TotalSeconds;
|
||||
Player.AvoidNextQueue = false;
|
||||
|
||||
ProgressTimer.Start(); // resync the progress timer
|
||||
}
|
||||
private void TrackTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.TrackInfo, 235, true);
|
||||
private void TrackTitle_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var cm = FindResource("MiscContext") as ContextMenu;
|
||||
cm.PlacementTarget = sender as Button;
|
||||
cm.IsOpen = true;
|
||||
}
|
||||
private void TrackContextTagEditor_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var tracks = new List<string>();
|
||||
if (Player.FileLoaded) tracks.Add(Player.FilePath); // if playing, edit the file the user is playing
|
||||
else tracks = Player.Queue.Queue;
|
||||
var tagEditor = new TagEditor(tracks, Player, Library);
|
||||
tagEditor.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
tagEditor.Owner = this;
|
||||
tagEditor.Show();
|
||||
}
|
||||
private void TrackContentPlaylistManagement_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string track;
|
||||
if (Player.FileLoaded) track = Player.FilePath;
|
||||
else track = null;
|
||||
var playlistManagement = new PlaylistManagement(Library, NotificationHandler, SelectedMenu, track);
|
||||
playlistManagement.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
playlistManagement.Owner = this;
|
||||
playlistManagement.Show();
|
||||
}
|
||||
private void TrackContextMiniplayer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Hide();
|
||||
var miniPlayer = new MiniPlayer(this);
|
||||
miniPlayer.Owner = this;
|
||||
miniPlayer.ShowDialog();
|
||||
Top = miniPlayer.Top;
|
||||
Left = miniPlayer.Left;
|
||||
Show();
|
||||
}
|
||||
private void TrackContext_PauseAuto_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PauseAfterCurrentTrack = !PauseAfterCurrentTrack;
|
||||
UpdatePlayButtonState();
|
||||
}
|
||||
private void TrackContextArtist_Click(object sender, RoutedEventArgs e) => ChangeTabs(Menu.Artists, CurrentTrack?.Artists[0]);
|
||||
|
||||
private void TrackContextAlbum_Click(object sender, RoutedEventArgs e) => ChangeTabs(Menu.Albums, CurrentTrack?.Album);
|
||||
|
||||
private void TrackContextLyrics_Click(object sender, RoutedEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.Lyrics, openleft: true);
|
||||
|
||||
private async void TrackContextOpenFile_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dialog = new Forms.FMPTextEntryBox(Properties.Resources.IMPORT_MANUALENTRY);
|
||||
dialog.ShowDialog();
|
||||
if (dialog.OK)
|
||||
{
|
||||
await Player.PlayAsync(dialog.Response);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region MenuBar
|
||||
private void TracksTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Menu.Tracks);
|
||||
private void ArtistsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Menu.Artists);
|
||||
private void AlbumsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Menu.Albums);
|
||||
private void PlaylistsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Menu.Playlists);
|
||||
private void ImportTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Menu.Import);
|
||||
private void SettingsButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.Settings, 335);
|
||||
private void SearchButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.Search, 335);
|
||||
private void QueueManagementButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.QueueManagement, 335);
|
||||
private void NotificationButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(AuxiliaryPane.Notifications);
|
||||
|
||||
private void NotificationHandler_NotificationInvalidate(object sender, EventArgs e)
|
||||
{
|
||||
NotificationCounterLabel.Text = NotificationHandler.Notifications.Count.ToString();
|
||||
if (NotificationHandler.Notifications.Count != 0)
|
||||
{
|
||||
NotificationButton.Visibility = Visibility.Visible;
|
||||
NotificationCounterLabel.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
NotificationButton.Visibility = Visibility.Collapsed;
|
||||
NotificationCounterLabel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
foreach (Notification box in NotificationHandler.Notifications)
|
||||
{
|
||||
if (box.DisplayAsToast && !box.Read)
|
||||
{
|
||||
if (SelectedAuxiliaryPane != AuxiliaryPane.Notifications)
|
||||
{
|
||||
ShowAuxilliaryPane(AuxiliaryPane.Notifications);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (!(e.OriginalSource is TextBox || e.OriginalSource is ListBoxItem) || Keyboard.IsKeyDown(Key.LeftCtrl))
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Q:
|
||||
ShowAuxilliaryPane(AuxiliaryPane.Settings, 335);
|
||||
break;
|
||||
case Key.A:
|
||||
ChangeTabs(Menu.Tracks);
|
||||
break;
|
||||
case Key.S:
|
||||
ChangeTabs(Menu.Artists);
|
||||
break;
|
||||
case Key.D:
|
||||
ChangeTabs(Menu.Albums);
|
||||
break;
|
||||
case Key.F:
|
||||
ChangeTabs(Menu.Playlists);
|
||||
break;
|
||||
case Key.G:
|
||||
ChangeTabs(Menu.Import);
|
||||
break;
|
||||
case Key.E:
|
||||
ShowAuxilliaryPane(AuxiliaryPane.Search, 335);
|
||||
break;
|
||||
case Key.R:
|
||||
ShowAuxilliaryPane(AuxiliaryPane.TrackInfo, 235, true);
|
||||
break;
|
||||
case Key.W:
|
||||
ShowAuxilliaryPane(AuxiliaryPane.QueueManagement, 335);
|
||||
break;
|
||||
case Key.Space:
|
||||
PlayPauseMethod();
|
||||
break;
|
||||
}
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.F1:
|
||||
Process.Start("https://royce551.github.io/FRESHMusicPlayer/docs/index.html");
|
||||
break;
|
||||
case Key.F11:
|
||||
if (SelectedMenu != Menu.Fullscreen) ChangeTabs(Menu.Fullscreen);
|
||||
else ChangeTabs(Menu.Playlists);
|
||||
break;
|
||||
case Key.F12:
|
||||
NotificationHandler.Add(new Notification { ContentText = "Debug Tools" });
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Garbage Collect",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
GC.Collect(2);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Throw exception",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
throw new Exception("Exception for debugging");
|
||||
}
|
||||
});
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Make FMP topmost",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
Topmost = !Topmost;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void Window_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effects = DragDropEffects.Copy;
|
||||
}
|
||||
|
||||
private async void ControlsBox_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
Player.Queue.Clear();
|
||||
InterfaceUtils.DoDragDrop((string[])e.Data.GetData(DataFormats.FileDrop), Player, Library, import: false);
|
||||
await Player.PlayAsync();
|
||||
}
|
||||
|
||||
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
VolumeBar.Value += e.Delta / 100 * 3;
|
||||
}
|
||||
|
||||
private void ProgressIndicator2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded)
|
||||
{
|
||||
if (App.Config.ShowRemainingProgress)
|
||||
{
|
||||
App.Config.ShowRemainingProgress = false;
|
||||
if (Player.CurrentBackend.TotalTime.TotalSeconds != 0) ProgressIndicator2.Text = Player.CurrentBackend.TotalTime.ToString(@"mm\:ss");
|
||||
else ProgressIndicator2.Text = "∞";
|
||||
}
|
||||
else App.Config.ShowRemainingProgress = true;
|
||||
}
|
||||
}
|
||||
private async void Window_SourceInitialized(object sender, EventArgs e)
|
||||
{
|
||||
UpdateIntegrations();
|
||||
|
@ -809,38 +137,11 @@ namespace FRESHMusicPlayer
|
|||
await new UpdateHandler(NotificationHandler).UpdateApp();
|
||||
await PerformAutoImport();
|
||||
}
|
||||
public async Task PerformAutoImport()
|
||||
{
|
||||
if (App.Config.AutoImportPaths.Count <= 0) return; // not really needed but prevents going through unneeded
|
||||
// effort (and showing the notification)
|
||||
var notification = new Notification { ContentText = Properties.Resources.NOTIFICATION_SCANNING };
|
||||
NotificationHandler.Add(notification);
|
||||
var filesToImport = new List<string>();
|
||||
var library = Library.Read();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
foreach (var folder in App.Config.AutoImportPaths)
|
||||
{
|
||||
var files = Directory.EnumerateFiles(folder, "*", SearchOption.AllDirectories)
|
||||
.Where(name => name.EndsWith(".mp3")
|
||||
|| name.EndsWith(".wav") || name.EndsWith(".m4a") || name.EndsWith(".ogg")
|
||||
|| name.EndsWith(".flac") || name.EndsWith(".aiff")
|
||||
|| name.EndsWith(".wma")
|
||||
|| name.EndsWith(".aac")).ToArray();
|
||||
foreach (var file in files)
|
||||
{
|
||||
if (!library.Select(x => x.Path).Contains(file))
|
||||
filesToImport.Add(file);
|
||||
}
|
||||
}
|
||||
Library.Import(filesToImport);
|
||||
});
|
||||
NotificationHandler.Remove(notification);
|
||||
}
|
||||
|
||||
private void Window_Closed(object sender, EventArgs e)
|
||||
{
|
||||
App.Config.Volume = (int)VolumeBar.Value;
|
||||
App.Config.CurrentMenu = SelectedMenu;
|
||||
App.Config.CurrentMenu = CurrentTab;
|
||||
TrackingHandler?.Close();
|
||||
ConfigurationHandler.Write(App.Config);
|
||||
Library.Database?.Dispose();
|
||||
|
@ -848,27 +149,5 @@ namespace FRESHMusicPlayer
|
|||
watcher.Dispose();
|
||||
WritePersistence();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void CoverArtBox_ToolTipOpening(object sender, ToolTipEventArgs e)
|
||||
{
|
||||
if (CurrentTrack != null)
|
||||
CoverArtBoxToolTip.Source = BitmapFrame.Create(new MemoryStream(CurrentTrack.CoverArt), BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
}
|
||||
|
||||
private void CoverArtBox_ToolTipClosing(object sender, ToolTipEventArgs e)
|
||||
{
|
||||
CoverArtBoxToolTip.Source = null;
|
||||
}
|
||||
|
||||
private void Window_Activated(object sender, EventArgs e)
|
||||
{
|
||||
ProgressTimer.Interval = 100;
|
||||
}
|
||||
|
||||
private void Window_Deactivated(object sender, EventArgs e)
|
||||
{
|
||||
ProgressTimer.Interval = 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
using FRESHMusicPlayer.Forms;
|
||||
using FRESHMusicPlayer.Forms.Playlists;
|
||||
using FRESHMusicPlayer.Forms.TagEditor;
|
||||
using FRESHMusicPlayer.Handlers.Notifications;
|
||||
using FRESHMusicPlayer.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.IO;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
namespace FRESHMusicPlayer
|
||||
{
|
||||
// Event handlers and other doo dads
|
||||
public partial class MainWindow
|
||||
{
|
||||
// Controls Box
|
||||
private void ShuffleButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ShuffleMethod();
|
||||
private void RepeatOneButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => RepeatOneMethod();
|
||||
private void PreviousButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => PreviousTrackMethod();
|
||||
private void PlayPauseButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => PlayPauseMethod();
|
||||
private void NextTrackButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => NextTrackMethod();
|
||||
private bool isDragging = false;
|
||||
private void ProgressBar_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e)
|
||||
{
|
||||
isDragging = true;
|
||||
ProgressTimer.Stop();
|
||||
}
|
||||
private void ProgressBar_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded)
|
||||
{
|
||||
ProgressTimer.Start();
|
||||
}
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
private void ProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
if (isDragging && Player.FileLoaded)
|
||||
{
|
||||
Player.RepositionMusic((int)ProgressBar.Value);
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
private void ProgressBar_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded && !isDragging)
|
||||
{
|
||||
Player.RepositionMusic((int)ProgressBar.Value);
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
private void VolumeBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
||||
{
|
||||
Player.Volume = (float)(VolumeBar.Value / 100);
|
||||
}
|
||||
private void ProgressTimer_Tick(object sender, EventArgs e) => ProgressTick();
|
||||
private void ProgressTick()
|
||||
{
|
||||
var time = Player.CurrentTime;
|
||||
ProgressIndicator1.Text = time.ToString(@"mm\:ss");
|
||||
if (App.Config.ShowRemainingProgress) ProgressIndicator2.Text
|
||||
= $"-{TimeSpan.FromSeconds(time.TotalSeconds - Math.Floor(Player.CurrentBackend.TotalTime.TotalSeconds)):mm\\:ss}";
|
||||
if (App.Config.ShowTimeInWindow) Title = $"{time:mm\\:ss}/{Player.CurrentBackend.TotalTime:mm\\:ss} | {WindowName}";
|
||||
if (!isDragging) ProgressBar.Value = time.TotalSeconds;
|
||||
Player.AvoidNextQueue = false;
|
||||
ProgressTimer.Start(); // resync the progress timer
|
||||
}
|
||||
private void TrackTitle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(Pane.TrackInfo, 235, true);
|
||||
private void TrackTitle_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
var cm = FindResource("MiscContext") as ContextMenu;
|
||||
cm.PlacementTarget = sender as Button;
|
||||
cm.IsOpen = true;
|
||||
}
|
||||
private void TrackContextTagEditor_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var tracks = new List<string>();
|
||||
if (Player.FileLoaded) tracks.Add(Player.FilePath); // if playing, edit the file the user is playing
|
||||
else tracks = Player.Queue.Queue;
|
||||
var tagEditor = new TagEditor(tracks, Player, Library);
|
||||
tagEditor.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
tagEditor.Owner = this;
|
||||
tagEditor.Show();
|
||||
}
|
||||
private void TrackContentPlaylistManagement_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
string track;
|
||||
if (Player.FileLoaded) track = Player.FilePath;
|
||||
else track = null;
|
||||
var playlistManagement = new PlaylistManagement(Library, NotificationHandler, CurrentTab, track);
|
||||
playlistManagement.WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
||||
playlistManagement.Owner = this;
|
||||
playlistManagement.Show();
|
||||
}
|
||||
private void TrackContextMiniplayer_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Hide();
|
||||
var miniPlayer = new MiniPlayer(this);
|
||||
miniPlayer.Owner = this;
|
||||
miniPlayer.ShowDialog();
|
||||
Top = miniPlayer.Top;
|
||||
Left = miniPlayer.Left;
|
||||
Show();
|
||||
}
|
||||
private void TrackContext_PauseAuto_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
PauseAfterCurrentTrack = !PauseAfterCurrentTrack;
|
||||
UpdatePlayButtonState();
|
||||
}
|
||||
private void TrackContextArtist_Click(object sender, RoutedEventArgs e) => ChangeTabs(Tab.Artists, CurrentTrack?.Artists[0]);
|
||||
|
||||
private void TrackContextAlbum_Click(object sender, RoutedEventArgs e) => ChangeTabs(Tab.Albums, CurrentTrack?.Album);
|
||||
|
||||
private void TrackContextLyrics_Click(object sender, RoutedEventArgs e) => ShowAuxilliaryPane(Pane.Lyrics, openleft: true);
|
||||
|
||||
private async void TrackContextOpenFile_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var dialog = new Forms.FMPTextEntryBox(Properties.Resources.IMPORT_MANUALENTRY);
|
||||
dialog.ShowDialog();
|
||||
if (dialog.OK)
|
||||
{
|
||||
await Player.PlayAsync(dialog.Response);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProgressIndicator2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (Player.FileLoaded)
|
||||
{
|
||||
if (App.Config.ShowRemainingProgress)
|
||||
{
|
||||
App.Config.ShowRemainingProgress = false;
|
||||
if (Player.CurrentBackend.TotalTime.TotalSeconds != 0) ProgressIndicator2.Text = Player.CurrentBackend.TotalTime.ToString(@"mm\:ss");
|
||||
else ProgressIndicator2.Text = "∞";
|
||||
}
|
||||
else App.Config.ShowRemainingProgress = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CoverArtBox_ToolTipOpening(object sender, ToolTipEventArgs e)
|
||||
{
|
||||
if (CurrentTrack != null)
|
||||
CoverArtBoxToolTip.Source = BitmapFrame.Create(new MemoryStream(CurrentTrack.CoverArt), BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
}
|
||||
|
||||
private void CoverArtBox_ToolTipClosing(object sender, ToolTipEventArgs e)
|
||||
{
|
||||
CoverArtBoxToolTip.Source = null;
|
||||
}
|
||||
|
||||
// NavBar
|
||||
private void TracksTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Tab.Tracks);
|
||||
private void ArtistsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Tab.Artists);
|
||||
private void AlbumsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Tab.Albums);
|
||||
private void PlaylistsTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Tab.Playlists);
|
||||
private void ImportTab_MouseDown(object sender, MouseButtonEventArgs e) => ChangeTabs(Tab.Import);
|
||||
private void SettingsButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(Pane.Settings, 335);
|
||||
private void SearchButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(Pane.Search, 335);
|
||||
private void QueueManagementButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(Pane.QueueManagement, 335);
|
||||
private void NotificationButton_Click(object sender, MouseButtonEventArgs e) => ShowAuxilliaryPane(Pane.Notifications);
|
||||
|
||||
private void NotificationHandler_NotificationInvalidate(object sender, EventArgs e)
|
||||
{
|
||||
NotificationCounterLabel.Text = NotificationHandler.Notifications.Count.ToString();
|
||||
if (NotificationHandler.Notifications.Count != 0)
|
||||
{
|
||||
NotificationButton.Visibility = Visibility.Visible;
|
||||
NotificationCounterLabel.Visibility = Visibility.Visible;
|
||||
}
|
||||
else
|
||||
{
|
||||
NotificationButton.Visibility = Visibility.Collapsed;
|
||||
NotificationCounterLabel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
foreach (Notification box in NotificationHandler.Notifications)
|
||||
{
|
||||
if (box.DisplayAsToast && !box.Read)
|
||||
{
|
||||
if (CurrentPane != Pane.Notifications)
|
||||
{
|
||||
ShowAuxilliaryPane(Pane.Notifications);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (!(e.OriginalSource is TextBox || e.OriginalSource is ListBoxItem) || Keyboard.IsKeyDown(Key.LeftCtrl))
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Q:
|
||||
ShowAuxilliaryPane(Pane.Settings, 335);
|
||||
break;
|
||||
case Key.A:
|
||||
ChangeTabs(Tab.Tracks);
|
||||
break;
|
||||
case Key.S:
|
||||
ChangeTabs(Tab.Artists);
|
||||
break;
|
||||
case Key.D:
|
||||
ChangeTabs(Tab.Albums);
|
||||
break;
|
||||
case Key.F:
|
||||
ChangeTabs(Tab.Playlists);
|
||||
break;
|
||||
case Key.G:
|
||||
ChangeTabs(Tab.Import);
|
||||
break;
|
||||
case Key.E:
|
||||
ShowAuxilliaryPane(Pane.Search, 335);
|
||||
break;
|
||||
case Key.R:
|
||||
ShowAuxilliaryPane(Pane.TrackInfo, 235, true);
|
||||
break;
|
||||
case Key.W:
|
||||
ShowAuxilliaryPane(Pane.QueueManagement, 335);
|
||||
break;
|
||||
case Key.Space:
|
||||
PlayPauseMethod();
|
||||
break;
|
||||
}
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.F1:
|
||||
Process.Start("https://royce551.github.io/FRESHMusicPlayer/docs/index.html");
|
||||
break;
|
||||
case Key.F11:
|
||||
if (CurrentTab != Tab.Fullscreen) ChangeTabs(Tab.Fullscreen);
|
||||
else ChangeTabs(Tab.Playlists);
|
||||
break;
|
||||
case Key.F12:
|
||||
NotificationHandler.Add(new Notification { ContentText = "Debug Tools" });
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Garbage Collect",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
GC.Collect(2);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Throw exception",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
throw new Exception("Exception for debugging");
|
||||
}
|
||||
});
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ButtonText = "Make FMP topmost",
|
||||
OnButtonClicked = () =>
|
||||
{
|
||||
Topmost = !Topmost;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Window
|
||||
private void Window_DragOver(object sender, DragEventArgs e)
|
||||
{
|
||||
e.Effects = DragDropEffects.Copy;
|
||||
}
|
||||
|
||||
private async void ControlsBox_Drop(object sender, DragEventArgs e)
|
||||
{
|
||||
Player.Queue.Clear();
|
||||
InterfaceUtils.DoDragDrop((string[])e.Data.GetData(DataFormats.FileDrop), Player, Library, import: false);
|
||||
await Player.PlayAsync();
|
||||
}
|
||||
|
||||
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
VolumeBar.Value += e.Delta / 100 * 3;
|
||||
}
|
||||
|
||||
private void Window_Activated(object sender, EventArgs e)
|
||||
{
|
||||
ProgressTimer.Interval = 100;
|
||||
}
|
||||
|
||||
private void Window_Deactivated(object sender, EventArgs e)
|
||||
{
|
||||
ProgressTimer.Interval = 1000;
|
||||
}
|
||||
}
|
||||
}
|
474
FRESHMusicPlayer/FRESHMusicPlayer-WPF/MainWindow_Logic.xaml.cs
Normal file
474
FRESHMusicPlayer/FRESHMusicPlayer-WPF/MainWindow_Logic.xaml.cs
Normal file
|
@ -0,0 +1,474 @@
|
|||
using FRESHMusicPlayer.Handlers;
|
||||
using FRESHMusicPlayer.Handlers.Integrations;
|
||||
using FRESHMusicPlayer.Handlers.Notifications;
|
||||
using FRESHMusicPlayer.Pages;
|
||||
using FRESHMusicPlayer.Pages.Library;
|
||||
using FRESHMusicPlayer.Pages.Lyrics;
|
||||
using FRESHMusicPlayer.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Animation;
|
||||
using System.Windows.Media.Imaging;
|
||||
using WinForms = System.Windows.Forms;
|
||||
|
||||
namespace FRESHMusicPlayer
|
||||
{
|
||||
public enum Tab
|
||||
{
|
||||
Tracks,
|
||||
Artists,
|
||||
Albums,
|
||||
Playlists,
|
||||
Import,
|
||||
Fullscreen,
|
||||
Other
|
||||
}
|
||||
public enum Pane
|
||||
{
|
||||
None,
|
||||
Settings,
|
||||
QueueManagement,
|
||||
Search,
|
||||
Notifications,
|
||||
TrackInfo,
|
||||
Lyrics
|
||||
}
|
||||
|
||||
// Code for the "shell" parts of the main window, player, and systemwide logic
|
||||
public partial class MainWindow
|
||||
{
|
||||
// Player
|
||||
public void PlayPauseMethod()
|
||||
{
|
||||
if (!Player.FileLoaded) return;
|
||||
if (Player.Paused)
|
||||
{
|
||||
Player.Resume();
|
||||
SetIntegrations(PlaybackStatus.Playing);
|
||||
ProgressTimer.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Pause();
|
||||
SetIntegrations(PlaybackStatus.Paused);
|
||||
ProgressTimer.Stop();
|
||||
}
|
||||
UpdatePlayButtonState();
|
||||
}
|
||||
public void StopMethod()
|
||||
{
|
||||
Player.Queue.Clear();
|
||||
Player.Stop();
|
||||
}
|
||||
public async void NextTrackMethod() => await Player.NextAsync();
|
||||
public async void PreviousTrackMethod()
|
||||
{
|
||||
if (!Player.FileLoaded) return;
|
||||
if (Player.CurrentTime.TotalSeconds <= 5) await Player.PreviousAsync();
|
||||
else
|
||||
{
|
||||
Player.CurrentTime = TimeSpan.FromSeconds(0);
|
||||
ProgressTimer.Start(); // to resync the progress timer
|
||||
}
|
||||
}
|
||||
public void ShuffleMethod()
|
||||
{
|
||||
if (Player.Queue.Shuffle)
|
||||
{
|
||||
Player.Queue.Shuffle = false;
|
||||
ShuffleButton.Fill = (Brush)FindResource("PrimaryTextColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Queue.Shuffle = true;
|
||||
ShuffleButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
}
|
||||
public void RepeatOneMethod()
|
||||
{
|
||||
if (Player.Queue.RepeatMode == RepeatMode.None)
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.RepeatAll;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatAllIcon");
|
||||
RepeatOneButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
else if (Player.Queue.RepeatMode == RepeatMode.RepeatAll)
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.RepeatOne;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatOneIcon");
|
||||
RepeatOneButton.Fill = new LinearGradientBrush(Color.FromRgb(105, 181, 120), Color.FromRgb(51, 139, 193), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.Queue.RepeatMode = RepeatMode.None;
|
||||
RepeatOneButton.Data = (Geometry)FindResource("RepeatAllIcon");
|
||||
RepeatOneButton.Fill = (Brush)FindResource("PrimaryTextColor");
|
||||
}
|
||||
}
|
||||
public void UpdatePlayButtonState()
|
||||
{
|
||||
if (!Player.Paused) PlayPauseButton.Data = (Geometry)FindResource("PauseIcon");
|
||||
else PlayPauseButton.Data = (Geometry)FindResource("PlayIcon");
|
||||
if (PauseAfterCurrentTrack) ProgressIndicator2.Foreground = new SolidColorBrush(Color.FromRgb(212, 70, 63));
|
||||
else ProgressIndicator2.Foreground = (Brush)FindResource("SecondaryTextColor");
|
||||
}
|
||||
private void Player_SongStopped(object sender, EventArgs e)
|
||||
{
|
||||
Title = WindowName;
|
||||
TitleLabel.Text = ArtistLabel.Text = Properties.Resources.MAINWINDOW_NOTHINGPLAYING;
|
||||
ProgressTimer.Stop();
|
||||
CoverArtBox.Source = null;
|
||||
SetIntegrations(PlaybackStatus.Stopped);
|
||||
SetCoverArtVisibility(false);
|
||||
|
||||
LoggingHandler.Log("Stopping!");
|
||||
}
|
||||
|
||||
private void Player_SongLoading(object sender, EventArgs e) => Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
|
||||
private void Player_SongChanged(object sender, EventArgs e)
|
||||
{
|
||||
Mouse.OverrideCursor = null;
|
||||
CurrentTrack = Player.CurrentBackend.Metadata;
|
||||
Title = $"{string.Join(", ", CurrentTrack.Artists)} - {CurrentTrack.Title} | {WindowName}";
|
||||
TitleLabel.Text = CurrentTrack.Title;
|
||||
ArtistLabel.Text = string.Join(", ", CurrentTrack.Artists) == "" ? Properties.Resources.MAINWINDOW_NOARTIST : string.Join(", ", CurrentTrack.Artists);
|
||||
ProgressBar.Maximum = Player.CurrentBackend.TotalTime.TotalSeconds;
|
||||
if (Player.CurrentBackend.TotalTime.TotalSeconds != 0) ProgressIndicator2.Text = Player.CurrentBackend.TotalTime.ToString(@"mm\:ss");
|
||||
else ProgressIndicator2.Text = "∞";
|
||||
SetIntegrations(PlaybackStatus.Playing);
|
||||
UpdatePlayButtonState();
|
||||
if (CurrentTrack.CoverArt is null)
|
||||
{
|
||||
var file = GetCoverArtFromDirectory();
|
||||
if (file != null)
|
||||
{
|
||||
CoverArtBox.Source = BitmapFrame.Create(file, BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
SetCoverArtVisibility(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverArtBox.Source = null;
|
||||
SetCoverArtVisibility(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CoverArtBox.Source = BitmapFrame.Create(new MemoryStream(CurrentTrack.CoverArt), BitmapCreateOptions.None, BitmapCacheOption.None);
|
||||
SetCoverArtVisibility(true);
|
||||
}
|
||||
ProgressTimer.Start();
|
||||
if (PauseAfterCurrentTrack && !Player.Paused)
|
||||
{
|
||||
PlayPauseMethod();
|
||||
PauseAfterCurrentTrack = false;
|
||||
}
|
||||
|
||||
LoggingHandler.Log("Changing tracks");
|
||||
}
|
||||
private async void Player_SongException(object sender, PlaybackExceptionEventArgs e)
|
||||
{
|
||||
NotificationHandler.Add(new Notification
|
||||
{
|
||||
ContentText = string.Format(Properties.Resources.MAINWINDOW_PLAYBACK_ERROR_DETAILS, e.Details),
|
||||
IsImportant = true,
|
||||
DisplayAsToast = true,
|
||||
Type = NotificationType.Failure
|
||||
});
|
||||
await Player.NextAsync();
|
||||
}
|
||||
|
||||
|
||||
// Shell
|
||||
|
||||
public Tab CurrentTab = Tab.Tracks;
|
||||
public Pane CurrentPane = Pane.None;
|
||||
|
||||
public bool IsControlsBoxVisible { get; private set; } = false;
|
||||
|
||||
public void SetCoverArtVisibility(bool mode)
|
||||
{
|
||||
if (!mode) CoverArtArea.Width = new GridLength(5);
|
||||
else CoverArtArea.Width = new GridLength(75);
|
||||
}
|
||||
public async void ShowAuxilliaryPane(Pane pane, int width = 235, bool openleft = false)
|
||||
{
|
||||
LoggingHandler.Log($"Showing pane --> {pane}");
|
||||
if (CurrentPane == pane)
|
||||
{
|
||||
await HideAuxilliaryPane();
|
||||
return;
|
||||
}
|
||||
if (CurrentPane != Pane.None) await HideAuxilliaryPane(true);
|
||||
switch (pane)
|
||||
{
|
||||
case Pane.Settings:
|
||||
RightFrame.Content = new SettingsPage(this);
|
||||
break;
|
||||
case Pane.QueueManagement:
|
||||
RightFrame.Content = new QueueManagement(this);
|
||||
break;
|
||||
case Pane.Search:
|
||||
RightFrame.Content = new SearchPage(this);
|
||||
break;
|
||||
case Pane.Notifications:
|
||||
RightFrame.Content = new NotificationPage(this);
|
||||
break;
|
||||
case Pane.TrackInfo:
|
||||
RightFrame.Content = new TrackInfoPage(this);
|
||||
break;
|
||||
case Pane.Lyrics:
|
||||
RightFrame.Content = new LyricsPage(this);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (!openleft) DockPanel.SetDock(RightFrame, Dock.Right); else DockPanel.SetDock(RightFrame, Dock.Left);
|
||||
RightFrame.Visibility = Visibility.Visible;
|
||||
RightFrame.Width = width;
|
||||
|
||||
var sb = InterfaceUtils.GetThicknessAnimation(
|
||||
openleft ? new Thickness(width * -1 /*negate*/, 0, 0, 0) : new Thickness(0, 0, width * -1 /*negate*/, 0),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(120),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseOut, Exponent = 3 });
|
||||
|
||||
sb.Begin(RightFrame);
|
||||
|
||||
CurrentPane = pane;
|
||||
}
|
||||
public async Task HideAuxilliaryPane(bool animate = true)
|
||||
{
|
||||
var sb = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
DockPanel.GetDock(RightFrame) == Dock.Left ? new Thickness(RightFrame.Width * -1, 0, 0, 0) : new Thickness(0, 0, RightFrame.Width * -1, 0),
|
||||
TimeSpan.FromMilliseconds(120),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
|
||||
if (animate) await sb.BeginStoryboardAsync(RightFrame);
|
||||
RightFrame.Visibility = Visibility.Collapsed;
|
||||
RightFrame.Content = null;
|
||||
CurrentPane = Pane.None;
|
||||
}
|
||||
public async void ShowControlsBox()
|
||||
{
|
||||
var navBarStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0, -25, 0, 0),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
var controlsBoxStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0, 0, 0, -84),
|
||||
new Thickness(0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
navBarStoryboard.Begin(MainBar);
|
||||
await controlsBoxStoryboard.BeginStoryboardAsync(ControlsBoxBorder);
|
||||
IsControlsBoxVisible = true;
|
||||
}
|
||||
public async void HideControlsBox()
|
||||
{
|
||||
var navBarStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
new Thickness(0, -25, 0, 0),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
var controlsBoxStoryboard = InterfaceUtils.GetThicknessAnimation(
|
||||
new Thickness(0),
|
||||
new Thickness(0, 0, 0, -84),
|
||||
TimeSpan.FromMilliseconds(500),
|
||||
new PropertyPath(MarginProperty),
|
||||
new ExponentialEase { EasingMode = EasingMode.EaseIn, Exponent = 3 });
|
||||
navBarStoryboard.Begin(MainBar);
|
||||
await controlsBoxStoryboard.BeginStoryboardAsync(ControlsBoxBorder);
|
||||
IsControlsBoxVisible = false;
|
||||
}
|
||||
public void ChangeTabs(Tab tab, string search = null)
|
||||
{
|
||||
LoggingHandler.Log($"Changing tabs -> {tab}");
|
||||
|
||||
var previousMenu = CurrentTab;
|
||||
CurrentTab = tab;
|
||||
TextBlock tabLabel;
|
||||
switch (CurrentTab)
|
||||
{
|
||||
case Tab.Tracks:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = TracksTab;
|
||||
break;
|
||||
case Tab.Artists:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = ArtistsTab;
|
||||
break;
|
||||
case Tab.Albums:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = AlbumsTab;
|
||||
break;
|
||||
case Tab.Playlists:
|
||||
ContentFrame.Content = new LibraryPage(this, search);
|
||||
tabLabel = PlaylistsTab;
|
||||
break;
|
||||
case Tab.Import:
|
||||
ContentFrame.Content = new ImportPage(this);
|
||||
tabLabel = ImportTab;
|
||||
break;
|
||||
case Tab.Fullscreen:
|
||||
ContentFrame.Content = new FullscreenPage(this, previousMenu);
|
||||
tabLabel = ImportTab;
|
||||
break;
|
||||
default:
|
||||
tabLabel = null;
|
||||
break;
|
||||
}
|
||||
TracksTab.FontWeight = ArtistsTab.FontWeight = AlbumsTab.FontWeight = PlaylistsTab.FontWeight = ImportTab.FontWeight = FontWeights.Normal;
|
||||
tabLabel.FontWeight = FontWeights.Bold;
|
||||
}
|
||||
|
||||
|
||||
// Systemwide logic
|
||||
|
||||
public void ProcessSettings(bool initialize = false)
|
||||
{
|
||||
if (initialize)
|
||||
{
|
||||
VolumeBar.Value = App.Config.Volume;
|
||||
ChangeTabs(App.Config.CurrentMenu);
|
||||
}
|
||||
if (App.Config.PlaybackTracking) TrackingHandler = new PlaytimeTrackingHandler(this);
|
||||
else if (TrackingHandler != null)
|
||||
{
|
||||
TrackingHandler?.Close();
|
||||
TrackingHandler = null;
|
||||
}
|
||||
}
|
||||
public async void HandlePersistence()
|
||||
{
|
||||
var persistenceFilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence");
|
||||
if (File.Exists(persistenceFilePath))
|
||||
{
|
||||
var fields = File.ReadAllText(persistenceFilePath).Split(';');
|
||||
|
||||
var top = double.Parse(fields[2]);
|
||||
var left = double.Parse(fields[3]);
|
||||
var height = double.Parse(fields[4]);
|
||||
var width = double.Parse(fields[5]);
|
||||
var rect = new System.Drawing.Rectangle((int)left, (int)top, (int)width, (int)height);
|
||||
if (WinForms.Screen.AllScreens.Any(y => y.WorkingArea.IntersectsWith(rect)))
|
||||
{
|
||||
Top = top;
|
||||
Left = left;
|
||||
Height = height;
|
||||
Width = width;
|
||||
}
|
||||
if (fields[0] != string.Empty)
|
||||
{
|
||||
await Player.PlayAsync(fields[0]);
|
||||
Player.RepositionMusic(int.Parse(fields[1]));
|
||||
PlayPauseMethod();
|
||||
ProgressTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void WritePersistence()
|
||||
{
|
||||
if (Player.FileLoaded) // TODO: make this less shitty
|
||||
{
|
||||
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence"),
|
||||
$"{Player.FilePath};{(int)Player.CurrentBackend.CurrentTime.TotalSeconds};{Top};{Left};{Height};{Width}");
|
||||
}
|
||||
else
|
||||
{
|
||||
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FRESHMusicPlayer", "Configuration", "FMP-WPF", "persistence"),
|
||||
$";;{Top};{Left};{Height};{Width}");
|
||||
}
|
||||
}
|
||||
public MemoryStream GetCoverArtFromDirectory()
|
||||
{
|
||||
if (File.Exists(Player.FilePath))
|
||||
{
|
||||
var currentDirectory = Path.GetDirectoryName(Player.FilePath);
|
||||
foreach (var file in Directory.EnumerateFiles(currentDirectory))
|
||||
{
|
||||
if (Path.GetFileNameWithoutExtension(file).ToUpper() == "COVER" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "ARTWORK" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "FRONT" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == "BACK" ||
|
||||
Path.GetFileNameWithoutExtension(file).ToUpper() == Player.FilePath)
|
||||
{
|
||||
if (Path.GetExtension(file) == ".png" || Path.GetExtension(file) == ".jpg" || Path.GetExtension(file) == ".jpeg")
|
||||
{
|
||||
return new MemoryStream(File.ReadAllBytes(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public void UpdateIntegrations()
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 10 && App.Config.IntegrateSMTC)
|
||||
{
|
||||
smtcIntegration = new SMTCIntegration(this);
|
||||
}
|
||||
else smtcIntegration = null;
|
||||
if (App.Config.IntegrateDiscordRPC) discordIntegration = new DiscordIntegration();
|
||||
else
|
||||
{
|
||||
discordIntegration?.Close();
|
||||
discordIntegration = null;
|
||||
}
|
||||
}
|
||||
public void SetIntegrations(PlaybackStatus status)
|
||||
{
|
||||
if (Environment.OSVersion.Version.Major >= 10 && App.Config.IntegrateSMTC)
|
||||
{
|
||||
smtcIntegration?.Update(CurrentTrack, status);
|
||||
}
|
||||
if (App.Config.IntegrateDiscordRPC)
|
||||
{
|
||||
discordIntegration?.Update(CurrentTrack, status);
|
||||
}
|
||||
}
|
||||
public async Task PerformAutoImport()
|
||||
{
|
||||
if (App.Config.AutoImportPaths.Count <= 0) return; // not really needed but prevents going through unneeded
|
||||
// effort (and showing the notification)
|
||||
var notification = new Notification { ContentText = Properties.Resources.NOTIFICATION_SCANNING };
|
||||
NotificationHandler.Add(notification);
|
||||
var filesToImport = new List<string>();
|
||||
var library = Library.Read();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
foreach (var folder in App.Config.AutoImportPaths)
|
||||
{
|
||||
var files = Directory.EnumerateFiles(folder, "*", SearchOption.AllDirectories)
|
||||
.Where(name => name.EndsWith(".mp3")
|
||||
|| name.EndsWith(".wav") || name.EndsWith(".m4a") || name.EndsWith(".ogg")
|
||||
|| name.EndsWith(".flac") || name.EndsWith(".aiff")
|
||||
|| name.EndsWith(".wma")
|
||||
|| name.EndsWith(".aac")).ToArray();
|
||||
foreach (var file in files)
|
||||
{
|
||||
if (!library.Select(x => x.Path).Contains(file))
|
||||
filesToImport.Add(file);
|
||||
}
|
||||
}
|
||||
Library.Import(filesToImport);
|
||||
});
|
||||
NotificationHandler.Remove(notification);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,8 +25,8 @@ namespace FRESHMusicPlayer.Pages
|
|||
public partial class FullscreenPage : UserControl
|
||||
{
|
||||
private readonly MainWindow window;
|
||||
private readonly Menu previousMenu;
|
||||
public FullscreenPage(MainWindow window, Menu previousMenu)
|
||||
private readonly Tab previousMenu;
|
||||
public FullscreenPage(MainWindow window, Tab previousMenu)
|
||||
{
|
||||
this.window = window;
|
||||
this.previousMenu = previousMenu;
|
||||
|
@ -118,8 +118,8 @@ namespace FRESHMusicPlayer.Pages
|
|||
window.WindowStyle = WindowStyle.SingleBorderWindow;
|
||||
window.TracksTab.Visibility = window.ArtistsTab.Visibility = window.AlbumsTab.Visibility = window.PlaylistsTab.Visibility = window.ImportTab.Visibility = Visibility.Visible;
|
||||
if (!window.IsControlsBoxVisible) window.ShowControlsBox();
|
||||
if (previousMenu != Menu.Fullscreen) window.ChangeTabs(previousMenu);
|
||||
else window.ChangeTabs(Menu.Import);
|
||||
if (previousMenu != Tab.Fullscreen) window.ChangeTabs(previousMenu);
|
||||
else window.ChangeTabs(Tab.Import);
|
||||
}
|
||||
|
||||
private readonly WinForms.Timer controlDismissTimer = new WinForms.Timer { Interval = 2000, Enabled = true };
|
||||
|
|
|
@ -35,18 +35,18 @@ namespace FRESHMusicPlayer.Pages.Library
|
|||
TracksPanel.Items.Clear();
|
||||
CategoryPanel.Items.Clear();
|
||||
InfoLabel.Visibility = Visibility.Hidden;
|
||||
switch (window.SelectedMenu) // all of this stuff is here so that i can avoid copying and pasting the same page thrice, maybe there's a better way?
|
||||
switch (window.CurrentTab) // all of this stuff is here so that i can avoid copying and pasting the same page thrice, maybe there's a better way?
|
||||
{
|
||||
case Menu.Tracks:
|
||||
case Tab.Tracks:
|
||||
await ShowTracks();
|
||||
break;
|
||||
case Menu.Artists:
|
||||
case Tab.Artists:
|
||||
await ShowArtists();
|
||||
break;
|
||||
case Menu.Albums:
|
||||
case Tab.Albums:
|
||||
await ShowAlbums();
|
||||
break;
|
||||
case Menu.Playlists:
|
||||
case Tab.Playlists:
|
||||
await ShowPlaylists();
|
||||
break;
|
||||
}
|
||||
|
@ -154,8 +154,8 @@ namespace FRESHMusicPlayer.Pages.Library
|
|||
{
|
||||
var selectedItem = (string)CategoryPanel.SelectedItem;
|
||||
if (selectedItem == null) return;
|
||||
if (window.SelectedMenu == Menu.Artists) await ShowTracksforArtist(selectedItem);
|
||||
else if (window.SelectedMenu == Menu.Playlists) await ShowTracksforPlaylist(selectedItem);
|
||||
if (window.CurrentTab == Tab.Artists) await ShowTracksforArtist(selectedItem);
|
||||
else if (window.CurrentTab == Tab.Playlists) await ShowTracksforPlaylist(selectedItem);
|
||||
else await ShowTracksforAlbum(selectedItem);
|
||||
}
|
||||
//private void MainWindow_TabChanged(object sender, string e)
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace FRESHMusicPlayer.Pages.Library
|
|||
otheritem.Header = Properties.Resources.PLAYLISTMANAGEMENT;
|
||||
otheritem.Click += (object send, RoutedEventArgs eee) =>
|
||||
{
|
||||
var management = new PlaylistManagement(library, notificationHandler, ((Application.Current as App).MainWindow as MainWindow).SelectedMenu, FilePath);
|
||||
var management = new PlaylistManagement(library, notificationHandler, ((Application.Current as App).MainWindow as MainWindow).CurrentTab, FilePath);
|
||||
management.ShowDialog();
|
||||
};
|
||||
MiscContext.Items.Add(otheritem);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<RowDefinition Height="33"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<ListBox x:Name="NotificationList" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch" VirtualizingPanel.IsVirtualizing="True" Background="{StaticResource SecondaryColor}" Grid.Row="1" BorderBrush="{x:Null}">
|
||||
<ListBox x:Name="NotificationList" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalContentAlignment="Stretch" VirtualizingPanel.IsVirtualizing="True" ScrollViewer.CanContentScroll="False" Background="{StaticResource SecondaryColor}" Grid.Row="1" BorderBrush="{x:Null}">
|
||||
</ListBox>
|
||||
<TextBlock TextWrapping="Wrap" Text="{x:Static resx:Resources.NOTIFICATIONS_TITLE}" Foreground="{StaticResource PrimaryTextColor}" FontWeight="Bold" FontSize="18" Margin="5,5,116,5"/>
|
||||
<TextBlock Text="{x:Static resx:Resources.NOTIFICATIONS_CLEAR_ALL}" Foreground="{StaticResource PrimaryTextColor}" FontSize="10" Margin="0,10,6,8" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" HorizontalAlignment="Right"/>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace FRESHMusicPlayer.Pages
|
|||
}
|
||||
|
||||
private void InvalidateNotifications(object sender, EventArgs e) => ShowNotifications();
|
||||
private void ShowNotifications()
|
||||
private async void ShowNotifications()
|
||||
{
|
||||
NotificationList.Items.Clear();
|
||||
foreach (Notification box in window.NotificationHandler.Notifications)
|
||||
|
@ -29,7 +29,7 @@ namespace FRESHMusicPlayer.Pages
|
|||
box.Read = true;
|
||||
NotificationList.Items.Add(new NotificationBox(box, window.NotificationHandler));
|
||||
}
|
||||
if (NotificationList.Items.Count == 0) (Application.Current.MainWindow as MainWindow)?.HideAuxilliaryPane();
|
||||
if (NotificationList.Items.Count == 0) await window.HideAuxilliaryPane();
|
||||
}
|
||||
|
||||
private void Page_Unloaded(object sender, RoutedEventArgs e)
|
||||
|
|
|
@ -16,23 +16,40 @@
|
|||
CornerRadius="2"
|
||||
BorderBrush="{TemplateBinding Background}"
|
||||
TextElement.Foreground="{TemplateBinding Foreground}"
|
||||
Tag="{TemplateBinding Background}"
|
||||
BorderThickness="1"
|
||||
Background="{TemplateBinding Background}">
|
||||
Background="{TemplateBinding Background}"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<ContentPresenter HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
TextElement.FontWeight="Regular"
|
||||
Margin="4,0" >
|
||||
</ContentPresenter>
|
||||
<Border.RenderTransform>
|
||||
<ScaleTransform x:Name="buttonScaleTransform" />
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" TargetName="border" Value="#4E9ED0"/>
|
||||
</Trigger>
|
||||
<EventTrigger RoutedEvent="Click">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="buttonScaleTransform"
|
||||
Storyboard.TargetProperty="ScaleX"
|
||||
To="0.9" Duration="0:0:.10" AutoReverse="True"/>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="buttonScaleTransform"
|
||||
Storyboard.TargetProperty="ScaleY"
|
||||
To="0.9" Duration="0:0:.10" AutoReverse="True"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" TargetName="border" Value="#FF338BC1"/>
|
||||
<Setter Property="BorderBrush" TargetName="border" Value="#FF338BC1"/>
|
||||
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" TargetName="grid" Value="0.25"/>
|
||||
|
@ -74,6 +91,9 @@
|
|||
Property="Height"
|
||||
Value="6" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" TargetName="CornerScrollBarRectangle" Value="#FF338BC1"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
|
@ -81,7 +101,7 @@
|
|||
</Style>
|
||||
<Style TargetType="{x:Type ScrollBar}">
|
||||
<Setter Property="Stylus.IsFlicksEnabled"
|
||||
Value="false" />
|
||||
Value="True" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{StaticResource ForegroundColor}" />
|
||||
<Setter Property="Background"
|
||||
|
@ -296,14 +316,13 @@
|
|||
x:Name="Border"
|
||||
Grid.ColumnSpan="2"
|
||||
CornerRadius="2" Padding="5"
|
||||
Background="{StaticResource ForegroundColor}"
|
||||
/>
|
||||
Background="{StaticResource ForegroundColor}"/>
|
||||
<Border
|
||||
x:Name="Border2"
|
||||
Grid.Column="0"
|
||||
CornerRadius="2"
|
||||
Margin="1"
|
||||
Background="{StaticResource ForegroundColor}"
|
||||
/>
|
||||
Background="{StaticResource ForegroundColor}" />
|
||||
<Path
|
||||
x:Name="Arrow"
|
||||
Grid.Column="1"
|
||||
|
@ -313,6 +332,12 @@
|
|||
Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z"
|
||||
/>
|
||||
</Grid>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" TargetName="Border" Value="#FF338BC1"/>
|
||||
<Setter Property="Background" TargetName="Border2" Value="#FF338BC1"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
|
||||
<ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
|
||||
|
@ -451,4 +476,112 @@
|
|||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--CheckBox-->
|
||||
|
||||
<Style x:Key="{x:Type CheckBox}" TargetType="{x:Type CheckBox}">
|
||||
<Setter Property="Background" Value="{StaticResource ForegroundColor}"/>
|
||||
<Setter Property="BorderBrush" Value="{StaticResource ForegroundColor}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="CheckBox">
|
||||
<Grid VerticalAlignment="Center" Background="Transparent">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="1*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border x:Name="Grid" VerticalAlignment="Top" Grid.Column="0" Margin="0,0,5,0" Width="22" Height="22"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="2"
|
||||
CornerRadius="2"
|
||||
RenderTransformOrigin="0.5,0.5"
|
||||
SnapsToDevicePixels="True" Padding="3">
|
||||
<Viewbox x:Name="Check" Stretch="UniformToFill" Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,-3,0,0">
|
||||
<Path Fill="{StaticResource PrimaryTextColor}" Data="M 17.939453 5.439453 L 7.5 15.888672 L 2.060547 10.439453 L 2.939453 9.560547 L 7.5 14.111328 L 17.060547 4.560547 Z"/>
|
||||
</Viewbox>
|
||||
<Border.RenderTransform>
|
||||
<ScaleTransform x:Name="ScaleTransform"/>
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
<ContentPresenter Grid.Column="1" VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<!--<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
<Setter TargetName="Check" Property="Visibility" Value="Visible"/>
|
||||
</MultiTrigger.Conditions>
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
<Condition Property="IsMouseOver" Value="False"/>
|
||||
</MultiTrigger.Conditions>
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsChecked" Value="False"/>
|
||||
<Condition Property="IsMouseOver" Value="True"/>
|
||||
</MultiTrigger.Conditions>
|
||||
</MultiTrigger>
|
||||
<MultiTrigger>
|
||||
<MultiTrigger.Conditions>
|
||||
<Condition Property="IsChecked" Value="True"/>
|
||||
<Condition Property="IsMouseOver" Value="False"/>
|
||||
</MultiTrigger.Conditions>
|
||||
</MultiTrigger>-->
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter TargetName="Check" Property="Visibility" Value="Visible"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Grid" Property="BorderBrush" Value="#FF338BC1"/>
|
||||
</Trigger>
|
||||
<EventTrigger RoutedEvent="Click">
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ScaleTransform"
|
||||
Storyboard.TargetProperty="ScaleX"
|
||||
To="0.9" Duration="0:0:.10" AutoReverse="True"/>
|
||||
<DoubleAnimation
|
||||
Storyboard.TargetName="ScaleTransform"
|
||||
Storyboard.TargetProperty="ScaleY"
|
||||
To="0.9" Duration="0:0:.10" AutoReverse="True"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</EventTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!--ListBox-->
|
||||
|
||||
<!--<Style x:Key="{x:Type ListBoxItem}" TargetType="{x:Type ListBoxItem}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ListBoxItem}">
|
||||
<Border x:Name="myBorder"
|
||||
Padding="5,2,0,2"
|
||||
CornerRadius="2"
|
||||
SnapsToDevicePixels="true">
|
||||
<ContentPresenter />
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsSelected" Value="true">
|
||||
<Setter TargetName="myBorder" Property="Background" Value="#FF338BC1"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="myBorder" Property="Background" Value="#FF338BC1"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>-->
|
||||
|
||||
</ResourceDictionary>
|
Loading…
Reference in a new issue