From e7d219d3871f5c24e0ec7ebccde5bdac26cc73f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Mon, 10 Jan 2011 14:55:38 +0100 Subject: [PATCH] Cage tool: add rubber band selection for deform mode --- app/gegl/gimpcageconfig.c | 63 ++++++++++++++++++++++++++++++++++++++- app/gegl/gimpcageconfig.h | 8 ++++- app/tools/gimpcagetool.c | 43 ++++++++++++++++++++++++++ app/tools/gimpcagetool.h | 3 ++ 4 files changed, 115 insertions(+), 2 deletions(-) diff --git a/app/gegl/gimpcageconfig.c b/app/gegl/gimpcageconfig.c index c61b8051c2..723530b4ba 100644 --- a/app/gegl/gimpcageconfig.c +++ b/app/gegl/gimpcageconfig.c @@ -591,6 +591,67 @@ gimp_cage_config_select_point (GimpCageConfig *gcc, } } +/** + * gimp_cage_config_select_area: + * @gcc: the cage config + * @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM + * @area: the area to select + * + * Select cage's point inside the given area and deselect others + */ +void +gimp_cage_config_select_area (GimpCageConfig *gcc, + GimpCageMode mode, + GeglRectangle area) +{ + g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc)); + + gimp_cage_config_deselect_points (gcc); + gimp_cage_config_select_add_area (gcc, mode, area); +} + +/** + * gimp_cage_config_select_add_area: + * @gcc: the cage config + * @mode: the actual mode of the cage, GIMP_CAGE_MODE_CAGE_CHANGE or GIMP_CAGE_MODE_DEFORM + * @area: the area to select + * + * Select cage's point inside the given area. Already selected point stay selected. + */ +void +gimp_cage_config_select_add_area (GimpCageConfig *gcc, + GimpCageMode mode, + GeglRectangle area) +{ + gint i; + + g_return_if_fail (GIMP_IS_CAGE_CONFIG (gcc)); + + for (i = 0; i < gcc->n_cage_vertices; i++) + { + if (mode == GIMP_CAGE_MODE_CAGE_CHANGE) + { + if (gcc->cage_points[i].src_point.x >= area.x && + gcc->cage_points[i].src_point.x <= area.x + area.width && + gcc->cage_points[i].src_point.y >= area.y && + gcc->cage_points[i].src_point.y <= area.y + area.height) + { + gcc->cage_points[i].selected = TRUE; + } + } + else + { + if (gcc->cage_points[i].dest_point.x >= area.x && + gcc->cage_points[i].dest_point.x <= area.x + area.width && + gcc->cage_points[i].dest_point.y >= area.y && + gcc->cage_points[i].dest_point.y <= area.y + area.height) + { + gcc->cage_points[i].selected = TRUE; + } + } + } +} + /** * gimp_cage_config_toggle_point_selection: * @gcc: the cage config @@ -616,7 +677,7 @@ gimp_cage_config_toggle_point_selection (GimpCageConfig *gcc, * Deselect all cage points. */ void -gimp_cage_deselect_points (GimpCageConfig *gcc) +gimp_cage_config_deselect_points (GimpCageConfig *gcc) { gint i; diff --git a/app/gegl/gimpcageconfig.h b/app/gegl/gimpcageconfig.h index f26f493863..42812c9be7 100644 --- a/app/gegl/gimpcageconfig.h +++ b/app/gegl/gimpcageconfig.h @@ -76,8 +76,14 @@ gboolean gimp_cage_config_point_inside (GimpCageConfig *gcc, gfloat y); void gimp_cage_config_select_point (GimpCageConfig *gcc, gint point_number); +void gimp_cage_config_select_area (GimpCageConfig *gcc, + GimpCageMode mode, + GeglRectangle area); +void gimp_cage_config_select_add_area (GimpCageConfig *gcc, + GimpCageMode mode, + GeglRectangle area); void gimp_cage_config_toggle_point_selection (GimpCageConfig *gcc, gint point_number); -void gimp_cage_deselect_points (GimpCageConfig *gcc); +void gimp_cage_config_deselect_points (GimpCageConfig *gcc); #endif /* __GIMP_CAGE_CONFIG_H__ */ diff --git a/app/tools/gimpcagetool.c b/app/tools/gimpcagetool.c index ba97ac409c..d10be25174 100644 --- a/app/tools/gimpcagetool.c +++ b/app/tools/gimpcagetool.c @@ -20,6 +20,7 @@ #include "config.h" #include +#include #include #include @@ -132,6 +133,7 @@ enum CAGE_STATE_CLOSING, DEFORM_STATE_WAIT, DEFORM_STATE_MOVE_HANDLE, + DEFORM_STATE_SELECTING }; void @@ -469,6 +471,13 @@ gimp_cage_tool_button_press (GimpTool *tool, break; case DEFORM_STATE_WAIT: + if (handle == -1) + /* User clicked on the background, we start a rubber band selection */ + { + ct->selection_start_x = coords->x; + ct->selection_start_y = coords->y; + ct->tool_state = DEFORM_STATE_SELECTING; + } if (handle >= 0) /* User clicked on a handle, so we move it */ { @@ -521,6 +530,10 @@ gimp_cage_tool_button_release (GimpTool *tool, gimp_cage_tool_image_map_update (ct); ct->tool_state = DEFORM_STATE_WAIT; break; + + case DEFORM_STATE_SELECTING: + ct->tool_state = DEFORM_STATE_WAIT; + break; } gimp_cage_config_reset_displacement (ct->config); } @@ -541,6 +554,26 @@ gimp_cage_tool_button_release (GimpTool *tool, ct->tool_state = DEFORM_STATE_WAIT; gimp_cage_tool_image_map_update (ct); break; + + case DEFORM_STATE_SELECTING: + { + GeglRectangle area = {MIN(ct->selection_start_x, coords->x), + MIN(ct->selection_start_y, coords->y), + abs (ct->selection_start_x - coords->x), + abs (ct->selection_start_y - coords->y)}; + + if (state & GDK_SHIFT_MASK) + { + gimp_cage_config_select_add_area (ct->config, GIMP_CAGE_MODE_DEFORM, area); + } + else + { + gimp_cage_config_select_area (ct->config, GIMP_CAGE_MODE_DEFORM, area); + } + ct->tool_state = DEFORM_STATE_WAIT; + } + break; + } gimp_cage_config_commit_displacement (ct->config); } @@ -669,6 +702,16 @@ gimp_cage_tool_draw (GimpDrawTool *draw_tool) GIMP_HANDLE_ANCHOR_CENTER); } } + + if (ct->tool_state == DEFORM_STATE_SELECTING) + { + gimp_draw_tool_add_rectangle (draw_tool, + FALSE, + MIN(ct->selection_start_x, ct->cursor_x), + MIN(ct->selection_start_y, ct->cursor_y), + abs (ct->selection_start_x - ct->cursor_x), + abs (ct->selection_start_y - ct->cursor_y)); + } } static gint diff --git a/app/tools/gimpcagetool.h b/app/tools/gimpcagetool.h index bc35fb0b54..3ea6f60a96 100644 --- a/app/tools/gimpcagetool.h +++ b/app/tools/gimpcagetool.h @@ -53,6 +53,9 @@ struct _GimpCageTool gdouble movement_start_x; /* Where the movement started */ gdouble movement_start_y; /* Where the movement started */ + gdouble selection_start_x; /* Where the selection started */ + gdouble selection_start_y; /* Where the selection started */ + gint hovering_handle; /* Handle which the cursor is above */ gboolean cage_complete; /* Cage closed or not */