Browse Source

Settings window improvements

Equbuxu 1 year ago
parent
commit
636bbbe378

+ 90 - 93
src/PixiEditor.AvaloniaUI/Views/Settings/SettingsWindow.axaml

@@ -9,7 +9,7 @@
     xmlns:sys="clr-namespace:System;assembly=System.Runtime"
     xmlns:converters="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Converters"
     xmlns:vm="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
-    xmlns:ui1="clr-namespace:PixiEditor.AvaloniaUI.Helpers.UI"
+    xmlns:controls="clr-namespace:PixiEditor.UI.Common.Controls;assembly=PixiEditor.UI.Common"
     xmlns:behaviours="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Behaviours"
     xmlns:i="clr-namespace:Avalonia.Xaml.Interactivity;assembly=Avalonia.Xaml.Interactivity"
     xmlns:markupExtensions="clr-namespace:PixiEditor.AvaloniaUI.Helpers.MarkupExtensions"
@@ -61,27 +61,31 @@
             <!--Width="Auto"-->
             <ListBox.ItemTemplate>
                 <DataTemplate>
-                    <TextBlock Margin="10 5 10 5" FontSize="15" Foreground="White" Text="{Binding Path=Name.Value}"/>
+                    <TextBlock Foreground="White" Text="{Binding Path=Name.Value}"/>
                 </DataTemplate>
             </ListBox.ItemTemplate>
         </ListBox>
         <StackPanel Orientation="Vertical">
+            <StackPanel.Styles>
+                <Style Selector=":is(Control).leftOffset">
+                    <Setter Property="Margin" Value="20, 0, 0, 0"/>
+                </Style>
+            </StackPanel.Styles>
             <!--Background="{StaticResource AccentColor}"-->
-            <StackPanel Orientation="Vertical" Margin="15,10" Tag="27">
-                <StackPanel.IsVisible>
+            <controls:FixedSizeStackPanel Orientation="Vertical" ChildSize="32" VerticalChildrenAlignment="Center">
+                <controls:FixedSizeStackPanel.IsVisible>
                     <Binding Path="CurrentPage" Converter="{converters:IsEqualConverter}">
                         <Binding.ConverterParameter><sys:Int32>0</sys:Int32></Binding.ConverterParameter>
                     </Binding>
-                </StackPanel.IsVisible>
-                <Label ui:Translator.Key="LANGUAGE"/>
-                <!-- Style="{StaticResource SettingsHeader}"-->
-                <ComboBox Margin="27 5" Width="200" Height="25" FontSize="12" HorizontalAlignment="Left"
+                </controls:FixedSizeStackPanel.IsVisible>
+                <TextBlock ui:Translator.Key="LANGUAGE" Classes="h5"/>
+                <ComboBox Classes="leftOffset" Width="200" HorizontalAlignment="Left"
                           ItemsSource="{Binding SettingsSubViewModel.General.AvailableLanguages}"
                           SelectedItem="{Binding SettingsSubViewModel.General.SelectedLanguage, Mode=TwoWay}">
                     <ComboBox.ItemTemplate>
                         <DataTemplate>
                             <StackPanel Orientation="Horizontal">
-                                <Image VerticalAlignment="Center" Margin="5 0" Source="{Binding IconFullPath}"/>
+                                <Image VerticalAlignment="Center" Source="{Binding IconFullPath}"/>
                                 <TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
                             </StackPanel>
                         </DataTemplate>
@@ -91,7 +95,7 @@
                             <Setter Property="Template">
                                 <Setter.Value>
                                     <ControlTemplate TargetType="{x:Type ComboBoxItem}">
-                                        <Border Height="25" Margin="0" Padding="5,0" BorderThickness="0,1">
+                                        <Border Height="25" Padding="5,0" BorderThickness="0,1">
                                             <ContentPresenter/>
                                             <Border.Style>
                                                 <Style TargetType="{x:Type Border}">
@@ -115,101 +119,96 @@
                     </ComboBox.ItemContainerStyle>-->
                 </ComboBox>
 
-                <Label ui:Translator.Key="MISC" d:Content="Misc"/> <!--Styles="{StaticResource SettingsHeader}"-->
+                <TextBlock ui:Translator.Key="MISC" Classes="h5"/>
 
