static void gdl_dock_object_real_detach (GdlDockObject *object, gboolean recursive) { GdlDockObject *parent; GtkWidget *widget; g_return_if_fail (object != NULL); /* detach children */ if (recursive && gdl_dock_object_is_compound (object)) { gtk_container_foreach (GTK_CONTAINER (object), (GtkCallback) gdl_dock_object_detach, GINT_TO_POINTER (recursive)); } /* detach the object itself */ object->priv->attached = FALSE; #ifndef GDL_DISABLE_DEPRECATED object->deprecated_flags &= ~GDL_DOCK_ATTACHED; #endif parent = gdl_dock_object_get_parent_object (object); widget = GTK_WIDGET (object); if (gtk_widget_get_parent (widget)) gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (GTK_WIDGET (widget))), widget); if (parent) gdl_dock_object_reduce (parent); }
static void gdl_dock_object_real_detach (GdlDockObject *object, gboolean recursive) { GdlDockObject *parent; GtkWidget *widget; g_return_if_fail (object != NULL); /* detach children */ if (recursive && gdl_dock_object_is_compound (object)) { gtk_container_foreach (GTK_CONTAINER (object), (GtkCallback) gdl_dock_object_detach, GINT_TO_POINTER (recursive)); } /* detach the object itself */ GDL_DOCK_OBJECT_UNSET_FLAGS (object, GDL_DOCK_ATTACHED); parent = gdl_dock_object_get_parent_object (object); widget = GTK_WIDGET (object); if (widget->parent) gtk_container_remove (GTK_CONTAINER (widget->parent), widget); if (parent) gdl_dock_object_reduce (parent); }
static void gdl_dock_object_update_parent_visibility (GdlDockObject *object) { GdlDockObject *parent; g_return_if_fail (object != NULL); parent = gdl_dock_object_get_parent_object (object); if (parent && gdl_dock_object_is_automatic (parent)) { gboolean visible = FALSE; gtk_container_foreach (GTK_CONTAINER (parent), (GtkCallback) gdl_dock_object_foreach_is_visible, &visible); parent->priv->attached = visible; #ifndef GDL_DISABLE_DEPRECATED if (visible) parent->deprecated_flags |= GDL_DOCK_ATTACHED; else parent->deprecated_flags &= ~GDL_DOCK_ATTACHED; #endif gtk_widget_set_visible (GTK_WIDGET (parent), visible); } gdl_dock_object_layout_changed_notify (object); }
/** * gdl_dock_object_dock: * @object: A #GdlDockObject * @requestor: The widget to dock * @position: The position for the child * @other_data: (allow-none): Optional data giving additional information * depending on the dock object. * * Dock a dock widget in @object at the defined position. */ void gdl_dock_object_dock (GdlDockObject *object, GdlDockObject *requestor, GdlDockPlacement position, GValue *other_data) { GdlDockObject *parent; g_return_if_fail (object != NULL && requestor != NULL); if (object == requestor) return; if (!object->priv->master) g_warning (_("Dock operation requested in a non-bound object %p. " "The application might crash"), object); if (!gdl_dock_object_is_bound (requestor)) gdl_dock_object_bind (requestor, object->priv->master); if (requestor->priv->master != object->priv->master) { g_warning (_("Cannot dock %p to %p because they belong to different masters"), requestor, object); return; } /* first, see if we can optimize things by reordering */ if (position != GDL_DOCK_NONE) { parent = gdl_dock_object_get_parent_object (object); if (gdl_dock_object_reorder (object, requestor, position, other_data) || (parent && gdl_dock_object_reorder (parent, requestor, position, other_data))) return; } /* freeze the object, since under some conditions it might be destroyed when detaching the requestor */ gdl_dock_object_freeze (object); /* detach the requestor before docking */ g_object_ref (requestor); gdl_dock_object_detach (requestor, FALSE); if (position != GDL_DOCK_NONE) g_signal_emit (object, gdl_dock_object_signals [DOCK], 0, requestor, position, other_data); g_object_unref (requestor); gdl_dock_object_thaw (object); if (gtk_widget_get_visible (GTK_WIDGET (requestor))) { requestor->priv->attached = TRUE; #ifndef GDL_DISABLE_DEPRECATED requestor->deprecated_flags |= GDL_DOCK_ATTACHED; #endif } /* Update visibility of automatic parents */ gdl_dock_object_update_parent_visibility (GDL_DOCK_OBJECT (requestor)); }
/** * gdl_dock_add_item: * @dock: A #GdlDock widget * @item: A #GdlDockItem widget * @placement: A position for the widget * * Dock in @dock, the widget @item at the position defined by @placement. The * function takes care of finding the right parent widget eventually creating * it if needed. */ void gdl_dock_add_item (GdlDock *dock, GdlDockItem *item, GdlDockPlacement placement) { GdlDockObject *placeholder; GdlDockObject *parent = NULL; GdlDockPlacement place; g_return_if_fail (dock != NULL); g_return_if_fail (item != NULL); /* Check if a placeholder widget already exist in the same dock */ placeholder = gdl_dock_master_get_object (GDL_DOCK_MASTER (gdl_dock_object_get_master (GDL_DOCK_OBJECT (dock))), gdl_dock_object_get_name (GDL_DOCK_OBJECT (item))); if ((placeholder != GDL_DOCK_OBJECT (item)) && (placeholder != NULL)) { if (gdl_dock_object_get_toplevel (placeholder) == dock) { parent = gdl_dock_object_get_parent_object (placeholder); } else { gtk_widget_destroy (GTK_WIDGET (placeholder)); } } if (parent && gdl_dock_object_child_placement (parent, placeholder, &place)) { gdl_dock_object_freeze (GDL_DOCK_OBJECT (parent)); gtk_widget_destroy (GTK_WIDGET (placeholder)); gdl_dock_object_dock (GDL_DOCK_OBJECT (parent), GDL_DOCK_OBJECT (item), place, NULL); gdl_dock_object_thaw (GDL_DOCK_OBJECT (parent)); } else if (placement == GDL_DOCK_FLOATING) /* Add the item to a new floating dock */ gdl_dock_add_floating_item (dock, item, 0, 0, -1, -1); else { GdlDockItem *best_dock_item; /* Non-floating item. */ if (dock->priv->root) { GdlDockPlacement local_placement; GtkRequisition preferred_size; best_dock_item = gdl_dock_find_best_placement_item (GDL_DOCK_ITEM (dock->priv->root), placement, 0); local_placement = gdl_dock_refine_placement (dock, best_dock_item, placement); gdl_dock_object_dock (GDL_DOCK_OBJECT (best_dock_item), GDL_DOCK_OBJECT (item), local_placement, NULL); } else { gdl_dock_object_dock (GDL_DOCK_OBJECT (dock), GDL_DOCK_OBJECT (item), placement, NULL); } } }
static void gdl_dock_object_update_parent_visibility (GdlDockObject *object) { GdlDockObject *parent; g_return_if_fail (object != NULL); parent = gdl_dock_object_get_parent_object (object); if (parent != NULL) gdl_dock_object_update_visibility (parent); }
void gdl_dock_object_dock (GdlDockObject *object, GdlDockObject *requestor, GdlDockPlacement position, GValue *other_data) { GdlDockObject *parent; g_return_if_fail (object != NULL && requestor != NULL); if (object == requestor) return; if (!object->master) g_warning (_("Dock operation requested in a non-bound object %p. " "The application might crash"), object); PF; if (!gdl_dock_object_is_bound (requestor)) gdl_dock_object_bind (requestor, object->master); if (requestor->master != object->master) { g_warning (_("Cannot dock %p to %p because they belong to different masters"), requestor, object); return; } /* first, see if we can optimize things by reordering */ if (position != GDL_DOCK_NONE) { parent = gdl_dock_object_get_parent_object (object); if (gdl_dock_object_reorder (object, requestor, position, other_data) || (parent && gdl_dock_object_reorder (parent, requestor, position, other_data))) return; } /* freeze the object, since under some conditions it might be destroyed when detaching the requestor */ gdl_dock_object_freeze (object); /* detach the requestor before docking */ g_object_ref (requestor); if (GDL_DOCK_OBJECT_ATTACHED (requestor)) gdl_dock_object_detach (requestor, FALSE); if (position != GDL_DOCK_NONE) g_signal_emit (object, gdl_dock_object_signals [DOCK], 0, requestor, position, other_data); dbg(1, "done"); g_object_unref (requestor); gdl_dock_object_thaw (object); }
GdlDock * gdl_dock_object_get_toplevel (GdlDockObject *object) { GdlDockObject *parent = object; g_return_val_if_fail (object != NULL, NULL); while (parent && !GDL_IS_DOCK (parent)) parent = gdl_dock_object_get_parent_object (parent); return parent ? GDL_DOCK (parent) : NULL; }
void gdl_dock_object_present (GdlDockObject *object, GdlDockObject *child) { GdlDockObject *parent; g_return_if_fail (object != NULL && GDL_IS_DOCK_OBJECT (object)); parent = gdl_dock_object_get_parent_object (object); if (parent) /* chain the call to our parent */ gdl_dock_object_present (parent, object); GDL_CALL_VIRTUAL (object, GDL_DOCK_OBJECT_GET_CLASS, present, (object, child)); }
static void gdl_dock_object_real_reduce (GdlDockObject *object) { GdlDockObject *parent; GList *children; g_return_if_fail (object != NULL); if (!gdl_dock_object_is_compound (object)) return; parent = gdl_dock_object_get_parent_object (object); children = gtk_container_get_children (GTK_CONTAINER (object)); if (g_list_length (children) <= 1) { GList *l; GList *dchildren = NULL; /* detach ourselves and then re-attach our children to our current parent. if we are not currently attached, the children are detached */ if (parent) gdl_dock_object_freeze (parent); gdl_dock_object_freeze (object); /* Detach the children before detaching this object, since in this * way the children can have access to the whole object hierarchy. * Set the InDetach flag now, so the children know that this object * is going to be detached. */ for (l = children; l; l = l->next) { GdlDockObject *child; if (!GDL_IS_DOCK_OBJECT (l->data)) continue; child = GDL_DOCK_OBJECT (l->data); g_object_ref (child); gdl_dock_object_detach (child, FALSE); if (parent) dchildren = g_list_append (dchildren, child); } /* Now it can be detached */ gdl_dock_object_detach (object, FALSE); /* After detaching the reduced object, we can add the children (the only child in fact) to the new parent */ for (l = dchildren; l; l = l->next) { gtk_container_add (GTK_CONTAINER (parent), l->data); g_object_unref (l->data); } g_list_free (dchildren); /* sink the widget, so any automatic floating widget is destroyed */ g_object_ref_sink (object); /* don't reenter */ object->priv->reduce_pending = FALSE; gdl_dock_object_thaw (object); if (parent) gdl_dock_object_thaw (parent); } g_list_free (children); }