From 731f2b5adbb6f9e9fc853a6506c695fd2fcec320 Mon Sep 17 00:00:00 2001 From: gustav_b Date: Wed, 29 Aug 2007 21:27:07 +0000 Subject: Dockable dialogs patch applied (https://sourceforge.net/tracker/?func=detail&atid=604308&aid=1688508&group_id=93438) (bzr r3613) --- src/ui/widget/dock.cpp | 235 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 src/ui/widget/dock.cpp (limited to 'src/ui/widget/dock.cpp') diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp new file mode 100644 index 000000000..828b70451 --- /dev/null +++ b/src/ui/widget/dock.cpp @@ -0,0 +1,235 @@ +/** + * \brief A desktop dock pane to dock dialogs. + * + * Author: + * Gustav Broberg + * + * Copyright (C) 2007 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "inkscape.h" +#include "desktop.h" + +#include "dock.h" + +namespace Inkscape { +namespace UI { +namespace Widget { + +namespace { + +void hideCallback(GtkObject *object, gpointer dock_ptr) +{ + g_return_if_fail( dock_ptr != NULL ); + + Dock *dock = (Dock *)dock_ptr; + dock->hide(); +} + +void unhideCallback(GtkObject *object, gpointer dock_ptr) +{ + g_return_if_fail( dock_ptr != NULL ); + + Dock *dock = (Dock *)dock_ptr; + dock->show(); +} + +} + +const int Dock::_default_empty_width = 0; +const int Dock::_default_dock_bar_width = 36; + + +Dock::Dock(Gtk::Orientation orientation) + : _gdl_dock (GDL_DOCK (gdl_dock_new())), + _gdl_dock_bar (GDL_DOCK_BAR (gdl_dock_bar_new(GDL_DOCK(_gdl_dock)))), + _scrolled_window (Gtk::manage(new Gtk::ScrolledWindow)) +{ + gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast(orientation)); + + switch (orientation) { + case Gtk::ORIENTATION_VERTICAL: + _dock_box = Gtk::manage(new Gtk::HBox()); + _paned = Gtk::manage(new Gtk::VPaned()); + break; + case Gtk::ORIENTATION_HORIZONTAL: + _dock_box = Gtk::manage(new Gtk::VBox()); + _paned = Gtk::manage(new Gtk::HPaned()); + } + + _scrolled_window->add(*_dock_box); + _scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + _paned->pack1(*Glib::wrap(GTK_WIDGET(_gdl_dock)), false, false); + _paned->pack2(_filler, true, false); + + _dock_box->pack_start(*_paned, Gtk::PACK_EXPAND_WIDGET); + _dock_box->pack_end(*Gtk::manage(Glib::wrap(GTK_WIDGET(_gdl_dock_bar))), Gtk::PACK_SHRINK); + _dock_box->get_parent()->set_resize_mode(Gtk::RESIZE_PARENT); + + _scrolled_window->set_size_request(0); + + g_object_set (GDL_DOCK_OBJECT(_gdl_dock)->master, + "switcher-style", GDL_SWITCHER_STYLE_BOTH, + NULL); + + g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(hideCallback), (void *)this); + g_signal_connect(G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(unhideCallback), (void *)this); + + signal_layout_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::Dock::_onLayoutChanged)); +} + +Dock::~Dock() +{ + g_free(_gdl_dock); + g_free(_gdl_dock_bar); +} + +void +Dock::addItem(DockItem& item, DockItem::Placement placement) +{ + _dock_items.push_back(&item); + gdl_dock_add_item(_gdl_dock, GDL_DOCK_ITEM(item.gobj()), (GdlDockPlacement)placement); + + // FIXME: This is a hack to prevent the dock from expanding the main window, this can't be done + // initially as the paned doesn't exist. + if (Gtk::Paned *paned = getParentPaned()) + paned->set_resize_mode(Gtk::RESIZE_QUEUE); +} + +Gtk::Widget& +Dock::getWidget() +{ + return *_scrolled_window; +} + +Gtk::Paned * +Dock::getParentPaned() +{ + g_return_val_if_fail(_dock_box, 0); + Gtk::Container *parent = getWidget().get_parent(); + return (parent != 0 ? dynamic_cast(parent) : 0); +} + + +Gtk::Paned * +Dock::getPaned() +{ + return _paned; +} + + +bool +Dock::isEmpty() const +{ + std::list::const_iterator + i = _dock_items.begin(), + e = _dock_items.end(); + + for (; i != e; ++i) + if ((*i)->getState() == DockItem::DOCKED_STATE) + return false; + + return true; +} + +bool +Dock::hasIconifiedItems() const +{ + std::list::const_iterator + i = _dock_items.begin(), + e = _dock_items.end(); + + for (; i != e; ++i) + if ((*i)->isIconified()) + return true; + + return false; +} + +void +Dock::hide() +{ + getWidget().hide(); +} + +void +Dock::show() +{ + getWidget().show(); +} + +void +Dock::toggleDockable(int width, int height) +{ + static int prev_horizontal_position, prev_vertical_position; + + Gtk::Paned *parent_paned = getParentPaned(); + + if (width > 0 && height > 0) { + prev_horizontal_position = parent_paned->get_position(); + prev_vertical_position = _paned->get_position(); + + if (getWidget().get_width() < width) + parent_paned->set_position(parent_paned->get_width() - width); + + if (_paned->get_position() < height) + _paned->set_position(height); + + } else { + parent_paned->set_position(prev_horizontal_position); + _paned->set_position(prev_vertical_position); + } + +} + +Glib::SignalProxy0 +Dock::signal_layout_changed() +{ + return Glib::SignalProxy0(Glib::wrap(GTK_WIDGET(_gdl_dock)), + &_signal_layout_changed_proxy); +} + +void +Dock::_onLayoutChanged() +{ + if (isEmpty()) { + + if (hasIconifiedItems()) + _scrolled_window->set_size_request(_default_dock_bar_width); + else + _scrolled_window->set_size_request(_default_empty_width); + + getParentPaned()->set_position(INT_MAX); + } else { + _scrolled_window->set_size_request(-1); + } +} + + +const Glib::SignalProxyInfo +Dock::_signal_layout_changed_proxy = +{ + "layout-changed", + (GCallback) &Glib::SignalProxyNormal::slot0_void_callback, + (GCallback) &Glib::SignalProxyNormal::slot0_void_callback +}; + + +} // namespace Widget +} // namespace UI +} // namespace Inkscape + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 -- cgit v1.2.3