-                <CheckBox Margin="27 0"
-                          VerticalAlignment="Center" ui:Translator.Key="SHOW_STARTUP_WINDOW" d:Content="Show startup window"
+                <CheckBox Classes="leftOffset" ui:Translator.Key="SHOW_STARTUP_WINDOW"
                           IsChecked="{Binding SettingsSubViewModel.File.ShowStartupWindow}"/>
 
-                <CheckBox Margin="27 10"
-                          VerticalAlignment="Center" ui:Translator.Key="DISABLE_NEWS_PANEL" d:Content="Hide news in startup window"
+                <CheckBox Classes="leftOffset" ui:Translator.Key="DISABLE_NEWS_PANEL"
                           IsChecked="{Binding SettingsSubViewModel.File.DisableNewsPanel}"/>
 
-                <CheckBox Margin="27 0"
-                          VerticalAlignment="Center" d:Content="Show image preview in taskbar" ui:Translator.Key="SHOW_IMAGE_PREVIEW_TASKBAR"
+                <CheckBox Classes="leftOffset" ui:Translator.Key="SHOW_IMAGE_PREVIEW_TASKBAR"
                           IsChecked="{Binding SettingsSubViewModel.General.ImagePreviewInTaskbar}"/>
 
-                <StackPanel Margin="27 10 27 0" Orientation="Horizontal">
+                <StackPanel Classes="leftOffset" Orientation="Horizontal">
                 <Label 
                     ui:Translator.Key="RECENT_FILE_LENGTH"
                     ui:Translator.TooltipKey="RECENT_FILE_LENGTH_TOOLTIP"/>
-                    <!--Styles="{StaticResource SettingsText}"-->
-                    <input:NumberInput Margin="10 0 0 0" 
-                                              Min="0" FontSize="12" HorizontalAlignment="Left"
-                                   Value="{Binding SettingsSubViewModel.File.MaxOpenedRecently, Mode=TwoWay}" Height="19" Width="40"/>
+                    <input:NumberInput Min="0" FontSize="12" HorizontalAlignment="Left"
+                                   Value="{Binding SettingsSubViewModel.File.MaxOpenedRecently, Mode=TwoWay}" Width="40"/>
                 </StackPanel>
 
-                <Label
+                <TextBlock
+                    Classes="h5"
                     d:Content="Default new file size" 
                     ui:Translator.Key="DEFAULT_NEW_SIZE"/>
-                    <!--Styles="{StaticResource SettingsHeader}"-->
 
-                <StackPanel Orientation="Horizontal" Margin="27 5">
-                    <Label  d:Content="Width" ui:Translator.Key="WIDTH"/>
-                    <!--Styles="{StaticResource SettingsText}"-->
-                    <input:SizeInput Margin="10 0 0 0" 
-                                 Size="{Binding SettingsSubViewModel.File.DefaultNewFileWidth, Mode=TwoWay}" 
-                                 Height="21" MaxSize="9999" HorizontalAlignment="Left"/>
+                <StackPanel Orientation="Horizontal"  Classes="leftOffset">
+                    <Label d:Content="Width" ui:Translator.Key="WIDTH"/>
+                    <input:SizeInput 
+                                 Size="{Binding SettingsSubViewModel.File.DefaultNewFileWidth, Mode=TwoWay}" MaxSize="9999" HorizontalAlignment="Left"/>
                 </StackPanel>
 
-                <StackPanel Orientation="Horizontal" Margin="27 5">
-                    <Label  d:Content="Height" ui:Translator.Key="HEIGHT"/> 
-                    <!--Styles="{StaticResource SettingsText}"-->
-                    <input:SizeInput Margin="7 0 0 0"
-                                 Size="{Binding SettingsSubViewModel.File.DefaultNewFileHeight, Mode=TwoWay}" 
-                                 Height="21" MaxSize="9999" HorizontalAlignment="Left"/>
+                <StackPanel Orientation="Horizontal" Classes="leftOffset">
+                    <Label d:Content="Height" ui:Translator.Key="HEIGHT"/> 
+                    <input:SizeInput
+                                 Size="{Binding SettingsSubViewModel.File.DefaultNewFileHeight, Mode=TwoWay}" MaxSize="9999" HorizontalAlignment="Left"/>
                 </StackPanel>
 
-                <Label  d:Content="Tools" ui:Translator.Key="TOOLS"/>
-                <!--Styles="{StaticResource SettingsHeader}"-->
+                <TextBlock d:Content="Tools" ui:Translator.Key="TOOLS" Classes="h5" />
                 
