Browse Source

Added TogglableMenuItem

Krzysztof Krysiński 1 year ago
parent
commit
c422498388

+ 11 - 13
src/PixiEditor.AvaloniaUI/Views/Main/MainTitleBar.axaml

@@ -7,6 +7,7 @@
              xmlns:dataHolders="clr-namespace:PixiEditor.AvaloniaUI.Models.UserData"
              xmlns:viewModels="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
              xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
+             xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input;assembly=PixiEditor.UI.Common"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
              x:Class="PixiEditor.AvaloniaUI.Views.Main.MainTitleBar">
     <Grid>
@@ -159,27 +160,24 @@
                     ui:Translator.Key="CENTER_CONTENT"
                     xaml:Menu.Command="PixiEditor.Document.CenterContent" />
                 <Separator />
-                <!--TODO: Create ToggleableMenuItem
-                <MenuItem
-                    IsCheckable="True"
-                    IsEnabled="{Binding DocumentManagerSubViewModel.ActiveDocument, Source={vm:MainVM}, Converter={converters:NotNullToBoolConverter}}"
-                    IsChecked="{Binding DocumentManagerSubViewModel.ActiveDocument.HorizontalSymmetryAxisEnabledBindable}"
+                <input:ToggleableMenuItem
+                    IsEnabled="{Binding !!DocumentManagerSubViewModel.ActiveDocument, Source={viewModels:MainVM}}"
+                    IsChecked="{Binding DocumentManagerSubViewModel.ActiveDocument.HorizontalSymmetryAxisEnabledBindable, Source={viewModels:MainVM}, Mode=TwoWay}"
                     ui:Translator.Key="HORIZONTAL_LINE_SYMMETRY">
                     <MenuItem.Icon>
-                        <Image Source="../Images/SymmetryHorizontal.png"
+                        <Image Source="/Images/SymmetryHorizontal.png"
                                Width="{x:Static xaml:Menu.IconDimensions}" Height="{x:Static xaml:Menu.IconDimensions}"/>
                     </MenuItem.Icon>
-                </MenuItem>
-                <MenuItem
-                    IsCheckable="True"
-                    IsEnabled="{Binding DocumentManagerSubViewModel.ActiveDocument, Source={vm:MainVM}, Converter={converters:NotNullToBoolConverter}}"
-                    IsChecked="{Binding DocumentManagerSubViewModel.ActiveDocument.VerticalSymmetryAxisEnabledBindable}"
+                </input:ToggleableMenuItem>
+                <input:ToggleableMenuItem
+                    IsEnabled="{Binding !!DocumentManagerSubViewModel.ActiveDocument, Source={viewModels:MainVM}}"
+                    IsChecked="{Binding DocumentManagerSubViewModel.ActiveDocument.VerticalSymmetryAxisEnabledBindable, Source={viewModels:MainVM}, Mode=TwoWay}"
                     ui:Translator.Key="VERTICAL_LINE_SYMMETRY">
                     <MenuItem.Icon>
-                        <Image Source="../Images/SymmetryVertical.png"
+                        <Image Source="/Images/SymmetryVertical.png"
                                Width="{x:Static xaml:Menu.IconDimensions}" Height="{x:Static xaml:Menu.IconDimensions}"/>
                     </MenuItem.Icon>
-                </MenuItem>-->
+                </input:ToggleableMenuItem>
                 <Separator/>
                 <MenuItem ui:Translator.Key="ROTATION">
                     <MenuItem ui:Translator.Key="ROT_IMG_90_D" xaml:Menu.Command="PixiEditor.Document.Rotate90Deg"/>

+ 108 - 0
src/PixiEditor.UI.Common/Controls/ToggleableMenuItem.axaml

