Explorar el Código

Glyphs and line overlay

flabbet hace 10 meses
padre
commit
622b0191cb

+ 1 - 1
src/Drawie

@@ -1 +1 @@
-Subproject commit d882a27adb2f27101b08ef5d4041f1ad5eee9df7
+Subproject commit ad48bffad7514c7338d2f56c0174c2cc9cece396

+ 7 - 1
src/PixiEditor.UI.Common/Fonts/PixiPerfectIcons.axaml.cs

@@ -2,6 +2,7 @@
 using Avalonia.Controls;
 using Avalonia.Layout;
 using Avalonia.Media;
+using Avalonia.Platform;
 using PixiEditor.UI.Common.Rendering;
 
 namespace PixiEditor.UI.Common.Fonts;
@@ -10,7 +11,7 @@ namespace PixiEditor.UI.Common.Fonts;
 public static class PixiPerfectIcons
 {
     private static readonly FontFamily pixiPerfectFontFamily = new("avares://PixiEditor.UI.Common/Fonts/pixiperfect.ttf#pixiperfect");
-
+    
     public const string AddReference = "\ue900";
     public const string AddToMask = "\ue901";
     public const string AlphaLock = "\ue902";
@@ -130,6 +131,11 @@ public static class PixiPerfectIcons
     public const string ToggleLayerVisible = "\u25a1;"; // TODO: Create a toggle layer visible icon
     public const string ToggleMask = "\u25a1;"; // TODO: Create a toggle mask icon
     public static string Pen => "\uE971";
+    
+    public static Stream GetFontStream()
+    {
+        return AssetLoader.Open(new Uri("avares://PixiEditor.UI.Common/Fonts/pixiperfect.ttf"));
+    }
 
     public static IImage ToIcon(string unicode, double size = 18)
     {

+ 1 - 0
src/PixiEditor/Views/Overlays/BrushShapeOverlay/BrushShapeOverlay.cs

@@ -55,6 +55,7 @@ internal class BrushShapeOverlay : Overlay
 
     public BrushShapeOverlay()
     {
+        IsHitTestVisible = false;
         threePixelCircle = CreateThreePixelCircle();
     }
 

+ 0 - 12
src/PixiEditor/Views/Overlays/Handles/Handle.cs

@@ -76,18 +76,6 @@ public abstract class Handle : IHandle
         return Geometry.Parse("M 0 0 L 1 0 M 0 0 L 0 1");
     }
 
-    public static HandleGlyph? GetHandleGlyph(string key)
-    {
-        DrawingGroup? glyph = GetResource<DrawingGroup>(key);
-        if (glyph != null)
-        {
-            glyph.Transform = new MatrixTransform();
-            return new HandleGlyph(glyph);
-        }
-
-        return null;
-    }
-
     protected static Paint? GetPaint(string key, PaintStyle style = PaintStyle.Fill)
     {
         if (Application.Current.Styles.TryGetResource(key, null, out object paint))

+ 26 - 20
src/PixiEditor/Views/Overlays/Handles/HandleGlyph.cs

@@ -1,23 +1,22 @@
 using Avalonia;
 using Avalonia.Media;
-using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Text;
 using Drawie.Numerics;
+using PixiEditor.UI.Common.Fonts;
+using Colors = Drawie.Backend.Core.ColorsImpl.Colors;
 
 namespace PixiEditor.Views.Overlays.Handles;
 
-public class HandleGlyph
+public abstract class HandleGlyph
 {
-    public DrawingGroup Glyph { get; set; }
-
     public VecD Size { get; set; }
 
-    private Rect originalBounds;
+    public VecD Offset { get; set; }
 
-    public HandleGlyph(DrawingGroup glyph)
+    public HandleGlyph()
     {
-        Glyph = glyph;
-        originalBounds = glyph.GetBounds();
     }
 
     public void Draw(Canvas context, double zoomboxScale, VecD position)
@@ -25,26 +24,33 @@ public class HandleGlyph
         VecD scale = NormalizeGlyph(zoomboxScale);
         VecD offset = CalculateOffset(zoomboxScale, position);
 
-        Glyph.Transform = new MatrixTransform(
-            new Matrix(
-                scale.X, 0,
-                0, scale.Y,
-                offset.X, offset.Y)
-        );
-        
-        // TODO: Implement
-        //Glyph.Draw(context);
+        int saved = context.Save();
+
+        context.Translate((float)offset.X, (float)offset.Y);
+        context.Scale((float)scale.X, (float)scale.Y);
+
+        DrawHandle(context);
+
+        context.RestoreToCount(saved);
     }
+    
+    protected abstract void DrawHandle(Canvas context);
+    protected abstract RectD GetBounds();
 
     private VecD CalculateOffset(double zoomboxScale, VecD position)
     {
-        return new VecD(position.X - Size.X / (zoomboxScale * 2) - originalBounds.Position.X / (zoomboxScale * 2), position.Y - Size.Y / (zoomboxScale * 2) - originalBounds.Position.Y / (zoomboxScale * 2));
+        RectD bounds = GetBounds();
+        VecD scaledPosition = position + new VecD(-Size.X / 2f / zoomboxScale, Size.Y / 2f / zoomboxScale);
+        VecD scaledOffset = Offset / zoomboxScale;
+
+        return new VecD(scaledPosition.X, scaledPosition.Y) + scaledOffset;
     }
 
     private VecD NormalizeGlyph(double scale)
     {
-        double scaleX = Size.X / originalBounds.Width / scale;
-        double scaleY = Size.Y / originalBounds.Height / scale;
+        RectD bounds = GetBounds();
+        double scaleX = Size.X / bounds.Width / scale;
+        double scaleY = Size.Y / bounds.Height / scale;
 
         return new VecD(scaleX, scaleY);
     }

+ 42 - 0
src/PixiEditor/Views/Overlays/Handles/IconGlyph.cs

@@ -0,0 +1,42 @@
+using Avalonia.Media;
+using Drawie.Backend.Core.Surfaces;
+using Drawie.Backend.Core.Surfaces.PaintImpl;
+using Drawie.Backend.Core.Text;
+using Drawie.Numerics;
+using PixiEditor.UI.Common.Fonts;
+using Colors = Drawie.Backend.Core.ColorsImpl.Colors;
+
+namespace PixiEditor.Views.Overlays.Handles;
+
+public class IconGlyph : HandleGlyph
+{
+    public string Icon { get; set; }
+    
+    private Paint fontPaint = new() { Color = Colors.White, IsAntiAliased = true };
+    private Font targetFont;
+    
+    private static Font? pixiPerfectFont;
+
+    public IconGlyph(string icon, Font font = null, Paint customPaint = null)
+    {
+        Icon = icon;
+        pixiPerfectFont ??= Font.FromStream(PixiPerfectIcons.GetFontStream());
+        targetFont = font ?? pixiPerfectFont;
+        if (customPaint != null)
+        {
+            fontPaint?.Dispose();
+            fontPaint = customPaint;
+        }
+    }
+
+    protected override void DrawHandle(Canvas context)
+    {
+        context.DrawText(Icon, VecD.Zero, targetFont, fontPaint);
+    }
+
+    protected override RectD GetBounds()
+    {
+        double measure = targetFont.MeasureText(Icon);
+        return new RectD(0, 0, measure, targetFont.FontSize);
+    }
+}

+ 7 - 5
src/PixiEditor/Views/Overlays/Handles/TransformHandle.cs

@@ -5,6 +5,7 @@ using Drawie.Backend.Core.Numerics;
 using Drawie.Backend.Core.Surfaces.PaintImpl;
 using PixiEditor.Extensions.UI.Overlays;
 using Drawie.Numerics;
+using PixiEditor.UI.Common.Fonts;
 using PixiEditor.Views.Overlays.TransformOverlay;
 using Canvas = Drawie.Backend.Core.Surfaces.Canvas;
 
@@ -13,14 +14,15 @@ namespace PixiEditor.Views.Overlays.Handles;
 public class TransformHandle : Handle
 {
     public double AnchorRadius { get; set; } = GetResource<double>("AnchorRadius");
-    public Paint GlyphPaint { get; set; } = GetPaint("HandleGlyphBrush");
+    public Paint GlyphPaint { get; set; } = GetPaint("HandleBrush");
 
-    private HandleGlyph handleGeometry;
+    private HandleGlyph handleGlyph;
 
     public TransformHandle(Overlay owner) : base(owner)
     {
-        handleGeometry = GetHandleGlyph("MoveHandle");
-        handleGeometry.Size = Size - new VecD(1, 1);
+        handleGlyph = new IconGlyph(PixiPerfectIcons.MoveView, customPaint: GlyphPaint); 
+        handleGlyph.Size = Size - new VecD(1);
+        handleGlyph.Offset = new VecD(0, -1f);
 
         Cursor = new Cursor(StandardCursorType.SizeAll);
     }
@@ -41,6 +43,6 @@ public class TransformHandle : Handle
                 (float)radius, (float)radius, StrokePaint);
         }
         
-        handleGeometry.Draw(context, ZoomScale, Position);
+        handleGlyph.Draw(context, ZoomScale, Position);
     }
 }

