[gimp/wip/Jehan/issue-498-quick-brush-edit: 512/523] app: new double action "tools-mypaint-brush-pixel-size-set", used as…
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/Jehan/issue-498-quick-brush-edit: 512/523] app: new double action "tools-mypaint-brush-pixel-size-set", used as…
- Date: Thu, 11 Aug 2022 17:06:26 +0000 (UTC)
commit 1adec5d4d4566f226d98a302ca018acac817a277
Author: Jehan <jehan girinstud io>
Date: Sat Apr 2 22:29:46 2022 +0200
app: new double action "tools-mypaint-brush-pixel-size-set", used as…
… new action_pixel_size of GimpMyBrushTool.
MyPaint brush tool clearly shows the limits of my trick to have some
enum actions work with absolute values whereas others work with
per-mille values between the property min and max.
Indeed firstly MyBrush's "radius" value is logarithmic and can be
negative. Since the enum trick relies on the fact that negative values
are the semantic enumerated constants, it's broken in such case. The
second issue is that while it was acceptable to use int size for most
paint tools (even though they were double), here radius only goes from
-2.0 to 6.0; so using int values only would leave us with jumping brush
sizes.
So now I create a proper double action which simply takes pixel size and
use this from the on-canvas brush size changing. No weird trick, no int
or sign limitations.
I also add a new optional action_pixel_size in GimpToolControl.
Note: I'm also updating a bit the logic for the MyPaint brush outline
function gimp_mybrush_tool_get_outline(). Indeed after skimming a bit
through mypaint-brush.c code in libmypaint, I am not sure at all we need
to use the offset_by_random like this. And really this shown outline
seems more indicative than anything else when I see the actual size
printed by the various brushes. Finally here it was counter-productive
as I needed to get easily the logarithmic radius from the pointer
interaction on canvas.
app/actions/tools-actions.c | 11 ++++++++
app/actions/tools-commands.c | 36 ++++++++++++++++++++++++
app/actions/tools-commands.h | 3 ++
app/display/gimpdisplayshell-tool-events.c | 45 ++++++++++++++++++++----------
app/tools/gimpmybrushtool.c | 25 +++++++++++------
app/tools/gimptoolcontrol.c | 23 +++++++++++++++
app/tools/gimptoolcontrol.h | 23 ++++++++++++++-
7 files changed, 143 insertions(+), 23 deletions(-)
---
diff --git a/app/actions/tools-actions.c b/app/actions/tools-actions.c
index b78681c16d..54baea36bc 100644
--- a/app/actions/tools-actions.c
+++ b/app/actions/tools-actions.c
@@ -224,6 +224,13 @@ static const GimpEnumActionEntry tools_mybrush_radius_actions[] =
NULL }
};
+static const GimpDoubleActionEntry tools_mybrush_pixel_size_actions[] =
+{
+ { "tools-mypaint-brush-pixel-size-set", GIMP_ICON_TOOL_MYPAINT_BRUSH,
+ "Set MyPaint Brush Diameter in pixel", NULL, NULL,
+ 1.0, NULL }
+};
+
static const GimpEnumActionEntry tools_mybrush_hardness_actions[] =
{
{ "tools-mypaint-brush-hardness-set", GIMP_ICON_TOOL_MYPAINT_BRUSH,
@@ -697,6 +704,10 @@ tools_actions_setup (GimpActionGroup *group)
tools_mybrush_radius_actions,
G_N_ELEMENTS (tools_mybrush_radius_actions),
tools_mybrush_radius_cmd_callback);
+ gimp_action_group_add_double_actions (group, NULL,
+ tools_mybrush_pixel_size_actions,
+ G_N_ELEMENTS (tools_mybrush_pixel_size_actions),
+ tools_mybrush_pixel_size_cmd_callback);
gimp_action_group_add_enum_actions (group, NULL,
tools_mybrush_hardness_actions,
G_N_ELEMENTS (tools_mybrush_hardness_actions),
diff --git a/app/actions/tools-commands.c b/app/actions/tools-commands.c
index b840e7f3c3..e15eab59db 100644
--- a/app/actions/tools-commands.c
+++ b/app/actions/tools-commands.c
@@ -466,6 +466,42 @@ tools_mybrush_radius_cmd_callback (GimpAction *action,
}
}
+void
+tools_mybrush_pixel_size_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data)
+{
+ GimpContext *context;
+ GimpToolInfo *tool_info;
+ gdouble dvalue;
+ return_if_no_context (context, data);
+
+ dvalue = g_variant_get_double (value);
+ /* Dividing by 2.0 because the parameter is the size of the brush,
+ * hence the diameter and this tool uses the radius as parameter.
+ * Furthermore MyPaint brush radius is stored as a natural logarithm
+ * radius.
+ */
+ dvalue = log (dvalue / 2.0);
+
+ tool_info = gimp_context_get_tool (context);
+
+ if (tool_info && GIMP_IS_MYBRUSH_OPTIONS (tool_info->tool_options))
+ {
+ GParamSpec *pspec;
+
+ pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (tool_info->tool_options),
+ "radius");
+ dvalue = CLAMP (dvalue,
+ G_PARAM_SPEC_DOUBLE (pspec)->minimum,
+ G_PARAM_SPEC_DOUBLE (pspec)->maximum);
+
+ g_object_set (G_OBJECT (tool_info->tool_options),
+ "radius", dvalue,
+ NULL);
+ }
+}
+
void
tools_mybrush_hardness_cmd_callback (GimpAction *action,
GVariant *value,
diff --git a/app/actions/tools-commands.h b/app/actions/tools-commands.h
index 38ab455b25..fa77369e32 100644
--- a/app/actions/tools-commands.h
+++ b/app/actions/tools-commands.h
@@ -68,6 +68,9 @@ void tools_airbrush_flow_cmd_callback (GimpAction *action,
void tools_mybrush_radius_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
+void tools_mybrush_pixel_size_cmd_callback (GimpAction *action,
+ GVariant *value,
+ gpointer data);
void tools_mybrush_hardness_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index 62f00634b1..8df1c60cae 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -48,6 +48,7 @@
#include "widgets/gimpdevicemanager.h"
#include "widgets/gimpdevices.h"
#include "widgets/gimpdialogfactory.h"
+#include "widgets/gimpdoubleaction.h"
#include "widgets/gimpenumaction.h"
#include "widgets/gimpuimanager.h"
#include "widgets/gimpwidgets-utils.h"
@@ -143,9 +144,9 @@ 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,
+static void gimp_display_shell_activate_action (GimpUIManager *manager,
const gchar *action_desc,
- gint value);
+ GVariant *value);
/* public functions */
@@ -1805,18 +1806,31 @@ gimp_display_shell_handle_scrolling (GimpDisplayShell *shell,
/* TODO: different logics with "lock brush to view". */
/* TODO 2: scale aware? */
- action = gimp_tool_control_get_action_size (active_tool->control);
-
+ action = gimp_tool_control_get_action_pixel_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);
+ gimp_display_shell_activate_action (manager, action,
+ g_variant_new_double ((gdouble) size));
+ }
+ else
+ {
+ 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_action (manager, action,
+ g_variant_new_int32 (size));
+ }
}
}
else
@@ -2257,9 +2271,9 @@ gimp_display_shell_untransform_event_coords (GimpDisplayShell *shell,
}
static void
-gimp_display_shell_activate_enum_action (GimpUIManager *manager,
- const gchar *action_desc,
- gint value)
+gimp_display_shell_activate_action (GimpUIManager *manager,
+ const gchar *action_desc,
+ GVariant *value)
{
gchar *group_name;
gchar *action_name;
@@ -2278,8 +2292,11 @@ gimp_display_shell_activate_enum_action (GimpUIManager *manager,
if (GIMP_IS_ENUM_ACTION (action) &&
GIMP_ENUM_ACTION (action)->value_variable)
{
- gimp_action_emit_activate (action,
- g_variant_new_int32 (value));
+ gimp_action_emit_activate (action, value);
+ }
+ else if (GIMP_IS_DOUBLE_ACTION (action))
+ {
+ gimp_action_emit_activate (action, value);
}
}
diff --git a/app/tools/gimpmybrushtool.c b/app/tools/gimpmybrushtool.c
index 4576b894e3..2a7378802f 100644
--- a/app/tools/gimpmybrushtool.c
+++ b/app/tools/gimpmybrushtool.c
@@ -94,11 +94,13 @@ gimp_mybrush_tool_init (GimpMybrushTool *mybrush_tool)
{
GimpTool *tool = GIMP_TOOL (mybrush_tool);
- gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_INK);
- gimp_tool_control_set_action_size (tool->control,
- "tools/tools-mypaint-brush-radius-set");
- gimp_tool_control_set_action_hardness (tool->control,
- "tools/tools-mypaint-brush-hardness-set");
+ gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_INK);
+ gimp_tool_control_set_action_size (tool->control,
+ "tools/tools-mypaint-brush-radius-set");
+ gimp_tool_control_set_action_pixel_size (tool->control,
+ "tools/tools-mypaint-brush-pixel-size-set");
+ gimp_tool_control_set_action_hardness (tool->control,
+ "tools/tools-mypaint-brush-hardness-set");
gimp_paint_tool_enable_color_picker (GIMP_PAINT_TOOL (mybrush_tool),
GIMP_COLOR_PICK_TARGET_FOREGROUND);
@@ -125,11 +127,18 @@ gimp_mybrush_tool_get_outline (GimpPaintTool *paint_tool,
gdouble y)
{
GimpMybrushOptions *options = GIMP_MYBRUSH_TOOL_GET_OPTIONS (paint_tool);
- GimpMybrush *brush = gimp_context_get_mybrush (GIMP_CONTEXT (options));
GimpCanvasItem *item = NULL;
GimpDisplayShell *shell = gimp_display_get_shell (display);
-
- gdouble radius = exp (options->radius) + 2 * options->radius * gimp_mybrush_get_offset_by_random (brush);
+ gdouble radius;
+
+ /* Radius size as used by libmypaint is logarithmic.
+ * The drawn outline in the MyBrush tool is more of a general idea of
+ * the brush size. With each brush having its own logic, actual drawn
+ * dabs may be quite different, smaller but also bigger. And there are
+ * some random elements in there too.
+ * See also mypaint-brush.c code in libmypaint.
+ */
+ radius = exp (options->radius);
radius = MAX (MAX (4 / shell->scale_x, 4 / shell->scale_y), radius);
item = gimp_mybrush_tool_create_cursor (paint_tool, display, x, y, radius);
diff --git a/app/tools/gimptoolcontrol.c b/app/tools/gimptoolcontrol.c
index d8b138683f..b6103f5395 100644
--- a/app/tools/gimptoolcontrol.c
+++ b/app/tools/gimptoolcontrol.c
@@ -98,6 +98,8 @@ gimp_tool_control_finalize (GObject *object)
g_free (control->action_object_1);
g_free (control->action_object_2);
+ g_free (control->action_pixel_size);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -725,3 +727,24 @@ gimp_tool_control_get_action_object_2 (GimpToolControl *control)
return control->action_object_2;
}
+
+void
+gimp_tool_control_set_action_pixel_size (GimpToolControl *control,
+ const gchar *action)
+{
+ g_return_if_fail (GIMP_IS_TOOL_CONTROL (control));
+
+ if (action != control->action_pixel_size)
+ {
+ g_free (control->action_pixel_size);
+ control->action_pixel_size = g_strdup (action);
+ }
+}
+
+const gchar *
+gimp_tool_control_get_action_pixel_size (GimpToolControl *control)
+{
+ g_return_val_if_fail (GIMP_IS_TOOL_CONTROL (control), NULL);
+
+ return control->action_pixel_size;
+}
diff --git a/app/tools/gimptoolcontrol.h b/app/tools/gimptoolcontrol.h
index 855180698f..6617258cba 100644
--- a/app/tools/gimptoolcontrol.h
+++ b/app/tools/gimptoolcontrol.h
@@ -79,15 +79,31 @@ struct _GimpToolControl
GimpToolCursorType toggle_tool_cursor;
GimpCursorModifier toggle_cursor_modifier;
- gchar *action_opacity;
gchar *action_size;
gchar *action_aspect;
gchar *action_angle;
+
gchar *action_spacing;
+
+ gchar *action_opacity;
gchar *action_hardness;
gchar *action_force;
+
gchar *action_object_1;
gchar *action_object_2;
+
+ /* Enum actions have a +-/min/max values which are not necessarily so
+ * useful. They also have a variable value which works as a per mille
+ * between the min and max, so it's hard to use, especially for
+ * actions which have a huge max or which can have negative values.
+ * For instance, aspect and angle can be negative. As for size and
+ * spacing, their max value can be huge. Finally "size" can be
+ * negative for the MyPaint brush tool, which uses a logarithmic
+ * radius as base value.
+ * For this reason, we also register specialized actions with clear
+ * unit if needed.
+ */
+ gchar *action_pixel_size;
};
struct _GimpToolControlClass
@@ -251,4 +267,9 @@ void gimp_tool_control_set_action_object_2 (GimpToolControl *control,
const gchar * gimp_tool_control_get_action_object_2 (GimpToolControl *control);
+void gimp_tool_control_set_action_pixel_size (GimpToolControl *control,
+ const gchar *action);
+const gchar * gimp_tool_control_get_action_pixel_size (GimpToolControl *control);
+
+
#endif /* __GIMP_TOOL_CONTROL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]