diff options
-rw-r--r-- | ChangeLog | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-0 | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-10 | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-2 | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-4 | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-6 | 40 | ||||
-rw-r--r-- | ChangeLog.pre-2-8 | 40 | ||||
-rw-r--r-- | gdk/gdkpango.c | 43 | ||||
-rw-r--r-- | gtk/gtkalignment.c | 175 | ||||
-rw-r--r-- | gtk/gtkentry.c | 2 | ||||
-rw-r--r-- | gtk/gtkentry.h | 6 | ||||
-rw-r--r-- | gtk/gtklabel.c | 686 | ||||
-rw-r--r-- | gtk/gtklabel.h | 15 | ||||
-rw-r--r-- | gtk/gtkrange.c | 53 | ||||
-rw-r--r-- | gtk/gtkrange.h | 9 | ||||
-rw-r--r-- | gtk/gtktextbtree.c | 2 | ||||
-rw-r--r-- | gtk/gtktextbtree.h | 2 | ||||
-rw-r--r-- | gtk/gtktextbuffer.c | 12 | ||||
-rw-r--r-- | gtk/gtktextbuffer.h | 2 | ||||
-rw-r--r-- | gtk/gtktextiter.c | 28 | ||||
-rw-r--r-- | gtk/gtktextiter.h | 2 | ||||
-rw-r--r-- | gtk/gtktextlayout.c | 8 | ||||
-rw-r--r-- | gtk/gtktextview.c | 2 | ||||
-rw-r--r-- | gtk/testgtk.c | 77 | ||||
-rw-r--r-- | gtk/testtext.c | 6 | ||||
-rw-r--r-- | gtk/testtextbuffer.c | 8 | ||||
-rw-r--r-- | tests/testgtk.c | 77 | ||||
-rw-r--r-- | tests/testtext.c | 6 | ||||
-rw-r--r-- | tests/testtextbuffer.c | 8 |
29 files changed, 1335 insertions, 174 deletions
@@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-0 +++ b/ChangeLog.pre-2-0 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 5a0cdd22cd..b495a1029c 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,6 +1,46 @@ +2001-02-15 Havoc Pennington <hp@redhat.com> + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): convert + the X coordinates so they're with respect to the line, rather than + with respect to the layout. + + * gtk/gtkalignment.c: Convert to new property API, patch from Lee + Mallabone + + * gtk/testgtk.c (create_range_controls): add vscale tests, + and inverted test + + * gtk/gtkrange.c (gtk_range_set_inverted): new function to fix + #50806 + + * gtk/gtkentry.c (gtk_entry_get_text): add G_CONST_RETURN + + * gtk/gtktextiter.h (gtk_text_iter_is_last): rename + gtk_text_iter_is_end + + * gtk/gtktextbuffer.h (gtk_text_buffer_get_last_iter): + rename gtk_text_buffer_get_end_iter + + * gtk/testgtk.c (create_labels): Add test for selectable + + * gtk/gtkentry.c (gtk_entry_draw_text): Use new GDK API to draw + the selection stuff. This code is kind of broken since it doesn't + use the theme engine. + + * gdk/gdkpango.c (gdk_pango_layout_line_get_clip_region): + fix infinite loop and y offset problem + (gdk_draw_layout_line_with_colors): fix foreground color handling + + * gtk/gtklabel.h, gtk/gtklabel.c: Implement a "selectable" flag + that makes the label selectable. + + * gtk/gtklabel.c (gtk_label_style_set): recreate the label's + layout when the style is set, since fonts etc. could have changed. + Fri Feb 16 14:22:05 2001 Jonathan Blandford <jrb@redhat.com> * gtk/Makefile.am: Removed gtktreemodelsimple.[ch] + * gtk/gtktreemodelsimple.[ch]: removes 2001-02-16 Alexander Larsson <alexl@redhat.com> diff --git a/gdk/gdkpango.c b/gdk/gdkpango.c index 7a7c7d1aa3..7146880c78 100644 --- a/gdk/gdkpango.c +++ b/gdk/gdkpango.c @@ -259,7 +259,7 @@ gdk_draw_layout_line_with_colors (GdkDrawable *drawable, tmp.green = foreground->green; } - fg_gc = gdk_pango_get_gc (context, fg_set ? &fg_color : NULL, + fg_gc = gdk_pango_get_gc (context, fg_set ? &tmp : NULL, stipple, gc); } else @@ -656,10 +656,15 @@ gdk_pango_attr_embossed_new (gboolean embossed) * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges * - * Obtains a clip region which contains the areas where the given ranges - * of text would be drawn. @x_origin and @y_origin are the same position - * you would pass to gdk_draw_layout_line(). @index_ranges should contain - * ranges of bytes in the layout's text. + * Obtains a clip region which contains the areas where the given + * ranges of text would be drawn. @x_origin and @y_origin are the same + * position you would pass to gdk_draw_layout_line(). @index_ranges + * should contain ranges of bytes in the layout's text. The clip + * region will include space to the left or right of the line (to the + * layout bounding box) if you have indexes above or below the indexes + * contained inside the line. This is to draw the selection all the way + * to the side of the layout. However, the clip region is in line coordinates, + * not layout coordinates. * * Return value: a clip region containing the given ranges **/ @@ -673,13 +678,20 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line, GdkRegion *clip_region; gint i; PangoRectangle logical_rect; + PangoLayoutIter *iter; + gint baseline; g_return_val_if_fail (line != NULL, NULL); g_return_val_if_fail (index_ranges != NULL, NULL); clip_region = gdk_region_new (); - pango_layout_line_get_extents (line, NULL, &logical_rect); + iter = pango_layout_get_iter (line->layout); + while (pango_layout_iter_get_line (iter) != line) + pango_layout_iter_next_line (iter); + + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); + baseline = pango_layout_iter_get_baseline (iter); i = 0; while (i < n_ranges) @@ -687,7 +699,9 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line, gint *pixel_ranges = NULL; gint n_pixel_ranges = 0; gint j; - + + /* Note that get_x_ranges returns layout coordinates + */ pango_layout_line_get_x_ranges (line, index_ranges[i*2], index_ranges[i*2+1], @@ -696,16 +710,17 @@ gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line, for (j=0; j < n_pixel_ranges; j++) { GdkRectangle rect; - - rect.x = x_origin + pixel_ranges[2*j] / PANGO_SCALE; - rect.y = y_origin - logical_rect.y / PANGO_SCALE; + + rect.x = x_origin + pixel_ranges[2*j] / PANGO_SCALE - logical_rect.x / PANGO_SCALE; + rect.y = y_origin - (baseline / PANGO_SCALE - logical_rect.y / PANGO_SCALE); rect.width = (pixel_ranges[2*j + 1] - pixel_ranges[2*j]) / PANGO_SCALE; - rect.height = logical_rect.height / PANGO_SCALE; - + rect.height = logical_rect.height / PANGO_SCALE; + gdk_region_union_with_rect (clip_region, &rect); } g_free (pixel_ranges); + ++i; } return clip_region; @@ -750,8 +765,8 @@ gdk_pango_layout_get_clip_region (PangoLayout *layout, GdkRegion *line_region; gint baseline; - line = pango_layout_iter_get_line (iter); - + line = pango_layout_iter_get_line (iter); + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); baseline = pango_layout_iter_get_baseline (iter); diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c index 54c49ee38f..8d9cb05ee2 100644 --- a/gtk/gtkalignment.c +++ b/gtk/gtkalignment.c @@ -25,14 +25,17 @@ */ #include "gtkalignment.h" - +#include "gtkintl.h" enum { - ARG_0, - ARG_XALIGN, - ARG_YALIGN, - ARG_XSCALE, - ARG_YSCALE + PROP_0, + + PROP_XALIGN, + PROP_YALIGN, + PROP_XSCALE, + PROP_YSCALE, + + PROP_LAST }; @@ -42,14 +45,16 @@ static void gtk_alignment_size_request (GtkWidget *widget, GtkRequisition *requisition); static void gtk_alignment_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static void gtk_alignment_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); -static void gtk_alignment_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id); - - +static void gtk_alignment_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec, + const gchar *trailer); +static void gtk_alignment_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec, + const gchar *trailer); GtkType gtk_alignment_get_type (void) @@ -85,13 +90,46 @@ gtk_alignment_class_init (GtkAlignmentClass *class) object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; - gtk_object_add_arg_type ("GtkAlignment::xalign", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_XALIGN); - gtk_object_add_arg_type ("GtkAlignment::yalign", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_YALIGN); - gtk_object_add_arg_type ("GtkAlignment::xscale", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_XSCALE); - gtk_object_add_arg_type ("GtkAlignment::yscale", GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_YSCALE); - - object_class->set_arg = gtk_alignment_set_arg; - object_class->get_arg = gtk_alignment_get_arg; + g_object_class_install_property(G_OBJECT_CLASS(object_class), + PROP_XALIGN, + g_param_spec_float("xalign", + _("Horizontal alignment"), + _("Value between 0.0 and 1.0 to indicate X alignment"), + 0.0, + 1.0, + 0.5, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + g_object_class_install_property(G_OBJECT_CLASS(object_class), + PROP_YALIGN, + g_param_spec_float("yalign", + _("Vertical alignment"), + _("Value between 0.0 and 1.0 to indicate Y alignment"), + 0.0, + 1.0, + 0.5, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + g_object_class_install_property(G_OBJECT_CLASS(object_class), + PROP_XSCALE, + g_param_spec_float("xscale", + _("Horizontal scale"), + _("Value between 0.0 and 1.0 to indicate X scale"), + 0.0, + 1.0, + 0.5, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + g_object_class_install_property(G_OBJECT_CLASS(object_class), + PROP_YSCALE, + g_param_spec_float("yscale", + _("Vertical scale"), + _("Value between 0.0 and 1.0 to indicate Y scale"), + 0.0, + 1.0, + 0.5, + G_PARAM_READABLE | G_PARAM_WRITABLE)); + + G_OBJECT_CLASS(object_class)->set_property = gtk_alignment_set_property; + G_OBJECT_CLASS(object_class)->get_property = gtk_alignment_get_property; widget_class->size_request = gtk_alignment_size_request; widget_class->size_allocate = gtk_alignment_size_allocate; @@ -126,75 +164,79 @@ gtk_alignment_new (gfloat xalign, return GTK_WIDGET (alignment); } -static void -gtk_alignment_set_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +static void gtk_alignment_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec, + const gchar *trailer) { GtkAlignment *alignment; alignment = GTK_ALIGNMENT (object); - switch (arg_id) + switch (prop_id) { - case ARG_XALIGN: + case PROP_XALIGN: gtk_alignment_set (alignment, - GTK_VALUE_FLOAT (*arg), + g_value_get_float(value), alignment->yalign, alignment->xscale, alignment->yscale); break; - case ARG_YALIGN: + case PROP_YALIGN: gtk_alignment_set (alignment, alignment->xalign, - GTK_VALUE_FLOAT (*arg), + g_value_get_float(value), alignment->xscale, alignment->yscale); break; - case ARG_XSCALE: + case PROP_XSCALE: gtk_alignment_set (alignment, alignment->xalign, alignment->yalign, - GTK_VALUE_FLOAT (*arg), + g_value_get_float(value), alignment->yscale); break; - case ARG_YSCALE: + case PROP_YSCALE: gtk_alignment_set (alignment, alignment->xalign, alignment->yalign, alignment->xscale, - GTK_VALUE_FLOAT (*arg)); + g_value_get_float(value)); break; default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } -static void -gtk_alignment_get_arg (GtkObject *object, - GtkArg *arg, - guint arg_id) +static void gtk_alignment_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec, + const gchar *trailer) { GtkAlignment *alignment; alignment = GTK_ALIGNMENT (object); - - switch (arg_id) + g_assert (GTK_IS_ALIGNMENT(object)); + + switch (prop_id) { - case ARG_XALIGN: - GTK_VALUE_FLOAT (*arg) = alignment->xalign; + case PROP_XALIGN: + g_value_set_float(value, alignment->xalign); break; - case ARG_YALIGN: - GTK_VALUE_FLOAT (*arg) = alignment->yalign; + case PROP_YALIGN: + g_value_set_float(value, alignment->yalign); break; - case ARG_XSCALE: - GTK_VALUE_FLOAT (*arg) = alignment->xscale; + case PROP_XSCALE: + g_value_set_float(value, alignment->xscale); break; - case ARG_YSCALE: - GTK_VALUE_FLOAT (*arg) = alignment->yscale; + case PROP_YSCALE: + g_value_set_float(value, alignment->yscale); break; default: - arg->type = GTK_TYPE_INVALID; + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -206,6 +248,8 @@ gtk_alignment_set (GtkAlignment *alignment, gfloat xscale, gfloat yscale) { + gboolean values_changed = FALSE; + g_return_if_fail (alignment != NULL); g_return_if_fail (GTK_IS_ALIGNMENT (alignment)); @@ -214,16 +258,33 @@ gtk_alignment_set (GtkAlignment *alignment, xscale = CLAMP (xscale, 0.0, 1.0); yscale = CLAMP (yscale, 0.0, 1.0); - if ((alignment->xalign != xalign) || - (alignment->yalign != yalign) || - (alignment->xscale != xscale) || - (alignment->yscale != yscale)) + if (alignment->xalign != xalign) + { + values_changed = TRUE; + alignment->xalign = xalign; + g_object_notify(G_OBJECT(alignment), "xalign"); + } + if (alignment->yalign != yalign) + { + values_changed = TRUE; + alignment->yalign = yalign; + g_object_notify(G_OBJECT(alignment), "yalign"); + } + if (alignment->xscale != xscale) { - alignment->xalign = xalign; - alignment->yalign = yalign; - alignment->xscale = xscale; - alignment->yscale = yscale; + values_changed = TRUE; + alignment->xscale = xscale; + g_object_notify(G_OBJECT(alignment), "xscale"); + } + if (alignment->yscale != yscale) + { + values_changed = TRUE; + alignment->yscale = yscale; + g_object_notify(G_OBJECT(alignment), "yscale"); + } + if (values_changed == TRUE) + { gtk_widget_size_allocate (GTK_WIDGET (alignment), &(GTK_WIDGET (alignment)->allocation)); gtk_widget_queue_draw (GTK_WIDGET (alignment)); } diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c index 76929a7455..75c486649c 100644 --- a/gtk/gtkentry.c +++ b/gtk/gtkentry.c @@ -2619,7 +2619,7 @@ gtk_entry_set_editable(GtkEntry *entry, gtk_editable_set_editable (GTK_EDITABLE (entry), editable); } -gchar* +G_CONST_RETURN gchar* gtk_entry_get_text (GtkEntry *entry) { g_return_val_if_fail (entry != NULL, NULL); diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h index c8dbcdd835..f9352ce805 100644 --- a/gtk/gtkentry.h +++ b/gtk/gtkentry.h @@ -149,10 +149,10 @@ void gtk_entry_set_max_length (GtkEntry *entry, /* Somewhat more convenient than the GtkEditable generic functions */ -void gtk_entry_set_text (GtkEntry *entry, - const gchar *text); +void gtk_entry_set_text (GtkEntry *entry, + const gchar *text); /* returns a reference to the text */ -gchar* gtk_entry_get_text (GtkEntry *entry); +G_CONST_RETURN gchar* gtk_entry_get_text (GtkEntry *entry); /* Deprecated compatibility functions */ diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index d8ff48516e..bef3322efc 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -27,9 +27,16 @@ #include <string.h> #include "gtklabel.h" #include "gdk/gdkkeysyms.h" +#include "gtkclipboard.h" #include "gdk/gdki18n.h" #include <pango/pango.h> +struct _GtkLabelSelectionInfo +{ + GdkWindow *window; + gint selection_anchor; + gint selection_end; +}; enum { ARG_0, @@ -50,6 +57,8 @@ static void gtk_label_get_arg (GtkObject *object, static void gtk_label_finalize (GObject *object); static void gtk_label_size_request (GtkWidget *widget, GtkRequisition *requisition); +static void gtk_label_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); static void gtk_label_style_set (GtkWidget *widget, GtkStyle *previous_style); static void gtk_label_direction_changed (GtkWidget *widget, @@ -57,7 +66,29 @@ static void gtk_label_direction_changed (GtkWidget *widget, static gint gtk_label_expose (GtkWidget *widget, GdkEventExpose *event); -static GtkMiscClass *parent_class = NULL; +static void gtk_label_realize (GtkWidget *widget); +static void gtk_label_unrealize (GtkWidget *widget); +static void gtk_label_map (GtkWidget *widget); +static void gtk_label_unmap (GtkWidget *widget); +static gint gtk_label_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_label_button_release (GtkWidget *widget, + GdkEventButton *event); +static gint gtk_label_motion (GtkWidget *widget, + GdkEventMotion *event); + +static void gtk_label_create_window (GtkLabel *label); +static void gtk_label_destroy_window (GtkLabel *label); +static void gtk_label_clear_layout (GtkLabel *label); +static void gtk_label_ensure_layout (GtkLabel *label, + gint *widthp, + gint *heightp); +static void gtk_label_select_region_index (GtkLabel *label, + gint anchor_index, + gint end_index); + + +GtkMiscClass *parent_class = NULL; GtkType gtk_label_get_type (void) @@ -108,9 +139,17 @@ gtk_label_class_init (GtkLabelClass *class) object_class->get_arg = gtk_label_get_arg; widget_class->size_request = gtk_label_size_request; + widget_class->size_allocate = gtk_label_size_allocate; widget_class->style_set = gtk_label_style_set; widget_class->direction_changed = gtk_label_direction_changed; widget_class->expose_event = gtk_label_expose; + widget_class->realize = gtk_label_realize; + widget_class->unrealize = gtk_label_unrealize; + widget_class->map = gtk_label_map; + widget_class->unmap = gtk_label_unmap; + widget_class->button_press_event = gtk_label_button_press; + widget_class->button_release_event = gtk_label_button_release; + widget_class->motion_notify_event = gtk_label_motion; } static void @@ -207,11 +246,10 @@ gtk_label_set_text_internal (GtkLabel *label, g_free (label->label); label->label = str; - if (label->layout) - { - g_object_unref (G_OBJECT (label->layout)); - label->layout = NULL; - } + + gtk_label_clear_layout (label); + + gtk_label_select_region_index (label, 0, 0); gtk_widget_queue_resize (GTK_WIDGET (label)); } @@ -426,6 +464,8 @@ gtk_label_finalize (GObject *object) if (label->attrs) pango_attr_list_unref (label->attrs); + + g_free (label->select_info); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -469,16 +509,25 @@ gtk_label_pattern_to_attrs (GtkLabel *label, } static void -gtk_label_size_request (GtkWidget *widget, - GtkRequisition *requisition) +gtk_label_clear_layout (GtkLabel *label) { - GtkLabel *label; + if (label->layout) + { + g_object_unref (G_OBJECT (label->layout)); + label->layout = NULL; + } +} + +static void +gtk_label_ensure_layout (GtkLabel *label, + gint *widthp, + gint *heightp) +{ + GtkWidget *widget; PangoRectangle logical_rect; - - g_return_if_fail (GTK_IS_LABEL (widget)); - g_return_if_fail (requisition != NULL); - - label = GTK_LABEL (widget); + gint width, height; + + widget = GTK_WIDGET (label); /* * There are a number of conditions which will necessitate re-filling @@ -501,8 +550,8 @@ gtk_label_size_request (GtkWidget *widget, * don't think it's really that slow. */ - requisition->width = label->misc.xpad * 2; - requisition->height = label->misc.ypad * 2; + width = label->misc.xpad * 2; + height = label->misc.ypad * 2; if (!label->layout) { @@ -512,7 +561,7 @@ gtk_label_size_request (GtkWidget *widget, label->layout = gtk_widget_create_pango_layout (widget, label->label); /* FIXME move to a model where the pattern isn't stored - * permanently, and just modifes or creates the AttrList + * permanently, and just modifies or creates the AttrList */ if (label->attrs) attrs = pango_attr_list_copy (label->attrs); @@ -521,7 +570,7 @@ gtk_label_size_request (GtkWidget *widget, if (label->pattern) gtk_label_pattern_to_attrs (label, attrs); - + if (attrs) { pango_layout_set_attributes (label->layout, attrs); @@ -564,8 +613,8 @@ gtk_label_size_request (GtkWidget *widget, pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE); pango_layout_get_extents (label->layout, NULL, &logical_rect); - requisition->width += aux_info->width; - requisition->height += PANGO_PIXELS (logical_rect.height); + width += aux_info->width; + height += PANGO_PIXELS (logical_rect.height); } else { @@ -632,8 +681,8 @@ gtk_label_size_request (GtkWidget *widget, } pango_layout_set_width (label->layout, width); - requisition->width += PANGO_PIXELS (real_width); - requisition->height += PANGO_PIXELS (height); + width += PANGO_PIXELS (real_width); + height += PANGO_PIXELS (height); } } else /* !label->wrap */ @@ -641,8 +690,52 @@ gtk_label_size_request (GtkWidget *widget, pango_layout_set_width (label->layout, -1); pango_layout_get_extents (label->layout, NULL, &logical_rect); - requisition->width += PANGO_PIXELS (logical_rect.width); - requisition->height += PANGO_PIXELS (logical_rect.height); + width += PANGO_PIXELS (logical_rect.width); + height += PANGO_PIXELS (logical_rect.height); + } + + if (widthp) + *widthp = width; + + if (heightp) + *heightp = height; +} + +static void +gtk_label_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + GtkLabel *label; + gint width, height; + + g_return_if_fail (GTK_IS_LABEL (widget)); + g_return_if_fail (requisition != NULL); + + label = GTK_LABEL (widget); + + gtk_label_ensure_layout (label, &width, &height); + + requisition->width = width; + requisition->height = height; +} + +static void +gtk_label_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation); + + if (label->select_info && label->select_info->window) + { + gdk_window_move_resize (label->select_info->window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); } } @@ -651,13 +744,13 @@ gtk_label_style_set (GtkWidget *widget, GtkStyle *previous_style) { GtkLabel *label; - + g_return_if_fail (GTK_IS_LABEL (widget)); label = GTK_LABEL (widget); - if (previous_style && label->layout) - pango_layout_context_changed (label->layout); + /* We have to clear the layout, fonts etc. may have changed */ + gtk_label_clear_layout (label); } static void @@ -703,42 +796,58 @@ gtk_label_paint_word (GtkLabel *label, } #endif +static void +get_layout_location (GtkLabel *label, + gint *xp, + gint *yp) +{ + GtkMisc *misc; + GtkWidget *widget; + gfloat xalign; + gint x, y; + + misc = GTK_MISC (label); + widget = GTK_WIDGET (label); + + if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) + xalign = misc->xalign; + else + xalign = 1.0 - misc->xalign; + + x = floor (widget->allocation.x + (gint)misc->xpad + + ((widget->allocation.width - widget->requisition.width) * xalign) + + 0.5); + + y = floor (widget->allocation.y + (gint)misc->ypad + + ((widget->allocation.height - widget->requisition.height) * misc->yalign) + + 0.5); + + + if (xp) + *xp = x; + + if (yp) + *yp = y; +} + static gint gtk_label_expose (GtkWidget *widget, GdkEventExpose *event) { GtkLabel *label; - GtkMisc *misc; gint x, y; - gfloat xalign; g_return_val_if_fail (GTK_IS_LABEL (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); label = GTK_LABEL (widget); - /* if label->layout is NULL it means we got a set_text since - * our last size request, so a resize should be queued, - * which means a full expose is in the queue anyway. - */ + gtk_label_ensure_layout (label, NULL, NULL); + if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) && - label->layout && label->label && (*label->label != '\0')) + label->label && (*label->label != '\0')) { - misc = GTK_MISC (widget); - - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) - xalign = misc->xalign; - else - xalign = 1. - misc->xalign; - - x = floor (widget->allocation.x + (gint)misc->xpad - + ((widget->allocation.width - widget->requisition.width) * xalign) - + 0.5); - - y = floor (widget->allocation.y + (gint)misc->ypad - + ((widget->allocation.height - widget->requisition.height) * misc->yalign) - + 0.5); - + get_layout_location (label, &x, &y); gtk_paint_layout (widget->style, widget->window, @@ -748,6 +857,45 @@ gtk_label_expose (GtkWidget *widget, "label", x, y, label->layout); + + if (label->select_info && + (label->select_info->selection_anchor != + label->select_info->selection_end)) + { + gint range[2]; + GdkRegion *clip; + + range[0] = label->select_info->selection_anchor; + range[1] = label->select_info->selection_end; + + if (range[0] > range[1]) + { + gint tmp = range[0]; + range[0] = range[1]; + range[1] = tmp; + } + + clip = gdk_pango_layout_get_clip_region (label->layout, + x, y, + range, + 1); + + /* FIXME should use gtk_paint, but it can't use a clip + * region + */ + + gdk_gc_set_clip_region (widget->style->white_gc, clip); + + gdk_draw_layout_with_colors (widget->window, + widget->style->white_gc, + x, y, + label->layout, + &widget->style->fg[GTK_STATE_SELECTED], + &widget->style->bg[GTK_STATE_SELECTED]); + + gdk_gc_set_clip_region (widget->style->white_gc, NULL); + gdk_region_destroy (clip); + } } return TRUE; @@ -836,3 +984,443 @@ gtk_label_parse_uline (GtkLabel *label, return accel_key; } + +static void +gtk_label_realize (GtkWidget *widget) +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + (* GTK_WIDGET_CLASS (parent_class)->realize) (widget); + + if (label->select_info) + gtk_label_create_window (label); +} + +static void +gtk_label_unrealize (GtkWidget *widget) +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + if (label->select_info) + gtk_label_destroy_window (label); + + (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget); +} + +static void +gtk_label_map (GtkWidget *widget) +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + (* GTK_WIDGET_CLASS (parent_class)->map) (widget); + + if (label->select_info) + gdk_window_show (label->select_info->window); +} + +static void +gtk_label_unmap (GtkWidget *widget) +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + if (label->select_info) + gdk_window_hide (label->select_info->window); + + (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget); +} + +static void +window_to_layout_coords (GtkLabel *label, + gint *x, + gint *y) +{ + gint lx, ly; + GtkWidget *widget; + + widget = GTK_WIDGET (label); + + /* get layout location in widget->window coords */ + get_layout_location (label, &lx, &ly); + + if (x) + { + *x += widget->allocation.x; /* go to widget->window */ + *x -= lx; /* go to layout */ + } + + if (y) + { + *y += widget->allocation.y; /* go to widget->window */ + *y -= ly; /* go to layout */ + } +} + +static void +layout_to_window_coords (GtkLabel *label, + gint *x, + gint *y) +{ + gint lx, ly; + GtkWidget *widget; + + widget = GTK_WIDGET (label); + + /* get layout location in widget->window coords */ + get_layout_location (label, &lx, &ly); + + if (x) + { + *x += lx; /* go to widget->window */ + *x -= widget->allocation.x; /* go to selection window */ + } + + if (y) + { + *y += ly; /* go to widget->window */ + *y -= widget->allocation.y; /* go to selection window */ + } +} + +static void +get_layout_index (GtkLabel *label, + gint x, + gint y, + gint *index) +{ + gint trailing = 0; + const gchar *cluster; + const gchar *cluster_end; + + *index = 0; + + gtk_label_ensure_layout (label, NULL, NULL); + + window_to_layout_coords (label, &x, &y); + + x *= PANGO_SCALE; + y *= PANGO_SCALE; + + pango_layout_xy_to_index (label->layout, + x, y, + index, &trailing); + + + cluster = label->label + *index; + cluster_end = cluster; + while (trailing) + { + cluster_end = g_utf8_next_char (cluster_end); + --trailing; + } + + *index += (cluster_end - cluster); +} + +static gint +gtk_label_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GtkLabel *label; + gint index = 0; + + label = GTK_LABEL (widget); + + if (label->select_info == NULL) + return FALSE; + + if (event->button != 1) + return FALSE; + + get_layout_index (label, event->x, event->y, &index); + + if ((label->select_info->selection_anchor != + label->select_info->selection_end) && + (event->state & GDK_SHIFT_MASK)) + { + /* extend (same as motion) */ + if (index < label->select_info->selection_end) + gtk_label_select_region_index (label, + index, + label->select_info->selection_end); + else + gtk_label_select_region_index (label, + label->select_info->selection_anchor, + index); + + /* ensure the anchor is opposite index */ + if (index == label->select_info->selection_anchor) + { + gint tmp = label->select_info->selection_end; + label->select_info->selection_end = label->select_info->selection_anchor; + label->select_info->selection_anchor = tmp; + } + } + else + { + /* start a replacement */ + gtk_label_select_region_index (label, index, index); + } + + return TRUE; +} + +static gint +gtk_label_button_release (GtkWidget *widget, + GdkEventButton *event) + +{ + GtkLabel *label; + + label = GTK_LABEL (widget); + + if (label->select_info == NULL) + return FALSE; + + if (event->button != 1) + return FALSE; + + /* The goal here is to return TRUE iff we ate the + * button press to start selecting. + */ + + return TRUE; +} + +static gint +gtk_label_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + GtkLabel *label; + gint index; + gint x, y; + + label = GTK_LABEL (widget); + + if (label->select_info == NULL) + return FALSE; + + if ((event->state & GDK_BUTTON1_MASK) == 0) + return FALSE; + + gdk_window_get_pointer (label->select_info->window, + &x, &y, NULL); + + get_layout_index (label, x, y, &index); + + gtk_label_select_region_index (label, + label->select_info->selection_anchor, + index); + + return TRUE; +} + +static void +gtk_label_create_window (GtkLabel *label) +{ + GtkWidget *widget; + GdkWindowAttr attributes; + gint attributes_mask; + + g_assert (label->select_info); + g_assert (GTK_WIDGET_REALIZED (label)); + + if (label->select_info->window) + return; + + widget = GTK_WIDGET (label); + + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.window_type = GDK_WINDOW_TEMP; + attributes.wclass = GDK_INPUT_ONLY; + attributes.override_redirect = TRUE; + attributes.event_mask = gtk_widget_get_events (widget) | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_MOTION_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR; + + label->select_info->window = gdk_window_new (widget->window, + &attributes, attributes_mask); + gdk_window_set_user_data (label->select_info->window, widget); +} + +static void +gtk_label_destroy_window (GtkLabel *label) +{ + g_assert (label->select_info); + + if (label->select_info->window == NULL) + return; + + gdk_window_set_user_data (label->select_info->window, NULL); + gdk_window_destroy (label->select_info->window); + label->select_info->window = NULL; +} + +void +gtk_label_set_selectable (GtkLabel *label, + gboolean setting) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + setting = setting != FALSE; + + if (setting) + { + if (label->select_info == NULL) + { + label->select_info = g_new (GtkLabelSelectionInfo, 1); + + label->select_info->window = NULL; + label->select_info->selection_anchor = 0; + label->select_info->selection_end = 0; + + if (GTK_WIDGET_REALIZED (label)) + gtk_label_create_window (label); + + if (GTK_WIDGET_MAPPED (label)) + gdk_window_show (label->select_info->window); + } + } + else + { + if (label->select_info) + { + if (label->select_info->window) + gtk_label_destroy_window (label); + + g_free (label->select_info); + + label->select_info = NULL; + } + } +} + +gboolean +gtk_label_get_selectable (GtkLabel *label) +{ + g_return_val_if_fail (GTK_IS_LABEL (label), FALSE); + + return label->select_info != NULL; +} + +static void +get_text_callback (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gpointer user_data_or_owner) +{ + GtkLabel *label; + gchar *str; + + label = GTK_LABEL (user_data_or_owner); + + if ((label->select_info->selection_anchor != + label->select_info->selection_end) && + label->label) + { + gint start, end; + + start = MIN (label->select_info->selection_anchor, + label->select_info->selection_end); + end = MAX (label->select_info->selection_anchor, + label->select_info->selection_end); + + str = g_strndup (label->label + start, + end - start); + + gtk_selection_data_set_text (selection_data, + str); + + g_free (str); + } +} + +static void +clear_text_callback (GtkClipboard *clipboard, + gpointer user_data_or_owner) +{ + GtkLabel *label; + + label = GTK_LABEL (user_data_or_owner); + + if (label->select_info) + { + label->select_info->selection_anchor = 0; + label->select_info->selection_end = 0; + + gtk_label_clear_layout (label); + gtk_widget_queue_draw (GTK_WIDGET (label)); + } +} + +static void +gtk_label_select_region_index (GtkLabel *label, + gint anchor_index, + gint end_index) +{ + static const GtkTargetEntry targets[] = { + { "STRING", 0, 0 }, + { "TEXT", 0, 0 }, + { "COMPOUND_TEXT", 0, 0 }, + { "UTF8_STRING", 0, 0 } + }; + + g_return_if_fail (GTK_IS_LABEL (label)); + + if (label->select_info) + { + GtkClipboard *clipboard; + + label->select_info->selection_anchor = anchor_index; + label->select_info->selection_end = end_index; + + clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + + gtk_clipboard_set_with_owner (clipboard, + targets, + G_N_ELEMENTS (targets), + get_text_callback, + clear_text_callback, + G_OBJECT (label)); + + gtk_label_clear_layout (label); + gtk_widget_queue_draw (GTK_WIDGET (label)); + } +} + +void +gtk_label_select_region (GtkLabel *label, + gint start_offset, + gint end_offset) +{ + g_return_if_fail (GTK_IS_LABEL (label)); + + if (label->label && label->select_info) + { + GtkClipboard *clipboard; + + if (start_offset < 0) + start_offset = 0; + + if (end_offset < 0) + end_offset = g_utf8_strlen (label->label, -1); + + gtk_label_select_region_index (label, + g_utf8_offset_to_pointer (label->label, start_offset) - label->label, + g_utf8_offset_to_pointer (label->label, end_offset) - label->label); + } +} + diff --git a/gtk/gtklabel.h b/gtk/gtklabel.h index 787ffed50f..6285670113 100644 --- a/gtk/gtklabel.h +++ b/gtk/gtklabel.h @@ -47,19 +47,24 @@ extern "C" { typedef struct _GtkLabel GtkLabel; typedef struct _GtkLabelClass GtkLabelClass; +typedef struct _GtkLabelSelectionInfo GtkLabelSelectionInfo; + struct _GtkLabel { GtkMisc misc; + /*< private >*/ + gchar *label; gchar *pattern; guint jtype : 2; guint wrap : 1; - /*< private >*/ PangoLayout *layout; PangoAttrList *attrs; + + GtkLabelSelectionInfo *select_info; }; struct _GtkLabelClass @@ -95,6 +100,14 @@ void gtk_label_set_line_wrap (GtkLabel *label, guint gtk_label_parse_uline (GtkLabel *label, const gchar *string); +void gtk_label_set_selectable (GtkLabel *label, + gboolean setting); +gboolean gtk_label_get_selectable (GtkLabel *label); + +void gtk_label_select_region (GtkLabel *label, + gint start_offset, + gint end_offset); + #ifndef GTK_DISABLE_COMPAT_H # define gtk_label_set gtk_label_set_text #endif /* GTK_DISABLE_COMPAT_H */ diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index 77e43d221a..66c3bbf967 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -306,6 +306,29 @@ gtk_range_set_adjustment (GtkRange *range, } void +gtk_range_set_inverted (GtkRange *range, + gboolean setting) +{ + g_return_if_fail (GTK_IS_RANGE (range)); + + setting = setting != FALSE; + + if (setting != range->inverted) + { + range->inverted = setting; + gtk_widget_queue_resize (GTK_WIDGET (range)); + } +} + +gboolean +gtk_range_get_inverted (GtkRange *range) +{ + g_return_val_if_fail (GTK_IS_RANGE (range), FALSE); + + return range->inverted; +} + +void gtk_range_draw_background (GtkRange *range) { g_return_if_fail (range != NULL); @@ -420,6 +443,19 @@ move_and_update_window (GdkWindow *window, gint x, gint y) gdk_window_process_updates (parent, TRUE); } +static gboolean +should_invert (GtkRange *range, + gboolean horizontal) +{ + if (horizontal) + return + (range->inverted && !range->flippable) || + (range->inverted && range->flippable && gtk_widget_get_direction (GTK_WIDGET (range)) == GTK_TEXT_DIR_LTR) || + (!range->inverted && range->flippable && gtk_widget_get_direction (GTK_WIDGET (range)) == GTK_TEXT_DIR_RTL); + else + return range->inverted; +} + void gtk_range_default_hslider_update (GtkRange *range) { @@ -455,7 +491,7 @@ gtk_range_default_hslider_update (GtkRange *range) else if (x > right) x = right; - if (range->flippable && gtk_widget_get_direction (GTK_WIDGET (range)) == GTK_TEXT_DIR_RTL) + if (should_invert (range, TRUE)) x = right - (x - left); move_and_update_window (range->slider, x, GTK_WIDGET (range)->style->ythickness); @@ -497,6 +533,9 @@ gtk_range_default_vslider_update (GtkRange *range) else if (y > bottom) y = bottom; + if (should_invert (range, FALSE)) + y = bottom - (y - top); + move_and_update_window (range->slider, GTK_WIDGET (range)->style->xthickness, y); } } @@ -523,7 +562,7 @@ gtk_range_default_htrough_click (GtkRange *range, gdk_window_get_size (range->slider, &slider_length, NULL); right += slider_length; - if (range->flippable && gtk_widget_get_direction (GTK_WIDGET (range)) == GTK_TEXT_DIR_RTL) + if (should_invert (range, TRUE)) x = (right - x) + left; if ((x > left) && (y > ythickness)) @@ -571,7 +610,10 @@ gtk_range_default_vtrough_click (GtkRange *range, gtk_range_trough_vdims (range, &top, &bottom); gdk_window_get_size (range->slider, NULL, &slider_length); bottom += slider_length; - + + if (should_invert (range, FALSE)) + y = (bottom - y) + top; + if ((x > xthickness) && (y > top)) { gdk_window_get_size (range->trough, &trough_width, &trough_height); @@ -618,7 +660,7 @@ gtk_range_default_hmotion (GtkRange *range, new_pos = slider_x + xdelta; - if (range->flippable && gtk_widget_get_direction (GTK_WIDGET (range)) == GTK_TEXT_DIR_RTL) + if (should_invert (range, TRUE)) new_pos = (right - new_pos) + left; if (new_pos < left) @@ -686,6 +728,9 @@ gtk_range_default_vmotion (GtkRange *range, new_pos = slider_y + ydelta; + if (should_invert (range, FALSE)) + new_pos = (bottom - new_pos) + top; + if (new_pos < top) new_pos = top; else if (new_pos > bottom) diff --git a/gtk/gtkrange.h b/gtk/gtkrange.h index 3842ab44dc..5b48aeaedd 100644 --- a/gtk/gtkrange.h +++ b/gtk/gtkrange.h @@ -69,7 +69,8 @@ struct _GtkRange guint click_child : 3; guint need_timer : 1; guint flippable : 1; - + guint inverted : 1; + guint32 timer; gfloat old_value; @@ -123,8 +124,12 @@ void gtk_range_set_update_policy (GtkRange *range, void gtk_range_set_adjustment (GtkRange *range, GtkAdjustment *adjustment); +void gtk_range_set_inverted (GtkRange *range, + gboolean setting); +gboolean gtk_range_get_inverted (GtkRange *range); + void gtk_range_draw_background (GtkRange *range); -void gtk_range_clear_background (GtkRange *range); +void gtk_range_clear_background (GtkRange *range); void gtk_range_draw_trough (GtkRange *range); void gtk_range_draw_slider (GtkRange *range); void gtk_range_draw_step_forw (GtkRange *range); diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c index 5cf5f889a1..205b0aac7c 100644 --- a/gtk/gtktextbtree.c +++ b/gtk/gtktextbtree.c @@ -5238,7 +5238,7 @@ get_tree_bounds (GtkTextBTree *tree, GtkTextIter *end) { _gtk_text_btree_get_iter_at_line_char (tree, start, 0, 0); - _gtk_text_btree_get_last_iter (tree, end); + _gtk_text_btree_get_end_iter (tree, end); } static void diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h index 65932b3dc0..17fd0a540b 100644 --- a/gtk/gtktextbtree.h +++ b/gtk/gtktextbtree.h @@ -118,7 +118,7 @@ gboolean _gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree, void _gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree, GtkTextIter *iter, GtkTextMark *mark); -void _gtk_text_btree_get_last_iter (GtkTextBTree *tree, +void _gtk_text_btree_get_end_iter (GtkTextBTree *tree, GtkTextIter *iter); void _gtk_text_btree_get_iter_at_line (GtkTextBTree *tree, GtkTextIter *iter, diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 1a4ccdb1f0..6b09e25257 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -1811,7 +1811,7 @@ gtk_text_buffer_place_cursor (GtkTextBuffer *buffer, real = *where; - if (gtk_text_iter_is_last (&real)) + if (gtk_text_iter_is_end (&real)) gtk_text_iter_backward_char (&real); _gtk_text_btree_place_cursor (get_btree (buffer), &real); @@ -2130,7 +2130,7 @@ gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer, } /** - * gtk_text_buffer_get_last_iter: + * gtk_text_buffer_get_end_iter: * @buffer: a #GtkTextBuffer * @iter: iterator to initialize * @@ -2143,13 +2143,13 @@ gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer, * **/ void -gtk_text_buffer_get_last_iter (GtkTextBuffer *buffer, +gtk_text_buffer_get_end_iter (GtkTextBuffer *buffer, GtkTextIter *iter) { g_return_if_fail (iter != NULL); g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer)); - _gtk_text_btree_get_last_iter (get_btree (buffer), iter); + _gtk_text_btree_get_end_iter (get_btree (buffer), iter); } /** @@ -2172,7 +2172,7 @@ gtk_text_buffer_get_bounds (GtkTextBuffer *buffer, g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer)); _gtk_text_btree_get_iter_at_char (get_btree (buffer), start, 0); - _gtk_text_btree_get_last_iter (get_btree (buffer), end); + _gtk_text_btree_get_end_iter (get_btree (buffer), end); } /* @@ -3078,7 +3078,7 @@ _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer, g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL); g_return_val_if_fail (anywhere_in_line != NULL, NULL); - g_return_val_if_fail (!gtk_text_iter_is_last (anywhere_in_line), NULL); + g_return_val_if_fail (!gtk_text_iter_is_end (anywhere_in_line), NULL); /* FIXME we also need to recompute log attrs if the language tag at * the start of a paragraph changes diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h index 88bf91190b..af00330cf7 100644 --- a/gtk/gtktextbuffer.h +++ b/gtk/gtktextbuffer.h @@ -291,7 +291,7 @@ void gtk_text_buffer_get_iter_at_offset (GtkTextBuffer *buffer, void gtk_text_buffer_get_iter_at_line (GtkTextBuffer *buffer, GtkTextIter *iter, gint line_number); -void gtk_text_buffer_get_last_iter (GtkTextBuffer *buffer, +void gtk_text_buffer_get_end_iter (GtkTextBuffer *buffer, GtkTextIter *iter); void gtk_text_buffer_get_bounds (GtkTextBuffer *buffer, GtkTextIter *start, diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index c216d4ca3c..73a51ed368 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -730,7 +730,7 @@ gtk_text_iter_get_char (const GtkTextIter *iter) check_invariants (iter); - if (gtk_text_iter_is_last (iter)) + if (gtk_text_iter_is_end (iter)) return 0; else if (real->segment->type == >k_text_char_type) { @@ -1382,18 +1382,18 @@ gtk_text_iter_ends_line (const GtkTextIter *iter) } /** - * gtk_text_iter_is_last: + * gtk_text_iter_is_end: * @iter: an iterator * * Returns TRUE if @iter is the end iterator, i.e. one past the last - * dereferenceable iterator in the buffer. gtk_text_iter_is_last () is + * dereferenceable iterator in the buffer. gtk_text_iter_is_end () is * the most efficient way to check whether an iterator is the end * iterator. * * Return value: whether @iter is the end iterator **/ gboolean -gtk_text_iter_is_last (const GtkTextIter *iter) +gtk_text_iter_is_end (const GtkTextIter *iter) { GtkTextRealIter *real; @@ -1722,7 +1722,7 @@ forward_char (GtkTextRealIter *real) check_invariants ((GtkTextIter*)real); - if (gtk_text_iter_is_last ((GtkTextIter*)real)) + if (gtk_text_iter_is_end ((GtkTextIter*)real)) return FALSE; else return TRUE; @@ -1813,7 +1813,7 @@ _gtk_text_iter_forward_indexable_segment (GtkTextIter *iter) check_invariants (iter); - if (gtk_text_iter_is_last (iter)) + if (gtk_text_iter_is_end (iter)) return FALSE; else return TRUE; @@ -2111,7 +2111,7 @@ gtk_text_iter_forward_chars (GtkTextIter *iter, gint count) /* Return FALSE if we're on the non-dereferenceable end * iterator. */ - if (gtk_text_iter_is_last (iter)) + if (gtk_text_iter_is_end (iter)) return FALSE; else return TRUE; @@ -2303,7 +2303,7 @@ gtk_text_iter_forward_line (GtkTextIter *iter) check_invariants (iter); - if (gtk_text_iter_is_last (iter)) + if (gtk_text_iter_is_end (iter)) return FALSE; else return TRUE; @@ -2415,7 +2415,7 @@ gtk_text_iter_forward_lines (GtkTextIter *iter, gint count) /* return whether it moved, and is dereferenceable. */ return (gtk_text_iter_get_line (iter) != old_line) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } } @@ -2702,7 +2702,7 @@ find_by_log_attrs (GtkTextIter *iter, return !gtk_text_iter_equal (iter, &orig) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } } @@ -3379,7 +3379,7 @@ gtk_text_iter_forward_to_end (GtkTextIter *iter) buffer = _gtk_text_btree_get_buffer (real->tree); - gtk_text_buffer_get_last_iter (buffer, iter); + gtk_text_buffer_get_end_iter (buffer, iter); } /** @@ -3477,7 +3477,7 @@ gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter, if (next_line == NULL) { /* End of search. Set to end of buffer. */ - _gtk_text_btree_get_last_iter (real->tree, iter); + _gtk_text_btree_get_end_iter (real->tree, iter); return FALSE; } @@ -4622,7 +4622,7 @@ _gtk_text_btree_get_iter_at_first_toggle (GtkTextBTree *tree, if (line == NULL) { /* Set iter to last in tree */ - _gtk_text_btree_get_last_iter (tree, iter); + _gtk_text_btree_get_end_iter (tree, iter); check_invariants (iter); return FALSE; } @@ -4724,7 +4724,7 @@ _gtk_text_btree_get_iter_at_child_anchor (GtkTextBTree *tree, } void -_gtk_text_btree_get_last_iter (GtkTextBTree *tree, +_gtk_text_btree_get_end_iter (GtkTextBTree *tree, GtkTextIter *iter) { g_return_if_fail (iter != NULL); diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h index 2522588a7a..9b25a8be49 100644 --- a/gtk/gtktextiter.h +++ b/gtk/gtktextiter.h @@ -141,7 +141,7 @@ gint gtk_text_iter_get_bytes_in_line (const GtkTextIter *iter); gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter, GtkTextAttributes *values); gchar* gtk_text_iter_get_language (const GtkTextIter *iter); -gboolean gtk_text_iter_is_last (const GtkTextIter *iter); +gboolean gtk_text_iter_is_end (const GtkTextIter *iter); gboolean gtk_text_iter_is_first (const GtkTextIter *iter); /* diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index f220646b66..8cf21002a6 100644 --- a/gtk/gtktextlayout.c +++ b/gtk/gtktextlayout.c @@ -2487,7 +2487,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout, return !gtk_text_iter_equal (iter, &orig) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } /** @@ -2557,7 +2557,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout, return !gtk_text_iter_equal (iter, &orig) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } /** @@ -2617,7 +2617,7 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout, return !gtk_text_iter_equal (iter, &orig) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } @@ -2850,7 +2850,7 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout, return !gtk_text_iter_equal (iter, &orig) && - !gtk_text_iter_is_last (iter); + !gtk_text_iter_is_end (iter); } void diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index df233806b8..283a72e8b9 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -3614,7 +3614,7 @@ gtk_text_view_move_cursor (GtkTextView *text_view, case GTK_MOVEMENT_BUFFER_ENDS: if (count > 0) - gtk_text_buffer_get_last_iter (get_buffer (text_view), &newplace); + gtk_text_buffer_get_end_iter (get_buffer (text_view), &newplace); else if (count < 0) gtk_text_buffer_get_iter_at_offset (get_buffer (text_view), &newplace, 0); break; diff --git a/gtk/testgtk.c b/gtk/testgtk.c index f257346ac9..97bf5e270d 100644 --- a/gtk/testgtk.c +++ b/gtk/testgtk.c @@ -2004,6 +2004,59 @@ create_sensitivity_control (GtkWidget *widget) return button; } +static void +set_selectable_recursive (GtkWidget *widget, + gboolean setting) +{ + if (GTK_IS_CONTAINER (widget)) + { + GList *children; + GList *tmp; + + children = gtk_container_children (GTK_CONTAINER (widget)); + tmp = children; + while (tmp) + { + set_selectable_recursive (tmp->data, setting); + + tmp = tmp->next; + } + g_list_free (children); + } + else if (GTK_IS_LABEL (widget)) + { + gtk_label_set_selectable (GTK_LABEL (widget), setting); + } +} + +static void +selectable_toggled (GtkWidget *toggle, + GtkWidget *widget) +{ + set_selectable_recursive (widget, + GTK_TOGGLE_BUTTON (toggle)->active); +} + +static GtkWidget* +create_selectable_control (GtkWidget *widget) +{ + GtkWidget *button; + + button = gtk_toggle_button_new_with_label ("Selectable"); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + FALSE); + + gtk_signal_connect (GTK_OBJECT (button), + "toggled", + GTK_SIGNAL_FUNC (selectable_toggled), + widget); + + gtk_widget_show_all (button); + + return button; +} + void create_labels (void) { static GtkWidget *window = NULL; @@ -2034,6 +2087,10 @@ void create_labels (void) button = create_sensitivity_control (hbox); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + button = create_selectable_control (hbox); + + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); vbox = gtk_vbox_new (FALSE, 5); @@ -6201,6 +6258,7 @@ create_range_controls (void) GtkWidget *scale; GtkWidget *separator; GtkObject *adjustment; + GtkWidget *hbox; if (!window) { @@ -6241,6 +6299,25 @@ create_range_controls (void) gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0); gtk_widget_show (scrollbar); + hbox = gtk_hbox_new (FALSE, 0); + + scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment)); + gtk_widget_set_usize (scale, -1, 200); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment)); + gtk_widget_set_usize (scale, -1, 200); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE); + gtk_range_set_inverted (GTK_RANGE (scale), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); diff --git a/gtk/testtext.c b/gtk/testtext.c index 85c662ef0e..292681e2be 100644 --- a/gtk/testtext.c +++ b/gtk/testtext.c @@ -665,7 +665,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename) /* We had a newline in the buffer to begin with. (The buffer always contains * a newline, so we delete to the end of the buffer to clean up. */ - gtk_text_buffer_get_last_iter (buffer, &end); + gtk_text_buffer_get_end_iter (buffer, &end); gtk_text_buffer_delete (buffer, &iter, &end); gtk_text_buffer_set_modified (buffer, FALSE); @@ -1281,7 +1281,7 @@ save_buffer (Buffer *buffer) else { gtk_text_buffer_get_iter_at_offset (buffer->buffer, &start, 0); - gtk_text_buffer_get_last_iter (buffer->buffer, &end); + gtk_text_buffer_get_end_iter (buffer->buffer, &end); chars = gtk_text_buffer_get_slice (buffer->buffer, &start, &end, FALSE); @@ -1972,7 +1972,7 @@ get_lines (GtkTextView *text_view, count = 0; size = 0; - while (!gtk_text_iter_is_last (&iter)) + while (!gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; diff --git a/gtk/testtextbuffer.c b/gtk/testtextbuffer.c index b14ce64eef..0d42dcb19a 100644 --- a/gtk/testtextbuffer.c +++ b/gtk/testtextbuffer.c @@ -186,7 +186,7 @@ check_specific_tag (GtkTextBuffer *buffer, state = FALSE; count = 0; - gtk_text_buffer_get_last_iter (buffer, &iter); + gtk_text_buffer_get_end_iter (buffer, &iter); last_offset = gtk_text_iter_get_offset (&iter); if (gtk_text_iter_toggles_tag (&iter, tag) || gtk_text_iter_backward_to_tag_toggle (&iter, tag)) @@ -292,7 +292,7 @@ run_tests (GtkTextBuffer *buffer) g_error ("Mark not created in the right place."); } - if (gtk_text_iter_is_last (&iter)) + if (gtk_text_iter_is_end (&iter)) g_error ("iterators ran out before chars (offset %d of %d)", i, num_chars); @@ -474,7 +474,7 @@ run_tests (GtkTextBuffer *buffer) tag_states = g_hash_table_new (NULL, NULL); count = 0; - gtk_text_buffer_get_last_iter (buffer, &iter); + gtk_text_buffer_get_end_iter (buffer, &iter); if (gtk_text_iter_toggles_tag (&iter, NULL) || gtk_text_iter_backward_to_tag_toggle (&iter, NULL)) { @@ -715,7 +715,7 @@ fill_buffer (GtkTextBuffer *buffer) gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2); tag = gtk_text_buffer_create_tag (buffer, "end_tag"); - gtk_text_buffer_get_last_iter (buffer, &iter2); + gtk_text_buffer_get_end_iter (buffer, &iter2); gtk_text_iter_backward_chars (&iter2, 12); iter = iter2; gtk_text_iter_backward_chars (&iter, 157); diff --git a/tests/testgtk.c b/tests/testgtk.c index f257346ac9..97bf5e270d 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -2004,6 +2004,59 @@ create_sensitivity_control (GtkWidget *widget) return button; } +static void +set_selectable_recursive (GtkWidget *widget, + gboolean setting) +{ + if (GTK_IS_CONTAINER (widget)) + { + GList *children; + GList *tmp; + + children = gtk_container_children (GTK_CONTAINER (widget)); + tmp = children; + while (tmp) + { + set_selectable_recursive (tmp->data, setting); + + tmp = tmp->next; + } + g_list_free (children); + } + else if (GTK_IS_LABEL (widget)) + { + gtk_label_set_selectable (GTK_LABEL (widget), setting); + } +} + +static void +selectable_toggled (GtkWidget *toggle, + GtkWidget *widget) +{ + set_selectable_recursive (widget, + GTK_TOGGLE_BUTTON (toggle)->active); +} + +static GtkWidget* +create_selectable_control (GtkWidget *widget) +{ + GtkWidget *button; + + button = gtk_toggle_button_new_with_label ("Selectable"); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), + FALSE); + + gtk_signal_connect (GTK_OBJECT (button), + "toggled", + GTK_SIGNAL_FUNC (selectable_toggled), + widget); + + gtk_widget_show_all (button); + + return button; +} + void create_labels (void) { static GtkWidget *window = NULL; @@ -2034,6 +2087,10 @@ void create_labels (void) button = create_sensitivity_control (hbox); gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + + button = create_selectable_control (hbox); + + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); vbox = gtk_vbox_new (FALSE, 5); @@ -6201,6 +6258,7 @@ create_range_controls (void) GtkWidget *scale; GtkWidget *separator; GtkObject *adjustment; + GtkWidget *hbox; if (!window) { @@ -6241,6 +6299,25 @@ create_range_controls (void) gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0); gtk_widget_show (scrollbar); + hbox = gtk_hbox_new (FALSE, 0); + + scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment)); + gtk_widget_set_usize (scale, -1, 200); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + scale = gtk_vscale_new (GTK_ADJUSTMENT (adjustment)); + gtk_widget_set_usize (scale, -1, 200); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE); + gtk_range_set_inverted (GTK_RANGE (scale), TRUE); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); separator = gtk_hseparator_new (); gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0); diff --git a/tests/testtext.c b/tests/testtext.c index 85c662ef0e..292681e2be 100644 --- a/tests/testtext.c +++ b/tests/testtext.c @@ -665,7 +665,7 @@ fill_file_buffer (GtkTextBuffer *buffer, const char *filename) /* We had a newline in the buffer to begin with. (The buffer always contains * a newline, so we delete to the end of the buffer to clean up. */ - gtk_text_buffer_get_last_iter (buffer, &end); + gtk_text_buffer_get_end_iter (buffer, &end); gtk_text_buffer_delete (buffer, &iter, &end); gtk_text_buffer_set_modified (buffer, FALSE); @@ -1281,7 +1281,7 @@ save_buffer (Buffer *buffer) else { gtk_text_buffer_get_iter_at_offset (buffer->buffer, &start, 0); - gtk_text_buffer_get_last_iter (buffer->buffer, &end); + gtk_text_buffer_get_end_iter (buffer->buffer, &end); chars = gtk_text_buffer_get_slice (buffer->buffer, &start, &end, FALSE); @@ -1972,7 +1972,7 @@ get_lines (GtkTextView *text_view, count = 0; size = 0; - while (!gtk_text_iter_is_last (&iter)) + while (!gtk_text_iter_is_end (&iter)) { gint y, height; gint line_num; diff --git a/tests/testtextbuffer.c b/tests/testtextbuffer.c index b14ce64eef..0d42dcb19a 100644 --- a/tests/testtextbuffer.c +++ b/tests/testtextbuffer.c @@ -186,7 +186,7 @@ check_specific_tag (GtkTextBuffer *buffer, state = FALSE; count = 0; - gtk_text_buffer_get_last_iter (buffer, &iter); + gtk_text_buffer_get_end_iter (buffer, &iter); last_offset = gtk_text_iter_get_offset (&iter); if (gtk_text_iter_toggles_tag (&iter, tag) || gtk_text_iter_backward_to_tag_toggle (&iter, tag)) @@ -292,7 +292,7 @@ run_tests (GtkTextBuffer *buffer) g_error ("Mark not created in the right place."); } - if (gtk_text_iter_is_last (&iter)) + if (gtk_text_iter_is_end (&iter)) g_error ("iterators ran out before chars (offset %d of %d)", i, num_chars); @@ -474,7 +474,7 @@ run_tests (GtkTextBuffer *buffer) tag_states = g_hash_table_new (NULL, NULL); count = 0; - gtk_text_buffer_get_last_iter (buffer, &iter); + gtk_text_buffer_get_end_iter (buffer, &iter); if (gtk_text_iter_toggles_tag (&iter, NULL) || gtk_text_iter_backward_to_tag_toggle (&iter, NULL)) { @@ -715,7 +715,7 @@ fill_buffer (GtkTextBuffer *buffer) gtk_text_buffer_apply_tag (buffer, tag, &iter, &iter2); tag = gtk_text_buffer_create_tag (buffer, "end_tag"); - gtk_text_buffer_get_last_iter (buffer, &iter2); + gtk_text_buffer_get_end_iter (buffer, &iter2); gtk_text_iter_backward_chars (&iter2, 12); iter = iter2; gtk_text_iter_backward_chars (&iter, 157); |