summaryrefslogtreecommitdiff
path: root/gtk/gtkentry.c
diff options
context:
space:
mode:
authorSoeren Sandmann <sandmann@daimi.au.dk>2004-08-14 15:59:39 +0000
committerSøren Sandmann Pedersen <ssp@src.gnome.org>2004-08-14 15:59:39 +0000
commit15ed3634a9c3f04d7c0a7952f27fad7f62a1657d (patch)
tree57cdb1883e543f20f1ca17aba5efcd1431450e94 /gtk/gtkentry.c
parent766d78659c91fe65f3595a54abfa0dfd50790432 (diff)
downloadgtk+-15ed3634a9c3f04d7c0a7952f27fad7f62a1657d.tar.gz
New function.
Sat Aug 14 17:56:33 2004 Soeren Sandmann <sandmann@daimi.au.dk> * gtk/gtkentry.c (gtk_entry_get_pixel_ranges): New function. * gtk/gtkentry.c (in_selection): New function using gtk_entry_get_pixel_ranges() to determine whether a click is in the selection. Improve entry behavior wrt. dragging and selecting. Bug #143249. Sat Aug 14 17:53:46 2004 Soeren Sandmann <sandmann@daimi.au.dk> * configure.in: Require glib 2.5.2 * gtk/gtksequence.[ch]: New internal data structure. * gtk/gtkliststore.[hc]: Reimplement in terms of new data structure * tests/Makefile.am (testtreemodel_SOURCES): * tests/testtreemodel.c: New test program written by Matthias.
Diffstat (limited to 'gtk/gtkentry.c')
-rw-r--r--gtk/gtkentry.c98
1 files changed, 76 insertions, 22 deletions
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index c583f3f5cf..82b89b201b 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -1400,6 +1400,70 @@ gtk_entry_expose (GtkWidget *widget,
return FALSE;
}
+static void
+gtk_entry_get_pixel_ranges (GtkEntry *entry,
+ gint **ranges,
+ gint *n_ranges)
+{
+ gint start_char, end_char;
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_char, &end_char))
+ {
+ PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
+ PangoLayoutLine *line = pango_layout_get_lines (layout)->data;
+ const char *text = pango_layout_get_text (layout);
+ gint start_index = g_utf8_offset_to_pointer (text, start_char) - text;
+ gint end_index = g_utf8_offset_to_pointer (text, end_char) - text;
+ gint real_n_ranges, i;
+
+ pango_layout_line_get_x_ranges (line, start_index, end_index, ranges, &real_n_ranges);
+
+ if (ranges)
+ {
+ gint *r = *ranges;
+
+ for (i = 0; i < real_n_ranges; ++i)
+ {
+ r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE;
+ r[2 * i] = r[2 * i] / PANGO_SCALE;
+ }
+ }
+
+ if (n_ranges)
+ *n_ranges = real_n_ranges;
+ }
+ else
+ {
+ if (n_ranges)
+ *n_ranges = 0;
+ if (ranges)
+ *ranges = NULL;
+ }
+}
+
+static gboolean
+in_selection (GtkEntry *entry,
+ gint x)
+{
+ gint *ranges;
+ gint n_ranges, i;
+ gint retval = FALSE;
+
+ gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
+
+ for (i = 0; i < n_ranges; ++i)
+ {
+ if (x >= ranges[2 * i] && x < ranges[2 * i] + ranges[2 * i + 1])
+ {
+ retval = TRUE;
+ break;
+ }
+ }
+
+ g_free (ranges);
+ return retval;
+}
+
static gint
gtk_entry_button_press (GtkWidget *widget,
GdkEventButton *event)
@@ -1491,21 +1555,18 @@ gtk_entry_button_press (GtkWidget *widget,
switch (event->type)
{
case GDK_BUTTON_PRESS:
- if (have_selection && tmp_pos >= sel_start && tmp_pos <= sel_end)
+ if (in_selection (entry, event->x + entry->scroll_offset))
{
/* Click inside the selection - we'll either start a drag, or
* clear the selection
*/
-
entry->in_drag = TRUE;
entry->drag_start_x = event->x + entry->scroll_offset;
entry->drag_start_y = event->y + entry->scroll_offset;
}
else
gtk_editable_set_position (editable, tmp_pos);
-
break;
-
case GDK_2BUTTON_PRESS:
/* We ALWAYS receive a GDK_BUTTON_PRESS immediately before
@@ -2997,7 +3058,6 @@ static void
gtk_entry_draw_text (GtkEntry *entry)
{
GtkWidget *widget;
- PangoLayoutLine *line;
if (!entry->visible && entry->invisible_char == 0)
return;
@@ -3021,19 +3081,12 @@ gtk_entry_draw_text (GtkEntry *entry)
gint *ranges;
gint n_ranges, i;
PangoRectangle logical_rect;
- const gchar *text = pango_layout_get_text (layout);
- gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
- gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
- GdkRegion *clip_region = gdk_region_new ();
- GdkGC *text_gc;
- GdkGC *selection_gc;
-
- line = pango_layout_get_lines (layout)->data;
-
- pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
+ GdkGC *selection_gc, *text_gc;
+ GdkRegion *clip_region;
+
+ pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+ gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
- pango_layout_get_extents (layout, NULL, &logical_rect);
-
if (GTK_WIDGET_HAS_FOCUS (entry))
{
selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
@@ -3045,21 +3098,22 @@ gtk_entry_draw_text (GtkEntry *entry)
text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
}
- for (i=0; i < n_ranges; i++)
+ clip_region = gdk_region_new ();
+ for (i = 0; i < n_ranges; ++i)
{
GdkRectangle rect;
- rect.x = INNER_BORDER - entry->scroll_offset + ranges[2*i] / PANGO_SCALE;
+ rect.x = INNER_BORDER - entry->scroll_offset + ranges[2 * i];
rect.y = y;
- rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
- rect.height = logical_rect.height / PANGO_SCALE;
+ rect.width = ranges[2 * i + 1];
+ rect.height = logical_rect.height;
gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_region_union_with_rect (clip_region, &rect);
}
-
+
gdk_gc_set_clip_region (text_gc, clip_region);
gdk_draw_layout (entry->text_area, text_gc,
x, y,