added "gboolean wants_click" member and getters/setters.

2007-02-27  Michael Natterer  <mitch@gimp.org>

	* app/tools/gimptoolcontrol.[ch]: added "gboolean wants_click"
	member and getters/setters.

	* app/tools/gimptool.[ch] (struct GimpTool): added members
	in_click_distance, press_coords and press_time.

	(gimp_tool_button_press): if the tool wants click events, record
	press_coords and press_time.

	(gimp_tool_motion): check if we are still in click distance.

	(gimp_tool_button_release): ditto. If we are still in click
	distance, synthesize a motion event back to the recorded
	press_coords and send the tool release_type = CLICK.

	(gimp_tool_check_click_distance): utility function which checks
	the current coords and time against the recorded ones, using
	gtk-double-click-time and gtk-double-click-distance as thresholds.

	* app/tools/gimpcroptool.c
	* app/tools/gimprectangleselecttool.c: request click events
	and handle them.

	* app/tools/gimprectangletool.[ch]: handle click events. Removed
	gimp_rectangle_tool_no_movement().


svn path=/trunk/; revision=22016
This commit is contained in:
Michael Natterer 2007-02-27 21:11:35 +00:00 committed by Michael Natterer
parent d7ed63948c
commit 83eb96db21
9 changed files with 114 additions and 18 deletions

View File

@ -1,3 +1,31 @@
2007-02-27 Michael Natterer <mitch@gimp.org>
* app/tools/gimptoolcontrol.[ch]: added "gboolean wants_click"
member and getters/setters.
* app/tools/gimptool.[ch] (struct GimpTool): added members
in_click_distance, press_coords and press_time.
(gimp_tool_button_press): if the tool wants click events, record
press_coords and press_time.
(gimp_tool_motion): check if we are still in click distance.
(gimp_tool_button_release): ditto. If we are still in click
distance, synthesize a motion event back to the recorded
press_coords and send the tool release_type = CLICK.
(gimp_tool_check_click_distance): utility function which checks
the current coords and time against the recorded ones, using
gtk-double-click-time and gtk-double-click-distance as thresholds.
* app/tools/gimpcroptool.c
* app/tools/gimprectangleselecttool.c: request click events
and handle them.
* app/tools/gimprectangletool.[ch]: handle click events. Removed
gimp_rectangle_tool_no_movement().
2007-02-27 Michael Natterer <mitch@gimp.org>
Step one towards enabling tool cancellation by other means than

View File

@ -140,10 +140,12 @@ gimp_crop_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface)
static void
gimp_crop_tool_init (GimpCropTool *crop_tool)
{
GimpTool *tool = GIMP_TOOL (crop_tool);
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (crop_tool);
GimpTool *tool = GIMP_TOOL (crop_tool);
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (crop_tool);
gimp_tool_control_set_wants_click (tool->control, TRUE);
gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_CROP);
gimp_rectangle_tool_set_constraint (rect_tool, TRUE);
}

View File

