Bill Skaggs <weskaggs@primate.ucdavis.edu>

* app/tools/gimpnewrectselecttool.[ch]
	* app/tools/gimprectangletool.[ch]: more work on rectangle
	tool ui.
This commit is contained in:
William Skaggs 2005-04-09 18:08:47 +00:00
parent 053a1913b2
commit b41d8898e9
7 changed files with 336 additions and 101 deletions

View File

@ -1,3 +1,9 @@
2005-04-09 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* app/tools/gimpnewrectselecttool.[ch]
* app/tools/gimprectangletool.[ch]: more work on rectangle
tool ui.
2005-04-09 Michael Natterer <mitch@gimp.org>
Implement dragging and dropping in any GdkPixbuf supported format.
@ -44,7 +50,7 @@
* app/display/gimpdisplayshell-dnd.c: allow dropping of pixbufs.
2005-04-10 Bill Skaggs <weskaggs@primate.ucdavis.edu>
2005-04-09 Bill Skaggs <weskaggs@primate.ucdavis.edu>
* plug-ins/common/screenshot.c: Change default back to Window
rather than Root. When shooting window, delay after instead

View File

@ -30,6 +30,7 @@
#include "core/gimpchannel.h"
#include "core/gimpchannel-select.h"
#include "core/gimplayer-floating-sel.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "core/gimp-utils.h"
@ -44,12 +45,6 @@
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-transform.h"
#ifdef __GNUC__
#warning FIXME #include "dialogs/dialogs-types.h"
#endif
#include "dialogs/dialogs-types.h"
#include "dialogs/info-dialog.h"
#include "gimpselectiontool.h"
#include "gimpselectionoptions.h"
#include "gimprectangletool.h"
@ -63,6 +58,11 @@
static void gimp_new_rect_select_tool_class_init (GimpNewRectSelectToolClass *klass);
static void gimp_new_rect_select_tool_init (GimpNewRectSelectTool *rect_tool);
static void gimp_new_rect_select_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_new_rect_select_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
@ -73,7 +73,7 @@ static void gimp_new_rect_select_tool_cursor_update (GimpTool
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
static gboolean gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
@ -137,6 +137,7 @@ gimp_new_rect_select_tool_class_init (GimpNewRectSelectToolClass *klass)
parent_class = g_type_class_peek_parent (klass);
tool_class->button_press = gimp_new_rect_select_tool_button_press;
tool_class->modifier_key = gimp_new_rect_select_tool_modifier_key;
tool_class->cursor_update = gimp_new_rect_select_tool_cursor_update;
@ -154,6 +155,43 @@ gimp_new_rect_select_tool_init (GimpNewRectSelectTool *new_rect_select_tool)
rectangle->selection_tool = TRUE;
}
static void
gimp_new_rect_select_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (tool);
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords,
time, state, gdisp);
if (gimp_selection_tool_start_edit (sel_tool, coords))
{
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
return;
}
switch (sel_tool->op)
{
case SELECTION_ADD:
gimp_tool_push_status (tool, _("Selection: ADD"));
break;
case SELECTION_SUBTRACT:
gimp_tool_push_status (tool, _("Selection: SUBTRACT"));
break;
case SELECTION_INTERSECT:
gimp_tool_push_status (tool, _("Selection: INTERSECT"));
break;
case SELECTION_REPLACE:
gimp_tool_push_status (tool, _("Selection: REPLACE"));
break;
default:
break;
}
}
static void
gimp_new_rect_select_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
@ -174,24 +212,89 @@ gimp_new_rect_select_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
/*
* This function is called if the user clicks and releases the left
* button without moving it. There are five things we might want
* to do here:
* 1) If there is a floating selection, we anchor it.
* 2) If there is an existing rectangle and we are inside it, we
* convert it into a selection.
* 3) If there is an existing rectangle and we are outside it, we
* clear it.
* 4) If there is no rectangle and we are inside the selection, we
* create a rectangle from the selection bounds.
* 5) If there is no rectangle and we are outside the selection,
* we clear the selection.
*/
static gboolean
gimp_new_rect_select_tool_execute (GimpRectangleTool *rectangle,
gint x,
gint y,
gint w,
gint h)
{
GimpTool *tool = GIMP_TOOL (rect_tool);
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (rect_tool);
GimpTool *tool = GIMP_TOOL (rectangle);
GimpSelectionOptions *options;
GimpImage *gimage;
gboolean rectangle_exists;
gboolean selected;
gint val;
GimpChannel *selection_mask;
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
gimp_channel_select_rectangle (gimp_image_get_mask (tool->gdisp->gimage),
x, y, w, h,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
gimage = tool->gdisp->gimage;
selection_mask = gimp_image_get_mask (gimage);
rectangle_exists = (w > 0 && h > 0);
/* If there is a floating selection, anchor it */
if (gimp_image_floating_sel (gimage))
{
floating_sel_anchor (gimp_image_floating_sel (gimage));
return FALSE;
}
/* if rectangle exists, turn it into a selection */
if (rectangle_exists)
{
GimpChannel *selection_mask = gimp_image_get_mask (gimage);
gimp_channel_select_rectangle (selection_mask,
x, y, w, h,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
return TRUE;
}
val = gimp_channel_value (selection_mask,
rectangle->pressx, rectangle->pressy);
selected = (val > 127);
/* if point clicked is inside selection, set rectangle to */
/* selection bounds. */
if (selected)
{
if (! gimp_channel_bounds (selection_mask,
&rectangle->x1, &rectangle->y1,
&rectangle->x2, &rectangle->y2))
{
rectangle->x1 = 0;
rectangle->y1 = 0;
rectangle->x2 = gimage->width;
rectangle->y2 = gimage->height;
}
return FALSE;
}
/* otherwise clear the selection */
gimp_channel_clear (selection_mask, NULL, TRUE);
return TRUE;
}

View File

@ -19,12 +19,6 @@
#ifndef __GIMP_NEW_RECT_SELECT_TOOL_H__
#define __GIMP_NEW_RECT_SELECT_TOOL_H__
#ifdef __GNUC__
#warning FIXME #include "gui/gui-types.h"
#endif
#include "gui/gui-types.h"
#include "gimprectangletool.h"

View File

@ -30,6 +30,7 @@
#include "core/gimpchannel.h"
#include "core/gimpchannel-select.h"
#include "core/gimplayer-floating-sel.h"
#include "core/gimpimage.h"
#include "core/gimptoolinfo.h"
#include "core/gimp-utils.h"
@ -44,12 +45,6 @@
#include "display/gimpdisplayshell.h"
#include "display/gimpdisplayshell-transform.h"
#ifdef __GNUC__
#warning FIXME #include "dialogs/dialogs-types.h"
#endif
#include "dialogs/dialogs-types.h"
#include "dialogs/info-dialog.h"
#include "gimpselectiontool.h"
#include "gimpselectionoptions.h"
#include "gimprectangletool.h"
@ -63,6 +58,11 @@
static void gimp_new_rect_select_tool_class_init (GimpNewRectSelectToolClass *klass);
static void gimp_new_rect_select_tool_init (GimpNewRectSelectTool *rect_tool);
static void gimp_new_rect_select_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_new_rect_select_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
@ -73,7 +73,7 @@ static void gimp_new_rect_select_tool_cursor_update (GimpTool
GdkModifierType state,
GimpDisplay *gdisp);
static void gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
static gboolean gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
@ -137,6 +137,7 @@ gimp_new_rect_select_tool_class_init (GimpNewRectSelectToolClass *klass)
parent_class = g_type_class_peek_parent (klass);
tool_class->button_press = gimp_new_rect_select_tool_button_press;
tool_class->modifier_key = gimp_new_rect_select_tool_modifier_key;
tool_class->cursor_update = gimp_new_rect_select_tool_cursor_update;
@ -154,6 +155,43 @@ gimp_new_rect_select_tool_init (GimpNewRectSelectTool *new_rect_select_tool)
rectangle->selection_tool = TRUE;
}
static void
gimp_new_rect_select_tool_button_press (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GdkModifierType state,
GimpDisplay *gdisp)
{
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (tool);
GIMP_TOOL_CLASS (parent_class)->button_press (tool, coords,
time, state, gdisp);
if (gimp_selection_tool_start_edit (sel_tool, coords))
{
gimp_draw_tool_stop (GIMP_DRAW_TOOL (tool));
return;
}
switch (sel_tool->op)
{
case SELECTION_ADD:
gimp_tool_push_status (tool, _("Selection: ADD"));
break;
case SELECTION_SUBTRACT:
gimp_tool_push_status (tool, _("Selection: SUBTRACT"));
break;
case SELECTION_INTERSECT:
gimp_tool_push_status (tool, _("Selection: INTERSECT"));
break;
case SELECTION_REPLACE:
gimp_tool_push_status (tool, _("Selection: REPLACE"));
break;
default:
break;
}
}
static void
gimp_new_rect_select_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
@ -174,24 +212,89 @@ gimp_new_rect_select_tool_cursor_update (GimpTool *tool,
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, gdisp);
}
static void
gimp_new_rect_select_tool_execute (GimpRectangleTool *rect_tool,
/*
* This function is called if the user clicks and releases the left
* button without moving it. There are five things we might want
* to do here:
* 1) If there is a floating selection, we anchor it.
* 2) If there is an existing rectangle and we are inside it, we
* convert it into a selection.
* 3) If there is an existing rectangle and we are outside it, we
* clear it.
* 4) If there is no rectangle and we are inside the selection, we
* create a rectangle from the selection bounds.
* 5) If there is no rectangle and we are outside the selection,
* we clear the selection.
*/
static gboolean
gimp_new_rect_select_tool_execute (GimpRectangleTool *rectangle,
gint x,
gint y,
gint w,
gint h)
{
GimpTool *tool = GIMP_TOOL (rect_tool);
GimpSelectionTool *sel_tool = GIMP_SELECTION_TOOL (rect_tool);
GimpTool *tool = GIMP_TOOL (rectangle);
GimpSelectionOptions *options;
GimpImage *gimage;
gboolean rectangle_exists;
gboolean selected;
gint val;
GimpChannel *selection_mask;
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
gimp_channel_select_rectangle (gimp_image_get_mask (tool->gdisp->gimage),
x, y, w, h,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
gimage = tool->gdisp->gimage;
selection_mask = gimp_image_get_mask (gimage);
rectangle_exists = (w > 0 && h > 0);
/* If there is a floating selection, anchor it */
if (gimp_image_floating_sel (gimage))
{
floating_sel_anchor (gimp_image_floating_sel (gimage));
return FALSE;
}
/* if rectangle exists, turn it into a selection */
if (rectangle_exists)
{
GimpChannel *selection_mask = gimp_image_get_mask (gimage);
gimp_channel_select_rectangle (selection_mask,
x, y, w, h,
options->operation,
options->feather,
options->feather_radius,
options->feather_radius);
return TRUE;
}
val = gimp_channel_value (selection_mask,
rectangle->pressx, rectangle->pressy);
selected = (val > 127);
/* if point clicked is inside selection, set rectangle to */
/* selection bounds. */
if (selected)
{
if (! gimp_channel_bounds (selection_mask,
&rectangle->x1, &rectangle->y1,
&rectangle->x2, &rectangle->y2))
{
rectangle->x1 = 0;
rectangle->y1 = 0;
rectangle->x2 = gimage->width;
rectangle->y2 = gimage->height;
}
return FALSE;
}
/* otherwise clear the selection */
gimp_channel_clear (selection_mask, NULL, TRUE);
return TRUE;
}

View File

@ -19,12 +19,6 @@
#ifndef __GIMP_NEW_RECT_SELECT_TOOL_H__
#define __GIMP_NEW_RECT_SELECT_TOOL_H__
#ifdef __GNUC__
#warning FIXME #include "gui/gui-types.h"
#endif
#include "gui/gui-types.h"
#include "gimprectangletool.h"

View File

@ -120,13 +120,13 @@ static void rectangle_automatic_callback (GtkWidget *widget,
static void rectangle_dimensions_changed (GtkWidget *widget,
GimpRectangleTool *rectangle);
static void rectangle_tool_execute (GimpRectangleTool *rect_tool,
static gboolean rectangle_tool_execute (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
gint h);
static void gimp_rectangle_tool_real_execute (GimpRectangleTool *rect_tool,
static gboolean gimp_rectangle_tool_real_execute (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
@ -376,14 +376,7 @@ gimp_rectangle_tool_button_release (GimpTool *tool,
if ( (rectangle->lastx == rectangle->pressx) &&
(rectangle->lasty == rectangle->pressy))
{
if (rectangle->function == RECT_CREATING)
{
rectangle_selection_callback (NULL, rectangle);
}
else if (rectangle->function == RECT_MOVING)
{
rectangle_response (NULL, GIMP_RECTANGLE_MODE_EXECUTE, rectangle);
}
rectangle_response (NULL, GIMP_RECTANGLE_MODE_EXECUTE, rectangle);
}
rectangle_info_update (rectangle);
@ -919,7 +912,12 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
gboolean inside_y;
if (tool->gdisp != gdisp)
return;
{
if (rectangle->selection_tool)
GIMP_TOOL_CLASS (parent_class)->oper_update (tool, coords, state, gdisp);
return;
}
inside_x = coords->x > rectangle->x1 && coords->x < rectangle->x2;
inside_y = coords->y > rectangle->y1 && coords->y < rectangle->y2;
@ -1029,6 +1027,7 @@ gimp_rectangle_tool_oper_update (GimpTool *tool,
gimp_tool_control_set_snap_offsets (tool->control, 0, 0, 0, 0);
}
}
static void
@ -1197,40 +1196,36 @@ rectangle_response (GtkWidget *widget,
GimpRectangleTool *rectangle)
{
GimpTool *tool = GIMP_TOOL (rectangle);
gboolean finish;
switch (response_id)
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
finish = rectangle_tool_execute (GIMP_RECTANGLE_TOOL (tool),
rectangle->x1, rectangle->y1,
rectangle->x2 - rectangle->x1,
rectangle->y2 - rectangle->y1);
rectangle_recalc (rectangle);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
if (finish)
{
case GIMP_RECTANGLE_MODE_EXECUTE:
gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->gdisp->shell),
NULL);
rectangle_tool_execute (GIMP_RECTANGLE_TOOL (tool),
rectangle->x1, rectangle->y1,
rectangle->x2 - rectangle->x1,
rectangle->y2 - rectangle->y1);
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (rectangle)))
gimp_draw_tool_stop (GIMP_DRAW_TOOL (rectangle));
if (gimp_tool_control_is_active (GIMP_TOOL (rectangle)->control))
gimp_tool_control_halt (GIMP_TOOL (rectangle)->control);
gimp_image_flush (tool->gdisp->gimage);
break;
default:
break;
tool->gdisp = NULL;
tool->drawable = NULL;
}
if (tool->gdisp)
gimp_display_shell_set_highlight (GIMP_DISPLAY_SHELL (tool->gdisp->shell),
NULL);
if (gimp_draw_tool_is_active (GIMP_DRAW_TOOL (rectangle)))
gimp_draw_tool_stop (GIMP_DRAW_TOOL (rectangle));
if (gimp_tool_control_is_active (GIMP_TOOL (rectangle)->control))
gimp_tool_control_halt (GIMP_TOOL (rectangle)->control);
tool->gdisp = NULL;
tool->drawable = NULL;
if (response_id != GIMP_RECTANGLE_MODE_EXECUTE)
gimp_rectangle_tool_zero_controls (rectangle);
}
static void
@ -1364,7 +1359,20 @@ rectangle_dimensions_changed (GtkWidget *widget,
GIMP_TOOL (rectangle)->gdisp);
}
static void
void
rectangle_width_changed (GimpRectangleTool *rectangle,
gint new_width)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (rectangle));
rectangle->x2 = rectangle->x1 + new_width;
rectangle_recalc (rectangle);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (rectangle));
}
static gboolean
rectangle_tool_execute (GimpRectangleTool *rect_tool,
gint x,
gint y,
@ -1374,7 +1382,7 @@ rectangle_tool_execute (GimpRectangleTool *rect_tool,
GimpTool *tool;
GimpSelectionOptions *options;
g_return_if_fail (GIMP_IS_RECTANGLE_TOOL (rect_tool));
g_return_val_if_fail (GIMP_IS_RECTANGLE_TOOL (rect_tool), FALSE);
tool = GIMP_TOOL (rect_tool);
options = GIMP_SELECTION_OPTIONS (tool->tool_info->tool_options);
@ -1391,7 +1399,7 @@ rectangle_tool_execute (GimpRectangleTool *rect_tool,
tool->gdisp->gimage->height,
&x, &y, &w, &h))
{
return;
return FALSE;
}
if (! options->shrink_merged)
@ -1409,7 +1417,7 @@ rectangle_tool_execute (GimpRectangleTool *rect_tool,
off_x, off_y, width, height,
&x, &y, &w, &h))
{
return;
return FALSE;
}
x -= off_x;
@ -1431,16 +1439,46 @@ rectangle_tool_execute (GimpRectangleTool *rect_tool,
y += off_y;
}
GIMP_RECTANGLE_TOOL_GET_CLASS (rect_tool)->execute (rect_tool, x, y, w, h);
return GIMP_RECTANGLE_TOOL_GET_CLASS (rect_tool)->execute (rect_tool, x, y, w, h);
}
static void
gimp_rectangle_tool_real_execute (GimpRectangleTool *rect_tool,
static gboolean
gimp_rectangle_tool_real_execute (GimpRectangleTool *rectangle,
gint x,
gint y,
gint w,
gint h)
{
GimpTool *tool = GIMP_TOOL (rectangle);
gboolean rectangle_exists = (rectangle->function != RECT_CREATING);
GimpChannel *selection_mask;
gint val;
gboolean selected;
GimpImage *gimage;
gimage = tool->gdisp->gimage;
selection_mask = gimp_image_get_mask (gimage);
val = gimp_channel_value (selection_mask,
rectangle->pressx, rectangle->pressy);
selected = (val > 127);
if (rectangle_exists && selected)
{
if (! gimp_channel_bounds (selection_mask,
&rectangle->x1, &rectangle->y1,
&rectangle->x2, &rectangle->y2))
{
rectangle->x1 = 0;
rectangle->y1 = 0;
rectangle->x2 = gimage->width;
rectangle->y2 = gimage->height;
}
return FALSE;
}
return TRUE;
}

View File

@ -20,11 +20,6 @@
#define __GIMP_RECTANGLE_TOOL_H__
#ifdef __GNUC__
#warning FIXME #include "gui/gui-types.h"
#endif
#include "gui/gui-types.h"
#include "gimpselectiontool.h"
@ -94,15 +89,17 @@ struct _GimpRectangleToolClass
/* virtual function */
void (* execute) (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
gint h);
gboolean (* execute) (GimpRectangleTool *rect_tool,
gint x,
gint y,
gint w,
gint h);
};
GType gimp_rectangle_tool_get_type (void) G_GNUC_CONST;
GType gimp_rectangle_tool_get_type (void) G_GNUC_CONST;
void gimp_rectangle_tool_width_changed (GimpRectangleTool *rectangle,
gint new_width);
#endif /* __GIMP_RECTANGLE_TOOL_H__ */