summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog40
-rw-r--r--ChangeLog.pre-2-040
-rw-r--r--ChangeLog.pre-2-1040
-rw-r--r--ChangeLog.pre-2-240
-rw-r--r--ChangeLog.pre-2-440
-rw-r--r--ChangeLog.pre-2-640
-rw-r--r--ChangeLog.pre-2-840
-rw-r--r--gdk/gdkpango.c43
-rw-r--r--gtk/gtkalignment.c175
-rw-r--r--gtk/gtkentry.c2
-rw-r--r--gtk/gtkentry.h6
-rw-r--r--gtk/gtklabel.c686
-rw-r--r--gtk/gtklabel.h15
-rw-r--r--gtk/gtkrange.c53
-rw-r--r--gtk/gtkrange.h9
-rw-r--r--gtk/gtktextbtree.c2
-rw-r--r--gtk/gtktextbtree.h2
-rw-r--r--gtk/gtktextbuffer.c12
-rw-r--r--gtk/gtktextbuffer.h2
-rw-r--r--gtk/gtktextiter.c28
-rw-r--r--gtk/gtktextiter.h2
-rw-r--r--gtk/gtktextlayout.c8
-rw-r--r--gtk/gtktextview.c2
-rw-r--r--gtk/testgtk.c77
-rw-r--r--gtk/testtext.c6
-rw-r--r--gtk/testtextbuffer.c8
-rw-r--r--tests/testgtk.c77
-rw-r--r--tests/testtext.c6
-rw-r--r--tests/testtextbuffer.c8
29 files changed, 1335 insertions, 174 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a0cdd22cd..b495a1029c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 == &gtk_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);