[gimp] Handle double and triple click and enable selecting words and lines
- From: Michael Natterer <mitch src gnome org>
- To: svn-commits-list gnome org
- Subject: [gimp] Handle double and triple click and enable selecting words and lines
- Date: Sun, 21 Jun 2009 10:21:14 -0400 (EDT)
commit a7271e6b25839af5c3024569f096ffa551c8047c
Author: Michael Natterer <mitch gimp org>
Date: Sun Jun 21 16:20:16 2009 +0200
Handle double and triple click and enable selecting words and lines
app/tools/gimptexttool.c | 229 ++++++++++++++++++++++++++++++++--------------
app/tools/gimptexttool.h | 3 +
2 files changed, 165 insertions(+), 67 deletions(-)
---
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index ca78a19..528b3a3 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -285,6 +285,8 @@ gimp_text_tool_init (GimpTextTool *text_tool)
text_tool);
gimp_tool_control_set_scroll_lock (tool->control, TRUE);
+ gimp_tool_control_set_wants_double_click (tool->control, TRUE);
+ gimp_tool_control_set_wants_triple_click (tool->control, TRUE);
gimp_tool_control_set_wants_all_key_events (tool->control, TRUE);
gimp_tool_control_set_precision (tool->control,
GIMP_CURSOR_PRECISION_PIXEL_BORDER);
@@ -413,60 +415,62 @@ gimp_text_tool_button_press (GimpTool *tool,
GimpRectangleTool *rect_tool = GIMP_RECTANGLE_TOOL (tool);
GimpText *text = text_tool->text;
GimpDrawable *drawable;
- gint x1, y1;
- gint x2, y2;
gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
- g_signal_handlers_block_by_func (text_tool->text_buffer,
- gimp_text_tool_text_buffer_mark_set,
- text_tool);
-
- g_object_get (rect_tool,
- "x1", &x1,
- "y1", &y1,
- "x2", &x2,
- "y2", &y2,
- NULL);
+ if (press_type == GIMP_BUTTON_PRESS_NORMAL)
+ {
+ gint x1, y1;
+ gint x2, y2;
- text_tool->selecting = FALSE;
+ g_signal_handlers_block_by_func (text_tool->text_buffer,
+ gimp_text_tool_text_buffer_mark_set,
+ text_tool);
- if (coords->x > x1 && coords->x <= x2 &&
- coords->y > y1 && coords->y <= y2 &&
- ! text_tool->moving)
- {
- text_tool->selecting = TRUE;
+ g_object_get (rect_tool,
+ "x1", &x1,
+ "y1", &y1,
+ "x2", &x2,
+ "y2", &y2,
+ NULL);
- gimp_rectangle_tool_set_function (rect_tool, GIMP_RECTANGLE_TOOL_DEAD);
- gimp_tool_control_activate (tool->control);
- }
- else
- {
- gimp_rectangle_tool_button_press (tool, coords, time, state, display);
- }
+ text_tool->selecting = FALSE;
+ if (coords->x > x1 && coords->x <= x2 &&
+ coords->y > y1 && coords->y <= y2 &&
+ ! text_tool->moving)
+ {
+ text_tool->selecting = TRUE;
- /* bail out now if the rectangle is narrow and the button press is
- * outside the layer
- */
- if (text_tool->layer &&
- gimp_rectangle_tool_get_function (rect_tool) !=
- GIMP_RECTANGLE_TOOL_CREATING)
- {
- GimpItem *item = GIMP_ITEM (text_tool->layer);
- gdouble x = coords->x - gimp_item_get_offset_x (item);
- gdouble y = coords->y - gimp_item_get_offset_y (item);
+ gimp_rectangle_tool_set_function (rect_tool, GIMP_RECTANGLE_TOOL_DEAD);
+ gimp_tool_control_activate (tool->control);
+ }
+ else
+ {
+ gimp_rectangle_tool_button_press (tool, coords, time, state, display);
+ }
- if (x < 0 || x > item->width ||
- y < 0 || y > item->height)
+ /* bail out now if the rectangle is narrow and the button press is
+ * outside the layer
+ */
+ if (text_tool->layer &&
+ gimp_rectangle_tool_get_function (rect_tool) !=
+ GIMP_RECTANGLE_TOOL_CREATING)
{
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
- return;
+ GimpItem *item = GIMP_ITEM (text_tool->layer);
+ gdouble x = coords->x - gimp_item_get_offset_x (item);
+ gdouble y = coords->y - gimp_item_get_offset_y (item);
+
+ if (x < 0 || x > item->width ||
+ y < 0 || y > item->height)
+ {
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
+ return;
+ }
}
}
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
-
drawable = gimp_image_get_active_drawable (display->image);
gimp_text_tool_set_drawable (text_tool, drawable, FALSE);
@@ -483,30 +487,67 @@ gimp_text_tool_button_press (GimpTool *tool,
/* did the user click on a text layer? */
if (gimp_text_tool_set_drawable (text_tool, drawable, TRUE))
{
- /* enable keyboard-handling for the text */
-
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
-
- if (text && text_tool->text == text)
+ if (press_type == GIMP_BUTTON_PRESS_NORMAL)
{
- gimp_text_tool_canvas_editor (text_tool);
- gtk_text_buffer_set_text (text_tool->text_buffer,
- text_tool->text->text, -1);
-
- gimp_text_tool_update_layout (text_tool);
+ /* enable keyboard-handling for the text */
+ if (text && text_tool->text == text)
+ {
+ gimp_text_tool_canvas_editor (text_tool);
+ gtk_text_buffer_set_text (text_tool->text_buffer,
+ text_tool->text->text, -1);
+
+ gimp_text_tool_update_layout (text_tool);
+ }
}
if (text_tool->layout && ! text_tool->moving)
{
GtkTextIter cursor;
+ GtkTextIter selection;
gint offset;
offset = gimp_text_tool_xy_to_offset (text_tool, x, y);
gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
&cursor, offset);
- gtk_text_buffer_place_cursor (text_tool->text_buffer,
- &cursor);
+
+ selection = cursor;
+
+ text_tool->select_start_offset = offset;
+ text_tool->select_words = FALSE;
+ text_tool->select_lines = FALSE;
+
+ switch (press_type)
+ {
+ case GIMP_BUTTON_PRESS_NORMAL:
+ gtk_text_buffer_place_cursor (text_tool->text_buffer,
+ &cursor);
+ break;
+
+ case GIMP_BUTTON_PRESS_DOUBLE:
+ text_tool->select_words = TRUE;
+
+ if (! gtk_text_iter_starts_word (&cursor))
+ gtk_text_iter_backward_visible_word_starts (&cursor, 1);
+
+ if (! gtk_text_iter_ends_word (&selection) &&
+ ! gtk_text_iter_forward_visible_word_ends (&selection, 1))
+ gtk_text_iter_forward_to_line_end (&selection);
+
+ gtk_text_buffer_select_range (text_tool->text_buffer,
+ &cursor, &selection);
+ break;
+
+ case GIMP_BUTTON_PRESS_TRIPLE:
+ text_tool->select_lines = TRUE;
+
+ gtk_text_iter_set_line_offset (&cursor, 0);
+ gtk_text_iter_forward_to_line_end (&selection);
+
+ gtk_text_buffer_select_range (text_tool->text_buffer,
+ &cursor, &selection);
+ break;
+ }
}
gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
@@ -528,6 +569,8 @@ gimp_text_tool_button_press (GimpTool *tool,
gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
gimp_text_tool_connect (text_tool, NULL, NULL);
gimp_text_tool_canvas_editor (text_tool);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
}
#define MIN_LAYER_WIDTH 20
@@ -636,33 +679,85 @@ gimp_text_tool_motion (GimpTool *tool,
GimpItem *item = GIMP_ITEM (text_tool->layer);
gdouble x = coords->x - gimp_item_get_offset_x (item);
gdouble y = coords->y - gimp_item_get_offset_y (item);
- GtkTextIter cursor;
- GtkTextIter old_selection_bound;
+ GtkTextMark *cursor_mark;
GtkTextMark *selection_mark;
+ GtkTextIter cursor;
+ GtkTextIter selection;
+ gint cursor_offset;
+ gint selection_offset;
gint offset;
- gint old_cursor_offset;
offset = gimp_text_tool_xy_to_offset (text_tool, x, y);
+ cursor_mark = gtk_text_buffer_get_insert (text_tool->text_buffer);
selection_mark = gtk_text_buffer_get_selection_bound (text_tool->text_buffer);
gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
- &old_selection_bound,
- selection_mark);
+ &cursor, cursor_mark);
+ gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
+ &selection, selection_mark);
- old_cursor_offset = gtk_text_iter_get_offset (&old_selection_bound);
+ cursor_offset = gtk_text_iter_get_offset (&cursor);
+ selection_offset = gtk_text_iter_get_offset (&selection);
- if (offset == old_cursor_offset)
- return;
+ if (text_tool->select_words ||
+ text_tool->select_lines)
+ {
+ /* when selecting words or lines, we always keep the
+ * cursor at the start and the selection mark at the
+ * end of the selection
+ */
+ if (offset < text_tool->select_start_offset)
+ {
+ gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+ &cursor, offset);
+ gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+ &selection,
+ text_tool->select_start_offset);
+ }
+ else
+ {
+ gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+ &cursor,
+ text_tool->select_start_offset);
+ gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+ &selection, offset);
+ }
- gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+ if (text_tool->select_words)
+ {
+ if (! gtk_text_iter_starts_word (&cursor))
+ gtk_text_iter_backward_visible_word_starts (&cursor, 1);
- gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
- &cursor, offset);
- gtk_text_buffer_move_mark_by_name (text_tool->text_buffer,
- "selection_bound", &cursor);
+ if (! gtk_text_iter_ends_word (&selection) &&
+ ! gtk_text_iter_forward_visible_word_ends (&selection, 1))
+ gtk_text_iter_forward_to_line_end (&selection);
+ }
+ else if (text_tool->select_lines)
+ {
+ gtk_text_iter_set_line_offset (&cursor, 0);
+ gtk_text_iter_forward_to_line_end (&selection);
+ }
+ }
+ else
+ {
+ if (selection_offset != offset)
+ {
+ gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+ &selection, offset);
+ }
+ }
- gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ if (cursor_offset != gtk_text_iter_get_offset (&cursor) ||
+ selection_offset != gtk_text_iter_get_offset (&selection))
+ {
+ gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
+ gtk_text_buffer_select_range (text_tool->text_buffer,
+ &cursor, &selection);
+
+ gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+ }
}
}
else
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index 5b20ce6..fe11781 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -65,6 +65,9 @@ struct _GimpTextTool
gboolean text_box_fixed;
gboolean selecting;
+ gint select_start_offset;
+ gboolean select_words;
+ gboolean select_lines;
gint x_pos;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]