[gtk+/wip/matthiasc/tab-strip] Don't derive from GtkBox
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/tab-strip] Don't derive from GtkBox
- Date: Thu, 26 May 2016 02:21:07 +0000 (UTC)
commit b875aaba99982b6d123dd07ac4d5feadf91809b1
Author: Matthias Clasen <mclasen redhat com>
Date: Wed May 25 21:27:17 2016 -0400
Don't derive from GtkBox
Instead, derive from GtkContainer and use a box gadget to
manage our internal children.
gtk/gtktabstrip.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++----
gtk/gtktabstrip.h | 6 +-
2 files changed, 182 insertions(+), 16 deletions(-)
---
diff --git a/gtk/gtktabstrip.c b/gtk/gtktabstrip.c
index eee7a33..77a3424 100644
--- a/gtk/gtktabstrip.c
+++ b/gtk/gtktabstrip.c
@@ -27,18 +27,21 @@
#include "gtkorientable.h"
#include "gtkscrolledwindow.h"
#include "gtkbutton.h"
+#include "gtkbox.h"
#include "gtkadjustmentprivate.h"
+#include "gtkboxgadgetprivate.h"
+#include "gtkwidgetprivate.h"
/*
* TODO:
* - reordering
* - dnd
- * - use a box gadget instead of GtkBox for tabs
* - improve scrolling: scroll by tabs for click/activation
*/
typedef struct
{
+ GtkCssGadget *gadget;
GtkStack *stack;
GtkPositionType edge;
gboolean closable;
@@ -52,7 +55,7 @@ typedef struct
guint autoscroll_id;
} GtkTabStripPrivate;
-G_DEFINE_TYPE_WITH_PRIVATE (GtkTabStrip, gtk_tab_strip, GTK_TYPE_BOX)
+G_DEFINE_TYPE_WITH_PRIVATE (GtkTabStrip, gtk_tab_strip, GTK_TYPE_CONTAINER)
enum {
PROP_0,
@@ -76,7 +79,37 @@ static void
gtk_tab_strip_add (GtkContainer *container,
GtkWidget *widget)
{
- GTK_CONTAINER_CLASS (gtk_tab_strip_parent_class)->add (container, widget);
+ g_warning ("Can't add children to %s", G_OBJECT_TYPE_NAME (container));
+}
+
+static void
+gtk_tab_strip_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ g_warning ("Can't remove children from %s", G_OBJECT_TYPE_NAME (container));
+}
+
+static void
+gtk_tab_strip_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (container);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ if (include_internals)
+ {
+ (*callback) (priv->start_scroll, callback_data);
+ (*callback) (priv->scrolledwindow, callback_data);
+ (*callback) (priv->end_scroll, callback_data);
+ }
+}
+
+static GType
+gtk_tab_strip_child_type (GtkContainer *container)
+{
+ return G_TYPE_NONE;
}
static void
@@ -93,6 +126,98 @@ gtk_tab_strip_destroy (GtkWidget *widget)
}
static void
+gtk_tab_strip_get_preferred_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ gtk_css_gadget_get_preferred_size (priv->gadget,
+ GTK_ORIENTATION_HORIZONTAL,
+ -1,
+ minimum_size, natural_size,
+ NULL, NULL);
+}
+
+static void
+gtk_tab_strip_get_preferred_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ gtk_css_gadget_get_preferred_size (priv->gadget,
+ GTK_ORIENTATION_VERTICAL,
+ -1,
+ minimum_size, natural_size,
+ NULL, NULL);
+}
+
+static void
+gtk_tab_strip_get_preferred_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ gtk_css_gadget_get_preferred_size (priv->gadget,
+ GTK_ORIENTATION_HORIZONTAL,
+ height,
+ minimum_size, natural_size,
+ NULL, NULL);
+}
+
+static void
+gtk_tab_strip_get_preferred_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ gtk_css_gadget_get_preferred_size (priv->gadget,
+ GTK_ORIENTATION_VERTICAL,
+ width,
+ minimum_size, natural_size,
+ NULL, NULL);
+}
+
+static void
+gtk_tab_strip_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+ GtkAllocation clip;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ gtk_css_gadget_allocate (priv->gadget,
+ allocation,
+ gtk_widget_get_allocated_baseline (widget),
+ &clip);
+
+ gtk_widget_set_clip (widget, &clip);
+}
+
+static gboolean
+gtk_tab_strip_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (widget);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ gtk_css_gadget_draw (priv->gadget, cr);
+
+ return FALSE;
+}
+
+static void
gtk_tab_strip_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -154,6 +279,17 @@ gtk_tab_strip_set_property (GObject *object,
}
}
+static void
+gtk_tab_strip_finalize (GObject *object)
+{
+ GtkTabStrip *self = GTK_TAB_STRIP (object);
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ g_clear_object (&priv->gadget);
+
+ G_OBJECT_CLASS (gtk_tab_strip_parent_class)->finalize (object);
+}
+
static GtkTab *gtk_tab_strip_real_create_tab (GtkTabStrip *self,
GtkWidget *widget);
@@ -166,10 +302,20 @@ gtk_tab_strip_class_init (GtkTabStripClass *klass)
object_class->get_property = gtk_tab_strip_get_property;
object_class->set_property = gtk_tab_strip_set_property;
+ object_class->finalize = gtk_tab_strip_finalize;
widget_class->destroy = gtk_tab_strip_destroy;
+ widget_class->get_preferred_width = gtk_tab_strip_get_preferred_width;
+ widget_class->get_preferred_height = gtk_tab_strip_get_preferred_height;
+ widget_class->get_preferred_width_for_height = gtk_tab_strip_get_preferred_width_for_height;
+ widget_class->get_preferred_height_for_width = gtk_tab_strip_get_preferred_height_for_width;
+ widget_class->size_allocate = gtk_tab_strip_size_allocate;
+ widget_class->draw = gtk_tab_strip_draw;
container_class->add = gtk_tab_strip_add;
+ container_class->remove = gtk_tab_strip_remove;
+ container_class->forall = gtk_tab_strip_forall;
+ container_class->child_type = gtk_tab_strip_child_type;
klass->create_tab = gtk_tab_strip_real_create_tab;
@@ -208,6 +354,17 @@ gtk_tab_strip_class_init (GtkTabStripClass *klass)
gtk_widget_class_set_css_name (widget_class, "tabs");
}
+static gboolean
+gtk_tab_strip_get_orientation (GtkTabStrip *self)
+{
+ GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
+
+ if (priv->edge == GTK_POS_TOP || priv->edge == GTK_POS_BOTTOM)
+ return GTK_ORIENTATION_HORIZONTAL;
+ else
+ return GTK_ORIENTATION_VERTICAL;
+}
+
static void
update_scrolling (GtkTabStrip *self)
{
@@ -217,7 +374,7 @@ update_scrolling (GtkTabStrip *self)
if (priv->scrollable)
{
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (self)) == GTK_ORIENTATION_HORIZONTAL)
+ if (gtk_tab_strip_get_orientation (self) == GTK_ORIENTATION_HORIZONTAL)
hscroll = GTK_POLICY_EXTERNAL;
else
vscroll = GTK_POLICY_EXTERNAL;
@@ -237,7 +394,7 @@ autoscroll_cb (GtkWidget *widget,
GtkAdjustment *adj;
gdouble value;
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (self)) == GTK_ORIENTATION_HORIZONTAL)
+ if (gtk_tab_strip_get_orientation (self) == GTK_ORIENTATION_HORIZONTAL)
adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
else
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
@@ -304,7 +461,7 @@ scroll_button_activate (GtkWidget *button,
GtkAdjustment *adj;
gdouble value;
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (self)) == GTK_ORIENTATION_HORIZONTAL)
+ if (gtk_tab_strip_get_orientation (self) == GTK_ORIENTATION_HORIZONTAL)
adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
else
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
@@ -326,7 +483,7 @@ adjustment_changed (GtkTabStrip *self)
gdouble value;
gboolean at_lower, at_upper;
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (self)) == GTK_ORIENTATION_HORIZONTAL)
+ if (gtk_tab_strip_get_orientation (self) == GTK_ORIENTATION_HORIZONTAL)
adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
else
adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scrolledwindow));
@@ -347,17 +504,25 @@ gtk_tab_strip_init (GtkTabStrip *self)
{
GtkTabStripPrivate *priv = gtk_tab_strip_get_instance_private (self);
GtkAdjustment *adj;
+ GtkCssNode *widget_node;
+
+ gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
priv->edge = GTK_POS_TOP;
priv->scrollable = FALSE;
priv->closable = FALSE;
+ widget_node = gtk_widget_get_css_node (GTK_WIDGET (self));
+ priv->gadget = gtk_box_gadget_new_for_node (widget_node, GTK_WIDGET (self));
+ gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL);
+
priv->start_scroll = gtk_button_new_from_icon_name ("pan-start-symbolic", GTK_ICON_SIZE_MENU);
gtk_button_set_relief (GTK_BUTTON (priv->start_scroll), GTK_RELIEF_NONE);
gtk_widget_show (priv->start_scroll);
gtk_widget_set_no_show_all (priv->start_scroll, TRUE);
gtk_widget_set_focus_on_click (priv->start_scroll, FALSE);
- gtk_box_pack_start (GTK_BOX (self), priv->start_scroll, FALSE, FALSE, 0);
+ gtk_widget_set_parent (priv->start_scroll, GTK_WIDGET (self));
+ gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 0, priv->start_scroll);
g_signal_connect (priv->start_scroll, "button-press-event",
G_CALLBACK (scroll_button_event), self);
g_signal_connect (priv->start_scroll, "button-release-event",
@@ -367,8 +532,9 @@ gtk_tab_strip_init (GtkTabStrip *self)
priv->scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_show (priv->scrolledwindow);
- gtk_box_pack_start (GTK_BOX (self), priv->scrolledwindow, TRUE, TRUE, 0);
-
+ gtk_widget_set_parent (priv->scrolledwindow, GTK_WIDGET (self));
+ gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 1, priv->scrolledwindow);
+ gtk_box_gadget_set_gadget_expand (GTK_BOX_GADGET (priv->gadget), G_OBJECT (priv->scrolledwindow), TRUE);
update_scrolling (self);
priv->end_scroll = gtk_button_new_from_icon_name ("pan-end-symbolic", GTK_ICON_SIZE_MENU);
@@ -376,7 +542,8 @@ gtk_tab_strip_init (GtkTabStrip *self)
gtk_widget_show (priv->end_scroll);
gtk_widget_set_no_show_all (priv->end_scroll, TRUE);
gtk_widget_set_focus_on_click (priv->end_scroll, FALSE);
- gtk_box_pack_start (GTK_BOX (self), priv->end_scroll, FALSE, FALSE, 0);
+ gtk_widget_set_parent (priv->end_scroll, GTK_WIDGET (self));
+ gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 2, priv->end_scroll);
g_signal_connect (priv->end_scroll, "button-press-event",
G_CALLBACK (scroll_button_event), self);
g_signal_connect (priv->end_scroll, "button-release-event",
@@ -392,7 +559,6 @@ gtk_tab_strip_init (GtkTabStrip *self)
g_signal_connect_swapped (adj, "changed", G_CALLBACK (adjustment_changed), self);
g_signal_connect_swapped (adj, "value-changed", G_CALLBACK (adjustment_changed), self);
-
priv->tabs = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_show (priv->tabs);
gtk_container_add (GTK_CONTAINER (priv->scrolledwindow), priv->tabs);
@@ -701,7 +867,7 @@ gtk_tab_strip_set_edge (GtkTabStrip *self,
gtk_style_context_add_class (context, classes[priv->edge]);
orientation = orientations[priv->edge];
- gtk_orientable_set_orientation (GTK_ORIENTABLE (self), orientation);
+ gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), orientation);
gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->tabs), orientation);
image = gtk_button_get_image (GTK_BUTTON (priv->start_scroll));
diff --git a/gtk/gtktabstrip.h b/gtk/gtktabstrip.h
index 2a38dd2..92f3993 100644
--- a/gtk/gtktabstrip.h
+++ b/gtk/gtktabstrip.h
@@ -23,7 +23,7 @@
#ifndef __GTK_TAB_STRIP_H__
#define __GTK_TAB_STRIP_H__
-#include <gtk/gtkbox.h>
+#include <gtk/gtkcontainer.h>
#include <gtk/gtkstack.h>
#include <gtk/gtktab.h>
#include <gtk/gtktypebuiltins.h>
@@ -42,12 +42,12 @@ typedef struct _GtkTabStripClass GtkTabStripClass;
struct _GtkTabStrip
{
- GtkBox parent;
+ GtkContainer parent;
};
struct _GtkTabStripClass
{
- GtkBoxClass parent_class;
+ GtkContainerClass parent_class;
GtkTab * (* create_tab) (GtkTabStrip *self,
GtkWidget *child);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]