Permalink
Browse files

Make GeanyWrapLabel work with GTK3

Although theoretically GtkLabel from GTK3 should be able to replace
GeanyWrapLabel altogether, a bug [1] with it makes it use way too much
space in our about dialog (and possibly other places), making it not
really usable.

So, port the GeanyWrapLabel hack to GTK3, with the appropriate
additional hacks for it to work.  At least it looks good and don't
seem to have resizing issues now.

[1] https://bugzilla.gnome.org/show_bug.cgi?id=657621
  • Loading branch information...
1 parent caf207c commit d6fba7ac8244ebf077e76468a5072552fa02aa89 @b4n b4n committed Sep 16, 2012
Showing with 96 additions and 31 deletions.
  1. +96 −6 src/geanywraplabel.c
  2. +0 −25 src/geanywraplabel.h
View
102 src/geanywraplabel.c
@@ -29,8 +29,6 @@
#include "utils.h"
#include "geanywraplabel.h"
-#if ! GTK_CHECK_VERSION(3, 0, 0)
-
struct _GeanyWrapLabelClass
{
@@ -50,9 +48,22 @@ struct _GeanyWrapLabel
};
+#if GTK_CHECK_VERSION(3, 0, 0)
+static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr);
+static void geany_wrap_label_get_preferred_width (GtkWidget *widget,
+ gint *minimal_width, gint *natural_width);
+static void geany_wrap_label_get_preferred_height (GtkWidget *widget,
+ gint *minimal_height, gint *natural_height);
+static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+ gint height, gint *minimal_width, gint *natural_width);
+static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+ gint width, gint *minimal_height, gint *natural_height);
+static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget);
+#else
+static gboolean geany_wrap_label_expose (GtkWidget *widget, GdkEventExpose *event);
static void geany_wrap_label_size_request (GtkWidget *widget, GtkRequisition *req);
+#endif
static void geany_wrap_label_size_allocate (GtkWidget *widget, GtkAllocation *alloc);
-static gboolean geany_wrap_label_expose (GtkWidget *widget, GdkEventExpose *event);
static void geany_wrap_label_set_wrap_width (GtkWidget *widget, gint width);
static void geany_wrap_label_label_notify (GObject *object, GParamSpec *pspec, gpointer data);
@@ -63,9 +74,18 @@ static void geany_wrap_label_class_init(GeanyWrapLabelClass *klass)
{
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->size_request = geany_wrap_label_size_request;
widget_class->size_allocate = geany_wrap_label_size_allocate;
+#if GTK_CHECK_VERSION(3, 0, 0)
+ widget_class->draw = geany_wrap_label_draw;
+ widget_class->get_preferred_width = geany_wrap_label_get_preferred_width;
+ widget_class->get_preferred_width_for_height = geany_wrap_label_get_preferred_width_for_height;
+ widget_class->get_preferred_height = geany_wrap_label_get_preferred_height;
+ widget_class->get_preferred_height_for_width = geany_wrap_label_get_preferred_height_for_width;
+ widget_class->get_request_mode = geany_wrap_label_get_request_mode;
+#else
+ widget_class->size_request = geany_wrap_label_size_request;
widget_class->expose_event = geany_wrap_label_expose;
+#endif
g_type_class_add_private(klass, sizeof (GeanyWrapLabelPrivate));
}
@@ -120,6 +140,67 @@ static void geany_wrap_label_label_notify(GObject *object, GParamSpec *pspec, gp
}
+#if GTK_CHECK_VERSION(3, 0, 0)
+/* makes sure the layout is setup for rendering and chains to parent renderer */
+static gboolean geany_wrap_label_draw(GtkWidget *widget, cairo_t *cr)
+{
+ GeanyWrapLabel *self = GEANY_WRAP_LABEL(widget);
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+ pango_layout_set_width(layout, self->priv->wrap_width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+
+ return (* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->draw)(widget, cr);
+}
+
+
+static void geany_wrap_label_get_preferred_width (GtkWidget *widget,
+ gint *minimal_width, gint *natural_width)
+{
+ *minimal_width = *natural_width = 0;
+}
+
+
+static void geany_wrap_label_get_preferred_width_for_height (GtkWidget *widget,
+ gint height, gint *minimal_width, gint *natural_width)
+{
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));;
+
+ pango_layout_set_height(layout, height * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_get_pixel_size(layout, natural_width, NULL);
+
+ *minimal_width = 0;
+}
+
+
+static void geany_wrap_label_get_preferred_height (GtkWidget *widget,
+ gint *minimal_height, gint *natural_height)
+{
+ *minimal_height = *natural_height = GEANY_WRAP_LABEL(widget)->priv->wrap_height;
+}
+
+
+static void geany_wrap_label_get_preferred_height_for_width (GtkWidget *widget,
+ gint width, gint *minimal_height, gint *natural_height)
+{
+ PangoLayout *layout = gtk_label_get_layout(GTK_LABEL(widget));
+
+ pango_layout_set_width(layout, width * PANGO_SCALE);
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_get_pixel_size(layout, NULL, natural_height);
+
+ *minimal_height = *natural_height;
+}
+
+
+static GtkSizeRequestMode geany_wrap_label_get_request_mode(GtkWidget *widget)
+{
+ return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
+#else /* GTK3 */
+
/* makes sure the layout is setup for rendering and chains to parent renderer */
static gboolean geany_wrap_label_expose(GtkWidget *widget, GdkEventExpose *event)
{
@@ -140,6 +221,7 @@ static void geany_wrap_label_size_request(GtkWidget *widget, GtkRequisition *req
req->width = 0;
req->height = GEANY_WRAP_LABEL(widget)->priv->wrap_height;
}
+#endif /* GTK3 */
/* Sets the wrap width to the width allocated to us. */
@@ -148,12 +230,20 @@ static void geany_wrap_label_size_allocate(GtkWidget *widget, GtkAllocation *all
(* GTK_WIDGET_CLASS(geany_wrap_label_parent_class)->size_allocate)(widget, alloc);
geany_wrap_label_set_wrap_width(widget, alloc->width);
+
+#if GTK_CHECK_VERSION(3, 0, 0)
+{
+ /* ask the parent to recompute our size, because it seems GTK3 size
+ * caching is too aggressive */
+ GtkWidget *parent = gtk_widget_get_parent(widget);
+ if (GTK_IS_CONTAINER(parent))
+ gtk_container_check_resize(GTK_CONTAINER(parent));
+}
+#endif
}
GtkWidget *geany_wrap_label_new(const gchar *text)
{
return g_object_new(GEANY_WRAP_LABEL_TYPE, "label", text, NULL);
}
-
-#endif
View
25 src/geanywraplabel.h
@@ -25,8 +25,6 @@
G_BEGIN_DECLS
-#if ! GTK_CHECK_VERSION(3, 0, 0)
-
#define GEANY_WRAP_LABEL_TYPE (geany_wrap_label_get_type())
#define GEANY_WRAP_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GEANY_WRAP_LABEL_TYPE, GeanyWrapLabel))
@@ -44,29 +42,6 @@ typedef struct _GeanyWrapLabelClass GeanyWrapLabelClass;
GType geany_wrap_label_get_type (void);
GtkWidget* geany_wrap_label_new (const gchar *text);
-#else /* GTK 3.0 */
-
-#define GEANY_WRAP_LABEL_TYPE GTK_TYPE_LABEL
-#define GEANY_WRAP_LABEL GTK_LABEL
-#define GEANY_WRAP_LABEL_CLASS GTK_LABEL_CLASS
-#define IS_GEANY_WRAP_LABEL GTK_IS_LABEL
-#define IS_GEANY_WRAP_LABEL_CLASS GTK_IS_LABEL_CLASS
-
-#define GeanyWrapLabel GtkLabel
-#define GeanyWrapLabelClass GtkLabelClass
-
-#define geany_wrap_label_get_type gtk_label_get_type
-#define geany_wrap_label_new(text) \
- g_object_new(GTK_TYPE_LABEL, \
- "label", (text), \
- "wrap", TRUE, \
- "wrap-mode", PANGO_WRAP_WORD_CHAR, \
- "xalign", 0.0, \
- "yalign", 0.0, \
- NULL)
-
-#endif
-
G_END_DECLS

0 comments on commit d6fba7a

Please sign in to comment.