[gnome-shell] Add StGroup container



commit 1e3bf0ea7e5c266a445bdf341b0f3bbabd4eb516
Author: Florian Müllner <fmuellner src gnome org>
Date:   Mon Mar 22 01:26:19 2010 +0100

    Add StGroup container
    
    Currently if we want a stylable fixed-layout container, we use either
    a Clutter.Group inside an St.Bin, or we abuse St.BoxLayout.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=613907

 src/Makefile-st.am |    2 +
 src/st/st-group.c  |  232 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/st/st-group.h  |   71 ++++++++++++++++
 3 files changed, 305 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile-st.am b/src/Makefile-st.am
index d3597fd..b3cc7aa 100644
--- a/src/Makefile-st.am
+++ b/src/Makefile-st.am
@@ -77,6 +77,7 @@ st_source_h =					\
     st/st-container.h				\
     st/st-drawing-area.h        \
     st/st-entry.h				\
+    st/st-group.h				\
     st/st-im-text.h				\
     st/st-label.h				\
     st/st-overflow-box.h        \
@@ -124,6 +125,7 @@ st_source_c =					\
     st/st-container.c				\
     st/st-drawing-area.c        \
     st/st-entry.c				\
+    st/st-group.c				\
     st/st-im-text.c				\
     st/st-label.c				\
     st/st-overflow-box.c        \
