HomeStream/MainWindow.xaml

418 lines
27 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<Window x:Class="FritzTV.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
Title="HomeStream"
Height="720" Width="1280"
Background="#1A1A1A"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<Style x:Key="SidebarButton" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#DDD"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="16,10"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="bd" Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}">
<ContentPresenter VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="#2A2A2A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Dunkle Scrollbars (sonst sind die Standard-WPF-Scrollbars hellgrau) -->
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="#0E0E0E"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Background="{TemplateBinding Background}">
<Track Name="PART_Track" IsDirectionReversed="true">
<Track.Thumb>
<Thumb>
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Border x:Name="thumbBd"
Background="#3A3A3A"
CornerRadius="3"
Margin="2"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="thumbBd" Property="Background" Value="#555"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Background="Transparent" BorderThickness="0"
Command="ScrollBar.PageDownCommand"
IsTabStop="False"/>
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton Background="Transparent" BorderThickness="0"
Command="ScrollBar.PageUpCommand"
IsTabStop="False"/>
</Track.DecreaseRepeatButton>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="10"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ChannelItem" TargetType="ListBoxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="#DDD"/>
<Setter Property="Padding" Value="12,8"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="bd" Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}">
<ContentPresenter/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bd" Property="Background" Value="#2A2A2A"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="bd" Property="Background" Value="#0078D4"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="SidebarColumn" Width="180"/>
<ColumnDefinition x:Name="ChannelsColumn" Width="280"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- Burger-Toggle: außerhalb der VideoView (sichtbar wenn Spalten eingeklappt + KEIN Sender läuft).
Wenn ein Sender läuft greift der Overlay-Burger innerhalb VideoView (HWND-Airspace). -->
<!-- (kein eigener Button hier mehr — BtnSidebarToggleOverlay reicht) -->
<!-- Sidebar: Kategorien -->
<Border Grid.Column="0" Background="#161616" BorderBrush="#0A0A0A" BorderThickness="0,0,1,0">
<DockPanel>
<Grid DockPanel.Dock="Top">
<TextBlock Text="HomeStream"
Foreground="White" FontSize="20" FontWeight="Bold"
Padding="16,20,16,16"/>
<Button x:Name="BtnCollapseSidebar"
HorizontalAlignment="Right" VerticalAlignment="Top"
Width="28" Height="28" Margin="0,16,8,0"
Background="Transparent" Foreground="#888" BorderThickness="0"
Content="" FontSize="14" Cursor="Hand"
Click="BtnCollapseSidebar_Click"
ToolTip="Kategorien einklappen"/>
</Grid>
<StackPanel DockPanel.Dock="Top">
<Button x:Name="BtnAll" Content="📺 Alle Sender" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="all"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnTvFritz" Content="🎬 TV (FritzBox)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv-fritz"
ToolTip="DVB-C über die FritzBox"/>
<Button x:Name="BtnTvOnline" Content="🎬 TV (Online)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="tv-online"
ToolTip="ÖR-TV über Internet (HLS)"/>
<Button x:Name="BtnRadioFritz" Content="📡 Radio (FritzBox)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio-fritz"
ToolTip="DVB-C-Radio über die FritzBox"/>
<Button x:Name="BtnRadioOnline" Content="📡 Radio (Online)" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="radio-online"
ToolTip="Webradio (ÖR-Streams)"/>
<Button x:Name="BtnWeb" Content="🌐 Streaming" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="web"
ToolTip="YouTube, Netflix, Mediatheken etc. (Browser)"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnFav" Content="⭐ Favoriten" Style="{StaticResource SidebarButton}" Click="BtnCategory_Click" Tag="fav"/>
<Separator Margin="8" Background="#333"/>
<Button x:Name="BtnEpgGrid" Content="📅 Programm" Style="{StaticResource SidebarButton}" Click="BtnEpgGrid_Click"
ToolTip="Programmübersicht aller Sender"/>
</StackPanel>
<StackPanel DockPanel.Dock="Bottom" Margin="16,0,16,16">
<Button x:Name="BtnSettings" Content="⚙ Einstellungen" Style="{StaticResource SidebarButton}" Click="BtnSettings_Click"/>
<Button x:Name="BtnAbout" Content=" Über" Style="{StaticResource SidebarButton}" Click="BtnAbout_Click"/>
<TextBlock x:Name="TxtFritzBox" Foreground="#666" FontSize="11" Margin="16,8,0,0"/>
</StackPanel>
</DockPanel>
</Border>
<!-- Kanal-Liste -->
<Border Grid.Column="1" Background="#1A1A1A" BorderBrush="#0A0A0A" BorderThickness="0,0,1,0">
<DockPanel>
<Grid DockPanel.Dock="Top">
<TextBox x:Name="TxtSearch"
Margin="12,12,40,4" Padding="8,8,28,8" FontSize="13"
Background="#2A2A2A" Foreground="White" BorderBrush="#444"
TextChanged="TxtSearch_TextChanged"
Tag="Suchen…"/>
<Button x:Name="BtnClearSearch" Content="✕" FontSize="11"
HorizontalAlignment="Right" VerticalAlignment="Center"
Width="22" Height="22" Margin="0,4,46,0"
Background="Transparent" Foreground="#888" BorderThickness="0"
Cursor="Hand" Visibility="Collapsed"
Click="BtnClearSearch_Click"
ToolTip="Suche zurücksetzen"/>
<Button x:Name="BtnCollapseList"
HorizontalAlignment="Right" VerticalAlignment="Top"
Width="28" Height="28" Margin="0,12,8,0"
Background="Transparent" Foreground="#888" BorderThickness="0"
Content="" FontSize="14" Cursor="Hand"
Click="BtnCollapseList_Click"
ToolTip="Senderliste einklappen"/>
</Grid>
<TextBlock x:Name="TxtStatus" DockPanel.Dock="Bottom"
Foreground="#666" FontSize="11" Padding="12,8"/>
<ListBox x:Name="LstChannels"
Background="Transparent" BorderThickness="0"
ItemContainerStyle="{StaticResource ChannelItem}"
SelectionChanged="LstChannels_SelectionChanged"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding LogoPath}"
Width="32" Height="24" Stretch="Uniform"
VerticalAlignment="Center" HorizontalAlignment="Left"
RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock Grid.Column="1" Text="{Binding Name}" FontSize="14" FontWeight="SemiBold"
VerticalAlignment="Center" Margin="6,0,0,0"/>
<TextBlock Grid.Column="2" VerticalAlignment="Center"
Text="⭐" FontSize="14"
Visibility="{Binding IsFavorite, Converter={StaticResource BoolToVis}}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DockPanel>
</Border>
<!-- Player + EPG -->
<Grid Grid.Column="2" Background="#000">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- VideoView + WebView2: beide im gleichen Grid-Cell, Visibility steuert wer sichtbar ist -->
<Grid Grid.Row="0">
<!-- VLC-Player fuer TV/Radio -->
<vlc:VideoView x:Name="VideoView" Background="Black">
<Border x:Name="VideoOverlay"
Background="#01000000"
PreviewMouseLeftButtonDown="VideoClickCatcher_DoubleClick">
<Grid>
<!-- Radio-Cover bei Audio-Streams — INNERHALB VideoView damit es die native HWND überdeckt -->
<Border x:Name="RadioCover" Visibility="Collapsed"
Background="#1A1A1A">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<Image x:Name="RadioLogo" Width="200" Height="200" Stretch="Uniform"
RenderOptions.BitmapScalingMode="HighQuality"/>
<TextBlock x:Name="RadioFallbackIcon" Text="📻"
FontSize="120" Foreground="#444"
HorizontalAlignment="Center"
Visibility="Collapsed"/>
<TextBlock x:Name="TxtRadioName"
FontSize="24" FontWeight="Bold" Foreground="White"
HorizontalAlignment="Center" Margin="0,24,0,0"/>
<TextBlock x:Name="TxtRadioText"
FontSize="16" Foreground="#0078D4" FontWeight="SemiBold"
HorizontalAlignment="Center" Margin="24,12,24,0"
TextWrapping="Wrap" TextAlignment="Center"
MaxWidth="600"/>
</StackPanel>
</Border>
<!-- EPG-Overlay (Joyn-Style): liegt INNERHALB der VideoView damit Klicks ber HWND funktionieren -->
<Border x:Name="EpgOverlay" Visibility="Collapsed"
Background="#D8000000">
<DockPanel>
<!-- Header: Programm + Datum/Zeit + Schließen -->
<Grid DockPanel.Dock="Top" Background="#0A0A0A" Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Programm"
Foreground="White" FontSize="24" FontWeight="Bold"
VerticalAlignment="Center" Margin="24,0"/>
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,16,0">
<TextBlock x:Name="TxtEpgDate" Foreground="#CCC" FontSize="14" VerticalAlignment="Center" Margin="0,0,16,0"/>
<TextBlock x:Name="TxtEpgTime" Foreground="White" FontSize="18" FontWeight="SemiBold" VerticalAlignment="Center" Margin="0,0,16,0"/>
<Button x:Name="BtnCloseEpg" Content="✕" FontSize="18"
Width="40" Height="40"
Background="Transparent" Foreground="White" BorderThickness="0"
Cursor="Hand"
Click="BtnCloseEpg_Click"
ToolTip="Schließen (Esc)"/>
</StackPanel>
</Grid>
<!-- Status-Zeile (Lade EPG… etc.) -->
<TextBlock x:Name="TxtEpgOverlayStatus" DockPanel.Dock="Bottom"
Foreground="#888" FontSize="11" Padding="24,8"
Background="#0A0A0A"/>
<!-- Scrollbares EPG-Grid (Canvas) -->
<!-- ScrollBar-Style explizit hier weil vlc:VideoView eine eigene HWND hat
und Window.Resources-Styles dort nicht greifen -->
<ScrollViewer x:Name="EpgScrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Background="#0A0A0A">
<ScrollViewer.Resources>
<Style TargetType="ScrollBar">
<Setter Property="Background" Value="#0E0E0E"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<Grid Background="{TemplateBinding Background}">
<Track Name="PART_Track" IsDirectionReversed="true">
<Track.Thumb>
<Thumb>
<Thumb.Template>
<ControlTemplate TargetType="Thumb">
<Border x:Name="thumbBd" Background="#3A3A3A" CornerRadius="3" Margin="2"/>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="thumbBd" Property="Background" Value="#555"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Background="Transparent" BorderThickness="0" Command="ScrollBar.PageDownCommand" IsTabStop="False"/>
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton Background="Transparent" BorderThickness="0" Command="ScrollBar.PageUpCommand" IsTabStop="False"/>
</Track.DecreaseRepeatButton>
</Track>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Orientation" Value="Horizontal">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="10"/>
</Trigger>
</Style.Triggers>
</Style>
</ScrollViewer.Resources>
<Canvas x:Name="EpgCanvas"/>
</ScrollViewer>
</DockPanel>
</Border>
</Grid>
</Border>
</vlc:VideoView>
<!-- WebView2 fuer Web-Sender (YouTube, Netflix, Mediatheken etc.) -->
<!-- Persistentes User-Data-Profil: Login bleibt erhalten -->
<!-- Liegt VOR dem VideoView im Z-Order, damit Klicks nicht vom VideoOverlay gefangen werden -->
<wv2:WebView2 x:Name="WebView"
Visibility="Collapsed"
Panel.ZIndex="5"/>
<!-- Burger-Button: ausserhalb VideoOverlay damit er auch bei WebView-Modus sichtbar bleibt -->
<Button x:Name="BtnSidebarToggleOverlay"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="36" Height="36" Margin="8"
Background="#80000000" Foreground="White" BorderThickness="0"
Content="☰" FontSize="16" Cursor="Hand"
Visibility="Collapsed"
Panel.ZIndex="20"
Click="BtnSidebarToggle_Click"
ToolTip="Seitenleiste wieder einblenden (Strg+B)"/>
<TextBlock x:Name="TxtNoChannel"
Text="Wähle einen Sender aus der Liste"
Foreground="#666" FontSize="18"
HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False"/>
</Grid>
<!-- Bottom Bar: EPG + Controls -->
<Border x:Name="BottomBar" Grid.Row="1" Background="#161616" BorderBrush="#0A0A0A" BorderThickness="0,1,0,0">
<DockPanel>
<!-- Hauptzeile mit Sender + Controls -->
<Grid Margin="16,12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="TxtCurrentChannel"
Foreground="White" FontSize="18" FontWeight="Bold"/>
<TextBlock x:Name="TxtChannelSource"
Foreground="#888" FontSize="11" FontWeight="SemiBold"
VerticalAlignment="Center" Margin="10,0,0,0"/>
</StackPanel>
<TextBlock x:Name="TxtEpgNow"
Foreground="#DDD" FontSize="12" Margin="0,4,0,0"
TextWrapping="Wrap"/>
<TextBlock x:Name="TxtEpgNext"
Foreground="#888" FontSize="11" Margin="0,2,0,0"
TextWrapping="Wrap"/>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Center">
<Button x:Name="BtnFavToggle" Content="☆" FontSize="20" Width="40" Height="40"
Background="Transparent" Foreground="White" BorderThickness="0"
Click="BtnFavToggle_Click" Cursor="Hand" ToolTip="Favorit"/>
<Button x:Name="BtnMute" Content="🔊" FontSize="16" Width="40" Height="40"
Background="Transparent" Foreground="White" BorderThickness="0"
Click="BtnMute_Click" Cursor="Hand" ToolTip="Stumm"/>
<Slider x:Name="SldVolume" Width="100" Minimum="0" Maximum="100" Value="80"
VerticalAlignment="Center" Margin="8,0"
ValueChanged="SldVolume_ValueChanged"/>
<Button x:Name="BtnFullscreen" Content="⛶" FontSize="16" Width="40" Height="40"
Background="Transparent" Foreground="White" BorderThickness="0"
Click="BtnFullscreen_Click" Cursor="Hand" ToolTip="Vollbild (F11)"/>
</StackPanel>
</Grid>
</DockPanel>
</Border>
</Grid>
</Grid>
</Window>