4293ae11a4
Button follows the user journey: 'Connect to YouTube' (not signed in) -> 'Go Live' (connected, idle) -> 'Stop Stream' (live).
237 lines
11 KiB
XML
237 lines
11 KiB
XML
<Window x:Class="ytLive.MainWindow"
|
||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||
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:vm="clr-namespace:ytLive.ViewModels"
|
||
mc:Ignorable="d"
|
||
Title="ytLive" Height="720" Width="1280"
|
||
Background="#1a1a2e"
|
||
WindowStartupLocation="CenterScreen">
|
||
|
||
<Window.DataContext>
|
||
<vm:MainViewModel/>
|
||
</Window.DataContext>
|
||
|
||
<Window.Resources>
|
||
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
|
||
|
||
<!-- Base button style -->
|
||
<Style x:Key="YtButton" TargetType="Button">
|
||
<Setter Property="Background" Value="#e94560"/>
|
||
<Setter Property="Foreground" Value="White"/>
|
||
<Setter Property="FontSize" Value="13"/>
|
||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||
<Setter Property="Padding" Value="16,8"/>
|
||
<Setter Property="BorderThickness" Value="0"/>
|
||
<Setter Property="Cursor" Value="Hand"/>
|
||
<Setter Property="Template">
|
||
<Setter.Value>
|
||
<ControlTemplate TargetType="Button">
|
||
<Border Background="{TemplateBinding Background}"
|
||
CornerRadius="4"
|
||
Padding="{TemplateBinding Padding}">
|
||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
</Border>
|
||
</ControlTemplate>
|
||
</Setter.Value>
|
||
</Setter>
|
||
</Style>
|
||
|
||
<Style x:Key="YtButtonSecondary" TargetType="Button" BasedOn="{StaticResource YtButton}">
|
||
<Setter Property="Background" Value="#16213e"/>
|
||
</Style>
|
||
|
||
<Style x:Key="YtTextBox" TargetType="TextBox">
|
||
<Setter Property="Background" Value="#0f3460"/>
|
||
<Setter Property="Foreground" Value="#e0e0e0"/>
|
||
<Setter Property="BorderThickness" Value="0"/>
|
||
<Setter Property="Padding" Value="8,6"/>
|
||
<Setter Property="FontSize" Value="13"/>
|
||
<Setter Property="CaretBrush" Value="White"/>
|
||
</Style>
|
||
|
||
<Style x:Key="YtLabel" TargetType="TextBlock">
|
||
<Setter Property="Foreground" Value="#a0a0b0"/>
|
||
<Setter Property="FontSize" Value="12"/>
|
||
</Style>
|
||
|
||
<Style x:Key="SectionHeader" TargetType="TextBlock">
|
||
<Setter Property="Foreground" Value="#e0e0e0"/>
|
||
<Setter Property="FontSize" Value="14"/>
|
||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||
<Setter Property="Margin" Value="0,0,0,8"/>
|
||
</Style>
|
||
</Window.Resources>
|
||
|
||
<Grid>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="*"/>
|
||
<RowDefinition Height="Auto"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<!-- ═══ TOP BAR: Stream Controls ═══ -->
|
||
<Border Grid.Row="0" Background="#16213e" Padding="16,10">
|
||
<Grid>
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="Auto"/>
|
||
<ColumnDefinition Width="*"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
<ColumnDefinition Width="Auto"/>
|
||
</Grid.ColumnDefinitions>
|
||
|
||
<!-- Logo / Brand -->
|
||
<TextBlock Grid.Column="0" Text="ytLive"
|
||
Foreground="#e94560" FontSize="22" FontWeight="Bold"
|
||
VerticalAlignment="Center" Margin="0,0,24,0"/>
|
||
|
||
<!-- Stream Title -->
|
||
<TextBox Grid.Column="1" Style="{StaticResource YtTextBox}"
|
||
Text="{Binding StreamTitle, UpdateSourceTrigger=PropertyChanged}"
|
||
Width="400" HorizontalAlignment="Left"
|
||
VerticalAlignment="Center"/>
|
||
|
||
<!-- Stream Status -->
|
||
<Border Grid.Column="2" Background="#0f3460" CornerRadius="4"
|
||
Padding="12,6" Margin="16,0" VerticalAlignment="Center">
|
||
<StackPanel Orientation="Horizontal">
|
||
<Ellipse Width="10" Height="10" Margin="0,0,8,0">
|
||
<Ellipse.Style>
|
||
<Style TargetType="Ellipse">
|
||
<Setter Property="Fill" Value="#555"/>
|
||
<Style.Triggers>
|
||
<DataTrigger Binding="{Binding StreamStatus}" Value="Streaming">
|
||
<Setter Property="Fill" Value="#00ff00"/>
|
||
</DataTrigger>
|
||
<DataTrigger Binding="{Binding StreamStatus}" Value="Connecting">
|
||
<Setter Property="Fill" Value="#ffaa00"/>
|
||
</DataTrigger>
|
||
<DataTrigger Binding="{Binding StreamStatus}" Value="Error">
|
||
<Setter Property="Fill" Value="#ff0000"/>
|
||
</DataTrigger>
|
||
</Style.Triggers>
|
||
</Style>
|
||
</Ellipse.Style>
|
||
</Ellipse>
|
||
<TextBlock Text="{Binding StatusDisplay}" Foreground="White"
|
||
FontSize="13" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
||
</StackPanel>
|
||
</Border>
|
||
|
||
<!-- Primary action: single button, adapts to state -->
|
||
<StackPanel Grid.Column="3" Orientation="Horizontal" VerticalAlignment="Center">
|
||
<Button Content="{Binding PrimaryButtonText}" Style="{StaticResource YtButton}"
|
||
Command="{Binding PrimaryCommand}"/>
|
||
</StackPanel>
|
||
</Grid>
|
||
</Border>
|
||
|
||
<!-- ═══ MIDDLE: Main Content ═══ -->
|
||
<Grid Grid.Row="1" Margin="8">
|
||
<Grid.ColumnDefinitions>
|
||
<ColumnDefinition Width="220"/>
|
||
<ColumnDefinition Width="*"/>
|
||
<ColumnDefinition Width="300"/>
|
||
</Grid.ColumnDefinitions>
|
||
|
||
<!-- LEFT PANEL: Scenes & Sources -->
|
||
<Border Grid.Column="0" Background="#16213e" CornerRadius="6" Padding="12">
|
||
<Grid>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="*"/>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="*"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<!-- Scenes -->
|
||
<TextBlock Grid.Row="0" Text="SCENES" Style="{StaticResource SectionHeader}"/>
|
||
|
||
<ListBox Grid.Row="1" Background="Transparent" BorderThickness="0"
|
||
ItemsSource="{Binding Scenes}"
|
||
SelectedItem="{Binding ActiveScene}"
|
||
Foreground="#e0e0e0" FontSize="13">
|
||
<ListBox.ItemTemplate>
|
||
<DataTemplate>
|
||
<TextBlock Text="{Binding Name}" Padding="4,4"/>
|
||
</DataTemplate>
|
||
</ListBox.ItemTemplate>
|
||
</ListBox>
|
||
|
||
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,8,0,0">
|
||
<Button Content="+" Style="{StaticResource YtButtonSecondary}"
|
||
Command="{Binding AddSceneCommand}" Padding="8,4" Margin="0,0,4,0"/>
|
||
<Button Content="−" Style="{StaticResource YtButtonSecondary}"
|
||
Command="{Binding RemoveSceneCommand}" Padding="8,4"/>
|
||
</StackPanel>
|
||
|
||
<!-- Sources (for active scene) -->
|
||
<TextBlock Grid.Row="3" Text="SOURCES" Style="{StaticResource SectionHeader}" Margin="0,12,0,0"/>
|
||
</Grid>
|
||
</Border>
|
||
|
||
<!-- CENTER: Preview Area -->
|
||
<Border Grid.Column="1" Background="#0a0a1a" CornerRadius="6" Margin="8,0">
|
||
<Grid>
|
||
<TextBlock Text="Preview" Foreground="#333" FontSize="24"
|
||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
<!-- TODO: D3DImage or MediaElement for video preview -->
|
||
</Grid>
|
||
</Border>
|
||
|
||
<!-- RIGHT PANEL: Chat -->
|
||
<Border Grid.Column="2" Background="#16213e" CornerRadius="6" Padding="12">
|
||
<Grid>
|
||
<Grid.RowDefinitions>
|
||
<RowDefinition Height="Auto"/>
|
||
<RowDefinition Height="*"/>
|
||
</Grid.RowDefinitions>
|
||
|
||
<TextBlock Grid.Row="0" Text="LIVE CHAT" Style="{StaticResource SectionHeader}"/>
|
||
|
||
<ListBox Grid.Row="1" Background="Transparent" BorderThickness="0"
|
||
ItemsSource="{Binding ChatMessages}"
|
||
Foreground="#e0e0e0" FontSize="12">
|
||
<ListBox.ItemTemplate>
|
||
<DataTemplate>
|
||
<StackPanel Margin="0,2">
|
||
<TextBlock>
|
||
<Run Text="{Binding AuthorName, Mode=OneWay}" FontWeight="Bold" Foreground="#e94560"/>
|
||
<Run Text=": "/>
|
||
<Run Text="{Binding Message, Mode=OneWay}" Foreground="#e0e0e0"/>
|
||
</TextBlock>
|
||
</StackPanel>
|
||
</DataTemplate>
|
||
</ListBox.ItemTemplate>
|
||
</ListBox>
|
||
</Grid>
|
||
</Border>
|
||
</Grid>
|
||
|
||
<!-- ═══ BOTTOM BAR: Stream Health ═══ -->
|
||
<Border Grid.Row="2" Background="#0f3460" Padding="16,6">
|
||
<StackPanel Orientation="Horizontal">
|
||
<TextBlock Text="Bitrate:" Style="{StaticResource YtLabel}" Margin="0,0,4,0"/>
|
||
<TextBlock Text="{Binding CurrentHealth.CurrentBitrate}" Style="{StaticResource YtLabel}"
|
||
Foreground="White" Margin="0,0,20,0"/>
|
||
|
||
<TextBlock Text="FPS:" Style="{StaticResource YtLabel}" Margin="0,0,4,0"/>
|
||
<TextBlock Text="{Binding CurrentHealth.FPS}" Style="{StaticResource YtLabel}"
|
||
Foreground="White" Margin="0,0,20,0"/>
|
||
|
||
<TextBlock Text="Dropped:" Style="{StaticResource YtLabel}" Margin="0,0,4,0"/>
|
||
<TextBlock Text="{Binding CurrentHealth.DroppedFrames}" Style="{StaticResource YtLabel}"
|
||
Foreground="White" Margin="0,0,20,0"/>
|
||
|
||
<TextBlock Text="Duration:" Style="{StaticResource YtLabel}" Margin="0,0,4,0"/>
|
||
<TextBlock Text="{Binding CurrentHealth.StreamDuration}" Style="{StaticResource YtLabel}"
|
||
Foreground="White"/>
|
||
|
||
<TextBlock Text="{Binding CurrentHealth.HealthMessage}" Style="{StaticResource YtLabel}"
|
||
Foreground="#e94560" Margin="20,0,0,0"/>
|
||
</StackPanel>
|
||
</Border>
|
||
</Grid>
|
||
</Window>
|