gdl-dock-bar.c revision b5c42580c384b01263eb1a1e199376e15eef7cd3
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński * This file is part of the GNOME Devtools Libraries.
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński * Copyright (C) 2003 Jeroen Zwartepoorte <jeroen@xs4all.nl>
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * This library is free software; you can redistribute it and/or
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński * modify it under the terms of the GNU Lesser General Public
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * License as published by the Free Software Foundation; either
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * version 2.1 of the License, or (at your option) any later version.
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * This library is distributed in the hope that it will be useful,
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * but WITHOUT ANY WARRANTY; without even the implied warranty of
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * Lesser General Public License for more details.
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * You should have received a copy of the GNU Lesser General Public
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * License along with this library; if not, write to the Free Software
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński/* ----- Private prototypes ----- */
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_class_init (GdlDockBarClass *klass);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_instance_init (GdlDockBar *dockbar);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_get_property (GObject *object,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosińskistatic void gdl_dock_bar_set_property (GObject *object,
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelenstatic void gdl_dock_bar_destroy (GtkObject *object);
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosińskistatic void gdl_dock_bar_attach (GdlDockBar *dockbar,
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelenstatic void gdl_dock_bar_remove_item (GdlDockBar *dockbar,
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński/* ----- Class variables and definitions ----- */
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński/* ----- Private functions ----- */
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof KosińskiGDL_CLASS_BOILERPLATE (GdlDockBar, gdl_dock_bar, GtkBox, GTK_TYPE_BOX)
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_request (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_allocate (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_vrequest (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_vallocate (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_hrequest (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void gdl_dock_bar_size_hallocate (GtkWidget *widget,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskistatic void update_dock_items (GdlDockBar *dockbar, gboolean full_update);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_class_init (GdlDockBarClass *klass)
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_object_class->get_property = gdl_dock_bar_get_property;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_object_class->set_property = gdl_dock_bar_set_property;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_object_class->destroy = gdl_dock_bar_destroy;
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński g_param_spec_object ("master", _("Master"),
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński _("GdlDockMaster object which the dockbar widget "
e4369b05aaa20df73a37f4d319ce456865cc74f3Krzysztof Kosiński "is attached to"),
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_param_spec_enum ("dockbar-style", _("Dockbar style"),
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński _("Dockbar style to show items on it"),
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński widget_class->size_request = gdl_dock_bar_size_request;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński widget_class->size_allocate = gdl_dock_bar_size_allocate;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_instance_init (GdlDockBar *dockbar)
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński dockbar->_priv = g_new0 (GdlDockBarPrivate, 1);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński dockbar->_priv->orientation = GTK_ORIENTATION_VERTICAL;
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński dockbar->_priv->dockbar_style = GDL_DOCK_BAR_BOTH;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_get_property (GObject *object,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GdlDockBar *dockbar = GDL_DOCK_BAR (object);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_value_set_object (value, dockbar->_priv->master);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_value_set_enum (value, dockbar->_priv->dockbar_style);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_set_property (GObject *object,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GdlDockBar *dockbar = GDL_DOCK_BAR (object);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gdl_dock_bar_attach (dockbar, g_value_get_object (value));
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński dockbar->_priv->dockbar_style = g_value_get_enum (value);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskion_dock_item_foreach_disconnect (GdlDockItem *item, GdlDockBar *dock_bar)
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen g_signal_handlers_disconnect_by_func (item, gdl_dock_bar_remove_item,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GdlDockBar *dockbar = GDL_DOCK_BAR (object);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GdlDockBarPrivate *priv = dockbar->_priv;
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_signal_handlers_disconnect_matched (priv->master,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GDL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_remove_item (GdlDockBar *dockbar,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_return_if_fail (GDL_IS_DOCK_BAR (dockbar));
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_return_if_fail (GDL_IS_DOCK_ITEM (item));
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if (g_slist_index (priv->items, item) == -1) {
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_warning ("Item has not been added to the dockbar");
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński priv->items = g_slist_remove (priv->items, item);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński button = g_object_get_data (G_OBJECT (item), "GdlDockBarButton");
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_container_remove (GTK_CONTAINER (dockbar), button);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_object_set_data (G_OBJECT (item), "GdlDockBarButton", NULL);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_signal_handlers_disconnect_by_func (item,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosińskigdl_dock_bar_item_clicked (GtkWidget *button,
d37634d73670180f99a3e0ea583621373d90ec4fJohan Engelen dockbar = g_object_get_data (G_OBJECT (item), "GdlDockBar");
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen g_object_set_data (G_OBJECT (item), "GdlDockBar", NULL);
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński controller = gdl_dock_master_get_controller (GDL_DOCK_OBJECT_GET_MASTER (item));
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński GDL_DOCK_OBJECT_UNSET_FLAGS (item, GDL_DOCK_ICONIFIED);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gdl_dock_bar_remove_item (dockbar, item);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_widget_queue_resize (GTK_WIDGET (controller));
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński g_return_if_fail (GDL_IS_DOCK_BAR (dockbar));
18d56400fb8d667bff7c64b550365d94725bfe6eDiederik van Lierop g_return_if_fail (GDL_IS_DOCK_ITEM (item));
c8589a6c7367d09fa756755cef0dd448c7328a71Johan B. C. Engelen if (g_slist_index (priv->items, item) != -1) {
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_warning ("Item has already been added to the dockbar");
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński priv->items = g_slist_append (priv->items, item);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński /* Create a button for the item. */
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if (dockbar->_priv->orientation == GTK_ORIENTATION_HORIZONTAL)
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński g_object_get (item, "stock-id", &stock_id, "pixbuf-icon", &pixbuf_icon,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if (dockbar->_priv->dockbar_style == GDL_DOCK_BAR_TEXT ||
18d56400fb8d667bff7c64b550365d94725bfe6eDiederik van Lierop dockbar->_priv->dockbar_style == GDL_DOCK_BAR_BOTH) {
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if (dockbar->_priv->orientation == GTK_ORIENTATION_VERTICAL)
18d56400fb8d667bff7c64b550365d94725bfe6eDiederik van Lierop gtk_label_set_angle (GTK_LABEL (label), 90);
18d56400fb8d667bff7c64b550365d94725bfe6eDiederik van Lierop gtk_box_pack_start_defaults (GTK_BOX (box), label);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński /* FIXME: For now AUTO behaves same as BOTH */
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński if (dockbar->_priv->dockbar_style == GDL_DOCK_BAR_ICONS ||
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński dockbar->_priv->dockbar_style == GDL_DOCK_BAR_BOTH ||
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński dockbar->_priv->dockbar_style == GDL_DOCK_BAR_AUTO) {
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński image = gtk_image_new_from_stock (stock_id,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński image = gtk_image_new_from_pixbuf (pixbuf_icon);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński image = gtk_image_new_from_stock (GTK_STOCK_NEW,
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_box_pack_start_defaults (GTK_BOX (box), image);
00f9ca0b3aa57e09f3c3f3632c5427fc03499df5Krzysztof Kosiński gtk_container_add (GTK_CONTAINER (button), box);
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen gtk_box_pack_start (GTK_BOX (dockbar), button, FALSE, FALSE, 0);
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen g_object_set_data (G_OBJECT (item), "GdlDockBar", dockbar);
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen g_object_set_data (G_OBJECT (item), "GdlDockBarButton", button);
1f37e9d97c3bb8cf02b2cc80af8dcfc9aba7c7b4johanengelen g_signal_connect (G_OBJECT (button), "clicked",
dockbar);
if (!full_update) {
(void)master;
dockbar);
case GTK_ORIENTATION_VERTICAL:
case GTK_ORIENTATION_VERTICAL:
nvis_children = 0;
while (children)
if (nvis_children > 0)
gint y;
nvis_children = 0;
nexpand_children = 0;
while (children)
if (nvis_children > 0)
else if (nexpand_children > 0)
height = 0;
extra = 0;
child_allocation.width = MAX (1, (gint) allocation->width - (gint) GTK_CONTAINER (box)->border_width * 2);
while (children)
while (children)
nvis_children = 0;
while (children)
if (nvis_children > 0)
gint x;
nvis_children = 0;
nexpand_children = 0;
while (children)
if (nvis_children > 0)
else if (nexpand_children > 0)
width = 0;
extra = 0;
child_allocation.height = MAX (1, (gint) allocation->height - (gint) GTK_CONTAINER (box)->border_width * 2);
while (children)
child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
while (children)
child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width;
if (dock)
return style;