Skip to content

Commit 6bb8148

Browse files
committed
Support ctrl+click to edit a palette color
This allows users without a middle mouse button (e.g. mac laptops) to still edit the palette color. Double-clicking was another alternative considered, but this doesn't work well since the single click action actually changes the current palette color Bug: #1436
1 parent 27e3a50 commit 6bb8148

6 files changed

Lines changed: 23 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Thanks to the following contributors who worked on this release:
1010

1111
### Added
1212
- The splatter brush now allows the minimum and maximum splatter size to be configured separately from the brush width
13+
- The status bar color palette now supports Ctrl+clicking to edit a color, in addition to middle clicking (#1436)
1314

1415
### Changed
1516

Pinta.Core/Extensions/Gtk/GtkExtensions.Interaction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static MouseButton GetCurrentMouseButton (this Gtk.GestureSingle gesture)
2020
/// Convert the "<Primary>" accelerator to the Ctrl or Command key, depending on the platform.
2121
/// This was done automatically in GTK3, but does not happen in GTK4.
2222
/// </summary>
23-
private static string ConvertPrimaryKey (this SystemManager system, string accel) =>
23+
private static string ConvertPrimaryKey (this ISystemService system, string accel) =>
2424
accel.Replace ("<Primary>", system.OperatingSystem == OS.Mac ? "<Meta>" : "<Control>");
2525

2626
private static string ConvertPrimaryKey (string accel) =>
@@ -30,7 +30,7 @@ private static string ConvertPrimaryKey (string accel) =>
3030
/// Returns the platform-specific label for the "Primary" (Ctrl) key.
3131
/// For example, this is the Cmd key on macOS.
3232
/// </summary>
33-
public static string CtrlLabel (this SystemManager system)
33+
public static string CtrlLabel (this ISystemService system)
3434
{
3535
AcceleratorParse (
3636
system.ConvertPrimaryKey ("<Primary>"),

Pinta.Core/Managers/SystemManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ namespace Pinta.Core;
3232

3333
public interface ISystemService
3434
{
35-
int RenderThreads { get; set; }
35+
int RenderThreads { get; }
36+
OS OperatingSystem { get; }
3637
}
3738

3839
public sealed class SystemManager : ISystemService

Pinta.Gui.Widgets/Widgets/StatusBarColorPaletteWidget.cs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@ public sealed class StatusBarColorPaletteWidget : Gtk.DrawingArea
4545

4646
private readonly IChromeService chrome;
4747
private readonly IPaletteService palette;
48+
private readonly ISystemService system;
4849

4950
private RectangleD palette_rect;
5051
private RectangleD recent_palette_rect;
5152

52-
public StatusBarColorPaletteWidget (IChromeService chrome, IPaletteService palette)
53+
public StatusBarColorPaletteWidget (IChromeService chrome, IPaletteService palette, ISystemService system)
5354
{
5455
this.chrome = chrome;
5556
this.palette = palette;
57+
this.system = system;
5658

5759
HasTooltip = true;
5860
OnQueryTooltip += HandleQueryTooltip;
@@ -71,13 +73,13 @@ public StatusBarColorPaletteWidget (IChromeService chrome, IPaletteService palet
7173
Gtk.GestureClick click_gesture = Gtk.GestureClick.New ();
7274
click_gesture.SetButton (0); // Listen for all mouse buttons.
7375
click_gesture.OnReleased += (_, e) => {
74-
HandleClick (new PointD (e.X, e.Y), click_gesture.GetCurrentButton ());
76+
HandleClick (new PointD (e.X, e.Y), click_gesture.GetCurrentButton (), click_gesture.GetCurrentEventState ());
7577
click_gesture.SetState (Gtk.EventSequenceState.Claimed);
7678
};
7779
AddController (click_gesture);
7880
}
7981

80-
private async void HandleClick (PointD point, uint button)
82+
private async void HandleClick (PointD point, uint button, Gdk.ModifierType state)
8183
{
8284
var element = GetElementAtPoint (point);
8385

@@ -138,11 +140,13 @@ private async void HandleClick (PointD point, uint button)
138140
if (index < 0)
139141
break;
140142

143+
bool isCtrlPressed = state.IsControlPressed ();
141144
if (button == GtkExtensions.MOUSE_RIGHT_BUTTON) {
142145
palette.SecondaryColor = palette.CurrentPalette.Colors[index];
143-
} else if (button == GtkExtensions.MOUSE_LEFT_BUTTON) {
146+
} else if (button == GtkExtensions.MOUSE_LEFT_BUTTON && !isCtrlPressed) {
144147
palette.PrimaryColor = palette.CurrentPalette.Colors[index];
145-
} else {
148+
} else if (button == GtkExtensions.MOUSE_MIDDLE_BUTTON ||
149+
(button == GtkExtensions.MOUSE_LEFT_BUTTON && isCtrlPressed)) {
146150
SingleColor pick = new (palette.CurrentPalette.Colors[index]);
147151
var colors = await GetUserChosenColor (
148152
pick,
@@ -307,8 +311,12 @@ private bool HandleQueryTooltip (object o, Gtk.Widget.QueryTooltipSignalArgs arg
307311

308312
switch (GetElementAtPoint (point)) {
309313
case WidgetElement.Palette:
310-
if (PaletteWidget.GetSwatchAtLocation (palette, point, palette_rect) >= 0)
311-
text = Translations.GetString ("Left click to set primary color. Right click to set secondary color. Middle click to choose palette color.");
314+
if (PaletteWidget.GetSwatchAtLocation (palette, point, palette_rect) >= 0) {
315+
// Translators: {0} is 'Ctrl', or a platform-specific key such as 'Command' on macOS.
316+
text = Translations.GetString ("Left click to set primary color. Right click to set secondary color. Middle click or press {0} and left click to choose palette color.",
317+
system.CtrlLabel ());
318+
}
319+
312320
break;
313321
case WidgetElement.RecentColorsPalette:
314322
if (PaletteWidget.GetSwatchAtLocation (palette, point, recent_palette_rect, true) >= 0)

Pinta/MainWindow.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,8 @@ private void CreateStatusBar ()
491491
statusbar.Append (
492492
new StatusBarColorPaletteWidget (
493493
PintaCore.Chrome,
494-
PintaCore.Palette) {
494+
PintaCore.Palette,
495+
PintaCore.System) {
495496
Hexpand = true,
496497
Halign = Gtk.Align.Fill,
497498
}

tests/Pinta.Effects.Tests/Mocks/MockSystemService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ namespace Pinta.Effects;
66
public class MockSystemService : ISystemService
77
{
88
public int RenderThreads { get; set; } = Environment.ProcessorCount;
9+
public OS OperatingSystem { get; } = OS.Other;
910
}

0 commit comments

Comments
 (0)