[gtk+/wip/actor: 8/24] actors: Add GtkCssBox
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/actor: 8/24] actors: Add GtkCssBox
- Date: Sat, 5 Jan 2013 19:23:09 +0000 (UTC)
commit bbe48d8144f071a3e9a562efbf7fb89e00eb89ba
Author: Benjamin Otte <otte redhat com>
Date: Fri Dec 7 12:29:13 2012 +0100
actors: Add GtkCssBox
GtkCssBox is an actor that does 2 things:
(1) It manages the styles
(2) It implements the CSS box model and provides for margin, padding and
border
And with this, GtkCssBox will be pretty much the most important layout
element when creating widgets.
gtk/actors/Makefile.am | 2 +
gtk/actors/gtkcssactor.c | 4 +-
gtk/actors/gtkcssbox.c | 662 +++++++++++++++++++++++++++++++++++++++++
gtk/actors/gtkcssboxprivate.h | 72 +++++
4 files changed, 738 insertions(+), 2 deletions(-)
---
diff --git a/gtk/actors/Makefile.am b/gtk/actors/Makefile.am
index ec6bf9a..2c56221 100644
--- a/gtk/actors/Makefile.am
+++ b/gtk/actors/Makefile.am
@@ -6,12 +6,14 @@ gtkactors_c_sources = \
gtkactor.c \
gtkbinlayout.c \
gtkcssactor.c \
+ gtkcssbox.c \
gtklayoutmanager.c
gtkactors_private_h_sources = \
gtkactorprivate.h \
gtkbinlayoutprivate.h \
gtkcssactorprivate.h \
+ gtkcssboxprivate.h \
gtklayoutmanagerprivate.h
libgtkactors_la_SOURCES = \
diff --git a/gtk/actors/gtkcssactor.c b/gtk/actors/gtkcssactor.c
index 3100891..5092909 100644
--- a/gtk/actors/gtkcssactor.c
+++ b/gtk/actors/gtkcssactor.c
@@ -21,6 +21,7 @@
#include "gtkcssactorprivate.h"
+#include "gtkcssboxprivate.h"
#include "gtkdebug.h"
#include "gtkintl.h"
#include "gtkprivate.h"
@@ -47,8 +48,7 @@ G_DEFINE_TYPE (GtkCssActor, _gtk_css_actor, GTK_TYPE_ACTOR)
static gboolean
gtk_css_actor_owns_context (GtkCssActor *actor)
{
- g_warning ("FIXME: owns context");
- return FALSE;
+ return GTK_IS_CSS_BOX (actor);
}
static void
diff --git a/gtk/actors/gtkcssbox.c b/gtk/actors/gtkcssbox.c
new file mode 100644
index 0000000..1f250e4
--- /dev/null
+++ b/gtk/actors/gtkcssbox.c
@@ -0,0 +1,662 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include "config.h"
+
+#include "gtkcssboxprivate.h"
+
+#include "gtkcssenumvalueprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkcsstypesprivate.h"
+#include "gtkdebug.h"
+#include "gtkintl.h"
+#include "gtklayoutmanagerprivate.h"
+#include "gtkprivate.h"
+#include "gtkstylecontext.h"
+#include "gtkstylecontextprivate.h"
+#include "gtktypebuiltins.h"
+
+/* state flags that when set will automatically be set on all parents */
+#define GTK_STATE_FLAGS_PROPAGATE_TO_PARENT (GTK_STATE_FLAG_PRELIGHT)
+
+/* state flags that when set will automatically propagate to all children */
+#define GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN (GTK_STATE_FLAG_INSENSITIVE | GTK_STATE_FLAG_BACKDROP)
+
+G_STATIC_ASSERT((GTK_STATE_FLAGS_PROPAGATE_TO_PARENT & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN) == 0);
+
+#define GTK_STATE_FLAGS_NO_PROPAGATE (~(GTK_STATE_FLAGS_PROPAGATE_TO_PARENT | GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN))
+
+struct _GtkCssBoxPrivate {
+ GtkStateFlags state;
+
+ char * id;
+};
+
+enum
+{
+ PROP_0,
+
+ PROP_EFFECTIVE_STATE,
+ PROP_STATE,
+ PROP_ID,
+
+ PROP_LAST
+};
+
+static GParamSpec *obj_props[PROP_LAST];
+
+G_DEFINE_TYPE (GtkCssBox, _gtk_css_box, GTK_TYPE_CSS_ACTOR)
+
+static void
+gtk_css_box_set_effective_state (GtkCssBox *box,
+ GtkStateFlags state)
+{
+ gtk_style_context_set_state (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (box)), state);
+ g_object_notify_by_pspec (G_OBJECT (box), obj_props[PROP_EFFECTIVE_STATE]);
+}
+
+GtkStateFlags
+_gtk_css_box_get_effective_state (GtkCssBox *self)
+{
+ g_return_val_if_fail (GTK_IS_CSS_BOX (self), 0);
+
+ return gtk_style_context_get_state (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)));
+}
+
+static void
+gtk_css_box_update_state_on_parent (GtkCssBox *box,
+ GtkStateFlags state_to_set,
+ GtkStateFlags state_to_unset)
+{
+ GtkStateFlags effective;
+ GtkActor *iter, *parent;
+
+ effective = _gtk_css_box_get_effective_state (box);
+ state_to_set = ~effective & state_to_set;
+ state_to_unset = effective & state_to_unset;
+
+ for (iter = _gtk_actor_get_first_child (GTK_ACTOR (box));
+ iter && state_to_unset != 0;
+ iter = _gtk_actor_get_next_sibling (iter))
+ {
+ if (!GTK_IS_CSS_BOX (iter))
+ continue;
+
+ state_to_unset &= ~_gtk_css_box_get_effective_state (GTK_CSS_BOX (iter));
+ }
+
+ if (state_to_set == 0 && state_to_unset == 0)
+ return;
+
+ gtk_css_box_set_effective_state (box, (effective | state_to_set) & ~state_to_unset);
+
+ parent = _gtk_actor_get_parent (GTK_ACTOR (box));
+ if (GTK_IS_CSS_BOX (parent))
+ gtk_css_box_update_state_on_parent (GTK_CSS_BOX (parent), state_to_set, state_to_unset);
+}
+
+static void
+gtk_css_box_update_state_on_children (GtkCssBox *box,
+ GtkStateFlags state_to_set,
+ GtkStateFlags state_to_unset)
+{
+ GtkStateFlags effective;
+ GtkActor *iter;
+
+ effective = _gtk_css_box_get_effective_state (box);
+ state_to_set = ~effective & state_to_set;
+ state_to_unset = effective & state_to_unset;
+
+ gtk_css_box_set_effective_state (box, (effective | state_to_set) & ~state_to_unset);
+
+ if (state_to_set == 0 && state_to_unset == 0)
+ return;
+
+ for (iter = _gtk_actor_get_first_child (GTK_ACTOR (box));
+ iter;
+ iter = _gtk_actor_get_next_sibling (iter))
+ {
+ if (!GTK_IS_CSS_BOX (iter))
+ continue;
+
+ gtk_css_box_update_state_on_children (GTK_CSS_BOX (iter), state_to_set, state_to_unset);
+ }
+}
+
+static void
+gtk_css_box_finalize (GObject *object)
+{
+ GtkCssBox *self = GTK_CSS_BOX (object);
+ GtkCssBoxPrivate *priv = self->priv;
+
+ g_free (priv->id);
+
+ G_OBJECT_CLASS (_gtk_css_box_parent_class)->finalize (object);
+}
+
+static void
+gtk_css_box_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCssBox *css_box = GTK_CSS_BOX (object);
+
+ switch (prop_id)
+ {
+ case PROP_STATE:
+ _gtk_css_box_set_state (css_box, g_value_get_enum (value));
+ break;
+
+ case PROP_ID:
+ _gtk_css_box_set_id (css_box, g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_css_box_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkCssBox *css_box = GTK_CSS_BOX (object);
+
+ switch (prop_id)
+ {
+ case PROP_EFFECTIVE_STATE:
+ g_value_set_enum (value, _gtk_css_box_get_effective_state (css_box));
+ break;
+
+ case PROP_STATE:
+ g_value_set_enum (value, _gtk_css_box_get_state (css_box));
+ break;
+
+ case PROP_ID:
+ g_value_set_string (value, _gtk_css_box_get_id (css_box));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_css_box_queue_restyle (GtkCssBox *self,
+ GtkCssChange change)
+{
+ _gtk_style_context_queue_invalidate (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)), change);
+}
+
+static void
+gtk_css_box_queue_restyle_siblings (GtkCssBox *self,
+ GtkCssChange change)
+{
+ GtkActor *iter;
+
+ for (iter = _gtk_actor_get_previous_sibling (GTK_ACTOR (self));
+ iter;
+ iter = _gtk_actor_get_previous_sibling (iter))
+ {
+ if (GTK_IS_CSS_BOX (iter))
+ gtk_css_box_queue_restyle (GTK_CSS_BOX (iter), change);
+ }
+
+ for (iter = _gtk_actor_get_next_sibling (GTK_ACTOR (self));
+ iter;
+ iter = _gtk_actor_get_next_sibling (iter))
+ {
+ if (GTK_IS_CSS_BOX (iter))
+ gtk_css_box_queue_restyle (GTK_CSS_BOX (iter), change);
+ }
+}
+
+static void
+gtk_css_box_real_show (GtkActor *self)
+{
+ GtkCssBox *box = GTK_CSS_BOX (self);
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->show (self);
+
+ gtk_css_box_queue_restyle_siblings (box, GTK_CSS_CHANGE_ANY_SIBLING);
+}
+
+static void
+gtk_css_box_real_hide (GtkActor *self)
+{
+ GtkCssBox *box = GTK_CSS_BOX (self);
+
+ gtk_css_box_queue_restyle_siblings (box, GTK_CSS_CHANGE_ANY_SIBLING);
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->hide (self);
+}
+
+static void
+gtk_css_box_real_map (GtkActor *self)
+{
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->map (self);
+
+ _gtk_style_context_update_animating (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)));
+}
+
+static void
+gtk_css_box_real_unmap (GtkActor *self)
+{
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->unmap (self);
+
+ _gtk_style_context_update_animating (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)));
+}
+
+static void
+gtk_css_box_real_parent_set (GtkActor *self,
+ GtkActor *old_parent)
+{
+ GtkCssBox *box = GTK_CSS_BOX (self);
+ GtkActor *parent;
+
+ parent = _gtk_actor_get_parent (self);
+
+ if (old_parent == NULL)
+ {
+ g_warn_if_fail (GTK_IS_CSS_BOX (parent));
+ }
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->parent_set (self, old_parent);
+
+ gtk_style_context_set_parent (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)),
+ parent ? _gtk_css_actor_get_style_context (GTK_CSS_ACTOR (parent)) : NULL);
+
+ if (parent)
+ {
+ gtk_css_box_update_state_on_children (box,
+ _gtk_css_box_get_effective_state (GTK_CSS_BOX (parent)) & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN,
+ 0);
+ gtk_css_box_update_state_on_parent (GTK_CSS_BOX (parent),
+ _gtk_css_box_get_effective_state (box) & GTK_STATE_FLAGS_PROPAGATE_TO_PARENT,
+ 0);
+ }
+ else
+ {
+ gtk_css_box_update_state_on_children (box,
+ 0,
+ _gtk_css_box_get_effective_state (GTK_CSS_BOX (old_parent)) & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN);
+ gtk_css_box_update_state_on_parent (GTK_CSS_BOX (old_parent),
+ 0,
+ _gtk_css_box_get_effective_state (box) & GTK_STATE_FLAGS_PROPAGATE_TO_PARENT);
+ }
+}
+
+static double
+gtk_css_box_get_edge (GtkCssBox *self,
+ GtkCssSide side)
+{
+ const struct {
+ guint margin;
+ guint border;
+ guint border_style;
+ guint padding;
+ } properties[] = {
+ /* [GTK_CSS_TOP] = */ { GTK_CSS_PROPERTY_MARGIN_TOP,
+ GTK_CSS_PROPERTY_BORDER_TOP_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_TOP_STYLE,
+ GTK_CSS_PROPERTY_PADDING_TOP },
+ /* [GTK_CSS_RIGHT] = */ { GTK_CSS_PROPERTY_MARGIN_RIGHT,
+ GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_RIGHT_STYLE,
+ GTK_CSS_PROPERTY_PADDING_RIGHT },
+ /* [GTK_CSS_BOTTOM] = */ { GTK_CSS_PROPERTY_MARGIN_BOTTOM,
+ GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_BOTTOM_STYLE,
+ GTK_CSS_PROPERTY_PADDING_BOTTOM },
+ /* [GTK_CSS_LEFT] = */ { GTK_CSS_PROPERTY_MARGIN_LEFT,
+ GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH,
+ GTK_CSS_PROPERTY_BORDER_LEFT_STYLE,
+ GTK_CSS_PROPERTY_PADDING_LEFT }
+ };
+ GtkStyleContext *context;
+ GtkBorderStyle border_style;
+ double result;
+
+ context = _gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self));
+
+ result = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, properties[side].margin), 100)
+ + _gtk_css_number_value_get (_gtk_style_context_peek_property (context, properties[side].padding), 100);
+
+ border_style = _gtk_css_border_style_value_get (_gtk_style_context_peek_property (context, properties[side].border_style));
+ if (border_style != GTK_BORDER_STYLE_NONE && border_style != GTK_BORDER_STYLE_HIDDEN)
+ result += _gtk_css_number_value_get (_gtk_style_context_peek_property (context, properties[side].border), 100);
+
+ return result;
+}
+
+static void
+adjust_size_for_css (GtkCssBox *self,
+ GtkOrientation orientation,
+ gfloat *min_size_p,
+ gfloat *nat_size_p)
+{
+ GtkStyleContext *context;
+ gfloat min_css, nat_css;
+
+ context = _gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self));
+
+ min_css = _gtk_css_number_value_get (
+ _gtk_style_context_peek_property (context,
+ orientation == GTK_ORIENTATION_HORIZONTAL ? GTK_CSS_PROPERTY_MIN_WIDTH
+ : GTK_CSS_PROPERTY_MIN_HEIGHT), 0);
+ nat_css = _gtk_css_number_value_get (
+ _gtk_style_context_peek_property (context,
+ orientation == GTK_ORIENTATION_HORIZONTAL ? GTK_CSS_PROPERTY_MAX_WIDTH
+ : GTK_CSS_PROPERTY_MAX_HEIGHT), 0);
+
+ *min_size_p = MAX (min_css, *min_size_p);
+ *nat_size_p = MIN (nat_css, *nat_size_p);
+ *nat_size_p = MAX (*min_size_p, *nat_size_p);
+}
+
+static void
+gtk_css_box_real_get_preferred_size (GtkActor *self,
+ GtkOrientation orientation,
+ gfloat for_size,
+ gfloat *min_size_p,
+ gfloat *nat_size_p)
+{
+ GtkCssBox *box = GTK_CSS_BOX (self);
+ float extra_size;
+
+ if (for_size >= 0)
+ {
+ if (orientation == GTK_ORIENTATION_VERTICAL)
+ extra_size = gtk_css_box_get_edge (box, GTK_CSS_LEFT) + gtk_css_box_get_edge (box, GTK_CSS_RIGHT);
+ else
+ extra_size = gtk_css_box_get_edge (box, GTK_CSS_TOP) + gtk_css_box_get_edge (box, GTK_CSS_BOTTOM);
+
+ for_size = MAX (0, for_size - extra_size);
+ }
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->get_preferred_size (self, orientation, for_size, min_size_p, nat_size_p);
+
+ adjust_size_for_css (box, orientation, min_size_p, nat_size_p);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ extra_size = gtk_css_box_get_edge (box, GTK_CSS_LEFT) + gtk_css_box_get_edge (box, GTK_CSS_RIGHT);
+ else
+ extra_size = gtk_css_box_get_edge (box, GTK_CSS_TOP) + gtk_css_box_get_edge (box, GTK_CSS_BOTTOM);
+
+ *min_size_p = MAX (0, *min_size_p + extra_size);
+ *nat_size_p = MAX (0, *nat_size_p + extra_size);
+}
+
+static void
+gtk_css_box_real_allocate (GtkActor *actor,
+ const cairo_matrix_t *position,
+ gfloat width,
+ gfloat height)
+{
+ GtkCssBox *self = GTK_CSS_BOX (actor);
+ GtkLayoutManager *layout_manager;
+
+ layout_manager = _gtk_actor_get_layout_manager (actor);
+
+ if (layout_manager)
+ {
+ cairo_matrix_t transform;
+ double top, left, bottom, right;
+
+ top = gtk_css_box_get_edge (self, GTK_CSS_TOP);
+ left = gtk_css_box_get_edge (self, GTK_CSS_LEFT);
+ bottom = gtk_css_box_get_edge (self, GTK_CSS_BOTTOM);
+ right = gtk_css_box_get_edge (self, GTK_CSS_RIGHT);
+
+ cairo_matrix_init_translate (&transform, left, top);
+
+ _gtk_layout_manager_allocate (layout_manager,
+ &transform,
+ width - left - right,
+ height - top - bottom);
+ }
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->allocate (actor, position, width, height);
+}
+
+static void
+gtk_css_box_real_draw (GtkActor *actor,
+ cairo_t *cr)
+{
+ GtkCssBox *self = GTK_CSS_BOX (actor);
+ GtkStyleContext *context;
+ double width, height;
+ double top, left, bottom, right;
+
+ context = _gtk_css_actor_get_style_context (GTK_CSS_ACTOR (actor));
+ top = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_MARGIN_TOP), 100);
+ right = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_MARGIN_RIGHT), 100);
+ bottom = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_MARGIN_BOTTOM), 100);
+ left = _gtk_css_number_value_get (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_MARGIN_LEFT), 100);
+ width = _gtk_actor_get_width (actor) - left - right;
+ height = _gtk_actor_get_height (actor) - bottom - top;
+
+ gtk_render_background (context,
+ cr,
+ left, top,
+ width, height);
+ gtk_render_frame (context,
+ cr,
+ left, top,
+ width, height);
+
+ cairo_translate (cr,
+ gtk_css_box_get_edge (self, GTK_CSS_LEFT),
+ gtk_css_box_get_edge (self, GTK_CSS_TOP));
+
+ GTK_ACTOR_CLASS (_gtk_css_box_parent_class)->draw (actor, cr);
+}
+
+static void
+_gtk_css_box_class_init (GtkCssBoxClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkActorClass *actor_class = GTK_ACTOR_CLASS (klass);
+
+ object_class->finalize = gtk_css_box_finalize;
+ object_class->set_property = gtk_css_box_set_property;
+ object_class->get_property = gtk_css_box_get_property;
+
+ actor_class->show = gtk_css_box_real_show;
+ actor_class->hide = gtk_css_box_real_hide;
+ actor_class->map = gtk_css_box_real_map;
+ actor_class->unmap = gtk_css_box_real_unmap;
+ actor_class->draw = gtk_css_box_real_draw;
+ actor_class->parent_set = gtk_css_box_real_parent_set;
+ actor_class->get_preferred_size = gtk_css_box_real_get_preferred_size;
+ actor_class->allocate = gtk_css_box_real_allocate;
+
+ /**
+ * GtkCssBox:state:
+ *
+ * The state flags explicitly set on the box.
+ *
+ * See also GtkCssBox:effective-state.
+ */
+ obj_props[PROP_STATE] =
+ g_param_spec_flags ("state",
+ P_("State"),
+ P_("State flags set on the box"),
+ GTK_TYPE_STATE_FLAGS,
+ 0,
+ GTK_PARAM_READWRITE);
+
+ /**
+ * GtkCssBox:effective-state:
+ *
+ * The state flags explicitly set on the box. These are the flags cpomputed
+ * from the box's own state and propagated state from parent or children boxes.
+ *
+ * See also GtkCssBox:state.
+ */
+ obj_props[PROP_EFFECTIVE_STATE] =
+ g_param_spec_flags ("effective-state",
+ P_("Effective State"),
+ P_("Effective state computed for the box"),
+ GTK_TYPE_STATE_FLAGS,
+ 0,
+ GTK_PARAM_READWRITE);
+
+ /**
+ * GtkCssBox:id:
+ *
+ * The ID given to this box or %NULL if the box does not have an ID. This is the
+ * default.
+ *
+ * The ID is used for matching in CSS and is supposed to be unique for an actor tree.
+ * Currently this is not enforced, but it might be in the future.
+ */
+ obj_props[PROP_ID] =
+ g_param_spec_string ("id",
+ P_("ID"),
+ P_("ID given to this actor"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ g_type_class_add_private (klass, sizeof (GtkCssBoxPrivate));
+}
+
+static void
+_gtk_css_box_init (GtkCssBox *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ GTK_TYPE_CSS_BOX,
+ GtkCssBoxPrivate);
+
+ _gtk_css_actor_init_box (GTK_CSS_ACTOR (self));
+}
+
+GtkActor *
+_gtk_css_box_new (void)
+{
+ return g_object_new (GTK_TYPE_CSS_BOX, NULL);
+}
+
+void
+_gtk_css_box_set_state (GtkCssBox *self,
+ GtkStateFlags state)
+{
+ GtkCssBoxPrivate *priv;
+ GtkStateFlags changed;
+
+ g_return_if_fail (GTK_IS_CSS_BOX (self));
+
+ priv = self->priv;
+
+ if (priv->state == state)
+ return;
+
+ g_object_freeze_notify (G_OBJECT (self));
+
+ changed = priv->state ^ state;
+
+ priv->state = state;
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_STATE]);
+
+ if (changed & GTK_STATE_FLAGS_PROPAGATE_TO_PARENT)
+ gtk_css_box_update_state_on_parent (self,
+ state & changed & GTK_STATE_FLAGS_PROPAGATE_TO_PARENT,
+ ~state & changed & GTK_STATE_FLAGS_PROPAGATE_TO_PARENT);
+ if (changed & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN)
+ gtk_css_box_update_state_on_children (self,
+ state & changed & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN,
+ ~state & changed & GTK_STATE_FLAGS_PROPAGATE_TO_CHILDREN);
+
+ gtk_css_box_set_effective_state (self,
+ (_gtk_css_box_get_effective_state (self) & GTK_STATE_FLAGS_NO_PROPAGATE)
+ | (state & ~GTK_STATE_FLAGS_NO_PROPAGATE));
+
+ g_object_thaw_notify (G_OBJECT (self));
+}
+
+GtkStateFlags
+_gtk_css_box_get_state (GtkCssBox *self)
+{
+ g_return_val_if_fail (GTK_IS_CSS_BOX (self), 0);
+
+ return self->priv->state;
+}
+
+void
+_gtk_css_box_add_class (GtkCssBox *self,
+ const gchar *class_name)
+{
+ g_return_if_fail (GTK_IS_CSS_BOX (self));
+ g_return_if_fail (class_name != NULL);
+
+ gtk_style_context_add_class (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)), class_name);
+}
+
+void
+_gtk_css_box_remove_class (GtkCssBox *self,
+ const gchar *class_name)
+{
+ g_return_if_fail (GTK_IS_CSS_BOX (self));
+ g_return_if_fail (class_name != NULL);
+
+ gtk_style_context_remove_class (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)), class_name);
+}
+
+gboolean
+_gtk_css_box_has_class (GtkCssBox *self,
+ const gchar *class_name)
+{
+ g_return_val_if_fail (GTK_IS_CSS_BOX (self), FALSE);
+ g_return_val_if_fail (class_name != NULL, FALSE);
+
+ return gtk_style_context_has_class (_gtk_css_actor_get_style_context (GTK_CSS_ACTOR (self)), class_name);
+}
+
+void
+_gtk_css_box_set_id (GtkCssBox *self,
+ const char *id)
+{
+ GtkCssBoxPrivate *priv;
+
+ g_return_if_fail (GTK_IS_CSS_BOX (self));
+
+ priv = self->priv;
+
+ if (g_strcmp0 (priv->id, id) == 0)
+ return;
+
+ g_free (priv->id);
+ priv->id = g_strdup (id);
+
+ gtk_css_box_queue_restyle (self, GTK_CSS_CHANGE_NAME);
+ g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ID]);
+}
+
+const char *
+_gtk_css_box_get_id (GtkCssBox *self)
+{
+ g_return_val_if_fail (GTK_IS_CSS_BOX (self), NULL);
+
+ return self->priv->id;
+}
diff --git a/gtk/actors/gtkcssboxprivate.h b/gtk/actors/gtkcssboxprivate.h
new file mode 100644
index 0000000..ad4b803
--- /dev/null
+++ b/gtk/actors/gtkcssboxprivate.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright  2012 Red Hat Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_CSS_BOX_PRIVATE_H__
+#define __GTK_CSS_BOX_PRIVATE_H__
+
+#include <gtk/actors/gtkcssactorprivate.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CSS_BOX (_gtk_css_box_get_type ())
+#define GTK_CSS_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_CSS_BOX, GtkCssBox))
+#define GTK_CSS_BOX_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_CSS_BOX, GtkCssBoxClass))
+#define GTK_IS_CSS_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_CSS_BOX))
+#define GTK_IS_CSS_BOX_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_CSS_BOX))
+#define GTK_CSS_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CSS_BOX, GtkCssBoxClass))
+
+typedef struct _GtkCssBox GtkCssBox;
+typedef struct _GtkCssBoxPrivate GtkCssBoxPrivate;
+typedef struct _GtkCssBoxClass GtkCssBoxClass;
+typedef struct _GtkCssBoxIter GtkCssBoxIter;
+
+struct _GtkCssBox
+{
+ GtkCssActor parent;
+
+ GtkCssBoxPrivate *priv;
+};
+
+struct _GtkCssBoxClass
+{
+ GtkCssActorClass parent_class;
+};
+
+GType _gtk_css_box_get_type (void) G_GNUC_CONST;
+
+GtkActor * _gtk_css_box_new (void);
+
+void _gtk_css_box_set_state (GtkCssBox *self,
+ GtkStateFlags state);
+GtkStateFlags _gtk_css_box_get_state (GtkCssBox *self);
+GtkStateFlags _gtk_css_box_get_effective_state (GtkCssBox *self);
+
+void _gtk_css_box_set_id (GtkCssBox *self,
+ const char *id);
+const char * _gtk_css_box_get_id (GtkCssBox *self);
+void _gtk_css_box_add_class (GtkCssBox *self,
+ const gchar *class_name);
+void _gtk_css_box_remove_class (GtkCssBox *self,
+ const gchar *class_name);
+gboolean _gtk_css_box_has_class (GtkCssBox *self,
+ const gchar *class_name);
+
+G_END_DECLS
+
+#endif /* __GTK_CSS_BOX_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]