EPG-Overlay aus VideoView raus - funktioniert jetzt auch ueber WebView und TV
This commit is contained in:
parent
d2eeffd200
commit
15e7182c22
2 changed files with 43 additions and 121 deletions
143
MainWindow.xaml
143
MainWindow.xaml
|
|
@ -227,133 +227,74 @@
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- VideoView + WebView2: beide im gleichen Grid-Cell, Visibility steuert wer sichtbar ist -->
|
<!-- VideoView + WebView2 + EPG-Overlay: alle im gleichen Grid-Cell -->
|
||||||
<Grid Grid.Row="0">
|
<Grid Grid.Row="0">
|
||||||
|
|
||||||
<!-- VLC-Player fuer TV/Radio -->
|
<!-- VLC-Player fuer TV/Radio -->
|
||||||
<vlc:VideoView x:Name="VideoView" Background="Black">
|
<vlc:VideoView x:Name="VideoView" Background="Black">
|
||||||
<Border x:Name="VideoOverlay"
|
<Border x:Name="VideoOverlay"
|
||||||
Background="#01000000"
|
Background="#01000000"
|
||||||
PreviewMouseLeftButtonDown="VideoClickCatcher_DoubleClick">
|
PreviewMouseLeftButtonDown="VideoClickCatcher_DoubleClick">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|
||||||
<!-- Radio-Cover bei Audio-Streams — INNERHALB VideoView damit es die native HWND überdeckt -->
|
<!-- Radio-Cover bei Audio-Streams — INNERHALB VideoView damit es die native HWND überdeckt -->
|
||||||
<Border x:Name="RadioCover" Visibility="Collapsed"
|
<Border x:Name="RadioCover" Visibility="Collapsed" Background="#1A1A1A">
|
||||||
Background="#1A1A1A">
|
|
||||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
<Image x:Name="RadioLogo" Width="200" Height="200" Stretch="Uniform"
|
<Image x:Name="RadioLogo" Width="200" Height="200" Stretch="Uniform"
|
||||||
RenderOptions.BitmapScalingMode="HighQuality"/>
|
RenderOptions.BitmapScalingMode="HighQuality"/>
|
||||||
<TextBlock x:Name="RadioFallbackIcon" Text="📻"
|
<TextBlock x:Name="RadioFallbackIcon" Text="📻"
|
||||||
FontSize="120" Foreground="#444"
|
FontSize="120" Foreground="#444"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center" Visibility="Collapsed"/>
|
||||||
Visibility="Collapsed"/>
|
|
||||||
<TextBlock x:Name="TxtRadioName"
|
<TextBlock x:Name="TxtRadioName"
|
||||||
FontSize="24" FontWeight="Bold" Foreground="White"
|
FontSize="24" FontWeight="Bold" Foreground="White"
|
||||||
HorizontalAlignment="Center" Margin="0,24,0,0"/>
|
HorizontalAlignment="Center" Margin="0,24,0,0"/>
|
||||||
<TextBlock x:Name="TxtRadioText"
|
<TextBlock x:Name="TxtRadioText"
|
||||||
FontSize="16" Foreground="#0078D4" FontWeight="SemiBold"
|
FontSize="16" Foreground="#0078D4" FontWeight="SemiBold"
|
||||||
HorizontalAlignment="Center" Margin="24,12,24,0"
|
HorizontalAlignment="Center" Margin="24,12,24,0"
|
||||||
TextWrapping="Wrap" TextAlignment="Center"
|
TextWrapping="Wrap" TextAlignment="Center" MaxWidth="600"/>
|
||||||
MaxWidth="600"/>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</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>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
</vlc:VideoView>
|
</vlc:VideoView>
|
||||||
|
|
||||||
<!-- WebView2 fuer Web-Sender (YouTube, Netflix, Mediatheken etc.) -->
|
<!-- WebView2 fuer Web-Sender -->
|
||||||
<!-- Persistentes User-Data-Profil: Login bleibt erhalten -->
|
<wv2:WebView2 x:Name="WebView" Visibility="Collapsed" Panel.ZIndex="5"/>
|
||||||
<!-- Liegt VOR dem VideoView im Z-Order, damit Klicks nicht vom VideoOverlay gefangen werden -->
|
|
||||||
<wv2:WebView2 x:Name="WebView"
|
<!-- EPG-Overlay: AUSSERHALB VideoView und WebView damit es immer sichtbar ist -->
|
||||||
Visibility="Collapsed"
|
<!-- Panel.ZIndex="10" stellt sicher dass es ueber VLC-HWND und WebView-HWND liegt -->
|
||||||
Panel.ZIndex="5"/>
|
<Border x:Name="EpgOverlay" Visibility="Collapsed"
|
||||||
|
Background="#D8000000"
|
||||||
|
Panel.ZIndex="10">
|
||||||
|
<DockPanel>
|
||||||
|
<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>
|
||||||
|
<TextBlock x:Name="TxtEpgOverlayStatus" DockPanel.Dock="Bottom"
|
||||||
|
Foreground="#888" FontSize="11" Padding="24,8" Background="#0A0A0A"/>
|
||||||
|
<ScrollViewer x:Name="EpgScrollViewer"
|
||||||
|
HorizontalScrollBarVisibility="Auto"
|
||||||
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
Background="#0A0A0A">
|
||||||
|
<Canvas x:Name="EpgCanvas"/>
|
||||||
|
</ScrollViewer>
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
<!-- Kein Burger-Button mehr - Strg+B zum Einblenden der Seitenleiste -->
|
|
||||||
<TextBlock x:Name="TxtNoChannel"
|
<TextBlock x:Name="TxtNoChannel"
|
||||||
Text="Wähle einen Sender aus der Liste"
|
Text="Wähle einen Sender aus der Liste"
|
||||||
Foreground="#666" FontSize="18"
|
Foreground="#666" FontSize="18"
|
||||||
|
|
|
||||||
|
|
@ -761,27 +761,16 @@ public partial class MainWindow : Window
|
||||||
|
|
||||||
private async void BtnEpgGrid_Click(object sender, RoutedEventArgs e)
|
private async void BtnEpgGrid_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// WebView pausieren damit EPG-Overlay sichtbar ist
|
// WebView pausieren (EPG-Overlay liegt jetzt ausserhalb der HWNDs, kein Visibility-Wechsel noetig)
|
||||||
if (_currentChannel?.Kind == ChannelKind.Web && _webViewReady)
|
if (_currentChannel?.Kind == ChannelKind.Web && _webViewReady)
|
||||||
{
|
|
||||||
await WebView.CoreWebView2.ExecuteScriptAsync(
|
await WebView.CoreWebView2.ExecuteScriptAsync(
|
||||||
"document.querySelectorAll('video,audio').forEach(m => m.pause())");
|
"document.querySelectorAll('video,audio').forEach(m => m.pause())");
|
||||||
WebView.Visibility = Visibility.Collapsed;
|
|
||||||
VideoView.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
await ShowEpgOverlayAsync();
|
await ShowEpgOverlayAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BtnCloseEpg_Click(object sender, RoutedEventArgs e)
|
private void BtnCloseEpg_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
HideEpgOverlay();
|
HideEpgOverlay();
|
||||||
// Wenn Web-Sender aktiv: WebView wieder anzeigen
|
|
||||||
if (_currentChannel?.Kind == ChannelKind.Web)
|
|
||||||
{
|
|
||||||
VideoView.Visibility = Visibility.Collapsed;
|
|
||||||
VideoOverlay.Visibility = Visibility.Collapsed;
|
|
||||||
WebView.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ────────── EPG-Overlay (Joyn-Style) ──────────
|
// ────────── EPG-Overlay (Joyn-Style) ──────────
|
||||||
|
|
@ -1124,15 +1113,7 @@ public partial class MainWindow : Window
|
||||||
case Key.F11: ToggleFullscreen(); e.Handled = true; break;
|
case Key.F11: ToggleFullscreen(); e.Handled = true; break;
|
||||||
case Key.Escape:
|
case Key.Escape:
|
||||||
if (EpgOverlay.Visibility == Visibility.Visible)
|
if (EpgOverlay.Visibility == Visibility.Visible)
|
||||||
{
|
|
||||||
HideEpgOverlay();
|
HideEpgOverlay();
|
||||||
if (_currentChannel?.Kind == ChannelKind.Web)
|
|
||||||
{
|
|
||||||
VideoView.Visibility = Visibility.Collapsed;
|
|
||||||
VideoOverlay.Visibility = Visibility.Collapsed;
|
|
||||||
WebView.Visibility = Visibility.Visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (_isFullscreen) ToggleFullscreen();
|
else if (_isFullscreen) ToggleFullscreen();
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue