[glade] Refactor: Move GtkBox adaptor into it's own separate file.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade] Refactor: Move GtkBox adaptor into it's own separate file.
- Date: Wed, 3 Apr 2013 09:11:04 +0000 (UTC)
commit c4c646fda47cced361dccb7c7565c5cb489c9530
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Wed Apr 3 16:27:22 2013 +0900
Refactor: Move GtkBox adaptor into it's own separate file.
plugins/gtk+/Makefile.am | 1 +
plugins/gtk+/glade-gtk-box.c | 751 ++++++++++++++++++++++++++++++++++++++++++
plugins/gtk+/glade-gtk.c | 715 +---------------------------------------
plugins/gtk+/glade-gtk.h | 15 +-
4 files changed, 769 insertions(+), 713 deletions(-)
---
diff --git a/plugins/gtk+/Makefile.am b/plugins/gtk+/Makefile.am
index 19364b1..92e55cd 100644
--- a/plugins/gtk+/Makefile.am
+++ b/plugins/gtk+/Makefile.am
@@ -44,6 +44,7 @@ libgladegtk_la_SOURCES = \
glade-string-list.c \
glade-gtk-table.c \
glade-gtk-grid.c \
+ glade-gtk-box.c \
glade-gtk-action-widgets.c \
glade-gtk-info-bar.c \
glade-gtk-activatable.c \
diff --git a/plugins/gtk+/glade-gtk-box.c b/plugins/gtk+/glade-gtk-box.c
new file mode 100644
index 0000000..a30fa9f
--- /dev/null
+++ b/plugins/gtk+/glade-gtk-box.c
@@ -0,0 +1,751 @@
+/*
+ * glade-gtk-box.c - GladeWidgetAdaptor for GtkGrid widget
+ *
+ * Copyright (C) 2013 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 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 program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "glade-fixed.h"
+#include "glade-gtk.h"
+
+
+static gboolean glade_gtk_box_configure_child (GladeFixed * fixed,
+ GladeWidget * child,
+ GdkRectangle * rect,
+ GtkWidget * box);
+
+static gboolean glade_gtk_box_configure_begin (GladeFixed * fixed,
+ GladeWidget * child,
+ GtkWidget * box);
+
+
+static gboolean glade_gtk_box_configure_end (GladeFixed * fixed,
+ GladeWidget * child,
+ GtkWidget * box);
+
+
+
+void
+glade_gtk_box_post_create (GladeWidgetAdaptor * adaptor,
+ GObject * container, GladeCreateReason reason)
+{
+ GladeWidget *gwidget = glade_widget_get_from_gobject (container);
+
+ /* Implement drag in GtkBox but not resize.
+ */
+ g_object_set (gwidget, "can-resize", FALSE, NULL);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-child",
+ G_CALLBACK (glade_gtk_box_configure_child), container);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-begin",
+ G_CALLBACK (glade_gtk_box_configure_begin), container);
+
+ g_signal_connect (G_OBJECT (gwidget), "configure-end",
+ G_CALLBACK (glade_gtk_box_configure_end), container);
+
+}
+
+static gint
+sort_box_children (GtkWidget * widget_a, GtkWidget * widget_b)
+{
+ GtkWidget *box;
+ GladeWidget *gwidget_a, *gwidget_b;
+ gint position_a, position_b;
+
+ gwidget_a = glade_widget_get_from_gobject (widget_a);
+ gwidget_b = glade_widget_get_from_gobject (widget_b);
+
+ box = gtk_widget_get_parent (widget_a);
+
+ /* XXX Sometimes the packing "position" property doesnt exist here, why ?
+ */
+
+ if (gwidget_a)
+ glade_widget_pack_property_get (gwidget_a, "position", &position_a);
+ else
+ gtk_container_child_get (GTK_CONTAINER (box),
+ widget_a, "position", &position_a, NULL);
+
+ if (gwidget_b)
+ glade_widget_pack_property_get (gwidget_b, "position", &position_b);
+ else
+ gtk_container_child_get (GTK_CONTAINER (box),
+ widget_b, "position", &position_b, NULL);
+ return position_a - position_b;
+}
+
+GList *
+glade_gtk_box_get_children (GladeWidgetAdaptor * adaptor,
+ GtkContainer * container)
+{
+ GList *children = glade_util_container_get_all_children (container);
+
+ return g_list_sort (children, (GCompareFunc) sort_box_children);
+}
+
+void
+glade_gtk_box_set_child_property (GladeWidgetAdaptor * adaptor,
+ GObject * container,
+ GObject * child,
+ const gchar * property_name, GValue * value)
+{
+ GladeWidget *gbox, *gchild, *gchild_iter;
+ GList *children, *list;
+ gboolean is_position;
+ gint old_position, iter_position, new_position;
+ static gboolean recursion = FALSE;
+
+ g_return_if_fail (GTK_IS_BOX (container));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (property_name != NULL || value != NULL);
+
+ gbox = glade_widget_get_from_gobject (container);
+ gchild = glade_widget_get_from_gobject (child);
+
+ g_return_if_fail (GLADE_IS_WIDGET (gbox));
+
+ if (gtk_widget_get_parent (GTK_WIDGET (child)) != GTK_WIDGET (container))
+ return;
+
+ /* Get old position */
+ if ((is_position = (strcmp (property_name, "position") == 0)) != FALSE)
+ {
+ gtk_container_child_get (GTK_CONTAINER (container),
+ GTK_WIDGET (child),
+ property_name, &old_position, NULL);
+
+
+ /* Get the real value */
+ new_position = g_value_get_int (value);
+ }
+
+ if (is_position && recursion == FALSE)
+ {
+ children = glade_widget_get_children (gbox);
+ children = g_list_sort (children, (GCompareFunc) sort_box_children);
+
+ for (list = children; list; list = list->next)
+ {
+ gchild_iter = glade_widget_get_from_gobject (list->data);
+
+ if (gchild_iter == gchild)
+ {
+ gtk_box_reorder_child (GTK_BOX (container),
+ GTK_WIDGET (child), new_position);
+ continue;
+ }
+
+ /* Get the old value from glade */
+ glade_widget_pack_property_get
+ (gchild_iter, "position", &iter_position);
+
+ /* Search for the child at the old position and update it */
+ if (iter_position == new_position &&
+ glade_property_superuser () == FALSE)
+ {
+ /* Update glade with the real value */
+ recursion = TRUE;
+ glade_widget_pack_property_set
+ (gchild_iter, "position", old_position);
+ recursion = FALSE;
+ continue;
+ }
+ else
+ {
+ gtk_box_reorder_child (GTK_BOX (container),
+ GTK_WIDGET (list->data), iter_position);
+ }
+ }
+
+ for (list = children; list; list = list->next)
+ {
+ gchild_iter = glade_widget_get_from_gobject (list->data);
+
+ /* Refresh values yet again */
+ glade_widget_pack_property_get
+ (gchild_iter, "position", &iter_position);
+
+ gtk_box_reorder_child (GTK_BOX (container),
+ GTK_WIDGET (list->data), iter_position);
+
+ }
+
+ if (children)
+ g_list_free (children);
+ }
+
+ /* Chain Up */
+ if (!is_position)
+ GWA_GET_CLASS
+ (GTK_TYPE_CONTAINER)->child_set_property (adaptor,
+ container,
+ child, property_name, value);
+
+ gtk_container_check_resize (GTK_CONTAINER (container));
+
+}
+
+void
+glade_gtk_box_get_property (GladeWidgetAdaptor * adaptor,
+ GObject * object, const gchar * id, GValue * value)
+{
+ if (!strcmp (id, "size"))
+ {
+ GtkBox *box = GTK_BOX (object);
+ GList *children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ g_value_reset (value);
+ g_value_set_int (value, g_list_length (children));
+ g_list_free (children);
+ }
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->get_property (adaptor, object, id,
+ value);
+}
+
+static gint
+glade_gtk_box_get_first_blank (GtkBox * box)
+{
+ GList *child, *children;
+ GladeWidget *gwidget;
+ gint position;
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ for (child = children, position = 0;
+ child && child->data; child = child->next, position++)
+ {
+ GtkWidget *widget = child->data;
+
+ if ((gwidget = glade_widget_get_from_gobject (widget)) != NULL)
+ {
+ gint gwidget_position = 0;
+ GladeProperty *property =
+ glade_widget_get_pack_property (gwidget, "position");
+
+ /* property can be NULL here when project is closing */
+ if (property)
+ gwidget_position = g_value_get_int (glade_property_inline_value (property));
+
+ if (gwidget_position > position)
+ break;
+ }
+ }
+
+ g_list_free (children);
+
+ return position;
+}
+
+static void
+glade_gtk_box_set_size (GObject * object, const GValue * value)
+{
+ GtkBox *box;
+ GList *child, *children;
+ guint new_size, old_size, i;
+
+ box = GTK_BOX (object);
+ g_return_if_fail (GTK_IS_BOX (box));
+
+ if (glade_util_object_is_loading (object))
+ return;
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ old_size = g_list_length (children);
+ new_size = g_value_get_int (value);
+
+ if (old_size == new_size)
+ {
+ g_list_free (children);
+ return;
+ }
+
+ /* Ensure placeholders first...
+ */
+ for (i = 0; i < new_size; i++)
+ {
+ if (g_list_length (children) < (i + 1))
+ {
+ GtkWidget *placeholder = glade_placeholder_new ();
+ gint blank = glade_gtk_box_get_first_blank (box);
+
+ gtk_container_add (GTK_CONTAINER (box), placeholder);
+ gtk_box_reorder_child (box, placeholder, blank);
+ }
+ }
+
+ /* The box has shrunk. Remove the widgets that are on those slots */
+ for (child = g_list_last (children);
+ child && old_size > new_size; child = g_list_previous (child))
+ {
+ GtkWidget *child_widget = child->data;
+
+ /* Refuse to remove any widgets that are either GladeWidget objects
+ * or internal to the hierarchic entity (may be a composite widget,
+ * not all internal widgets have GladeWidgets).
+ */
+ if (glade_widget_get_from_gobject (child_widget) ||
+ GLADE_IS_PLACEHOLDER (child_widget) == FALSE)
+ continue;
+
+ g_object_ref (G_OBJECT (child_widget));
+ gtk_container_remove (GTK_CONTAINER (box), child_widget);
+ gtk_widget_destroy (child_widget);
+ old_size--;
+ }
+ g_list_free (children);
+
+}
+
+void
+glade_gtk_box_set_property (GladeWidgetAdaptor * adaptor,
+ GObject * object,
+ const gchar * id, const GValue * value)
+{
+ if (!strcmp (id, "size"))
+ glade_gtk_box_set_size (object, value);
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object, id,
+ value);
+}
+
+static gboolean
+glade_gtk_box_verify_size (GObject *object, const GValue *value)
+{
+ GList *child, *children;
+ gint old_size, count = 0;
+ gint new_size = g_value_get_int (value);
+
+ children = gtk_container_get_children (GTK_CONTAINER (object));
+ old_size = g_list_length (children);
+
+ for (child = g_list_last (children);
+ child && old_size > new_size;
+ child = g_list_previous (child))
+ {
+ GtkWidget *widget = child->data;
+ if (glade_widget_get_from_gobject (widget) != NULL)
+ count++;
+ else
+ old_size--;
+ }
+
+ g_list_free (children);
+
+ return count > new_size ? FALSE : new_size >= 0;
+}
+
+
+gboolean
+glade_gtk_box_verify_property (GladeWidgetAdaptor * adaptor,
+ GObject * object,
+ const gchar * id, const GValue * value)
+{
+ if (!strcmp (id, "size"))
+ return glade_gtk_box_verify_size (object, value);
+ else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
+ return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
+ id, value);
+
+ return TRUE;
+}
+
+
+static void
+fix_response_id_on_child (GladeWidget * gbox, GObject * child, gboolean add)
+{
+ GladeWidget *gchild;
+ const gchar *internal_name;
+
+ gchild = glade_widget_get_from_gobject (child);
+
+ /* Fix response id property on child buttons */
+ if (gchild && GTK_IS_BUTTON (child))
+ {
+ if (add && (internal_name = glade_widget_get_internal (gbox)) &&
+ !strcmp (internal_name, "action_area"))
+ glade_widget_property_set_sensitive (gchild, "response-id", TRUE,
+ NULL);
+ else
+ glade_widget_property_set_sensitive (gchild, "response-id", FALSE,
+ RESPID_INSENSITIVE_MSG);
+ }
+}
+
+void
+glade_gtk_box_add_child (GladeWidgetAdaptor * adaptor,
+ GObject * object, GObject * child)
+{
+ GladeWidget *gbox, *gchild;
+ GList *children;
+ gint num_children;
+
+ g_return_if_fail (GTK_IS_BOX (object));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ gbox = glade_widget_get_from_gobject (object);
+
+ /*
+ Try to remove the last placeholder if any, this way GtkBox`s size
+ will not be changed.
+ */
+ if (glade_widget_superuser () == FALSE && !GLADE_IS_PLACEHOLDER (child))
+ {
+ GList *l, *children;
+ GtkBox *box = GTK_BOX (object);
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ for (l = g_list_last (children); l; l = g_list_previous (l))
+ {
+ GtkWidget *child_widget = l->data;
+ if (GLADE_IS_PLACEHOLDER (child_widget))
+ {
+ gtk_container_remove (GTK_CONTAINER (box), child_widget);
+ break;
+ }
+ }
+ g_list_free (children);
+ }
+
+ gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
+
+ children = gtk_container_get_children (GTK_CONTAINER (object));
+ num_children = g_list_length (children);
+ g_list_free (children);
+
+ glade_widget_property_set (gbox, "size", num_children);
+
+ gchild = glade_widget_get_from_gobject (child);
+
+ /* The "Remove Slot" operation only makes sence on placeholders,
+ * otherwise its a "Delete" operation on the child widget.
+ */
+ if (gchild)
+ glade_widget_set_pack_action_visible (gchild, "remove_slot", FALSE);
+
+ /* Packing props arent around when parenting during a glade_widget_dup() */
+ if (gchild && glade_widget_get_packing_properties (gchild))
+ glade_widget_pack_property_set (gchild, "position", num_children - 1);
+
+ fix_response_id_on_child (gbox, child, TRUE);
+}
+
+void
+glade_gtk_box_remove_child (GladeWidgetAdaptor * adaptor,
+ GObject * object, GObject * child)
+{
+ GladeWidget *gbox;
+ gint size;
+
+ g_return_if_fail (GTK_IS_BOX (object));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+
+ gbox = glade_widget_get_from_gobject (object);
+
+ gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
+
+ if (glade_widget_superuser () == FALSE)
+ {
+ glade_widget_property_get (gbox, "size", &size);
+ glade_widget_property_set (gbox, "size", size);
+ }
+
+ fix_response_id_on_child (gbox, child, FALSE);
+}
+
+
+void
+glade_gtk_box_replace_child (GladeWidgetAdaptor * adaptor,
+ GObject * container,
+ GObject * current, GObject * new_widget)
+{
+ GladeWidget *gchild;
+ GladeWidget *gbox;
+
+ g_object_ref (G_OBJECT (current));
+
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->replace_child (adaptor,
+ container,
+ current, new_widget);
+ gbox = glade_widget_get_from_gobject (container);
+
+ if ((gchild = glade_widget_get_from_gobject (new_widget)) != NULL)
+ /* The "Remove Slot" operation only makes sence on placeholders,
+ * otherwise its a "Delete" operation on the child widget.
+ */
+ glade_widget_set_pack_action_visible (gchild, "remove_slot", FALSE);
+
+ fix_response_id_on_child (gbox, current, FALSE);
+ fix_response_id_on_child (gbox, new_widget, TRUE);
+
+ g_object_unref (G_OBJECT (current));
+}
+
+void
+glade_gtk_box_child_action_activate (GladeWidgetAdaptor * adaptor,
+ GObject * container,
+ GObject * object,
+ const gchar * action_path)
+{
+ if (strcmp (action_path, "insert_after") == 0)
+ {
+ glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
+ object, "size",
+ _
+ ("Insert placeholder to %s"),
+ FALSE, TRUE);
+ }
+ else if (strcmp (action_path, "insert_before") == 0)
+ {
+ glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
+ object, "size",
+ _
+ ("Insert placeholder to %s"),
+ FALSE, FALSE);
+ }
+ else if (strcmp (action_path, "remove_slot") == 0)
+ {
+ glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
+ object, "size",
+ _
+ ("Remove placeholder from %s"),
+ TRUE, FALSE);
+ }
+ else
+ GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
+ container,
+ object,
+ action_path);
+}
+
+
+/**********************************************************
+ * GladeFixed drag implementation *
+ **********************************************************/
+typedef struct
+{
+ GtkWidget *widget;
+ gint position;
+} GladeGtkBoxChild;
+
+static GList *glade_gtk_box_original_positions = NULL;
+
+static gboolean
+glade_gtk_box_configure_child (GladeFixed * fixed,
+ GladeWidget * child,
+ GdkRectangle * rect, GtkWidget * box)
+{
+ GList *list, *children;
+ GtkWidget *bchild;
+ GtkAllocation allocation, bchild_allocation;
+ gint point, trans_point, span,
+ iter_span, position, old_position, offset, orig_offset;
+ gboolean found = FALSE;
+
+ gtk_widget_get_allocation (GTK_WIDGET (glade_widget_get_object (child)), &allocation);
+
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (box)) == GTK_ORIENTATION_HORIZONTAL)
+ {
+ point = fixed->mouse_x;
+ span = allocation.width;
+ offset = rect->x;
+ orig_offset = fixed->child_x_origin;
+ }
+ else
+ {
+ point = fixed->mouse_y;
+ span = allocation.height;
+ offset = rect->y;
+ orig_offset = fixed->child_y_origin;
+ }
+
+ glade_widget_pack_property_get (child, "position", &old_position);
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ for (list = children; list; list = list->next)
+ {
+ bchild = list->data;
+
+ if (bchild == GTK_WIDGET (glade_widget_get_object (child)))
+ continue;
+
+ /* Find the widget in the box where the center of
+ * this rectangle fits... and set the position to that
+ * position.
+ */
+
+ gtk_widget_get_allocation (GTK_WIDGET (bchild), &bchild_allocation);
+ if (gtk_orientable_get_orientation (GTK_ORIENTABLE (box)) == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gtk_widget_translate_coordinates
+ (GTK_WIDGET (box), bchild, point, 0, &trans_point, NULL);
+
+ iter_span = bchild_allocation.width;
+ }
+ else
+ {
+ gtk_widget_translate_coordinates
+ (GTK_WIDGET (box), bchild, 0, point, NULL, &trans_point);
+ iter_span = bchild_allocation.height;
+ }
+
+#if 0
+ gtk_container_child_get (GTK_CONTAINER (box),
+ bchild, "position", &position, NULL);
+ g_print ("widget: %p pos %d, point %d, trans_point %d, iter_span %d\n",
+ bchild, position, point, trans_point, iter_span);
+#endif
+
+ if (iter_span <= span)
+ {
+ found = trans_point >= 0 && trans_point < iter_span;
+ }
+ else
+ {
+ if (offset > orig_offset)
+ found = trans_point >= iter_span - span && trans_point < iter_span;
+ else if (offset < orig_offset)
+ found = trans_point >= 0 && trans_point < span;
+ }
+
+ if (found)
+ {
+ gtk_container_child_get (GTK_CONTAINER (box),
+ bchild, "position", &position, NULL);
+
+#if 0
+ g_print ("setting position of %s from %d to %d, "
+ "(point %d iter_span %d)\n",
+ glade_widget_get_name (child), old_position, position, trans_point, iter_span);
+#endif
+
+ glade_widget_pack_property_set (child, "position", position);
+
+ break;
+ }
+
+ }
+
+ g_list_free (children);
+
+ return TRUE;
+}
+
+static gboolean
+glade_gtk_box_configure_begin (GladeFixed * fixed,
+ GladeWidget * child, GtkWidget * box)
+{
+ GList *list, *children;
+ GtkWidget *bchild;
+
+ g_assert (glade_gtk_box_original_positions == NULL);
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ for (list = children; list; list = list->next)
+ {
+ GladeGtkBoxChild *gbchild;
+ GladeWidget *gchild;
+
+ bchild = list->data;
+ if ((gchild = glade_widget_get_from_gobject (bchild)) == NULL)
+ continue;
+
+ gbchild = g_new0 (GladeGtkBoxChild, 1);
+ gbchild->widget = bchild;
+ glade_widget_pack_property_get (gchild, "position", &gbchild->position);
+
+ glade_gtk_box_original_positions =
+ g_list_prepend (glade_gtk_box_original_positions, gbchild);
+ }
+
+ g_list_free (children);
+
+ return TRUE;
+}
+
+static gboolean
+glade_gtk_box_configure_end (GladeFixed * fixed,
+ GladeWidget * child, GtkWidget * box)
+{
+ GList *list, *l, *children;
+ GList *prop_list = NULL;
+
+ children = gtk_container_get_children (GTK_CONTAINER (box));
+
+ for (list = children; list; list = list->next)
+ {
+ GtkWidget *bchild = list->data;
+
+ for (l = glade_gtk_box_original_positions; l; l = l->next)
+ {
+ GladeGtkBoxChild *gbchild = l->data;
+ GladeWidget *gchild = glade_widget_get_from_gobject (gbchild->widget);
+
+
+ if (bchild == gbchild->widget)
+ {
+ GCSetPropData *prop_data = g_new0 (GCSetPropData, 1);
+ prop_data->property =
+ glade_widget_get_pack_property (gchild, "position");
+
+ prop_data->old_value = g_new0 (GValue, 1);
+ prop_data->new_value = g_new0 (GValue, 1);
+
+ glade_property_get_value (prop_data->property,
+ prop_data->new_value);
+
+ g_value_init (prop_data->old_value, G_TYPE_INT);
+ g_value_set_int (prop_data->old_value, gbchild->position);
+
+ prop_list = g_list_prepend (prop_list, prop_data);
+ break;
+ }
+ }
+ }
+
+ g_list_free (children);
+
+ glade_command_push_group (_("Ordering children of %s"),
+ glade_widget_get_name (GLADE_WIDGET (fixed)));
+ glade_property_push_superuser ();
+ if (prop_list)
+ glade_command_set_properties_list (glade_widget_get_project (GLADE_WIDGET (fixed)),
+ prop_list);
+ glade_property_pop_superuser ();
+ glade_command_pop_group ();
+
+ for (l = glade_gtk_box_original_positions; l; l = l->next)
+ g_free (l->data);
+
+ glade_gtk_box_original_positions =
+ (g_list_free (glade_gtk_box_original_positions), NULL);
+
+
+ return TRUE;
+}
diff --git a/plugins/gtk+/glade-gtk.c b/plugins/gtk+/glade-gtk.c
index 5c86399..28e0a62 100644
--- a/plugins/gtk+/glade-gtk.c
+++ b/plugins/gtk+/glade-gtk.c
@@ -1349,8 +1349,7 @@ glade_gtk_container_create_editable (GladeWidgetAdaptor * adaptor,
return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->create_editable (adaptor, type);
}
-/* ----------------------------- GtkBox ------------------------------ */
-
+/* ----------------- Generic GladeFixed constructor ------------------ */
GladeWidget *
glade_gtk_create_fixed_widget (GladeWidgetAdaptor * adaptor,
const gchar * first_property_name,
@@ -1360,715 +1359,6 @@ glade_gtk_create_fixed_widget (GladeWidgetAdaptor * adaptor,
first_property_name, var_args);
}
-typedef struct
-{
- GtkWidget *widget;
- gint position;
-} GladeGtkBoxChild;
-
-static GList *glade_gtk_box_original_positions = NULL;
-
-static gboolean
-glade_gtk_box_configure_child (GladeFixed * fixed,
- GladeWidget * child,
- GdkRectangle * rect, GtkWidget * box)
-{
- GList *list, *children;
- GtkWidget *bchild;
- GtkAllocation allocation, bchild_allocation;
- gint point, trans_point, span,
- iter_span, position, old_position, offset, orig_offset;
- gboolean found = FALSE;
-
- gtk_widget_get_allocation (GTK_WIDGET (glade_widget_get_object (child)), &allocation);
-
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (box)) == GTK_ORIENTATION_HORIZONTAL)
- {
- point = fixed->mouse_x;
- span = allocation.width;
- offset = rect->x;
- orig_offset = fixed->child_x_origin;
- }
- else
- {
- point = fixed->mouse_y;
- span = allocation.height;
- offset = rect->y;
- orig_offset = fixed->child_y_origin;
- }
-
- glade_widget_pack_property_get (child, "position", &old_position);
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- for (list = children; list; list = list->next)
- {
- bchild = list->data;
-
- if (bchild == GTK_WIDGET (glade_widget_get_object (child)))
- continue;
-
- /* Find the widget in the box where the center of
- * this rectangle fits... and set the position to that
- * position.
- */
-
- gtk_widget_get_allocation (GTK_WIDGET (bchild), &bchild_allocation);
- if (gtk_orientable_get_orientation (GTK_ORIENTABLE (box)) == GTK_ORIENTATION_HORIZONTAL)
- {
- gtk_widget_translate_coordinates
- (GTK_WIDGET (box), bchild, point, 0, &trans_point, NULL);
-
- iter_span = bchild_allocation.width;
- }
- else
- {
- gtk_widget_translate_coordinates
- (GTK_WIDGET (box), bchild, 0, point, NULL, &trans_point);
- iter_span = bchild_allocation.height;
- }
-
-#if 0
- gtk_container_child_get (GTK_CONTAINER (box),
- bchild, "position", &position, NULL);
- g_print ("widget: %p pos %d, point %d, trans_point %d, iter_span %d\n",
- bchild, position, point, trans_point, iter_span);
-#endif
-
- if (iter_span <= span)
- {
- found = trans_point >= 0 && trans_point < iter_span;
- }
- else
- {
- if (offset > orig_offset)
- found = trans_point >= iter_span - span && trans_point < iter_span;
- else if (offset < orig_offset)
- found = trans_point >= 0 && trans_point < span;
- }
-
- if (found)
- {
- gtk_container_child_get (GTK_CONTAINER (box),
- bchild, "position", &position, NULL);
-
-#if 0
- g_print ("setting position of %s from %d to %d, "
- "(point %d iter_span %d)\n",
- glade_widget_get_name (child), old_position, position, trans_point, iter_span);
-#endif
-
- glade_widget_pack_property_set (child, "position", position);
-
- break;
- }
-
- }
-
- g_list_free (children);
-
- return TRUE;
-}
-
-static gboolean
-glade_gtk_box_configure_begin (GladeFixed * fixed,
- GladeWidget * child, GtkWidget * box)
-{
- GList *list, *children;
- GtkWidget *bchild;
-
- g_assert (glade_gtk_box_original_positions == NULL);
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- for (list = children; list; list = list->next)
- {
- GladeGtkBoxChild *gbchild;
- GladeWidget *gchild;
-
- bchild = list->data;
- if ((gchild = glade_widget_get_from_gobject (bchild)) == NULL)
- continue;
-
- gbchild = g_new0 (GladeGtkBoxChild, 1);
- gbchild->widget = bchild;
- glade_widget_pack_property_get (gchild, "position", &gbchild->position);
-
- glade_gtk_box_original_positions =
- g_list_prepend (glade_gtk_box_original_positions, gbchild);
- }
-
- g_list_free (children);
-
- return TRUE;
-}
-
-static gboolean
-glade_gtk_box_configure_end (GladeFixed * fixed,
- GladeWidget * child, GtkWidget * box)
-{
- GList *list, *l, *children;
- GList *prop_list = NULL;
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- for (list = children; list; list = list->next)
- {
- GtkWidget *bchild = list->data;
-
- for (l = glade_gtk_box_original_positions; l; l = l->next)
- {
- GladeGtkBoxChild *gbchild = l->data;
- GladeWidget *gchild = glade_widget_get_from_gobject (gbchild->widget);
-
-
- if (bchild == gbchild->widget)
- {
- GCSetPropData *prop_data = g_new0 (GCSetPropData, 1);
- prop_data->property =
- glade_widget_get_pack_property (gchild, "position");
-
- prop_data->old_value = g_new0 (GValue, 1);
- prop_data->new_value = g_new0 (GValue, 1);
-
- glade_property_get_value (prop_data->property,
- prop_data->new_value);
-
- g_value_init (prop_data->old_value, G_TYPE_INT);
- g_value_set_int (prop_data->old_value, gbchild->position);
-
- prop_list = g_list_prepend (prop_list, prop_data);
- break;
- }
- }
- }
-
- g_list_free (children);
-
- glade_command_push_group (_("Ordering children of %s"),
- glade_widget_get_name (GLADE_WIDGET (fixed)));
- glade_property_push_superuser ();
- if (prop_list)
- glade_command_set_properties_list (glade_widget_get_project (GLADE_WIDGET (fixed)),
- prop_list);
- glade_property_pop_superuser ();
- glade_command_pop_group ();
-
- for (l = glade_gtk_box_original_positions; l; l = l->next)
- g_free (l->data);
-
- glade_gtk_box_original_positions =
- (g_list_free (glade_gtk_box_original_positions), NULL);
-
-
- return TRUE;
-}
-
-void
-glade_gtk_box_post_create (GladeWidgetAdaptor * adaptor,
- GObject * container, GladeCreateReason reason)
-{
- GladeWidget *gwidget = glade_widget_get_from_gobject (container);
-
- /* Implement drag in GtkBox but not resize.
- */
- g_object_set (gwidget, "can-resize", FALSE, NULL);
-
- g_signal_connect (G_OBJECT (gwidget), "configure-child",
- G_CALLBACK (glade_gtk_box_configure_child), container);
-
- g_signal_connect (G_OBJECT (gwidget), "configure-begin",
- G_CALLBACK (glade_gtk_box_configure_begin), container);
-
- g_signal_connect (G_OBJECT (gwidget), "configure-end",
- G_CALLBACK (glade_gtk_box_configure_end), container);
-
-}
-
-static gint
-sort_box_children (GtkWidget * widget_a, GtkWidget * widget_b)
-{
- GtkWidget *box;
- GladeWidget *gwidget_a, *gwidget_b;
- gint position_a, position_b;
-
- gwidget_a = glade_widget_get_from_gobject (widget_a);
- gwidget_b = glade_widget_get_from_gobject (widget_b);
-
- box = gtk_widget_get_parent (widget_a);
-
- /* XXX Sometimes the packing "position" property doesnt exist here, why ?
- */
-
- if (gwidget_a)
- glade_widget_pack_property_get (gwidget_a, "position", &position_a);
- else
- gtk_container_child_get (GTK_CONTAINER (box),
- widget_a, "position", &position_a, NULL);
-
- if (gwidget_b)
- glade_widget_pack_property_get (gwidget_b, "position", &position_b);
- else
- gtk_container_child_get (GTK_CONTAINER (box),
- widget_b, "position", &position_b, NULL);
- return position_a - position_b;
-}
-
-GList *
-glade_gtk_box_get_children (GladeWidgetAdaptor * adaptor,
- GtkContainer * container)
-{
- GList *children = glade_util_container_get_all_children (container);
-
- return g_list_sort (children, (GCompareFunc) sort_box_children);
-}
-
-void
-glade_gtk_box_set_child_property (GladeWidgetAdaptor * adaptor,
- GObject * container,
- GObject * child,
- const gchar * property_name, GValue * value)
-{
- GladeWidget *gbox, *gchild, *gchild_iter;
- GList *children, *list;
- gboolean is_position;
- gint old_position, iter_position, new_position;
- static gboolean recursion = FALSE;
-
- g_return_if_fail (GTK_IS_BOX (container));
- g_return_if_fail (GTK_IS_WIDGET (child));
- g_return_if_fail (property_name != NULL || value != NULL);
-
- gbox = glade_widget_get_from_gobject (container);
- gchild = glade_widget_get_from_gobject (child);
-
- g_return_if_fail (GLADE_IS_WIDGET (gbox));
-
- if (gtk_widget_get_parent (GTK_WIDGET (child)) != GTK_WIDGET (container))
- return;
-
- /* Get old position */
- if ((is_position = (strcmp (property_name, "position") == 0)) != FALSE)
- {
- gtk_container_child_get (GTK_CONTAINER (container),
- GTK_WIDGET (child),
- property_name, &old_position, NULL);
-
-
- /* Get the real value */
- new_position = g_value_get_int (value);
- }
-
- if (is_position && recursion == FALSE)
- {
- children = glade_widget_get_children (gbox);
- children = g_list_sort (children, (GCompareFunc) sort_box_children);
-
- for (list = children; list; list = list->next)
- {
- gchild_iter = glade_widget_get_from_gobject (list->data);
-
- if (gchild_iter == gchild)
- {
- gtk_box_reorder_child (GTK_BOX (container),
- GTK_WIDGET (child), new_position);
- continue;
- }
-
- /* Get the old value from glade */
- glade_widget_pack_property_get
- (gchild_iter, "position", &iter_position);
-
- /* Search for the child at the old position and update it */
- if (iter_position == new_position &&
- glade_property_superuser () == FALSE)
- {
- /* Update glade with the real value */
- recursion = TRUE;
- glade_widget_pack_property_set
- (gchild_iter, "position", old_position);
- recursion = FALSE;
- continue;
- }
- else
- {
- gtk_box_reorder_child (GTK_BOX (container),
- GTK_WIDGET (list->data), iter_position);
- }
- }
-
- for (list = children; list; list = list->next)
- {
- gchild_iter = glade_widget_get_from_gobject (list->data);
-
- /* Refresh values yet again */
- glade_widget_pack_property_get
- (gchild_iter, "position", &iter_position);
-
- gtk_box_reorder_child (GTK_BOX (container),
- GTK_WIDGET (list->data), iter_position);
-
- }
-
- if (children)
- g_list_free (children);
- }
-
- /* Chain Up */
- if (!is_position)
- GWA_GET_CLASS
- (GTK_TYPE_CONTAINER)->child_set_property (adaptor,
- container,
- child, property_name, value);
-
- gtk_container_check_resize (GTK_CONTAINER (container));
-
-}
-
-void
-glade_gtk_box_get_property (GladeWidgetAdaptor * adaptor,
- GObject * object, const gchar * id, GValue * value)
-{
- if (!strcmp (id, "size"))
- {
- GtkBox *box = GTK_BOX (object);
- GList *children = gtk_container_get_children (GTK_CONTAINER (box));
-
- g_value_reset (value);
- g_value_set_int (value, g_list_length (children));
- g_list_free (children);
- }
- else
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->get_property (adaptor, object, id,
- value);
-}
-
-static gint
-glade_gtk_box_get_first_blank (GtkBox * box)
-{
- GList *child, *children;
- GladeWidget *gwidget;
- gint position;
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- for (child = children, position = 0;
- child && child->data; child = child->next, position++)
- {
- GtkWidget *widget = child->data;
-
- if ((gwidget = glade_widget_get_from_gobject (widget)) != NULL)
- {
- gint gwidget_position = 0;
- GladeProperty *property =
- glade_widget_get_pack_property (gwidget, "position");
-
- /* property can be NULL here when project is closing */
- if (property)
- gwidget_position = g_value_get_int (glade_property_inline_value (property));
-
- if (gwidget_position > position)
- break;
- }
- }
-
- g_list_free (children);
-
- return position;
-}
-
-static void
-glade_gtk_box_set_size (GObject * object, const GValue * value)
-{
- GtkBox *box;
- GList *child, *children;
- guint new_size, old_size, i;
-
- box = GTK_BOX (object);
- g_return_if_fail (GTK_IS_BOX (box));
-
- if (glade_util_object_is_loading (object))
- return;
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- old_size = g_list_length (children);
- new_size = g_value_get_int (value);
-
- if (old_size == new_size)
- {
- g_list_free (children);
- return;
- }
-
- /* Ensure placeholders first...
- */
- for (i = 0; i < new_size; i++)
- {
- if (g_list_length (children) < (i + 1))
- {
- GtkWidget *placeholder = glade_placeholder_new ();
- gint blank = glade_gtk_box_get_first_blank (box);
-
- gtk_container_add (GTK_CONTAINER (box), placeholder);
- gtk_box_reorder_child (box, placeholder, blank);
- }
- }
-
- /* The box has shrunk. Remove the widgets that are on those slots */
- for (child = g_list_last (children);
- child && old_size > new_size; child = g_list_previous (child))
- {
- GtkWidget *child_widget = child->data;
-
- /* Refuse to remove any widgets that are either GladeWidget objects
- * or internal to the hierarchic entity (may be a composite widget,
- * not all internal widgets have GladeWidgets).
- */
- if (glade_widget_get_from_gobject (child_widget) ||
- GLADE_IS_PLACEHOLDER (child_widget) == FALSE)
- continue;
-
- g_object_ref (G_OBJECT (child_widget));
- gtk_container_remove (GTK_CONTAINER (box), child_widget);
- gtk_widget_destroy (child_widget);
- old_size--;
- }
- g_list_free (children);
-
-}
-
-void
-glade_gtk_box_set_property (GladeWidgetAdaptor * adaptor,
- GObject * object,
- const gchar * id, const GValue * value)
-{
- if (!strcmp (id, "size"))
- glade_gtk_box_set_size (object, value);
- else
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->set_property (adaptor, object, id,
- value);
-}
-
-static gboolean
-glade_gtk_box_verify_size (GObject *object, const GValue *value)
-{
- GList *child, *children;
- gint old_size, count = 0;
- gint new_size = g_value_get_int (value);
-
- children = gtk_container_get_children (GTK_CONTAINER (object));
- old_size = g_list_length (children);
-
- for (child = g_list_last (children);
- child && old_size > new_size;
- child = g_list_previous (child))
- {
- GtkWidget *widget = child->data;
- if (glade_widget_get_from_gobject (widget) != NULL)
- count++;
- else
- old_size--;
- }
-
- g_list_free (children);
-
- return count > new_size ? FALSE : new_size >= 0;
-}
-
-
-gboolean
-glade_gtk_box_verify_property (GladeWidgetAdaptor * adaptor,
- GObject * object,
- const gchar * id, const GValue * value)
-{
- if (!strcmp (id, "size"))
- return glade_gtk_box_verify_size (object, value);
- else if (GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property)
- return GWA_GET_CLASS (GTK_TYPE_CONTAINER)->verify_property (adaptor, object,
- id, value);
-
- return TRUE;
-}
-
-
-static void
-fix_response_id_on_child (GladeWidget * gbox, GObject * child, gboolean add)
-{
- GladeWidget *gchild;
- const gchar *internal_name;
-
- gchild = glade_widget_get_from_gobject (child);
-
- /* Fix response id property on child buttons */
- if (gchild && GTK_IS_BUTTON (child))
- {
- if (add && (internal_name = glade_widget_get_internal (gbox)) &&
- !strcmp (internal_name, "action_area"))
- glade_widget_property_set_sensitive (gchild, "response-id", TRUE,
- NULL);
- else
- glade_widget_property_set_sensitive (gchild, "response-id", FALSE,
- RESPID_INSENSITIVE_MSG);
- }
-}
-
-void
-glade_gtk_box_add_child (GladeWidgetAdaptor * adaptor,
- GObject * object, GObject * child)
-{
- GladeWidget *gbox, *gchild;
- GList *children;
- gint num_children;
-
- g_return_if_fail (GTK_IS_BOX (object));
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- gbox = glade_widget_get_from_gobject (object);
-
- /*
- Try to remove the last placeholder if any, this way GtkBox`s size
- will not be changed.
- */
- if (glade_widget_superuser () == FALSE && !GLADE_IS_PLACEHOLDER (child))
- {
- GList *l, *children;
- GtkBox *box = GTK_BOX (object);
-
- children = gtk_container_get_children (GTK_CONTAINER (box));
-
- for (l = g_list_last (children); l; l = g_list_previous (l))
- {
- GtkWidget *child_widget = l->data;
- if (GLADE_IS_PLACEHOLDER (child_widget))
- {
- gtk_container_remove (GTK_CONTAINER (box), child_widget);
- break;
- }
- }
- g_list_free (children);
- }
-
- gtk_container_add (GTK_CONTAINER (object), GTK_WIDGET (child));
-
- children = gtk_container_get_children (GTK_CONTAINER (object));
- num_children = g_list_length (children);
- g_list_free (children);
-
- glade_widget_property_set (gbox, "size", num_children);
-
- gchild = glade_widget_get_from_gobject (child);
-
- /* The "Remove Slot" operation only makes sence on placeholders,
- * otherwise its a "Delete" operation on the child widget.
- */
- if (gchild)
- glade_widget_set_pack_action_visible (gchild, "remove_slot", FALSE);
-
- /* Packing props arent around when parenting during a glade_widget_dup() */
- if (gchild && glade_widget_get_packing_properties (gchild))
- glade_widget_pack_property_set (gchild, "position", num_children - 1);
-
- fix_response_id_on_child (gbox, child, TRUE);
-}
-
-void
-glade_gtk_box_remove_child (GladeWidgetAdaptor * adaptor,
- GObject * object, GObject * child)
-{
- GladeWidget *gbox;
- gint size;
-
- g_return_if_fail (GTK_IS_BOX (object));
- g_return_if_fail (GTK_IS_WIDGET (child));
-
- gbox = glade_widget_get_from_gobject (object);
-
- gtk_container_remove (GTK_CONTAINER (object), GTK_WIDGET (child));
-
- if (glade_widget_superuser () == FALSE)
- {
- glade_widget_property_get (gbox, "size", &size);
- glade_widget_property_set (gbox, "size", size);
- }
-
- fix_response_id_on_child (gbox, child, FALSE);
-}
-
-
-void
-glade_gtk_box_replace_child (GladeWidgetAdaptor * adaptor,
- GObject * container,
- GObject * current, GObject * new_widget)
-{
- GladeWidget *gchild;
- GladeWidget *gbox;
-
- g_object_ref (G_OBJECT (current));
-
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->replace_child (adaptor,
- container,
- current, new_widget);
- gbox = glade_widget_get_from_gobject (container);
-
- if ((gchild = glade_widget_get_from_gobject (new_widget)) != NULL)
- /* The "Remove Slot" operation only makes sence on placeholders,
- * otherwise its a "Delete" operation on the child widget.
- */
- glade_widget_set_pack_action_visible (gchild, "remove_slot", FALSE);
-
- fix_response_id_on_child (gbox, current, FALSE);
- fix_response_id_on_child (gbox, new_widget, TRUE);
-
- g_object_unref (G_OBJECT (current));
-}
-
-static void
-glade_gtk_box_notebook_child_insert_remove_action (GladeWidgetAdaptor * adaptor,
- GObject * container,
- GObject * object,
- const gchar * size_prop,
- const gchar * group_format,
- gboolean remove,
- gboolean after);
-
-void
-glade_gtk_box_child_action_activate (GladeWidgetAdaptor * adaptor,
- GObject * container,
- GObject * object,
- const gchar * action_path)
-{
- if (strcmp (action_path, "insert_after") == 0)
- {
- glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
- object, "size",
- _
- ("Insert placeholder to %s"),
- FALSE, TRUE);
- }
- else if (strcmp (action_path, "insert_before") == 0)
- {
- glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
- object, "size",
- _
- ("Insert placeholder to %s"),
- FALSE, FALSE);
- }
- else if (strcmp (action_path, "remove_slot") == 0)
- {
- glade_gtk_box_notebook_child_insert_remove_action (adaptor, container,
- object, "size",
- _
- ("Remove placeholder from %s"),
- TRUE, FALSE);
- }
- else
- GWA_GET_CLASS (GTK_TYPE_CONTAINER)->child_action_activate (adaptor,
- container,
- object,
- action_path);
-}
-
/* ----------------------------- GtkFrame ------------------------------ */
void
glade_gtk_frame_post_create (GladeWidgetAdaptor * adaptor,
@@ -3028,7 +2318,8 @@ glade_gtk_notebook_get_child_property (GladeWidgetAdaptor * adaptor,
GTK_WIDGET (child), property_name, value);
}
-static void
+/* Shared with glade-gtk-box.c */
+void
glade_gtk_box_notebook_child_insert_remove_action (GladeWidgetAdaptor * adaptor,
GObject * container,
GObject * object,
diff --git a/plugins/gtk+/glade-gtk.h b/plugins/gtk+/glade-gtk.h
index 0373f04..4c97d95 100644
--- a/plugins/gtk+/glade-gtk.h
+++ b/plugins/gtk+/glade-gtk.h
@@ -27,7 +27,7 @@
#include <glib/gi18n-lib.h>
-G_BEGIN_DECLS
+#include <gladeui/glade-widget-adaptor.h>
/* --------------------------------- Constants ------------------------------ */
@@ -41,6 +41,19 @@ G_BEGIN_DECLS
#define ONLY_THIS_GOES_IN_THAT_MSG _("Only objects of type %s can be added to objects of type %s.")
+G_BEGIN_DECLS
+
+/* Shared functions */
+void
+glade_gtk_box_notebook_child_insert_remove_action (GladeWidgetAdaptor * adaptor,
+ GObject * container,
+ GObject * object,
+ const gchar * size_prop,
+ const gchar * group_format,
+ gboolean remove,
+ gboolean after);
+
+
G_END_DECLS
#endif /* __GLADE_GTK_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]