Skip to content

Commit a0b7a45

Browse files
committed
Fix a couple issues with dragging points in the Curves dialog
- The proximity tolerance for highlighting and removing control points is also now used to start dragging an existing control point. Previously this required clicking on the exact location - Fix issues where other control points could be erased while dragging a control point around, if the point was dragged over the x coordinate of the other point. Fixes: #1973602
1 parent a33d29c commit a0b7a45

2 files changed

Lines changed: 55 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Thanks to the following contributors who worked on this release:
2525
- Fixed errors when saving a file that was opened with a missing or incorrect extension ([#2013050](https://bugs.launchpad.net/pinta/+bug/2013050))
2626
- Fixed a bug where certain layer opacity settings could be incorrectly rounded ([#2020596](https://bugs.launchpad.net/pinta/+bug/2020596))
2727
- Fixed bugs in the shape tools and the Lasso Select tool which prevented the last row and column of the image from being used (#467)
28+
- Fixed issues where the Curves dialog could not easily edit existing control points ([#1973602](https://bugs.launchpad.net/pinta/+bug/1973602))
29+
- Fixed a bug where dragging a control point in the Curves dialog could unexpectedly erase other control points ([#1973602](https://bugs.launchpad.net/pinta/+bug/1973602))
2830

2931
## [2.1.1](https://github.com/PintaProject/Pinta/releases/tag/2.1.1) - 2023/02/26
3032

Pinta.Effects/Dialogs/Effects.CurvesDialog.cs

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@
2626

2727
using System;
2828
using System.Collections.Generic;
29+
using System.Collections.ObjectModel;
30+
using System.Linq;
2931
using Cairo;
3032
using Gtk;
33+
using HarfBuzz;
3134
using Pinta.Core;
3235

3336
namespace Pinta.Effects;
@@ -57,12 +60,13 @@ private sealed class ControlPointDrawingInfo
5760

5861
private int channels;
5962
//last added control point x;
60-
private int last_cpx;
63+
private int? last_cpx;
6164
private PointI last_mouse_pos = new (0, 0);
65+
// Keys of existing control points which cannot be overwritten by a new control point.
66+
private HashSet<int> orig_cps = new ();
6267

6368
//control points for luminosity transfer mode
6469
private SortedList<int, int>[] luminosity_cps = null!; // NRT - Set via code flow
65-
//control points for rg transfer mode
6670
private SortedList<int, int>[] rgb_cps = null!;
6771

6872
public SortedList<int, int>[] ControlPoints {
@@ -262,26 +266,67 @@ private void HandleDrawingMotionNotifyEvent (EventControllerMotion controller, E
262266
return;
263267

264268
if (controller.GetCurrentEventState () == Gdk.ModifierType.Button1Mask) {
265-
// first and last control point cannot be removed
266-
if (last_cpx != 0 && last_cpx != size - 1) {
267-
foreach (var controlPoints in GetActiveControlPoints ()) {
268-
if (controlPoints.ContainsKey (last_cpx))
269-
controlPoints.Remove (last_cpx);
269+
if (last_cpx is not null) {
270+
// The first and last control points cannot be removed, so also forbid dragging them away.
271+
if (last_cpx == 0)
272+
x = 0;
273+
else if (last_cpx == size - 1)
274+
x = size - 1;
275+
else {
276+
// Remove the old version of the control point being edited.
277+
foreach (var controlPoints in GetActiveControlPoints ()) {
278+
if (controlPoints.ContainsKey (last_cpx.Value))
279+
controlPoints.Remove (last_cpx.Value);
280+
}
270281
}
271282
}
272283

273-
AddControlPoint (x, y);
284+
// Don't allow overwriting any of the original control points while dragging.
285+
if (!orig_cps.Contains (x))
286+
AddControlPoint (x, y);
287+
else
288+
last_cpx = null;
274289
}
275290

276291
InvalidateDrawing ();
277292
}
278293

294+
/// <summary>
295+
/// If the provided coordinates are close to an existing control point, snap to the control point's coordinates.
296+
/// </summary>
297+
private static bool SnapToControlPointProximity (IEnumerable<SortedList<int, int>> activeControlPoints, ref int x, ref int y)
298+
{
299+
foreach (var controlPoints in activeControlPoints) {
300+
for (int i = 0; i < controlPoints.Count; i++) {
301+
int cpx = controlPoints.Keys[i];
302+
int cpy = size - 1 - (int) controlPoints.Values[i];
303+
304+
if (CheckControlPointProximity (cpx, cpy, x, y)) {
305+
x = cpx;
306+
y = cpy;
307+
return true;
308+
}
309+
}
310+
}
311+
312+
return false;
313+
}
314+
279315
private void HandleDrawingButtonPressEvent (GestureClick controller, GestureClick.PressedSignalArgs args)
280316
{
281317
int x = (int) args.X;
282318
int y = (int) args.Y;
283319

284320
if (controller.GetCurrentMouseButton () == MouseButton.Left) {
321+
322+
orig_cps.Clear ();
323+
foreach (var controlPoints in GetActiveControlPoints ()) {
324+
orig_cps.UnionWith (controlPoints.Keys);
325+
}
326+
327+
if (SnapToControlPointProximity (GetActiveControlPoints (), ref x, ref y))
328+
orig_cps.Remove (x); // Allow dragging the snapped control point.
329+
285330
AddControlPoint (x, y);
286331
}
287332

0 commit comments

Comments
 (0)