Sfoglia il codice sorgente

Category picking worky

Krzysztof Krysiński 3 settimane fa
parent
commit
964ea4db05

+ 4 - 3
src/PixiEditor.Desktop/PixiEditor.Desktop.csproj

@@ -20,9 +20,10 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaVersion)"/>
+    <PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
     <!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
-    <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)"/>
+    <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="$(AvaloniaVersion)" />
+    <PackageReference Condition="'$(Configuration)' == 'Debug'"  Include="AvaloniaUI.DiagnosticsSupport" Version="2.1.1" />
   </ItemGroup>
 
   <ItemGroup>
@@ -36,7 +37,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <ProjectReference Include="..\PixiEditor\PixiEditor.csproj"/>
+    <ProjectReference Include="..\PixiEditor\PixiEditor.csproj" />
   </ItemGroup>
 
 </Project>

+ 9 - 2
src/PixiEditor.Desktop/Program.cs

@@ -44,12 +44,18 @@ public class Program
             .UsePlatformDetect()
             .With(new Win32PlatformOptions()
             {
-                RenderingMode = openGlPreferred ? [ Win32RenderingMode.Wgl, Win32RenderingMode.Vulkan] : [ Win32RenderingMode.Vulkan, Win32RenderingMode.Wgl],
+                RenderingMode =
+                    openGlPreferred
+                        ? [Win32RenderingMode.Wgl, Win32RenderingMode.Vulkan]
+                        : [Win32RenderingMode.Vulkan, Win32RenderingMode.Wgl],
                 OverlayPopups = true,
             })
             .With(new X11PlatformOptions()
             {
-                RenderingMode = openGlPreferred ? [ X11RenderingMode.Glx, X11RenderingMode.Vulkan] : [ X11RenderingMode.Vulkan, X11RenderingMode.Glx],
+                RenderingMode =
+                    openGlPreferred
+                        ? [X11RenderingMode.Glx, X11RenderingMode.Vulkan]
+                        : [X11RenderingMode.Vulkan, X11RenderingMode.Glx],
                 OverlayPopups = true,
             })
             .With(new SkiaOptions()
@@ -59,6 +65,7 @@ public class Program
             .WithDrawie()
 #if DEBUG
             .LogToTrace(LogEventLevel.Verbose, "Vulkan")
+            .WithDeveloperTools()
 #endif
             .LogToTrace();
     }

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1225,5 +1225,8 @@
   "STABILIZATION_MODE_SETTING": "Stabilization Mode",
   "NONE_STABILIZATION": "None - No stabilization is applied",
   "DISTANCE_BASED_STABILIZATION": "Distance Based - Stabilization based on pointer movement distance. Movement is applied when pointer moves more than the specified distance.",
-  "TIME_BASED_STABILIZATION": "Time Based - Stabilization based on time. Amount of smoothing is dependent on how much time has passed between points."
+  "TIME_BASED_STABILIZATION": "Time Based - Stabilization based on time. Amount of smoothing is dependent on how much time has passed between points.",
+  "ALL": "All",
+  "NONE": "None",
+  "SELECTED_CATEGORIES": "{0} selected"
 }

+ 145 - 47
src/PixiEditor/Views/Input/BrushPicker.axaml

@@ -7,6 +7,7 @@
              xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
              xmlns:controls="clr-namespace:Drawie.Interop.Avalonia.Core.Controls;assembly=Drawie.Interop.Avalonia.Core"
              xmlns:behaviours="clr-namespace:PixiEditor.Helpers.Behaviours"
+             xmlns:visuals="clr-namespace:PixiEditor.Views.Visuals"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
              x:ClassModifier="internal"
              x:Class="PixiEditor.Views.Input.BrushPicker">
@@ -16,6 +17,14 @@
             ZIndex="1"
             SamplingOptions="Bilinear"
             Texture="{Binding Path=SelectedBrush.PointPreview, RelativeSource={RelativeSource FindAncestor, AncestorType=input:BrushPicker}}" />