+ 1 - 0
src/PixiEditor/Views/Overlays/LineToolOverlay/LineToolOverlay.cs

@@ -87,6 +87,7 @@ internal class LineToolOverlay : Overlay
         startHandle.OnDrag += StartHandleOnDrag;
         startHandle.OnHover += handle => Refresh();
         startHandle.OnRelease += OnHandleRelease;
+        startHandle.Cursor = new Cursor(StandardCursorType.Arrow);
         AddHandle(startHandle);
 
         endHandle = new AnchorHandle(this);

+ 6 - 7
src/PixiEditor/Views/Rendering/Scene.cs

@@ -131,6 +131,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
     private VulkanResources resources;
     private DrawingSurface renderSurface;
     private PixelSize lastSize = PixelSize.Empty;
+    private Cursor lastCursor;
 
     static Scene()
     {
@@ -273,13 +274,11 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
         var pushedMatrix = context.PushTransform(matrix);
 
 
-
         pushedMatrix.Dispose();
 
         //RenderFrame(new PixelSize(width, height));
 
         context.PushTransform(matrix);
-
     }
 
     private void RenderScene(RectD bounds)
@@ -308,7 +307,7 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
 
         renderSurface.Canvas.DrawRect(operationSurfaceRectToRender, checkerPaint);
     }
-    
+
     private void DrawOverlays(DrawingSurface renderSurface, RectD dirtyBounds, OverlayRenderSorting sorting)
     {
         if (AllOverlays != null)
@@ -325,10 +324,6 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
                 if (!overlay.CanRender()) continue;
 
                 overlay.RenderOverlay(renderSurface.Canvas, dirtyBounds);
-                if (overlay.IsHitTestVisible)
-                {
-                    Cursor = overlay.Cursor ?? DefaultCursor;
-                }
             }
         }
     }
@@ -398,6 +393,10 @@ internal class Scene : Zoombox.Zoombox, ICustomHitTest
                     }
 
                     overlay.MovePointer(args);
+                    if (overlay.IsHitTestVisible)
+                    {
+                        Cursor = overlay.Cursor ?? DefaultCursor;
+                    }
                 }
             }