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.
This commit is contained in:
parent
12be7bdc37
commit
c7979e7f06
7 changed files with 142 additions and 22 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
gdouble radius = exp (options->radius) + 2 * options->radius * gimp_mybrush_get_offset_by_random (brush);
|
||||
/* 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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue