void gdl_dock_master_remove (GdlDockMaster *master, GdlDockObject *object) { g_return_if_fail (master != NULL && object != NULL); /* remove from locked/unlocked hashes and property change if * that's the case */ if (GDL_IS_DOCK_ITEM (object) && GDL_DOCK_ITEM_HAS_GRIP (GDL_DOCK_ITEM (object))) { gint locked = COMPUTE_LOCKED (master); if (g_hash_table_remove (master->_priv->locked_items, object) || g_hash_table_remove (master->_priv->unlocked_items, object)) { if (COMPUTE_LOCKED (master) != locked) g_object_notify (G_OBJECT (master), "locked"); } } /* ref the master, since removing the controller could cause master disposal */ g_object_ref (master); /* all the interesting stuff happens in _gdl_dock_master_remove */ _gdl_dock_master_remove (object, master); /* post a layout_changed emission if the item is not automatic * (since it should be removed from the items model) */ if (!GDL_DOCK_OBJECT_AUTOMATIC (object)) { if (!master->_priv->idle_layout_changed_id) master->_priv->idle_layout_changed_id = g_idle_add (idle_emit_layout_changed, master); } /* balance ref count */ g_object_unref (master); }
static void gdl_dock_object_foreach_automatic (GdlDockObject *object, gpointer user_data) { void (* function) (GtkWidget *) = user_data; if (GDL_DOCK_OBJECT_AUTOMATIC (object)) (* function) (GTK_WIDGET (object)); }
static void _gdl_dock_master_remove (GdlDockObject *object, GdlDockMaster *master) { g_return_if_fail (master != NULL && object != NULL); if (GDL_IS_DOCK (object)) { GList *found_link; found_link = g_list_find (master->toplevel_docks, object); if (found_link) master->toplevel_docks = g_list_delete_link (master->toplevel_docks, found_link); if (object == master->controller) { GList *last; GdlDockObject *new_controller = NULL; /* now find some other non-automatic toplevel to use as a new controller. start from the last dock, since it's probably a non-floating and manual */ last = g_list_last (master->toplevel_docks); while (last) { if (!GDL_DOCK_OBJECT_AUTOMATIC (last->data)) { new_controller = GDL_DOCK_OBJECT (last->data); break; } last = last->prev; }; if (new_controller) { /* the new controller gets the ref (implicitly of course) */ master->controller = new_controller; } else { master->controller = NULL; /* no controller, no master */ g_object_unref (master); } } } /* disconnect dock object signals */ g_signal_handlers_disconnect_matched (object, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, master); /* unref the object from the hash if it's there */ if (object->name) { GdlDockObject *found_object; found_object = g_hash_table_lookup (master->dock_objects, object->name); if (found_object == object) { g_hash_table_remove (master->dock_objects, object->name); g_object_unref (object); } } }
static void item_detach_cb (GdlDockObject *object, gboolean recursive, gpointer user_data) { GdlDockMaster *master = user_data; g_return_if_fail (object && GDL_IS_DOCK_OBJECT (object)); g_return_if_fail (master && GDL_IS_DOCK_MASTER (master)); if (!GDL_DOCK_OBJECT_IN_REFLOW (object) && !GDL_DOCK_OBJECT_AUTOMATIC (object)) { if (!master->_priv->idle_layout_changed_id) master->_priv->idle_layout_changed_id = g_idle_add (idle_emit_layout_changed, master); } }
void gdl_dock_master_set_controller (GdlDockMaster *master, GdlDockObject *new_controller) { g_return_if_fail (master != NULL); if (new_controller) { if (GDL_DOCK_OBJECT_AUTOMATIC (new_controller)) g_warning (_("The new dock controller %p is automatic. Only manual " "dock objects should be named controller."), new_controller); /* check that the controller is in the toplevel list */ if (!g_list_find (master->toplevel_docks, new_controller)) gdl_dock_master_add (master, new_controller); master->controller = new_controller; } else { master->controller = NULL; /* no controller, no master */ g_object_unref (master); } }
static void item_dock_cb (GdlDockObject *object, GdlDockObject *requestor, GdlDockPlacement position, GValue *other_data, gpointer user_data) { GdlDockMaster *master = user_data; g_return_if_fail (requestor && GDL_IS_DOCK_OBJECT (requestor)); g_return_if_fail (master && GDL_IS_DOCK_MASTER (master)); /* here we are in fact interested in the requestor, since it's * assumed that object will not change its visibility... for the * requestor, however, could mean that it's being shown */ if (!GDL_DOCK_OBJECT_IN_REFLOW (requestor) && !GDL_DOCK_OBJECT_AUTOMATIC (requestor)) { if (!master->_priv->idle_layout_changed_id) master->_priv->idle_layout_changed_id = g_idle_add (idle_emit_layout_changed, master); } }
static void gdl_dock_reduce (GdlDockObject *object) { GdlDock *dock = GDL_DOCK (object); if (dock->root) return; if (GDL_DOCK_OBJECT_AUTOMATIC (dock)) { gtk_widget_destroy (GTK_WIDGET (dock)); } else if (!GDL_DOCK_OBJECT_ATTACHED (dock)) { /* if the user explicitly detached the object */ if (dock->_priv->floating) gtk_widget_hide (GTK_WIDGET (dock)); else { GtkWidget *widget = GTK_WIDGET (object); if (widget->parent) gtk_container_remove (GTK_CONTAINER (widget->parent), widget); } } }
void gdl_dock_master_add (GdlDockMaster *master, GdlDockObject *object) { g_return_if_fail (master != NULL && object != NULL); if (!GDL_DOCK_OBJECT_AUTOMATIC (object)) { GdlDockObject *found_object; /* create a name for the object if it doesn't have one */ if (!object->name) /* directly set the name, since it's a construction only property */ object->name = g_strdup_printf ("__dock_%u", master->_priv->number++); /* add the object to our hash list */ if ((found_object = g_hash_table_lookup (master->dock_objects, object->name))) { g_warning (_("master %p: unable to add object %p[%s] to the hash. " "There already is an item with that name (%p)."), master, object, object->name, found_object); } else { g_object_ref_sink (object); g_hash_table_insert (master->dock_objects, g_strdup (object->name), object); } } if (GDL_IS_DOCK (object)) { gboolean floating; /* if this is the first toplevel we are adding, name it controller */ if (!master->toplevel_docks) /* the dock should already have the ref */ master->controller = object; /* add dock to the toplevel list */ g_object_get (object, "floating", &floating, NULL); if (floating) master->toplevel_docks = g_list_prepend (master->toplevel_docks, object); else master->toplevel_docks = g_list_append (master->toplevel_docks, object); /* we are interested in the dock request this toplevel * receives to update the layout */ g_signal_connect (object, "dock", G_CALLBACK (item_dock_cb), master); } else if (GDL_IS_DOCK_ITEM (object)) { /* we need to connect the item's signals */ g_signal_connect (object, "dock_drag_begin", G_CALLBACK (gdl_dock_master_drag_begin), master); g_signal_connect (object, "dock_drag_motion", G_CALLBACK (gdl_dock_master_drag_motion), master); g_signal_connect (object, "dock_drag_end", G_CALLBACK (gdl_dock_master_drag_end), master); g_signal_connect (object, "dock", G_CALLBACK (item_dock_cb), master); g_signal_connect (object, "detach", G_CALLBACK (item_detach_cb), master); /* register to "locked" notification if the item has a grip, * and add the item to the corresponding hash */ if (GDL_DOCK_ITEM_HAS_GRIP (GDL_DOCK_ITEM (object))) { g_signal_connect (object, "notify::locked", G_CALLBACK (item_notify_cb), master); item_notify_cb (object, NULL, master); } /* If the item is notebook, set the switcher style */ if (GDL_IS_DOCK_NOTEBOOK (object) && GDL_IS_SWITCHER (GDL_DOCK_ITEM (object)->child)) { g_object_set (GDL_DOCK_ITEM (object)->child, "switcher-style", master->_priv->switcher_style, NULL); } /* post a layout_changed emission if the item is not automatic * (since it should be added to the items model) */ if (!GDL_DOCK_OBJECT_AUTOMATIC (object)) { if (!master->_priv->idle_layout_changed_id) master->_priv->idle_layout_changed_id = g_idle_add (idle_emit_layout_changed, master); } } }