[gimp] app: improve empty-selection check in GimpSelectionTool
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: improve empty-selection check in GimpSelectionTool
- Date: Mon, 3 Feb 2020 10:41:42 +0000 (UTC)
commit 57eaf91fbc95ea6aaa7206a882eb6d845279ae15
Author: Ell <ell_se yahoo com>
Date: Mon Feb 3 12:14:08 2020 +0200
app: improve empty-selection check in GimpSelectionTool
Add a new GimpSelectionTool::have_selection() virtual function,
which determines if the image has a selection (default
implementation), or if the tool will create one upon committing
(implemented by subclasses). Use this function in
gimp_selection_tool_oper_update() to determine the tool function;
in particular, don't use SELECTION_MOVE and SELECTION_MOVE_COPY
when there's no selection.
Override have_selection() in GimpFreeSelectTool, and return TRUE if
we have a polygon with three or more vertices, which will create a
selection upon committing.
app/tools/gimpfreeselecttool.c | 27 ++++++++++++
app/tools/gimpselectiontool.c | 99 ++++++++++++++++++++++++++----------------
app/tools/gimpselectiontool.h | 4 ++
3 files changed, 93 insertions(+), 37 deletions(-)
---
diff --git a/app/tools/gimpfreeselecttool.c b/app/tools/gimpfreeselecttool.c
index 71baa00b0c..c97096fc01 100644
--- a/app/tools/gimpfreeselecttool.c
+++ b/app/tools/gimpfreeselecttool.c
@@ -73,6 +73,9 @@ static void gimp_free_select_tool_options_notify (GimpTool *
GimpToolOptions *options,
const GParamSpec *pspec);
+static gboolean gimp_free_select_tool_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display);
+
static void gimp_free_select_tool_change_complete (GimpPolygonSelectTool *poly_sel,
GimpDisplay *display);
@@ -112,6 +115,7 @@ static void
gimp_free_select_tool_class_init (GimpFreeSelectToolClass *klass)
{
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
+ GimpSelectionToolClass *sel_class = GIMP_SELECTION_TOOL_CLASS (klass);
GimpPolygonSelectToolClass *poly_sel_class = GIMP_POLYGON_SELECT_TOOL_CLASS (klass);
tool_class->control = gimp_free_select_tool_control;
@@ -119,6 +123,8 @@ gimp_free_select_tool_class_init (GimpFreeSelectToolClass *klass)
tool_class->button_release = gimp_free_select_tool_button_release;
tool_class->options_notify = gimp_free_select_tool_options_notify;
+ sel_class->have_selection = gimp_free_select_tool_have_selection;
+
poly_sel_class->change_complete = gimp_free_select_tool_change_complete;
}
@@ -248,6 +254,27 @@ gimp_free_select_tool_options_notify (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->options_notify (tool, options, pspec);
}
+static gboolean
+gimp_free_select_tool_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display)
+{
+ GimpPolygonSelectTool *poly_sel = GIMP_POLYGON_SELECT_TOOL (sel_tool);
+ GimpTool *tool = GIMP_TOOL (sel_tool);
+
+ if (display == tool->display)
+ {
+ gint n_points;
+
+ gimp_polygon_select_tool_get_points (poly_sel, NULL, &n_points);
+
+ if (n_points > 2)
+ return TRUE;
+ }
+
+ return GIMP_SELECTION_TOOL_CLASS (parent_class)->have_selection (sel_tool,
+ display);
+}
+
static void
gimp_free_select_tool_change_complete (GimpPolygonSelectTool *poly_sel,
GimpDisplay *display)
diff --git a/app/tools/gimpselectiontool.c b/app/tools/gimpselectiontool.c
index ba94752f70..3029a38ac1 100644
--- a/app/tools/gimpselectiontool.c
+++ b/app/tools/gimpselectiontool.c
@@ -46,34 +46,40 @@
#include "gimp-intl.h"
-static void gimp_selection_tool_control (GimpTool *tool,
- GimpToolAction action,
- GimpDisplay *display);
-static void gimp_selection_tool_modifier_key (GimpTool *tool,
- GdkModifierType key,
- gboolean press,
- GdkModifierType state,
- GimpDisplay *display);
-static void gimp_selection_tool_oper_update (GimpTool *tool,
- const GimpCoords *coords,
- GdkModifierType state,
- gboolean proximity,
- GimpDisplay *display);
-static void gimp_selection_tool_cursor_update (GimpTool *tool,
- const GimpCoords *coords,
- GdkModifierType state,
- GimpDisplay *display);
-
-static void gimp_selection_tool_commit (GimpSelectionTool *sel_tool);
-static void gimp_selection_tool_halt (GimpSelectionTool *sel_tool,
- GimpDisplay *display);
-
-static gboolean gimp_selection_tool_check (GimpSelectionTool *sel_tool,
- GimpDisplay *display,
- GError **error);
-
-static void gimp_selection_tool_set_undo_ptr (GimpUndo **undo_ptr,
- GimpUndo *undo);
+static void gimp_selection_tool_control (GimpTool *tool,
+ GimpToolAction action,
+ GimpDisplay *display);
+static void gimp_selection_tool_modifier_key (GimpTool *tool,
+ GdkModifierType key,
+ gboolean press,
+ GdkModifierType state,
+ GimpDisplay *display);
+static void gimp_selection_tool_oper_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ gboolean proximity,
+ GimpDisplay *display);
+static void gimp_selection_tool_cursor_update (GimpTool *tool,
+ const GimpCoords *coords,
+ GdkModifierType state,
+ GimpDisplay *display);
+
+static gboolean gimp_selection_tool_real_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display);
+
+static void gimp_selection_tool_commit (GimpSelectionTool *sel_tool);
+static void gimp_selection_tool_halt (GimpSelectionTool *sel_tool,
+ GimpDisplay *display);
+
+static gboolean gimp_selection_tool_check (GimpSelectionTool *sel_tool,
+ GimpDisplay *display,
+ GError **error);
+
+static gboolean gimp_selection_tool_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display);
+
+static void gimp_selection_tool_set_undo_ptr (GimpUndo **undo_ptr,
+ GimpUndo *undo);
G_DEFINE_TYPE (GimpSelectionTool, gimp_selection_tool, GIMP_TYPE_DRAW_TOOL)
@@ -91,6 +97,8 @@ gimp_selection_tool_class_init (GimpSelectionToolClass *klass)
tool_class->key_press = gimp_edit_selection_tool_key_press;
tool_class->oper_update = gimp_selection_tool_oper_update;
tool_class->cursor_update = gimp_selection_tool_cursor_update;
+
+ klass->have_selection = gimp_selection_tool_real_have_selection;
}
static void
@@ -210,18 +218,16 @@ gimp_selection_tool_oper_update (GimpTool *tool,
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
GimpImage *image;
- GimpChannel *selection;
GimpDrawable *drawable;
GimpLayer *layer;
GimpLayer *floating_sel;
GdkModifierType extend_mask;
GdkModifierType modify_mask;
+ gboolean have_selection;
gboolean move_layer = FALSE;
gboolean move_floating_sel = FALSE;
- gboolean selection_empty;
image = gimp_display_get_image (display);
- selection = gimp_image_get_mask (image);
drawable = gimp_image_get_active_drawable (image);
layer = gimp_image_pick_layer (image, coords->x, coords->y, NULL);
floating_sel = gimp_image_get_floating_selection (image);
@@ -229,6 +235,8 @@ gimp_selection_tool_oper_update (GimpTool *tool,
extend_mask = gimp_get_extend_selection_mask ();
modify_mask = gimp_get_modify_selection_mask ();
+ have_selection = gimp_selection_tool_have_selection (selection_tool, display);
+
if (drawable)
{
if (floating_sel)
@@ -236,15 +244,14 @@ gimp_selection_tool_oper_update (GimpTool *tool,
if (layer == floating_sel)
move_floating_sel = TRUE;
}
- else if (gimp_item_mask_intersect (GIMP_ITEM (drawable),
+ else if (have_selection &&
+ gimp_item_mask_intersect (GIMP_ITEM (drawable),
NULL, NULL, NULL, NULL))
{
move_layer = TRUE;
}
}
- selection_empty = gimp_channel_is_empty (selection);
-
selection_tool->function = SELECTION_SELECT;
if (selection_tool->allow_move &&
@@ -260,7 +267,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
selection_tool->function = SELECTION_MOVE_COPY;
}
else if (selection_tool->allow_move &&
- (state & GDK_MOD1_MASK) && ! selection_empty)
+ (state & GDK_MOD1_MASK) && have_selection)
{
/* move the selection mask */
selection_tool->function = SELECTION_MOVE_MASK;
@@ -291,7 +298,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
gboolean free_status = FALSE;
GdkModifierType modifiers = (extend_mask | modify_mask);
- if (! selection_empty)
+ if (have_selection)
modifiers |= GDK_MOD1_MASK;
switch (selection_tool->function)
@@ -300,7 +307,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
switch (options->operation)
{
case GIMP_CHANNEL_OP_REPLACE:
- if (! selection_empty)
+ if (have_selection)
{
status = gimp_suggest_modifiers (_("Click-Drag to replace the "
"current selection"),
@@ -439,6 +446,16 @@ gimp_selection_tool_cursor_update (GimpTool *tool,
modifier);
}
+static gboolean
+gimp_selection_tool_real_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display)
+{
+ GimpImage *image = gimp_display_get_image (display);
+ GimpChannel *selection = gimp_image_get_mask (image);
+
+ return ! gimp_channel_is_empty (selection);
+}
+
static void
gimp_selection_tool_commit (GimpSelectionTool *sel_tool)
{
@@ -550,6 +567,14 @@ gimp_selection_tool_check (GimpSelectionTool *sel_tool,
return TRUE;
}
+static gboolean
+gimp_selection_tool_have_selection (GimpSelectionTool *sel_tool,
+ GimpDisplay *display)
+{
+ return GIMP_SELECTION_TOOL_GET_CLASS (sel_tool)->have_selection (sel_tool,
+ display);
+}
+
static void
gimp_selection_tool_set_undo_ptr (GimpUndo **undo_ptr,
GimpUndo *undo)
diff --git a/app/tools/gimpselectiontool.h b/app/tools/gimpselectiontool.h
index e56db3c679..077605691c 100644
--- a/app/tools/gimpselectiontool.h
+++ b/app/tools/gimpselectiontool.h
@@ -54,6 +54,10 @@ struct _GimpSelectionTool
struct _GimpSelectionToolClass
{
GimpDrawToolClass parent_class;
+
+ /* virtual functions */
+ gboolean (* have_selection) (GimpSelectionTool *sel_tool,
+ GimpDisplay *display);
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]