Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions Pinta.Core/Classes/BaseTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ namespace Pinta.Core;
public abstract class BaseTool
{
private readonly IToolService tools;
private readonly IWorkspaceService workspace;
protected readonly IWorkspaceService workspace;

protected IResourceService Resources { get; }
protected ISettingsService Settings { get; }
Expand All @@ -55,11 +55,9 @@ protected BaseTool (IServiceProvider services)
CurrentCursor = DefaultCursor;

// Update cursor when active document changes
workspace.ActiveDocumentChanged += (_, _) => {
if (tools.CurrentTool == this)
SetCursor (CurrentCursor);
};

workspace.ActiveDocumentChanged += (_, _) => RefreshCursorIfActive ();
// Update cursor on zoom
workspace.ViewSizeChanged += (_, _) => RefreshCursorIfActive ();
// Give tools a chance to save their settings on application quit
Settings.SaveSettingsBeforeQuit += (_, _)
=> OnSaveSettings (Settings);
Expand Down Expand Up @@ -92,12 +90,6 @@ public virtual Cursor? DefaultCursor
/// </summary>
public Cursor? CurrentCursor { get; private set; }

/// <summary>
/// Specifies whether this application needs to update this tool's
/// cursor after a zoom operation.
/// </summary>
public virtual bool CursorChangesOnZoom
=> false;

/// <summary>
/// Specifies whether the tool manipulates selections.
Expand Down Expand Up @@ -327,6 +319,18 @@ public void SetCursor (Cursor? cursor)
workspace.ActiveWorkspace.Canvas.Cursor = cursor;
}

private void RefreshCursorIfActive ()
{
if (tools.CurrentTool == this) {
RefreshCursor ();
}
}

protected virtual void RefreshCursor ()
{
SetCursor (DefaultCursor);
}