-                <StackPanel Margin="27 0" Orientation="Horizontal">
-                    <Label Margin="0,0,7,0"
-                           ui:Translator.Key="RIGHT_CLICK_MODE"/>
-                    <!--Styles="{StaticResource SettingsText}"-->
+                <StackPanel Orientation="Horizontal" Classes="leftOffset">
+                    <Label Target="rightClickModeComboBox" ui:Translator.Key="RIGHT_CLICK_MODE" VerticalAlignment="Center"/>
                     <ComboBox SelectedItem="{Binding RightClickMode, Source={vm:MainVM ToolsSVM}, Mode=TwoWay}"
+                              Name="rightClickModeComboBox"
                               ItemsSource="{markupExtensions:Enum preferences:RightClickMode}"
-                              Width="160"/>
+                              Width="160"
+                              VerticalAlignment="Center"/>
                     <!--Styles="{StaticResource TranslatedEnum}"-->
                 </StackPanel>
 
-                <CheckBox VerticalAlignment="Center" Margin="27 5"
-                    IsChecked="{Binding SettingsSubViewModel.Tools.EnableSharedToolbar}" d:Content="Enable shared toolbar" ui:Translator.Key="ENABLE_SHARED_TOOLBAR"/>
+                <CheckBox Classes="leftOffset"
+                          IsChecked="{Binding SettingsSubViewModel.Tools.EnableSharedToolbar}"
+                          ui:Translator.Key="ENABLE_SHARED_TOOLBAR"/>
 
-                <Label  d:Content="Automatic updates" ui:Translator.Key="AUTOMATIC_UPDATES"/>
-                <!--Styles="{StaticResource SettingsHeader}"-->
+                <TextBlock ui:Translator.Key="AUTOMATIC_UPDATES" Classes="h5"/>
 
-                <CheckBox Margin="27 5" VerticalAlignment="Center" IsEnabled="{Binding Path=ShowUpdateTab}"
-                    IsChecked="{Binding SettingsSubViewModel.Update.CheckUpdatesOnStartup}" ui:Translator.Key="CHECK_FOR_UPDATES" d:Content="Check updates on startup"/>
+                <CheckBox 
+                    VerticalAlignment="Center" 
+                    IsEnabled="{Binding Path=ShowUpdateTab}"
+                    IsChecked="{Binding SettingsSubViewModel.Update.CheckUpdatesOnStartup}" 
+                    ui:Translator.Key="CHECK_FOR_UPDATES"
+                    Classes="leftOffset"/>
 
-                <StackPanel Orientation="Horizontal" Margin="27 5">
-                    <Label Grid.Row="11" Grid.Column="1" d:Content="Update stream" ui:Translator.Key="UPDATE_STREAM"/>
-                    <!--Styles="{StaticResource SettingsText}"-->
-                    <StackPanel Margin="5 0" Orientation="Horizontal" VerticalAlignment="Center"
-                            Height="21.96" HorizontalAlignment="Left">
-                <ComboBox Width="110" IsEnabled="{Binding Path=ShowUpdateTab}"
-                    ItemsSource="{Binding SettingsSubViewModel.Update.UpdateChannels}"
-                    SelectedValue="{Binding SettingsSubViewModel.Update.UpdateChannelName}"/>
-                <Image Cursor="Help" Margin="10 0 0 0" Source="/Images/Commands/PixiEditor/Links/OpenDocumentation.png"
-                       IsVisible="{Binding !ShowUpdateTab}"
-                       ui:Translator.TooltipKey="UPDATE_CHANNEL_HELP_TOOLTIP"/>
-                       <!-- ToolTipService.InitialShowDelay="0"-->
-                </StackPanel>
+                <StackPanel Orientation="Horizontal" Classes="leftOffset">
+                    <Label Target="updateStreamComboBox" ui:Translator.Key="UPDATE_STREAM" VerticalAlignment="Center"/>
+                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
+                        <ComboBox Width="110"
+                                  Name="updateStreamComboBox"
+                                  VerticalAlignment="Center"
+                                  IsEnabled="{Binding Path=ShowUpdateTab}"
+                                  ItemsSource="{Binding SettingsSubViewModel.Update.UpdateChannels}"
+                                  SelectedValue="{Binding SettingsSubViewModel.Update.UpdateChannelName}"/>
+                        <Image Cursor="Help" Source="/Images/Commands/PixiEditor/Links/OpenDocumentation.png"
+                               VerticalAlignment="Center"
+                               IsVisible="{Binding !ShowUpdateTab}"
+                               ui:Translator.TooltipKey="UPDATE_CHANNEL_HELP_TOOLTIP"/>
+                               <!-- ToolTipService.InitialShowDelay="0"-->
+                    </StackPanel>
                 </StackPanel>
 
