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);
}
Example #2
0
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);
    }
}
Example #7
0
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);
        }
    }
}