diff --git a/src/st/st-group.c b/src/st/st-group.c
new file mode 100644
index 0000000..690f7a7
--- /dev/null
+++ b/src/st/st-group.c
@@ -0,0 +1,232 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * st-group.h: A fixed layout container based on ClutterGroup
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+/**
+ * SECTION:st-group
+ * SECTION:clutter-group
+ * @short_description: A fixed layout container
+ *
+ * A #StGroup is an Actor which contains multiple child actors positioned
+ * relative to the #StGroup position. Other operations such as scaling,
+ * rotating and clipping of the group will apply to the child actors.
+ *
+ * A #StGroup's size is defined by the size and position of its children;
+ * it will be the smallest non-negative size that covers the right and bottom
+ * edges of all of its children.
+ *
+ * Setting the size on a Group using #ClutterActor methods like
+ * clutter_actor_set_size() will override the natural size of the Group,
+ * however this will not affect the size of the children and they may still
+ * be painted outside of the allocation of the group. One way to constrain
+ * the visible area of a #StGroup to a specified allocation is to
+ * explicitly set the size of the #StGroup and then use the
+ * #ClutterActor:clip-to-allocation property.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <clutter/clutter.h>
+
+#include "st-group.h"
+#include "st-enum-types.h"
+#include "st-private.h"
+
+G_DEFINE_TYPE (StGroup, st_group, ST_TYPE_CONTAINER);
+
+static void
+st_group_paint (ClutterActor *actor)
+{
+  CLUTTER_ACTOR_CLASS (st_group_parent_class)->paint (actor);
+
+  clutter_container_foreach (CLUTTER_CONTAINER (actor),
+                             CLUTTER_CALLBACK (clutter_actor_paint),
+                             NULL);
+}
+
+static void
+st_group_pick (ClutterActor       *actor,
+               const ClutterColor *pick)
+{
+  /* Chain up so we get a bounding box painted (if we are reactive) */
+  CLUTTER_ACTOR_CLASS (st_group_parent_class)->pick (actor, pick);
+
+  clutter_container_foreach (CLUTTER_CONTAINER (actor),
+                             CLUTTER_CALLBACK (clutter_actor_paint),
+                             NULL);
+}
+
+static void
+st_group_get_preferred_width (ClutterActor *actor,
+                              gfloat        for_height,
+                              gfloat       *min_width,
+                              gfloat       *natural_width)
+{
+  GList *l, *children;
+  gdouble min_right, natural_right;
+
+  /* We will always be at least 0 sized (ie, if all of the actors are
+     to the left of the origin we won't return a negative size) */
+  min_right = 0;
+  natural_right = 0;
+
+  children = st_container_get_children_list (ST_CONTAINER (actor));
+
+  for (l = children; l != NULL; l = l->next)
+    {
+      ClutterActor *child = l->data;
+      gfloat child_x, child_min, child_nat;
+
+      child_x = clutter_actor_get_x (child);
+
+      /* for_height is irrelevant to the fixed layout, so it's not used */
+      _st_actor_get_preferred_width (child, -1, FALSE,
+                                     &child_min, &child_nat);
+
+      /* Track the rightmost edge */
+      if (child_x + child_min > min_right)
+        min_right = child_x + child_min;
+
+      if (child_x + child_nat > natural_right)
+        natural_right = child_x + child_nat;
+    }
+
+  /* The size is defined as the distance from the origin to the right-hand
+     edge of the rightmost actor */
+  if (min_width)
+    *min_width = min_right;
+
+  if (natural_width)
+    *natural_width = natural_right;
+}
+
+static void
+st_group_get_preferred_height (ClutterActor *actor,
+                               gfloat        for_width,
+                               gfloat       *min_height,
+                               gfloat       *natural_height)
+{
+  GList *l, *children;
+  gdouble min_bottom, natural_bottom;
+
+  /* We will always be at least 0 sized (ie, if all of the actors are
+     above of the origin we won't return a negative size) */
+  min_bottom = 0;
+  natural_bottom = 0;
+
+  children = st_container_get_children_list (ST_CONTAINER (actor));
+
+  for (l = children; l != NULL; l = l->next)
+    {
+      ClutterActor *child = l->data;
+      gfloat child_y, child_min, child_nat;
+
+      child_y = clutter_actor_get_y (child);
+
+      /* for_width is irrelevant to the fixed layout, so it's not used */
+      _st_actor_get_preferred_height (child, -1, FALSE,
+                                      &child_min, &child_nat);
+
+      /* Track the bottommost edge */
+      if (child_y + child_min > min_bottom)
+        min_bottom = child_y + child_min;
+
+      if (child_y + child_nat > natural_bottom)
+        natural_bottom = child_y + child_nat;
+    }
+
+  /* The size is defined as the distance from the origin to the right-hand
+     edge of the rightmost actor */
+  if (min_height)
+    *min_height = min_bottom;
+
+  if (natural_height)
+    *natural_height = natural_bottom;
+}
+
+static void
+st_group_allocate (ClutterActor           *actor,
+                   const ClutterActorBox  *box,
+                   ClutterAllocationFlags  flags)
+{
+  GList *l, *children;
+
+  CLUTTER_ACTOR_CLASS (st_group_parent_class)->allocate (actor, box, flags);
+
+  children = st_container_get_children_list (ST_CONTAINER (actor));
+  for (l = children; l != NULL; l = l->next)
+    {
+      ClutterActor *child = l->data;
+      clutter_actor_allocate_preferred_size (child, flags);
+    }
+}
+
+static void
+st_group_show_all (ClutterActor *actor)
+{
+  clutter_container_foreach (CLUTTER_CONTAINER (actor),
+                             CLUTTER_CALLBACK (clutter_actor_show),
+                             NULL);
+  clutter_actor_show (actor);
+}
+
+static void
+st_group_hide_all (ClutterActor *actor)
+{
+  clutter_actor_hide (actor);
+  clutter_container_foreach (CLUTTER_CONTAINER (actor),
+                             CLUTTER_CALLBACK (clutter_actor_hide),
+                             NULL);
+}
+
+
+
+
+static void
+st_group_class_init (StGroupClass *klass)
+{
+  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+
+  actor_class->get_preferred_width = st_group_get_preferred_width;
+  actor_class->get_preferred_height = st_group_get_preferred_height;
+  actor_class->allocate = st_group_allocate;
+  actor_class->paint = st_group_paint;
+  actor_class->pick = st_group_pick;
+  actor_class->show_all = st_group_show_all;
+  actor_class->hide_all = st_group_hide_all;
+}
+
+static void
+st_group_init (StGroup *self)
+{
+}
+
+/**
+ * st_group_new:
+ *
+ * Create a new  #StGroup.
+ *
+ * Return value: the newly created #StGroup actor
+ */
+StWidget *
+st_group_new (void)
+{
+  return g_object_new (ST_TYPE_GROUP, NULL);
+}
diff --git a/src/st/st-group.h b/src/st/st-group.h
new file mode 100644
index 0000000..bf7e34b
--- /dev/null
+++ b/src/st/st-group.h
@@ -0,0 +1,71 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * st-group.h: A fixed layout container based on ClutterGroup
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#if !defined(ST_H_INSIDE) && !defined(ST_COMPILATION)
+#error "Only <st/st.h> can be included directly.h"
+#endif
+
+#ifndef __ST_GROUP_H__
+#define __ST_GROUP_H__
+
+#include <st/st-types.h>
+#include <st/st-container.h>
+
+G_BEGIN_DECLS
+
+#define ST_TYPE_GROUP                   (st_group_get_type ())
+#define ST_GROUP(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), ST_TYPE_GROUP, StGroup))
+#define ST_IS_GROUP(obj)                (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ST_TYPE_GROUP))
+#define ST_GROUP_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), ST_TYPE_GROUP, StGroupClass))
+#define ST_IS_GROUP_CLASS(klass)        (G_TYPE_CHECK_CLASS_TYPE ((klass), ST_TYPE_GROUP))
+#define ST_GROUP_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), ST_TYPE_GROUP, StGroupClass))
+
+typedef struct _StGroup                 StGroup;
+typedef struct _StGroupPrivate          StGroupPrivate;
+typedef struct _StGroupClass            StGroupClass;
+
+/**
+ * StGroup:
+ *
+ * The #StGroup struct contains only private data
+ */
+struct _StGroup
+{
+  /*< private >*/
+  StContainer parent_instance;
+};
+
+/**
+ * StGroupClass:
+ *
+ * The #StGroupClass struct contains only private data
+ */
+struct _StGroupClass
+{
+  /*< private >*/
+  StContainerClass parent_class;
+};
+
+GType         st_group_get_type        (void) G_GNUC_CONST;
+StWidget     *st_group_new              (void);
+
+G_END_DECLS
+
+#endif /* __ST_GROUP_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]