-                <Label d:Content="Debug" ui:Translator.Key="DEBUG"/>
-                <!--Styles="{StaticResource SettingsHeader}"-->
-                <CheckBox Margin="27 5" VerticalAlignment="Center"
+                <TextBlock ui:Translator.Key="DEBUG" Classes="h5"/>
+                <CheckBox Classes="leftOffset"
                     IsChecked="{Binding SettingsSubViewModel.General.IsDebugModeEnabled}" ui:Translator.Key="ENABLE_DEBUG_MODE" d:Content="Enable Debug Mode"/>
-                <!--<Label Margin="0 5" Styles="{StaticResource SettingsText}" VerticalAlignment="Center">
+                <!--<Label Classes="{StaticResource SettingsText}" VerticalAlignment="Center">
                     <ui1:Hyperlink Command="{cmds:Command PixiEditor.Debug.OpenCrashReportsDirectory}" Style="{StaticResource SettingsLink}">
                         <Run ui:Translator.Key="OPEN_CRASH_REPORTS_DIR" d:Text="Open crash reports directory"/>
                         <Run Text="" FontFamily="{StaticResource Feather}"/>
                     </ui1:Hyperlink>
                 </Label>-->
-            </StackPanel>
+            </controls:FixedSizeStackPanel>
 
-            <StackPanel Margin="15,10">
+            <StackPanel>
                 <StackPanel.IsVisible>
                     <Binding Path="CurrentPage" Converter="{converters:IsEqualConverter}">
                         <Binding.ConverterParameter>
@@ -217,32 +216,31 @@
                         </Binding.ConverterParameter>
                     </Binding>
                 </StackPanel.IsVisible>
-                <StackPanel Orientation="Vertical">
-                    <Label d:Content="Rich Presence" ui:Translator.Key="DISCORD_RICH_PRESENCE"/>
-                    <!--Styles="{StaticResource SettingsHeader}"-->
+            
+                <controls:FixedSizeStackPanel ChildSize="32" Orientation="Vertical" VerticalChildrenAlignment="Center">
+                    <TextBlock ui:Translator.Key="DISCORD_RICH_PRESENCE" Classes="h5"/>
 
-                    <CheckBox Margin="27 5" VerticalAlignment="Center"
-                              IsChecked="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" d:Content="Enabled" ui:Translator.Key="ENABLED"/>
-                    <CheckBox Margin="27 5" VerticalAlignment="Center"
-                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
-                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentName}" d:Content="Show image name" ui:Translator.Key="SHOW_IMAGE_NAME"/>
-                    <CheckBox Margin="27 5" VerticalAlignment="Center"
-                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" d:Content="Show image size" ui:Translator.Key="SHOW_IMAGE_SIZE"
-                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentSize}"/>
-                    <CheckBox Margin="27 5" VerticalAlignment="Center"
-                              IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" ui:Translator.Key="SHOW_LAYER_COUNT" d:Content="Show layer count"
-                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowLayerCount}"/>
-                </StackPanel>
-                <!--<usercontrols:DiscordRPPreview 
-                    Margin="15"
-                    Width="280"
-                    State="{Binding SettingsSubViewModel.Discord.StatePreview}" 
-                    Detail="{Binding SettingsSubViewModel.Discord.DetailPreview}" 
-                    IsPlaying="{Binding SettingsSubViewModel.Discord.EnableRichPresence}"/>-->
+                    <CheckBox IsChecked="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              ui:Translator.Key="ENABLED"/>
+                    <CheckBox IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentName}" 
+                              ui:Translator.Key="SHOW_IMAGE_NAME"/>
+                    <CheckBox IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowDocumentSize}"
+                              ui:Translator.Key="SHOW_IMAGE_SIZE"/>
+                    <CheckBox IsEnabled="{Binding SettingsSubViewModel.Discord.EnableRichPresence}" 
+                              IsChecked="{Binding SettingsSubViewModel.Discord.ShowLayerCount}"
+                              ui:Translator.Key="SHOW_LAYER_COUNT" d:Content="Show layer count"/>
+
+                    <!--<usercontrols:DiscordRPPreview 
+                        Width="280"
+                        State="{Binding SettingsSubViewModel.Discord.StatePreview}" 
+                        Detail="{Binding SettingsSubViewModel.Discord.DetailPreview}" 
+                        IsPlaying="{Binding SettingsSubViewModel.Discord.EnableRichPresence}"/>-->
+                </controls:FixedSizeStackPanel>
             </StackPanel>
 
