laptop->pc

This commit is contained in:
unknown
2025-07-04 21:51:23 +02:00
parent 9a8ad0bb2f
commit 739e5ccfa6
35 changed files with 685 additions and 293 deletions

View File

@@ -3,174 +3,132 @@
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"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
KeyUp="Key_Up">
<Grid>
<!-- Layout Definitions -->
KeyUp="Key_Up"
PreviewKeyDown="MainWindow_PreviewKeyDown"
Loaded="MainWindow_Loaded"
KeyboardNavigation.DirectionalNavigation="None">
<Window.Resources>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="BorderThickness" Value="2"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid KeyboardNavigation.DirectionalNavigation="None">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"/> <!-- Top bar -->
<RowDefinition/> <!-- Content -->
<RowDefinition Height="70"/> <!-- Bottom player -->
<RowDefinition Height="60"/>
<RowDefinition/>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<!-- TOP BAR -->
<Grid Grid.ColumnSpan="2" Grid.Row="0" Background="#333">
<Button Content="Login"
Width="80"
Margin="10,10,0,10"
HorizontalAlignment="Left"
VerticalAlignment="Center"/>
<Grid Grid.ColumnSpan="2" Grid.Row="0" Background="#333" KeyboardNavigation.DirectionalNavigation="None">
<Button Content="Login" TabIndex="0" Focusable="True" Width="80" Margin="10,10,0,10"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Width="300">
<TextBox Name="SearchBox"
Padding="8"
FontSize="14"
Background="White"
Foreground="Black"/>
<TextBlock Text="Search..."
Margin="12,0,0,0"
VerticalAlignment="Center"
Foreground="Gray"
IsHitTestVisible="False"/>
<TextBox Name="SearchBox" TabIndex="1" Focusable="True" Padding="8" FontSize="14"
Background="White" Foreground="Black"/>
<TextBlock Text="Search..." Margin="12,0,0,0" VerticalAlignment="Center"
Foreground="Gray" IsHitTestVisible="False"/>
</Grid>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right"
Margin="0,0,20,0"
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,20,0"
VerticalAlignment="Center">
<Button Content="scann"
Width="40"
Height="40"
Margin="0,0,10,0"
Click="scanButton_Click"/>
<Button Content="scann" TabIndex="2" Focusable="True" Width="40" Height="40"
Margin="0,0,10,0" Click="scanButton_Click"/>
</StackPanel>
</Grid>
<!-- LEFT NAVIGATION -->
<StackPanel Grid.Row="1"
Grid.Column="0"
Background="#222"
VerticalAlignment="Stretch">
<Button Content="Home" Height="60" Foreground="White" Background="Transparent" Click="Home_OnClick" />
<Button Content="Musik" Height="60" Foreground="White" Background="Transparent" Click="Musik_OnClick"/>
<Button Content="Photos" Height="60" Foreground="White" Background="Transparent" Click="Photo_OnClick"/>
<Button Content="Video" Height="60" Foreground="White" Background="Transparent" Click="Video_OnClick" />
<Button Content="Playlist" Height="60" Foreground="White" Background="Transparent" Click="PlayListButton_OnClick" />
<StackPanel Name="catPan" Grid.Row="1" Grid.Column="0" Background="#222" VerticalAlignment="Stretch"
KeyboardNavigation.DirectionalNavigation="None">
<Button Name="FirstCat" Content="Home" Height="60" TabIndex="3" Focusable="True"
Foreground="White" Background="Transparent" Click="Home_OnClick"/>
<Button Content="Musik" Height="60" TabIndex="4" Focusable="True"
Foreground="White" Background="Transparent" Click="Musik_OnClick"/>
<Button Content="Photos" Height="60" TabIndex="5" Focusable="True"
Foreground="White" Background="Transparent" Click="Photo_OnClick"/>
<Button Content="Video" Height="60" TabIndex="6" Focusable="True"
Foreground="White" Background="Transparent" Click="Video_OnClick"/>
<Button Content="Playlist" Height="60" TabIndex="7" Focusable="True"
Foreground="White" Background="Transparent" Click="PlayListButton_OnClick"/>
</StackPanel>
<!-- MAIN CONTENT WRAPPED IN A GRID FOR LAYERING -->
<Grid Grid.Column="1" Grid.Row="1">
<!-- ScrollViewer (Background) -->
<ScrollViewer x:Name="ScrollContentHome" Background="#444" Panel.ZIndex="0">
<StackPanel Margin="10">
<!-- Favorites -->
<!-- MAIN CONTENT -->
<Grid Grid.Column="1" Grid.Row="1" KeyboardNavigation.DirectionalNavigation="None">
<ScrollViewer x:Name="ScrollContentHome" Background="#444" Panel.ZIndex="0"
KeyboardNavigation.DirectionalNavigation="None" Focusable="False">
<StackPanel Margin="10" KeyboardNavigation.DirectionalNavigation="None">
<TextBlock Text="Favorites" FontSize="18" Foreground="White" Margin="0,10"/>
<WrapPanel Name="Favorites_Home">
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<WrapPanel Name="Favorites_Home" KeyboardNavigation.DirectionalNavigation="None"/>
<!-- Movies -->
<TextBlock Text="Movies" FontSize="18" Foreground="White" Margin="0,20,0,10"/>
<WrapPanel Name="Muvies_Home">
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<!-- Series -->
<WrapPanel Name="Muvies_Home" KeyboardNavigation.DirectionalNavigation="None"/>
<TextBlock Text="Series" FontSize="18" Foreground="White" Margin="0,20,0,10"/>
<WrapPanel Name="Series_Home">
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightGreen" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<WrapPanel Name="Series_Home" KeyboardNavigation.DirectionalNavigation="None"/>
<!-- Music -->
<TextBlock Text="Music" FontSize="18" Foreground="White" Margin="0,20,0,10"/>
<WrapPanel Name="Music_Home">
<Rectangle Fill="LightCoral" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightCoral" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightCoral" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightCoral" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<!-- Photos -->
<WrapPanel Name="Music_Home" KeyboardNavigation.DirectionalNavigation="None"/>
<TextBlock Text="Photos" FontSize="18" Foreground="White" Margin="0,20,0,10"/>
<WrapPanel Name="Photos_Home">
<Rectangle Fill="DarkRed" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="DarkRed" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="DarkRed" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="DarkRed" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<WrapPanel Name="Photos_Home" KeyboardNavigation.DirectionalNavigation="None"/>
</StackPanel>
</ScrollViewer>
<!-- Video Player (Foreground) -->
<vlc:VideoView x:Name="VideoView"
Panel.ZIndex="1"
Visibility="Collapsed"
Background="Black" />
<!--Catagory-->
<ScrollViewer x:Name="ScrollContentCat" Background="#444" Panel.ZIndex="0" Visibility="Collapsed">
<StackPanel Margin="10">
<!-- Cat-name -->
<!-- VIDEO PLAYER -->
<vlc:VideoView x:Name="VideoView" Panel.ZIndex="1" Visibility="Collapsed" Background="Black"/>
<!-- CATEGORY VIEW -->
<ScrollViewer x:Name="ScrollContentCat" Background="#444" Panel.ZIndex="0" Visibility="Collapsed"
Focusable="False" KeyboardNavigation.DirectionalNavigation="None">
<StackPanel Margin="10" KeyboardNavigation.DirectionalNavigation="None">
<TextBlock Name="Name_of_Catagory_Text" Text="Name_of_Catagory" FontSize="18" Foreground="White" Margin="0,10"/>
<WrapPanel Name="Name_of_Catagory">
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<WrapPanel Name="Name_of_Catagory" KeyboardNavigation.DirectionalNavigation="None"/>
<TextBlock Name="Name_of_Catagory_Text1" Text="Name_of_Catagory1" FontSize="18" Foreground="White" Margin="0,10"/>
<WrapPanel Name="Name_of_Catagory1" Visibility="Collapsed">
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
<Rectangle Fill="LightBlue" Width="150" Height="100" Margin="5"/>
</WrapPanel>
<WrapPanel Name="Name_of_Catagory1" Visibility="Collapsed" KeyboardNavigation.DirectionalNavigation="None"/>
</StackPanel>
</ScrollViewer>
<!--Playlists-->
<ScrollViewer x:Name="ScrollContentPlaylist" Background="#444" Panel.ZIndex="0" Visibility="Collapsed">
<StackPanel x:Name="PlaylistContentPanel">
<Button Content="New Playlist" Background="Black" Foreground="White" Click="PlayListButton_Click"></Button>
</StackPanel>
<!-- PLAYLIST VIEW -->
<ScrollViewer x:Name="ScrollContentPlaylist" Background="#444" Panel.ZIndex="0" Visibility="Collapsed"
Focusable="False" KeyboardNavigation.DirectionalNavigation="None">
<StackPanel x:Name="PlaylistContentPanel" KeyboardNavigation.DirectionalNavigation="None"/>
</ScrollViewer>
</Grid>
<!-- SETTINGS BUTTON -->
<Button Grid.Column="0" Grid.Row="2"
Content="Settings"
Margin="10"
HorizontalAlignment="Left"
Click="PlayListButton_Click"/>
<Button Grid.Column="0" Grid.Row="2" Content="Settings" Margin="10" HorizontalAlignment="Left"
TabIndex="8" Focusable="True" Click="PlayListButton_Click"/>
<!-- PLAYER PROGRESS -->
<Slider Name="itemProgress" TabIndex="9" Focusable="True" PreviewMouseDown="ItemProgress_OnPreviewMouseDown"
Panel.ZIndex="2" VerticalAlignment="Top" ValueChanged="ItemProgress_OnValueChanged"
Grid.Row="2" Grid.Column="1" Padding="10"/>
<ProgressBar Name="itemProgressVisual" Panel.ZIndex="1" Height="20" VerticalAlignment="Top"
Grid.Row="2" Grid.Column="1" Padding="10"/>
<!-- PLAYER CONTROLS -->
<Slider Name="itemProgress" PreviewMouseDown="ItemProgress_OnPreviewMouseDown" Panel.ZIndex="2" VerticalAlignment="Top" ValueChanged="ItemProgress_OnValueChanged" Grid.Row="2" Grid.Column="1" Padding="10"></Slider>
<ProgressBar Name="itemProgressVisual" Panel.ZIndex="1" Height="20" VerticalAlignment="Top" Grid.Row="2" Grid.Column="1" Padding="10"></ProgressBar>
<StackPanel Grid.Column="1" Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Background="#222">
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center"
VerticalAlignment="Bottom" Background="#222" KeyboardNavigation.DirectionalNavigation="None">
<TextBlock Name="title" Text="Titel" Foreground="White" FontSize="16" Margin="10"/>
<Button Content="⏮" Width="40" Margin="10" Click="OnItemPriorButtonClick"/>
<Button Content="▶" Width="40" Margin="10" Click="OnItemPauseBtn_Click"/>
<Button Content="⏭" Width="40" Margin="10" Click="OnItemNextButtonClick"/>
<Button Content="⏮" Width="40" Margin="10" TabIndex="10" Focusable="True" Click="OnItemPriorButtonClick"/>
<Button Content="▶" Width="40" Margin="10" TabIndex="11" Focusable="True" Click="OnItemPauseBtn_Click"/>
<Button Content="⏭" Width="40" Margin="10" TabIndex="12" Focusable="True" Click="OnItemNextButtonClick"/>
<TextBlock Text="🔊" Foreground="White" VerticalAlignment="Center" Margin="10,0"/>
<Slider Name="vol" Width="100" Minimum="0" Maximum="100" Value="50" Margin="10" ValueChanged="RangeBase_OnValueChanged"/>
<Slider Name="vol" Width="100" Minimum="0" Maximum="100" Value="50" Margin="10"
TabIndex="13" Focusable="True" ValueChanged="RangeBase_OnValueChanged"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -82,6 +82,11 @@ public partial class MainWindow : Window
#endregion
//code start
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
FirstCat?.Focus();
}
public MainWindow()
{
#region Init wpf
@@ -460,12 +465,14 @@ public partial class MainWindow : Window
{
Close_Player();
Name_of_Catagory_Text1.Visibility = Visibility.Collapsed;
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Collapsed;
Name_of_Catagory1.Visibility = Visibility.Collapsed;
PopulateAllCategoriesFromPlaylists();
PopulateAllCategoriesFromPlaylists(); // <-- This needs to set ScrollContentPlaylist visible
}
#endregion
@@ -841,6 +848,8 @@ public partial class MainWindow : Window
// Make the ScrollViewer visible
ScrollContentPlaylist.Visibility = Visibility.Visible;
PopulatePlaylistsWithButtons();
}
#region tvRemote
@@ -854,6 +863,7 @@ public partial class MainWindow : Window
Dispatcher.Invoke(() =>
{
MessageBox.Show("🔗 Client connected!");
});
};
@@ -862,7 +872,25 @@ public partial class MainWindow : Window
Dispatcher.Invoke(() =>
{
MessageBox.Show($"📨 Message: {msg.Trim()}");
switch (msg.Trim())
{
//arrow up
case "\u2191": MessageBox.Show("case 1"); break;
//arrow down
case "\u2193": MessageBox.Show("case 2"); break;
//arrow left
//arrow right
//double left
//double right
//enter
//home
//vol +
//vol -
//mute
//time stamp
}
});
// Optional: echo back the message
Server1.SendMessage("Echo: " + msg.Trim());
@@ -1004,103 +1032,204 @@ public partial class MainWindow : Window
}
}
private void PopulatePlaylistsWithButtons()
{
// Make sure the playlist ScrollViewer is visible
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Collapsed;
ScrollContentPlaylist.Visibility = Visibility.Visible;
// Clear previous content
PlaylistContentPanel.Children.Clear();
// Add "New Playlist" button
var newPlaylistBtn = new Button
{
Content = "New Playlist",
Background = Brushes.Black,
Foreground = Brushes.White,
Margin = new Thickness(5)
};
newPlaylistBtn.Click += PlayListButton_Click;
PlaylistContentPanel.Children.Add(newPlaylistBtn);
// Guard: If there are no playlists, show a message
if (_playlists?.SharedRefs == null || !_playlists.SharedRefs.Any())
{
PlaylistContentPanel.Children.Add(new TextBlock
{
Text = "No playlists available.",
Foreground = Brushes.White,
Margin = new Thickness(10)
});
return;
}
// Add playlist sections
foreach (var playlistCategory in _playlists.SharedRefs)
{
var container = new StackPanel
{
Margin = new Thickness(10),
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Stretch
};
// Header row with playlist name and ">>" button
var headerRow = new DockPanel
{
LastChildFill = true, // Let the title take remaining space
HorizontalAlignment = HorizontalAlignment.Stretch
};
// Button (goes first, docked right)
var btn = new Button
{
Content = ">>",
Width = 30,
Height = 25,
Margin = new Thickness(10, 0, 0, 0),
VerticalAlignment = VerticalAlignment.Center
};
DockPanel.SetDock(btn, Dock.Right);
btn.Click += (s, e) => ShowFullCategoryView(playlistCategory);
headerRow.Children.Add(btn);
// Playlist name
var title = new TextBlock
{
Text = playlistCategory.name,
FontSize = 18,
FontWeight = FontWeights.Bold,
Foreground = Brushes.White,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(5)
};
headerRow.Children.Add(title);
container.Children.Add(headerRow);
// Preview items in WrapPanel
var wrap = new WrapPanel();
PopulatePanelWithItems(playlistCategory.getAllItems().Take(9).ToList(), wrap);
container.Children.Add(wrap);
PlaylistContentPanel.Children.Add(container);
}
}
private void ShowFullCategoryView(Catagory category)
{
ScrollContentHome.Visibility = Visibility.Collapsed;
ScrollContentPlaylist.Visibility = Visibility.Collapsed;
ScrollContentCat.Visibility = Visibility.Visible;
Name_of_Catagory_Text.Text = category.name;
Name_of_Catagory1.Visibility = Visibility.Collapsed;
PopulatePanelWithItems(category.getAllItems(), Name_of_Catagory);
}
#endregion
#region load saved data
private async void LoadSavedData()
{
try
{
Jason_Writer jason_Writer = new Jason_Writer(); // Uses default "Temp Data" folder
// Load main media lists
var muvies = await jason_Writer.LoadListAsync("Muvies");
var series = await jason_Writer.LoadListAsync("Series");
var photos = await jason_Writer.LoadListAsync("Photos");
var music = await jason_Writer.LoadListAsync("Music");
var favorites = await jason_Writer.LoadListAsync("Favorit");
// Initialize progress bar with total count
progressScann = new ProgressBar("Reading saved data",
muvies.Count + series.Count + photos.Count + music.Count + favorites.Count);
progressScann.Show();
// Create Item lists from JSON
List<Item> MuvieItems = CreateItemsFromJson(muvies);
List<Item> SerieItems = CreateItemsFromJson(series);
List<Item> PhotoItems = CreateItemsFromJson(photos, isPhoto: true);
List<Item> MusicItems = CreateItemsFromJson(music, isPhoto: false, isMusic: true);
Muvie.addItems(MuvieItems);
Serie.addItems(SerieItems);
Photo.addItems(PhotoItems);
Music.addItems(MusicItems);
// Combine all media items for playlist/favorite matching
var allLocs = muvies.Concat(series).Concat(photos).Concat(music).ToList();
// Enrich favorite items by matching them with main list entries
var enrichedFavorites = new List<locJason>();
foreach (var fav in favorites)
{
var match = allLocs.FirstOrDefault(item =>
string.Equals(item.path, fav.path, StringComparison.OrdinalIgnoreCase));
if (match != null)
{
enrichedFavorites.Add(match);
}
else
{
enrichedFavorites.Add(fav); // fallback if not found
Console.WriteLine($"[Warning] Favorite not found in main lists: {fav.path}");
}
}
List<Item> FavoriteItems = CreateItemsFromJson(enrichedFavorites);
Favorites.addItems(FavoriteItems);
// Load playlists
var playlistNames = await jason_Writer.GetSavedPlaylistNamesAsync();
foreach (var playlistName in playlistNames)
{
var playlistEntries = await jason_Writer.LoadPlaylistListAsync(playlistName);
var matchedLocs = new List<locJason>();
foreach (var entry in playlistEntries)
{
var match = allLocs.FirstOrDefault(item =>
string.Equals(item.path, entry.path, StringComparison.OrdinalIgnoreCase));
if (match != null)
try
{
matchedLocs.Add(match);
Jason_Writer jason_Writer = new Jason_Writer(); // Uses default "Temp Data" folder
// Load main media lists
var muvies = await jason_Writer.LoadListAsync("Muvies");
var series = await jason_Writer.LoadListAsync("Series");
var photos = await jason_Writer.LoadListAsync("Photos");
var music = await jason_Writer.LoadListAsync("Music");
var favorites = await jason_Writer.LoadListAsync("Favorit");
// Initialize progress bar with total count
progressScann = new ProgressBar("Reading saved data",
muvies.Count + series.Count + photos.Count + music.Count + favorites.Count);
progressScann.Show();
// Create Item lists from JSON
List<Item> MuvieItems = CreateItemsFromJson(muvies);
List<Item> SerieItems = CreateItemsFromJson(series);
List<Item> PhotoItems = CreateItemsFromJson(photos, isPhoto: true);
List<Item> MusicItems = CreateItemsFromJson(music, isPhoto: false, isMusic: true);
Muvie.addItems(MuvieItems);
Serie.addItems(SerieItems);
Photo.addItems(PhotoItems);
Music.addItems(MusicItems);
// Combine all media items for playlist/favorite matching
var allLocs = muvies.Concat(series).Concat(photos).Concat(music).ToList();
// Enrich favorite items by matching them with main list entries
var enrichedFavorites = new List<locJason>();
foreach (var fav in favorites)
{
var match = allLocs.FirstOrDefault(item =>
string.Equals(item.path, fav.path, StringComparison.OrdinalIgnoreCase));
if (match != null)
{
enrichedFavorites.Add(match);
}
else
{
enrichedFavorites.Add(fav); // fallback if not found
Console.WriteLine($"[Warning] Favorite not found in main lists: {fav.path}");
}
}
List<Item> FavoriteItems = CreateItemsFromJson(enrichedFavorites);
Favorites.addItems(FavoriteItems);
// Load playlists
var playlistNames = await jason_Writer.GetSavedPlaylistNamesAsync();
foreach (var playlistName in playlistNames)
{
var playlistEntries = await jason_Writer.LoadPlaylistListAsync(playlistName);
var matchedLocs = new List<locJason>();
foreach (var entry in playlistEntries)
{
var match = allLocs.FirstOrDefault(item =>
string.Equals(item.path, entry.path, StringComparison.OrdinalIgnoreCase));
if (match != null)
{
matchedLocs.Add(match);
}
else
{
Console.WriteLine($"[Warning] Playlist '{playlistName}' contains unknown path: {entry.path}");
}
}
List<Item> PlaylistItems = CreateItemsFromJson(matchedLocs);
var playlistCategory = new Catagory(playlistName);
playlistCategory.addItems(PlaylistItems);
_playlists.SharedRefs.Add(playlistCategory);
}
MenueItems(); // Refresh the UI
progressScann.Hide();
log.Log("Loaded saved data from JSON.");
}
else
catch (Exception ex)
{
Console.WriteLine($"[Warning] Playlist '{playlistName}' contains unknown path: {entry.path}");
MessageBox.Show($"Failed to load saved data:\n{ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
log.Error($"LoadSavedData error: {ex}");
}
}
List<Item> PlaylistItems = CreateItemsFromJson(matchedLocs);
var playlistCategory = new Catagory(playlistName);
playlistCategory.addItems(PlaylistItems);
_playlists.SharedRefs.Add(playlistCategory);
}
MenueItems(); // Refresh the UI
progressScann.Hide();
log.Log("Loaded saved data from JSON.");
}
catch (Exception ex)
{
MessageBox.Show($"Failed to load saved data:\n{ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
log.Error($"LoadSavedData error: {ex}");
}
}
private List<Item> CreateItemsFromJson(List<locJason> jsonItems)
{
return CreateItemsFromJson(jsonItems, isPhoto: false, isMusic: false);
@@ -1245,14 +1374,6 @@ public partial class MainWindow : Window
{
switch (e.Key)
{
case Key.Left:_mediaPlayer.Time=_mediaPlayer.Time-10000;break;
case Key.Right:_mediaPlayer.Time=_mediaPlayer.Time+10000;break;
case Key.Space:
if (_mediaPlayer.IsPlaying)
_mediaPlayer.Pause();
else
_mediaPlayer.Play();
break;
case Key.Escape:
var result = MessageBox.Show(
"Do you want to quit?",
@@ -1268,8 +1389,223 @@ public partial class MainWindow : Window
break;
}
}
if (VideoView.IsVisible)
{
switch (e.Key)
{
case Key.Left:_mediaPlayer.Time=_mediaPlayer.Time-10000;break;
case Key.Right:_mediaPlayer.Time=_mediaPlayer.Time+10000;break;
case Key.Space:
if (_mediaPlayer.IsPlaying)
_mediaPlayer.Pause();
else
_mediaPlayer.Play();
break;
}
}
else
{
}
}
#endregion
#region arrow nav
private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.FocusedElement is not DependencyObject focusedElement)
return;
var wrapPanel = FindAncestor<WrapPanel>(focusedElement);
if (wrapPanel != null && wrapPanel.Children.Count > 0)
{
int focusedIndex = FindFocusedIndexInWrapPanel(wrapPanel, focusedElement);
if (focusedIndex == -1)
return;
int columns = CalculateColumns(wrapPanel);
switch (e.Key)
{
case Key.Left:
e.Handled = true;
if (IsLeftmostInRow(focusedIndex, columns))
{
FirstCat?.Focus();
}
else
{
MoveFocusInWrapPanel(wrapPanel, focusedIndex - 1);
}
break;
case Key.Right:
e.Handled = true;
MoveFocusInWrapPanel(wrapPanel, focusedIndex + 1);
break;
case Key.Up:
e.Handled = true;
MoveFocusInWrapPanel(wrapPanel, focusedIndex - columns);
break;
case Key.Down:
e.Handled = true;
MoveFocusInWrapPanel(wrapPanel, focusedIndex + columns);
break;
}
}
else if (FirstCat.IsFocused && e.Key == Key.Right)
{
// Find the first visible WrapPanel child in your current visible ScrollViewer
var firstFocusable = FindFirstFocusableInVisibleWrapPanel();
if (firstFocusable != null)
{
firstFocusable.Focus();
e.Handled = true;
}
}
}
// Finds the first focusable control in the first visible WrapPanel child of your main ScrollViewer content
private Control FindFirstFocusableInVisibleWrapPanel()
{
ScrollViewer currentScrollViewer = null;
if (ScrollContentHome.Visibility == Visibility.Visible)
{
currentScrollViewer = ScrollContentHome;
}
else if (ScrollContentCat.Visibility == Visibility.Visible)
{
currentScrollViewer = ScrollContentCat;
}
else if (ScrollContentPlaylist.Visibility == Visibility.Visible)
{
currentScrollViewer = ScrollContentPlaylist;
}
else
{
Console.WriteLine("No visible ScrollViewer found");
return null;
}
Panel mainPanel = currentScrollViewer.Content as Panel;
if (mainPanel != null)
{
for (int i = 0; i < mainPanel.Children.Count; i++)
{
var child = mainPanel.Children[i];
WrapPanel wp = child as WrapPanel;
if (wp != null && wp.Visibility == Visibility.Visible && wp.Children.Count > 0)
{
Control firstFocusable = FindFirstFocusableChild(wp);
if (firstFocusable != null)
{
return firstFocusable;
}
}
}
}
else
{
Console.WriteLine("ScrollViewer content is not a Panel");
}
Control fallback = FindFirstFocusableChild(currentScrollViewer.Content as DependencyObject);
if (fallback != null)
return fallback;
return null;
}
// ... rest of your helpers remain unchanged ...
private int CalculateColumns(WrapPanel panel)
{
if (panel.Children.Count == 0) return 1;
var firstChild = panel.Children[0] as FrameworkElement;
if (firstChild == null) return 1;
double itemWidth = firstChild.ActualWidth + firstChild.Margin.Left + firstChild.Margin.Right;
if (itemWidth <= 1) itemWidth = 150; // fallback
double panelWidth = panel.ActualWidth;
int columns = Math.Max(1, (int)(panelWidth / itemWidth));
return columns;
}
private bool IsLeftmostInRow(int index, int columns) => (index % columns) == 0;
private void MoveFocusInWrapPanel(WrapPanel panel, int index)
{
if (index < 0 || index >= panel.Children.Count) return;
if (panel.Children[index] is Control ctrl && ctrl.Focusable)
ctrl.Focus();
else if (panel.Children[index] is Panel container)
{
var focusable = FindFirstFocusableChild(container);
focusable?.Focus();
}
}
private int FindFocusedIndexInWrapPanel(WrapPanel panel, DependencyObject focusedElement)
{
for (int i = 0; i < panel.Children.Count; i++)
{
var container = panel.Children[i];
if (IsOrContains(container, focusedElement))
return i;
}
return -1;
}
private bool IsOrContains(DependencyObject parent, DependencyObject child)
{
if (parent == child) return true;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var sub = VisualTreeHelper.GetChild(parent, i);
if (IsOrContains(sub, child))
return true;
}
return false;
}
private Control FindFirstFocusableChild(DependencyObject parent)
{
if (parent is Control c && c.Focusable)
return c;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var found = FindFirstFocusableChild(VisualTreeHelper.GetChild(parent, i));
if (found != null)
return found;
}
return null;
}
private static T FindAncestor<T>(DependencyObject child) where T : DependencyObject
{
DependencyObject current = child;
while (current != null)
{
if (current is T match)
return match;
current = VisualTreeHelper.GetParent(current);
}
return null;
}
#endregion
}