#region Toolbar
private ToolBoxButton? tool_item;
private ToolBarDropDownButton? antialiasing_button;
Expand Down
2 changes: 1 addition & 1 deletion Pinta.Core/Classes/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public Document (
Selection = new DocumentSelection ();

Layers = new DocumentLayers (tools, this);
Workspace = new DocumentWorkspace (actions, tools, this);
Workspace = new DocumentWorkspace (actions, this);
IsDirty = false;
HasBeenSavedInSession = false;
ImageSize = size;
Expand Down
8 changes: 0 additions & 8 deletions Pinta.Core/Classes/DocumentWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ public sealed class DocumentWorkspace
private readonly Document document;

private readonly ActionManager actions;
private readonly ToolManager tools;

private enum ZoomType
{
Expand All @@ -44,11 +43,9 @@ private enum ZoomType

internal DocumentWorkspace (
ActionManager actions,
ToolManager tools,
Document document)
{
this.actions = actions;
this.tools = tools;

this.document = document;

Expand Down Expand Up @@ -116,11 +113,6 @@ public double Scale {
ViewSize = GetNewViewSize (document.ImageSize, value);

Invalidate ();

if (tools.CurrentTool?.CursorChangesOnZoom == true) {
//The current tool's cursor changes when the zoom changes.
tools.CurrentTool.SetCursor (tools.CurrentTool.CurrentCursor);
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions Pinta.Core/Extensions/GdkExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ public static Gdk.Texture CreateIconWithShape (
RectangleI initialShapeBBox = new (
imgToShapeX - Math.Max (halfOfShapeWidth, halfOfShapeHeight),
imgToShapeY - Math.Max (halfOfShapeWidth, halfOfShapeHeight),
clampedWidth,
clampedHeight);
Math.Max (clampedWidth, clampedHeight),
Math.Max (clampedWidth, clampedHeight));

// Inflate shape bounding box to allow for anti-aliasing
RectangleI inflatedBBox = initialShapeBBox.Inflated (2, 2);
Expand Down Expand Up @@ -186,7 +186,7 @@ public static Gdk.Texture CreateIconWithShape (
shapeRect = shapeRect.Inflated (-1, -1);
PointD[] pointsOfInflatedRotatedRectangle = RotateRectangle (shapeRect, shapeAngle);
g.DrawPolygonal (new ReadOnlySpan<PointD> (pointsOfRotatedRectangle), outerColor, LineCap.Butt);
g.DrawPolygonal (new ReadOnlySpan<PointD> (pointsOfInflatedRotatedRectangle), innerColor, LineCap.Butt);
g.DrawPolygonal (new ReadOnlySpan<PointD> ([.. pointsOfInflatedRotatedRectangle, pointsOfInflatedRotatedRectangle[0]]), innerColor, LineCap.Butt);
}
break;
}
Expand Down
9 changes: 9 additions & 0 deletions Pinta.Core/Managers/WorkspaceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public interface IWorkspaceService
public event EventHandler? LayerAdded;
public event EventHandler? LayerRemoved;
public event EventHandler? SelectedLayerChanged;
public event EventHandler? ViewSizeChanged;
public event PropertyChangedEventHandler? LayerPropertyChanged;
}

Expand Down Expand Up @@ -207,6 +208,7 @@ public void ActivateDocument (Document document)
document.Layers.LayerRemoved += Document_LayerRemoved;
document.Layers.SelectedLayerChanged += Document_SelectedLayerChanged;
document.Layers.LayerPropertyChanged += Document_LayerPropertyChanged;
document.Workspace.ViewSizeChanged += Document_ViewSizeChanged;

open_documents.Add (document);

Expand Down Expand Up @@ -236,6 +238,11 @@ private void Document_LayerAdded (object? sender, IndexEventArgs e)
LayerAdded?.Invoke (sender, e);
}

private void Document_ViewSizeChanged (object? sender, EventArgs ev)
{
ViewSizeChanged?.Invoke (sender, ev);
}

public void CloseDocument (Document document)
{
int index = open_documents.IndexOf (document);
Expand Down Expand Up @@ -263,6 +270,7 @@ public void CloseDocument (Document document)
document.Layers.LayerRemoved -= Document_LayerRemoved;
document.Layers.SelectedLayerChanged -= Document_SelectedLayerChanged;
document.Layers.LayerPropertyChanged -= Document_LayerPropertyChanged;
document.Workspace.ViewSizeChanged -= Document_ViewSizeChanged;
document.Close ();

OnDocumentClosed (new DocumentEventArgs (document));
Expand Down Expand Up @@ -453,6 +461,7 @@ private Task ShowFilePermissionErrorDialog (
public event EventHandler? LayerRemoved;
public event EventHandler? SelectedLayerChanged;
public event PropertyChangedEventHandler? LayerPropertyChanged;
public event EventHandler? ViewSizeChanged;

public event EventHandler<DocumentEventArgs>? DocumentActivated;
public event EventHandler<DocumentEventArgs>? DocumentClosed;
Expand Down
2 changes: 1 addition & 1 deletion Pinta.Tools/Brushes/SlashBrush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ present logic...
new_bottom.X * old_bottom.Y - new_bottom.Y * old_bottom.X +
old_bottom.X * old_top.Y - old_bottom.Y * old_top.X));

if (area < 2) {
if (area < 2 && (last_pos.X != current_pos.X || last_pos.Y != current_pos.Y)) {
old_top = OffsetPoint (old_top, -1, 1, angle + 90);
new_top = OffsetPoint (new_top, -1, 1, angle + 90);
old_bottom = OffsetPoint (old_bottom, 1, 1, angle + 90);
Expand Down
1 change: 0 additions & 1 deletion Pinta.Tools/Tools/CloneStampTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public CloneStampTool (IServiceProvider services) : base (services)
public override string Icon => Pinta.Resources.Icons.ToolCloneStamp;
// Translators: {0} is 'Ctrl', or a platform-specific key such as 'Command' on macOS.
public override string StatusBarText => Translations.GetString ("{0} + left click to set origin, left click to paint.", system_manager.CtrlLabel ());
public override bool CursorChangesOnZoom => true;
public override Gdk.Key ShortcutKey => new (Gdk.Constants.KEY_L);
public override int Priority => 47;
protected override bool ShowAntialiasingButton => true;
Expand Down
1 change: 0 additions & 1 deletion Pinta.Tools/Tools/ColorPickerTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ public ColorPickerTool (IServiceProvider services) : base (services)
public override string Name => Translations.GetString ("Color Picker");
public override string Icon => Pinta.Resources.Icons.ToolColorPicker;
public override string StatusBarText => Translations.GetString ("Left click to set primary color.\nRight click to set secondary color.");
public override bool CursorChangesOnZoom => true;
public override Gdk.Key ShortcutKey => new (Gdk.Constants.KEY_K);
public override int Priority => 33;
private int SampleSize => SampleSizeDropDown.SelectedItem.GetTagOrDefault (1);
Expand Down
3 changes: 0 additions & 3 deletions Pinta.Tools/Tools/EraserTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ public override string Icon
public override string StatusBarText
=> Translations.GetString ("Left click to erase to transparent, right click to erase to secondary color. ");

public override bool CursorChangesOnZoom
=> true;

public override Gdk.Key ShortcutKey
=> new (Gdk.Constants.KEY_E);

Expand Down
9 changes: 1 addition & 8 deletions Pinta.Tools/Tools/LassoSelectTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@

namespace Pinta.Tools;

public sealed class LassoSelectTool : BaseTool
public sealed class LassoSelectTool (IServiceProvider services) : BaseTool (services)
{
private readonly IWorkspaceService workspace;

private bool is_dragging = false;
private CombineMode combine_mode;
private SelectionHistoryItem? hist;
Expand All @@ -47,11 +45,6 @@ public sealed class LassoSelectTool : BaseTool
private Label? lasso_mode_label;
private ToolBarDropDownButton? lasso_mode_buttom;

public LassoSelectTool (IServiceProvider services) : base (services)
{
workspace = services.GetService<IWorkspaceService> ();
}

public override string Name => Translations.GetString ("Lasso Select");
public override string Icon => Pinta.Resources.Icons.ToolSelectLasso;
public override string StatusBarText => Translations.GetString ("In Freeform mode, click and drag to draw the outline for a selection area." +
Expand Down
2 changes: 0 additions & 2 deletions Pinta.Tools/Tools/MagicWandTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@ namespace Pinta.Tools;

public sealed class MagicWandTool : FloodTool
{
private readonly IWorkspaceService workspace;

private CombineMode combine_mode;

public MagicWandTool (IServiceProvider services) : base (services)
{
workspace = services.GetService<IWorkspaceService> ();
LimitToSelection = false;
}

Expand Down
2 changes: 0 additions & 2 deletions Pinta.Tools/Tools/MoveSelectionTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ public sealed class MoveSelectionTool : BaseTransformTool
private DocumentSelection? original_selection;

private readonly SystemManager system_manager;
private readonly IWorkspaceService workspace;
public MoveSelectionTool (IServiceProvider services) : base (services)
{
system_manager = services.GetService<SystemManager> ();
workspace = services.GetService<IWorkspaceService> ();
}

public override string Name => Translations.GetString ("Move Selection");
Expand Down
11 changes: 10 additions & 1 deletion Pinta.Tools/Tools/PaintBrushTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public PaintBrushTool (IServiceProvider services) : base (services)
public override string Name => Translations.GetString ("Paintbrush");
public override string Icon => Pinta.Resources.Icons.ToolPaintBrush;
public override string StatusBarText => Translations.GetString ("Left click to draw with primary color, right click to draw with secondary color.");
public override bool CursorChangesOnZoom => true;
public override Gdk.Key ShortcutKey => new (Gdk.Constants.KEY_B);
public override int Priority => 21;

Expand Down Expand Up @@ -206,13 +205,23 @@ protected override void OnBrushWidthChanged ()
}
}

protected override void RefreshCursor ()
{
if (active_brush is null) {
base.RefreshCursor ();
} else {
SetCursorFromBrush (active_brush);
}
}

private Label? brush_label;
private ToolBarComboBox? brush_combo_box;
private Gtk.Separator? separator;

private Gtk.Separator Separator => separator ??= GtkExtensions.CreateToolBarSeparator ();
private Label BrushLabel => brush_label ??= Label.New (string.Format (" {0}: ", Translations.GetString ("Type")));


private ToolBarComboBox BrushComboBox {
get {
if (brush_combo_box is null) {
Expand Down
8 changes: 1 addition & 7 deletions Pinta.Tools/Tools/RecolorTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,12 @@

namespace Pinta.Tools;

public class RecolorTool : BaseBrushTool
public class RecolorTool (IServiceProvider services) : BaseBrushTool (services)
{
private readonly IWorkspaceService workspace;

private PointI? last_point = null;
private BitMask? stencil;

public RecolorTool (IServiceProvider services) : base (services)
{
workspace = services.GetService<IWorkspaceService> ();
}

public override string Name => Translations.GetString ("Recolor");
public override string Icon => Pinta.Resources.Icons.ToolRecolor;
public override string StatusBarText => Translations.GetString (
Expand Down
2 changes: 0 additions & 2 deletions Pinta.Tools/Tools/SelectTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ namespace Pinta.Tools;
public abstract class SelectTool : BaseTool
{
private readonly IToolService tools;
private readonly IWorkspaceService workspace;

private SelectionHistoryItem? hist = default;
private CombineMode combine_mode = default;
Expand All @@ -49,7 +48,6 @@ public abstract class SelectTool : BaseTool
public SelectTool (IServiceProvider services) : base (services)
{
tools = services.GetService<IToolService> ();
workspace = services.GetService<IWorkspaceService> ();

handle = new (workspace) { InvertIfNegative = true };

Expand Down
2 changes: 0 additions & 2 deletions Pinta.Tools/Tools/TextTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,12 @@ public override string StatusBarText

private readonly IChromeService chrome;
private readonly IPaletteService palette;
private readonly IWorkspaceService workspace;
public TextTool (IServiceProvider services) : base (services)
{
IChromeService chromeService = services.GetService<IChromeService> ();

chrome = chromeService;
palette = services.GetService<IPaletteService> ();
workspace = services.GetService<IWorkspaceService> ();

im_context = Gtk.IMMulticontext.New ();
im_context.OnCommit += OnIMCommit;
Expand Down
1 change: 1 addition & 0 deletions tests/Pinta.Effects.Tests/Mocks/MockWorkspaceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ internal sealed class MockWorkspaceService (Size imageSize) : IWorkspaceService
public event EventHandler? LayerRemoved;
public event EventHandler? SelectedLayerChanged;
public event PropertyChangedEventHandler? LayerPropertyChanged;
public event EventHandler? ViewSizeChanged;
#pragma warning restore CS0067
}
1 change: 1 addition & 0 deletions tests/PintaBenchmarks/Mocks/MockWorkspaceService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ internal sealed class MockWorkspaceService (Size imageSize) : IWorkspaceService
public event EventHandler? LayerRemoved;
public event EventHandler? SelectedLayerChanged;
public event PropertyChangedEventHandler? LayerPropertyChanged;
public event EventHandler? ViewSizeChanged;

#pragma warning restore CS0067
}
Loading