+        <Panel.Styles>
+            <Style Selector="Panel > ToggleButton:checked">
+                <Setter Property="Background" Value="{DynamicResource ThemeControlMidBrush}" />
+            </Style>
+            <Style Selector="Panel > ToggleButton:pressed">
+                <Setter Property="Background" Value="{DynamicResource ThemeControlMidBrush}" />
+            </Style>
+        </Panel.Styles>
         <ToggleButton Name="PopupToggle" Width="40" Height="20">
             <ToggleButton.Styles>
                 <Style Selector="FlyoutPresenter">
@@ -44,29 +53,58 @@
                                 <RowDefinition Height="Auto" />
                             </Grid.RowDefinitions>
 
-                            <TextBox Watermark="{localization:Translate Key=SEARCH}" Text="{Binding $parent[input:BrushPicker].SearchText}">
+                            <TextBox Watermark="{localization:Translate Key=SEARCH}"
+                                     Name="SearchBox"
+                                     Text="{Binding $parent[input:BrushPicker].SearchText}">
                                 <TextBox.InnerLeftContent>
                                     <TextBlock Classes="pixi-icon" Text="{DynamicResource icon-search}"
                                                Margin="0, 0, 5, 0" />
                                 </TextBox.InnerLeftContent>
                             </TextBox>
-                            <ComboBox Grid.Column="1" Margin="5,0,0,0" />
+                            <DropDownButton Grid.Row="0" Grid.Column="1"
+                                            Margin="5,0,0,0">
+                                <TextBlock Name="SelectionText"/>
+                                <DropDownButton.Flyout>
+                                    <Flyout>
+                                        <ListBox SelectionMode="Multiple,Toggle"
+                                                 Name="SelectCategoriesListBox">
+                                            <ListBox.ItemTemplate>
+                                                <DataTemplate>
+                                                    <TextBlock Text="{Binding }" Padding="5" />
+                                                </DataTemplate>
+                                            </ListBox.ItemTemplate>
+                                        </ListBox>
+                                    </Flyout>
+                                </DropDownButton.Flyout>
+                            </DropDownButton>
                             <StackPanel Orientation="Horizontal" Grid.Column="2" Grid.Row="0" Spacing="5"
                                         Margin="5,0,0,0">
+                                <StackPanel.Styles>
+                                    <Style Selector="ToggleButton#ViewModeListButton">
+                                        <Setter Property="Content" Value="{DynamicResource icon-grid}" />
+                                    </Style>
+                                    <Style Selector="ToggleButton#ViewModeListButton:checked">
+                                        <Setter Property="Content" Value="{DynamicResource icon-lasso}" />
+                                        <Setter Property="Background" Value="{DynamicResource ThemeControlMidBrush}" />
+                                    </Style>
+                                </StackPanel.Styles>
                                 <ToggleButton Classes="pixi-icon"
                                               Name="SortButton"
                                               Content="{DynamicResource icon-arrow-up}" />
                                 <ToggleButton Classes="pixi-icon"
-                                              Content="{DynamicResource icon-grid}" />
+                                              Name="ViewModeListButton"
+                                              IsChecked="{Binding $parent[input:BrushPicker].IsGridView,Mode=TwoWay}">
+                                </ToggleButton>
                             </StackPanel>
 
                             <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
                                         HorizontalAlignment="Right" Margin="0,5,5,0" Spacing="5"
                                         IsVisible="{Binding IsChecked, ElementName=SortButton}">
                                 <TextBlock Text="{localization:Translate Key=SORT_BY}" />
-                                <ComboBox SelectedIndex="{Binding $parent[input:BrushPicker].SelectedSortingIndex,
+                                <ComboBox
+                                    SelectedIndex="{Binding $parent[input:BrushPicker].SelectedSortingIndex,
                                                          Mode=TwoWay}"
-                                          ItemsSource="{Binding $parent[input:BrushPicker].SortingOptions}">
+                                    ItemsSource="{Binding $parent[input:BrushPicker].SortingOptions}">
 
                                 </ComboBox>
                             </StackPanel>
@@ -92,49 +130,109 @@
 
                         <ScrollViewer Grid.Row="1" Margin="0,10,0,0" HorizontalScrollBarVisibility="Disabled"
                                       VerticalScrollBarVisibility="Auto">