-            <Grid Height="{Binding ElementName=window, Path=Height, Converter={converters:SubtractConverter}, ConverterParameter=50}"
-                  Margin="10,10,10,50">
+            <Grid Height="{Binding ElementName=window, Path=Height, Converter={converters:SubtractConverter}, ConverterParameter=50}">
                 <Grid.IsVisible>
                     <Binding Path="CurrentPage" Converter="{converters:IsEqualConverter}">
                         <Binding.ConverterParameter>
@@ -261,7 +259,6 @@
                             <Setter Property="HorizontalAlignment" Value="Stretch"/>
                             <Setter Property="MinWidth" Value="115"/>
                             <Setter Property="Height" Value="Auto"/>
-                            <Setter Property="Margin" Value="5,0"/>
                             <Setter Property="FontSize" Value="12"/>
                             <Setter Property="Padding" Value="5"/>
                         </Style>
@@ -275,7 +272,7 @@
                     <Button Command="{cmds:Command PixiEditor.Shortcuts.Reset}"
                             d:Content="Reset all" ui:Translator.Key="RESET_ALL"/>
                 </StackPanel>
-                <TextBox Grid.Row="1" Margin="0,10"
+                <TextBox Grid.Row="1"
                          Text="{Binding SearchTerm, Mode=TwoWay}">
                         <!--Styles="{StaticResource DarkTextBoxStyle}"-->
                     <i:Interaction.Behaviors>

+ 1 - 0
src/PixiEditor.UI.Common/Accents/Base.axaml

@@ -92,6 +92,7 @@
             <system:Double x:Key="Header2">26</system:Double>
             <system:Double x:Key="Header3">22</system:Double>
             <system:Double x:Key="Header4">20</system:Double>
+            <system:Double x:Key="Header5">16</system:Double>
         </ResourceDictionary>
     </ResourceDictionary.ThemeDictionaries>
 

+ 147 - 0
src/PixiEditor.UI.Common/Controls/FixedSizeStackPanel.cs

