Code

Dockable dialogs patch applied
[inkscape.git] / src / ui / widget / dock.cpp
1 /**
2  * \brief A desktop dock pane to dock dialogs.
3  *
4  * Author:
5  *   Gustav Broberg <broberg@kth.se>
6  *
7  * Copyright (C) 2007 Authors
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #include "inkscape.h"
13 #include "desktop.h"
15 #include "dock.h"
17 namespace Inkscape {
18 namespace UI {
19 namespace Widget {
21 namespace {
23 void hideCallback(GtkObject *object, gpointer dock_ptr)
24 {
25     g_return_if_fail( dock_ptr != NULL );
27     Dock *dock = (Dock *)dock_ptr;
28     dock->hide();
29 }
31 void unhideCallback(GtkObject *object, gpointer dock_ptr)
32 {
33     g_return_if_fail( dock_ptr != NULL );
35     Dock *dock = (Dock *)dock_ptr;
36     dock->show();
37 }
39 }
41 const int Dock::_default_empty_width = 0;
42 const int Dock::_default_dock_bar_width = 36;
45 Dock::Dock(Gtk::Orientation orientation)
46     : _gdl_dock (GDL_DOCK (gdl_dock_new())),
47       _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))),
48       _scrolled_window (Gtk::manage(new Gtk::ScrolledWindow))
49 {
50     gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation));
52     switch (orientation) {
53         case Gtk::ORIENTATION_VERTICAL:
54             _dock_box = Gtk::manage(new Gtk::HBox());
55             _paned = Gtk::manage(new Gtk::VPaned());
56             break;
57         case Gtk::ORIENTATION_HORIZONTAL:
58             _dock_box = Gtk::manage(new Gtk::VBox());
59             _paned = Gtk::manage(new Gtk::HPaned());
60     }
62     _scrolled_window->add(*_dock_box);
63     _scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
65     _paned->pack1(*Glib::wrap(GTK_WIDGET(_gdl_dock)), false, false);
66     _paned->pack2(_filler, true, false);
68     _dock_box->pack_start(*_paned, Gtk::PACK_EXPAND_WIDGET);
69     _dock_box->pack_end(*Gtk::manage(Glib::wrap(GTK_WIDGET(_gdl_dock_bar))), Gtk::PACK_SHRINK);
70     _dock_box->get_parent()->set_resize_mode(Gtk::RESIZE_PARENT);
72     _scrolled_window->set_size_request(0);
74     g_object_set (GDL_DOCK_OBJECT(_gdl_dock)->master,
75                   "switcher-style", GDL_SWITCHER_STYLE_BOTH,
76                   NULL);
78     g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this);
79     g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this);
81     signal_layout_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::Dock::_onLayoutChanged));
82 }    
84 Dock::~Dock()
85 {
86     g_free(_gdl_dock);
87     g_free(_gdl_dock_bar);
88 }
90 void
91 Dock::addItem(DockItem& item, DockItem::Placement placement)
92 {
93     _dock_items.push_back(&item);
94     gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement);
96     // FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done
97     // initially as the paned doesn't exist.
98     if (Gtk::Paned *paned = getParentPaned())
99         paned->set_resize_mode(Gtk::RESIZE_QUEUE);
102 Gtk::Widget&
103 Dock::getWidget()
105      return *_scrolled_window;
108 Gtk::Paned *
109 Dock::getParentPaned()
111     g_return_val_if_fail(_dock_box, 0);
112     Gtk::Container *parent = getWidget().get_parent();
113     return (parent != 0 ? dynamic_cast<Gtk::Paned *>(parent) : 0);
117 Gtk::Paned *
118 Dock::getPaned()
120     return _paned;
124 bool
125 Dock::isEmpty() const
127     std::list<const DockItem *>::const_iterator
128         i = _dock_items.begin(),
129         e = _dock_items.end();
131     for (; i != e; ++i)
132         if ((*i)->getState() == DockItem::DOCKED_STATE)
133             return false;
135     return true;
138 bool
139 Dock::hasIconifiedItems() const
141     std::list<const DockItem *>::const_iterator
142         i = _dock_items.begin(),
143         e = _dock_items.end();
145     for (; i != e; ++i)
146         if ((*i)->isIconified())
147             return true;
148     
149     return false;
152 void
153 Dock::hide()
155     getWidget().hide();
158 void 
159 Dock::show()
161     getWidget().show();
164 void
165 Dock::toggleDockable(int width, int height)
167     static int prev_horizontal_position, prev_vertical_position;
169     Gtk::Paned *parent_paned = getParentPaned();
171     if (width > 0 && height > 0) {
172         prev_horizontal_position = parent_paned->get_position();
173         prev_vertical_position = _paned->get_position();
175         if (getWidget().get_width() < width)
176             parent_paned->set_position(parent_paned->get_width() - width);
177         
178         if (_paned->get_position() < height)
179             _paned->set_position(height);
181     } else {
182         parent_paned->set_position(prev_horizontal_position);
183         _paned->set_position(prev_vertical_position);
184     }
188 Glib::SignalProxy0<void>
189 Dock::signal_layout_changed()
191     return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock)), 
192                                     &_signal_layout_changed_proxy);
195 void
196 Dock::_onLayoutChanged()
198     if (isEmpty()) {
200         if (hasIconifiedItems())
201             _scrolled_window->set_size_request(_default_dock_bar_width);
202         else
203             _scrolled_window->set_size_request(_default_empty_width);
205         getParentPaned()->set_position(INT_MAX);
206     } else {
207         _scrolled_window->set_size_request(-1);
208     }
212 const Glib::SignalProxyInfo
213 Dock::_signal_layout_changed_proxy = 
215     "layout-changed",
216     (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
217     (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
218 };
221 } // namespace Widget
222 } // namespace UI
223 } // namespace Inkscape
226 /*
227   Local Variables:
228   mode:c++
229   c-file-style:"stroustrup"
230   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
231   indent-tabs-mode:nil
232   fill-column:99
233   End:
234 */
235 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99