-                            <ItemsControl
-                                ItemsSource="{Binding $parent[input:BrushPicker].FilteredBrushes}">
-                                <ItemsControl.Styles>
-                                    <Style Selector="ContentPresenter > Border">
-                                        <Setter Property="Background" Value="Transparent" />
-                                        <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderMidBrush}" />
-                                        <Setter Property="BorderThickness" Value="0, 0, 0, 1" />
-                                        <Setter Property="Padding" Value="6, 6, 6, 5" />
-                                    </Style>
-                                    <Style Selector="ContentPresenter:pointerover > Border">
-                                        <Setter Property="Background" Value="{DynamicResource ThemeControlHighBrush}" />
-                                        <Setter Property="BorderBrush" Value="{DynamicResource ThemeBorderHighBrush}" />
-                                        <Setter Property="BorderThickness" Value="1" />
-                                        <Setter Property="Padding" Value="5" />
-                                    </Style>
+                            <Panel>
+                                <ItemsControl
+                                    IsVisible="{Binding Path=!$parent[input:BrushPicker].IsGridView}"
+                                    ItemsSource="{Binding $parent[input:BrushPicker].FilteredBrushes}">
+                                    <ItemsControl.Styles>
+                                        <Style Selector="ContentPresenter > Border">
+                                            <Setter Property="Background" Value="Transparent" />
+                                            <Setter Property="BorderBrush"
+                                                    Value="{DynamicResource ThemeBorderMidBrush}" />
+                                            <Setter Property="BorderThickness" Value="0, 0, 0, 1" />
+                                            <Setter Property="Padding" Value="6, 6, 6, 5" />
+                                        </Style>
+                                        <Style Selector="ContentPresenter:pointerover > Border">
+                                            <Setter Property="Background"
+                                                    Value="{DynamicResource ThemeControlHighBrush}" />
+                                            <Setter Property="BorderBrush"
+                                                    Value="{DynamicResource ThemeBorderHighBrush}" />
+                                            <Setter Property="BorderThickness" Value="1" />
+                                            <Setter Property="Padding" Value="5" />
+                                        </Style>
 