@@ -0,0 +1,108 @@
+<ResourceDictionary xmlns="https://github.com/avaloniaui"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+                    xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input"
+                    xmlns:converters="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"
+                    xmlns:system="clr-namespace:System;assembly=System.Runtime">
+    <ControlTheme x:Key="{x:Type input:ToggleableMenuItem}"
+                  TargetType="input:ToggleableMenuItem">
+        <Setter Property="Background" Value="Transparent" />
+        <Setter Property="BorderThickness" Value="1" />
+        <Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />
+        <Setter Property="Padding" Value="6 0" />
+        <Setter Property="Template">
+            <ControlTemplate>
+                <Border Name="root"
+                        Background="{TemplateBinding Background}"
+                        BorderBrush="{TemplateBinding BorderBrush}"
+                        BorderThickness="{TemplateBinding BorderThickness}"
+                        CornerRadius="{TemplateBinding CornerRadius}">
+                    <Grid>
+                        <Grid.ColumnDefinitions>
+                            <ColumnDefinition Width="20" />
+                            <ColumnDefinition Width="5" />
+                            <ColumnDefinition Width="*" />
+                            <ColumnDefinition Width="Auto"
+                                              SharedSizeGroup="MenuItemIGT" />
+                            <ColumnDefinition Width="20" />
+                        </Grid.ColumnDefinitions>
+                        <ContentPresenter Name="icon"
+                                          Width="16"
+                                          Height="16"
+                                          Margin="3"
+                                          HorizontalAlignment="Center"
+                                          VerticalAlignment="Center"
+                                          Content="{TemplateBinding Icon}" />
+                        <StackPanel Grid.Column="2" Orientation="Horizontal">
+                            <ContentPresenter Name="PART_HeaderPresenter"
+                                              Margin="{TemplateBinding Padding}"
+                                              VerticalAlignment="Center"
+                                              Content="{TemplateBinding Header}"
+                                              ContentTemplate="{TemplateBinding HeaderTemplate}">
+                                <ContentPresenter.DataTemplates>
+                                    <DataTemplate DataType="system:String">
+                                        <AccessText Text="{Binding}" />
+                                    </DataTemplate>
+                                </ContentPresenter.DataTemplates>
+                            </ContentPresenter>
+                            <Grid Width="12" Margin="3">
+                                <Path Name="check"
+                                      VerticalAlignment="Center"
+                                      Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z"
+                                      Fill="{TemplateBinding Foreground}"
+                                      IsVisible="{TemplateBinding IsChecked}" />
+                            </Grid>
+                        </StackPanel>
+                        <TextBlock x:Name="PART_InputGestureText"
+                                   Grid.Column="3"
+                                   VerticalAlignment="Center"
+                                   Text="{TemplateBinding InputGesture,
+                                              Converter={StaticResource KeyGestureConverter}}" />
+                        <Path Name="rightArrow"
+                              Grid.Column="4"
+                              Margin="10,0,0,0"
+                              VerticalAlignment="Center"
+                              Data="M0,0L4,3.5 0,7z"
+                              Fill="{DynamicResource ThemeForegroundBrush}" />
+                        <Popup Name="PART_Popup"
+                               IsLightDismissEnabled="False"
+                               IsOpen="{TemplateBinding IsSubMenuOpen,
+                                            Mode=TwoWay}"
+                               Placement="RightEdgeAlignedTop">
+                            <Border Background="{DynamicResource ThemeBackgroundBrush}"
+                                    BorderBrush="{DynamicResource ThemeBorderMidBrush}"
+                                    CornerRadius="{TemplateBinding CornerRadius}"
+                                    BorderThickness="{TemplateBinding BorderThickness}">
+                                <ScrollViewer>
+                                    <ItemsPresenter Name="PART_ItemsPresenter"
+                                                    Margin="2"
+                                                    Grid.IsSharedSizeScope="True"
+                                                    ItemsPanel="{TemplateBinding ItemsPanel}" />
+                                </ScrollViewer>
+                            </Border>
+                        </Popup>
+                    </Grid>
+                </Border>
+            </ControlTemplate>
+        </Setter>
+
+        <Style Selector="^:separator">
+            <Setter Property="Template">
+                <ControlTemplate>
+                    <Separator />
+                </ControlTemplate>
+            </Setter>
+        </Style>
+
+        <Style Selector="^:selected /template/ Border#root">
+            <Setter Property="Background" Value="{DynamicResource ThemeControlHighBrush}" />
+        </Style>
+
+        <Style Selector="^:empty /template/ Path#rightArrow">
+            <Setter Property="IsVisible" Value="False" />
+        </Style>
+
+        <Style Selector="^:disabled">
+            <Setter Property="Opacity" Value="{DynamicResource ThemeDisabledOpacity}" />
+        </Style>
+    </ControlTheme>
+</ResourceDictionary>

+ 45 - 0
src/PixiEditor.UI.Common/Controls/ToggleableMenuItem.cs

@@ -0,0 +1,45 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Metadata;
+using Avalonia.Input;
+
+namespace PixiEditor.AvaloniaUI.Views.Input;
+
+[PseudoClasses(":checked")]
+public class ToggleableMenuItem : MenuItem
+{
+    public static readonly StyledProperty<bool> IsCheckedProperty = AvaloniaProperty.Register<ToggleableMenuItem, bool>(
+        nameof(IsChecked));
+
+    public bool IsChecked
+    {
+        get => GetValue(IsCheckedProperty);
+        set => SetValue(IsCheckedProperty, value);
+    }
+
+    public ToggleableMenuItem()
+    {
+        IsCheckedProperty.Changed.Subscribe(OnCheckedChanged);
+        PointerPressed += OnPointerPressedHandler;
+    }
+
+    private void OnPointerPressedHandler(object? sender, PointerPressedEventArgs e)
+    {
+        if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
+        {
+            IsChecked = !IsChecked;
+        }
+    }
+
+    private void OnCheckedChanged(AvaloniaPropertyChangedEventArgs<bool> args)
+    {
+        if (args.NewValue.Value)
+        {
+            PseudoClasses.Add("checked");
+        }
+        else
+        {
+            PseudoClasses.Remove("checked");
+        }
+    }
+}

+ 1 - 0
src/PixiEditor.UI.Common/Styles/PixiEditor.Controls.axaml

@@ -70,6 +70,7 @@
                 <MergeResourceInclude Source="avares://PixiEditor.UI.Common/Controls/TreeViewItem.axaml"/>
                 <MergeResourceInclude Source="avares://PixiEditor.UI.Common/Controls/WindowNotificationManager.axaml"/>
                 <MergeResourceInclude Source="avares://PixiEditor.UI.Common/Controls/Shelf.axaml"/>
+                <MergeResourceInclude Source="avares://PixiEditor.UI.Common/Controls/ToggleableMenuItem.axaml"/>
             </ResourceDictionary.MergedDictionaries>
         </ResourceDictionary>
     </Styles.Resources>