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
14 changes: 11 additions & 3 deletions Pinta.Core/Managers/WorkspaceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -383,12 +383,13 @@ public void SetActiveDocument (
}

internal void SetActiveDocumentInternal (
ToolManager tools,
Document document)
ToolManager tools,
Document document,
bool suppressCommit = false)
{
// Work around a case where we closed a document but haven't updated
// the active_document_index yet and it points to the closed document
if (HasOpenDocuments && active_document_index != -1 && open_documents.Count > active_document_index)
if (!suppressCommit && HasOpenDocuments && active_document_index != -1 && open_documents.Count > active_document_index)
tools.Commit ();

int index = open_documents.IndexOf (document);
Expand All @@ -397,6 +398,13 @@ internal void SetActiveDocumentInternal (
OnActiveDocumentChanged (EventArgs.Empty);
}

public void SetActiveDocumentForClose (Document document)
{
// Sets the active document in preparation for closing it. This avoids committing
// tool state when switching, so canceling the close will not finalize editable shapes, for example.
SetActiveDocumentInternal (PintaCore.Tools, document, suppressCommit: true);
}

private void OnActiveDocumentChanged (EventArgs _)
{
ActiveDocumentChanged?.Invoke (this, EventArgs.Empty);
Expand Down
14 changes: 10 additions & 4 deletions Pinta.Docking/DockNotebook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public sealed class DockNotebook : Gtk.Box
private readonly Adw.TabView tab_view;
private readonly Adw.TabBar tab_bar;
private readonly HashSet<IDockNotebookItem> items = [];
public bool IsClosingTab { get; private set; }

public DockNotebook ()
{
Expand Down Expand Up @@ -95,12 +96,17 @@ private bool TabView_OnClosePage (Adw.TabView _, Adw.TabView.ClosePageSignalArgs

TabClosedEventArgs close_args = new (item);

TabClosed?.Invoke (this, close_args);
IsClosingTab = true;
try {
TabClosed?.Invoke (this, close_args);

tab_view.ClosePageFinish (page, !close_args.Cancel);
tab_view.ClosePageFinish (page, !close_args.Cancel);

if (!close_args.Cancel)
items.Remove (item);
if (!close_args.Cancel)
items.Remove (item);
} finally {
IsClosingTab = false;
}

// Prevent the default close handler from running.
return Gdk.Constants.EVENT_STOP;
Expand Down
5 changes: 5 additions & 0 deletions Pinta.Gui.Widgets/Widgets/Canvas/PintaCanvas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ private void DrawHandles (Gtk.Snapshot snapshot, Graphene.Rect canvasViewBounds)
if (tool is null)
return;

// Only draw tool handles on the canvas for the active document.
// This prevents handles from one document appearing on another tab's canvas.
if (!ReferenceEquals (document, PintaCore.Workspace.ActiveDocumentOrDefault))
return;

snapshot.PushClip (canvasViewBounds);

foreach (IToolHandle control in tool.Handles.Where (c => c.Active)) {
Expand Down
36 changes: 34 additions & 2 deletions Pinta.Tools/Editable/EditEngines/BaseEditEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,40 @@ public ShapeEngine? ActiveShapeEngine {
//Helps to keep track of the first modification on a shape after the mouse is clicked, to prevent unnecessary history items.
protected bool clicked_without_modifying = false;

//Stores the editable shape data.
// Stores editable shape data per document; the static SEngines reference is
// rebound on active-document changes to point at the current document's list.
private static readonly Dictionary<Document, Collection<ShapeEngine>> shapes_by_document = new ();

// Stores the editable shape data for the currently active document.
public static Collection<ShapeEngine> SEngines = [];

static BaseEditEngine ()
{
// Initialize mapping for the current active document if available.
if (PintaCore.Workspace.ActiveDocumentOrDefault is Document doc)
SEngines = GetShapesForDocument (doc);

PintaCore.Workspace.ActiveDocumentChanged += (_, __) => {
if (PintaCore.Workspace.ActiveDocumentOrDefault is Document active)
SEngines = GetShapesForDocument (active);
};

PintaCore.Workspace.DocumentClosed += (_, e) => {
// Clean up mapping for closed documents.
if (e.Document is Document closed)
shapes_by_document.Remove (closed);
};
}

private static Collection<ShapeEngine> GetShapesForDocument (Document doc)
{
if (!shapes_by_document.TryGetValue (doc, out var shapes)) {
shapes = [];
shapes_by_document[doc] = shapes;
}
return shapes;
}

#region ToolbarEventHandlers

protected virtual void BrushMinusButtonClickedEvent (object? o, EventArgs args)
Expand Down Expand Up @@ -1455,7 +1486,8 @@ protected void CalculateModifiedCurrentPoint ()
/// </summary>
protected void ResetShapes ()
{
SEngines = [];
// Clear the current document's editable shape data.
SEngines.Clear ();

//The fields are modified instead of the properties here because a redraw call is undesired (for speed/efficiency).
SelectedPointIndex = -1;
Expand Down
3 changes: 0 additions & 3 deletions Pinta/Actions/File/CloseDocumentAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@ void IActionHandler.Uninitialize ()

private void Activated (object sender, EventArgs e)
{
// Commit any pending changes
tools.Commit ();

// If it's not dirty, just close it
if (!workspace.ActiveDocument.IsDirty) {
workspace.CloseActiveDocument (actions);
Expand Down
5 changes: 4 additions & 1 deletion Pinta/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private void DockNotebook_TabClosed (object? sender, TabClosedEventArgs e)
if (PintaCore.Workspace.OpenDocuments.IndexOf (view.Document) < 0)
return;

PintaCore.Actions.Window.SetActiveDocument (view.Document);
PintaCore.Workspace.SetActiveDocumentForClose (view.Document);
PintaCore.Actions.File.Close.Activate ();

if (PintaCore.Workspace.OpenDocuments.IndexOf (view.Document) < 0)
Expand All @@ -162,6 +162,9 @@ private void DockNotebook_TabClosed (object? sender, TabClosedEventArgs e)

private void DockNotebook_ActiveTabChanged (object? sender, EventArgs e)
{
if (canvas_pad.Notebook.IsClosingTab)
return;

var item = canvas_pad.Notebook.ActiveItem;

if (item == null)
Expand Down