[glade] Fix for drag/resize in GtkGrid.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade] Fix for drag/resize in GtkGrid.
- Date: Wed, 3 Apr 2013 07:15:12 +0000 (UTC)
commit 0391bd594480315da265fe0b72a1cc7070f3e340
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Wed Apr 3 16:12:35 2013 +0900
Fix for drag/resize in GtkGrid.
This patch ensures that width/height child properties of grid
are properly updated while expanding left & right, it also
moves all the GladeFixed code to a single section at the bottom
of the file.
plugins/gtk+/glade-gtk-grid.c | 1367 +++++++++++++++++++++--------------------
1 files changed, 691 insertions(+), 676 deletions(-)
---
diff --git a/plugins/gtk+/glade-gtk-grid.c b/plugins/gtk+/glade-gtk-grid.c
index 63b250d..d5a5900 100644
--- a/plugins/gtk+/glade-gtk-grid.c
+++ b/plugins/gtk+/glade-gtk-grid.c
@@ -31,32 +31,22 @@
typedef struct
{
- /* comparable part: */
- GladeWidget *widget;
- gint left_attach;
- gint top_attach;
- gint width;
- gint height;
-} GladeGridChild;
-
-typedef struct
-{
gint left_attach;
gint top_attach;
gint width;
gint height;
} GladeGridAttachments;
-typedef enum
-{
- DIR_UP,
- DIR_DOWN,
- DIR_LEFT,
- DIR_RIGHT
-} GladeGridDir;
-
-static GladeGridChild grid_edit = { 0, };
-static GladeGridChild grid_cur_attach = { 0, };
+static gboolean glade_gtk_grid_configure_begin (GladeFixed *fixed,
+ GladeWidget *child,
+ GtkWidget *grid);
+static gboolean glade_gtk_grid_configure_end (GladeFixed *fixed,
+ GladeWidget *child,
+ GtkWidget *grid);
+static gboolean glade_gtk_grid_configure_child (GladeFixed *fixed,
+ GladeWidget *child,
+ GdkRectangle *rect,
+ GtkWidget *grid);
static void
glade_gtk_grid_get_child_attachments (GtkWidget *grid,
@@ -141,838 +131,863 @@ glade_gtk_grid_refresh_placeholders (GtkGrid *grid,
g_list_free (children);
}
-/* Takes a point (x or y depending on 'row') relative to
-* grid, and returns the row or column in which the point
-* was found.
-*/
-static gint
-glade_gtk_grid_get_row_col_from_point (GtkGrid *grid, gboolean row, gint point)
+static void
+glade_gtk_grid_parse_finished (GladeProject *project, GObject *container)
{
+ GladeWidget *gwidget = glade_widget_get_from_gobject (container);
GladeGridAttachments attach;
- GtkAllocation allocation;
GList *list, *children;
- gint span, trans_point, size, base, end;
+ gint row = 0, column = 0, n_row = 0, n_column = 0;
- children = gtk_container_get_children (GTK_CONTAINER (grid));
+ children = gtk_container_get_children (GTK_CONTAINER (container));
for (list = children; list; list = list->next)
{
GtkWidget *widget = list->data;
- glade_gtk_grid_get_child_attachments (GTK_WIDGET (grid), widget, &attach);
-
- if (row)
- gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, 0, point, NULL, &trans_point);
- else
- gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, point, 0, &trans_point, NULL);
-
- gtk_widget_get_allocation (widget, &allocation);
+ if (GLADE_IS_PLACEHOLDER (widget)) continue;
- /* Find any widget in our row/column
- */
- end = row ? allocation.height : allocation.width;
+ glade_gtk_grid_get_child_attachments (GTK_WIDGET (container), widget, &attach);
- if (trans_point >= 0 &&
- /* should be trans_point < end ... test FIXME ! */
- trans_point < end)
- {
- base = row ? attach.top_attach : attach.left_attach;
- size = row ? allocation.height : allocation.width;
- span = row ? attach.height : attach.width;
+ n_row = attach.top_attach + attach.height;
+ n_column = attach.left_attach + attach.width;
- return base + (trans_point * span / size);
- }
+ if (row < n_row) row = n_row;
+ if (column < n_column) column = n_column;
}
+ if (column) glade_widget_property_set (gwidget, "n-columns", column);
+ if (row) glade_widget_property_set (gwidget, "n-rows", row);
+
g_list_free (children);
- return -1;
+ /* Refresh placeholders only once after the project is finished parsing */
+ glade_gtk_grid_refresh_placeholders (GTK_GRID (container), TRUE);
}
+void
+glade_gtk_grid_post_create (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GladeCreateReason reason)
+{
+ GladeWidget *gwidget = glade_widget_get_from_gobject (container);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-child",
+ G_CALLBACK (glade_gtk_grid_configure_child), container);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-begin",
+ G_CALLBACK (glade_gtk_grid_configure_begin), container);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-end",
+ G_CALLBACK (glade_gtk_grid_configure_end), container);
+
+ if (reason == GLADE_CREATE_LOAD)
+ g_signal_connect (glade_widget_get_project (gwidget), "parse-finished",
+ G_CALLBACK (glade_gtk_grid_parse_finished),
+ container);
+}
static gboolean
-glade_gtk_grid_point_crosses_threshold (GtkGrid *grid,
- gboolean row,
- gint num,
- GladeGridDir dir,
- gint point)
+glade_gtk_grid_widget_exceeds_bounds (GtkGrid *grid, gint n_rows, gint n_cols)
{
- GladeGridAttachments attach;
- GtkAllocation allocation;
GList *list, *children;
- gint span, trans_point, size, rowcol_size, base;
+ gboolean ret = FALSE;
children = gtk_container_get_children (GTK_CONTAINER (grid));
- for (list = children; list; list = list->next)
+ for (list = children; list && list->data; list = g_list_next (list))
{
+ GladeGridAttachments attach;
GtkWidget *widget = list->data;
+ if (GLADE_IS_PLACEHOLDER (widget)) continue;
+
glade_gtk_grid_get_child_attachments (GTK_WIDGET (grid), widget, &attach);
- /* Find any widget in our row/column
- */
- if ((row && num >= attach.top_attach && num < attach.top_attach + attach.height) ||
- (!row && num >= attach.left_attach && num < attach.left_attach + attach.width))
+ if (attach.left_attach + attach.width > n_cols ||
+ attach.top_attach + attach.height > n_rows)
{
-
- if (row)
- gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, 0, point, NULL, &trans_point);
- else
- gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, point, 0, &trans_point, NULL);
-
- span = row ? attach.height : attach.width;
- gtk_widget_get_allocation (widget, &allocation);
- size = row ? allocation.height : allocation.width;
-
- base = row ? attach.top_attach : attach.left_attach;
- rowcol_size = size / span;
- trans_point -= (num - base) * rowcol_size;
-
-#if 0
- g_print ("dir: %s, widget size: %d, rowcol size: %d, "
- "requested rowcol: %d, widget base rowcol: %d, trim: %d, "
- "widget point: %d, thresh: %d\n",
- dir == DIR_UP ? "up" : dir == DIR_DOWN ? "down" :
- dir == DIR_LEFT ? "left" : "right",
- size, rowcol_size, num, base, (num - base) * rowcol_size,
- trans_point,
- dir == DIR_UP || dir == DIR_LEFT ?
- (rowcol_size / 2) : (rowcol_size / 2));
-#endif
- switch (dir)
- {
- case DIR_UP:
- case DIR_LEFT:
- return trans_point <= (rowcol_size / 2);
- case DIR_DOWN:
- case DIR_RIGHT:
- return trans_point >= (rowcol_size / 2);
- default:
- break;
- }
+ ret = TRUE;
+ break;
}
-
}
g_list_free (children);
- return FALSE;
+ return ret;
}
-static gboolean
-glade_gtk_grid_get_attachments (GladeFixed *fixed,
- GtkGrid *grid,
- GdkRectangle *rect,
- GladeGridChild *configure)
+static void
+gtk_grid_children_callback (GtkWidget *widget, gpointer client_data)
{
- GladeWidget *widget = GLADE_WIDGET (fixed);
- gint center_x, center_y, row, column;
- guint n_columns, n_rows;
-
- center_x = rect->x + (rect->width / 2);
- center_y = rect->y + (rect->height / 2);
-
- column = glade_gtk_grid_get_row_col_from_point (grid, FALSE, center_x);
- row = glade_gtk_grid_get_row_col_from_point (grid, TRUE, center_y);
+ GList **children;
- /* its a start, now try to grow when the rect extents
- * reach at least half way into the next row/column
- */
- configure->left_attach = column;
- configure->width = 1;
- configure->top_attach = row;
- configure->height = 1;
+ children = (GList **) client_data;
+ *children = g_list_prepend (*children, widget);
+}
- glade_widget_property_get (widget, "n-columns", &n_columns);
- glade_widget_property_get (widget, "n-rows", &n_rows);
+GList *
+glade_gtk_grid_get_children (GladeWidgetAdaptor *adaptor,
+ GtkContainer *container)
+{
+ GList *children = NULL;
- if (column >= 0 && row >= 0)
- {
- /* Check and expand left
- */
- while (configure->left_attach > 0)
- {
- if (rect->x < fixed->child_x_origin &&
- fixed->operation != GLADE_CURSOR_DRAG &&
- GLADE_FIXED_CURSOR_LEFT (fixed->operation) == FALSE)
- break;
+ g_return_val_if_fail (GTK_IS_GRID (container), NULL);
- if (glade_gtk_grid_point_crosses_threshold
- (grid, FALSE, configure->left_attach - 1,
- DIR_LEFT, rect->x) == FALSE)
- break;
+ gtk_container_forall (container, gtk_grid_children_callback, &children);
- configure->left_attach--;
- }
+ /* GtkGrid has the children list already reversed */
+ return children;
+}
- /* Check and expand right
- */
- while (configure->left_attach + configure->width < n_columns)
- {
- if (rect->x + rect->width >
- fixed->child_x_origin + fixed->child_width_origin &&
- fixed->operation != GLADE_CURSOR_DRAG &&
- GLADE_FIXED_CURSOR_RIGHT (fixed->operation) == FALSE)
- break;
+void
+glade_gtk_grid_add_child (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ GObject *child)
+{
+ g_return_if_fail (GTK_IS_GRID (object));
+ g_return_if_fail (GTK_IS_WIDGET (child));
- if (glade_gtk_grid_point_crosses_threshold
- (grid, FALSE, configure->left_attach + configure->width,
- DIR_RIGHT, rect->x + rect->width) == FALSE)
- break;
+ gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
- configure->width++;
- }
+ glade_gtk_grid_refresh_placeholders (GTK_GRID (object), FALSE);
+}
- /* Check and expand top
- */
- while (configure->top_attach > 0)
- {
- if (rect->y < fixed->child_y_origin &&
- fixed->operation != GLADE_CURSOR_DRAG &&
- GLADE_FIXED_CURSOR_TOP (fixed->operation) == FALSE)
- break;
+void
+glade_gtk_grid_remove_child (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ GObject *child)
+{
+ g_return_if_fail (GTK_IS_GRID (object));
+ g_return_if_fail (GTK_IS_WIDGET (child));
- if (glade_gtk_grid_point_crosses_threshold
- (grid, TRUE, configure->top_attach - 1,
- DIR_UP, rect->y) == FALSE)
- break;
+ gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
- configure->top_attach--;
- }
+ glade_gtk_grid_refresh_placeholders (GTK_GRID (object), FALSE);
+}
- /* Check and expand bottom
- */
- while (configure->top_attach + configure->height < n_rows)
- {
- if (rect->y + rect->height >
- fixed->child_y_origin + fixed->child_height_origin &&
- fixed->operation != GLADE_CURSOR_DRAG &&
- GLADE_FIXED_CURSOR_BOTTOM (fixed->operation) == FALSE)
- break;
-
- if (glade_gtk_grid_point_crosses_threshold
- (grid, TRUE, configure->top_attach + configure->height,
- DIR_DOWN, rect->y + rect->height) == FALSE)
- break;
+void
+glade_gtk_grid_replace_child (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GObject *current,
+ GObject *new_widget)
+{
+ g_return_if_fail (GTK_IS_GRID (container));
+ g_return_if_fail (GTK_IS_WIDGET (current));
+ g_return_if_fail (GTK_IS_WIDGET (new_widget));
- configure->height++;
- }
- }
+ /* Chain Up */
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->replace_child (adaptor,
+ container,
+ current,
+ new_widget);
- return column >= 0 && row >= 0;
+ /* If we are replacing a GladeWidget, we must refresh placeholders
+ * because the widget may have spanned multiple rows/columns, we must
+ * not do so in the case we are pasting multiple widgets into a grid,
+ * where destroying placeholders results in default packing properties
+ * (since the remaining placeholder templates no longer exist, only the
+ * first pasted widget would have proper packing properties).
+ */
+ if (!GLADE_IS_PLACEHOLDER (new_widget))
+ glade_gtk_grid_refresh_placeholders (GTK_GRID (container), FALSE);
}
-static gboolean
-glade_gtk_grid_configure_child (GladeFixed *fixed,
- GladeWidget *child,
- GdkRectangle *rect,
- GtkWidget *grid)
+static void
+glade_gtk_grid_set_n_common (GObject *object,
+ const GValue *value,
+ gboolean for_rows)
{
- GladeGridChild configure = { child, };
+ GladeWidget *widget;
+ GtkGrid *grid;
+ guint new_size, n_columns, n_rows;
- /* Sometimes we are unable to find a widget in the appropriate column,
- * usually because a placeholder hasnt had its size allocation yet.
- */
- if (glade_gtk_grid_get_attachments (fixed, GTK_GRID (grid), rect, &configure))
- {
- if (memcmp (&configure, &grid_cur_attach, sizeof (GladeGridChild)) != 0)
- {
+ grid = GTK_GRID (object);
+ widget = glade_widget_get_from_gobject (GTK_WIDGET (grid));
- glade_property_push_superuser ();
- glade_widget_pack_property_set (child, "left-attach",
- configure.left_attach);
- glade_widget_pack_property_set (child, "width",
- configure.width);
- glade_widget_pack_property_set (child, "top-attach",
- configure.top_attach);
- glade_widget_pack_property_set (child, "height",
- configure.height);
- glade_property_pop_superuser ();
+ glade_widget_property_get (widget, "n-columns", &n_columns);
+ glade_widget_property_get (widget, "n-rows", &n_rows);
- memcpy (&grid_cur_attach, &configure, sizeof (GladeGridChild));
- }
- }
- return TRUE;
-}
+ new_size = g_value_get_uint (value);
-static gboolean
-glade_gtk_grid_configure_begin (GladeFixed *fixed,
- GladeWidget *child,
- GtkWidget *grid)
-{
- grid_edit.widget = child;
+ if (new_size < 1)
+ return;
- glade_widget_pack_property_get (child, "left-attach", &grid_edit.left_attach);
- glade_widget_pack_property_get (child, "width", &grid_edit.width);
- glade_widget_pack_property_get (child, "top-attach", &grid_edit.top_attach);
- glade_widget_pack_property_get (child, "height", &grid_edit.height);
+ if (glade_gtk_grid_widget_exceeds_bounds
+ (grid, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
+ /* Refuse to shrink if it means orphaning widgets */
+ return;
- memcpy (&grid_cur_attach, &grid_edit, sizeof (GladeGridChild));
+ /* Fill grid with placeholders */
+ glade_gtk_grid_refresh_placeholders (grid, FALSE);
+}
- return TRUE;
+void
+glade_gtk_grid_set_property (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *id,
+ const GValue *value)
+{
+ if (!strcmp (id, "n-rows"))
+ glade_gtk_grid_set_n_common (object, value, TRUE);
+ else if (!strcmp (id, "n-columns"))
+ glade_gtk_grid_set_n_common (object, value, FALSE);
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
+ id, value);
}
static gboolean
-glade_gtk_grid_configure_end (GladeFixed *fixed,
- GladeWidget *child,
- GtkWidget *grid)
+glade_gtk_grid_verify_n_common (GObject *object,
+ const GValue *value,
+ gboolean for_rows)
{
- GladeGridChild new_child = { child, };
-
- glade_widget_pack_property_get (child, "left-attach", &new_child.left_attach);
- glade_widget_pack_property_get (child, "width", &new_child.width);
- glade_widget_pack_property_get (child, "top-attach", &new_child.top_attach);
- glade_widget_pack_property_get (child, "height", &new_child.height);
-
- /* Compare the meaningfull part of the current edit. */
- if (memcmp (&new_child, &grid_edit, sizeof (GladeGridChild)) != 0)
- {
- GValue left_attach_value = { 0, };
- GValue width_attach_value = { 0, };
- GValue top_attach_value = { 0, };
- GValue height_attach_value = { 0, };
-
- GValue new_left_attach_value = { 0, };
- GValue new_width_attach_value = { 0, };
- GValue new_top_attach_value = { 0, };
- GValue new_height_attach_value = { 0, };
-
- GladeProperty *left_attach_prop, *width_attach_prop,
- *top_attach_prop, *height_attach_prop;
-
- left_attach_prop = glade_widget_get_pack_property (child, "left-attach");
- width_attach_prop = glade_widget_get_pack_property (child, "width");
- top_attach_prop = glade_widget_get_pack_property (child, "top-attach");
- height_attach_prop = glade_widget_get_pack_property (child, "height");
-
- g_return_val_if_fail (GLADE_IS_PROPERTY (left_attach_prop), FALSE);
- g_return_val_if_fail (GLADE_IS_PROPERTY (width_attach_prop), FALSE);
- g_return_val_if_fail (GLADE_IS_PROPERTY (top_attach_prop), FALSE);
- g_return_val_if_fail (GLADE_IS_PROPERTY (height_attach_prop), FALSE);
-
- glade_property_get_value (left_attach_prop, &new_left_attach_value);
- glade_property_get_value (width_attach_prop, &new_width_attach_value);
- glade_property_get_value (top_attach_prop, &new_top_attach_value);
- glade_property_get_value (height_attach_prop, &new_height_attach_value);
+ GtkGrid *grid = GTK_GRID (object);
+ GladeWidget *widget;
+ guint n_columns, n_rows, new_size = g_value_get_uint (value);
- g_value_init (&left_attach_value, G_TYPE_INT);
- g_value_init (&width_attach_value, G_TYPE_INT);
- g_value_init (&top_attach_value, G_TYPE_INT);
- g_value_init (&height_attach_value, G_TYPE_INT);
+ widget = glade_widget_get_from_gobject (GTK_WIDGET (grid));
+ glade_widget_property_get (widget, "n-columns", &n_columns);
+ glade_widget_property_get (widget, "n-rows", &n_rows);
- g_value_set_int (&left_attach_value, grid_edit.left_attach);
- g_value_set_int (&width_attach_value, grid_edit.width);
- g_value_set_int (&top_attach_value, grid_edit.top_attach);
- g_value_set_int (&height_attach_value, grid_edit.height);
+ if (glade_gtk_grid_widget_exceeds_bounds
+ (grid, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
+ /* Refuse to shrink if it means orphaning widgets */
+ return FALSE;
- glade_command_push_group (_("Placing %s inside %s"),
- glade_widget_get_name (child),
- glade_widget_get_name (GLADE_WIDGET (fixed)));
- glade_command_set_properties
- (left_attach_prop, &left_attach_value, &new_left_attach_value,
- width_attach_prop, &width_attach_value, &new_width_attach_value,
- top_attach_prop, &top_attach_value, &new_top_attach_value,
- height_attach_prop, &height_attach_value, &new_height_attach_value,
- NULL);
- glade_command_pop_group ();
+ return TRUE;
+}
- g_value_unset (&left_attach_value);
- g_value_unset (&width_attach_value);
- g_value_unset (&top_attach_value);
- g_value_unset (&height_attach_value);
- g_value_unset (&new_left_attach_value);
- g_value_unset (&new_width_attach_value);
- g_value_unset (&new_top_attach_value);
- g_value_unset (&new_height_attach_value);
- }
+gboolean
+glade_gtk_grid_verify_property (GladeWidgetAdaptor *adaptor,
+ GObject *object,
+ const gchar *id,
+ const GValue *value)
+{
+ if (!strcmp (id, "n-rows"))
+ return glade_gtk_grid_verify_n_common (object, value, TRUE);
+ else if (!strcmp (id, "n-columns"))
+ return glade_gtk_grid_verify_n_common (object, value, FALSE);
+ else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
+ id, value);
return TRUE;
}
-static void
-glade_gtk_grid_parse_finished (GladeProject *project, GObject *container)
+void
+glade_gtk_grid_set_child_property (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GObject *child,
+ const gchar *property_name,
+ GValue *value)
{
- GladeWidget *gwidget = glade_widget_get_from_gobject (container);
- GladeGridAttachments attach;
- GList *list, *children;
- gint row = 0, column = 0, n_row = 0, n_column = 0;
+ g_return_if_fail (GTK_IS_GRID (container));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (property_name != NULL && value != NULL);
- children = gtk_container_get_children (GTK_CONTAINER (container));
+ GWA_GET_CLASS
+ (GTK_TYPE_CONTAINER)->child_set_property (adaptor,
+ container, child,
+ property_name, value);
- for (list = children; list; list = list->next)
+ if (strcmp (property_name, "left-attach") == 0 ||
+ strcmp (property_name, "top-attach") == 0 ||
+ strcmp (property_name, "width") == 0 ||
+ strcmp (property_name, "height") == 0)
{
- GtkWidget *widget = list->data;
+ /* Refresh placeholders */
+ glade_gtk_grid_refresh_placeholders (GTK_GRID (container), FALSE);
+ }
+}
- if (GLADE_IS_PLACEHOLDER (widget)) continue;
+static gboolean
+glade_gtk_grid_verify_attach_common (GObject *object,
+ GValue *value,
+ const gchar *prop,
+ const gchar *parent_prop)
+{
+ GladeWidget *widget, *parent;
+ guint parent_val;
+ gint val, prop_val;
- glade_gtk_grid_get_child_attachments (GTK_WIDGET (container), widget, &attach);
+ widget = glade_widget_get_from_gobject (object);
+ g_return_val_if_fail (GLADE_IS_WIDGET (widget), TRUE);
+ parent = glade_widget_get_parent (widget);
+ g_return_val_if_fail (GLADE_IS_WIDGET (parent), TRUE);
- n_row = attach.top_attach + attach.height;
- n_column = attach.left_attach + attach.width;
+ val = g_value_get_int (value);
+ glade_widget_property_get (widget, prop, &prop_val);
+ glade_widget_property_get (parent, parent_prop, &parent_val);
- if (row < n_row) row = n_row;
- if (column < n_column) column = n_column;
- }
+ if (val < 0 || (val+prop_val) > parent_val)
+ return FALSE;
- if (column) glade_widget_property_set (gwidget, "n-columns", column);
- if (row) glade_widget_property_set (gwidget, "n-rows", row);
+ return TRUE;
+}
- g_list_free (children);
+gboolean
+glade_gtk_grid_child_verify_property (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GObject *child,
+ const gchar *id,
+ GValue *value)
+{
+ if (!strcmp (id, "left-attach"))
+ return glade_gtk_grid_verify_attach_common (child, value, "width", "n-columns");
+ else if (!strcmp (id, "width"))
+ return glade_gtk_grid_verify_attach_common (child, value, "left-attach", "n-columns");
+ else if (!strcmp (id, "top-attach"))
+ return glade_gtk_grid_verify_attach_common (child, value, "height", "n-rows");
+ else if (!strcmp (id, "height"))
+ return glade_gtk_grid_verify_attach_common (child, value, "top-attach", "n-rows");
+ else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_verify_property)
+ GWA_GET_CLASS
+ (GTK_TYPE_CONTAINER)->child_verify_property (adaptor,
+ container, child,
+ id, value);
- /* Refresh placeholders only once after the project is finished parsing */
- glade_gtk_grid_refresh_placeholders (GTK_GRID (container), TRUE);
+ return TRUE;
}
-void
-glade_gtk_grid_post_create (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GladeCreateReason reason)
+static void
+glade_gtk_grid_child_insert_remove_action (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GObject *object,
+ const gchar *group_format,
+ const gchar *n_row_col,
+ const gchar *attach1, /* should be smaller (top/left)
attachment */
+ const gchar *attach2, /* should be larger (bot/right)
attachment */
+ gboolean remove,
+ gboolean after)
{
- GladeWidget *gwidget = glade_widget_get_from_gobject (container);
+ GladeWidget *parent;
+ GList *children, *l;
+ gint child_pos, size, offset;
- g_signal_connect (G_OBJECT (gwidget), "configure-child",
- G_CALLBACK (glade_gtk_grid_configure_child), container);
+ gtk_container_child_get (GTK_CONTAINER (container),
+ GTK_WIDGET (object),
+ attach1, &child_pos, NULL);
- g_signal_connect (G_OBJECT (gwidget), "configure-begin",
- G_CALLBACK (glade_gtk_grid_configure_begin), container);
+ parent = glade_widget_get_from_gobject (container);
+ glade_command_push_group (group_format, glade_widget_get_name (parent));
- g_signal_connect (G_OBJECT (gwidget), "configure-end",
- G_CALLBACK (glade_gtk_grid_configure_end), container);
+ children = glade_widget_adaptor_get_children (adaptor, container);
+ /* Make sure widgets does not get destroyed */
+ g_list_foreach (children, (GFunc) g_object_ref, NULL);
- if (reason == GLADE_CREATE_LOAD)
- g_signal_connect (glade_widget_get_project (gwidget), "parse-finished",
- G_CALLBACK (glade_gtk_grid_parse_finished),
- container);
-}
+ glade_widget_property_get (parent, n_row_col, &size);
-static gboolean
-glade_gtk_grid_widget_exceeds_bounds (GtkGrid *grid, gint n_rows, gint n_cols)
-{
- GList *list, *children;
- gboolean ret = FALSE;
+ if (remove)
+ {
+ GList *del = NULL;
+ /* Remove children first */
+ for (l = children; l; l = g_list_next (l))
+ {
+ GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
+ gint pos1, pos2;
- children = gtk_container_get_children (GTK_CONTAINER (grid));
+ /* Skip placeholders */
+ if (gchild == NULL)
+ continue;
- for (list = children; list && list->data; list = g_list_next (list))
+ glade_widget_pack_property_get (gchild, attach1, &pos1);
+ glade_widget_pack_property_get (gchild, attach2, &pos2);
+ pos2 += pos1;
+ if ((pos1 + 1 == pos2) && ((after ? pos2 : pos1) == child_pos))
+ {
+ del = g_list_prepend (del, gchild);
+ }
+ }
+ if (del)
+ {
+ glade_command_delete (del);
+ g_list_free (del);
+ }
+ offset = -1;
+ }
+ else
{
- GladeGridAttachments attach;
- GtkWidget *widget = list->data;
+ /* Expand the grid */
+ glade_command_set_property (glade_widget_get_property (parent, n_row_col),
+ size + 1);
+ offset = 1;
+ }
- if (GLADE_IS_PLACEHOLDER (widget)) continue;
+ /* Reorder children */
+ for (l = children; l; l = g_list_next (l))
+ {
+ GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
+ gint pos;
- glade_gtk_grid_get_child_attachments (GTK_WIDGET (grid), widget, &attach);
+ /* Skip placeholders */
+ if (gchild == NULL)
+ continue;
- if (attach.left_attach + attach.width > n_cols ||
- attach.top_attach + attach.height > n_rows)
+ /* if removing, do top/left before bot/right */
+ if (remove)
{
- ret = TRUE;
- break;
+ /* adjust top-left attachment */
+ glade_widget_pack_property_get (gchild, attach1, &pos);
+ if (pos > child_pos || (after && pos == child_pos))
+ {
+ glade_command_set_property (glade_widget_get_pack_property
+ (gchild, attach1), pos + offset);
+ }
+ }
+ /* if inserting, do bot/right before top/left */
+ else
+ {
+ /* adjust top-left attachment */
+ glade_widget_pack_property_get (gchild, attach1, &pos);
+
+ if ((after && pos > child_pos) || (!after && pos >= child_pos))
+ {
+ glade_command_set_property (glade_widget_get_pack_property
+ (gchild, attach1), pos + offset);
+ }
}
}
+ if (remove)
+ {
+ /* Shrink the grid */
+ glade_command_set_property (glade_widget_get_property (parent, n_row_col),
+ size - 1);
+ }
+
+ g_list_foreach (children, (GFunc) g_object_unref, NULL);
g_list_free (children);
- return ret;
+ glade_command_pop_group ();
}
-static void
-gtk_grid_children_callback (GtkWidget *widget, gpointer client_data)
+void
+glade_gtk_grid_child_action_activate (GladeWidgetAdaptor *adaptor,
+ GObject *container,
+ GObject *object,
+ const gchar *action_path)
{
- GList **children;
-
- children = (GList **) client_data;
- *children = g_list_prepend (*children, widget);
+ if (strcmp (action_path, "insert_row/after") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Insert Row on %s"),
+ "n-rows", "top-attach",
+ "height", FALSE, TRUE);
+ }
+ else if (strcmp (action_path, "insert_row/before") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Insert Row on %s"),
+ "n-rows", "top-attach",
+ "height",
+ FALSE, FALSE);
+ }
+ else if (strcmp (action_path, "insert_column/after") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Insert Column on %s"),
+ "n-columns", "left-attach",
+ "width", FALSE, TRUE);
+ }
+ else if (strcmp (action_path, "insert_column/before") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Insert Column on %s"),
+ "n-columns", "left-attach",
+ "width", FALSE, FALSE);
+ }
+ else if (strcmp (action_path, "remove_column") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Remove Column on %s"),
+ "n-columns", "left-attach",
+ "width", TRUE, FALSE);
+ }
+ else if (strcmp (action_path, "remove_row") == 0)
+ {
+ glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
+ _("Remove Row on %s"),
+ "n-rows", "top-attach",
+ "height", TRUE, FALSE);
+ }
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
+ container,
+ object,
+ action_path);
}
-GList *
-glade_gtk_grid_get_children (GladeWidgetAdaptor *adaptor,
- GtkContainer *container)
+/***************************************************************
+ * GladeFixed drag/resize *
+ ***************************************************************/
+typedef struct
{
- GList *children = NULL;
-
- g_return_val_if_fail (GTK_IS_GRID (container), NULL);
-
- gtk_container_forall (container, gtk_grid_children_callback, &children);
-
- /* GtkGrid has the children list already reversed */
- return children;
-}
+ GladeWidget *widget;
+ gint left_attach;
+ gint top_attach;
+ gint width;
+ gint height;
+} GladeGridChild;
-void
-glade_gtk_grid_add_child (GladeWidgetAdaptor *adaptor,
- GObject *object,
- GObject *child)
+typedef enum
{
- g_return_if_fail (GTK_IS_GRID (object));
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
+ DIR_UP,
+ DIR_DOWN,
+ DIR_LEFT,
+ DIR_RIGHT
+} GladeGridDir;
- glade_gtk_grid_refresh_placeholders (GTK_GRID (object), FALSE);
-}
+static GladeGridChild grid_edit = { 0, };
+static GladeGridChild grid_cur_attach = { 0, };
-void
-glade_gtk_grid_remove_child (GladeWidgetAdaptor *adaptor,
- GObject *object,
- GObject *child)
+/* Takes a point (x or y depending on 'row') relative to
+* grid, and returns the row or column in which the point
+* was found.
+*/
+static gint
+glade_gtk_grid_get_row_col_from_point (GtkGrid *grid, gboolean row, gint point)
{
- g_return_if_fail (GTK_IS_GRID (object));
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
-
- glade_gtk_grid_refresh_placeholders (GTK_GRID (object), FALSE);
-}
+ GladeGridAttachments attach;
+ GtkAllocation allocation;
+ GList *list, *children;
+ gint span, trans_point, size, base, end;
-void
-glade_gtk_grid_replace_child (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GObject *current,
- GObject *new_widget)
-{
- g_return_if_fail (GTK_IS_GRID (container));
- g_return_if_fail (GTK_IS_WIDGET (current));
- g_return_if_fail (GTK_IS_WIDGET (new_widget));
+ children = gtk_container_get_children (GTK_CONTAINER (grid));
- /* Chain Up */
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->replace_child (adaptor,
- container,
- current,
- new_widget);
+ for (list = children; list; list = list->next)
+ {
+ GtkWidget *widget = list->data;
- /* If we are replacing a GladeWidget, we must refresh placeholders
- * because the widget may have spanned multiple rows/columns, we must
- * not do so in the case we are pasting multiple widgets into a grid,
- * where destroying placeholders results in default packing properties
- * (since the remaining placeholder templates no longer exist, only the
- * first pasted widget would have proper packing properties).
- */
- if (!GLADE_IS_PLACEHOLDER (new_widget))
- glade_gtk_grid_refresh_placeholders (GTK_GRID (container), FALSE);
-}
+ glade_gtk_grid_get_child_attachments (GTK_WIDGET (grid), widget, &attach);
-static void
-glade_gtk_grid_set_n_common (GObject *object,
- const GValue *value,
- gboolean for_rows)
-{
- GladeWidget *widget;
- GtkGrid *grid;
- guint new_size, n_columns, n_rows;
+ if (row)
+ gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, 0, point, NULL, &trans_point);
+ else
+ gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, point, 0, &trans_point, NULL);
- grid = GTK_GRID (object);
- widget = glade_widget_get_from_gobject (GTK_WIDGET (grid));
+ gtk_widget_get_allocation (widget, &allocation);
- glade_widget_property_get (widget, "n-columns", &n_columns);
- glade_widget_property_get (widget, "n-rows", &n_rows);
+ /* Find any widget in our row/column
+ */
+ end = row ? allocation.height : allocation.width;
- new_size = g_value_get_uint (value);
+ if (trans_point >= 0 &&
+ /* should be trans_point < end ... test FIXME ! */
+ trans_point < end)
+ {
+ base = row ? attach.top_attach : attach.left_attach;
+ size = row ? allocation.height : allocation.width;
+ span = row ? attach.height : attach.width;
- if (new_size < 1)
- return;
+ return base + (trans_point * span / size);
+ }
+ }
- if (glade_gtk_grid_widget_exceeds_bounds
- (grid, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
- /* Refuse to shrink if it means orphaning widgets */
- return;
+ g_list_free (children);
- /* Fill grid with placeholders */
- glade_gtk_grid_refresh_placeholders (grid, FALSE);
+ return -1;
}
-void
-glade_gtk_grid_set_property (GladeWidgetAdaptor *adaptor,
- GObject *object,
- const gchar *id,
- const GValue *value)
-{
- if (!strcmp (id, "n-rows"))
- glade_gtk_grid_set_n_common (object, value, TRUE);
- else if (!strcmp (id, "n-columns"))
- glade_gtk_grid_set_n_common (object, value, FALSE);
- else
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object,
- id, value);
-}
static gboolean
-glade_gtk_grid_verify_n_common (GObject *object,
- const GValue *value,
- gboolean for_rows)
+glade_gtk_grid_point_crosses_threshold (GtkGrid *grid,
+ gboolean row,
+ gint num,
+ GladeGridDir dir,
+ gint point)
{
- GtkGrid *grid = GTK_GRID (object);
- GladeWidget *widget;
- guint n_columns, n_rows, new_size = g_value_get_uint (value);
+ GladeGridAttachments attach;
+ GtkAllocation allocation;
+ GList *list, *children;
+ gint span, trans_point, size, rowcol_size, base;
- widget = glade_widget_get_from_gobject (GTK_WIDGET (grid));
- glade_widget_property_get (widget, "n-columns", &n_columns);
- glade_widget_property_get (widget, "n-rows", &n_rows);
+ children = gtk_container_get_children (GTK_CONTAINER (grid));
- if (glade_gtk_grid_widget_exceeds_bounds
- (grid, for_rows ? new_size : n_rows, for_rows ? n_columns : new_size))
- /* Refuse to shrink if it means orphaning widgets */
- return FALSE;
+ for (list = children; list; list = list->next)
+ {
+ GtkWidget *widget = list->data;
- return TRUE;
-}
+ glade_gtk_grid_get_child_attachments (GTK_WIDGET (grid), widget, &attach);
-gboolean
-glade_gtk_grid_verify_property (GladeWidgetAdaptor *adaptor,
- GObject *object,
- const gchar *id,
- const GValue *value)
-{
- if (!strcmp (id, "n-rows"))
- return glade_gtk_grid_verify_n_common (object, value, TRUE);
- else if (!strcmp (id, "n-columns"))
- return glade_gtk_grid_verify_n_common (object, value, FALSE);
- else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
- id, value);
+ /* Find any widget in our row/column
+ */
+ if ((row && num >= attach.top_attach && num < attach.top_attach + attach.height) ||
+ (!row && num >= attach.left_attach && num < attach.left_attach + attach.width))
+ {
- return TRUE;
-}
+ if (row)
+ gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, 0, point, NULL, &trans_point);
+ else
+ gtk_widget_translate_coordinates (GTK_WIDGET (grid), widget, point, 0, &trans_point, NULL);
-void
-glade_gtk_grid_set_child_property (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GObject *child,
- const gchar *property_name,
- GValue *value)
-{
- g_return_if_fail (GTK_IS_GRID (container));
- g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (property_name != NULL && value != NULL);
+ span = row ? attach.height : attach.width;
+ gtk_widget_get_allocation (widget, &allocation);
+ size = row ? allocation.height : allocation.width;
- GWA_GET_CLASS
- (GTK_TYPE_CONTAINER)->child_set_property (adaptor,
- container, child,
- property_name, value);
+ base = row ? attach.top_attach : attach.left_attach;
+ rowcol_size = size / span;
+ trans_point -= (num - base) * rowcol_size;
+
+#if 0
+ g_print ("dir: %s, widget size: %d, rowcol size: %d, "
+ "requested rowcol: %d, widget base rowcol: %d, trim: %d, "
+ "widget point: %d, thresh: %d\n",
+ dir == DIR_UP ? "up" : dir == DIR_DOWN ? "down" :
+ dir == DIR_LEFT ? "left" : "right",
+ size, rowcol_size, num, base, (num - base) * rowcol_size,
+ trans_point,
+ dir == DIR_UP || dir == DIR_LEFT ?
+ (rowcol_size / 2) : (rowcol_size / 2));
+#endif
+ switch (dir)
+ {
+ case DIR_UP:
+ case DIR_LEFT:
+ return trans_point <= (rowcol_size / 2);
+ case DIR_DOWN:
+ case DIR_RIGHT:
+ return trans_point >= (rowcol_size / 2);
+ default:
+ break;
+ }
+ }
- if (strcmp (property_name, "left-attach") == 0 ||
- strcmp (property_name, "top-attach") == 0 ||
- strcmp (property_name, "width") == 0 ||
- strcmp (property_name, "height") == 0)
- {
- /* Refresh placeholders */
- glade_gtk_grid_refresh_placeholders (GTK_GRID (container), FALSE);
}
+
+ g_list_free (children);
+
+ return FALSE;
}
static gboolean
-glade_gtk_grid_verify_attach_common (GObject *object,
- GValue *value,
- const gchar *prop,
- const gchar *parent_prop)
+glade_gtk_grid_get_attachments (GladeFixed *fixed,
+ GtkGrid *grid,
+ GdkRectangle *rect,
+ GladeGridChild *configure)
{
- GladeWidget *widget, *parent;
- guint parent_val;
- gint val, prop_val;
+ GladeWidget *widget = GLADE_WIDGET (fixed);
+ gint center_x, center_y, row, column;
+ guint n_columns, n_rows;
- widget = glade_widget_get_from_gobject (object);
- g_return_val_if_fail (GLADE_IS_WIDGET (widget), TRUE);
- parent = glade_widget_get_parent (widget);
- g_return_val_if_fail (GLADE_IS_WIDGET (parent), TRUE);
+ center_x = rect->x + (rect->width / 2);
+ center_y = rect->y + (rect->height / 2);
- val = g_value_get_int (value);
- glade_widget_property_get (widget, prop, &prop_val);
- glade_widget_property_get (parent, parent_prop, &parent_val);
+ column = glade_gtk_grid_get_row_col_from_point (grid, FALSE, center_x);
+ row = glade_gtk_grid_get_row_col_from_point (grid, TRUE, center_y);
- if (val < 0 || (val+prop_val) > parent_val)
- return FALSE;
+ /* its a start, now try to grow when the rect extents
+ * reach at least half way into the next row/column
+ */
+ configure->left_attach = column;
+ configure->width = 1;
+ configure->top_attach = row;
+ configure->height = 1;
- return TRUE;
-}
+ glade_widget_property_get (widget, "n-columns", &n_columns);
+ glade_widget_property_get (widget, "n-rows", &n_rows);
-gboolean
-glade_gtk_grid_child_verify_property (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GObject *child,
- const gchar *id,
- GValue *value)
-{
- if (!strcmp (id, "left-attach"))
- return glade_gtk_grid_verify_attach_common (child, value, "width", "n-columns");
- else if (!strcmp (id, "width"))
- return glade_gtk_grid_verify_attach_common (child, value, "left-attach", "n-columns");
- else if (!strcmp (id, "top-attach"))
- return glade_gtk_grid_verify_attach_common (child, value, "height", "n-rows");
- else if (!strcmp (id, "height"))
- return glade_gtk_grid_verify_attach_common (child, value, "top-attach", "n-rows");
- else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_verify_property)
- GWA_GET_CLASS
- (GTK_TYPE_CONTAINER)->child_verify_property (adaptor,
- container, child,
- id, value);
-
- return TRUE;
-}
+ if (column >= 0 && row >= 0)
+ {
+ /* Check and expand left
+ */
+ while (configure->left_attach > 0)
+ {
+ if (rect->x < fixed->child_x_origin &&
+ fixed->operation != GLADE_CURSOR_DRAG &&
+ GLADE_FIXED_CURSOR_LEFT (fixed->operation) == FALSE)
+ break;
-static void
-glade_gtk_grid_child_insert_remove_action (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GObject *object,
- const gchar *group_format,
- const gchar *n_row_col,
- const gchar *attach1, /* should be smaller (top/left)
attachment */
- const gchar *attach2, /* should be larger (bot/right)
attachment */
- gboolean remove,
- gboolean after)
-{
- GladeWidget *parent;
- GList *children, *l;
- gint child_pos, size, offset;
+ if (glade_gtk_grid_point_crosses_threshold
+ (grid, FALSE, configure->left_attach - 1,
+ DIR_LEFT, rect->x) == FALSE)
+ break;
- gtk_container_child_get (GTK_CONTAINER (container),
- GTK_WIDGET (object),
- attach1, &child_pos, NULL);
+ configure->left_attach--;
+ configure->width++;
+ }
- parent = glade_widget_get_from_gobject (container);
- glade_command_push_group (group_format, glade_widget_get_name (parent));
+ /* Check and expand right
+ */
+ while (configure->left_attach + configure->width < n_columns)
+ {
+ if (rect->x + rect->width >
+ fixed->child_x_origin + fixed->child_width_origin &&
+ fixed->operation != GLADE_CURSOR_DRAG &&
+ GLADE_FIXED_CURSOR_RIGHT (fixed->operation) == FALSE)
+ break;
- children = glade_widget_adaptor_get_children (adaptor, container);
- /* Make sure widgets does not get destroyed */
- g_list_foreach (children, (GFunc) g_object_ref, NULL);
+ if (glade_gtk_grid_point_crosses_threshold
+ (grid, FALSE, configure->left_attach + configure->width,
+ DIR_RIGHT, rect->x + rect->width) == FALSE)
+ break;
- glade_widget_property_get (parent, n_row_col, &size);
+ configure->width++;
+ }
- if (remove)
- {
- GList *del = NULL;
- /* Remove children first */
- for (l = children; l; l = g_list_next (l))
+ /* Check and expand top
+ */
+ while (configure->top_attach > 0)
{
- GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
- gint pos1, pos2;
+ if (rect->y < fixed->child_y_origin &&
+ fixed->operation != GLADE_CURSOR_DRAG &&
+ GLADE_FIXED_CURSOR_TOP (fixed->operation) == FALSE)
+ break;
- /* Skip placeholders */
- if (gchild == NULL)
- continue;
+ if (glade_gtk_grid_point_crosses_threshold
+ (grid, TRUE, configure->top_attach - 1,
+ DIR_UP, rect->y) == FALSE)
+ break;
- glade_widget_pack_property_get (gchild, attach1, &pos1);
- glade_widget_pack_property_get (gchild, attach2, &pos2);
- pos2 += pos1;
- if ((pos1 + 1 == pos2) && ((after ? pos2 : pos1) == child_pos))
- {
- del = g_list_prepend (del, gchild);
- }
+ configure->top_attach--;
+ configure->height++;
}
- if (del)
+
+ /* Check and expand bottom
+ */
+ while (configure->top_attach + configure->height < n_rows)
{
- glade_command_delete (del);
- g_list_free (del);
+ if (rect->y + rect->height >
+ fixed->child_y_origin + fixed->child_height_origin &&
+ fixed->operation != GLADE_CURSOR_DRAG &&
+ GLADE_FIXED_CURSOR_BOTTOM (fixed->operation) == FALSE)
+ break;
+
+ if (glade_gtk_grid_point_crosses_threshold
+ (grid, TRUE, configure->top_attach + configure->height,
+ DIR_DOWN, rect->y + rect->height) == FALSE)
+ break;
+
+ configure->height++;
}
- offset = -1;
- }
- else
- {
- /* Expand the grid */
- glade_command_set_property (glade_widget_get_property (parent, n_row_col),
- size + 1);
- offset = 1;
}
- /* Reorder children */
- for (l = children; l; l = g_list_next (l))
- {
- GladeWidget *gchild = glade_widget_get_from_gobject (l->data);
- gint pos;
+ return column >= 0 && row >= 0;
+}
- /* Skip placeholders */
- if (gchild == NULL)
- continue;
+static gboolean
+glade_gtk_grid_configure_child (GladeFixed *fixed,
+ GladeWidget *child,
+ GdkRectangle *rect,
+ GtkWidget *grid)
+{
+ GladeGridChild configure = { child, };
- /* if removing, do top/left before bot/right */
- if (remove)
- {
- /* adjust top-left attachment */
- glade_widget_pack_property_get (gchild, attach1, &pos);
- if (pos > child_pos || (after && pos == child_pos))
- {
- glade_command_set_property (glade_widget_get_pack_property
- (gchild, attach1), pos + offset);
- }
- }
- /* if inserting, do bot/right before top/left */
- else
+ /* Sometimes we are unable to find a widget in the appropriate column,
+ * usually because a placeholder hasnt had its size allocation yet.
+ */
+ if (glade_gtk_grid_get_attachments (fixed, GTK_GRID (grid), rect, &configure))
+ {
+ if (memcmp (&configure, &grid_cur_attach, sizeof (GladeGridChild)) != 0)
{
- /* adjust top-left attachment */
- glade_widget_pack_property_get (gchild, attach1, &pos);
- if ((after && pos > child_pos) || (!after && pos >= child_pos))
- {
- glade_command_set_property (glade_widget_get_pack_property
- (gchild, attach1), pos + offset);
- }
+ glade_property_push_superuser ();
+ glade_widget_pack_property_set (child, "left-attach",
+ configure.left_attach);
+ glade_widget_pack_property_set (child, "width",
+ configure.width);
+ glade_widget_pack_property_set (child, "top-attach",
+ configure.top_attach);
+ glade_widget_pack_property_set (child, "height",
+ configure.height);
+ glade_property_pop_superuser ();
+
+ memcpy (&grid_cur_attach, &configure, sizeof (GladeGridChild));
}
}
+ return TRUE;
+}
- if (remove)
- {
- /* Shrink the grid */
- glade_command_set_property (glade_widget_get_property (parent, n_row_col),
- size - 1);
- }
+static gboolean
+glade_gtk_grid_configure_begin (GladeFixed *fixed,
+ GladeWidget *child,
+ GtkWidget *grid)
+{
+ grid_edit.widget = child;
- g_list_foreach (children, (GFunc) g_object_unref, NULL);
- g_list_free (children);
+ glade_widget_pack_property_get (child, "left-attach", &grid_edit.left_attach);
+ glade_widget_pack_property_get (child, "width", &grid_edit.width);
+ glade_widget_pack_property_get (child, "top-attach", &grid_edit.top_attach);
+ glade_widget_pack_property_get (child, "height", &grid_edit.height);
- glade_command_pop_group ();
+ memcpy (&grid_cur_attach, &grid_edit, sizeof (GladeGridChild));
+
+ return TRUE;
}
-void
-glade_gtk_grid_child_action_activate (GladeWidgetAdaptor *adaptor,
- GObject *container,
- GObject *object,
- const gchar *action_path)
+static gboolean
+glade_gtk_grid_configure_end (GladeFixed *fixed,
+ GladeWidget *child,
+ GtkWidget *grid)
{
- if (strcmp (action_path, "insert_row/after") == 0)
- {
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Insert Row on %s"),
- "n-rows", "top-attach",
- "height", FALSE, TRUE);
- }
- else if (strcmp (action_path, "insert_row/before") == 0)
- {
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Insert Row on %s"),
- "n-rows", "top-attach",
- "height",
- FALSE, FALSE);
- }
- else if (strcmp (action_path, "insert_column/after") == 0)
- {
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Insert Column on %s"),
- "n-columns", "left-attach",
- "width", FALSE, TRUE);
- }
- else if (strcmp (action_path, "insert_column/before") == 0)
- {
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Insert Column on %s"),
- "n-columns", "left-attach",
- "width", FALSE, FALSE);
- }
- else if (strcmp (action_path, "remove_column") == 0)
- {
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Remove Column on %s"),
- "n-columns", "left-attach",
- "width", TRUE, FALSE);
- }
- else if (strcmp (action_path, "remove_row") == 0)
+ GladeGridChild new_child = { child, };
+
+ glade_widget_pack_property_get (child, "left-attach", &new_child.left_attach);
+ glade_widget_pack_property_get (child, "width", &new_child.width);
+ glade_widget_pack_property_get (child, "top-attach", &new_child.top_attach);
+ glade_widget_pack_property_get (child, "height", &new_child.height);
+
+ /* Compare the meaningfull part of the current edit. */
+ if (memcmp (&new_child, &grid_edit, sizeof (GladeGridChild)) != 0)
{
- glade_gtk_grid_child_insert_remove_action (adaptor, container, object,
- _("Remove Row on %s"),
- "n-rows", "top-attach",
- "height", TRUE, FALSE);
+ GValue left_attach_value = { 0, };
+ GValue width_attach_value = { 0, };
+ GValue top_attach_value = { 0, };
+ GValue height_attach_value = { 0, };
+
+ GValue new_left_attach_value = { 0, };
+ GValue new_width_attach_value = { 0, };
+ GValue new_top_attach_value = { 0, };
+ GValue new_height_attach_value = { 0, };
+
+ GladeProperty *left_attach_prop, *width_attach_prop,
+ *top_attach_prop, *height_attach_prop;
+
+ left_attach_prop = glade_widget_get_pack_property (child, "left-attach");
+ width_attach_prop = glade_widget_get_pack_property (child, "width");
+ top_attach_prop = glade_widget_get_pack_property (child, "top-attach");
+ height_attach_prop = glade_widget_get_pack_property (child, "height");
+
+ g_return_val_if_fail (GLADE_IS_PROPERTY (left_attach_prop), FALSE);
+ g_return_val_if_fail (GLADE_IS_PROPERTY (width_attach_prop), FALSE);
+ g_return_val_if_fail (GLADE_IS_PROPERTY (top_attach_prop), FALSE);
+ g_return_val_if_fail (GLADE_IS_PROPERTY (height_attach_prop), FALSE);
+
+ glade_property_get_value (left_attach_prop, &new_left_attach_value);
+ glade_property_get_value (width_attach_prop, &new_width_attach_value);
+ glade_property_get_value (top_attach_prop, &new_top_attach_value);
+ glade_property_get_value (height_attach_prop, &new_height_attach_value);
+
+ g_value_init (&left_attach_value, G_TYPE_INT);
+ g_value_init (&width_attach_value, G_TYPE_INT);
+ g_value_init (&top_attach_value, G_TYPE_INT);
+ g_value_init (&height_attach_value, G_TYPE_INT);
+
+ g_value_set_int (&left_attach_value, grid_edit.left_attach);
+ g_value_set_int (&width_attach_value, grid_edit.width);
+ g_value_set_int (&top_attach_value, grid_edit.top_attach);
+ g_value_set_int (&height_attach_value, grid_edit.height);
+
+ glade_command_push_group (_("Placing %s inside %s"),
+ glade_widget_get_name (child),
+ glade_widget_get_name (GLADE_WIDGET (fixed)));
+ glade_command_set_properties
+ (left_attach_prop, &left_attach_value, &new_left_attach_value,
+ width_attach_prop, &width_attach_value, &new_width_attach_value,
+ top_attach_prop, &top_attach_value, &new_top_attach_value,
+ height_attach_prop, &height_attach_value, &new_height_attach_value,
+ NULL);
+ glade_command_pop_group ();
+
+ g_value_unset (&left_attach_value);
+ g_value_unset (&width_attach_value);
+ g_value_unset (&top_attach_value);
+ g_value_unset (&height_attach_value);
+ g_value_unset (&new_left_attach_value);
+ g_value_unset (&new_width_attach_value);
+ g_value_unset (&new_top_attach_value);
+ g_value_unset (&new_height_attach_value);
}
- else
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
- container,
- object,
- action_path);
+
+ return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]