[gimp/wip/Jehan/issue-498-quick-brush-edit: 2/26] app: allow to change the brush size on alt-right click.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/issue-498-quick-brush-edit: 2/26] app: allow to change the brush size on alt-right click.
- Date: Wed, 17 Aug 2022 12:20:45 +0000 (UTC)
commit 43f0147bfebe04f1d37cae63fe58ed79102a3562
Author: Jehan <jehan girinstud io>
Date: Tue Feb 15 00:10:34 2022 +0100
app: allow to change the brush size on alt-right click.
I started from mitch's patch (though code changed so it was not working,
yet I ended up with quite a different direction).
Modified from original proposition in #498:
* Do not mix opacity and brush size in a same action, one on horizontal
movement, the other on vertical. The problem is that it's hard to stay
perfectly horizontal or vertical, so you nearly necessarily change one
while changing the other and this would be frustrating.
* Do not just use modifiers, but modifiers + right click. The logics is
that left (or whatever is the first button) click is for the tool
actions. The middle click for navigation (panning, rotation, and even
layer navigation now). Right click for now is only for menu. With this
change, let's use right click for various settings-related changes
too. Also we already have people complaining with things like canvas
rotation happening unexpectedly even though it requires button clicks.
Imagine an action just made of modifiers! Many people would hit these
by mistake all the time!
* Focus on brush size only for now. Instead of just calling the action
repetitively with the "SElECT_NEXT" action as proposed in the original
patch by mitch, let's compute the actual size between the press and
release. This would allow to have a real visual hint and also would
make it a lot more useful and meaningful to be an on-canvas change.
Say you want to reproduce a stroke size on canvas. You can click the
center and expand to retrieve approximately the size without computing
it in pixels.
Limitations and future work:
* This is a first draft and I still want to test if it works well with
the "lock brush to view" and with scale factor > 1.
* I want to associate this with work done for #7034 so that visual hint
still appear even when we have no visual hint set.
* I am not so fond of with the way we use enum actions which doesn't
really make satisfying logics (I hacked a bit over it, but it's
getting ugly). I'm considering creating int/double actions to really
set some values with exact numbers through actions.
* Right now we need to stop the right click first. I want to be able to
stop the brush sizing with releasing Alt too.
* It would be nice to make this all more customizable, which is why I
called internal variable "mod1_setting". The goal will be to have
other types of actions possibly. Also it could be deactivatable for
people really not liking these or hitting these by mistake (while not
needing these). Same for the navigation shorcuts.
* Similarly the right-click menu could be deactivatable or switched to
other actions conditionally (through Preferences). It is doubtful how
useful it is (compared to using the same menus on top of the GUI)
though I don't want to just delete the option because some people
would clearly be used to it.
* I think we should start breaking down the whole tool events code a bit
more, in particular the function gimp_display_shell_canvas_tool_events().
* For more settings, a small on-canvas GUI could be of interest where
you could customize various values through sliders and buttons, and
also where you could put your favorite brushes or dynamics or whatnot.
It's not replacing the more complete dockable but could be a nice
quick version for fast editing.
app/actions/actions.c | 46 ++++++++++--
app/actions/actions.h | 6 +-
app/actions/context-commands.c | 42 +++++------
app/actions/layers-commands.c | 4 +-
app/actions/tools-commands.c | 36 ++++-----
app/actions/view-commands.c | 10 +--
app/display/gimpdisplayshell-tool-events.c | 116 +++++++++++++++++++++++++----
app/display/gimpdisplayshell.h | 2 +
8 files changed, 194 insertions(+), 68 deletions(-)
---
diff --git a/app/actions/actions.c b/app/actions/actions.c
index caaedd8e4f..daa06ef9bb 100644
--- a/app/actions/actions.c
+++ b/app/actions/actions.c
@@ -492,6 +492,29 @@ action_data_sel_count (gpointer data)
}
}
+/* action_select_value:
+ * @select_type:
+ * @value:
+ * @min:
+ * max:
+ * def:
+ * small_inc:
+ * inc:
+ * skip_inc:
+ * delta_factor:
+ * wrap:
+ * set_to_value:
+ *
+ * For any valid enum @value (which are all negative), the corresponding
+ * action computes the semantic value (default, first, next, etc.).
+ * For a positive @value:
+ * - if @set_to_value is used, then @value is used as-is (possibly
+ * wrapped if @wrap is set, clamped otherwise).
+ * - otherwise, @value is considered as a per-thousand value between the
+ * @min and @max, allowing to compute the returned value.
+ *
+ * Returns: the computed value to use for the action.
+ */
gdouble
action_select_value (GimpActionSelectType select_type,
gdouble value,
@@ -502,7 +525,8 @@ action_select_value (GimpActionSelectType select_type,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
- gboolean wrap)
+ gboolean wrap,
+ gboolean set_to_value)
{
switch (select_type)
{
@@ -554,9 +578,16 @@ action_select_value (GimpActionSelectType select_type,
default:
if ((gint) select_type >= 0)
- value = (gdouble) select_type * (max - min) / 1000.0 + min;
+ {
+ if (set_to_value)
+ value = (gdouble) select_type;
+ else
+ value = (gdouble) select_type * (max - min) / 1000.0 + min;
+ }
else
- g_return_val_if_reached (value);
+ {
+ g_return_val_if_reached (value);
+ }
break;
}
@@ -585,7 +616,8 @@ action_select_property (GimpActionSelectType select_type,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
- gboolean wrap)
+ gboolean wrap,
+ gboolean set_to_value)
{
GParamSpec *pspec;
@@ -607,7 +639,8 @@ action_select_property (GimpActionSelectType select_type,
G_PARAM_SPEC_DOUBLE (pspec)->minimum,
G_PARAM_SPEC_DOUBLE (pspec)->maximum,
G_PARAM_SPEC_DOUBLE (pspec)->default_value,
- small_inc, inc, skip_inc, delta_factor, wrap);
+ small_inc, inc, skip_inc, delta_factor, wrap,
+ set_to_value);
g_object_set (object, property_name, value, NULL);
@@ -633,7 +666,8 @@ action_select_property (GimpActionSelectType select_type,
G_PARAM_SPEC_INT (pspec)->minimum,
G_PARAM_SPEC_INT (pspec)->maximum,
G_PARAM_SPEC_INT (pspec)->default_value,
- small_inc, inc, skip_inc, delta_factor, wrap);
+ small_inc, inc, skip_inc, delta_factor, wrap,
+ set_to_value);
g_object_set (object, property_name, value, NULL);
diff --git a/app/actions/actions.h b/app/actions/actions.h
index b34636c828..b325f91864 100644
--- a/app/actions/actions.h
+++ b/app/actions/actions.h
@@ -42,7 +42,8 @@ gdouble action_select_value (GimpActionSelectType select_type,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
- gboolean wrap);
+ gboolean wrap,
+ gboolean set_to_value);
void action_select_property (GimpActionSelectType select_type,
GimpDisplay *display,
GObject *object,
@@ -51,7 +52,8 @@ void action_select_property (GimpActionSelectType select_type,
gdouble inc,
gdouble skip_inc,
gdouble delta_factor,
- gboolean wrap);
+ gboolean wrap,
+ gboolean set_to_value);
GimpObject * action_select_object (GimpActionSelectType select_type,
GimpContainer *container,
GimpObject *current);
diff --git a/app/actions/context-commands.c b/app/actions/context-commands.c
index e6c20049b9..167bb2d67b 100644
--- a/app/actions/context-commands.c
+++ b/app/actions/context-commands.c
@@ -145,7 +145,7 @@ context_foreground_red_cmd_callback (GimpAction *action,
color.r = action_select_value (select_type,
color.r,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_foreground (context, &color);
}
@@ -165,7 +165,7 @@ context_foreground_green_cmd_callback (GimpAction *action,
color.g = action_select_value (select_type,
color.g,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_foreground (context, &color);
}
@@ -185,7 +185,7 @@ context_foreground_blue_cmd_callback (GimpAction *action,
color.b = action_select_value (select_type,
color.b,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_foreground (context, &color);
}
@@ -205,7 +205,7 @@ context_background_red_cmd_callback (GimpAction *action,
color.r = action_select_value (select_type,
color.r,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_background (context, &color);
}
@@ -225,7 +225,7 @@ context_background_green_cmd_callback (GimpAction *action,
color.g = action_select_value (select_type,
color.g,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_background (context, &color);
}
@@ -245,7 +245,7 @@ context_background_blue_cmd_callback (GimpAction *action,
color.b = action_select_value (select_type,
color.b,
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_context_set_background (context, &color);
}
@@ -267,7 +267,7 @@ context_foreground_hue_cmd_callback (GimpAction *action,
hsv.h = action_select_value (select_type,
hsv.h,
0.0, 1.0, 1.0,
- 1.0 / 360.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 360.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_foreground (context, &color);
}
@@ -290,7 +290,7 @@ context_foreground_saturation_cmd_callback (GimpAction *action,
hsv.s = action_select_value (select_type,
hsv.s,
0.0, 1.0, 1.0,
- 0.01, 0.01, 0.1, 0.0, FALSE);
+ 0.01, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_foreground (context, &color);
}
@@ -313,7 +313,7 @@ context_foreground_value_cmd_callback (GimpAction *action,
hsv.v = action_select_value (select_type,
hsv.v,
0.0, 1.0, 1.0,
- 0.01, 0.01, 0.1, 0.0, FALSE);
+ 0.01, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_foreground (context, &color);
}
@@ -336,7 +336,7 @@ context_background_hue_cmd_callback (GimpAction *action,
hsv.h = action_select_value (select_type,
hsv.h,
0.0, 1.0, 1.0,
- 1.0 / 360.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 360.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_background (context, &color);
}
@@ -359,7 +359,7 @@ context_background_saturation_cmd_callback (GimpAction *action,
hsv.s = action_select_value (select_type,
hsv.s,
0.0, 1.0, 1.0,
- 0.01, 0.01, 0.1, 0.0, FALSE);
+ 0.01, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_background (context, &color);
}
@@ -382,7 +382,7 @@ context_background_value_cmd_callback (GimpAction *action,
hsv.v = action_select_value (select_type,
hsv.v,
0.0, 1.0, 1.0,
- 0.01, 0.01, 0.1, 0.0, FALSE);
+ 0.01, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_hsv_to_rgb (&hsv, &color);
gimp_context_set_background (context, &color);
}
@@ -407,7 +407,7 @@ context_opacity_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"opacity",
- 1.0 / 255.0, 0.01, 0.1, 0.1, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
@@ -435,7 +435,7 @@ context_paint_mode_cmd_callback (GimpAction *action,
index = context_paint_mode_index (paint_mode, modes, n_modes);
index = action_select_value (select_type,
index, 0, n_modes - 1, 0,
- 0.0, 1.0, 1.0, 0.0, FALSE);
+ 0.0, 1.0, 1.0, 0.0, FALSE, FALSE);
paint_mode = modes[index];
g_free (modes);
@@ -576,7 +576,7 @@ context_brush_spacing_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (brush),
"spacing",
- 1.0, 5.0, 20.0, 0.1, FALSE);
+ 1.0, 5.0, 20.0, 0.1, FALSE, FALSE);
}
}
@@ -665,7 +665,7 @@ context_brush_radius_cmd_callback (GimpAction *action,
radius = action_select_value (select_type,
radius,
min_radius, 4000.0, min_radius,
- 0.1, 1.0, 10.0, 0.05, FALSE);
+ 0.1, 1.0, 10.0, 0.05, FALSE, FALSE);
gimp_brush_generated_set_radius (generated, radius);
display = action_data_get_display (data);
@@ -699,7 +699,7 @@ context_brush_spikes_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (brush),
"spikes",
- 0.0, 1.0, 4.0, 0.1, FALSE);
+ 0.0, 1.0, 4.0, 0.1, FALSE, FALSE);
}
}
@@ -724,7 +724,7 @@ context_brush_hardness_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (brush),
"hardness",
- 0.001, 0.01, 0.1, 0.1, FALSE);
+ 0.001, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
@@ -749,7 +749,7 @@ context_brush_aspect_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (brush),
"aspect-ratio",
- 0.1, 1.0, 4.0, 0.1, FALSE);
+ 0.1, 1.0, 4.0, 0.1, FALSE, FALSE);
}
}
@@ -784,7 +784,7 @@ context_brush_angle_cmd_callback (GimpAction *action,
angle = action_select_value (select_type,
angle,
0.0, 180.0, 0.0,
- 0.1, 1.0, 15.0, 0.1, TRUE);
+ 0.1, 1.0, 15.0, 0.1, TRUE, FALSE);
gimp_brush_generated_set_angle (generated, angle);
@@ -881,7 +881,7 @@ context_select_color (GimpActionSelectType select_type,
index = action_select_value (select_type,
index,
0, max, 0,
- 0, 1, 4, 0, FALSE);
+ 0, 1, 4, 0, FALSE, FALSE);
context_set_color_index (index, use_colormap, use_palette, color);
}
diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c
index 262fb4f297..9c16fa382b 100644
--- a/app/actions/layers-commands.c
+++ b/app/actions/layers-commands.c
@@ -1788,7 +1788,7 @@ layers_opacity_cmd_callback (GimpAction *action,
opacity = action_select_value (select_type,
gimp_layer_get_opacity (iter->data),
0.0, 1.0, 1.0,
- 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE);
+ 1.0 / 255.0, 0.01, 0.1, 0.0, FALSE, FALSE);
gimp_layer_set_opacity (iter->data, opacity, push_undo);
}
@@ -1842,7 +1842,7 @@ layers_mode_cmd_callback (GimpAction *action,
index = layers_mode_index (layer_mode, modes, n_modes);
index = action_select_value (select_type,
index, 0, n_modes - 1, 0,
- 0.0, 1.0, 1.0, 0.0, FALSE);
+ 0.0, 1.0, 1.0, 0.0, FALSE, FALSE);
layer_mode = modes[index];
g_free (modes);
diff --git a/app/actions/tools-commands.c b/app/actions/tools-commands.c
index 7e84c5397e..9562c301c6 100644
--- a/app/actions/tools-commands.c
+++ b/app/actions/tools-commands.c
@@ -171,7 +171,7 @@ tools_color_average_radius_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"average-radius",
- 1.0, 1.0, 10.0, 0.1, FALSE);
+ 1.0, 1.0, 10.0, 0.1, FALSE, FALSE);
}
}
@@ -195,7 +195,7 @@ tools_paintbrush_size_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-size",
- 0.1, 1.0, 10.0, 1.0, FALSE);
+ 0.1, 1.0, 10.0, 1.0, FALSE, TRUE);
}
}
@@ -219,7 +219,7 @@ tools_paintbrush_angle_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-angle",
- 0.1, 1.0, 15.0, 0.1, TRUE);
+ 0.1, 1.0, 15.0, 0.1, TRUE, FALSE);
}
}
@@ -243,7 +243,7 @@ tools_paintbrush_aspect_ratio_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-aspect-ratio",
- 0.01, 0.1, 1.0, 0.1, TRUE);
+ 0.01, 0.1, 1.0, 0.1, TRUE, FALSE);
}
}
@@ -267,7 +267,7 @@ tools_paintbrush_spacing_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-spacing",
- 0.001, 0.01, 0.1, 0.1, FALSE);
+ 0.001, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
@@ -291,7 +291,7 @@ tools_paintbrush_hardness_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-hardness",
- 0.001, 0.01, 0.1, 0.1, FALSE);
+ 0.001, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
@@ -315,7 +315,7 @@ tools_paintbrush_force_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"brush-force",
- 0.001, 0.01, 0.1, 0.1, FALSE);
+ 0.001, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
@@ -339,7 +339,7 @@ tools_ink_blob_size_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"size",
- 0.1, 1.0, 10.0, 0.1, FALSE);
+ 0.1, 1.0, 10.0, 0.1, FALSE, FALSE);
}
}
@@ -363,7 +363,7 @@ tools_ink_blob_aspect_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"blob-aspect",
- 1.0, 0.1, 1.0, 0.1, FALSE);
+ 1.0, 0.1, 1.0, 0.1, FALSE, FALSE);
}
}
@@ -390,7 +390,7 @@ tools_ink_blob_angle_cmd_callback (GimpAction *action,
gimp_deg_to_rad (0.1),
gimp_deg_to_rad (1.0),
gimp_deg_to_rad (15.0),
- 0.1, TRUE);
+ 0.1, TRUE, FALSE);
}
}
@@ -414,7 +414,7 @@ tools_airbrush_rate_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"rate",
- 0.1, 1.0, 10.0, 0.1, FALSE);
+ 0.1, 1.0, 10.0, 0.1, FALSE, FALSE);
}
}
@@ -438,7 +438,7 @@ tools_airbrush_flow_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"flow",
- 0.1, 1.0, 10.0, 0.1, FALSE);
+ 0.1, 1.0, 10.0, 0.1, FALSE, FALSE);
}
}
@@ -462,7 +462,7 @@ tools_mybrush_radius_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"radius",
- 0.1, 0.1, 0.5, 1.0, FALSE);
+ 0.1, 0.1, 0.5, 1.0, FALSE, FALSE);
}
}
@@ -486,7 +486,7 @@ tools_mybrush_hardness_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"hardness",
- 0.001, 0.01, 0.1, 1.0, FALSE);
+ 0.001, 0.01, 0.1, 1.0, FALSE, FALSE);
}
}
@@ -510,7 +510,7 @@ tools_fg_select_brush_size_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"stroke-width",
- 1.0, 4.0, 16.0, 0.1, FALSE);
+ 1.0, 4.0, 16.0, 0.1, FALSE, FALSE);
}
}
@@ -534,7 +534,7 @@ tools_transform_preview_opacity_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"preview-opacity",
- 0.01, 0.1, 0.5, 0.1, FALSE);
+ 0.01, 0.1, 0.5, 0.1, FALSE, FALSE);
}
}
@@ -558,7 +558,7 @@ tools_warp_effect_size_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"effect-size",
- 1.0, 4.0, 16.0, 0.1, FALSE);
+ 1.0, 4.0, 16.0, 0.1, FALSE, FALSE);
}
}
@@ -582,7 +582,7 @@ tools_warp_effect_hardness_cmd_callback (GimpAction *action,
action_data_get_display (data),
G_OBJECT (tool_info->tool_options),
"effect-hardness",
- 0.001, 0.01, 0.1, 0.1, FALSE);
+ 0.001, 0.01, 0.1, 0.1, FALSE, FALSE);
}
}
diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c
index ecb0f4a129..8e70eaf4c1 100644
--- a/app/actions/view-commands.c
+++ b/app/actions/view-commands.c
@@ -247,7 +247,7 @@ view_zoom_cmd_callback (GimpAction *action,
scale,
0.0, 512.0, 1.0,
1.0 / 8.0, 1.0, 16.0, 0.0,
- FALSE);
+ FALSE, FALSE);
/* min = 1.0 / 256, max = 256.0 */
/* scale = min * (max / min)**(i/n), i = 0..n */
@@ -435,7 +435,7 @@ view_rotate_absolute_cmd_callback (GimpAction *action,
0.0,
-180.0, 180.0, 0.0,
1.0, 15.0, 90.0, 0.0,
- TRUE);
+ TRUE, FALSE);
gimp_display_shell_rotate_to (shell, angle);
}
@@ -459,7 +459,7 @@ view_rotate_relative_cmd_callback (GimpAction *action,
0.0,
-180.0, 180.0, 0.0,
1.0, 15.0, 90.0, 0.0,
- TRUE);
+ TRUE, FALSE);
gimp_display_shell_rotate (shell, delta);
}
@@ -518,7 +518,7 @@ view_scroll_horizontal_cmd_callback (GimpAction *action,
gtk_adjustment_get_step_increment (adj),
gtk_adjustment_get_page_increment (adj),
0,
- FALSE);
+ FALSE, FALSE);
gtk_adjustment_set_value (shell->hsbdata, offset);
}
@@ -548,7 +548,7 @@ view_scroll_vertical_cmd_callback (GimpAction *action,
gtk_adjustment_get_step_increment (adj),
gtk_adjustment_get_page_increment (adj),
0,
- FALSE);
+ FALSE, FALSE);
gtk_adjustment_set_value (shell->vsbdata, offset);
}
diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index ca6000b712..4d1f205d2c 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -17,6 +17,8 @@
#include "config.h"
+#include <math.h>
+
#include <gegl.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
@@ -36,6 +38,7 @@
#include "core/gimpimage-pick-item.h"
#include "core/gimpitem.h"
+#include "widgets/gimpaction.h"
#include "widgets/gimpcontrollers.h"
#include "widgets/gimpcontrollerkeyboard.h"
#include "widgets/gimpcontrollermouse.h"
@@ -45,6 +48,7 @@
#include "widgets/gimpdevicemanager.h"
#include "widgets/gimpdevices.h"
#include "widgets/gimpdialogfactory.h"
+#include "widgets/gimpenumaction.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
@@ -138,6 +142,10 @@ static void gimp_display_shell_untransform_event_coords (GimpDisplayShell
GimpCoords *image_coords,
gboolean *update_software_cursor);
+static void gimp_display_shell_activate_enum_action (GimpUIManager *manager,
+ const gchar *action_desc,
+ gint value);
+
/* public functions */
@@ -508,22 +516,35 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
if (gdk_event_triggers_context_menu (event))
{
- GimpUIManager *ui_manager;
- const gchar *ui_path;
+ GimpUIManager *ui_manager;
+ const gchar *ui_path;
+ GdkModifierType mod_state;
- ui_manager = tool_manager_get_popup_active (gimp,
- &image_coords, state,
- display,
- &ui_path);
+ mod_state = state & gimp_get_all_modifiers_mask ();
- if (! ui_manager)
+ /* Menu only with a right-click and no modifiers. */
+ if (mod_state == 0)
{
- ui_manager = shell->popup_manager;
- ui_path = "/dummy-menubar/image-popup";
- }
+ ui_manager = tool_manager_get_popup_active (gimp,
+ &image_coords, state,
+ display,
+ &ui_path);
- gimp_ui_manager_ui_popup_at_pointer (ui_manager, ui_path, event,
- NULL, NULL);
+ if (! ui_manager)
+ {
+ ui_manager = shell->popup_manager;
+ ui_path = "/dummy-menubar/image-popup";
+ }
+
+ gimp_ui_manager_ui_popup_at_pointer (ui_manager, ui_path, event,
+ NULL, NULL);
+ }
+ else if (mod_state == GDK_MOD1_MASK)
+ {
+ shell->mod1_settings = TRUE;
+ gimp_display_shell_start_scrolling (shell, event, state,
+ bevent->x, bevent->y);
+ }
}
else if (bevent->button == 1)
{
@@ -703,7 +724,8 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas,
}
else if (bevent->button == 3)
{
- /* nop */
+ if (shell->mod1_settings)
+ gimp_display_shell_stop_scrolling (shell, event);
}
else
{
@@ -1624,7 +1646,8 @@ gimp_display_shell_start_scrolling (GimpDisplayShell *shell,
shell->rotating = (state & gimp_get_extend_selection_mask ()) ? TRUE : FALSE;
shell->rotate_drag_angle = shell->rotate_angle;
shell->scaling = (state & gimp_get_toggle_behavior_mask ()) ? TRUE : FALSE;
- shell->layer_picking = (state & GDK_MOD1_MASK) ? TRUE : FALSE;
+ shell->layer_picking = ! gdk_event_triggers_context_menu (event) && (state & GDK_MOD1_MASK) ? TRUE :
FALSE;
+ shell->mod1_settings = gdk_event_triggers_context_menu (event) && (state & GDK_MOD1_MASK) ? TRUE :
FALSE;
if (shell->rotating)
{
@@ -1679,6 +1702,10 @@ gimp_display_shell_start_scrolling (GimpDisplayShell *shell,
shell->picked_layer = layer;
}
}
+ else if (shell->mod1_settings == TRUE)
+ {
+ /* no-op. */
+ }
else
gimp_display_shell_set_override_cursor (shell,
(GimpCursorType) GDK_FLEUR);
@@ -1701,6 +1728,7 @@ gimp_display_shell_stop_scrolling (GimpDisplayShell *shell,
shell->rotate_drag_angle = 0.0;
shell->scaling = FALSE;
shell->layer_picking = FALSE;
+ shell->mod1_settings = FALSE;
/* We may have ungrabbed the pointer when space was released while
* mouse was down, to be able to catch a GDK_BUTTON_RELEASE event.
@@ -1740,6 +1768,36 @@ gimp_display_shell_handle_scrolling (GimpDisplayShell *shell,
{
/* Do nothing. We only pick the layer on click. */
}
+ else if (shell->mod1_settings == TRUE)
+ {
+ GimpDisplay *display = shell->display;
+ Gimp *gimp = gimp_display_get_gimp (display);
+ GimpTool *active_tool = tool_manager_get_active (gimp);
+ const gchar *action;
+ gint size;
+
+ /* Size in image pixels: distance between start and current
+ * position.
+ */
+ size = (gint) (sqrt (pow ((x - shell->scroll_start_x) / shell->scale_x, 2) +
+ pow ((y - shell->scroll_start_y) / shell->scale_y, 2)) * 2.0);
+
+ /* TODO: different logics with "lock brush to view". */
+ /* TODO 2: scale aware? */
+ action = gimp_tool_control_get_action_size (active_tool->control);
+
+ if (action)
+ {
+ GimpImageWindow *window = gimp_display_shell_get_window (shell);
+ GimpUIManager *manager = gimp_image_window_get_ui_manager (window);
+
+ /* Special trick with these enum actions. If using any
+ * positive value, we get the GIMP_ACTION_SELECT_SET behavior
+ * which sets to the given value.
+ */
+ gimp_display_shell_activate_enum_action (manager, action, size);
+ }
+ }
else
{
gimp_display_shell_scroll (shell,
@@ -2176,3 +2234,33 @@ gimp_display_shell_untransform_event_coords (GimpDisplayShell *shell,
}
}
}
+
+static void
+gimp_display_shell_activate_enum_action (GimpUIManager *manager,
+ const gchar *action_desc,
+ gint value)
+{
+ gchar *group_name;
+ gchar *action_name;
+
+ group_name = g_strdup (action_desc);
+ action_name = strchr (group_name, '/');
+
+ if (action_name)
+ {
+ GimpAction *action;
+
+ *action_name++ = '\0';
+
+ action = gimp_ui_manager_find_action (manager, group_name, action_name);
+
+ if (GIMP_IS_ENUM_ACTION (action) &&
+ GIMP_ENUM_ACTION (action)->value_variable)
+ {
+ gimp_action_emit_activate (action,
+ g_variant_new_int32 (value));
+ }
+ }
+
+ g_free (group_name);
+}
diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h
index 395364b863..fb1b04aff8 100644
--- a/app/display/gimpdisplayshell.h
+++ b/app/display/gimpdisplayshell.h
@@ -227,6 +227,8 @@ struct _GimpDisplayShell
gboolean layer_picking;
GimpLayer *picked_layer;
+ gboolean mod1_settings;
+
GeglBuffer *mask;
gint mask_offset_x;
gint mask_offset_y;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]