From 90043461797226572e3646e77f3bd82706578cad Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Wed, 1 Mar 2000 23:22:43 +0000 Subject: [PATCH] added a modifier_key_func which gives immediate cursor_update feedback on 2000-03-02 Michael Natterer * app/rect_select.[ch]: added a modifier_key_func which gives immediate cursor_update feedback on modifier key events. * app/ellipse_select.c * app/free_select.c * app/fuzzy_select.c * app/rect_selectP.h: call the new function. Added current_[x|y] fields to the tools' structures which get updated from the "motion" functions. They have to appear in the same order in all structures because the modifier_key_func treats them all as rectangular selection tools. This is ugly and cries for a object hierarchy of tools. --- ChangeLog | 15 +++++++ app/ellipse_select.c | 1 + app/free_select.c | 22 ++++++++--- app/fuzzy_select.c | 25 ++++++++---- app/rect_select.c | 66 ++++++++++++++++++++++++++----- app/rect_select.h | 13 +++--- app/rect_selectP.h | 40 ++++++++++++++----- app/tools/ellipse_select.c | 1 + app/tools/free_select.c | 22 ++++++++--- app/tools/fuzzy_select.c | 25 ++++++++---- app/tools/gimpellipseselecttool.c | 1 + app/tools/gimpfreeselecttool.c | 22 ++++++++--- app/tools/gimpfuzzyselecttool.c | 25 ++++++++---- app/tools/gimprectselecttool.c | 66 ++++++++++++++++++++++++++----- app/tools/gimprectselecttool.h | 13 +++--- app/tools/gimpregionselecttool.c | 25 ++++++++---- app/tools/rect_select.c | 66 ++++++++++++++++++++++++++----- app/tools/rect_select.h | 13 +++--- app/tools/rect_selectP.h | 40 ++++++++++++++----- 19 files changed, 388 insertions(+), 113 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc2ea839c7..74198b940b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2000-03-02 Michael Natterer + + * app/rect_select.[ch]: added a modifier_key_func which gives + immediate cursor_update feedback on modifier key events. + + * app/ellipse_select.c + * app/free_select.c + * app/fuzzy_select.c + * app/rect_selectP.h: call the new function. + Added current_[x|y] fields to the tools' structures which get + updated from the "motion" functions. They have to appear in the + same order in all structures because the modifier_key_func treats + them all as rectangular selection tools. + This is ugly and cries for a object hierarchy of tools. + 2000-03-01 Michael Natterer * app/gimpdrawable.c: gimp_drawable_get_color_at(): put the check diff --git a/app/ellipse_select.c b/app/ellipse_select.c index c9324d0a03..0ba91cbd31 100644 --- a/app/ellipse_select.c +++ b/app/ellipse_select.c @@ -133,6 +133,7 @@ tools_new_ellipse_select (void) tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/free_select.c b/app/free_select.c index 3a1aa07d8a..18a4f9bdec 100644 --- a/app/free_select.c +++ b/app/free_select.c @@ -39,10 +39,15 @@ typedef struct _FreeSelect FreeSelect; struct _FreeSelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ - int num_pts; /* Number of points in the polygon */ + gint op; /* selection operation (ADD, SUB, etc) */ + + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint num_pts; /* Number of points in the polygon */ }; @@ -224,12 +229,16 @@ free_select_motion (Tool *tool, FreeSelect *free_sel; GDisplay *gdisp; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; free_sel = (FreeSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + free_sel->current_x = mevent->x; + free_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + if (add_point (free_sel->num_pts, mevent->x, mevent->y)) { gdk_draw_line (free_sel->core->win, free_sel->core->gc, @@ -318,6 +327,7 @@ tools_new_free_select (void) tool->button_press_func = free_select_button_press; tool->button_release_func = free_select_button_release; tool->motion_func = free_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = free_select_control; diff --git a/app/fuzzy_select.c b/app/fuzzy_select.c index dda726d327..a4195d4bd8 100644 --- a/app/fuzzy_select.c +++ b/app/fuzzy_select.c @@ -40,14 +40,18 @@ typedef struct _FuzzySelect FuzzySelect; struct _FuzzySelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ + gint op; /* selection operation (ADD, SUB, etc) */ - int x, y; /* Point from which to execute seed fill */ - int first_x; /* */ - int first_y; /* variables to keep track of sensitivity */ - double first_threshold; /* initial value of threshold slider */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint x, y; /* Point from which to execute seed fill */ + gint first_x; /* */ + gint first_y; /* variables to keep track of sensitivity */ + gdouble first_threshold; /* initial value of threshold slider */ }; @@ -472,6 +476,12 @@ fuzzy_select_motion (Tool *tool, static guint last_time = 0; + fuzzy_sel = (FuzzySelect *) tool->private; + + /* needed for immediate cursor update on modifier event */ + fuzzy_sel->current_x = mevent->x; + fuzzy_sel->current_y = mevent->y; + if (tool->state != ACTIVE) return; @@ -481,8 +491,6 @@ fuzzy_select_motion (Tool *tool, last_time = mevent->time; - fuzzy_sel = (FuzzySelect *) tool->private; - diff_x = mevent->x - fuzzy_sel->first_x; diff_y = mevent->y - fuzzy_sel->first_y; @@ -692,6 +700,7 @@ tools_new_fuzzy_select () tool->button_press_func = fuzzy_select_button_press; tool->button_release_func = fuzzy_select_button_release; tool->motion_func = fuzzy_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = fuzzy_select_control; diff --git a/app/rect_select.c b/app/rect_select.c index 41580ef877..c5b50ec0ac 100644 --- a/app/rect_select.c +++ b/app/rect_select.c @@ -41,8 +41,11 @@ static SelectionOptions *rect_options = NULL; extern SelectionOptions *ellipse_options; extern void ellipse_select (GImage *, int, int, int, int, int, int, int, double); -static void selection_tool_update_op_state(RectSelect *rect_sel, int x, int y, - int state, GDisplay *gdisp); +static void selection_tool_update_op_state (RectSelect *rect_sel, + gint x, + gint y, + gint state, + GDisplay *gdisp); /*************************************/ /* Rectangular selection apparatus */ @@ -285,12 +288,16 @@ rect_select_motion (Tool *tool, int tw, th; double ratio; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; rect_sel = (RectSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + rect_sel->current_x = mevent->x; + rect_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + draw_core_pause (rect_sel->core, tool); /* Calculate starting point */ @@ -456,9 +463,9 @@ rect_select_draw (Tool *tool) static void selection_tool_update_op_state (RectSelect *rect_sel, - int x, - int y, - int state, + gint x, + gint y, + gint state, GDisplay *gdisp) { if (active_tool->state == ACTIVE) @@ -491,11 +498,51 @@ rect_select_oper_update (Tool *tool, { RectSelect *rect_sel; - rect_sel = (RectSelect*)tool->private; + rect_sel = (RectSelect *) tool->private; selection_tool_update_op_state (rect_sel, mevent->x, mevent->y, mevent->state, gdisp_ptr); } +void +rect_select_modifier_update (Tool *tool, + GdkEventKey *kevent, + gpointer gdisp_ptr) +{ + RectSelect *rect_sel; + gint state; + + state = kevent->state; + + switch (kevent->keyval) + { + case GDK_Alt_L: case GDK_Alt_R: + if (state & GDK_MOD1_MASK) + state &= ~GDK_MOD1_MASK; + else + state |= GDK_MOD1_MASK; + break; + + case GDK_Shift_L: case GDK_Shift_R: + if (state & GDK_SHIFT_MASK) + state &= ~GDK_SHIFT_MASK; + else + state |= GDK_SHIFT_MASK; + break; + + case GDK_Control_L: case GDK_Control_R: + if (state & GDK_CONTROL_MASK) + state &= ~GDK_CONTROL_MASK; + else + state |= GDK_CONTROL_MASK; + break; + } + + rect_sel = (RectSelect *) tool->private; + selection_tool_update_op_state (rect_sel, + rect_sel->current_x, rect_sel->current_y, + state, gdisp_ptr); +} + void rect_select_cursor_update (Tool *tool, GdkEventMotion *mevent, @@ -591,6 +638,7 @@ tools_new_rect_select () tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/rect_select.h b/app/rect_select.h index d2491e73cf..9a22a79286 100644 --- a/app/rect_select.h +++ b/app/rect_select.h @@ -22,12 +22,13 @@ #include "tools.h" /* rect select action functions */ -void rect_select_button_press (Tool *, GdkEventButton *, gpointer); -void rect_select_button_release (Tool *, GdkEventButton *, gpointer); -void rect_select_motion (Tool *, GdkEventMotion *, gpointer); -void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_control (Tool *, ToolAction, gpointer); +void rect_select_button_press (Tool *, GdkEventButton *, gpointer); +void rect_select_button_release (Tool *, GdkEventButton *, gpointer); +void rect_select_motion (Tool *, GdkEventMotion *, gpointer); +void rect_select_modifier_update (Tool *, GdkEventKey * , gpointer); +void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_control (Tool *, ToolAction, gpointer); /* rect select functions */ void rect_select_draw (Tool *); diff --git a/app/rect_selectP.h b/app/rect_selectP.h index 91d888376a..31b3a84bb8 100644 --- a/app/rect_selectP.h +++ b/app/rect_selectP.h @@ -1,3 +1,20 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef __RECT_SELECTP_H__ #define __RECT_SELECTP_H__ @@ -7,18 +24,23 @@ typedef struct _RectSelect RectSelect, EllipseSelect; struct _RectSelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - SelectOps op; /* selection operation (SELECTION_ADD etc.) */ + SelectOps op; /* selection operation (SELECTION_ADD etc.) */ - int x, y; /* upper left hand coordinate */ - int w, h; /* width and height */ - int center; /* is the selection being created from the center out? */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ - int fixed_size; - double fixed_width; - double fixed_height; - guint context_id; /* for the statusbar */ + gint x, y; /* upper left hand coordinate */ + gint w, h; /* width and height */ + gint center; /* is the selection being created from the + * center out? */ + + gint fixed_size; + gdouble fixed_width; + gdouble fixed_height; + guint context_id; /* for the statusbar */ }; #endif /* __RECT_SELECTP_H__ */ diff --git a/app/tools/ellipse_select.c b/app/tools/ellipse_select.c index c9324d0a03..0ba91cbd31 100644 --- a/app/tools/ellipse_select.c +++ b/app/tools/ellipse_select.c @@ -133,6 +133,7 @@ tools_new_ellipse_select (void) tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/tools/free_select.c b/app/tools/free_select.c index 3a1aa07d8a..18a4f9bdec 100644 --- a/app/tools/free_select.c +++ b/app/tools/free_select.c @@ -39,10 +39,15 @@ typedef struct _FreeSelect FreeSelect; struct _FreeSelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ - int num_pts; /* Number of points in the polygon */ + gint op; /* selection operation (ADD, SUB, etc) */ + + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint num_pts; /* Number of points in the polygon */ }; @@ -224,12 +229,16 @@ free_select_motion (Tool *tool, FreeSelect *free_sel; GDisplay *gdisp; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; free_sel = (FreeSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + free_sel->current_x = mevent->x; + free_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + if (add_point (free_sel->num_pts, mevent->x, mevent->y)) { gdk_draw_line (free_sel->core->win, free_sel->core->gc, @@ -318,6 +327,7 @@ tools_new_free_select (void) tool->button_press_func = free_select_button_press; tool->button_release_func = free_select_button_release; tool->motion_func = free_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = free_select_control; diff --git a/app/tools/fuzzy_select.c b/app/tools/fuzzy_select.c index dda726d327..a4195d4bd8 100644 --- a/app/tools/fuzzy_select.c +++ b/app/tools/fuzzy_select.c @@ -40,14 +40,18 @@ typedef struct _FuzzySelect FuzzySelect; struct _FuzzySelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ + gint op; /* selection operation (ADD, SUB, etc) */ - int x, y; /* Point from which to execute seed fill */ - int first_x; /* */ - int first_y; /* variables to keep track of sensitivity */ - double first_threshold; /* initial value of threshold slider */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint x, y; /* Point from which to execute seed fill */ + gint first_x; /* */ + gint first_y; /* variables to keep track of sensitivity */ + gdouble first_threshold; /* initial value of threshold slider */ }; @@ -472,6 +476,12 @@ fuzzy_select_motion (Tool *tool, static guint last_time = 0; + fuzzy_sel = (FuzzySelect *) tool->private; + + /* needed for immediate cursor update on modifier event */ + fuzzy_sel->current_x = mevent->x; + fuzzy_sel->current_y = mevent->y; + if (tool->state != ACTIVE) return; @@ -481,8 +491,6 @@ fuzzy_select_motion (Tool *tool, last_time = mevent->time; - fuzzy_sel = (FuzzySelect *) tool->private; - diff_x = mevent->x - fuzzy_sel->first_x; diff_y = mevent->y - fuzzy_sel->first_y; @@ -692,6 +700,7 @@ tools_new_fuzzy_select () tool->button_press_func = fuzzy_select_button_press; tool->button_release_func = fuzzy_select_button_release; tool->motion_func = fuzzy_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = fuzzy_select_control; diff --git a/app/tools/gimpellipseselecttool.c b/app/tools/gimpellipseselecttool.c index c9324d0a03..0ba91cbd31 100644 --- a/app/tools/gimpellipseselecttool.c +++ b/app/tools/gimpellipseselecttool.c @@ -133,6 +133,7 @@ tools_new_ellipse_select (void) tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/tools/gimpfreeselecttool.c b/app/tools/gimpfreeselecttool.c index 3a1aa07d8a..18a4f9bdec 100644 --- a/app/tools/gimpfreeselecttool.c +++ b/app/tools/gimpfreeselecttool.c @@ -39,10 +39,15 @@ typedef struct _FreeSelect FreeSelect; struct _FreeSelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ - int num_pts; /* Number of points in the polygon */ + gint op; /* selection operation (ADD, SUB, etc) */ + + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint num_pts; /* Number of points in the polygon */ }; @@ -224,12 +229,16 @@ free_select_motion (Tool *tool, FreeSelect *free_sel; GDisplay *gdisp; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; free_sel = (FreeSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + free_sel->current_x = mevent->x; + free_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + if (add_point (free_sel->num_pts, mevent->x, mevent->y)) { gdk_draw_line (free_sel->core->win, free_sel->core->gc, @@ -318,6 +327,7 @@ tools_new_free_select (void) tool->button_press_func = free_select_button_press; tool->button_release_func = free_select_button_release; tool->motion_func = free_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = free_select_control; diff --git a/app/tools/gimpfuzzyselecttool.c b/app/tools/gimpfuzzyselecttool.c index dda726d327..a4195d4bd8 100644 --- a/app/tools/gimpfuzzyselecttool.c +++ b/app/tools/gimpfuzzyselecttool.c @@ -40,14 +40,18 @@ typedef struct _FuzzySelect FuzzySelect; struct _FuzzySelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ + gint op; /* selection operation (ADD, SUB, etc) */ - int x, y; /* Point from which to execute seed fill */ - int first_x; /* */ - int first_y; /* variables to keep track of sensitivity */ - double first_threshold; /* initial value of threshold slider */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint x, y; /* Point from which to execute seed fill */ + gint first_x; /* */ + gint first_y; /* variables to keep track of sensitivity */ + gdouble first_threshold; /* initial value of threshold slider */ }; @@ -472,6 +476,12 @@ fuzzy_select_motion (Tool *tool, static guint last_time = 0; + fuzzy_sel = (FuzzySelect *) tool->private; + + /* needed for immediate cursor update on modifier event */ + fuzzy_sel->current_x = mevent->x; + fuzzy_sel->current_y = mevent->y; + if (tool->state != ACTIVE) return; @@ -481,8 +491,6 @@ fuzzy_select_motion (Tool *tool, last_time = mevent->time; - fuzzy_sel = (FuzzySelect *) tool->private; - diff_x = mevent->x - fuzzy_sel->first_x; diff_y = mevent->y - fuzzy_sel->first_y; @@ -692,6 +700,7 @@ tools_new_fuzzy_select () tool->button_press_func = fuzzy_select_button_press; tool->button_release_func = fuzzy_select_button_release; tool->motion_func = fuzzy_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = fuzzy_select_control; diff --git a/app/tools/gimprectselecttool.c b/app/tools/gimprectselecttool.c index 41580ef877..c5b50ec0ac 100644 --- a/app/tools/gimprectselecttool.c +++ b/app/tools/gimprectselecttool.c @@ -41,8 +41,11 @@ static SelectionOptions *rect_options = NULL; extern SelectionOptions *ellipse_options; extern void ellipse_select (GImage *, int, int, int, int, int, int, int, double); -static void selection_tool_update_op_state(RectSelect *rect_sel, int x, int y, - int state, GDisplay *gdisp); +static void selection_tool_update_op_state (RectSelect *rect_sel, + gint x, + gint y, + gint state, + GDisplay *gdisp); /*************************************/ /* Rectangular selection apparatus */ @@ -285,12 +288,16 @@ rect_select_motion (Tool *tool, int tw, th; double ratio; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; rect_sel = (RectSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + rect_sel->current_x = mevent->x; + rect_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + draw_core_pause (rect_sel->core, tool); /* Calculate starting point */ @@ -456,9 +463,9 @@ rect_select_draw (Tool *tool) static void selection_tool_update_op_state (RectSelect *rect_sel, - int x, - int y, - int state, + gint x, + gint y, + gint state, GDisplay *gdisp) { if (active_tool->state == ACTIVE) @@ -491,11 +498,51 @@ rect_select_oper_update (Tool *tool, { RectSelect *rect_sel; - rect_sel = (RectSelect*)tool->private; + rect_sel = (RectSelect *) tool->private; selection_tool_update_op_state (rect_sel, mevent->x, mevent->y, mevent->state, gdisp_ptr); } +void +rect_select_modifier_update (Tool *tool, + GdkEventKey *kevent, + gpointer gdisp_ptr) +{ + RectSelect *rect_sel; + gint state; + + state = kevent->state; + + switch (kevent->keyval) + { + case GDK_Alt_L: case GDK_Alt_R: + if (state & GDK_MOD1_MASK) + state &= ~GDK_MOD1_MASK; + else + state |= GDK_MOD1_MASK; + break; + + case GDK_Shift_L: case GDK_Shift_R: + if (state & GDK_SHIFT_MASK) + state &= ~GDK_SHIFT_MASK; + else + state |= GDK_SHIFT_MASK; + break; + + case GDK_Control_L: case GDK_Control_R: + if (state & GDK_CONTROL_MASK) + state &= ~GDK_CONTROL_MASK; + else + state |= GDK_CONTROL_MASK; + break; + } + + rect_sel = (RectSelect *) tool->private; + selection_tool_update_op_state (rect_sel, + rect_sel->current_x, rect_sel->current_y, + state, gdisp_ptr); +} + void rect_select_cursor_update (Tool *tool, GdkEventMotion *mevent, @@ -591,6 +638,7 @@ tools_new_rect_select () tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/tools/gimprectselecttool.h b/app/tools/gimprectselecttool.h index d2491e73cf..9a22a79286 100644 --- a/app/tools/gimprectselecttool.h +++ b/app/tools/gimprectselecttool.h @@ -22,12 +22,13 @@ #include "tools.h" /* rect select action functions */ -void rect_select_button_press (Tool *, GdkEventButton *, gpointer); -void rect_select_button_release (Tool *, GdkEventButton *, gpointer); -void rect_select_motion (Tool *, GdkEventMotion *, gpointer); -void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_control (Tool *, ToolAction, gpointer); +void rect_select_button_press (Tool *, GdkEventButton *, gpointer); +void rect_select_button_release (Tool *, GdkEventButton *, gpointer); +void rect_select_motion (Tool *, GdkEventMotion *, gpointer); +void rect_select_modifier_update (Tool *, GdkEventKey * , gpointer); +void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_control (Tool *, ToolAction, gpointer); /* rect select functions */ void rect_select_draw (Tool *); diff --git a/app/tools/gimpregionselecttool.c b/app/tools/gimpregionselecttool.c index dda726d327..a4195d4bd8 100644 --- a/app/tools/gimpregionselecttool.c +++ b/app/tools/gimpregionselecttool.c @@ -40,14 +40,18 @@ typedef struct _FuzzySelect FuzzySelect; struct _FuzzySelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - int op; /* selection operation (ADD, SUB, etc) */ + gint op; /* selection operation (ADD, SUB, etc) */ - int x, y; /* Point from which to execute seed fill */ - int first_x; /* */ - int first_y; /* variables to keep track of sensitivity */ - double first_threshold; /* initial value of threshold slider */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ + + gint x, y; /* Point from which to execute seed fill */ + gint first_x; /* */ + gint first_y; /* variables to keep track of sensitivity */ + gdouble first_threshold; /* initial value of threshold slider */ }; @@ -472,6 +476,12 @@ fuzzy_select_motion (Tool *tool, static guint last_time = 0; + fuzzy_sel = (FuzzySelect *) tool->private; + + /* needed for immediate cursor update on modifier event */ + fuzzy_sel->current_x = mevent->x; + fuzzy_sel->current_y = mevent->y; + if (tool->state != ACTIVE) return; @@ -481,8 +491,6 @@ fuzzy_select_motion (Tool *tool, last_time = mevent->time; - fuzzy_sel = (FuzzySelect *) tool->private; - diff_x = mevent->x - fuzzy_sel->first_x; diff_y = mevent->y - fuzzy_sel->first_y; @@ -692,6 +700,7 @@ tools_new_fuzzy_select () tool->button_press_func = fuzzy_select_button_press; tool->button_release_func = fuzzy_select_button_release; tool->motion_func = fuzzy_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = fuzzy_select_control; diff --git a/app/tools/rect_select.c b/app/tools/rect_select.c index 41580ef877..c5b50ec0ac 100644 --- a/app/tools/rect_select.c +++ b/app/tools/rect_select.c @@ -41,8 +41,11 @@ static SelectionOptions *rect_options = NULL; extern SelectionOptions *ellipse_options; extern void ellipse_select (GImage *, int, int, int, int, int, int, int, double); -static void selection_tool_update_op_state(RectSelect *rect_sel, int x, int y, - int state, GDisplay *gdisp); +static void selection_tool_update_op_state (RectSelect *rect_sel, + gint x, + gint y, + gint state, + GDisplay *gdisp); /*************************************/ /* Rectangular selection apparatus */ @@ -285,12 +288,16 @@ rect_select_motion (Tool *tool, int tw, th; double ratio; - if (tool->state != ACTIVE) - return; - gdisp = (GDisplay *) gdisp_ptr; rect_sel = (RectSelect *) tool->private; + /* needed for immediate cursor update on modifier event */ + rect_sel->current_x = mevent->x; + rect_sel->current_y = mevent->y; + + if (tool->state != ACTIVE) + return; + draw_core_pause (rect_sel->core, tool); /* Calculate starting point */ @@ -456,9 +463,9 @@ rect_select_draw (Tool *tool) static void selection_tool_update_op_state (RectSelect *rect_sel, - int x, - int y, - int state, + gint x, + gint y, + gint state, GDisplay *gdisp) { if (active_tool->state == ACTIVE) @@ -491,11 +498,51 @@ rect_select_oper_update (Tool *tool, { RectSelect *rect_sel; - rect_sel = (RectSelect*)tool->private; + rect_sel = (RectSelect *) tool->private; selection_tool_update_op_state (rect_sel, mevent->x, mevent->y, mevent->state, gdisp_ptr); } +void +rect_select_modifier_update (Tool *tool, + GdkEventKey *kevent, + gpointer gdisp_ptr) +{ + RectSelect *rect_sel; + gint state; + + state = kevent->state; + + switch (kevent->keyval) + { + case GDK_Alt_L: case GDK_Alt_R: + if (state & GDK_MOD1_MASK) + state &= ~GDK_MOD1_MASK; + else + state |= GDK_MOD1_MASK; + break; + + case GDK_Shift_L: case GDK_Shift_R: + if (state & GDK_SHIFT_MASK) + state &= ~GDK_SHIFT_MASK; + else + state |= GDK_SHIFT_MASK; + break; + + case GDK_Control_L: case GDK_Control_R: + if (state & GDK_CONTROL_MASK) + state &= ~GDK_CONTROL_MASK; + else + state |= GDK_CONTROL_MASK; + break; + } + + rect_sel = (RectSelect *) tool->private; + selection_tool_update_op_state (rect_sel, + rect_sel->current_x, rect_sel->current_y, + state, gdisp_ptr); +} + void rect_select_cursor_update (Tool *tool, GdkEventMotion *mevent, @@ -591,6 +638,7 @@ tools_new_rect_select () tool->button_press_func = rect_select_button_press; tool->button_release_func = rect_select_button_release; tool->motion_func = rect_select_motion; + tool->modifier_key_func = rect_select_modifier_update; tool->cursor_update_func = rect_select_cursor_update; tool->oper_update_func = rect_select_oper_update; tool->control_func = rect_select_control; diff --git a/app/tools/rect_select.h b/app/tools/rect_select.h index d2491e73cf..9a22a79286 100644 --- a/app/tools/rect_select.h +++ b/app/tools/rect_select.h @@ -22,12 +22,13 @@ #include "tools.h" /* rect select action functions */ -void rect_select_button_press (Tool *, GdkEventButton *, gpointer); -void rect_select_button_release (Tool *, GdkEventButton *, gpointer); -void rect_select_motion (Tool *, GdkEventMotion *, gpointer); -void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); -void rect_select_control (Tool *, ToolAction, gpointer); +void rect_select_button_press (Tool *, GdkEventButton *, gpointer); +void rect_select_button_release (Tool *, GdkEventButton *, gpointer); +void rect_select_motion (Tool *, GdkEventMotion *, gpointer); +void rect_select_modifier_update (Tool *, GdkEventKey * , gpointer); +void rect_select_cursor_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_oper_update (Tool *, GdkEventMotion *, gpointer); +void rect_select_control (Tool *, ToolAction, gpointer); /* rect select functions */ void rect_select_draw (Tool *); diff --git a/app/tools/rect_selectP.h b/app/tools/rect_selectP.h index 91d888376a..31b3a84bb8 100644 --- a/app/tools/rect_selectP.h +++ b/app/tools/rect_selectP.h @@ -1,3 +1,20 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifndef __RECT_SELECTP_H__ #define __RECT_SELECTP_H__ @@ -7,18 +24,23 @@ typedef struct _RectSelect RectSelect, EllipseSelect; struct _RectSelect { - DrawCore * core; /* Core select object */ + DrawCore *core; /* Core select object */ - SelectOps op; /* selection operation (SELECTION_ADD etc.) */ + SelectOps op; /* selection operation (SELECTION_ADD etc.) */ - int x, y; /* upper left hand coordinate */ - int w, h; /* width and height */ - int center; /* is the selection being created from the center out? */ + gint current_x; /* these values are updated on every motion event */ + gint current_y; /* (enables immediate cursor updating on modifier + * key events). */ - int fixed_size; - double fixed_width; - double fixed_height; - guint context_id; /* for the statusbar */ + gint x, y; /* upper left hand coordinate */ + gint w, h; /* width and height */ + gint center; /* is the selection being created from the + * center out? */ + + gint fixed_size; + gdouble fixed_width; + gdouble fixed_height; + guint context_id; /* for the statusbar */ }; #endif /* __RECT_SELECTP_H__ */