@@ -0,0 +1,147 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Layout;
+using OrientationEnum = Avalonia.Layout.Orientation;
+
+namespace PixiEditor.UI.Common.Controls;
+
+public class FixedSizeStackPanel : Panel
+{
+    public static readonly StyledProperty<double> ChildSizeProperty = 
+        AvaloniaProperty.Register<FixedSizeStackPanel, double>(nameof(ChildSize), 10d);
+    public double ChildSize
+    {
+        get => GetValue(ChildSizeProperty);
+        set => SetValue(ChildSizeProperty, value);
+    }
+    
+    public static readonly StyledProperty<double> SpacingProperty = 
+        AvaloniaProperty.Register<FixedSizeStackPanel, double>(nameof(Spacing), 0d);
+    public double Spacing
+    {
+        get => GetValue(SpacingProperty);
+        set => SetValue(SpacingProperty, value);
+    }
+
+    public static readonly StyledProperty<OrientationEnum> OrientationProperty = 
+        AvaloniaProperty.Register<FixedSizeStackPanel, OrientationEnum>(nameof(Orientation), OrientationEnum.Vertical);
+    public OrientationEnum Orientation
+    {
+        get => GetValue(OrientationProperty);
+        set => SetValue(OrientationProperty, value);
+    }
+    
+    public static readonly StyledProperty<HorizontalAlignment> HorizontalChildrenAlignmentProperty = 
+        AvaloniaProperty.Register<FixedSizeStackPanel, HorizontalAlignment>(nameof(Orientation), HorizontalAlignment.Left);
+    public HorizontalAlignment HorizontalChildrenAlignment
+    {
+        get => GetValue(HorizontalChildrenAlignmentProperty);
+        set => SetValue(HorizontalChildrenAlignmentProperty, value);
+    }
+    
+    
+    public static readonly StyledProperty<VerticalAlignment> VerticalChildrenAlignmentProperty = 
+        AvaloniaProperty.Register<FixedSizeStackPanel, VerticalAlignment>(nameof(Orientation), VerticalAlignment.Center);
+    public VerticalAlignment VerticalChildrenAlignment
+    {
+        get => GetValue(VerticalChildrenAlignmentProperty);
+        set => SetValue(VerticalChildrenAlignmentProperty, value);
+    }
+    
+    protected override Size MeasureOverride(Size availableSize)
+    {
+        Size childSize = Orientation switch
+        {
+            OrientationEnum.Horizontal => new Size(
+                ChildSize, 
+                FirstValid(availableSize.Height, Height, 0)),
+            OrientationEnum.Vertical => new Size(
+                FirstValid(availableSize.Width, Width, 0), 
+                ChildSize),
+            _ => throw new ArgumentOutOfRangeException()
+        };
+        
+        foreach (var child in Children)
+        {
+            child.Measure(childSize);
+        }
+        
+        double totalSize = Children.Count * ChildSize + Math.Max(Children.Count - 1, 0) * Spacing;
+        return Orientation switch
+        {
+            OrientationEnum.Horizontal => new Size(
+                Math.Min(totalSize, availableSize.Width), 
+                FirstValid(availableSize.Height, Height, 0)),
+            OrientationEnum.Vertical => new Size(
+                FirstValid(availableSize.Width, Width, 0), 
+                Math.Min(totalSize, availableSize.Height)),
+            _ => throw new ArgumentOutOfRangeException()
+        };
+    }
+
+    private double FirstValid(double v1, double v2, double v3) => FirstValid(FirstValid(v1, v2), v3);
+    
+    private double FirstValid(double v1, double v2)
+    {
+        if (double.IsNaN(v1) || double.IsInfinity(v1))
+            return v2;
+        return v1;
+    }
+
+    protected override Size ArrangeOverride(Size finalSize)
+    {
+        for (var i = 0; i < Children.Count; i++)
+        {
+            Control child = Children[i];
+            double offset = (ChildSize + Spacing) * i;
+
+            switch (Orientation)
+            {
+                case Orientation.Horizontal:
+                    child.Arrange(
+                        AlignChild(
+                            new Rect(new Point(offset, 0), new Size(ChildSize, finalSize.Height)),
+                            child.DesiredSize,
+                            HorizontalChildrenAlignment,
+                            VerticalChildrenAlignment)
+                        );
+                    break;
+                case Orientation.Vertical:
+                    child.Arrange(
+                        AlignChild(
+                                new Rect(new Point(0, offset), new Size(finalSize.Width, ChildSize)),
+                                child.DesiredSize,
+                                HorizontalChildrenAlignment,
+                                VerticalChildrenAlignment)
+                            );
+                    break;
+            }
+        }
+
+        return finalSize;
+    }
+
+    private Rect AlignChild(Rect area, Size childSize, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment)
+    {
+        double x = area.X + horizontalAlignment switch
+        {
+            HorizontalAlignment.Stretch or HorizontalAlignment.Left => 0,
+            HorizontalAlignment.Center => (area.Size.Width - childSize.Width) / 2,
+            HorizontalAlignment.Right => area.Size.Width - childSize.Width,
+            _ => throw new ArgumentOutOfRangeException(nameof(horizontalAlignment), horizontalAlignment, null)
+        };
+        
+        double y = area.Y + verticalAlignment switch
+        {
+            VerticalAlignment.Stretch or VerticalAlignment.Top => 0,
+            VerticalAlignment.Center => (area.Size.Height - childSize.Height) / 2,
+            VerticalAlignment.Bottom => area.Size.Height - childSize.Height,
+            _ => throw new ArgumentOutOfRangeException(nameof(verticalAlignment), verticalAlignment, null)
+        };
+
+        double width = horizontalAlignment == HorizontalAlignment.Stretch ? area.Width : childSize.Width;
+        double height = horizontalAlignment == HorizontalAlignment.Stretch ? area.Height : childSize.Height;
+
+        return new Rect(x, y, width, height);
+    }
+}

+ 4 - 0
src/PixiEditor.UI.Common/Styles/TextStyles.axaml

@@ -21,4 +21,8 @@
     <Style Selector="TextBlock.h4">
         <Setter Property="FontSize" Value="{DynamicResource Header4}"/>
     </Style>
+    
+    <Style Selector="TextBlock.h5">
+        <Setter Property="FontSize" Value="{DynamicResource Header5}"/>
+    </Style>
 </Styles>