[glom/spread-table] Use EggSpreadTable instead of GtkSpreadTable (not added to GTK+).
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom/spread-table] Use EggSpreadTable instead of GtkSpreadTable (not added to GTK+).
- Date: Fri, 5 Nov 2010 14:54:57 +0000 (UTC)
commit 866dd53f8c717f2ce6aa63f3f88b6a28a3e68621
Author: Murray Cumming <murrayc murrayc com>
Date: Fri Nov 5 15:54:48 2010 +0100
Use EggSpreadTable instead of GtkSpreadTable (not added to GTK+).
* glom/utility_widgets/eggspreadtable/eggspreadtable.[h|cc]:
* glom/utility_widgets/eggspreadtable/testspreadtable.c
* glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.[h|cc]:
* glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.
h: New files.
* glom/Makefile_glom.am
* glom/Makefile_tests.am: Mention the new files.
* glom/utility_widgets/flowtable.[h|cc]: Use Egg::SpreadTable instead of
Gtk::SpreadTable.
ChangeLog | 14 +
Makefile_glom.am | 5 +
Makefile_tests.am | 8 +-
.../eggspreadtable/eggspreadtable.c | 1126 ++++++++++++++++++++
.../eggspreadtable/eggspreadtable.h | 89 ++
.../eggspreadtable/testspreadtable.c | 393 +++++++
.../eggspreadtablemm/eggspreadtablemm.cc | 230 ++++
.../eggspreadtablemm/eggspreadtablemm.h | 202 ++++
.../eggspreadtablemm/private/eggspreadtablemm_p.h | 45 +
glom/utility_widgets/flowtable.cc | 6 +-
glom/utility_widgets/flowtable.h | 3 +-
po/POTFILES.in | 1 +
12 files changed, 2116 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b07f324..9f7eb49 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-11-05 Murray Cumming <murrayc murrayc com>
+
+ Use EggSpreadTable instead of GtkSpreadTable (not added to GTK+).
+
+ * glom/utility_widgets/eggspreadtable/eggspreadtable.[h|cc]:
+ * glom/utility_widgets/eggspreadtable/testspreadtable.c
+ * glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.[h|cc]:
+ * glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.
+ h: New files.
+ * glom/Makefile_glom.am
+ * glom/Makefile_tests.am: Mention the new files.
+ * glom/utility_widgets/flowtable.[h|cc]: Use Egg::SpreadTable instead of
+ Gtk::SpreadTable.
+
2010-11-04 Murray Cumming <murrayc murrayc com>
Remove the gconfmm dependency, because we don't use it.
diff --git a/Makefile_glom.am b/Makefile_glom.am
index d8aae46..0ab3ebe 100644
--- a/Makefile_glom.am
+++ b/Makefile_glom.am
@@ -165,6 +165,11 @@ glom_source_files = \
glom/utility_widgets/dialog_properties.h \
glom/utility_widgets/flowtable.cc \
glom/utility_widgets/flowtable.h \
+ glom/utility_widgets/eggspreadtable/eggspreadtable.c \
+ glom/utility_widgets/eggspreadtable/eggspreadtable.h \
+ glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.c \
+ glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h \
+ glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h \
glom/utility_widgets/imageglom.cc \
glom/utility_widgets/imageglom.h \
glom/utility_widgets/layoutwidgetbase.cc \
diff --git a/Makefile_tests.am b/Makefile_tests.am
index cdb43d2..0bf7a2c 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -56,7 +56,7 @@ TESTS = tests/test_document_load \
tests/test_python_execute_script \
tests/test_selfhosting_new_empty \
tests/test_selfhosting_new_from_example
-
+
# These hang most of the time, but not always:
# tests/import/test_parsing \
# tests/import/test_signals
@@ -116,6 +116,11 @@ glom_libglom_test_sharedptr_layoutitem_LDADD = $(tests_ldadd)
glom_utility_widgets_test_flowtable_SOURCES = \
glom/utility_widgets/flowtable.cc \
glom/utility_widgets/flowtable.h \
+ glom/utility_widgets/eggspreadtable/eggspreadtable.c \
+ glom/utility_widgets/eggspreadtable/eggspreadtable.h \
+ glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.c \
+ glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h \
+ glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h \
glom/utility_widgets/test_flowtable.cc
glom_utility_widgets_test_flowtable_LDADD = $(GLOM_LIBS)
@@ -157,4 +162,3 @@ tests_import_test_signals_LDADD = $(GLOM_LIBS)
tests_test_glade_derived_instantiation_LDADD = $(glom_all_libs)
tests_test_selfhosting_new_empty_LDADD = $(glom_all_libs)
tests_test_selfhosting_new_from_example_LDADD = $(glom_all_libs)
-
diff --git a/glom/utility_widgets/eggspreadtable/eggspreadtable.c b/glom/utility_widgets/eggspreadtable/eggspreadtable.c
new file mode 100644
index 0000000..2e9170e
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtable/eggspreadtable.c
@@ -0,0 +1,1126 @@
+/* gtkspreadtable.c
+ * Copyright (C) 2007-2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gtkspreadtable
+ * @Short_Description: A container that distributes its children evenly across rows/columns.
+ * @Title: EggSpreadTable
+ *
+ * #EggSpreadTable positions its children by distributing them as
+ * evenly as possible across a fixed number of rows or columns.
+ *
+ * When oriented vertically the #EggSpreadTable will list its
+ * children in order from top to bottom in columns and request
+ * the smallest height as possible regardless of differences in
+ * child sizes.
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+#include <string.h>
+#include "eggspreadtable.h"
+
+#define DEFAULT_LINES 2
+#define P_(msgid) (msgid)
+
+enum {
+ PROP_0,
+ PROP_ORIENTATION,
+ PROP_HORIZONTAL_SPACING,
+ PROP_VERTICAL_SPACING,
+ PROP_LINES
+};
+
+struct _EggSpreadTablePrivate {
+ GList *children;
+
+ GtkOrientation orientation;
+
+ guint16 lines;
+ guint16 horizontal_spacing;
+ guint16 vertical_spacing;
+};
+
+/* GObjectClass */
+static void egg_spread_table_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void egg_spread_table_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+/* GtkWidgetClass */
+
+static GtkSizeRequestMode egg_spread_table_get_request_mode (GtkWidget *widget);
+static void egg_spread_table_get_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size);
+static void egg_spread_table_get_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size);
+static void egg_spread_table_get_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+static void egg_spread_table_get_width_for_height (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height);
+static void egg_spread_table_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+
+/* GtkContainerClass */
+static void egg_spread_table_add (GtkContainer *container,
+ GtkWidget *widget);
+static void egg_spread_table_remove (GtkContainer *container,
+ GtkWidget *widget);
+
+
+static void egg_spread_table_forall (GtkContainer *container,
+ gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data);
+static GType egg_spread_table_child_type (GtkContainer *container);
+
+
+G_DEFINE_TYPE_WITH_CODE (EggSpreadTable, egg_spread_table, GTK_TYPE_CONTAINER,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL))
+
+#define ITEM_SPACING(table) \
+ (((EggSpreadTable *)(table))->priv->orientation == GTK_ORIENTATION_HORIZONTAL ? \
+ ((EggSpreadTable *)(table))->priv->horizontal_spacing : \
+ ((EggSpreadTable *)(table))->priv->vertical_spacing)
+
+#define LINE_SPACING(table) \
+ (((EggSpreadTable *)(table))->priv->orientation == GTK_ORIENTATION_HORIZONTAL ? \
+ ((EggSpreadTable *)(table))->priv->vertical_spacing : \
+ ((EggSpreadTable *)(table))->priv->horizontal_spacing)
+
+#define OPPOSITE_ORIENTATION(table) \
+ (((EggSpreadTable *)(table))->priv->orientation == GTK_ORIENTATION_HORIZONTAL ? \
+ GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL)
+
+static void
+egg_spread_table_class_init (EggSpreadTableClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
+
+ gobject_class->get_property = egg_spread_table_get_property;
+ gobject_class->set_property = egg_spread_table_set_property;
+
+ widget_class->get_request_mode = egg_spread_table_get_request_mode;
+ widget_class->get_preferred_width = egg_spread_table_get_width;
+ widget_class->get_preferred_height = egg_spread_table_get_height;
+ widget_class->get_preferred_height_for_width = egg_spread_table_get_height_for_width;
+ widget_class->get_preferred_width_for_height = egg_spread_table_get_width_for_height;
+ widget_class->size_allocate = egg_spread_table_size_allocate;
+
+ container_class->add = egg_spread_table_add;
+ container_class->remove = egg_spread_table_remove;
+ container_class->forall = egg_spread_table_forall;
+ container_class->child_type = egg_spread_table_child_type;
+
+ gtk_container_class_handle_border_width (container_class);
+
+ /* GObjectClass properties */
+ g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
+
+ /**
+ * EggSpreadTable:lines:
+ *
+ * The number of lines (rows/columns) to evenly distribute children to.
+ *
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_LINES,
+ g_param_spec_uint ("lines",
+ P_("Lines"),
+ P_("The number of lines (rows/columns) to "
+ "evenly distribute children to."),
+ 1,
+ 65535,
+ DEFAULT_LINES,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+
+ /**
+ * EggSpreadTable:vertical-spacing:
+ *
+ * The amount of vertical space between two children.
+ *
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_VERTICAL_SPACING,
+ g_param_spec_uint ("vertical-spacing",
+ P_("Vertical spacing"),
+ P_("The amount of vertical space between two children"),
+ 0,
+ 65535,
+ 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ /**
+ * EggSpreadTable:horizontal-spacing:
+ *
+ * The amount of horizontal space between two children.
+ *
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_HORIZONTAL_SPACING,
+ g_param_spec_uint ("horizontal-spacing",
+ P_("Horizontal spacing"),
+ P_("The amount of horizontal space between two children"),
+ 0,
+ 65535,
+ 0,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+ g_type_class_add_private (class, sizeof (EggSpreadTablePrivate));
+}
+
+static void
+egg_spread_table_init (EggSpreadTable *spread_table)
+{
+ EggSpreadTablePrivate *priv;
+
+ spread_table->priv = priv =
+ G_TYPE_INSTANCE_GET_PRIVATE (spread_table, EGG_TYPE_SPREAD_TABLE, EggSpreadTablePrivate);
+
+ /* We are vertical by default */
+ priv->orientation = GTK_ORIENTATION_VERTICAL;
+ priv->lines = DEFAULT_LINES;
+
+ gtk_widget_set_has_window (GTK_WIDGET (spread_table), FALSE);
+}
+
+/*****************************************************
+ * GObectClass *
+ *****************************************************/
+static void
+egg_spread_table_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (object);
+ EggSpreadTablePrivate *priv = table->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, priv->orientation);
+ break;
+ case PROP_LINES:
+ g_value_set_uint (value, egg_spread_table_get_lines (table));
+ break;
+ case PROP_VERTICAL_SPACING:
+ g_value_set_uint (value, egg_spread_table_get_vertical_spacing (table));
+ break;
+ case PROP_HORIZONTAL_SPACING:
+ g_value_set_uint (value, egg_spread_table_get_horizontal_spacing (table));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+egg_spread_table_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (object);
+ EggSpreadTablePrivate *priv = table->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ priv->orientation = g_value_get_enum (value);
+
+ /* Re-spread_table the children in the new orientation */
+ gtk_widget_queue_resize (GTK_WIDGET (table));
+ break;
+ case PROP_LINES:
+ egg_spread_table_set_lines (table, g_value_get_uint (value));
+ break;
+ case PROP_HORIZONTAL_SPACING:
+ egg_spread_table_set_horizontal_spacing (table, g_value_get_uint (value));
+ break;
+ case PROP_VERTICAL_SPACING:
+ egg_spread_table_set_vertical_spacing (table, g_value_get_uint (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+
+/*****************************************************
+ * Geometric helper functions for request/allocate *
+ *****************************************************/
+static void
+get_widget_size (GtkWidget *widget,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *min_size,
+ gint *nat_size)
+{
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ if (for_size < 0)
+ gtk_widget_get_preferred_width (widget, min_size, nat_size);
+ else
+ gtk_widget_get_preferred_width_for_height (widget, for_size, min_size, nat_size);
+ }
+ else
+ {
+ if (for_size < 0)
+ gtk_widget_get_preferred_height (widget, min_size, nat_size);
+ else
+ gtk_widget_get_preferred_height_for_width (widget, for_size, min_size, nat_size);
+ }
+}
+
+
+static GList *
+get_visible_children (EggSpreadTable *table)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ GtkWidget *child;
+ GList *list, *visible = NULL;
+
+ for (list = priv->children; list; list = list->next)
+ {
+ child = list->data;
+
+ if (!gtk_widget_get_visible (child))
+ continue;
+
+ visible = g_list_prepend (visible, child);
+ }
+
+ return g_list_reverse (visible);
+}
+
+/* This gets the widest child, it is used to reserve
+ * enough space for (columns * widest_child)
+ */
+static void
+get_largest_line_thickness (EggSpreadTable *table,
+ gint *min_thickness,
+ gint *nat_thickness)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *list;
+ gint min_size = 0, nat_size = 0;
+ GtkOrientation opposite_orientation;
+
+ opposite_orientation = OPPOSITE_ORIENTATION (table);
+
+ for (list = priv->children; list; list = list->next)
+ {
+ GtkWidget *child = list->data;
+ gint child_min, child_nat;
+
+ if (!gtk_widget_get_visible (child))
+ continue;
+
+ get_widget_size (child, opposite_orientation, -1, &child_min, &child_nat);
+
+ min_size = MAX (min_size, child_min);
+ nat_size = MAX (nat_size, child_nat);
+ }
+
+ *min_thickness = min_size;
+ *nat_thickness = nat_size;
+}
+
+/* Gets the column width for a given width */
+static gint
+get_line_thickness (EggSpreadTable *table,
+ gint for_thickness)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ gint line_thickness;
+
+ /* Get the available size per line (when vertical, we are getting the column width here) */
+ line_thickness = for_thickness - (priv->lines -1) * LINE_SPACING (table);
+ line_thickness = line_thickness / priv->lines;
+
+ return line_thickness;
+}
+
+/* Gets the overall height of a column (length of a line segment) */
+static gint
+get_segment_length (EggSpreadTable *table,
+ gint line_thickness,
+ GList *seg_children)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *list;
+ gint size = 0, i = 0;
+ gint spacing;
+
+ spacing = ITEM_SPACING (table);
+
+ for (i = 0, list = seg_children; list; list = list->next)
+ {
+ GtkWidget *child = list->data;
+ gint child_nat;
+
+ if (!gtk_widget_get_visible (child))
+ continue;
+
+ get_widget_size (child, priv->orientation, line_thickness, NULL, &child_nat);
+
+ size += child_nat;
+
+ if (i != 0)
+ size += spacing;
+
+ i++;
+ }
+
+ return size;
+}
+
+static gboolean
+children_fit_segment_size (EggSpreadTable *table,
+ GList *children,
+ gint line_thickness,
+ gint size,
+ gint *segments,
+ gint *largest_segment_size)
+{
+ EggSpreadTablePrivate *priv;
+ GList *l;
+ gint segment_size, i;
+ gint spacing;
+
+ priv = table->priv;
+ spacing = ITEM_SPACING (table);
+
+ /* reset segments */
+ memset (segments, 0x0, sizeof (gint) * priv->lines);
+
+ for (l = children, i = 0; l && i < priv->lines; i++)
+ {
+ segment_size = 0;
+
+ /* While we still have children to place and
+ * there is space left on this line */
+ while (l && segment_size < size)
+ {
+ GtkWidget *child = l->data;
+ gint widget_size;
+
+ get_widget_size (child, priv->orientation, line_thickness, NULL, &widget_size);
+
+ if (segment_size != 0)
+ segment_size += spacing;
+
+ segment_size += widget_size;
+
+ /* Consume this widget in this line segment if it fits the size
+ * or it is alone taller than the whole tested size */
+ if (segment_size <= size || segments[i] == 0)
+ {
+ *largest_segment_size = MAX (*largest_segment_size, segment_size);
+ segments[i]++;
+
+ l = l->next;
+ }
+ }
+ }
+
+ /* If we placed all the widgets in the target size, the size fits. */
+ return (l == NULL);
+}
+
+/* All purpose algorithm entry point, this function takes an allocated size
+ * to fit the columns (or rows) and then splits up the child list into
+ * 'n' children per 'segment' in a way that it takes the least space as possible.
+ *
+ * If 'segments' is specified, it will be allocated the array of integers representing
+ * how many children are to be fit per line segment (and must be freed afterwards with g_free()).
+ *
+ * The function returns the required space (the required height for all columns).
+ */
+static gint
+segment_lines_for_size (EggSpreadTable *table,
+ gint for_size,
+ gint **segments)
+{
+ EggSpreadTablePrivate *priv;
+ GList *children;
+ gint line_thickness;
+ gint *segment_counts = NULL, *test_counts;
+ gint upper, lower, segment_size, largest_size = 0;
+ gint i, j;
+
+ priv = table->priv;
+ line_thickness = get_line_thickness (table, for_size);
+
+ segment_counts = g_new0 (gint, priv->lines);
+ test_counts = g_new0 (gint, priv->lines);
+
+ /* Start by getting the child list/total size/average size */
+ children = get_visible_children (table);
+ upper = get_segment_length (table, line_thickness, children);
+ lower = upper / priv->lines;
+
+ /* Handle a single line spread table as a special case */
+ if (priv->lines == 1)
+ {
+ segment_counts[0] = g_list_length (children);
+ largest_size = upper;
+ }
+ else
+ {
+ /* Start with half way between the average and total height */
+ segment_size = lower + (upper - lower) / 2;
+
+ while (segment_size > lower && segment_size < upper)
+ {
+ gint test_largest = 0;
+
+ if (children_fit_segment_size (table, children, line_thickness,
+ segment_size, test_counts, &test_largest))
+ {
+ upper = segment_size;
+ segment_size -= (segment_size - lower) / 2;
+
+ /* Save the last arrangement that 'fit' */
+ largest_size = test_largest;
+ memcpy (segment_counts, test_counts, sizeof (gint) * priv->lines);
+ }
+ else
+ {
+ lower = segment_size;
+ segment_size += (upper - segment_size) / 2;
+ }
+ }
+
+ /* Perform some corrections: fill in any trailing columns that are missing widgets */
+ for (i = 0; i < priv->lines; i++)
+ {
+ /* If this column has no widgets... */
+ if (!segment_counts[i])
+ {
+ /* rewind to the last column that had more than 1 widget */
+ for (j = i - 1; j >= 0; j--)
+ {
+ if (segment_counts[j] > 1)
+ {
+ /* put an available widget in the empty column */
+ segment_counts[j]--;
+ segment_counts[i]++;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (segments)
+ *segments = segment_counts;
+ else
+ g_free (segment_counts);
+
+ g_free (test_counts);
+
+ return largest_size;
+}
+
+
+/*****************************************************
+ * GtkWidgetClass *
+ *****************************************************/
+static GtkSizeRequestMode
+egg_spread_table_get_request_mode (GtkWidget *widget)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+
+ if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+ return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
+ else
+ return GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT;
+}
+
+static void
+egg_spread_table_get_width (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+ gint min_width, nat_width;
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ /* Get the width for minimum height */
+ gint min_height;
+
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_height, NULL);
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_width_for_height (widget, min_height,
+ &min_width, &nat_width);
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ gint min_thickness, nat_thickness;
+
+ get_largest_line_thickness (table, &min_thickness, &nat_thickness);
+
+ min_width = min_thickness * priv->lines + LINE_SPACING (table) * (priv->lines - 1);
+ nat_width = nat_thickness * priv->lines + LINE_SPACING (table) * (priv->lines - 1);
+ }
+
+#if 0
+ g_print ("get_width() called; returning min %d and nat %d\n",
+ min_width, nat_width);
+#endif
+
+ if (minimum_size)
+ *minimum_size = min_width;
+
+ if (natural_size)
+ *natural_size = nat_width;
+}
+
+static void
+egg_spread_table_get_height (GtkWidget *widget,
+ gint *minimum_size,
+ gint *natural_size)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+ gint min_height, nat_height;
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gint min_thickness, nat_thickness;
+
+ get_largest_line_thickness (table, &min_thickness, &nat_thickness);
+
+ min_height = min_thickness * priv->lines + LINE_SPACING (table) * (priv->lines - 1);
+ nat_height = nat_thickness * priv->lines + LINE_SPACING (table) * (priv->lines - 1);
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ /* Return the height for the minimum width */
+ gint min_width;
+
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_width, NULL);
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, min_width,
+ &min_height, &nat_height);
+ }
+
+#if 0
+ g_print ("get_height() called; returning min %d and nat %d\n",
+ min_height, nat_height);
+#endif
+
+ if (minimum_size)
+ *minimum_size = min_height;
+
+ if (natural_size)
+ *natural_size = nat_height;
+}
+
+static void
+egg_spread_table_get_height_for_width (GtkWidget *widget,
+ gint width,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+ gint min_height = 0, nat_height = 0;
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ /* Just return the minimum/natural height */
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_height, &nat_height);
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ gint min_width;
+
+ /* Make sure its no smaller than the minimum */
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_width, NULL);
+
+ /* This will segment the lines evenly and return the overall
+ * lengths of the split segments */
+ nat_height = min_height = segment_lines_for_size (table, MAX (width, min_width), NULL);
+ }
+
+#if 0
+ g_print ("get_height_for_width() called for width %d; returning min %d and nat %d\n",
+ width, min_height, nat_height);
+#endif
+
+ if (minimum_height)
+ *minimum_height = min_height;
+
+ if (natural_height)
+ *natural_height = nat_height;
+}
+
+static void
+egg_spread_table_get_width_for_height (GtkWidget *widget,
+ gint height,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+ gint min_width = 0, nat_width = 0;
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gint min_height;
+
+ /* Make sure its no smaller than the minimum */
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, &min_height, NULL);
+
+ /* This will segment the lines evenly and return the overall
+ * lengths of the split segments */
+ nat_width = min_width = segment_lines_for_size (table, MAX (height, min_height), NULL);
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ /* Just return the minimum/natural height */
+ GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_width, &nat_width);
+ }
+
+#if 0
+ g_print ("get_width_for_height() called for height %d; returning min %d and nat %d\n",
+ height, min_width, nat_width);
+#endif
+
+ if (minimum_width)
+ *minimum_width = min_width;
+
+ if (natural_width)
+ *natural_width = nat_width;
+}
+
+static void
+allocate_child (EggSpreadTable *table,
+ GtkWidget *child,
+ gint item_offset,
+ gint line_offset,
+ gint item_size,
+ gint line_size)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ GtkAllocation widget_allocation;
+ GtkAllocation child_allocation;
+
+ gtk_widget_get_allocation (GTK_WIDGET (table), &widget_allocation);
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ child_allocation.x = widget_allocation.x + item_offset;
+ child_allocation.y = widget_allocation.y + line_offset;
+ child_allocation.width = item_size;
+ child_allocation.height = line_size;
+ }
+ else /* GTK_ORIENTATION_VERTICAL */
+ {
+ child_allocation.x = widget_allocation.x + line_offset;
+ child_allocation.y = widget_allocation.y + item_offset;
+ child_allocation.width = line_size;
+ child_allocation.height = item_size;
+ }
+
+ gtk_widget_size_allocate (child, &child_allocation);
+}
+
+static void
+egg_spread_table_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (widget);
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *list;
+ gint *segments = NULL;
+ gint full_thickness;
+ gint i, j;
+ gint line_offset, item_offset;
+ gint line_thickness;
+ gint line_spacing;
+ gint item_spacing;
+ GtkOrientation opposite_orientation;
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ full_thickness = allocation->height;
+ else
+ full_thickness = allocation->width;
+
+ line_thickness = get_line_thickness (table, full_thickness);
+ line_spacing = LINE_SPACING (table);
+ item_spacing = ITEM_SPACING (table);
+ opposite_orientation = OPPOSITE_ORIENTATION (table);
+
+ segment_lines_for_size (table, full_thickness, &segments);
+
+ for (list = priv->children, line_offset = 0, i = 0;
+ i < priv->lines;
+ line_offset += line_thickness + line_spacing, i++)
+ {
+ for (j = 0, item_offset = 0; list && j < segments[i]; list = list->next)
+ {
+ GtkWidget *child = list->data;
+ gint child_size;
+
+ if (!gtk_widget_get_visible (child))
+ continue;
+
+ get_widget_size (child, priv->orientation,
+ line_thickness, NULL, &child_size);
+
+ allocate_child (table, child, item_offset, line_offset, child_size, line_thickness);
+
+ item_offset += child_size + item_spacing;
+
+ j++;
+ }
+ }
+
+ g_free (segments);
+}
+
+/*****************************************************
+ * GtkContainerClass *
+ *****************************************************/
+static void
+egg_spread_table_add (GtkContainer *container,
+ GtkWidget *widget)
+{
+ egg_spread_table_insert_child (EGG_SPREAD_TABLE (container), widget, -1);
+}
+
+
+static void
+egg_spread_table_remove (GtkContainer *container,
+ GtkWidget *widget)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (container);
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *list;
+
+ list = g_list_find (priv->children, widget);
+
+ if (list)
+ {
+ gboolean was_visible = gtk_widget_get_visible (widget);
+
+ gtk_widget_unparent (widget);
+
+ priv->children = g_list_delete_link (priv->children, list);
+
+ if (was_visible && gtk_widget_get_visible (GTK_WIDGET (container)))
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+}
+
+
+static void
+egg_spread_table_forall (GtkContainer *container,
+ G_GNUC_UNUSED gboolean include_internals,
+ GtkCallback callback,
+ gpointer callback_data)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (container);
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *list;
+
+ for (list = priv->children; list; list = list->next)
+ (* callback) ((GtkWidget *)list->data, callback_data);
+}
+
+static GType
+egg_spread_table_child_type (G_GNUC_UNUSED GtkContainer *container)
+{
+ return GTK_TYPE_WIDGET;
+}
+
+/*****************************************************
+ * API *
+ *****************************************************/
+
+/**
+ * egg_spread_table_new:
+ * @orientation: The #GtkOrientation for the #EggSpreadTable
+ * @lines: The fixed amount of lines to distribute children to.
+ *
+ * Creates a #EggSpreadTable.
+ *
+ * Returns: A new #EggSpreadTable container
+ */
+GtkWidget *
+egg_spread_table_new (GtkOrientation orientation,
+ guint lines)
+{
+ return (GtkWidget *)g_object_new (EGG_TYPE_SPREAD_TABLE,
+ "orientation", orientation,
+ "lines", lines,
+ NULL);
+}
+
+/**
+ * egg_spread_table_insert_child:
+ * @spread_table: An #EggSpreadTable
+ * @widget: the child #GtkWidget to add
+ * @index: the position in the child list to insert, specify -1 to append to the list.
+ *
+ * Adds a child to an #EggSpreadTable with its packing options set
+ */
+void
+egg_spread_table_insert_child (EggSpreadTable *table,
+ GtkWidget *child,
+ gint index)
+{
+ EggSpreadTablePrivate *priv;
+ GList *list;
+
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ priv = table->priv;
+
+ list = g_list_find (priv->children, child);
+ g_return_if_fail (list == NULL);
+
+ priv->children = g_list_insert (priv->children, child, index);
+
+ gtk_widget_set_parent (child, GTK_WIDGET (table));
+}
+
+
+
+/**
+ * egg_spread_table_get_child_line:
+ * @table: A #EggSpreadTable
+ * @child: A Child of the @table.
+ * @size: A size in the opposing orientation of @table
+ *
+ * Gets the line index in which @child would be positioned
+ * if @table were to be allocated @size in the opposing
+ * orientation of @table.
+ *
+ * For instance, if the @table is oriented vertically,
+ * this function will return @child's column if @table
+ * were to be allocated @size width.
+ *
+ * Returns: the line index @child would be positioned in
+ * for @size (starting from 0).
+ */
+guint
+egg_spread_table_get_child_line (EggSpreadTable *table,
+ GtkWidget *child,
+ gint size)
+
+{
+ EggSpreadTablePrivate *priv;
+ gint *segments = NULL;
+ gint i, child_count, child_idx = 0;
+ GList *l;
+
+ g_return_val_if_fail (EGG_IS_SPREAD_TABLE (table), 0);
+ g_return_val_if_fail (GTK_IS_WIDGET (child), 0);
+
+ priv = table->priv;
+
+ segment_lines_for_size (table, size, &segments);
+
+ /* Get child index in list */
+ l = g_list_find (priv->children, child);
+ g_return_val_if_fail (l != NULL, 0);
+
+ child_idx = g_list_position (priv->children, l);
+
+ for (i = 0, child_count = 0; i < priv->lines; i++)
+ {
+ child_count += segments[i];
+
+ if (child_idx < child_count)
+ break;
+ }
+
+ g_assert (i < priv->lines);
+
+ g_free (segments);
+
+ return i;
+}
+
+
+/**
+ * egg_spread_table_set_lines:
+ * @table: A #EggSpreadTable
+ * @lines: The amount of evenly allocated child segments.
+ *
+ * Sets the fixed amount of lines (rows or columns) to
+ * distribute children to.
+ *
+ * <note><para>Space will be allocated for all lines even
+ * if there are not enough children to be placed on every
+ * line, for instance if @lines is set to 4 and the table
+ * has only 3 children; then the last line will appear empty.</para></note>
+ */
+void
+egg_spread_table_set_lines (EggSpreadTable *table,
+ guint lines)
+{
+ EggSpreadTablePrivate *priv;
+
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+ g_return_if_fail (lines > 0);
+
+ priv = table->priv;
+
+ if (priv->lines != lines)
+ {
+ priv->lines = lines;
+
+ gtk_widget_queue_resize (GTK_WIDGET (table));
+
+ g_object_notify (G_OBJECT (table), "lines");
+ }
+}
+
+/**
+ * egg_spread_table_get_lines:
+ * @table: An #EggSpreadTable
+ *
+ * Gets the fixed amount of lines (rows or columns) to
+ * distribute children to.
+ *
+ * Returns: The amount of lines.
+ */
+guint
+egg_spread_table_get_lines (EggSpreadTable *table)
+{
+ g_return_val_if_fail (EGG_IS_SPREAD_TABLE (table), 0);
+
+ return table->priv->lines;
+}
+
+
+/**
+ * egg_spread_table_set_vertical_spacing:
+ * @table: An #EggSpreadTable
+ * @spacing: The spacing to use.
+ *
+ * Sets the vertical space to add between children.
+ */
+void
+egg_spread_table_set_vertical_spacing (EggSpreadTable *table,
+ guint spacing)
+{
+ EggSpreadTablePrivate *priv;
+
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+
+ priv = table->priv;
+
+ if (priv->vertical_spacing != spacing)
+ {
+ priv->vertical_spacing = spacing;
+
+ gtk_widget_queue_resize (GTK_WIDGET (table));
+
+ g_object_notify (G_OBJECT (table), "vertical-spacing");
+ }
+}
+
+/**
+ * egg_spread_table_get_vertical_spacing:
+ * @table: An #EggSpreadTable
+ *
+ * Gets the vertical spacing.
+ *
+ * Returns: The vertical spacing.
+ */
+guint
+egg_spread_table_get_vertical_spacing (EggSpreadTable *table)
+{
+ g_return_val_if_fail (EGG_IS_SPREAD_TABLE (table), 0);
+
+ return table->priv->vertical_spacing;
+}
+
+/**
+ * egg_spread_table_set_horizontal_spacing:
+ * @table: A #EggSpreadTable
+ * @spacing: The spacing to use.
+ *
+ * Sets the horizontal space to add between children.
+ */
+void
+egg_spread_table_set_horizontal_spacing (EggSpreadTable *table,
+ guint spacing)
+{
+ EggSpreadTablePrivate *priv;
+
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+
+ priv = table->priv;
+
+ if (priv->horizontal_spacing != spacing)
+ {
+ priv->horizontal_spacing = spacing;
+
+ gtk_widget_queue_resize (GTK_WIDGET (table));
+
+ g_object_notify (G_OBJECT (table), "horizontal-spacing");
+ }
+}
+
+/**
+ * egg_spread_table_get_horizontal_spacing:
+ * @table: A #EggSpreadTable
+ *
+ * Gets the horizontal spacing.
+ *
+ * Returns: The horizontal spacing.
+ */
+guint
+egg_spread_table_get_horizontal_spacing (EggSpreadTable *table)
+{
+ g_return_val_if_fail (EGG_IS_SPREAD_TABLE (table), 0);
+
+ return table->priv->horizontal_spacing;
+}
diff --git a/glom/utility_widgets/eggspreadtable/eggspreadtable.h b/glom/utility_widgets/eggspreadtable/eggspreadtable.h
new file mode 100644
index 0000000..7531a80
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtable/eggspreadtable.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Authors:
+ * Tristan Van Berkom <tristanvb openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_SPREAD_TABLE_H__
+#define __EGG_SPREAD_TABLE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+#define EGG_TYPE_SPREAD_TABLE (egg_spread_table_get_type ())
+#define EGG_SPREAD_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SPREAD_TABLE, EggSpreadTable))
+#define EGG_SPREAD_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SPREAD_TABLE, EggSpreadTableClass))
+#define EGG_IS_SPREAD_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SPREAD_TABLE))
+#define EGG_IS_SPREAD_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SPREAD_TABLE))
+#define EGG_SPREAD_TABLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SPREAD_TABLE, EggSpreadTableClass))
+
+typedef struct _EggSpreadTable EggSpreadTable;
+typedef struct _EggSpreadTablePrivate EggSpreadTablePrivate;
+typedef struct _EggSpreadTableClass EggSpreadTableClass;
+
+
+struct _EggSpreadTable
+{
+ GtkContainer parent_instance;
+
+ /*< private >*/
+ EggSpreadTablePrivate *priv;
+};
+
+struct _EggSpreadTableClass
+{
+ GtkContainerClass parent_class;
+};
+
+
+GType egg_spread_table_get_type (void) G_GNUC_CONST;
+
+
+GtkWidget *egg_spread_table_new (GtkOrientation orientation,
+ guint lines);
+
+void egg_spread_table_insert_child (EggSpreadTable *table,
+ GtkWidget *child,
+ gint index);
+
+guint egg_spread_table_get_child_line (EggSpreadTable *table,
+ GtkWidget *child,
+ gint size);
+
+void egg_spread_table_set_lines (EggSpreadTable *table,
+ guint lines);
+guint egg_spread_table_get_lines (EggSpreadTable *table);
+
+void egg_spread_table_set_horizontal_spacing (EggSpreadTable *table,
+ guint spacing);
+guint egg_spread_table_get_horizontal_spacing (EggSpreadTable *table);
+
+void egg_spread_table_set_vertical_spacing (EggSpreadTable *table,
+ guint spacing);
+guint egg_spread_table_get_vertical_spacing (EggSpreadTable *table);
+
+
+
+
+G_END_DECLS
+
+
+#endif /* __EGG_SPREAD_TABLE_H__ */
diff --git a/glom/utility_widgets/eggspreadtable/testspreadtable.c b/glom/utility_widgets/eggspreadtable/testspreadtable.c
new file mode 100644
index 0000000..2da5073
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtable/testspreadtable.c
@@ -0,0 +1,393 @@
+/* testspreadtable.c
+ * Copyright (C) 2010 Openismus GmbH
+ *
+ * Author:
+ * Tristan Van Berkom <tristanvb openismus com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <eggspreadtable.h>
+
+enum {
+ IMAGE_NONE,
+ IMAGE_SMALL,
+ IMAGE_LARGE,
+ IMAGE_HUGE
+};
+
+#define INITIAL_HSPACING 2
+#define INITIAL_VSPACING 2
+#define INITIAL_LINES 3
+#define INITIAL_HALIGN GTK_ALIGN_FILL
+#define INITIAL_IMAGE IMAGE_NONE
+#define INITIAL_IMAGE_INDEX 10
+
+static GtkWidget *paper = NULL;
+static GtkAlign child_halign = INITIAL_HALIGN;
+static int test_image = INITIAL_IMAGE;
+static int test_image_index = INITIAL_IMAGE_INDEX;
+
+static void
+populate_spread_table_wrappy (EggSpreadTable *spread_table)
+{
+ GList *children, *l;
+ GtkWidget *widget, *frame;
+ gsize i;
+
+ const gchar *strings[] = {
+ "These are", "some wrappy label", "texts", "of various", "lengths.",
+ "They should always be", "shown", "consecutively. Except it's",
+ "hard to say", "where exactly the", "label", "will wrap", "and where exactly",
+ "the actual", "container", "will wrap.", "This label is really really really long !",
+ "Let's add some more", "labels to the",
+ "mix. Just to", "make sure we", "got something to work", "with here."
+ };
+
+ /* Remove all children first */
+ children = gtk_container_get_children (GTK_CONTAINER (paper));
+ for (l = children; l; l = l->next)
+ {
+ GtkWidget *child = l->data;
+
+ gtk_container_remove (GTK_CONTAINER (paper), child);
+ }
+ g_list_free (children);
+
+ for (i = 0; i < G_N_ELEMENTS (strings); i++)
+ {
+ widget = gtk_label_new (strings[i]);
+ frame = gtk_frame_new (NULL);
+ gtk_widget_show (widget);
+ gtk_widget_show (frame);
+
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+
+ gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
+ gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD);
+ gtk_label_set_width_chars (GTK_LABEL (widget), 10);
+
+ gtk_widget_set_halign (frame, child_halign);
+
+ egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table), frame, -1);
+ }
+
+ /* Insert an image into the mix */
+ if (test_image)
+ {
+ widget = gtk_image_new_from_file ("apple-red.png");
+
+ switch (test_image)
+ {
+ case IMAGE_SMALL:
+ gtk_widget_set_size_request (widget, 100, 100);
+ break;
+ case IMAGE_LARGE:
+ gtk_widget_set_size_request (widget, 150, 200);
+ break;
+ case IMAGE_HUGE:
+ gtk_widget_set_size_request (widget, 200, 300);
+ break;
+ default:
+ break;
+ }
+
+ frame = gtk_frame_new (NULL);
+ gtk_widget_show (widget);
+ gtk_widget_show (frame);
+
+ gtk_container_add (GTK_CONTAINER (frame), widget);
+ egg_spread_table_insert_child (EGG_SPREAD_TABLE (spread_table), frame, test_image_index);
+ }
+}
+
+static void
+orientation_changed (GtkComboBox *box,
+ EggSpreadTable *paper)
+{
+ GtkOrientation orientation = gtk_combo_box_get_active (box);
+
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (paper), orientation);
+}
+
+static void
+lines_changed (GtkSpinButton *button,
+ G_GNUC_UNUSED gpointer data)
+{
+ gint lines = gtk_spin_button_get_value_as_int (button);
+
+ egg_spread_table_set_lines (EGG_SPREAD_TABLE (paper), lines);
+}
+
+static void
+spacing_changed (GtkSpinButton *button,
+ gpointer data)
+{
+ GtkOrientation orientation = GPOINTER_TO_INT (data);
+ gint state = gtk_spin_button_get_value_as_int (button);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ egg_spread_table_set_horizontal_spacing (EGG_SPREAD_TABLE (paper), state);
+ else
+ egg_spread_table_set_vertical_spacing (EGG_SPREAD_TABLE (paper), state);
+}
+
+
+
+static void
+halign_changed (GtkComboBox *box,
+ EggSpreadTable *paper)
+{
+ child_halign = gtk_combo_box_get_active (box);
+
+ populate_spread_table_wrappy (EGG_SPREAD_TABLE (paper));
+}
+
+static void
+test_image_changed (GtkComboBox *box,
+ EggSpreadTable *paper)
+{
+ test_image = gtk_combo_box_get_active (box);
+
+ populate_spread_table_wrappy (EGG_SPREAD_TABLE (paper));
+}
+
+
+
+static void
+test_image_index_changed (GtkSpinButton *button,
+ G_GNUC_UNUSED gpointer data)
+{
+ test_image_index = gtk_spin_button_get_value_as_int (button);
+
+ populate_spread_table_wrappy (EGG_SPREAD_TABLE (paper));
+}
+
+
+static GtkWidget *
+create_window (void)
+{
+ GtkWidget *window;
+ GtkWidget *hbox, *vbox, *widget;
+ GtkWidget *swindow, *frame, *expander;
+ GtkWidget *paper_cntl, *items_cntl;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ hbox = gtk_hbox_new (FALSE, 2);
+ vbox = gtk_vbox_new (FALSE, 6);
+
+ gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+
+ gtk_widget_show (vbox);
+ gtk_widget_show (hbox);
+ gtk_container_add (GTK_CONTAINER (window), hbox);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+ frame = gtk_frame_new ("SpreadTable");
+ gtk_widget_show (frame);
+ gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+
+ swindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ gtk_widget_show (swindow);
+ gtk_container_add (GTK_CONTAINER (frame), swindow);
+
+ paper = egg_spread_table_new (GTK_ORIENTATION_VERTICAL, INITIAL_LINES);
+ egg_spread_table_set_vertical_spacing (EGG_SPREAD_TABLE (paper), INITIAL_VSPACING);
+ egg_spread_table_set_horizontal_spacing (EGG_SPREAD_TABLE (paper), INITIAL_HSPACING);
+ gtk_widget_show (paper);
+
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), paper);
+
+ /* Add SpreadTable test control frame */
+ expander = gtk_expander_new ("SpreadTable controls");
+ gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
+ paper_cntl = gtk_vbox_new (FALSE, 2);
+ gtk_widget_show (paper_cntl);
+ gtk_widget_show (expander);
+ gtk_container_add (GTK_CONTAINER (expander), paper_cntl);
+ gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
+
+ /* Add Orientation control */
+ widget = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Horizontal");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Vertical");
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the spread_table orientation");
+ gtk_box_pack_start (GTK_BOX (paper_cntl), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (orientation_changed), paper);
+
+
+ /* Add horizontal/vertical spacing controls */
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox);
+
+ widget = gtk_label_new ("H Spacing");
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+ widget = gtk_spin_button_new_with_range (0, 30, 1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_HSPACING);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the horizontal spacing between children");
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
+
+ gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
+
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox);
+
+ widget = gtk_label_new ("V Spacing");
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+ widget = gtk_spin_button_new_with_range (0, 30, 1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_VSPACING);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the vertical spacing between children");
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
+
+ gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
+
+
+ /* Add lines controls */
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox);
+
+ widget = gtk_label_new ("Lines");
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+ widget = gtk_spin_button_new_with_range (1, 30, 1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_LINES);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the horizontal spacing between children");
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (lines_changed), NULL);
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (lines_changed), NULL);
+
+ gtk_box_pack_start (GTK_BOX (paper_cntl), hbox, FALSE, FALSE, 0);
+
+
+ /* Add test items control frame */
+ expander = gtk_expander_new ("Test item controls");
+ gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
+ items_cntl = gtk_vbox_new (FALSE, 2);
+ gtk_widget_show (items_cntl);
+ gtk_widget_show (expander);
+ gtk_container_add (GTK_CONTAINER (expander), items_cntl);
+ gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
+
+ /* Add child halign control */
+ widget = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Fill");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Start");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "End");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Center");
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_HALIGN);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the children's halign property");
+ gtk_box_pack_start (GTK_BOX (items_cntl), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (halign_changed), paper);
+
+
+ /* Add image control */
+ widget = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "None");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Small");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Large");
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Huge");
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_IMAGE);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Use an image to test the container");
+ gtk_box_pack_start (GTK_BOX (items_cntl), widget, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (test_image_changed), paper);
+
+
+ /* Add horizontal/vertical spacing controls */
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_widget_show (hbox);
+
+ widget = gtk_label_new ("Image index");
+ gtk_widget_show (widget);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+
+ widget = gtk_spin_button_new_with_range (0, 25, 1);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_IMAGE_INDEX);
+ gtk_widget_show (widget);
+
+ gtk_widget_set_tooltip_text (widget, "Set the child list index for the optional test image");
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (items_cntl), hbox, FALSE, FALSE, 0);
+
+ g_signal_connect (G_OBJECT (widget), "changed",
+ G_CALLBACK (test_image_index_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
+ g_signal_connect (G_OBJECT (widget), "value-changed",
+ G_CALLBACK (test_image_index_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
+
+ populate_spread_table_wrappy (EGG_SPREAD_TABLE (paper));
+
+ gtk_window_set_default_size (GTK_WINDOW (window), 500, 400);
+
+ return window;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GtkWidget *window;
+
+ gtk_init (&argc, &argv);
+
+ window = create_window ();
+
+ g_signal_connect (window, "delete-event",
+ G_CALLBACK (gtk_main_quit), window);
+
+ gtk_widget_show (window);
+
+ gtk_main ();
+
+ return 0;
+}
diff --git a/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.cc b/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.cc
new file mode 100644
index 0000000..7cadf23
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.cc
@@ -0,0 +1,230 @@
+/*
+ *
+ * Copyright 2010 The gtkmm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h>
+#include <glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h>
+
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <glom/utility_widgets/eggspreadtable/eggspreadtable.h>
+
+namespace Egg
+{
+
+void SpreadTable::append_child(Widget& widget)
+{
+ insert_child(widget, -1 /* see the C documentation */);
+}
+
+} // namespace Egg
+
+namespace Glib
+{
+
+Egg::SpreadTable* wrap(EggSpreadTable* object, bool take_copy)
+{
+ return dynamic_cast<Egg::SpreadTable *> (Glib::wrap_auto ((GObject*)(object), take_copy));
+}
+
+} /* namespace Glib */
+
+namespace Egg
+{
+
+
+/* The *_Class implementation: */
+
+const Glib::Class& SpreadTable_Class::init()
+{
+ if(!gtype_) // create the GType if necessary
+ {
+ // Glib::Class has to know the class init function to clone custom types.
+ class_init_func_ = &SpreadTable_Class::class_init_function;
+
+ // This is actually just optimized away, apparently with no harm.
+ // Make sure that the parent type has been created.
+ //CppClassParent::CppObjectType::get_type();
+
+ // Create the wrapper type, with the same class/instance size as the base type.
+ register_derived_type(egg_spread_table_get_type());
+
+ // Add derived versions of interfaces, if the C type implements any interfaces:
+ Gtk::Orientable::add_interface(get_type());
+
+ }
+
+ return *this;
+}
+
+
+void SpreadTable_Class::class_init_function(void* g_class, void* class_data)
+{
+ BaseClassType *const klass = static_cast<BaseClassType*>(g_class);
+ CppClassParent::class_init_function(klass, class_data);
+
+
+}
+
+
+Glib::ObjectBase* SpreadTable_Class::wrap_new(GObject* o)
+{
+ return manage(new SpreadTable((EggSpreadTable*)(o)));
+
+}
+
+
+/* The implementation: */
+
+SpreadTable::SpreadTable(const Glib::ConstructParams& construct_params)
+:
+ Gtk::Container(construct_params)
+{
+ }
+
+SpreadTable::SpreadTable(EggSpreadTable* castitem)
+:
+ Gtk::Container((GtkContainer*)(castitem))
+{
+ }
+
+SpreadTable::~SpreadTable()
+{
+ destroy_();
+}
+
+SpreadTable::CppClassType SpreadTable::spreadtable_class_; // initialize static member
+
+GType SpreadTable::get_type()
+{
+ return spreadtable_class_.init().get_type();
+}
+
+
+GType SpreadTable::get_base_type()
+{
+ return egg_spread_table_get_type();
+}
+
+
+SpreadTable::SpreadTable()
+:
+ // Mark this class as non-derived to allow C++ vfuncs to be skipped.
+ Glib::ObjectBase(0),
+ Gtk::Container(Glib::ConstructParams(spreadtable_class_.init()))
+{
+
+
+}
+
+SpreadTable::SpreadTable(Gtk::Orientation orientation, guint lines)
+:
+ // Mark this class as non-derived to allow C++ vfuncs to be skipped.
+ Glib::ObjectBase(0),
+ Gtk::Container(Glib::ConstructParams(spreadtable_class_.init(), "orientation", ((GtkOrientation)(orientation)), "lines", lines, static_cast<char*>(0)))
+{
+
+
+}
+
+void SpreadTable::insert_child(Gtk::Widget& widget, int index)
+{
+egg_spread_table_insert_child(gobj(), (widget).gobj(), index);
+}
+
+guint SpreadTable::get_child_line(const Gtk::Widget& child, int size) const
+{
+ return egg_spread_table_get_child_line(const_cast<EggSpreadTable*>(gobj()), const_cast<GtkWidget*>(child.gobj()), size);
+}
+
+void SpreadTable::set_lines(guint lines)
+{
+egg_spread_table_set_lines(gobj(), lines);
+}
+
+guint SpreadTable::get_lines() const
+{
+ return egg_spread_table_get_lines(const_cast<EggSpreadTable*>(gobj()));
+}
+
+void SpreadTable::set_vertical_spacing(guint spacing)
+{
+egg_spread_table_set_vertical_spacing(gobj(), spacing);
+}
+
+guint SpreadTable::get_vertical_spacing() const
+{
+ return egg_spread_table_get_vertical_spacing(const_cast<EggSpreadTable*>(gobj()));
+}
+
+void SpreadTable::set_horizontal_spacing(guint spacing)
+{
+egg_spread_table_set_horizontal_spacing(gobj(), spacing);
+}
+
+guint SpreadTable::get_horizontal_spacing() const
+{
+ return egg_spread_table_get_horizontal_spacing(const_cast<EggSpreadTable*>(gobj()));
+}
+
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy<guint> SpreadTable::property_vertical_spacing()
+{
+ return Glib::PropertyProxy<guint>(this, "vertical-spacing");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy_ReadOnly<guint> SpreadTable::property_vertical_spacing() const
+{
+ return Glib::PropertyProxy_ReadOnly<guint>(this, "vertical-spacing");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy<guint> SpreadTable::property_horizontal_spacing()
+{
+ return Glib::PropertyProxy<guint>(this, "horizontal-spacing");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy_ReadOnly<guint> SpreadTable::property_horizontal_spacing() const
+{
+ return Glib::PropertyProxy_ReadOnly<guint>(this, "horizontal-spacing");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy<guint> SpreadTable::property_lines()
+{
+ return Glib::PropertyProxy<guint>(this, "lines");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+Glib::PropertyProxy_ReadOnly<guint> SpreadTable::property_lines() const
+{
+ return Glib::PropertyProxy_ReadOnly<guint>(this, "lines");
+}
+#endif //GLIBMM_PROPERTIES_ENABLED
+
+
+} // namespace Egg
diff --git a/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h b/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h
new file mode 100644
index 0000000..ce89c4d
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h
@@ -0,0 +1,202 @@
+/* Copyright (C) 2010 The gtkmm Development Team
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _EGG_SPREADTABLE_H
+#define _EGG_SPREADTABLE_H
+
+#include <glibmm.h>
+#include <gtkmm/container.h>
+#include <gtkmm/orientable.h>
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+typedef struct _EggSpreadTable EggSpreadTable;
+typedef struct _EggSpreadTableClass EggSpreadTableClass;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+
+namespace Egg
+{ class SpreadTable_Class; } // namespace Egg
+namespace Egg
+{
+
+class SpreadTable
+: public Gtk::Container
+{
+ public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ typedef SpreadTable CppObjectType;
+ typedef SpreadTable_Class CppClassType;
+ typedef EggSpreadTable BaseObjectType;
+ typedef EggSpreadTableClass BaseClassType;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+ virtual ~SpreadTable();
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+private:
+ friend class SpreadTable_Class;
+ static CppClassType spreadtable_class_;
+
+ // noncopyable
+ SpreadTable(const SpreadTable&);
+ SpreadTable& operator=(const SpreadTable&);
+
+protected:
+ explicit SpreadTable(const Glib::ConstructParams& construct_params);
+ explicit SpreadTable(EggSpreadTable* castitem);
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ static GType get_type() G_GNUC_CONST;
+
+
+ static GType get_base_type() G_GNUC_CONST;
+#endif
+
+ ///Provides access to the underlying C GtkObject.
+ EggSpreadTable* gobj() { return reinterpret_cast<EggSpreadTable*>(gobject_); }
+
+ ///Provides access to the underlying C GtkObject.
+ const EggSpreadTable* gobj() const { return reinterpret_cast<EggSpreadTable*>(gobject_); }
+
+
+public:
+ //C++ methods used to invoke GTK+ virtual functions:
+
+protected:
+ //GTK+ Virtual Functions (override these to change behaviour):
+
+ //Default Signal Handlers::
+
+
+private:
+
+
+public:
+ SpreadTable();
+ explicit SpreadTable(Gtk::Orientation orientation, guint lines);
+
+ //TODO: Is the default packing appropriate (and like the default for a Box::pack_start())?
+
+ void insert_child(Gtk::Widget& widget, int index);
+
+
+ guint get_child_line(const Gtk::Widget& child, int size) const;
+
+
+ void set_lines(guint lines);
+
+ guint get_lines() const;
+
+
+ void set_vertical_spacing(guint spacing);
+
+ guint get_vertical_spacing() const;
+
+
+ void set_horizontal_spacing(guint spacing);
+
+ guint get_horizontal_spacing() const;
+
+ //TODO: Documentation
+ void append_child(Widget& widget);
+
+ #ifdef GLIBMM_PROPERTIES_ENABLED
+/** The amount of vertical space between two children.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy<guint> property_vertical_spacing() ;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+/** The amount of vertical space between two children.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy_ReadOnly<guint> property_vertical_spacing() const;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+ #ifdef GLIBMM_PROPERTIES_ENABLED
+/** The amount of horizontal space between two children.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy<guint> property_horizontal_spacing() ;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+/** The amount of horizontal space between two children.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy_ReadOnly<guint> property_horizontal_spacing() const;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+ #ifdef GLIBMM_PROPERTIES_ENABLED
+/** The number of lines (rows/columns) to evenly distribute children to.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy<guint> property_lines() ;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+#ifdef GLIBMM_PROPERTIES_ENABLED
+/** The number of lines (rows/columns) to evenly distribute children to.
+ *
+ * You rarely need to use properties because there are get_ and set_ methods for almost all of them.
+ * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when
+ * the value of the property changes.
+ */
+ Glib::PropertyProxy_ReadOnly<guint> property_lines() const;
+#endif //#GLIBMM_PROPERTIES_ENABLED
+
+
+};
+
+} // namespace Egg
+
+
+namespace Glib
+{
+ /** A Glib::wrap() method for this object.
+ *
+ * @param object The C instance.
+ * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
+ * @result A C++ instance that wraps this C instance.
+ *
+ * @relates Egg::SpreadTable
+ */
+ Egg::SpreadTable* wrap(EggSpreadTable* object, bool take_copy = false);
+} //namespace Glib
+
+
+#endif /* _EGG_SPREADTABLE_H */
diff --git a/glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h b/glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h
new file mode 100644
index 0000000..eb95ba2
--- /dev/null
+++ b/glom/utility_widgets/eggspreadtablemm/private/eggspreadtablemm_p.h
@@ -0,0 +1,45 @@
+#ifndef _EGG_SPREADTABLE_P_H
+#define _EGG_SPREADTABLE_P_H
+
+
+#include <gtkmm/private/container_p.h>
+
+#include <glibmm/class.h>
+
+namespace Egg
+{
+
+class SpreadTable_Class : public Glib::Class
+{
+public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ typedef SpreadTable CppObjectType;
+ typedef EggSpreadTable BaseObjectType;
+ typedef EggSpreadTableClass BaseClassType;
+ typedef Gtk::Container_Class CppClassParent;
+ typedef GtkContainerClass BaseClassParent;
+
+ friend class SpreadTable;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+ const Glib::Class& init();
+
+
+ static void class_init_function(void* g_class, void* class_data);
+
+ static Glib::ObjectBase* wrap_new(GObject*);
+
+protected:
+
+ //Callbacks (default signal handlers):
+ //These will call the *_impl member methods, which will then call the existing default signal callbacks, if any.
+ //You could prevent the original default signal handlers being called by overriding the *_impl method.
+
+ //Callbacks (virtual functions):
+};
+
+
+} // namespace Egg
+
+
+#endif /* _EGG_SPREADTABLE_P_H */
diff --git a/glom/utility_widgets/flowtable.cc b/glom/utility_widgets/flowtable.cc
index 9947a76..f9a4e44 100644
--- a/glom/utility_widgets/flowtable.cc
+++ b/glom/utility_widgets/flowtable.cc
@@ -99,7 +99,7 @@ void FlowTable::delete_and_forget_hbox(Gtk::HBox* hbox)
std::cout << G_STRFUNC << "Removing: hbox=" << hbox << std::endl;
if(hbox->get_parent() == this)
{
- Gtk::SpreadTable::remove(*hbox);
+ Egg::SpreadTable::remove(*hbox);
}
else
{
@@ -231,7 +231,7 @@ void FlowTable::remove(Gtk::Widget& first)
return;
}
- Gtk::SpreadTable::remove(first);
+ Egg::SpreadTable::remove(first);
}
bool FlowTable::get_column_for_first_widget(const Gtk::Widget& first, guint& column) const
@@ -250,7 +250,7 @@ bool FlowTable::get_column_for_first_widget(const Gtk::Widget& first, guint& col
if(!widget)
continue;
- //Get the widget that GtkSpreadTable thinks of as the child:
+ //Get the widget that EggSpreadTable thinks of as the child:
const Gtk::Widget* child = 0;
if(widget == &first) //It must be a single item.
diff --git a/glom/utility_widgets/flowtable.h b/glom/utility_widgets/flowtable.h
index 117b77d..8a426e3 100644
--- a/glom/utility_widgets/flowtable.h
+++ b/glom/utility_widgets/flowtable.h
@@ -22,12 +22,13 @@
#define GLOM_UTILITYWIDGETS_FLOWTABLE_H
#include <gtkmm.h>
+#include <glom/utility_widgets/eggspreadtablemm/eggspreadtablemm.h>
#include "layoutwidgetbase.h"
namespace Glom
{
-class FlowTable : public Gtk::SpreadTable
+class FlowTable : public Egg::SpreadTable
{
public:
FlowTable();
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7d30d5e..fa69055 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -124,6 +124,7 @@ glom/mode_data/db_adddel/db_adddel.cc
glom/mode_data/datawidget/dialog_choose_id.cc
glom/utility_widgets/dialog_image_progress.cc
glom/mode_data/datawidget/entry.cc
+glom/utility_widgets/eggspreadtable/eggspreadtable.c
glom/utility_widgets/filechooserdialog_saveextras.cc
glom/utility_widgets/imageglom.cc
glom/utility_widgets/layouttoolbar.cc
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]