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); /* Indirect children might be internal children, sort internal children before any other children */ if (box != gtk_widget_get_parent (widget_a)) return -1; if (box != gtk_widget_get_parent (widget_b)) return 1; if (gtk_box_get_center_widget (GTK_BOX (box)) == widget_a) return -1; if (gtk_box_get_center_widget (GTK_BOX (box)) == widget_b) return -1; /* 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; }
static gint sort_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); /* Sort internal children before any other children */ if (box != gtk_widget_get_parent (widget_a)) return -1; if (box != gtk_widget_get_parent (widget_b)) return 1; if (gtk_action_bar_get_center_widget (GTK_ACTION_BAR (box)) == widget_a) return -1; if (gtk_action_bar_get_center_widget (GTK_ACTION_BAR (box)) == widget_b) return -1; 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; }
static gboolean glade_gtk_grid_configure_begin (GladeFixed *fixed, GladeWidget *child, GtkWidget *grid) { grid_edit.widget = child; 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); memcpy (&grid_cur_attach, &grid_edit, sizeof (GladeGridChild)); return TRUE; }
static void sync_row_positions (GtkListBox *listbox) { GList *l, *rows; int position; static gboolean recursion = FALSE; /* Avoid feedback loop */ if (recursion) return; rows = gtk_container_get_children (GTK_CONTAINER (listbox)); position = 0; for (l = rows; l; l = g_list_next (l)) { gint old_position; glade_widget_pack_property_get (glade_widget_get_from_gobject (l->data), "position", &old_position); if (position != old_position) { /* Update glade with the new value */ recursion = TRUE; glade_widget_pack_property_set (glade_widget_get_from_gobject (l->data), "position", position); recursion = FALSE; } position++; } g_list_free (rows); }
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_grid_configure_end (GladeFixed *fixed, GladeWidget *child, GtkWidget *grid) { 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); 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); } return TRUE; }
static void glade_gtk_grid_child_insert_remove_action (GladeWidgetAdaptor *adaptor, GObject *container, GObject *object, GroupAction group_action, 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; gtk_container_child_get (GTK_CONTAINER (container), GTK_WIDGET (object), attach1, &child_pos, NULL); parent = glade_widget_get_from_gobject (container); switch (group_action) { case GROUP_ACTION_INSERT_ROW: glade_command_push_group (_("Insert Row on %s"), glade_widget_get_name (parent)); break; case GROUP_ACTION_INSERT_COLUMN: glade_command_push_group (_("Insert Column on %s"), glade_widget_get_name (parent)); break; case GROUP_ACTION_REMOVE_COLUMN: glade_command_push_group (_("Remove Column on %s"), glade_widget_get_name (parent)); break; case GROUP_ACTION_REMOVE_ROW: glade_command_push_group (_("Remove Row on %s"), glade_widget_get_name (parent)); break; default: g_assert_not_reached (); } children = glade_widget_adaptor_get_children (adaptor, container); /* Make sure widgets does not get destroyed */ g_list_foreach (children, (GFunc) g_object_ref, NULL); glade_widget_property_get (parent, n_row_col, &size); 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; /* Skip placeholders */ if (gchild == NULL) continue; 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 { /* 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; /* Skip placeholders */ if (gchild == NULL) continue; /* 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 { /* 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); glade_command_pop_group (); }
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; }
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)); }