void gdl_dock_add_floating_item (GdlDock *dock, GdlDockItem *item, gint x, gint y, gint width, gint height) { GdlDock *new_dock; g_return_if_fail (dock != NULL); g_return_if_fail (item != NULL); new_dock = GDL_DOCK (g_object_new (GDL_TYPE_DOCK, "master", GDL_DOCK_OBJECT_GET_MASTER (dock), "floating", TRUE, "width", width, "height", height, "floatx", x, "floaty", y, NULL)); if (GTK_WIDGET_VISIBLE (dock)) { gtk_widget_show (GTK_WIDGET (new_dock)); if (GTK_WIDGET_MAPPED (dock)) gtk_widget_map (GTK_WIDGET (new_dock)); /* Make the widget resize. */ gtk_widget_queue_resize (GTK_WIDGET (new_dock)); } gdl_dock_add_item (GDL_DOCK (new_dock), item, GDL_DOCK_TOP); }
GList * gdl_dock_get_named_items (GdlDock *dock) { GList *list = NULL; g_return_val_if_fail (dock != NULL, NULL); gdl_dock_master_foreach (GDL_DOCK_OBJECT_GET_MASTER (dock), (GFunc) _gdl_dock_foreach_build_list, &list); return list; }
GdlDockItem * gdl_dock_get_item_by_name (GdlDock *dock, const gchar *name) { GdlDockObject *found; g_return_val_if_fail (dock != NULL && name != NULL, NULL); /* proxy the call to our master */ found = gdl_dock_master_get_object (GDL_DOCK_OBJECT_GET_MASTER (dock), name); return (found && GDL_IS_DOCK_ITEM (found)) ? GDL_DOCK_ITEM (found) : NULL; }
GtkWidget * gdl_dock_new_from (GdlDock *original, gboolean floating) { GObject *new_dock; g_return_val_if_fail (original != NULL, NULL); new_dock = g_object_new (GDL_TYPE_DOCK, "master", GDL_DOCK_OBJECT_GET_MASTER (original), "floating", floating, NULL); GDL_DOCK_OBJECT_UNSET_FLAGS (new_dock, GDL_DOCK_AUTOMATIC); return GTK_WIDGET (new_dock); }
static void gdl_dock_hide (GtkWidget *widget) { GdlDock *dock; g_return_if_fail (widget != NULL); g_return_if_fail (GDL_IS_DOCK (widget)); GDL_CALL_PARENT (GTK_WIDGET_CLASS, hide, (widget)); dock = GDL_DOCK (widget); if (dock->_priv->floating && dock->_priv->window) gtk_widget_hide (dock->_priv->window); if (GDL_DOCK_IS_CONTROLLER (dock)) { gdl_dock_master_foreach_toplevel (GDL_DOCK_OBJECT_GET_MASTER (dock), FALSE, (GFunc) gdl_dock_foreach_automatic, gtk_widget_hide); } }
static void gdl_dock_master_drag_motion (GdlDockItem *item, gint root_x, gint root_y, gpointer data) { GdlDockMaster *master; GdlDockRequest my_request, *request; GdkWindow *window; gint win_x, win_y; gint x, y; GdlDock *dock = NULL; gboolean may_dock = FALSE; g_return_if_fail (item != NULL && data != NULL); master = GDL_DOCK_MASTER (data); request = master->_priv->drag_request; g_return_if_fail (GDL_DOCK_OBJECT (item) == request->applicant); my_request = *request; /* first look under the pointer */ window = gdk_window_at_pointer (&win_x, &win_y); if (window) { GtkWidget *widget; /* ok, now get the widget who owns that window and see if we can get to a GdlDock by walking up the hierarchy */ gdk_window_get_user_data (window, (gpointer) &widget); if (GTK_IS_WIDGET (widget)) { while (widget && (!GDL_IS_DOCK (widget) || GDL_DOCK_OBJECT_GET_MASTER (widget) != master)) widget = widget->parent; if (widget) { gint win_w, win_h; /* verify that the pointer is still in that dock (the user could have moved it) */ gdk_window_get_geometry (widget->window, NULL, NULL, &win_w, &win_h, NULL); gdk_window_get_origin (widget->window, &win_x, &win_y); if (root_x >= win_x && root_x < win_x + win_w && root_y >= win_y && root_y < win_y + win_h) dock = GDL_DOCK (widget); } } } if (dock) { /* translate root coordinates into dock object coordinates (i.e. widget coordinates) */ gdk_window_get_origin (GTK_WIDGET (dock)->window, &win_x, &win_y); x = root_x - win_x; y = root_y - win_y; may_dock = gdl_dock_object_dock_request (GDL_DOCK_OBJECT (dock), x, y, &my_request); } else { GList *l; /* try to dock the item in all the docks in the ring in turn */ for (l = master->toplevel_docks; l; l = l->next) { dock = GDL_DOCK (l->data); /* translate root coordinates into dock object coordinates (i.e. widget coordinates) */ gdk_window_get_origin (GTK_WIDGET (dock)->window, &win_x, &win_y); x = root_x - win_x; y = root_y - win_y; may_dock = gdl_dock_object_dock_request (GDL_DOCK_OBJECT (dock), x, y, &my_request); if (may_dock) break; } } if (!may_dock) { GtkRequisition req; /* Special case for GdlDockItems : they must respect the flags */ if(GDL_IS_DOCK_ITEM(item) && GDL_DOCK_ITEM(item)->behavior & GDL_DOCK_ITEM_BEH_NEVER_FLOATING) return; dock = NULL; my_request.target = GDL_DOCK_OBJECT ( gdl_dock_object_get_toplevel (request->applicant)); my_request.position = GDL_DOCK_FLOATING; gdl_dock_item_preferred_size (GDL_DOCK_ITEM (request->applicant), &req); my_request.rect.width = req.width; my_request.rect.height = req.height; my_request.rect.x = root_x - GDL_DOCK_ITEM (request->applicant)->dragoff_x; my_request.rect.y = root_y - GDL_DOCK_ITEM (request->applicant)->dragoff_y; /* setup extra docking information */ if (G_IS_VALUE (&my_request.extra)) g_value_unset (&my_request.extra); g_value_init (&my_request.extra, GDK_TYPE_RECTANGLE); g_value_set_boxed (&my_request.extra, &my_request.rect); } /* if we want to enforce GDL_DOCK_ITEM_BEH_NEVER_FLOATING */ /* the item must remain attached to the controller, otherwise */ /* it could be inserted in another floating dock */ /* so check for the flag at this moment */ else if(GDL_IS_DOCK_ITEM(item) && GDL_DOCK_ITEM(item)->behavior & GDL_DOCK_ITEM_BEH_NEVER_FLOATING && dock != GDL_DOCK(master->controller)) return; if (!(my_request.rect.x == request->rect.x && my_request.rect.y == request->rect.y && my_request.rect.width == request->rect.width && my_request.rect.height == request->rect.height && dock == master->_priv->rect_owner)) { /* erase the previous rectangle */ if (master->_priv->rect_drawn) gdl_dock_master_xor_rect (master); } /* set the new values */ *request = my_request; master->_priv->rect_owner = dock; /* draw the previous rectangle */ if (~master->_priv->rect_drawn) gdl_dock_master_xor_rect (master); }
static GObject * gdl_dock_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_param) { GObject *g_object; g_object = GDL_CALL_PARENT_WITH_DEFAULT (G_OBJECT_CLASS, constructor, (type, n_construct_properties, construct_param), NULL); if (g_object) { GdlDock *dock = GDL_DOCK (g_object); GdlDockMaster *master; /* create a master for the dock if none was provided in the construction */ master = GDL_DOCK_OBJECT_GET_MASTER (GDL_DOCK_OBJECT (dock)); if (!master) { GDL_DOCK_OBJECT_UNSET_FLAGS (dock, GDL_DOCK_AUTOMATIC); master = g_object_new (GDL_TYPE_DOCK_MASTER, NULL); /* the controller owns the master ref */ gdl_dock_object_bind (GDL_DOCK_OBJECT (dock), G_OBJECT (master)); } if (dock->_priv->floating) { GdlDockObject *controller; /* create floating window for this dock */ dock->_priv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_object_set_data (G_OBJECT (dock->_priv->window), "dock", dock); /* set position and default size */ gtk_window_set_position (GTK_WINDOW (dock->_priv->window), GTK_WIN_POS_MOUSE); gtk_window_set_default_size (GTK_WINDOW (dock->_priv->window), dock->_priv->width, dock->_priv->height); gtk_window_set_type_hint (GTK_WINDOW (dock->_priv->window), GDK_WINDOW_TYPE_HINT_NORMAL); /* metacity ignores this */ gtk_window_move (GTK_WINDOW (dock->_priv->window), dock->_priv->float_x, dock->_priv->float_y); /* connect to the configure event so we can track down window geometry */ g_signal_connect (dock->_priv->window, "configure_event", (GCallback) gdl_dock_floating_configure_event_cb, dock); /* set the title and connect to the long_name notify queue so we can reset the title when this prop changes */ gdl_dock_set_title (dock); g_signal_connect (dock, "notify::long-name", (GCallback) gdl_dock_notify_cb, NULL); gtk_container_add (GTK_CONTAINER (dock->_priv->window), GTK_WIDGET (dock)); g_signal_connect (dock->_priv->window, "delete_event", G_CALLBACK (gdl_dock_floating_window_delete_event_cb), NULL); } GDL_DOCK_OBJECT_SET_FLAGS (dock, GDL_DOCK_ATTACHED); } return g_object; }