[libegg/spread-table-dnd] Added apis to EggSpreadTable to better cooperate with the DnD subclass
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libegg/spread-table-dnd] Added apis to EggSpreadTable to better cooperate with the DnD subclass
- Date: Fri, 1 Apr 2011 20:19:36 +0000 (UTC)
commit 82fa24c78cf997eb5570a4aa098c337d3efc9930
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Fri Apr 1 17:15:11 2011 +0900
Added apis to EggSpreadTable to better cooperate with the DnD subclass
- Added child property "position"
- Added api egg_spread_table_reorder_child() so that "position" property
can be writable
- Added egg_spread_table_lock()/unlock() to lock the configuration of
children during DnD operations
- Added egg_spread_table_get_segments() so that the subclass can see
how many children are in each column
- Added egg_spread_table_set_segment_length() to allow the subclass to
manually configure the segments while locked.
libegg/spreadtable/eggspreadtable.c | 247 ++++++++++++++++++++++++++++++++++-
libegg/spreadtable/eggspreadtable.h | 12 ++
2 files changed, 256 insertions(+), 3 deletions(-)
---
diff --git a/libegg/spreadtable/eggspreadtable.c b/libegg/spreadtable/eggspreadtable.c
index f965551..8e8e198 100644
--- a/libegg/spreadtable/eggspreadtable.c
+++ b/libegg/spreadtable/eggspreadtable.c
@@ -50,11 +50,18 @@ enum {
PROP_LINES
};
+enum {
+ CHILD_PROP_0,
+ CHILD_PROP_POSITION
+};
+
struct _EggSpreadTablePrivate {
GList *children;
GtkOrientation orientation;
+ gint *locked_config;
+
guint16 lines;
guint16 horizontal_spacing;
guint16 vertical_spacing;
@@ -94,14 +101,22 @@ static void egg_spread_table_add (GtkContainer *containe
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);
+static void egg_spread_table_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void egg_spread_table_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
/* EggSpreadTableClass */
static void egg_spread_table_real_insert_child (EggSpreadTable *table,
@@ -146,6 +161,8 @@ egg_spread_table_class_init (EggSpreadTableClass *class)
container_class->remove = egg_spread_table_remove;
container_class->forall = egg_spread_table_forall;
container_class->child_type = egg_spread_table_child_type;
+ container_class->get_child_property = egg_spread_table_get_child_property;
+ container_class->set_child_property = egg_spread_table_set_child_property;
class->insert_child = egg_spread_table_real_insert_child;
@@ -204,6 +221,20 @@ egg_spread_table_class_init (EggSpreadTableClass *class)
0,
G_PARAM_READABLE | G_PARAM_WRITABLE));
+ /**
+ * EggSpreadTable:position:
+ *
+ * The position of the child in the spread table.
+ *
+ */
+ gtk_container_class_install_child_property (container_class,
+ CHILD_PROP_POSITION,
+ g_param_spec_int ("position",
+ P_("Position"),
+ P_("The index of the child in the table"),
+ -1, G_MAXINT, -1,
+ G_PARAM_READABLE | G_PARAM_WRITABLE));
+
g_type_class_add_private (class, sizeof (EggSpreadTablePrivate));
}
@@ -470,6 +501,41 @@ children_fit_segment_size (EggSpreadTable *table,
return (l == NULL);
}
+
+static gint
+get_size_for_locked_config (EggSpreadTable *table,
+ gint line_thickness)
+{
+ EggSpreadTablePrivate *priv = table->priv;
+ GList *l;
+ gint line = 0, i = 0;
+ gint largest_line = 0, line_size = 0, widget_size;
+
+ for (l = priv->children; l && line < priv->lines; l = l->next)
+ {
+ GtkWidget *child = l->data;
+
+ if (!gtk_widget_get_visible (child))
+ continue;
+
+ get_widget_size (child, priv->orientation, line_thickness, NULL, &widget_size);
+
+ line_size += widget_size;
+ if (i > 0)
+ line_size += ITEM_SPACING (table);
+
+ if (i++ >= priv->locked_config[line])
+ {
+ largest_line = MAX (largest_line, line_size);
+
+ line_size = 0;
+ i = 0;
+ line++;
+ }
+ }
+ return largest_line;
+}
+
/* 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.
@@ -491,9 +557,18 @@ segment_lines_for_size (EggSpreadTable *table,
gint upper, lower, segment_size, largest_size = 0;
gint i, j;
- priv = table->priv;
+ priv = table->priv;
+
line_thickness = get_line_thickness (table, for_size);
+ if (priv->locked_config)
+ {
+ if (segments)
+ *segments = g_memdup (priv->locked_config, sizeof (gint) * priv->lines);
+
+ return get_size_for_locked_config (table, line_thickness);
+ }
+
segment_counts = g_new0 (gint, priv->lines);
test_counts = g_new0 (gint, priv->lines);
@@ -896,6 +971,49 @@ egg_spread_table_child_type (G_GNUC_UNUSED GtkContainer *container)
return GTK_TYPE_WIDGET;
}
+static void
+egg_spread_table_get_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EggSpreadTable *table = EGG_SPREAD_TABLE (container);
+ EggSpreadTablePrivate *priv = table->priv;
+ gint position;
+
+ switch (property_id)
+ {
+ case CHILD_PROP_POSITION:
+ position = g_list_index (priv->children, child);
+ g_value_set_int (value, position);
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
+static void
+egg_spread_table_set_child_property (GtkContainer *container,
+ GtkWidget *child,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case CHILD_PROP_POSITION:
+ egg_spread_table_reorder_child (EGG_SPREAD_TABLE (container), child, g_value_get_int (value));
+ break;
+
+ default:
+ GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
+ break;
+ }
+}
+
/*****************************************************
* EggSpreadTableClass *
@@ -960,6 +1078,129 @@ egg_spread_table_insert_child (EggSpreadTable *table,
EGG_SPREAD_TABLE_GET_CLASS (table)->insert_child (table, child, index);
}
+/**
+ * egg_spread_table_reorder_child:
+ * @spread_table: An #EggSpreadTable
+ * @widget: The child to reorder
+ * @index: The new child position
+ *
+ * Reorders the child @widget in @spread_table's list of children.
+ */
+void
+egg_spread_table_reorder_child (EggSpreadTable *spread_table,
+ GtkWidget *widget,
+ guint index)
+{
+ EggSpreadTablePrivate *priv;
+ GList *link;
+
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (spread_table));
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+
+ priv = spread_table->priv;
+
+ link = g_list_find (priv->children, widget);
+ g_return_if_fail (link != NULL);
+
+ if (g_list_position (priv->children, link) != index)
+ {
+ priv->children = g_list_delete_link (priv->children, link);
+ priv->children = g_list_insert (priv->children, widget, index);
+ gtk_widget_queue_resize (GTK_WIDGET (spread_table));
+ }
+}
+
+/**
+ * egg_spread_table_lock:
+ * @spread_table: An #EggSpreadTable
+ *
+ * Locks @spread_table into the current configuration, while
+ * the table is locked children stay in their respective columns/rows.
+ *
+ * Before adding or removing widgets from the table while it is locked,
+ * calls to egg_spread_table_set_segment_length() should be made to
+ * hand configure where the newly inserted widgets will appear.
+ */
+void
+egg_spread_table_lock (EggSpreadTable *table)
+
+{
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+
+ if (table->priv->locked_config == NULL)
+ table->priv->locked_config = egg_spread_table_get_segments (table);
+}
+
+/**
+ * egg_spread_table_unlock:
+ * @spread_table: An #EggSpreadTable
+ *
+ * Unlocks @spread_table (see egg_spread_table_lock()).
+ */
+void
+egg_spread_table_unlock (EggSpreadTable *table)
+{
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+
+ g_free (table->priv->locked_config);
+ table->priv->locked_config = NULL;
+}
+
+/**
+ * egg_spread_table_get_segments:
+ * @table: A #EggSpreadTable
+ *
+ * Gets the number of children distributed in each line.
+ *
+ * Returns: An array of integers representing how many
+ * widgets are in each line, the returned array
+ * is the length of the amount of lines
+ * (see egg_spread_table_get_lines()).
+ */
+gint *
+egg_spread_table_get_segments (EggSpreadTable *table)
+{
+ EggSpreadTablePrivate *priv;
+ GtkAllocation allocation;
+ gint *segments = NULL;
+ gint size;
+
+ g_return_val_if_fail (EGG_IS_SPREAD_TABLE (table), NULL);
+
+ priv = table->priv;
+
+ gtk_widget_get_allocation (GTK_WIDGET (table), &allocation);
+
+ if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
+ size = allocation.height;
+ else
+ size = allocation.width;
+
+ segment_lines_for_size (table, size, &segments);
+
+ return segments;
+}
+
+/**
+ * egg_spread_table_set_segment_length:
+ * @table: A #EggSpreadTable
+ * @segment: The segment or 'line' which to adjust the length
+ * @length: The new length for @segment
+ *
+ * This is used to manually configure the length of segments
+ * while @table is locked (see egg_spread_table_lock()).
+ */
+void
+egg_spread_table_set_segment_length (EggSpreadTable *table,
+ gint segment,
+ gint length)
+{
+ g_return_if_fail (EGG_IS_SPREAD_TABLE (table));
+ g_return_if_fail (table->priv->locked_config != NULL);
+ g_return_if_fail (segment >= 0 && segment < table->priv->lines);
+
+ table->priv->locked_config[segment] = length;
+}
/**
diff --git a/libegg/spreadtable/eggspreadtable.h b/libegg/spreadtable/eggspreadtable.h
index 50fa8fd..0a2cd63 100644
--- a/libegg/spreadtable/eggspreadtable.h
+++ b/libegg/spreadtable/eggspreadtable.h
@@ -68,6 +68,18 @@ void egg_spread_table_insert_child (EggSpreadTable
GtkWidget *child,
gint index);
+void egg_spread_table_reorder_child (EggSpreadTable *table,
+ GtkWidget *widget,
+ guint index);
+
+void egg_spread_table_lock (EggSpreadTable *table);
+void egg_spread_table_unlock (EggSpreadTable *table);
+
+gint *egg_spread_table_get_segments (EggSpreadTable *table);
+void egg_spread_table_set_segment_length (EggSpreadTable *table,
+ gint segment,
+ gint length);
+
guint egg_spread_table_get_child_line (EggSpreadTable *table,
GtkWidget *child,
gint size);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]