@ -181,6 +181,7 @@ gimp_rect_select_tool_init (GimpRectSelectTool *rect_select)
{
GimpTool *tool = GIMP_TOOL (rect_select);
gimp_tool_control_set_wants_click (tool->control, TRUE);
gimp_tool_control_set_tool_cursor (tool->control,
GIMP_TOOL_CURSOR_RECT_SELECT);
gimp_tool_control_set_dirty_mask (tool->control,
@ -385,7 +386,6 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
GimpDisplay *display)
{
GimpRectSelectTool *rect_select = GIMP_RECT_SELECT_TOOL (tool);
GimpRectangleTool *rectangle = GIMP_RECTANGLE_TOOL (tool);
gimp_tool_pop_status (tool, display);
gimp_display_shell_set_show_selection (GIMP_DISPLAY_SHELL (display->shell),
@ -395,7 +395,7 @@ gimp_rect_select_tool_button_release (GimpTool *tool,
* if the user has not moved the mouse, we need to redo the operation
* that was undone on button press.
*/
if (gimp_rectangle_tool_no_movement (rectangle))
if (release_type == GIMP_BUTTON_RELEASE_CLICK)
{
GimpImage *image = tool->display->image;
GimpUndo *redo;

View File

@ -639,7 +639,7 @@ gimp_rectangle_tool_button_release (GimpTool *tool,
if (release_type != GIMP_BUTTON_RELEASE_CANCEL)
{
if (gimp_rectangle_tool_no_movement (rectangle))
if (release_type == GIMP_BUTTON_RELEASE_CLICK)
{
if (gimp_rectangle_tool_execute (rectangle))
gimp_rectangle_tool_halt (rectangle);
@ -2016,17 +2016,6 @@ gimp_rectangle_tool_set_function (GimpRectangleTool *rectangle,
}
}
gboolean
gimp_rectangle_tool_no_movement (GimpRectangleTool *rectangle)
{
GimpRectangleToolPrivate *private;
private = GIMP_RECTANGLE_TOOL_GET_PRIVATE (rectangle);
return (private->lastx == private->pressx &&
private->lasty == private->pressy);
}
/*
* check whether the coordinates extend outside the bounds of the image
* or active drawable, if it is constrained not to. If it does,

View File

@ -127,7 +127,6 @@ void gimp_rectangle_tool_set_constraint (GimpRectangleTool *re
GimpRectangleFunction gimp_rectangle_tool_get_function (GimpRectangleTool *rectangle);
void gimp_rectangle_tool_set_function (GimpRectangleTool *rectangle,
GimpRectangleFunction function);
gboolean gimp_rectangle_tool_no_movement (GimpRectangleTool *rectangle);
void gimp_rectangle_tool_get_press_coords (GimpRectangleTool *rectangle,
gint *pressx_ptr,
gint *pressy_ptr);

View File

@ -454,6 +454,40 @@ gimp_tool_button_press (GimpTool *tool,
{
tool->button_press_state = state;
tool->active_modifier_state = state;
if (gimp_tool_control_get_wants_click (tool->control))
{
tool->in_click_distance = TRUE;
tool->press_coords = *coords;
tool->press_time = time;
}
else
{
tool->in_click_distance = FALSE;
}
}
}
static void
gimp_tool_check_click_distance (GimpTool *tool,
GimpCoords *coords,
guint32 time,
GimpDisplay *display)
{
GtkSettings *settings = gtk_widget_get_settings (display->shell);
gint double_click_time;
gint double_click_distance;
g_object_get (settings,
"gtk-double-click-time", &double_click_time,
"gtk-double-click-distance", &double_click_distance,
NULL);
if ((time - tool->press_time) > double_click_time ||
sqrt (SQR (tool->press_coords.x - coords->x) +
SQR (tool->press_coords.y - coords->y)) > double_click_distance)
{
tool->in_click_distance = FALSE;
}
}
@ -473,7 +507,22 @@ gimp_tool_button_release (GimpTool *tool,
g_object_ref (tool);
if (state & GDK_BUTTON3_MASK)
release_type = GIMP_BUTTON_RELEASE_CANCEL;
{
release_type = GIMP_BUTTON_RELEASE_CANCEL;
}
else if (tool->in_click_distance)
{
gimp_tool_check_click_distance (tool, coords, time, display);
if (tool->in_click_distance)
{
release_type = GIMP_BUTTON_RELEASE_CLICK;
GIMP_TOOL_GET_CLASS (tool)->motion (tool, &tool->press_coords, time,
state & GDK_BUTTON1_MASK,
display);
}
}
GIMP_TOOL_GET_CLASS (tool)->button_release (tool, coords, time, state,
release_type, display);
@ -498,6 +547,9 @@ gimp_tool_motion (GimpTool *tool,
g_return_if_fail (GIMP_IS_DISPLAY (display));
g_return_if_fail (gimp_tool_control_is_active (tool->control));
if (tool->in_click_distance)
gimp_tool_check_click_distance (tool, coords, time, display);
GIMP_TOOL_GET_CLASS (tool)->motion (tool, coords, time, state, display);
}

View File

@ -57,6 +57,10 @@ struct _GimpTool
GdkModifierType modifier_state;
GdkModifierType button_press_state;
GdkModifierType active_modifier_state;
gboolean in_click_distance;
GimpCoords press_coords;
guint32 press_time;
};
struct _GimpToolClass

View File

@ -202,6 +202,23 @@ gimp_tool_control_get_handle_empty_image (GimpToolControl *control)
return control->handle_empty_image;
}
void
gimp_tool_control_set_wants_click (GimpToolControl *control,
gboolean wants_click)
{
g_return_if_fail (GIMP_IS_TOOL_CONTROL (control));
control->wants_click = wants_click ? TRUE : FALSE;
}
gboolean
gimp_tool_control_get_wants_click (GimpToolControl *control)
{
g_return_val_if_fail (GIMP_IS_TOOL_CONTROL (control), FALSE);
return control->wants_click;
}
void
gimp_tool_control_set_dirty_mask (GimpToolControl *control,
GimpDirtyMask dirty_mask)

View File

@ -46,6 +46,7 @@ struct _GimpToolControl
gboolean scroll_lock; /* allow scrolling or not */
gboolean handle_empty_image; /* invoke the tool on images *
* without active drawable */
gboolean wants_click; /* wants click detection */
GimpDirtyMask dirty_mask; /* if preserve is FALSE, cancel *
* the tool on these events */
GimpMotionMode motion_mode; /* how to process motion events *
@ -102,6 +103,10 @@ void gimp_tool_control_set_handle_empty_image (GimpToolControl *control,
gboolean handle_empty);
gboolean gimp_tool_control_get_handle_empty_image (GimpToolControl *control);
void gimp_tool_control_set_wants_click (GimpToolControl *control,
gboolean wants_click);
gboolean gimp_tool_control_get_wants_click (GimpToolControl *control);
void gimp_tool_control_set_dirty_mask (GimpToolControl *control,
GimpDirtyMask dirty_mask);
GimpDirtyMask gimp_tool_control_get_dirty_mask (GimpToolControl *control);