Browse Source

Fixed GridLines

Krzysztof Krysiński 1 year ago
parent
commit
82147e1583

+ 5 - 5
src/PixiEditor.AvaloniaUI/Helpers/Converters/ReciprocalConverter.cs

@@ -10,12 +10,12 @@ internal class ReciprocalConverter : SingleInstanceConverter<ReciprocalConverter
         if (value is not double num)
         if (value is not double num)
             return AvaloniaProperty.UnsetValue;
             return AvaloniaProperty.UnsetValue;
 
 
-        double result;
-        if (parameter is not double mult)
-            result = 1 / num;
-        else
-            result = mult / num;
+        return Convert(num, parameter is double mult ? mult : 1d);
+    }
 
 
+    public static double Convert(double num, double mult = 1)
+    {
+        var result = mult / num;
         return Math.Clamp(result, 1e-15, 1e15);
         return Math.Clamp(result, 1e-15, 1e15);
     }
     }
 }
 }

+ 1 - 0
src/PixiEditor.AvaloniaUI/Helpers/IconEvaluators.cs

@@ -10,6 +10,7 @@ namespace PixiEditor.Helpers;
 
 
 internal static class IconEvaluators
 internal static class IconEvaluators
 {
 {
+    /*TODO: Segoe is Windows only*/
     private static readonly FontFamily segeoMdl2 = new FontFamily("Segoe MDL2 Assets");
     private static readonly FontFamily segeoMdl2 = new FontFamily("Segoe MDL2 Assets");
 
 
     [Evaluator.Icon("PixiEditor.FontIcon")]
     [Evaluator.Icon("PixiEditor.FontIcon")]

+ 2 - 2
src/PixiEditor.AvaloniaUI/ViewModels/SubViewModels/UndoViewModel.cs

@@ -16,7 +16,7 @@ internal class UndoViewModel : SubViewModel<ViewModelMain>
     ///     Redo last action.
     ///     Redo last action.
     /// </summary>
     /// </summary>
     [Command.Basic("PixiEditor.Undo.Redo", "REDO", "REDO_DESCRIPTIVE", CanExecute = "PixiEditor.Undo.CanRedo", Key = Key.Y, Modifiers = KeyModifiers.Control,
     [Command.Basic("PixiEditor.Undo.Redo", "REDO", "REDO_DESCRIPTIVE", CanExecute = "PixiEditor.Undo.CanRedo", Key = Key.Y, Modifiers = KeyModifiers.Control,
-        IconPath = "E7A6", IconEvaluator = "PixiEditor.FontIcon")]
+        IconPath = "Redo.png")]
     public void Redo()
     public void Redo()
     {
     {
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
@@ -29,7 +29,7 @@ internal class UndoViewModel : SubViewModel<ViewModelMain>
     ///     Undo last action.
     ///     Undo last action.
     /// </summary>
     /// </summary>
     [Command.Basic("PixiEditor.Undo.Undo", "UNDO", "UNDO_DESCRIPTIVE", CanExecute = "PixiEditor.Undo.CanUndo", Key = Key.Z, Modifiers = KeyModifiers.Control,
     [Command.Basic("PixiEditor.Undo.Undo", "UNDO", "UNDO_DESCRIPTIVE", CanExecute = "PixiEditor.Undo.CanUndo", Key = Key.Z, Modifiers = KeyModifiers.Control,
-        IconPath = "E7A7", IconEvaluator = "PixiEditor.FontIcon")]
+        IconPath = "Undo.png")]
     public void Undo()
     public void Undo()
     {
     {
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;
         var doc = Owner.DocumentManagerSubViewModel.ActiveDocument;

+ 5 - 5
src/PixiEditor.AvaloniaUI/Views/Main/MainTitleBar.axaml

@@ -8,6 +8,7 @@
              xmlns:viewModels="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
              xmlns:viewModels="clr-namespace:PixiEditor.AvaloniaUI.ViewModels"
              xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
              xmlns:dialogs="clr-namespace:PixiEditor.AvaloniaUI.Views.Dialogs"
              xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input;assembly=PixiEditor.UI.Common"
              xmlns:input="clr-namespace:PixiEditor.AvaloniaUI.Views.Input;assembly=PixiEditor.UI.Common"
+             xmlns:avaloniaUi="clr-namespace:PixiEditor.AvaloniaUI"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
              x:Class="PixiEditor.AvaloniaUI.Views.Main.MainTitleBar">
              x:Class="PixiEditor.AvaloniaUI.Views.Main.MainTitleBar">
     <Grid>
     <Grid>
@@ -216,16 +217,15 @@
                     ui:Translator.Key="OPEN_PALETTE_BROWSER"
                     ui:Translator.Key="OPEN_PALETTE_BROWSER"
                     xaml:Menu.Command="PixiEditor.Window.OpenPalettesBrowserWindow" />
                     xaml:Menu.Command="PixiEditor.Window.OpenPalettesBrowserWindow" />
                 <Separator/>
                 <Separator/>
-                <!--<MenuItem
+                <input:ToggleableMenuItem
                     ui:Translator.Key="TOGGLE_GRIDLINES"
                     ui:Translator.Key="TOGGLE_GRIDLINES"
                     IsChecked="{Binding ViewportSubViewModel.GridLinesEnabled, Mode=TwoWay}"
                     IsChecked="{Binding ViewportSubViewModel.GridLinesEnabled, Mode=TwoWay}"
-                    IsCheckable="True"
-                    InputGestureText="{xaml:ShortcutBinding PixiEditor.View.ToggleGrid}">
+                    InputGesture="{xaml:ShortcutBinding PixiEditor.View.ToggleGrid}">
                     <MenuItem.Icon>
                     <MenuItem.Icon>
-                        <Image Source="../Images/Commands/PixiEditor/View/ToggleGrid.png"
+                        <Image Source="/Images/Commands/PixiEditor/View/ToggleGrid.png"
                                Width="{x:Static xaml:Menu.IconDimensions}" Height="{x:Static xaml:Menu.IconDimensions}"/>
                                Width="{x:Static xaml:Menu.IconDimensions}" Height="{x:Static xaml:Menu.IconDimensions}"/>
                     </MenuItem.Icon>
                     </MenuItem.Icon>
-                </MenuItem>-->
+                </input:ToggleableMenuItem>
             </MenuItem>
             </MenuItem>
             <MenuItem
             <MenuItem
                 Focusable="False"
                 Focusable="False"

+ 8 - 56
src/PixiEditor.AvaloniaUI/Views/Main/ViewportControls/Viewport.axaml

@@ -24,6 +24,7 @@
     xmlns:viewModels1="clr-namespace:PixiEditor.ViewModels"
     xmlns:viewModels1="clr-namespace:PixiEditor.ViewModels"
     xmlns:converters="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Converters"
     xmlns:converters="clr-namespace:PixiEditor.AvaloniaUI.Helpers.Converters"
     xmlns:ui1="clr-namespace:PixiEditor.AvaloniaUI.Helpers.UI"
     xmlns:ui1="clr-namespace:PixiEditor.AvaloniaUI.Helpers.UI"
+    xmlns:visuals="clr-namespace:PixiEditor.AvaloniaUI.Views.Visuals"
     mc:Ignorable="d"
     mc:Ignorable="d"
     x:Name="vpUc"
     x:Name="vpUc"
     d:DesignHeight="450"
     d:DesignHeight="450"
@@ -330,70 +331,21 @@
                         <Grid.Resources>
                         <Grid.Resources>
                             <converters:ThresholdVisibilityConverter Threshold="10" x:Key="ThresholdVisibilityConverter"/>
                             <converters:ThresholdVisibilityConverter Threshold="10" x:Key="ThresholdVisibilityConverter"/>
                         </Grid.Resources>
                         </Grid.Resources>
-                        <Rectangle Focusable="False" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}">
+                        <visuals:GridLines Scale="{Binding Zoombox.Scale}" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}"
+                                           Rows="{Binding Document.Width}" Columns="{Binding Document.Height}"/>
+                        <!--<Rectangle Focusable="False" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}">
                             <Rectangle.Fill>
                             <Rectangle.Fill>
                                 <VisualBrush DestinationRect="{Binding Document.Width, Converter={converters:IntToViewportRectConverter}, ConverterParameter=vertical}"
                                 <VisualBrush DestinationRect="{Binding Document.Width, Converter={converters:IntToViewportRectConverter}, ConverterParameter=vertical}"
-                                            TileMode="Tile" >
+                                            TileMode="Tile">
                                     <VisualBrush.Visual>
                                     <VisualBrush.Visual>
+                                        <
                                         <Line StartPoint="0, 0" EndPoint="0, 1" Stroke="Black"
                                         <Line StartPoint="0, 0" EndPoint="0, 1" Stroke="Black"
-                                              StrokeThickness="{Binding Zoombox.Scale, Converter={converters:ReciprocalConverter}}"/>
+                                              StrokeThickness="}"/>
                                     </VisualBrush.Visual>
                                     </VisualBrush.Visual>
                                 </VisualBrush>
                                 </VisualBrush>
                             </Rectangle.Fill>
                             </Rectangle.Fill>
-                        </Rectangle>
-                        <Rectangle Focusable="False" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}">
-                            <Rectangle.Fill>
-                                <VisualBrush DestinationRect="{Binding Document.Height, Converter={converters:IntToViewportRectConverter}}"
-                                           TileMode="Tile" >
-                                    <VisualBrush.Visual>
-                                        <Line StartPoint="0, 0" EndPoint="1, 0" Stroke="Black" StrokeThickness="{Binding Zoombox.Scale, Converter={converters:ReciprocalConverter}}"/>
-                                    </VisualBrush.Visual>
-                                </VisualBrush>
-                            </Rectangle.Fill>
-                        </Rectangle>
-                        <Rectangle Focusable="False" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}">
-                            <Rectangle.Fill>
-                                <VisualBrush DestinationRect="{Binding Document.Width, Converter={converters:IntToViewportRectConverter}, ConverterParameter=vertical}" TileMode="Tile" >
-                                    <VisualBrush.Visual>
-                                        <Line StartPoint="0, 0" EndPoint="0, 1" Stroke="White">
-                                            <Line.StrokeThickness>
-                                                <Binding Converter="{converters:ReciprocalConverter}">
-                                                    <Binding.Path>Zoombox.Scale</Binding.Path>
-                                                    <Binding.ConverterParameter>
-                                                        <sys:Double>
-                                                            1.1
-                                                        </sys:Double>
-                                                    </Binding.ConverterParameter>
-                                                </Binding>
-                                            </Line.StrokeThickness>
-                                        </Line>
-                                    </VisualBrush.Visual>
-                                </VisualBrush>
-                            </Rectangle.Fill>
-                        </Rectangle>
-                        <Rectangle Focusable="False" IsVisible="{Binding Zoombox.Scale, Converter={StaticResource ThresholdVisibilityConverter}}">
-                            <Rectangle.Fill>
-                                <!--TODO: Make sure Viewport is DestinationRect in Avalonia. Also Viewbox Units not found-->
-                                <VisualBrush DestinationRect="{Binding Document.Height, Converter={converters:IntToViewportRectConverter}}" TileMode="Tile">
-                                    <VisualBrush.Visual>
-                                        <Line StartPoint="0, 0" EndPoint="1, 0" Stroke="White">
-                                            <Line.StrokeThickness>
-                                                <Binding Converter="{converters:ReciprocalConverter}">
-                                                    <Binding.Path>Zoombox.Scale</Binding.Path>
-                                                    <Binding.ConverterParameter>
-                                                        <sys:Double>
-                                                            1.1
-                                                        </sys:Double>
-                                                    </Binding.ConverterParameter>
-                                                </Binding>
-                                            </Line.StrokeThickness>
-                                        </Line>
-                                    </VisualBrush.Visual>
-                                </VisualBrush>
-                            </Rectangle.Fill>
-                        </Rectangle>
+                        </Rectangle>-->
                     </Grid>
                     </Grid>
-                    <!--TODO: what was the purpose of the rectangle below lol-->
                     <Rectangle Stroke="{DynamicResource ThemeBackgroundBrush1}" Opacity=".8" ZIndex="2"
                     <Rectangle Stroke="{DynamicResource ThemeBackgroundBrush1}" Opacity=".8" ZIndex="2"
                                IsVisible="{Binding Document.ReferenceLayerViewModel.IsVisibleBindable}">
                                IsVisible="{Binding Document.ReferenceLayerViewModel.IsVisibleBindable}">
                         <Rectangle.StrokeThickness>
                         <Rectangle.StrokeThickness>

+ 76 - 0
src/PixiEditor.AvaloniaUI/Views/Visuals/GridLines.cs

@@ -0,0 +1,76 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Media;
+using Avalonia.Media.Imaging;
+using PixiEditor.AvaloniaUI.Helpers.Converters;
+
+namespace PixiEditor.AvaloniaUI.Views.Visuals;
+
+public class GridLines : Control
+{
+    public static readonly StyledProperty<double> ScaleProperty = AvaloniaProperty.Register<GridLines, double>(
+        nameof(Scale),
+        defaultValue: 1d);
+
+    public static readonly StyledProperty<int> RowsProperty = AvaloniaProperty.Register<GridLines, int>(
+        nameof(Rows));
+
+    public static readonly StyledProperty<int> ColumnsProperty = AvaloniaProperty.Register<GridLines, int>(
+        nameof(Columns));
+
+    public int Columns
+    {
+        get => GetValue(ColumnsProperty);
+        set => SetValue(ColumnsProperty, value);
+    }
+
+    public int Rows
+    {
+        get => GetValue(RowsProperty);
+        set => SetValue(RowsProperty, value);
+    }
+
+    public double Scale
+    {
+        get => GetValue(ScaleProperty);
+        set => SetValue(ScaleProperty, value);
+    }
+
+    private const double PenWidth = 0.8d;
+    private Pen pen1 = new(Brushes.Black, PenWidth);
+    private Pen pen2 = new(Brushes.White, PenWidth);
+
+    static GridLines()
+    {
+        AffectsRender<GridLines>(ColumnsProperty, RowsProperty, ScaleProperty);
+    }
+
+    public override void Render(DrawingContext context)
+    {
+        // Draw lines in vertical and horizontal directions, size should be relative to the scale
+
+        base.Render(context);
+        double width = Bounds.Width;
+        double height = Bounds.Height;
+
+        double columnWidth = width / Columns;
+        double rowHeight = height / Rows;
+
+        pen1.Thickness = ReciprocalConverter.Convert(Scale);
+        pen2.Thickness = ReciprocalConverter.Convert(Scale, 1.2);
+
+        for (int i = 0; i < Columns; i++)
+        {
+            double x = i * columnWidth;
+            context.DrawLine(pen1, new Point(x, 0), new Point(x, height));
+            context.DrawLine(pen2, new Point(x, 0), new Point(x, height));
+        }
+
+        for (int i = 0; i < Rows; i++)
+        {
+            double y = i * rowHeight;
+            context.DrawLine(pen1, new Point(0, y), new Point(width, y));
+            context.DrawLine(pen2, new Point(0, y), new Point(width, y));
+        }
+    }
+}