fix(text): show selected formatting and style controls

Use category-filtered font and selected-item dropdowns, separate horizontal and vertical alignment, and reuse the border-color palette templates for text color. Persist vertical alignment additively. Follow the established static text-source pattern: https://obsproject.com/kb/text-sources
This commit is contained in:
2026-11-04 17:05:06 -08:00
parent 5c4acf141b
commit 5f7bcc2425
15 changed files with 417 additions and 52 deletions
+51 -42
View File
@@ -2,8 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:ytLive.Helpers"
xmlns:models="clr-namespace:ytLive.Models"
xmlns:media="clr-namespace:System.Windows.Media;assembly=PresentationCore">
xmlns:models="clr-namespace:ytLive.Models">
<UserControl.Resources>
<!-- TASK 63: the border-colour drop-down is the app's own YtComboBox, so the
colour entries are drawn by TEMPLATES, in the theme's colours and with the
@@ -321,47 +320,46 @@
<StackPanel Visibility="{Binding SelectedElement.IsTextOverlay, Converter={StaticResource BoolToVis}}" Margin="0,0,0,8">
<TextBlock Text="Text" Style="{StaticResource PropertyHeader}"/>
<TextBlock Text="Static text — it will not animate automatically. Move and resize it in the preview."
Style="{StaticResource PropertyHint}" Margin="0,0,0,6" TextWrapping="Wrap"/>
Style="{StaticResource PropertyHint}" Margin="10,0,0,6" TextWrapping="Wrap"/>
<TextBox x:Name="TextLayerEditor" Text="{Binding SelectedElement.TextContent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Style="{StaticResource YtTextBoxCompact}" AcceptsReturn="True" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" MinHeight="72" MaxHeight="120"
VerticalScrollBarVisibility="Auto" MinHeight="72" MaxHeight="120" Margin="10,0,0,8"
AutomationProperties.Name="Text layer content"/>
<TextBlock Text="Font" Style="{StaticResource PropertyHeader}"/>
<ComboBox IsEditable="True" ItemsSource="{x:Static media:Fonts.SystemFontFamilies}"
DisplayMemberPath="Source"
Text="{Binding SelectedElement.TextFontFamily, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
Style="{StaticResource YtComboBox}" Height="26" Margin="0,0,0,6"
AutomationProperties.Name="Text layer font"/>
<DockPanel Margin="0,0,0,6" LastChildFill="False">
<TextBlock DockPanel.Dock="Left" Text="Size" Style="{StaticResource PropertyFieldLabel}"
Width="42" VerticalAlignment="Center"/>
<ComboBox IsEditable="True"
Text="{Binding SelectedElement.TextFontSize, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
Style="{StaticResource YtComboBox}" Height="26" Width="76"
AutomationProperties.Name="Text layer size">
<ComboBoxItem Content="12"/><ComboBoxItem Content="16"/>
<ComboBoxItem Content="20"/><ComboBoxItem Content="24"/>
<ComboBoxItem Content="32"/><ComboBoxItem Content="36"/>
<ComboBoxItem Content="48"/><ComboBoxItem Content="60"/>
<ComboBoxItem Content="72"/><ComboBoxItem Content="96"/>
<ComboBoxItem Content="120"/><ComboBoxItem Content="144"/>
<ComboBoxItem Content="180"/><ComboBoxItem Content="240"/>
<ComboBoxItem Content="300"/>
</ComboBox>
</DockPanel>
<DockPanel Margin="0,0,0,6" LastChildFill="False">
<TextBlock DockPanel.Dock="Left" Text="Color" Style="{StaticResource PropertyFieldLabel}"
Width="42" VerticalAlignment="Center"/>
<TextBlock Text="Typography" Style="{StaticResource PropertyHeader}"/>
<StackPanel Margin="10,0,0,6">
<TextBlock Text="Font Type" Style="{StaticResource PropertyFieldLabel}" Margin="0,0,0,3"/>
<ComboBox x:Name="TextLayerFontTypePicker"
ItemsSource="{Binding TextFontTypeOptions}"
SelectedItem="{Binding SelectedTextFontType, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="30" Margin="0,0,0,6"/>
<TextBlock Text="Font" Style="{StaticResource PropertyFieldLabel}" Margin="0,0,0,3"/>
<ComboBox x:Name="TextLayerFontPicker"
ItemsSource="{Binding TextFontFamilies}"
SelectedItem="{Binding SelectedTextFontFamily, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="30" Margin="0,0,0,6"
AutomationProperties.Name="Text layer font"/>
<TextBlock Text="Size" Style="{StaticResource PropertyFieldLabel}" Margin="0,0,0,3"/>
<ComboBox x:Name="TextLayerSizePicker"
ItemsSource="{Binding TextFontSizeOptions}"
SelectedItem="{Binding SelectedElement.TextFontSize, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="30" Width="92"
HorizontalAlignment="Left" AutomationProperties.Name="Text layer size"/>
</StackPanel>
<TextBlock Text="Color" Style="{StaticResource PropertyHeader}"/>
<DockPanel Margin="10,0,0,6" LastChildFill="False">
<TextBox x:Name="TextLayerColorEditor"
Text="{Binding SelectedElement.TextColor, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
Style="{StaticResource YtTextBoxCompact}" MaxLength="9" Width="82"
ToolTip="#RRGGBB or #AARRGGBB" AutomationProperties.Name="Text layer color"/>
<Border Width="18" Height="18" Margin="8,0,0,0" CornerRadius="2"
Background="{Binding SelectedElement.TextColor, Converter={StaticResource HexToBrush}}"
BorderBrush="{StaticResource Brush.Outline}" BorderThickness="1"
VerticalAlignment="Center"/>
<ComboBox x:Name="TextLayerColorPicker"
ItemsSource="{Binding SelectedElement.TextColorOptions}"
SelectedItem="{Binding SelectedElement.TextColorEntry, Mode=TwoWay}"
ItemTemplateSelector="{StaticResource BorderColorTemplates}"
Style="{StaticResource YtComboBox}" MinWidth="112" Margin="8,0,0,0"
ToolTip="Choose a text color" AutomationProperties.Name="Text layer color palette"/>
</DockPanel>
<WrapPanel Margin="0,0,0,4">
<TextBlock Text="Emphasis" Style="{StaticResource PropertyHeader}"/>
<WrapPanel Margin="10,0,0,4">
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Bold" Margin="0,0,8,4"
IsChecked="{Binding SelectedElement.TextBold, Mode=TwoWay}"/>
<CheckBox Style="{StaticResource PropertyPillCheck}" Content="Italic" Margin="0,0,8,4"
@@ -370,13 +368,24 @@
IsChecked="{Binding SelectedElement.TextUnderline, Mode=TwoWay}"/>
</WrapPanel>
<TextBlock Text="Alignment" Style="{StaticResource PropertyHeader}"/>
<ComboBox SelectedValuePath="Tag"
SelectedValue="{Binding SelectedElement.TextAlignment, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="26">
<ComboBoxItem Content="Left" Tag="{x:Static models:TextLayerAlignment.Left}"/>
<ComboBoxItem Content="Center" Tag="{x:Static models:TextLayerAlignment.Center}"/>
<ComboBoxItem Content="Right" Tag="{x:Static models:TextLayerAlignment.Right}"/>
</ComboBox>
<DockPanel Margin="10,0,0,4">
<TextBlock DockPanel.Dock="Left" Text="Horizontal" Style="{StaticResource PropertyFieldLabel}"
Width="72" VerticalAlignment="Center"/>
<ComboBox x:Name="TextLayerHorizontalAlignmentPicker"
ItemsSource="{Binding TextHorizontalAlignmentOptions}"
SelectedItem="{Binding SelectedElement.TextAlignment, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="30"
AutomationProperties.Name="Horizontal text alignment"/>
</DockPanel>
<DockPanel Margin="10,0,0,0">
<TextBlock DockPanel.Dock="Left" Text="Vertical" Style="{StaticResource PropertyFieldLabel}"
Width="72" VerticalAlignment="Center"/>
<ComboBox x:Name="TextLayerVerticalAlignmentPicker"
ItemsSource="{Binding TextVerticalAlignmentOptions}"
SelectedItem="{Binding SelectedElement.TextVerticalAlignment, Mode=TwoWay}"
Style="{StaticResource YtComboBox}" Height="30"
AutomationProperties.Name="Vertical text alignment"/>
</DockPanel>
</StackPanel>
<!-- Opacity + mirror/shape (draggable elements: image, webcam) -->