-                                    <Style Selector="ContentPresenter > Border.selected">
-                                        <Setter Property="Background"
-                                                Value="{DynamicResource ThemeAccent2TranslucentBrush}" />
-                                        <Setter Property="BorderBrush" Value="{DynamicResource ThemeAccent2Brush}" />
-                                        <Setter Property="BorderThickness" Value="1" />
-                                        <Setter Property="Padding" Value="5" />
-                                    </Style>
-                                </ItemsControl.Styles>
-                                <ItemsControl.ItemTemplate>
-                                    <DataTemplate>
-                                        <Border CornerRadius="4" IsHitTestVisible="True">
-                                            <input:BrushItem Brush="{Binding .}" />
-                                            <Interaction.Behaviors>
-                                                <ExecuteCommandOnPointerPressedBehavior
-                                                    Command="{Binding $parent[input:BrushPicker].SelectBrushCommand}"
-                                                    CommandParameter="{Binding }" />
-                                            </Interaction.Behaviors>
-                                            <Classes.selected>
-                                                <MultiBinding Converter="{converters:AreEqualConverter}">
-                                                    <Binding Path="$parent[input:BrushPicker].SelectedBrush" />
-                                                    <Binding />
-                                                </MultiBinding>
-                                            </Classes.selected>
-                                        </Border>
-                                    </DataTemplate>
-                                </ItemsControl.ItemTemplate>
-                            </ItemsControl>
+                                        <Style Selector="ContentPresenter > Border.selected">
+                                            <Setter Property="Background"
+                                                    Value="{DynamicResource ThemeAccent2TranslucentBrush}" />
+                                            <Setter Property="BorderBrush" Value="{DynamicResource ThemeAccent2Brush}" />
+                                            <Setter Property="BorderThickness" Value="1" />
+                                            <Setter Property="Padding" Value="5" />
+                                        </Style>
+                                    </ItemsControl.Styles>
+                                    <ItemsControl.ItemTemplate>
+                                        <DataTemplate>
+                                            <Border CornerRadius="4" IsHitTestVisible="True">
+                                                <input:BrushItem Brush="{Binding .}" />
+                                                <Interaction.Behaviors>
+                                                    <ExecuteCommandOnPointerPressedBehavior
+                                                        Command="{Binding $parent[input:BrushPicker].SelectBrushCommand}"
+                                                        CommandParameter="{Binding }" />
+                                                </Interaction.Behaviors>
+                                                <Classes.selected>
+                                                    <MultiBinding Converter="{converters:AreEqualConverter}">
+                                                        <Binding Path="$parent[input:BrushPicker].SelectedBrush" />
+                                                        <Binding />
+                                                    </MultiBinding>
+                                                </Classes.selected>
+                                            </Border>
+                                        </DataTemplate>
+                                    </ItemsControl.ItemTemplate>
+                                </ItemsControl>
+                                <ItemsControl
+                                    IsVisible="{Binding Path=$parent[input:BrushPicker].IsGridView}"
+                                    ItemsSource="{Binding $parent[input:BrushPicker].FilteredBrushes}">
+                                    <ItemsControl.Styles>
+                                        <Style Selector="ContentPresenter > Border">
+                                            <Setter Property="Background" Value="Transparent" />
+                                            <Setter Property="BorderBrush"
+                                                    Value="{DynamicResource ThemeBorderMidBrush}" />
+                                            <Setter Property="BorderThickness" Value="0, 0, 0, 1" />
+                                            <Setter Property="Padding" Value="6, 6, 6, 5" />
+                                        </Style>
+                                        <Style Selector="ContentPresenter:pointerover > Border">
+                                            <Setter Property="BorderBrush"
+                                                    Value="{DynamicResource ThemeBorderHighBrush}" />
+                                            <Setter Property="BorderThickness" Value="1" />
+                                            <Setter Property="Padding" Value="5" />
+                                        </Style>
+
+                                        <Style Selector="ContentPresenter > Border.selected">
+                                            <Setter Property="BorderBrush" Value="{DynamicResource ThemeAccent2Brush}" />
+                                            <Setter Property="BorderThickness" Value="1" />
+                                            <Setter Property="Padding" Value="5" />
+                                        </Style>
+                                    </ItemsControl.Styles>
+                                    <ItemsControl.ItemsPanel>
+                                        <ItemsPanelTemplate>
+                                            <WrapPanel Orientation="Horizontal" ItemWidth="60" ItemHeight="60"
+                                                       Margin="0" ItemSpacing="2" LineSpacing="2" />
+                                        </ItemsPanelTemplate>
+                                    </ItemsControl.ItemsPanel>
+                                    <ItemsControl.ItemTemplate>
+                                        <DataTemplate>
+                                            <Border Cursor="Hand" CornerRadius="4"
+                                                    ToolTip.Tip="{Binding Name}"
+                                                    IsHitTestVisible="True">
+                                                <visuals:TextureControl
+                                                    Width="50" Height="50"
+                                                    SamplingOptions="Bilinear"
+                                                    Texture="{Binding PointPreview}" />
+                                                <Interaction.Behaviors>
+                                                    <ExecuteCommandOnPointerPressedBehavior
+                                                        Command="{Binding $parent[input:BrushPicker].SelectBrushCommand}"
+                                                        CommandParameter="{Binding }" />
+                                                </Interaction.Behaviors>
+                                                <Classes.selected>
+                                                    <MultiBinding Converter="{converters:AreEqualConverter}">
+                                                        <Binding Path="$parent[input:BrushPicker].SelectedBrush" />
+                                                        <Binding />
+                                                    </MultiBinding>
+                                                </Classes.selected>
+                                            </Border>
+                                        </DataTemplate>
+                                    </ItemsControl.ItemTemplate>
+                                </ItemsControl>
+                            </Panel>
                         </ScrollViewer>
                     </Grid>
                 </Flyout>

+ 72 - 3
src/PixiEditor/Views/Input/BrushPicker.axaml.cs

@@ -1,11 +1,17 @@
 using System.Collections.ObjectModel;
 using Avalonia;
 using Avalonia.Controls;
+using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Templates;
+using Avalonia.Interactivity;
+using Avalonia.LogicalTree;
 using Avalonia.Markup.Xaml;
 using Avalonia.Media;
+using Avalonia.Metadata;
 using Avalonia.VisualTree;
 using CommunityToolkit.Mvvm.Input;
 using PixiEditor.Models.Palettes;
+using PixiEditor.UI.Common.Localization;
 using Brush = PixiEditor.Models.BrushEngine.Brush;
 
 namespace PixiEditor.Views.Input;
@@ -26,8 +32,28 @@ internal partial class BrushPicker : UserControl
     public static readonly StyledProperty<int> SelectedSortingProperty = AvaloniaProperty.Register<BrushPicker, int>(
         nameof(SelectedSortingIndex));
 
-    public static readonly StyledProperty<string> SortingDirectionProperty = AvaloniaProperty.Register<BrushPicker, string>(
-        nameof(SortingDirection), "ascending");
+    public static readonly StyledProperty<string> SortingDirectionProperty =
+        AvaloniaProperty.Register<BrushPicker, string>(
+            nameof(SortingDirection), "ascending");
+
+    public static readonly StyledProperty<bool> IsGridViewProperty = AvaloniaProperty.Register<BrushPicker, bool>(
+        nameof(IsGridView));
+
+    public static readonly StyledProperty<ObservableCollection<string>> CategoriesProperty =
+        AvaloniaProperty.Register<BrushPicker, ObservableCollection<string>>(
+            nameof(Categories));
+
+    public ObservableCollection<string> Categories
+    {
+        get => GetValue(CategoriesProperty);
+        set => SetValue(CategoriesProperty, value);
+    }
+
+    public bool IsGridView
+    {
+        get => GetValue(IsGridViewProperty);
+        set => SetValue(IsGridViewProperty, value);
+    }
 
     public string SortingDirection
     {
@@ -102,14 +128,57 @@ internal partial class BrushPicker : UserControl
     public BrushPicker()
     {
         InitializeComponent();
+        Categories = new ObservableCollection<string>() { "Basic", "Texture", "Special", "Custom" };
     }
 
     protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
     {
-        if(SelectedSortingIndex < 0 || SelectedSortingIndex >= SortingOptions.Length)
+        if (SelectedSortingIndex < 0 || SelectedSortingIndex >= SortingOptions.Length)
         {
             SelectedSortingIndex = 0;
         }
+
+        PopupToggle.Flyout.Opened += Flyout_Opened;
+        SelectCategoriesListBox.ItemsSource = Categories;
+        SelectCategoriesListBox.SelectionChanged += SelectCategoriesListBoxOnSelectionChanged;
+        
+        SelectCategoriesListBox.SelectAll();
+
+    }
+
+    private void SelectCategoriesListBoxOnSelectionChanged(object? sender, SelectionChangedEventArgs e)
+    {
+        if (Categories.Count == SelectCategoriesListBox.SelectedItems.Count)
+        {
+            SelectionText.Text = new LocalizedString("ALL");
+        }
+        else if (SelectCategoriesListBox.SelectedItems.Count == 0)
+        {
+            SelectionText.Text = new LocalizedString("NONE");
+        }
+        else if (SelectCategoriesListBox.SelectedItems.Count == 1)
+        {
+            SelectionText.Text = SelectCategoriesListBox.SelectedItems[0].ToString();
+        }
+        else
+        {
+            SelectionText.Text = new LocalizedString("SELECTED_CATEGORIES", SelectCategoriesListBox.SelectedItems.Count);
+        }
+
+        UpdateResults();
+    }
+
+    protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+    {
+        PopupToggle.Flyout.Opened -= Flyout_Opened;
+        SelectCategoriesListBox.SelectionChanged -= SelectCategoriesListBoxOnSelectionChanged;
+    }
+
+    private void Flyout_Opened(object? sender, EventArgs e)
+    {
+        int index = SelectedSortingIndex;
+        SelectedSortingIndex = -1;
+        SelectedSortingIndex = index;
     }
 
     private void UpdateResults()