summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorgustav_b <gustav_b@users.sourceforge.net>2007-08-29 21:27:07 +0000
committergustav_b <gustav_b@users.sourceforge.net>2007-08-29 21:27:07 +0000
commit731f2b5adbb6f9e9fc853a6506c695fd2fcec320 (patch)
tree6e7775c500ffc41d1376d7496c9334840b0f065f /src/ui
parentDon't snap node handles to the parent path, plus a small string change (diff)
downloadinkscape-731f2b5adbb6f9e9fc853a6506c695fd2fcec320.tar.gz
inkscape-731f2b5adbb6f9e9fc853a6506c695fd2fcec320.zip
Dockable dialogs patch applied
(https://sourceforge.net/tracker/?func=detail&atid=604308&aid=1688508&group_id=93438) (bzr r3613)
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/dialog/Makefile_insert7
-rw-r--r--src/ui/dialog/align-and-distribute.cpp4
-rw-r--r--src/ui/dialog/align-and-distribute.h5
-rw-r--r--src/ui/dialog/behavior.h108
-rw-r--r--src/ui/dialog/dialog-manager.cpp92
-rw-r--r--src/ui/dialog/dialog.cpp250
-rw-r--r--src/ui/dialog/dialog.h68
-rw-r--r--src/ui/dialog/dock-behavior.cpp308
-rw-r--r--src/ui/dialog/dock-behavior.h119
-rw-r--r--src/ui/dialog/document-metadata.cpp8
-rw-r--r--src/ui/dialog/document-metadata.h4
-rw-r--r--src/ui/dialog/document-properties.cpp8
-rw-r--r--src/ui/dialog/document-properties.h4
-rw-r--r--src/ui/dialog/export.cpp4
-rw-r--r--src/ui/dialog/export.h5
-rw-r--r--src/ui/dialog/extension-editor.cpp4
-rw-r--r--src/ui/dialog/extension-editor.h5
-rw-r--r--src/ui/dialog/fill-and-stroke.cpp4
-rw-r--r--src/ui/dialog/fill-and-stroke.h5
-rw-r--r--src/ui/dialog/filter-effects-dialog.cpp7
-rw-r--r--src/ui/dialog/filter-effects-dialog.h7
-rw-r--r--src/ui/dialog/find.cpp4
-rw-r--r--src/ui/dialog/find.h5
-rw-r--r--src/ui/dialog/floating-behavior.cpp182
-rw-r--r--src/ui/dialog/floating-behavior.h88
-rw-r--r--src/ui/dialog/inkscape-preferences.cpp13
-rw-r--r--src/ui/dialog/inkscape-preferences.h7
-rw-r--r--src/ui/dialog/layer-editor.cpp4
-rw-r--r--src/ui/dialog/layer-editor.h5
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp4
-rw-r--r--src/ui/dialog/livepatheffect-editor.h5
-rw-r--r--src/ui/dialog/memory.cpp4
-rw-r--r--src/ui/dialog/memory.h5
-rw-r--r--src/ui/dialog/messages.cpp4
-rw-r--r--src/ui/dialog/messages.h5
-rw-r--r--src/ui/dialog/scriptdialog.cpp9
-rw-r--r--src/ui/dialog/scriptdialog.h5
-rw-r--r--src/ui/dialog/text-properties.cpp4
-rw-r--r--src/ui/dialog/text-properties.h5
-rw-r--r--src/ui/dialog/tracedialog.cpp9
-rw-r--r--src/ui/dialog/tracedialog.h5
-rw-r--r--src/ui/dialog/transformation.cpp8
-rw-r--r--src/ui/dialog/transformation.h6
-rw-r--r--src/ui/dialog/undo-history.cpp10
-rw-r--r--src/ui/dialog/undo-history.h4
-rw-r--r--src/ui/dialog/xml-editor.cpp4
-rw-r--r--src/ui/dialog/xml-editor.h5
-rw-r--r--src/ui/view/edit-widget-interface.h5
-rw-r--r--src/ui/view/edit-widget.cpp9
-rw-r--r--src/ui/view/edit-widget.h4
-rw-r--r--src/ui/widget/Makefile_insert4
-rw-r--r--src/ui/widget/dock-item.cpp539
-rw-r--r--src/ui/widget/dock-item.h165
-rw-r--r--src/ui/widget/dock.cpp235
-rw-r--r--src/ui/widget/dock.h97
55 files changed, 2227 insertions, 266 deletions
diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert
index d3bb8b62c..6679e99de 100644
--- a/src/ui/dialog/Makefile_insert
+++ b/src/ui/dialog/Makefile_insert
@@ -10,12 +10,17 @@ ui_dialog_libuidialog_a_SOURCES = \
ui/dialog/dialog-manager.h \
ui/dialog/dialog.cpp \
ui/dialog/dialog.h \
+ ui/dialog/behavior.h \
+ ui/dialog/dock-behavior.h \
+ ui/dialog/dock-behavior.cpp \
+ ui/dialog/floating-behavior.h \
+ ui/dialog/floating-behavior.cpp \
ui/dialog/align-and-distribute.cpp \
ui/dialog/align-and-distribute.h \
ui/dialog/document-metadata.cpp \
ui/dialog/document-metadata.h \
ui/dialog/document-properties.cpp \
- ui/dialog/document-properties.h \
+ ui/dialog/document-properties.h \
ui/dialog/export.cpp \
ui/dialog/export.h \
ui/dialog/extension-editor.cpp \
diff --git a/src/ui/dialog/align-and-distribute.cpp b/src/ui/dialog/align-and-distribute.cpp
index 34fa910cc..924a98790 100644
--- a/src/ui/dialog/align-and-distribute.cpp
+++ b/src/ui/dialog/align-and-distribute.cpp
@@ -774,8 +774,8 @@ void on_selection_changed(Inkscape::Application *inkscape, Inkscape::Selection *
-AlignAndDistribute::AlignAndDistribute()
- : Dialog ("dialogs.align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE),
+AlignAndDistribute::AlignAndDistribute(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE),
randomize_bbox(NR::Nothing()),
_alignFrame(_("Align")),
_distributeFrame(_("Distribute")),
diff --git a/src/ui/dialog/align-and-distribute.h b/src/ui/dialog/align-and-distribute.h
index 6d22071f3..0559a11e9 100644
--- a/src/ui/dialog/align-and-distribute.h
+++ b/src/ui/dialog/align-and-distribute.h
@@ -46,10 +46,11 @@ class Action;
class AlignAndDistribute : public Dialog {
public:
- AlignAndDistribute();
+ AlignAndDistribute(Behavior::BehaviorFactory behavior_factory);
virtual ~AlignAndDistribute();
- static AlignAndDistribute *create() { return new AlignAndDistribute(); }
+ static AlignAndDistribute *create(Behavior::BehaviorFactory behavior_factory)
+ { return new AlignAndDistribute(behavior_factory); }
enum AlignTarget { LAST=0, FIRST, BIGGEST, SMALLEST, PAGE, DRAWING, SELECTION };
diff --git a/src/ui/dialog/behavior.h b/src/ui/dialog/behavior.h
new file mode 100644
index 000000000..b7455bbe5
--- /dev/null
+++ b/src/ui/dialog/behavior.h
@@ -0,0 +1,108 @@
+/**
+ * \brief Dialog behavior interface
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_DIALOG_BEHAVIOR_H
+#define INKSCAPE_UI_DIALOG_BEHAVIOR_H
+
+#include <gtkmm/button.h>
+#include <gtkmm/box.h>
+
+class SPDesktop;
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+
+class Dialog;
+
+namespace Behavior {
+
+class Behavior;
+
+typedef Behavior *(*BehaviorFactory)(Dialog& dialog);
+
+template <typename T>
+Behavior *create(Dialog& dialog)
+{
+ return T::create(dialog);
+}
+
+
+class Behavior {
+
+public:
+ virtual ~Behavior() { }
+
+ /** Gtk::Dialog methods */
+ virtual operator Gtk::Widget&() =0;
+ virtual GtkWidget *gobj() =0;
+ virtual void present() =0;
+ virtual Gtk::VBox *get_vbox() =0;
+ virtual void show() =0;
+ virtual void hide() =0;
+ virtual void show_all_children() =0;
+ virtual void resize(int width, int height) =0;
+ virtual void move(int x, int y) =0;
+ virtual void set_position(Gtk::WindowPosition) =0;
+ virtual void set_size_request(int width, int height) =0;
+ virtual void size_request(Gtk::Requisition& requisition) =0;
+ virtual void get_position(int& x, int& y) =0;
+ virtual void get_size(int& width, int& height) =0;
+ virtual void set_title(Glib::ustring title) =0;
+ virtual void set_response_sensitive(int response_id, bool setting) =0;
+ virtual void set_sensitive(bool sensitive) =0;
+ virtual Gtk::Button *add_button(const Glib::ustring& button_text, int response_id) =0;
+ virtual Gtk::Button *add_button(const Gtk::StockID& stock_id, int response_id) =0;
+ virtual void set_default_response(int response_id) =0;
+
+ /** Gtk::Dialog signal proxies */
+ virtual Glib::SignalProxy0<void> signal_show() =0;
+ virtual Glib::SignalProxy0<void> signal_hide() =0;
+ virtual Glib::SignalProxy1<bool, GdkEventAny *> signal_delete_event() =0;
+ virtual Glib::SignalProxy1<void, int> signal_response() =0;
+
+ /** Custom signal handlers */
+ virtual void onHideF12() =0;
+ virtual void onShowF12() =0;
+ virtual void onShutdown() =0;
+ virtual void onDesktopActivated(SPDesktop *desktop) =0;
+
+protected:
+ Behavior(Dialog& dialog)
+ : _dialog (dialog)
+ { }
+
+ Dialog& _dialog; //< reference to the owner
+
+private:
+ Behavior(); // no constructor without params
+ Behavior(const Behavior&); // no copy
+ Behavior& operator=(const Behavior&); // no assign
+};
+
+} // namespace Behavior
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+
+#endif //INKSCAPE_UI_DIALOG_BEHAVIOR_H
+
+/*
+ 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 :
diff --git a/src/ui/dialog/dialog-manager.cpp b/src/ui/dialog/dialog-manager.cpp
index 23c64f1d5..e5d326efe 100644
--- a/src/ui/dialog/dialog-manager.cpp
+++ b/src/ui/dialog/dialog-manager.cpp
@@ -2,11 +2,12 @@
* \brief Object for managing a set of dialogs, including their signals and
* construction/caching/destruction of them.
*
- * Author:
+ * Authors:
* Bryce W. Harrington <bryce@bryceharrington.org>
* Jon Phillips <jon@rejon.org>
+ * Gustav Broberg <broberg@kth.se>
*
- * Copyright (C) 2004, 2005 Authors
+ * Copyright (C) 2004--2007 Authors
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -37,7 +38,12 @@
#include "ui/dialog/undo-history.h"
#include "ui/dialog/xml-editor.h"
+#include "dialogs/layers-panel.h"
#include "dialogs/tiledialog.h"
+#include "dialogs/iconpreview.h"
+
+#include "ui/dialog/floating-behavior.h"
+#include "ui/dialog/dock-behavior.h"
namespace Inkscape {
namespace UI {
@@ -45,8 +51,8 @@ namespace Dialog {
namespace {
-template <typename T>
-Dialog *create() { return T::create(); }
+template <typename T, typename B>
+inline Dialog *create() { return T::create(&B::create); }
}
@@ -71,26 +77,63 @@ Dialog *create() { return T::create(); }
*
*/
DialogManager::DialogManager() {
- registerFactory("AlignAndDistribute", &create<AlignAndDistribute>);
- registerFactory("DocumentMetadata", &create<DocumentMetadata>);
- registerFactory("DocumentProperties", &create<DocumentProperties>);
- registerFactory("Export", &create<Export>);
- registerFactory("ExtensionEditor", &create<ExtensionEditor>);
- registerFactory("FillAndStroke", &create<FillAndStroke>);
- registerFactory("FilterEffectsDialog", &create<FilterEffectsDialog>);
- registerFactory("Find", &create<Find>);
- registerFactory("InkscapePreferences", &create<InkscapePreferences>);
- registerFactory("LayerEditor", &create<LayerEditor>);
- registerFactory("LivePathEffect", &create<LivePathEffectEditor>);
- registerFactory("Memory", &create<Memory>);
- registerFactory("Messages", &create<Messages>);
- registerFactory("Script", &create<ScriptDialog>);
- registerFactory("TextProperties", &create<TextProperties>);
- registerFactory("TileDialog", &create<TileDialog>);
- registerFactory("Trace", &create<TraceDialog>);
- registerFactory("Transformation", &create<Transformation>);
- registerFactory("UndoHistory", &create<UndoHistory>);
- registerFactory("XmlEditor", &create<XmlEditor>);
+
+ using namespace Behavior;
+ using namespace Inkscape::UI::Dialogs; // temporary
+
+ int dialogs_type = prefs_get_int_attribute_limited ("options.dialogtype", "value", DOCK, 0, 1);
+
+ if (dialogs_type == FLOATING) {
+
+ registerFactory("AlignAndDistribute", &create<AlignAndDistribute, FloatingBehavior>);
+ registerFactory("DocumentMetadata", &create<DocumentMetadata, FloatingBehavior>);
+ registerFactory("DocumentProperties", &create<DocumentProperties, FloatingBehavior>);
+ registerFactory("Export", &create<Export, FloatingBehavior>);
+ registerFactory("ExtensionEditor", &create<ExtensionEditor, FloatingBehavior>);
+ registerFactory("FillAndStroke", &create<FillAndStroke, FloatingBehavior>);
+ registerFactory("FilterEffectsDialog", &create<FilterEffectsDialog, FloatingBehavior>);
+ registerFactory("Find", &create<Find, FloatingBehavior>);
+ registerFactory("IconPreviewPanel", &create<IconPreviewPanel, FloatingBehavior>);
+ registerFactory("InkscapePreferences", &create<InkscapePreferences, FloatingBehavior>);
+ registerFactory("LayerEditor", &create<LayerEditor, FloatingBehavior>);
+ registerFactory("LayersPanel", &create<LayersPanel, FloatingBehavior>);
+ registerFactory("LivePathEffect", &create<LivePathEffectEditor, FloatingBehavior>);
+ registerFactory("Memory", &create<Memory, FloatingBehavior>);
+ registerFactory("Messages", &create<Messages, FloatingBehavior>);
+ registerFactory("Script", &create<ScriptDialog, FloatingBehavior>);
+ registerFactory("TextProperties", &create<TextProperties, FloatingBehavior>);
+ registerFactory("TileDialog", &create<TileDialog, FloatingBehavior>);
+ registerFactory("Trace", &create<TraceDialog, FloatingBehavior>);
+ registerFactory("Transformation", &create<Transformation, FloatingBehavior>);
+ registerFactory("UndoHistory", &create<UndoHistory, FloatingBehavior>);
+ registerFactory("XmlEditor", &create<XmlEditor, FloatingBehavior>);
+
+ } else {
+
+ registerFactory("AlignAndDistribute", &create<AlignAndDistribute, DockBehavior>);
+ registerFactory("DocumentMetadata", &create<DocumentMetadata, DockBehavior>);
+ registerFactory("DocumentProperties", &create<DocumentProperties, DockBehavior>);
+ registerFactory("Export", &create<Export, DockBehavior>);
+ registerFactory("ExtensionEditor", &create<ExtensionEditor, DockBehavior>);
+ registerFactory("FillAndStroke", &create<FillAndStroke, DockBehavior>);
+ registerFactory("FilterEffectsDialog", &create<FilterEffectsDialog, DockBehavior>);
+ registerFactory("Find", &create<Find, DockBehavior>);
+ registerFactory("IconPreviewPanel", &create<IconPreviewPanel, DockBehavior>);
+ registerFactory("InkscapePreferences", &create<InkscapePreferences, DockBehavior>);
+ registerFactory("LayerEditor", &create<LayerEditor, DockBehavior>);
+ registerFactory("LayersPanel", &create<LayersPanel, DockBehavior>);
+ registerFactory("LivePathEffect", &create<LivePathEffectEditor, DockBehavior>);
+ registerFactory("Memory", &create<Memory, DockBehavior>);
+ registerFactory("Messages", &create<Messages, DockBehavior>);
+ registerFactory("Script", &create<ScriptDialog, DockBehavior>);
+ registerFactory("TextProperties", &create<TextProperties, DockBehavior>);
+ registerFactory("TileDialog", &create<TileDialog, DockBehavior>);
+ registerFactory("Trace", &create<TraceDialog, DockBehavior>);
+ registerFactory("Transformation", &create<Transformation, DockBehavior>);
+ registerFactory("UndoHistory", &create<UndoHistory, DockBehavior>);
+ registerFactory("XmlEditor", &create<XmlEditor, DockBehavior>);
+
+ }
}
DialogManager::~DialogManager() {
@@ -163,7 +206,6 @@ void DialogManager::showDialog(GQuark name) {
Dialog *dialog=getDialog(name);
if (dialog) {
dialog->present();
- dialog->read_geometry();
}
}
diff --git a/src/ui/dialog/dialog.cpp b/src/ui/dialog/dialog.cpp
index ac147d656..16124d9f5 100644
--- a/src/ui/dialog/dialog.cpp
+++ b/src/ui/dialog/dialog.cpp
@@ -2,12 +2,13 @@
* \brief Base class for dialogs in Inkscape. This class provides certain
* common behaviors and styles wanted of all dialogs in the application.
*
- * Author:
+ * Authors:
* Bryce W. Harrington <bryce@bryceharrington.org>
* buliabyak@gmail.com
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ * Gustav Broberg <broberg@kth.se>
*
- * Copyright (C) 2004-2007 Authors
+ * Copyright (C) 2004--2007 Authors
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -32,23 +33,13 @@
#include "interface.h"
#include "verbs.h"
-
#define MIN_ONSCREEN_DISTANCE 50
-
namespace Inkscape {
namespace UI {
namespace Dialog {
-static gboolean
-sp_retransientize_again (gpointer dlgPtr)
-{
- Dialog *dlg = (Dialog *)dlgPtr;
- dlg->retransientize_suppress = false;
- return FALSE; // so that it is only called once
-}
-
static void
sp_retransientize (Inkscape::Application *inkscape, SPDesktop *desktop, gpointer dlgPtr)
{
@@ -63,13 +54,6 @@ sp_dialog_shutdown (GtkObject *object, gpointer dlgPtr)
dlg->onShutdown();
}
-void
-Dialog::present()
-{
- _user_hidden = false;
- Gtk::Dialog::present();
-}
-
void
Dialog::save_geometry()
{
@@ -78,7 +62,7 @@ Dialog::save_geometry()
get_position(x, y);
get_size(w, h);
-// g_print ("write %d %d %d %d\n", x, y, w, h);
+ // g_print ("write %d %d %d %d\n", x, y, w, h);
if (x<0) x=0;
if (y<0) y=0;
@@ -87,8 +71,27 @@ Dialog::save_geometry()
prefs_set_int_attribute (_prefs_path, "y", y);
prefs_set_int_attribute (_prefs_path, "w", w);
prefs_set_int_attribute (_prefs_path, "h", h);
+
}
+void hideCallback(GtkObject *object, gpointer dlgPtr)
+{
+ g_return_if_fail( dlgPtr != NULL );
+
+ Dialog *dlg = (Dialog *)dlgPtr;
+ dlg->onHideF12();
+}
+
+void unhideCallback(GtkObject *object, gpointer dlgPtr)
+{
+ g_return_if_fail( dlgPtr != NULL );
+
+ Dialog *dlg = (Dialog *)dlgPtr;
+ dlg->onShowF12();
+}
+
+
+
void
Dialog::read_geometry()
{
@@ -99,12 +102,12 @@ Dialog::read_geometry()
int w = prefs_get_int_attribute (_prefs_path, "w", 0);
int h = prefs_get_int_attribute (_prefs_path, "h", 0);
-// g_print ("read %d %d %d %d\n", x, y, w, h);
+ // g_print ("read %d %d %d %d\n", x, y, w, h);
// If there are stored height and width values for the dialog,
// resize the window to match; otherwise we leave it at its default
if (w != 0 && h != 0) {
- resize (w, h);
+ resize(w, h);
}
// If there are stored values for where the dialog should be
@@ -116,22 +119,47 @@ Dialog::read_geometry()
// ...otherwise just put it in the middle of the screen
set_position(Gtk::WIN_POS_CENTER);
}
-}
-
-void hideCallback(GtkObject *object, gpointer dlgPtr)
-{
- g_return_if_fail( dlgPtr != NULL );
- Dialog *dlg = (Dialog *)dlgPtr;
- dlg->onHideF12();
}
-void unhideCallback(GtkObject *object, gpointer dlgPtr)
+inline Dialog::operator Gtk::Widget&() { return *_behavior; }
+inline GtkWidget *Dialog::gobj() { return _behavior->gobj(); }
+inline void Dialog::present() { _behavior->present(); }
+inline Gtk::VBox *Dialog::get_vbox() { return _behavior->get_vbox(); }
+inline void Dialog::show_all_children() { _behavior->show_all_children(); }
+inline void Dialog::hide() { _behavior->hide(); }
+inline void Dialog::show() { _behavior->show(); }
+inline void Dialog::set_size_request(int width, int height) { _behavior->set_size_request(width, height); }
+inline void Dialog::size_request(Gtk::Requisition& requisition) { _behavior->size_request(requisition); }
+inline void Dialog::get_position(int& x, int& y) { _behavior->get_position(x, y); }
+inline void Dialog::get_size(int& width, int& height) { _behavior->get_size(width, height); }
+inline void Dialog::resize(int width, int height) { _behavior->resize(width, height); }
+inline void Dialog::move(int x, int y) { _behavior->move(x, y); }
+inline void Dialog::set_position(Gtk::WindowPosition position) { _behavior->set_position(position); }
+inline void Dialog::set_title(Glib::ustring title) { _behavior->set_title(title); }
+inline void Dialog::set_sensitive(bool sensitive) { _behavior->set_sensitive(sensitive); }
+
+inline void Dialog::set_response_sensitive(int response_id, bool setting)
+{ _behavior->set_response_sensitive(response_id, setting); }
+
+void Dialog::set_resizable(bool) { }
+void Dialog::set_default(Gtk::Widget&) { }
+
+inline void Dialog::set_default_response(int response_id) { _behavior->set_default_response(response_id); }
+
+Glib::SignalProxy0<void> Dialog::signal_show () { return _behavior->signal_show(); }
+Glib::SignalProxy0<void> Dialog::signal_hide () { return _behavior->signal_hide(); }
+Glib::SignalProxy1<void, int> Dialog::signal_response () { return _behavior->signal_response(); }
+
+Gtk::Button* Dialog::add_button (const Glib::ustring& button_text, int response_id)
+{ return _behavior->add_button(button_text, response_id); }
+
+Gtk::Button* Dialog::add_button (const Gtk::StockID& stock_id, int response_id)
+{ return _behavior->add_button(stock_id, response_id); }
+
+Dialog::Dialog(const char *prefs_path, int verb_num, const char *apply_label)
{
- g_return_if_fail( dlgPtr != NULL );
- Dialog *dlg = (Dialog *)dlgPtr;
- dlg->onShowF12();
}
//=====================================================================
@@ -146,34 +174,24 @@ void unhideCallback(GtkObject *object, gpointer dlgPtr)
* It also provides some general purpose signal handlers for things like
* showing and hiding all dialogs.
*/
-Dialog::Dialog(const char *prefs_path, int verb_num, const char *apply_label)
+Dialog::Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_path, int verb_num,
+ const char *apply_label)
+ : _hiddenF12 (false),
+ _prefs_path (prefs_path),
+ _verb_num(verb_num),
+ _apply_label (apply_label)
{
- hide();
- set_has_separator(false);
-
- _prefs_path = prefs_path;
-
- if (prefs_get_int_attribute ("dialogs", "showclose", 0) || apply_label) {
- // TODO: make the order of buttons obey the global preference
- if (apply_label) {
- add_button(Glib::ustring(apply_label), Gtk::RESPONSE_APPLY);
- set_default_response(Gtk::RESPONSE_APPLY);
- }
- add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
- }
-
- GtkWidget *dlg = GTK_WIDGET(gobj());
+ gchar title[500];
if (verb_num)
- {
- gchar title[500];
sp_ui_dialog_title_string (Inkscape::Verb::get(verb_num), title);
- set_title(title);
- }
- gtk_signal_connect( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC(sp_dialog_event_handler), dlg );
+ _title = title;
+
+ _behavior = behavior_factory(*this);
+
+ gtk_signal_connect( GTK_OBJECT (gobj()), "event", GTK_SIGNAL_FUNC(sp_dialog_event_handler), gobj() );
- _hiddenF12 = false;
if (Inkscape::NSApplication::Application::getNewGui())
{
_desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::mem_fun (*this, &Dialog::onDesktopActivated));
@@ -183,23 +201,25 @@ Dialog::Dialog(const char *prefs_path, int verb_num, const char *apply_label)
}
else
{
- g_signal_connect (G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_retransientize), (void *)this);
- 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 );
- g_signal_connect (G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_dialog_shutdown), (void *)this);
+ g_signal_connect (G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_retransientize), (void *)this);
+ 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 );
+ g_signal_connect (G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_dialog_shutdown), (void *)this);
}
- g_signal_connect_after( gobj(), "key_press_event", (GCallback)windowKeyPress, NULL );
+ Glib::wrap(gobj())->signal_key_press_event().connect(sigc::ptr_fun(&windowKeyPress));
+
+ if (prefs_get_int_attribute ("dialogs", "showclose", 0) || apply_label) {
+ // TODO: make the order of buttons obey the global preference
+ if (apply_label) {
+ add_button(Glib::ustring(apply_label), Gtk::RESPONSE_APPLY);
+ set_default_response(Gtk::RESPONSE_APPLY);
+ }
+ add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
+ }
read_geometry();
present();
- sp_transientize(dlg);
- retransientize_suppress = false;
-}
-
-Dialog::Dialog(BaseObjectType *gobj)
- : Gtk::Dialog(gobj)
-{
}
Dialog::~Dialog()
@@ -213,10 +233,11 @@ Dialog::~Dialog()
}
save_geometry();
+ delete _behavior;
}
-bool Dialog::windowKeyPress( GtkWidget *widget, GdkEventKey *event )
+bool Dialog::windowKeyPress(GdkEventKey *event)
{
unsigned int shortcut = 0;
shortcut = get_group0_keyval (event) |
@@ -226,6 +247,7 @@ bool Dialog::windowKeyPress( GtkWidget *widget, GdkEventKey *event )
SP_SHORTCUT_CONTROL_MASK : 0 ) |
( event->state & GDK_MOD1_MASK ?
SP_SHORTCUT_ALT_MASK : 0 );
+
return sp_shortcut_invoke( shortcut, SP_ACTIVE_DESKTOP );
}
@@ -259,8 +281,7 @@ void
Dialog::onHideF12()
{
_hiddenF12 = true;
- save_geometry();
- hide();
+ _behavior->onHideF12();
}
void
@@ -270,8 +291,7 @@ Dialog::onShowF12()
return;
if (_hiddenF12) {
- show();
- read_geometry();
+ _behavior->onShowF12();
}
_hiddenF12 = false;
@@ -282,61 +302,15 @@ Dialog::onShutdown()
{
save_geometry();
_user_hidden = true;
+ _behavior->onShutdown();
}
void
-Dialog::onDesktopActivated (SPDesktop *desktop)
+Dialog::onDesktopActivated(SPDesktop *desktop)
{
- gint transient_policy = prefs_get_int_attribute_limited ( "options.transientpolicy", "value", 1, 0, 2);
-
-#ifdef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs
- if (prefs_get_int_attribute ( "options.dialogsontopwin32", "value", 0))
- transient_policy = 2;
- else
- return;
-#endif
-
- if (!transient_policy)
- return;
-
-
-
- GtkWindow *dialog_win = GTK_WINDOW(gobj());
-
- if (retransientize_suppress) {
- /* if retransientizing of this dialog is still forbidden after
- * previous call warning turned off because it was confusingly fired
- * when loading many files from command line
- */
-
- // g_warning("Retranzientize aborted! You're switching windows too fast!");
- return;
- }
-
- if (dialog_win)
- {
- retransientize_suppress = true; // disallow other attempts to retranzientize this dialog
-
- desktop->setWindowTransient (dialog_win);
-
- /*
- * This enables "aggressive" transientization,
- * i.e. dialogs always emerging on top when you switch documents. Note
- * however that this breaks "click to raise" policy of a window
- * manager because the switched-to document will be raised at once
- * (so that its transients also could raise)
- */
- if (transient_policy == 2 && !_hiddenF12 && !_user_hidden) {
- // without this, a transient window not always emerges on top
- gtk_window_present (dialog_win);
- }
- }
-
- // we're done, allow next retransientizing not sooner than after 120 msec
- gtk_timeout_add (120, (GtkFunction) sp_retransientize_again, (gpointer) this);
+ _behavior->onDesktopActivated(desktop);
}
-
Inkscape::Selection*
Dialog::_getSelection()
{
@@ -352,20 +326,26 @@ Dialog::_apply()
void
Dialog::_close()
{
- GtkWidget *dlg = GTK_WIDGET(gobj());
-
- /* this code sends a delete_event to the dialog,
- * instead of just destroying it, so that the
- * dialog can do some housekeeping, such as remember
- * its position.
- */
- GdkEventAny event;
- event.type = GDK_DELETE;
- event.window = dlg->window;
- event.send_event = TRUE;
- g_object_ref (G_OBJECT (event.window));
- gtk_main_do_event ((GdkEvent*)&event);
- g_object_unref (G_OBJECT (event.window));
+ GtkWidget *dlg = GTK_WIDGET(_behavior->gobj());
+
+ /* this code sends a delete_event to the dialog,
+ * instead of just destroying it, so that the
+ * dialog can do some housekeeping, such as remember
+ * its position.
+ */
+
+ GdkEventAny event;
+ event.type = GDK_DELETE;
+ event.window = dlg->window;
+ event.send_event = TRUE;
+
+ if (event.window)
+ g_object_ref (G_OBJECT (event.window));
+
+ gtk_main_do_event ((GdkEvent*)&event);
+
+ if (event.window)
+ g_object_unref (G_OBJECT (event.window));
}
} // namespace Dialog
diff --git a/src/ui/dialog/dialog.h b/src/ui/dialog/dialog.h
index dd3cdaafe..7530b9a35 100644
--- a/src/ui/dialog/dialog.h
+++ b/src/ui/dialog/dialog.h
@@ -1,11 +1,13 @@
/**
- * \brief Base class for dialogs in Inkscape. This class provides certain
- * common behaviors and styles wanted of all dialogs in the application.
+ * \brief Base class for dialogs in Inkscape. This class provides certain common behaviors and
+ * styles wanted of all dialogs in the application. Fundamental parts of the dialog's
+ * behavior is controlled by a Dialog::Behavior subclass instance connected to the dialog.
*
* Author:
* Bryce W. Harrington <bryce@bryceharrington.org>
+ * Gustav Broberg <broberg@kth.se>
*
- * Copyright (C) 2004, 2005 Authors
+ * Copyright (C) 2004--2007 Authors
*
* Released under GNU GPL. Read the file 'COPYING' for more information.
*/
@@ -16,6 +18,9 @@
#include <gtkmm/dialog.h>
#include <gtkmm/tooltips.h>
+#include "dock-behavior.h"
+#include "floating-behavior.h"
+
namespace Inkscape { class Selection; }
class SPDesktop;
@@ -23,11 +28,15 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-class Dialog : public Gtk::Dialog {
+enum BehaviorType { FLOATING, DOCK };
+
+class Dialog {
public:
- Dialog(BaseObjectType *gobj); // fixme: remove this
- Dialog(const char *prefs_path, int verb_num = 0, const char *apply_label = NULL);
+ Dialog(const char *prefs_path = NULL, int verb_num = 0, const char *apply_label = NULL);
+
+ Dialog(Behavior::BehaviorFactory behavior_factory, const char *prefs_path = NULL,
+ int verb_num = 0, const char *apply_label = NULL);
virtual ~Dialog();
@@ -37,20 +46,50 @@ public:
virtual void present();
/** Hide and show dialogs */
- virtual void onHideF12();
- virtual void onShowF12();
+ virtual void onHideF12();
+ virtual void onShowF12();
+
+ virtual operator Gtk::Widget&();
+ virtual GtkWidget *gobj();
+ virtual Gtk::VBox *get_vbox();
+ virtual void show();
+ virtual void hide();
+ virtual void show_all_children();
+ virtual void set_resizable(bool);
+ virtual void set_sensitive(bool sensitive=true);
+ virtual void set_default(Gtk::Widget&);
+ virtual void set_size_request(int, int);
+ virtual void size_request(Gtk::Requisition&);
+ virtual void get_position(int& x, int& y);
+ virtual void get_size(int& width, int& height);
+ virtual void resize(int width, int height);
+ virtual void move(int x, int y);
+ virtual void set_position(Gtk::WindowPosition position);
+ virtual void set_title(Glib::ustring title);
+
+ virtual void set_response_sensitive(int response_id, bool setting);
+ virtual Glib::SignalProxy0<void> signal_show();
+ virtual Glib::SignalProxy0<void> signal_hide();
+ virtual Glib::SignalProxy1<void, int> signal_response();
+
+ virtual Gtk::Button* add_button (const Glib::ustring& button_text, int response_id);
+ virtual Gtk::Button* add_button (const Gtk::StockID& stock_id, int response_id);
+
+ virtual void set_default_response(int response_id);
- bool _hiddenF12;
bool _user_hidden; // when it is closed by the user, to prevent repopping on f12
+ bool _hiddenF12;
void read_geometry();
void save_geometry();
- const char *_prefs_path;
-
bool retransientize_suppress; // when true, do not retransientize (prevents races when switching new windows too fast)
protected:
+ const char *_prefs_path;
+ int _verb_num;
+ Glib::ustring _title;
+ const char *_apply_label;
/**
* Tooltips object for all descendants to use
@@ -62,7 +101,7 @@ protected:
virtual void _apply();
virtual void _close();
- static bool windowKeyPress( GtkWidget *widget, GdkEventKey *event );
+ static bool windowKeyPress(GdkEventKey *event);
Inkscape::Selection* _getSelection();
@@ -72,10 +111,15 @@ protected:
sigc::connection _shutdown_connection;
private:
+ Behavior::Behavior* _behavior;
+
Dialog(); // no constructor without params
Dialog(Dialog const &d); // no copy
Dialog& operator=(Dialog const &d); // no assign
+
+ friend class Behavior::FloatingBehavior;
+ friend class Behavior::DockBehavior;
};
} // namespace Dialog
diff --git a/src/ui/dialog/dock-behavior.cpp b/src/ui/dialog/dock-behavior.cpp
new file mode 100644
index 000000000..188fc6fb1
--- /dev/null
+++ b/src/ui/dialog/dock-behavior.cpp
@@ -0,0 +1,308 @@
+/**
+ * \brief A dockable dialog implementation.
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "dock-behavior.h"
+#include "inkscape.h"
+#include "desktop.h"
+#include "interface.h"
+#include "widgets/icon.h"
+#include "ui/widget/dock.h"
+#include "verbs.h"
+#include "dialog.h"
+#include "prefs-utils.h"
+
+#include <gtkmm/invisible.h>
+#include <gtkmm/label.h>
+#include <gtkmm/stock.h>
+
+#include <gtk/gtk.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+namespace Behavior {
+
+
+DockBehavior::DockBehavior(Dialog& dialog) :
+ Behavior(dialog),
+ _dock_item(*SP_ACTIVE_DESKTOP->getDock(),
+ Inkscape::Verb::get(dialog._verb_num)->get_id(), dialog._title.c_str(),
+ (Inkscape::Verb::get(dialog._verb_num)->get_image() ?
+ Inkscape::Verb::get(dialog._verb_num)->get_image() : ""),
+ static_cast<Widget::DockItem::State>(
+ prefs_get_int_attribute (_dialog._prefs_path, "state",
+ UI::Widget::DockItem::DOCKED_STATE)))
+{
+ // Connect signals
+ _signal_hide_connection = signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::Behavior::DockBehavior::_onHide));
+ signal_response().connect(sigc::mem_fun(_dialog, &Inkscape::UI::Dialog::Dialog::on_response));
+ signal_drag_end().connect(sigc::mem_fun(*this, &Inkscape::UI::Dialog::Behavior::DockBehavior::_onDragEnd));
+}
+
+DockBehavior::~DockBehavior()
+{
+}
+
+
+Behavior *
+DockBehavior::create(Dialog& dialog)
+{
+ return new DockBehavior(dialog);
+}
+
+
+DockBehavior::operator Gtk::Widget&()
+{
+ return _dock_item.getWidget();
+}
+
+GtkWidget *
+DockBehavior::gobj()
+{
+ return _dock_item.gobj();
+}
+
+Gtk::VBox *
+DockBehavior::get_vbox()
+{
+ return _dock_item.get_vbox();
+}
+
+void
+DockBehavior::present()
+{
+ bool was_attached = _dock_item.isAttached();
+
+ _dock_item.present();
+
+ if (!was_attached)
+ _dialog.read_geometry();
+}
+
+void
+DockBehavior::hide()
+{
+ _signal_hide_connection.block();
+ _dock_item.hide();
+ _signal_hide_connection.unblock();
+}
+
+void
+DockBehavior::show()
+{
+ _dock_item.show();
+}
+
+void
+DockBehavior::show_all_children()
+{
+ get_vbox()->show_all_children();
+}
+
+void
+DockBehavior::get_position(int& x, int& y)
+{
+ _dock_item.get_position(x, y);
+}
+
+void
+DockBehavior::get_size(int& width, int& height)
+{
+ _dock_item.get_size(width, height);
+}
+
+void
+DockBehavior::resize(int width, int height)
+{
+ _dock_item.resize(width, height);
+}
+
+void
+DockBehavior::move(int x, int y)
+{
+ _dock_item.move(x, y);
+}
+
+void
+DockBehavior::set_position(Gtk::WindowPosition position)
+{
+ _dock_item.set_position(position);
+}
+
+void
+DockBehavior::set_size_request(int width, int height)
+{
+ _dock_item.set_size_request(width, height);
+}
+
+void
+DockBehavior::size_request(Gtk::Requisition& requisition)
+{
+ _dock_item.size_request(requisition);
+}
+
+void
+DockBehavior::set_title(Glib::ustring title)
+{
+ _dock_item.set_title(title);
+}
+
+void
+DockBehavior::set_response_sensitive(int response_id, bool setting)
+{
+ if (_response_map[response_id])
+ _response_map[response_id]->set_sensitive(setting);
+}
+
+void
+DockBehavior::set_sensitive(bool sensitive)
+{
+ get_vbox()->set_sensitive();
+}
+
+Gtk::Button *
+DockBehavior::add_button(const Glib::ustring& button_text, int response_id)
+{
+ Gtk::Button *button = new Gtk::Button(button_text);
+ _addButton(button, response_id);
+ return button;
+}
+
+Gtk::Button *
+DockBehavior::add_button(const Gtk::StockID& stock_id, int response_id)
+{
+ Gtk::Button *button = new Gtk::Button(stock_id);
+ _addButton(button, response_id);
+ return button;
+}
+
+void
+DockBehavior::_addButton(Gtk::Button *button, int response_id)
+{
+ _dock_item.addButton(button, response_id);
+
+ if (response_id != 0) {
+
+ /* Pass the signal_clicked signals onto a our own signal handler that can re-emit them as
+ * signal_response signals
+ */
+ button->signal_clicked().connect(
+ sigc::bind<int>(sigc::mem_fun(*this,
+ &Inkscape::UI::Dialog::Behavior::DockBehavior::_onResponse),
+ response_id));
+
+ _response_map[response_id] = button;
+ }
+}
+
+void
+DockBehavior::set_default_response(int response_id)
+{
+ ResponseMap::iterator widget_found;
+ widget_found = _response_map.find(response_id);
+
+ if (widget_found != _response_map.end()) {
+ widget_found->second->activate();
+ widget_found->second->property_can_default() = true;
+ widget_found->second->grab_default();
+ }
+}
+
+
+void
+DockBehavior::_onHide()
+{
+ _dialog.save_geometry();
+ prefs_set_int_attribute (_dialog._prefs_path, "state", _dock_item.getPrevState());
+}
+
+void
+DockBehavior::_onDragEnd(bool)
+{
+ Widget::DockItem::State prev_state = _dock_item.getPrevState(), state = _dock_item.getState();
+
+ if (prev_state != state) {
+ prefs_set_int_attribute (_dialog._prefs_path, "state", state);
+ }
+}
+
+void
+DockBehavior::_onResponse(int response_id)
+{
+ g_signal_emit_by_name (_dock_item.gobj(), "signal_response", response_id);
+}
+
+void
+DockBehavior::onHideF12()
+{
+ _dialog.save_geometry();
+ hide();
+}
+
+void
+DockBehavior::onShowF12()
+{
+ present();
+}
+
+void
+DockBehavior::onShutdown()
+{
+ prefs_set_int_attribute (_dialog._prefs_path, "state", _dock_item.getPrevState());
+}
+
+void
+DockBehavior::onDesktopActivated(SPDesktop *desktop)
+{
+}
+
+
+/* Signal wrappers */
+
+Glib::SignalProxy0<void>
+DockBehavior::signal_show() { return _dock_item.signal_show(); }
+
+Glib::SignalProxy0<void>
+DockBehavior::signal_hide() { return _dock_item.signal_hide(); }
+
+Glib::SignalProxy1<void, int>
+DockBehavior::signal_response() { return _dock_item.signal_response(); }
+
+Glib::SignalProxy1<bool, GdkEventAny *>
+DockBehavior::signal_delete_event() { return _dock_item.signal_delete_event(); }
+
+Glib::SignalProxy0<void>
+DockBehavior::signal_drag_begin() { return _dock_item.signal_drag_begin(); }
+
+Glib::SignalProxy1<void, bool>
+DockBehavior::signal_drag_end() { return _dock_item.signal_drag_end(); }
+
+
+} // namespace Behavior
+} // namespace Dialog
+} // 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 :
diff --git a/src/ui/dialog/dock-behavior.h b/src/ui/dialog/dock-behavior.h
new file mode 100644
index 000000000..75bd14be4
--- /dev/null
+++ b/src/ui/dialog/dock-behavior.h
@@ -0,0 +1,119 @@
+/**
+ * \brief A dockable dialog implementation.
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+
+#ifndef INKSCAPE_UI_DIALOG_DOCK_BEHAVIOR_H
+#define INKSCAPE_UI_DIALOG_DOCK_BEHAVIOR_H
+
+#include <map>
+
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/paned.h>
+
+#include "ui/widget/dock-item.h"
+
+#include "libgdl/libgdl.h"
+
+#include "behavior.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+namespace Behavior {
+
+class DockBehavior : public Behavior {
+
+public:
+ static Behavior *create(Dialog& dialog);
+
+ ~DockBehavior();
+
+ /** Gtk::Dialog methods */
+ operator Gtk::Widget&();
+ GtkWidget *gobj();
+ void present();
+ Gtk::VBox *get_vbox();
+ void show();
+ void hide();
+ void show_all_children();
+ void resize(int width, int height);
+ void move(int x, int y);
+ void set_position(Gtk::WindowPosition);
+ void set_size_request(int width, int height);
+ void size_request(Gtk::Requisition& requisition);
+ void get_position(int& x, int& y);
+ void get_size(int& width, int& height);
+ void set_title(Glib::ustring title);
+ void set_response_sensitive(int response_id, bool setting);
+ void set_sensitive(bool sensitive);
+ Gtk::Button *add_button(const Glib::ustring& button_text, int response_id);
+ Gtk::Button *add_button(const Gtk::StockID& stock_id, int response_id);
+ void set_default_response(int response_id);
+
+ /** Gtk::Dialog signal proxies */
+ Glib::SignalProxy0<void> signal_show();
+ Glib::SignalProxy0<void> signal_hide();
+ Glib::SignalProxy1<bool, GdkEventAny *> signal_delete_event();
+ Glib::SignalProxy0<void> signal_drag_begin();
+ Glib::SignalProxy1<void, bool> signal_drag_end();
+ Glib::SignalProxy1<void, int> signal_response();
+
+ /** Custom signal handlers */
+ void onHideF12();
+ void onShowF12();
+ void onDesktopActivated(SPDesktop *desktop);
+ void onShutdown();
+
+private:
+ Widget::DockItem _dock_item;
+
+ DockBehavior(Dialog& dialog);
+
+ /** A map to store which widget that emits a certain response signal */
+ typedef std::map<int, Gtk::Widget *> ResponseMap;
+ ResponseMap _response_map;
+
+ /** Internal helpers */
+ void _addButton(Gtk::Button *button, int response_id);
+ Gtk::Paned *_getPaned(); //< gives the parent pane, if the dock item has one
+ void _requestHeight(int height); //< tries to resize the dock item to the requested hieght
+
+ /** Internal signal handlers */
+ void _onHide();
+ bool _onDeleteEvent(GdkEventAny *event);
+ void _onResponse(int response_id);
+ void _onDragBegin();
+ void _onDragEnd(bool cancelled);
+ bool _onKeyPress(GdkEventKey *event);
+
+ sigc::connection _signal_hide_connection;
+ sigc::connection _signal_key_press_event_connection;
+
+};
+
+} // namespace Behavior
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_DIALOG_DOCK_BEHAVIOR_H
+
+/*
+ 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 :
diff --git a/src/ui/dialog/document-metadata.cpp b/src/ui/dialog/document-metadata.cpp
index a3e87b31b..ca2da205e 100644
--- a/src/ui/dialog/document-metadata.cpp
+++ b/src/ui/dialog/document-metadata.cpp
@@ -63,10 +63,10 @@ static Inkscape::XML::NodeEventVector const _repr_events = {
DocumentMetadata*
-DocumentMetadata::create()
+DocumentMetadata::create(Behavior::BehaviorFactory behavior_factory)
{
if (_instance) return _instance;
- _instance = new DocumentMetadata;
+ _instance = new DocumentMetadata(behavior_factory);
_instance->init();
return _instance;
}
@@ -81,8 +81,8 @@ DocumentMetadata::destroy()
}
}
-DocumentMetadata::DocumentMetadata()
- : Dialog ("dialogs.documentmetadata", SP_VERB_DIALOG_METADATA),
+DocumentMetadata::DocumentMetadata(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.documentmetadata", SP_VERB_DIALOG_METADATA),
_page_metadata1(1, 1), _page_metadata2(1, 1),
_prefs_path("dialogs.documentmetadata")
{
diff --git a/src/ui/dialog/document-metadata.h b/src/ui/dialog/document-metadata.h
index c3cba2d34..478f9334e 100644
--- a/src/ui/dialog/document-metadata.h
+++ b/src/ui/dialog/document-metadata.h
@@ -40,7 +40,7 @@ typedef std::list<EntityEntry*> RDElist;
class DocumentMetadata : public Inkscape::UI::Dialog::Dialog {
public:
void update();
- static DocumentMetadata *create();
+ static DocumentMetadata *create(Behavior::BehaviorFactory behavior_factory);
static void destroy();
sigc::connection _doc_replaced_connection;
@@ -62,7 +62,7 @@ protected:
Registry _wr;
private:
- DocumentMetadata();
+ DocumentMetadata(Behavior::BehaviorFactory behavior_factory);
virtual ~DocumentMetadata();
};
diff --git a/src/ui/dialog/document-properties.cpp b/src/ui/dialog/document-properties.cpp
index 141a0c8cb..e2dc2c0b9 100644
--- a/src/ui/dialog/document-properties.cpp
+++ b/src/ui/dialog/document-properties.cpp
@@ -72,10 +72,10 @@ static Inkscape::XML::NodeEventVector const _repr_events = {
DocumentProperties*
-DocumentProperties::create()
+DocumentProperties::create(Behavior::BehaviorFactory behavior_factory)
{
if (_instance) return _instance;
- _instance = new DocumentProperties;
+ _instance = new DocumentProperties(behavior_factory);
_instance->init();
return _instance;
}
@@ -90,8 +90,8 @@ DocumentProperties::destroy()
}
}
-DocumentProperties::DocumentProperties()
- : Dialog ("dialogs.documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
+DocumentProperties::DocumentProperties(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.documentoptions", SP_VERB_DIALOG_NAMEDVIEW),
_page_page(1, 1), _page_guides(1, 1),
_page_snap(1, 1), _page_grids(1, 1),
_grids_button_new(_("_New"), _("Create new grid.")),
diff --git a/src/ui/dialog/document-properties.h b/src/ui/dialog/document-properties.h
index 846d95341..aa6e9c03b 100644
--- a/src/ui/dialog/document-properties.h
+++ b/src/ui/dialog/document-properties.h
@@ -38,7 +38,7 @@ namespace Inkscape {
class DocumentProperties : public Inkscape::UI::Dialog::Dialog {
public:
void update();
- static DocumentProperties *create();
+ static DocumentProperties *create(Behavior::BehaviorFactory behavior_factory);
static void destroy();
sigc::connection _doc_replaced_connection;
@@ -88,7 +88,7 @@ protected:
Registry _wr;
private:
- DocumentProperties();
+ DocumentProperties(Behavior::BehaviorFactory behavior_factory);
virtual ~DocumentProperties();
// callback methods for buttons on grids page.
diff --git a/src/ui/dialog/export.cpp b/src/ui/dialog/export.cpp
index d9ea2d25d..4e4efafb5 100644
--- a/src/ui/dialog/export.cpp
+++ b/src/ui/dialog/export.cpp
@@ -20,8 +20,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-Export::Export()
- : Dialog ("dialogs.export", SP_VERB_FILE_EXPORT),
+Export::Export(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.export", SP_VERB_FILE_EXPORT),
_page_export(1, 1)
{
// Top level vbox
diff --git a/src/ui/dialog/export.h b/src/ui/dialog/export.h
index 567eae10d..c47c7c8cc 100644
--- a/src/ui/dialog/export.h
+++ b/src/ui/dialog/export.h
@@ -26,10 +26,11 @@ namespace Dialog {
class Export : public Dialog {
public:
- Export();
+ Export(Behavior::BehaviorFactory behavior_factory);
virtual ~Export();
- static Export *create() { return new Export(); }
+ static Export *create(Behavior::BehaviorFactory behavior_factory)
+ { return new Export(behavior_factory); }
protected:
Gtk::Notebook _notebook;
diff --git a/src/ui/dialog/extension-editor.cpp b/src/ui/dialog/extension-editor.cpp
index 5f6386046..3a62cb144 100644
--- a/src/ui/dialog/extension-editor.cpp
+++ b/src/ui/dialog/extension-editor.cpp
@@ -42,8 +42,8 @@ namespace Dialog {
about the selected extension. A handler is set up so that when
a new extension is selected, the notebooks are changed appropriately.
*/
-ExtensionEditor::ExtensionEditor()
- : Dialog ("dialogs.extensioneditor", SP_VERB_DIALOG_EXTENSIONEDITOR)
+ExtensionEditor::ExtensionEditor(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.extensioneditor", SP_VERB_DIALOG_EXTENSIONEDITOR)
{
_notebook_info.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
_notebook_help.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
diff --git a/src/ui/dialog/extension-editor.h b/src/ui/dialog/extension-editor.h
index b6c331eae..284a3651d 100644
--- a/src/ui/dialog/extension-editor.h
+++ b/src/ui/dialog/extension-editor.h
@@ -31,10 +31,11 @@ namespace Dialog {
class ExtensionEditor : public Dialog {
public:
- ExtensionEditor();
+ ExtensionEditor(Behavior::BehaviorFactory behavior_factory);
virtual ~ExtensionEditor();
- static ExtensionEditor *create() { return new ExtensionEditor(); }
+ static ExtensionEditor *create(Behavior::BehaviorFactory behavior_factory)
+ { return new ExtensionEditor(behavior_factory); }
static void show_help (gchar const * extension_id);
diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp
index 8cf6bcfb4..ad9a9f031 100644
--- a/src/ui/dialog/fill-and-stroke.cpp
+++ b/src/ui/dialog/fill-and-stroke.cpp
@@ -55,8 +55,8 @@ void on_selection_modified(Inkscape::Application *inkscape,
}
-FillAndStroke::FillAndStroke()
- : Dialog ("dialogs.fillstroke", SP_VERB_DIALOG_FILL_STROKE),
+FillAndStroke::FillAndStroke(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.fillstroke", SP_VERB_DIALOG_FILL_STROKE),
_page_fill(1, 1, true, true),
_page_stroke_paint(1, 1, true, true),
_page_stroke_style(1, 1, true, true),
diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h
index b573161d9..87d5181db 100644
--- a/src/ui/dialog/fill-and-stroke.h
+++ b/src/ui/dialog/fill-and-stroke.h
@@ -33,10 +33,11 @@ namespace Dialog {
class FillAndStroke : public Dialog {
public:
- FillAndStroke();
+ FillAndStroke(Behavior::BehaviorFactory behavior_factory);
virtual ~FillAndStroke();
- static FillAndStroke *create() { return new FillAndStroke(); }
+ static FillAndStroke *create(Behavior::BehaviorFactory behavior_factory)
+ { return new FillAndStroke(behavior_factory); }
void selectionChanged(Inkscape::Application *inkscape,
Inkscape::Selection *selection);
diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp
index 3fa7d73d4..3bffb1285 100644
--- a/src/ui/dialog/filter-effects-dialog.cpp
+++ b/src/ui/dialog/filter-effects-dialog.cpp
@@ -1166,7 +1166,8 @@ void FilterEffectsDialog::FilterModifier::duplicate_filter()
void FilterEffectsDialog::FilterModifier::rename_filter()
{
SPFilter* filter = get_selected_filter();
- Gtk::Dialog m("", _dialog, true);
+ Gtk::Window *window = dynamic_cast<Gtk::Window *>(_dialog.get_vbox()->get_ancestor(GTK_TYPE_WINDOW));
+ Gtk::Dialog m("", *window, true);
m.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
m.add_button(_("_Rename"), Gtk::RESPONSE_OK);
m.set_default_response(Gtk::RESPONSE_OK);
@@ -1843,8 +1844,8 @@ int FilterEffectsDialog::PrimitiveList::primitive_count() const
/*** FilterEffectsDialog ***/
-FilterEffectsDialog::FilterEffectsDialog()
- : Dialog ("dialogs.filtereffects", SP_VERB_DIALOG_FILTER_EFFECTS),
+FilterEffectsDialog::FilterEffectsDialog(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.filtereffects", SP_VERB_DIALOG_FILTER_EFFECTS),
_filter_modifier(*this),
_primitive_list(*this),
_add_primitive_type(FPConverter),
diff --git a/src/ui/dialog/filter-effects-dialog.h b/src/ui/dialog/filter-effects-dialog.h
index 1a4285dd9..743ce0239 100644
--- a/src/ui/dialog/filter-effects-dialog.h
+++ b/src/ui/dialog/filter-effects-dialog.h
@@ -40,11 +40,14 @@ class DualSpinButton;
class MultiSpinButton;
class FilterEffectsDialog : public Dialog {
public:
+
+ FilterEffectsDialog(Behavior::BehaviorFactory behavior_factory);
~FilterEffectsDialog();
- void set_attrs_locked(const bool);
+ static FilterEffectsDialog *create(Behavior::BehaviorFactory behavior_factory)
+ { return new FilterEffectsDialog(behavior_factory); }
- static FilterEffectsDialog *create() { return new FilterEffectsDialog(); }
+ void set_attrs_locked(const bool);
private:
class SignalObserver;
diff --git a/src/ui/dialog/find.cpp b/src/ui/dialog/find.cpp
index 22fa608bf..0a0538c30 100644
--- a/src/ui/dialog/find.cpp
+++ b/src/ui/dialog/find.cpp
@@ -56,8 +56,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-Find::Find()
- : Dialog ("dialogs.find", SP_VERB_DIALOG_FIND),
+Find::Find(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.find", SP_VERB_DIALOG_FIND),
_entry_text(_("_Text: "), _("Find objects by their text content (exact or partial match)")),
_entry_id(_("_ID: "), _("Find objects by the value of the id attribute (exact or partial match)")),
_entry_style(_("_Style: "), _("Find objects by the value of the style attribute (exact or partial match)")),
diff --git a/src/ui/dialog/find.h b/src/ui/dialog/find.h
index 9594669fa..fb52b2c8e 100644
--- a/src/ui/dialog/find.h
+++ b/src/ui/dialog/find.h
@@ -59,10 +59,11 @@ namespace Dialog {
class Find : public Dialog {
public:
- Find();
+ Find(Behavior::BehaviorFactory behavior_factory);
virtual ~Find();
- static Find *create() { return new Find(); }
+ static Find *create(Behavior::BehaviorFactory behavior_factory)
+ { return new Find(behavior_factory); }
protected:
// Widgets:
diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp
new file mode 100644
index 000000000..b6b6949da
--- /dev/null
+++ b/src/ui/dialog/floating-behavior.cpp
@@ -0,0 +1,182 @@
+/**
+ * \brief A floating dialog implementation.
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#include <gtkmm/stock.h>
+#include <gtk/gtk.h>
+
+#include "floating-behavior.h"
+#include "dialog.h"
+
+#include "application/application.h"
+#include "application/editor.h"
+#include "inkscape.h"
+#include "desktop.h"
+#include "dialogs/dialog-events.h"
+#include "interface.h"
+#include "prefs-utils.h"
+#include "verbs.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+namespace Behavior {
+
+static gboolean
+sp_retransientize_again (gpointer dlgPtr)
+{
+ Dialog *dlg = (Dialog *)dlgPtr;
+ dlg->retransientize_suppress = false;
+ return FALSE; // so that it is only called once
+}
+
+
+FloatingBehavior::FloatingBehavior(Dialog& dialog) :
+ Behavior(dialog),
+ _d (new Gtk::Dialog(_dialog._title))
+{
+ hide();
+ _d->set_has_separator(false);
+
+ signal_response().connect(sigc::mem_fun(_dialog, &Inkscape::UI::Dialog::Dialog::on_response));
+ _d->signal_delete_event().connect(sigc::mem_fun(_dialog, &Inkscape::UI::Dialog::Dialog::on_delete_event));
+
+ sp_transientize(GTK_WIDGET(_d->gobj()));
+ _dialog.retransientize_suppress = false;
+}
+
+FloatingBehavior::~FloatingBehavior()
+{
+ delete _d;
+}
+
+Behavior *
+FloatingBehavior::create(Dialog& dialog)
+{
+ return new FloatingBehavior(dialog);
+}
+
+inline FloatingBehavior::operator Gtk::Widget&() { return *_d; }
+inline GtkWidget *FloatingBehavior::gobj() { return GTK_WIDGET(_d->gobj()); }
+inline Gtk::VBox* FloatingBehavior::get_vbox() { return _d->get_vbox(); }
+inline void FloatingBehavior::present() { _d->present(); }
+inline void FloatingBehavior::hide() { _d->hide(); }
+inline void FloatingBehavior::show() { _d->show(); }
+inline void FloatingBehavior::show_all_children() { _d->show_all_children(); }
+inline void FloatingBehavior::resize(int width, int height) { _d->resize(width, height); }
+inline void FloatingBehavior::move(int x, int y) { _d->move(x, y); }
+inline void FloatingBehavior::set_position(Gtk::WindowPosition position) { _d->set_position(position); }
+inline void FloatingBehavior::set_size_request(int width, int height) { _d->set_size_request(width, height); }
+inline void FloatingBehavior::size_request(Gtk::Requisition& requisition) { _d->size_request(requisition); }
+inline void FloatingBehavior::get_position(int& x, int& y) { _d->get_position(x, y); }
+inline void FloatingBehavior::get_size(int& width, int& height) { _d->get_size(width, height); }
+inline void FloatingBehavior::set_title(Glib::ustring title) { _d->set_title(title); }
+inline void FloatingBehavior::set_sensitive(bool sensitive) { _d->set_sensitive(sensitive); }
+
+void FloatingBehavior::set_response_sensitive(int response_id, bool setting)
+{ _d->set_response_sensitive(response_id, setting); }
+
+Gtk::Button *FloatingBehavior::add_button(const Glib::ustring& button_text, int response_id)
+{ return _d->add_button(button_text, response_id); }
+
+Gtk::Button *FloatingBehavior::add_button(const Gtk::StockID& stock_id, int response_id)
+{ return _d->add_button(stock_id, response_id); }
+
+inline void FloatingBehavior::set_default_response(int response_id) { _d->set_default_response(response_id); }
+
+Glib::SignalProxy0<void> FloatingBehavior::signal_show() { return _d->signal_show(); }
+Glib::SignalProxy0<void> FloatingBehavior::signal_hide() { return _d->signal_hide(); }
+Glib::SignalProxy1<bool, GdkEventAny *> FloatingBehavior::signal_delete_event () { return _d->signal_delete_event(); }
+Glib::SignalProxy1<void, int> FloatingBehavior::signal_response () { return _d->signal_response(); }
+
+
+void
+FloatingBehavior::onHideF12()
+{
+ _dialog.save_geometry();
+ hide();
+}
+
+void
+FloatingBehavior::onShowF12()
+{
+ show();
+ _dialog.read_geometry();
+}
+
+void
+FloatingBehavior::onShutdown() {}
+
+void
+FloatingBehavior::onDesktopActivated (SPDesktop *desktop)
+{
+ gint transient_policy = prefs_get_int_attribute_limited ( "options.transientpolicy", "value", 1, 0, 2);
+
+#ifdef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs
+ if (prefs_get_int_attribute ( "options.dialogsontopwin32", "value", 0))
+ transient_policy = 2;
+ else
+ return;
+#endif
+
+ if (!transient_policy)
+ return;
+
+ GtkWindow *dialog_win = GTK_WINDOW(_d->gobj());
+
+ if (_dialog.retransientize_suppress) {
+ /* if retransientizing of this dialog is still forbidden after
+ * previous call warning turned off because it was confusingly fired
+ * when loading many files from command line
+ */
+
+ // g_warning("Retranzientize aborted! You're switching windows too fast!");
+ return;
+ }
+
+ if (dialog_win)
+ {
+ _dialog.retransientize_suppress = true; // disallow other attempts to retranzientize this dialog
+
+ desktop->setWindowTransient (dialog_win);
+
+ /*
+ * This enables "aggressive" transientization,
+ * i.e. dialogs always emerging on top when you switch documents. Note
+ * however that this breaks "click to raise" policy of a window
+ * manager because the switched-to document will be raised at once
+ * (so that its transients also could raise)
+ */
+ if (transient_policy == 2 && ! _dialog._hiddenF12 && !_dialog._user_hidden) {
+ // without this, a transient window not always emerges on top
+ gtk_window_present (dialog_win);
+ }
+ }
+
+ // we're done, allow next retransientizing not sooner than after 120 msec
+ gtk_timeout_add (120, (GtkFunction) sp_retransientize_again, (gpointer) _d);
+}
+
+
+} // namespace Behavior
+} // namespace Dialog
+} // 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 :
diff --git a/src/ui/dialog/floating-behavior.h b/src/ui/dialog/floating-behavior.h
new file mode 100644
index 000000000..354987dde
--- /dev/null
+++ b/src/ui/dialog/floating-behavior.h
@@ -0,0 +1,88 @@
+/**
+ * \brief A floating dialog implementation.
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+
+#ifndef INKSCAPE_UI_DIALOG_FLOATING_BEHAVIOR_H
+#define INKSCAPE_UI_DIALOG_FLOATING_BEHAVIOR_H
+
+#include <gtkmm/dialog.h>
+#include "behavior.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Dialog {
+namespace Behavior {
+
+class FloatingBehavior : public Behavior {
+
+public:
+ static Behavior *create(Dialog& dialog);
+
+ ~FloatingBehavior();
+
+ /** Gtk::Dialog methods */
+ operator Gtk::Widget&();
+ GtkWidget *gobj();
+ void present();
+ Gtk::VBox *get_vbox();
+ void show();
+ void hide();
+ void show_all_children();
+ void resize(int width, int height);
+ void move(int x, int y);
+ void set_position(Gtk::WindowPosition);
+ void set_size_request(int width, int height);
+ void size_request(Gtk::Requisition& requisition);
+ void get_position(int& x, int& y);
+ void get_size(int& width, int& height);
+ void set_title(Glib::ustring title);
+ void set_response_sensitive(int response_id, bool setting);
+ void set_sensitive(bool sensitive);
+ Gtk::Button *add_button(const Glib::ustring& button_text, int response_id);
+ Gtk::Button *add_button(const Gtk::StockID& stock_id, int response_id);
+ void set_default_response(int response_id);
+
+ /** Gtk::Dialog signal proxies */
+ Glib::SignalProxy0<void> signal_show();
+ Glib::SignalProxy0<void> signal_hide();
+ Glib::SignalProxy1<bool, GdkEventAny *> signal_delete_event();
+ Glib::SignalProxy1<void, int> signal_response();
+
+ /** Custom signal handlers */
+ void onHideF12();
+ void onShowF12();
+ void onDesktopActivated(SPDesktop *desktop);
+ void onShutdown();
+
+private:
+ FloatingBehavior(Dialog& dialog);
+
+ Gtk::Dialog *_d; //< the actual dialog
+
+};
+
+} // namespace Behavior
+} // namespace Dialog
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_DIALOG_FLOATING_BEHAVIOR_H
+
+/*
+ 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 :
diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp
index 744d4f555..138f36c29 100644
--- a/src/ui/dialog/inkscape-preferences.cpp
+++ b/src/ui/dialog/inkscape-preferences.cpp
@@ -42,8 +42,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-InkscapePreferences::InkscapePreferences()
- : Dialog ("dialogs.preferences", SP_VERB_DIALOG_DISPLAY),
+InkscapePreferences::InkscapePreferences(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.preferences", SP_VERB_DIALOG_DISPLAY),
_max_dialog_width(0),
_max_dialog_height(0),
_current_page(0)
@@ -429,6 +429,9 @@ void InkscapePreferences::initPageWindows()
_win_save_geom_prefs.init ( _("Remember and use last window's geometry"), "options.savewindowgeometry", "value", 2, false, &_win_save_geom);
_win_save_geom_off.init ( _("Don't save window geometry"), "options.savewindowgeometry", "value", 0, false, &_win_save_geom);
+ _win_dockable.init ( _("Dockable"), "options.dialogtype", "value", 1, true, 0);
+ _win_floating.init ( _("Floating"), "options.dialogtype", "value", 0, false, &_win_dockable);
+
_win_hide_task.init ( _("Dialogs are hidden in taskbar"), "options.dialogsskiptaskbar", "value", true);
_win_zoom_resize.init ( _("Zoom when window is resized"), "options.stickyzoom", "value", false);
_win_show_close.init ( _("Show close button on dialogs"), "dialogs", "showclose", false);
@@ -449,6 +452,12 @@ void InkscapePreferences::initPageWindows()
_page_windows.add_line( false, "", _win_save_geom, "",
_("Save and restore window geometry for each document (saves geometry in the document)"));
+ _page_windows.add_group_header( _("Dialog behavior (requires restart):"));
+ _page_windows.add_line( true, "", _win_dockable, "",
+ _("Dockable"));
+ _page_windows.add_line( true, "", _win_floating, "",
+ _("Floating"));
+
_page_windows.add_group_header( _("Dialogs on top:"));
#ifndef WIN32 // FIXME: Temporary Win32 special code to enable transient dialogs
_page_windows.add_line( true, "", _win_ontop_none, "",
diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h
index 48cec9341..6798de21d 100644
--- a/src/ui/dialog/inkscape-preferences.h
+++ b/src/ui/dialog/inkscape-preferences.h
@@ -76,7 +76,9 @@ class InkscapePreferences : public Dialog {
public:
virtual ~InkscapePreferences();
- static InkscapePreferences *create() {return new InkscapePreferences(); }
+ static InkscapePreferences *create(Behavior::BehaviorFactory behavior_factory)
+ { return new InkscapePreferences(behavior_factory); }
+
void present();
protected:
@@ -123,6 +125,7 @@ protected:
PrefSpinButton _t_pencil_tolerance;
+ PrefRadioButton _win_dockable, _win_floating;
PrefRadioButton _win_ontop_none, _win_ontop_normal, _win_ontop_agressive;
PrefRadioButton _win_save_geom_off, _win_save_geom, _win_save_geom_prefs;
PrefCheckButton _win_hide_task, _win_zoom_resize , _win_show_close;
@@ -191,7 +194,7 @@ protected:
void initPageMisc();
private:
- InkscapePreferences();
+ InkscapePreferences(Behavior::BehaviorFactory behavior_factory);
InkscapePreferences(InkscapePreferences const &d);
InkscapePreferences operator=(InkscapePreferences const &d);
};
diff --git a/src/ui/dialog/layer-editor.cpp b/src/ui/dialog/layer-editor.cpp
index 79c4fbcc2..cb4b8a0b4 100644
--- a/src/ui/dialog/layer-editor.cpp
+++ b/src/ui/dialog/layer-editor.cpp
@@ -20,8 +20,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-LayerEditor::LayerEditor()
- : Dialog ("dialogs.layers", SP_VERB_NONE /*FIXME*/)
+LayerEditor::LayerEditor(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.layers", SP_VERB_NONE /*FIXME*/)
{
// TODO: Insert widgets
diff --git a/src/ui/dialog/layer-editor.h b/src/ui/dialog/layer-editor.h
index 3d68a7fcf..3c25c7bc0 100644
--- a/src/ui/dialog/layer-editor.h
+++ b/src/ui/dialog/layer-editor.h
@@ -22,10 +22,11 @@ namespace Dialog {
class LayerEditor : public Dialog {
public:
- LayerEditor();
+ LayerEditor(Behavior::BehaviorFactory behavior_factory);
virtual ~LayerEditor();
- static LayerEditor *create() { return new LayerEditor(); }
+ static LayerEditor *create(Behavior::BehaviorFactory behavior_factory)
+ { return new LayerEditor(behavior_factory); }
protected:
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 5f765b420..ee010eeca 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -66,8 +66,8 @@ static void lpeeditor_desktop_change(Inkscape::Application*, SPDesktop* desktop,
/*#######################
* LivePathEffectEditor
*/
-LivePathEffectEditor::LivePathEffectEditor()
- : Dialog ("dialogs.livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
+LivePathEffectEditor::LivePathEffectEditor(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
combo_effecttype(Inkscape::LivePathEffect::LPETypeConverter),
button_apply(_("_Apply"), _("Apply chosen effect to selection")),
button_remove(_("_Remove"), _("Remove effect from selection")),
diff --git a/src/ui/dialog/livepatheffect-editor.h b/src/ui/dialog/livepatheffect-editor.h
index 5476f8a1d..d99177fdd 100644
--- a/src/ui/dialog/livepatheffect-editor.h
+++ b/src/ui/dialog/livepatheffect-editor.h
@@ -30,10 +30,11 @@ namespace Dialog {
class LivePathEffectEditor : public Dialog {
public:
- LivePathEffectEditor();
+ LivePathEffectEditor(Behavior::BehaviorFactory behavior_factory);
virtual ~LivePathEffectEditor();
- static LivePathEffectEditor *create() { return new LivePathEffectEditor(); }
+ static LivePathEffectEditor *create(Behavior::BehaviorFactory behavior_factory)
+ { return new LivePathEffectEditor(behavior_factory); }
void onSelectionChanged(Inkscape::Selection *sel);
void setDesktop(SPDesktop *desktop);
diff --git a/src/ui/dialog/memory.cpp b/src/ui/dialog/memory.cpp
index e81db17d8..eb61aaf9f 100644
--- a/src/ui/dialog/memory.cpp
+++ b/src/ui/dialog/memory.cpp
@@ -203,8 +203,8 @@ void Memory::Private::stop_update_task() {
update_task.disconnect();
}
-Memory::Memory()
- : Dialog ("dialogs.memory", SP_VERB_HELP_MEMORY, _("Recalculate")),
+Memory::Memory(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.memory", SP_VERB_HELP_MEMORY, _("Recalculate")),
_private(*(new Memory::Private()))
{
get_vbox()->add(_private.view);
diff --git a/src/ui/dialog/memory.h b/src/ui/dialog/memory.h
index bec6c8fd0..0fe7f87c5 100644
--- a/src/ui/dialog/memory.h
+++ b/src/ui/dialog/memory.h
@@ -20,10 +20,11 @@ namespace Dialog {
class Memory : public Dialog {
public:
- Memory();
+ Memory(Behavior::BehaviorFactory behavior_factory);
~Memory();
- static Memory *create() { return new Memory(); }
+ static Memory *create(Behavior::BehaviorFactory behavior_factory)
+ { return new Memory(behavior_factory); }
protected:
void _apply();
diff --git a/src/ui/dialog/messages.cpp b/src/ui/dialog/messages.cpp
index 9c7434edd..9e78903c9 100644
--- a/src/ui/dialog/messages.cpp
+++ b/src/ui/dialog/messages.cpp
@@ -45,8 +45,8 @@ void Messages::clear()
/**
* Constructor
*/
-Messages::Messages()
- : Dialog ("dialogs.messages", SP_VERB_DIALOG_DEBUG)
+Messages::Messages(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.messages", SP_VERB_DIALOG_DEBUG)
{
Gtk::VBox *mainVBox = get_vbox();
diff --git a/src/ui/dialog/messages.h b/src/ui/dialog/messages.h
index 3ce7b5a87..85a7c4f0f 100644
--- a/src/ui/dialog/messages.h
+++ b/src/ui/dialog/messages.h
@@ -35,10 +35,11 @@ namespace Dialog {
class Messages : public Dialog {
public:
- Messages();
+ Messages(Behavior::BehaviorFactory behavior_factory);
virtual ~Messages();
- static Messages *create() { return new Messages(); }
+ static Messages *create(Behavior::BehaviorFactory behavior_factory)
+ { return new Messages(behavior_factory); }
/**
* Clear all information from the dialog
diff --git a/src/ui/dialog/scriptdialog.cpp b/src/ui/dialog/scriptdialog.cpp
index 07f26b71f..304362f60 100644
--- a/src/ui/dialog/scriptdialog.cpp
+++ b/src/ui/dialog/scriptdialog.cpp
@@ -43,7 +43,7 @@ class ScriptDialogImpl : public ScriptDialog
/**
* Constructor
*/
- ScriptDialogImpl();
+ ScriptDialogImpl(Behavior::BehaviorFactory behavior_factory);
/**
* Destructor
@@ -192,7 +192,8 @@ void ScriptDialogImpl::executePerl()
/**
* Constructor
*/
-ScriptDialogImpl::ScriptDialogImpl()
+ScriptDialogImpl::ScriptDialogImpl(Behavior::BehaviorFactory behavior_factory) :
+ ScriptDialog(behavior_factory)
{
Gtk::VBox *mainVBox = get_vbox();
@@ -249,9 +250,9 @@ ScriptDialogImpl::ScriptDialogImpl()
/**
* Factory method. Use this to create a new ScriptDialog
*/
-ScriptDialog *ScriptDialog::create()
+ScriptDialog *ScriptDialog::create(Behavior::BehaviorFactory behavior_factory)
{
- ScriptDialog *dialog = new ScriptDialogImpl();
+ ScriptDialog *dialog = new ScriptDialogImpl(behavior_factory);
return dialog;
}
diff --git a/src/ui/dialog/scriptdialog.h b/src/ui/dialog/scriptdialog.h
index b66aa93e7..00680d431 100644
--- a/src/ui/dialog/scriptdialog.h
+++ b/src/ui/dialog/scriptdialog.h
@@ -34,14 +34,15 @@ class ScriptDialog : public Dialog
/**
* Constructor
*/
- ScriptDialog() : Dialog ("dialogs.script", SP_VERB_DIALOG_SCRIPT)
+ ScriptDialog(Behavior::BehaviorFactory behavior_factory) :
+ Dialog (behavior_factory, "dialogs.script", SP_VERB_DIALOG_SCRIPT)
{}
/**
* Factory method
*/
- static ScriptDialog *create();
+ static ScriptDialog *create(Behavior::BehaviorFactory behavior_factory);
/**
* Destructor
diff --git a/src/ui/dialog/text-properties.cpp b/src/ui/dialog/text-properties.cpp
index a79992677..e6194ab56 100644
--- a/src/ui/dialog/text-properties.cpp
+++ b/src/ui/dialog/text-properties.cpp
@@ -20,8 +20,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-TextProperties::TextProperties()
- : Dialog ("dialogs.textandfont", SP_VERB_DIALOG_TEXT),
+TextProperties::TextProperties(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.textandfont", SP_VERB_DIALOG_TEXT),
_page_font(1, 1),
_page_text(1, 1)
{
diff --git a/src/ui/dialog/text-properties.h b/src/ui/dialog/text-properties.h
index 2d5a03b9e..393ca63b2 100644
--- a/src/ui/dialog/text-properties.h
+++ b/src/ui/dialog/text-properties.h
@@ -26,10 +26,11 @@ namespace Dialog {
class TextProperties : public Dialog {
public:
- TextProperties();
+ TextProperties(Behavior::BehaviorFactory behavior_factory);
virtual ~TextProperties();
- static TextProperties *create() { return new TextProperties(); }
+ static TextProperties *create(Behavior::BehaviorFactory behavior_factory)
+ { return new TextProperties(behavior_factory); }
protected:
Gtk::Notebook _notebook;
diff --git a/src/ui/dialog/tracedialog.cpp b/src/ui/dialog/tracedialog.cpp
index 2c041864f..b7602b36a 100644
--- a/src/ui/dialog/tracedialog.cpp
+++ b/src/ui/dialog/tracedialog.cpp
@@ -50,7 +50,7 @@ class TraceDialogImpl : public TraceDialog
/**
* Constructor
*/
- TraceDialogImpl();
+ TraceDialogImpl(Behavior::BehaviorFactory behavior_factory);
/**
* Destructor
@@ -376,7 +376,8 @@ void TraceDialogImpl::responseCallback(int response_id)
/**
* Constructor
*/
-TraceDialogImpl::TraceDialogImpl()
+TraceDialogImpl::TraceDialogImpl(Behavior::BehaviorFactory behavior_factory) :
+ TraceDialog(behavior_factory)
{
Gtk::VBox *mainVBox = get_vbox();
@@ -685,9 +686,9 @@ TraceDialogImpl::TraceDialogImpl()
/**
* Factory method. Use this to create a new TraceDialog
*/
-TraceDialog *TraceDialog::create()
+TraceDialog *TraceDialog::create(Behavior::BehaviorFactory behavior_factory)
{
- TraceDialog *dialog = new TraceDialogImpl();
+ TraceDialog *dialog = new TraceDialogImpl(behavior_factory);
return dialog;
}
diff --git a/src/ui/dialog/tracedialog.h b/src/ui/dialog/tracedialog.h
index 80311bb15..0e352ce10 100644
--- a/src/ui/dialog/tracedialog.h
+++ b/src/ui/dialog/tracedialog.h
@@ -34,14 +34,15 @@ public:
/**
* Constructor
*/
- TraceDialog() : Dialog ("dialogs.trace", SP_VERB_SELECTION_TRACE)
+ TraceDialog(Behavior::BehaviorFactory behavior_factory) :
+ Dialog (behavior_factory, "dialogs.trace", SP_VERB_SELECTION_TRACE)
{}
/**
* Factory method
*/
- static TraceDialog *create();
+ static TraceDialog *create(Behavior::BehaviorFactory behavior_factory);
/**
* Destructor
diff --git a/src/ui/dialog/transformation.cpp b/src/ui/dialog/transformation.cpp
index be5a8bb03..b2385a29c 100644
--- a/src/ui/dialog/transformation.cpp
+++ b/src/ui/dialog/transformation.cpp
@@ -70,8 +70,8 @@ void on_selection_modified ( Inkscape::Application *inkscape,
* we use the ScalarUnit class for this.
*
*/
-Transformation::Transformation()
- : Dialog ("dialogs.transformation", SP_VERB_DIALOG_TRANSFORM),
+Transformation::Transformation(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.transformation", SP_VERB_DIALOG_TRANSFORM),
_page_move (4, 2),
_page_scale (4, 2),
_page_rotate (4, 2),
@@ -181,8 +181,8 @@ void
Transformation::presentPage(Transformation::PageType page)
{
_notebook.set_current_page(page);
- Gtk::Dialog::show();
- Gtk::Dialog::present();
+ show();
+ present();
}
diff --git a/src/ui/dialog/transformation.h b/src/ui/dialog/transformation.h
index 0c7833c9e..361b30a04 100644
--- a/src/ui/dialog/transformation.h
+++ b/src/ui/dialog/transformation.h
@@ -46,7 +46,7 @@ public:
/**
* Create a new transform
*/
- Transformation();
+ Transformation(Behavior::BehaviorFactory behavior_factory);
/**
* Cleanup
@@ -57,8 +57,8 @@ public:
/**
* Factory method. Create an instance of this class/interface
*/
- static Transformation *create()
- { return new Transformation(); }
+ static Transformation *create(Behavior::BehaviorFactory behavior_factory)
+ { return new Transformation(behavior_factory); }
/**
diff --git a/src/ui/dialog/undo-history.cpp b/src/ui/dialog/undo-history.cpp
index 98f8cc0cc..344efc557 100644
--- a/src/ui/dialog/undo-history.cpp
+++ b/src/ui/dialog/undo-history.cpp
@@ -103,10 +103,10 @@ static void on_activate_desktop(Inkscape::Application*, SPDesktop* desktop, void
static void on_deactivate_desktop(Inkscape::Application*, SPDesktop* desktop, void*);
UndoHistory*
-UndoHistory::create()
+UndoHistory::create(Behavior::BehaviorFactory behavior_factory)
{
if (_instance) return _instance;
- _instance = new UndoHistory;
+ _instance = new UndoHistory(behavior_factory);
return _instance;
}
@@ -131,8 +131,8 @@ UndoHistory::setDesktop(SPDesktop* desktop)
_callback_connections[EventLog::CALLB_SELECTION_CHANGE].block(false);
}
-UndoHistory::UndoHistory()
- : Dialog ("dialogs.undo-history", SP_VERB_DIALOG_UNDO_HISTORY),
+UndoHistory::UndoHistory(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.undo-history", SP_VERB_DIALOG_UNDO_HISTORY),
_desktop (SP_ACTIVE_DESKTOP),
_document (SP_ACTIVE_DOCUMENT),
_event_log (_desktop ? _desktop->event_log : NULL),
@@ -141,7 +141,7 @@ UndoHistory::UndoHistory()
{
if( !_document || !_event_log || !_columns ) return;
- set_size_request(300, 400);
+ set_size_request(300, 200);
get_vbox()->pack_start(_scrolled_window);
_scrolled_window.set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
diff --git a/src/ui/dialog/undo-history.h b/src/ui/dialog/undo-history.h
index 7b900fde5..d7b00f343 100644
--- a/src/ui/dialog/undo-history.h
+++ b/src/ui/dialog/undo-history.h
@@ -120,7 +120,7 @@ class UndoHistory : public Dialog {
public:
virtual ~UndoHistory();
- static UndoHistory *create();
+ static UndoHistory *create(Behavior::BehaviorFactory behavior_factory);
void setDesktop(SPDesktop* desktop);
sigc::connection _document_replaced_connection;
@@ -146,9 +146,9 @@ protected:
void _onCollapseEvent(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
private:
+ UndoHistory(Behavior::BehaviorFactory behavior_factory);
// no default constructor, noncopyable, nonassignable
- UndoHistory();
UndoHistory(UndoHistory const &d);
UndoHistory operator=(UndoHistory const &d);
diff --git a/src/ui/dialog/xml-editor.cpp b/src/ui/dialog/xml-editor.cpp
index b8abf8bfd..53f3b4c2c 100644
--- a/src/ui/dialog/xml-editor.cpp
+++ b/src/ui/dialog/xml-editor.cpp
@@ -20,8 +20,8 @@ namespace Inkscape {
namespace UI {
namespace Dialog {
-XmlEditor::XmlEditor()
- : Dialog ("dialogs.xml", SP_VERB_DIALOG_XML_EDITOR)
+XmlEditor::XmlEditor(Behavior::BehaviorFactory behavior_factory)
+ : Dialog (behavior_factory, "dialogs.xml", SP_VERB_DIALOG_XML_EDITOR)
{
// TODO: Insert widgets
diff --git a/src/ui/dialog/xml-editor.h b/src/ui/dialog/xml-editor.h
index b494ade1f..65f25423f 100644
--- a/src/ui/dialog/xml-editor.h
+++ b/src/ui/dialog/xml-editor.h
@@ -22,10 +22,11 @@ namespace Dialog {
class XmlEditor : public Dialog {
public:
- XmlEditor();
+ XmlEditor(Behavior::BehaviorFactory behavior_factory);
virtual ~XmlEditor();
- static XmlEditor *create() { return new XmlEditor(); }
+ static XmlEditor *create(Behavior::BehaviorFactory behavior_factory)
+ { return new XmlEditor(behavior_factory); }
protected:
diff --git a/src/ui/view/edit-widget-interface.h b/src/ui/view/edit-widget-interface.h
index 8e388529e..c8219b7b2 100644
--- a/src/ui/view/edit-widget-interface.h
+++ b/src/ui/view/edit-widget-interface.h
@@ -18,9 +18,10 @@
#include "libnr/nr-point.h"
#include "message.h"
-
#include <gtkmm/window.h>
+namespace Inkscape { namespace UI { namespace Widget { class Dock; } } }
+
namespace Inkscape {
namespace UI {
namespace View {
@@ -135,6 +136,8 @@ struct EditWidgetInterface
/// Open yes/no dialog with warning text and confirmation question.
virtual bool warnDialog (gchar*) = 0;
+
+ virtual Inkscape::UI::Widget::Dock* getDock () = 0;
};
} // namespace View
diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp
index b87250e47..066d4d0ba 100644
--- a/src/ui/view/edit-widget.cpp
+++ b/src/ui/view/edit-widget.cpp
@@ -65,6 +65,8 @@
#include "interface.h"
#include "extension/db.h"
+#include "ui/dialog/dialog-manager.h"
+
using namespace Inkscape::UI;
using namespace Inkscape::UI::Widget;
@@ -152,7 +154,6 @@ EditWidget::initLayout()
_viewport_table.attach(_svg_canvas.widget(), 1, 2, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND);
_svg_canvas.widget().show_all();
-
// The statusbar comes last and appears at the bottom of _main_window_table
initStatusbar();
@@ -1532,6 +1533,12 @@ EditWidget::warnDialog (gchar* msg)
}
+Inkscape::UI::Widget::Dock*
+EditWidget::getDock ()
+{
+ return &_dock;
+}
+
void EditWidget::_namedview_modified (SPObject *obj, guint flags) {
SPNamedView *nv = static_cast<SPNamedView *>(obj);
if (flags & SP_OBJECT_MODIFIED_FLAG) {
diff --git a/src/ui/view/edit-widget.h b/src/ui/view/edit-widget.h
index 443b10ac8..4341f667c 100644
--- a/src/ui/view/edit-widget.h
+++ b/src/ui/view/edit-widget.h
@@ -27,6 +27,7 @@
#include "ui/dialog/dialog-manager.h"
#include "ui/view/edit-widget-interface.h"
+#include "ui/widget/dock.h"
#include "ui/widget/selected-style.h"
#include "ui/widget/ruler.h"
#include "ui/widget/toolbox.h"
@@ -132,6 +133,8 @@ public:
virtual void setMessage (Inkscape::MessageType type, gchar const* msg);
virtual bool warnDialog (gchar*);
+ virtual Inkscape::UI::Widget::Dock* getDock ();
+
protected:
void _namedview_modified(SPObject *namedview, guint);
@@ -157,6 +160,7 @@ protected:
Gtk::ToggleButton _sticky_zoom;
UI::Widget::SVGCanvas _svg_canvas;
Gtk::HBox _statusbar;
+ UI::Widget::Dock _dock;
UI::Widget::SelectedStyle _selected_style_status;
UI::Widget::ZoomStatus _zoom_status;
Inkscape::Widgets::LayerSelector _layer_selector;
diff --git a/src/ui/widget/Makefile_insert b/src/ui/widget/Makefile_insert
index 178e954a4..7113857c8 100644
--- a/src/ui/widget/Makefile_insert
+++ b/src/ui/widget/Makefile_insert
@@ -15,6 +15,10 @@ ui_widget_libuiwidget_a_SOURCES = \
ui/widget/combo-enums.h \
ui/widget/combo-text.cpp \
ui/widget/combo-text.h \
+ ui/widget/dock.h \
+ ui/widget/dock.cpp \
+ ui/widget/dock-item.h \
+ ui/widget/dock-item.cpp \
ui/widget/entity-entry.cpp \
ui/widget/entity-entry.h \
ui/widget/entry.cpp \
diff --git a/src/ui/widget/dock-item.cpp b/src/ui/widget/dock-item.cpp
new file mode 100644
index 000000000..1e232cb4e
--- /dev/null
+++ b/src/ui/widget/dock-item.cpp
@@ -0,0 +1,539 @@
+/**
+ * \brief A custom Inkscape wrapper around gdl_dock_item
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#include "dock-item.h"
+#include "desktop.h"
+#include "inkscape.h"
+#include "ui/widget/dock.h"
+#include "widgets/icon.h"
+
+#include <gtk/gtk.h>
+
+#include <gtkmm/invisible.h>
+#include <gtkmm/stock.h>
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+DockItem::DockItem(Dock& dock, const Glib::ustring& name, const Glib::ustring& long_name,
+ const Glib::ustring& icon_name, State state) :
+ _dock (dock),
+ _prev_state (state),
+ _window (NULL),
+ _dock_item_action_area (NULL)
+{
+ /* Add a "signal_response" signal to the GdlDockItem, make sure it is
+ * only done once for the class.
+ */
+ static guint response_signal = 0;
+
+ if (response_signal == 0) {
+ response_signal = g_signal_new ("signal_response",
+ GDL_TYPE_DOCK_ITEM,
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+ }
+
+
+ if (!icon_name.empty()) {
+ Gtk::Widget *icon = sp_icon_get_icon(icon_name, Inkscape::ICON_SIZE_MENU);
+ if (icon) {
+ // check icon type (inkscape, gtk, none)
+ if ( SP_IS_ICON(icon->gobj()) ) {
+ SPIcon* sp_icon = SP_ICON(icon->gobj());
+ sp_icon_fetch_pixbuf(sp_icon);
+ _icon_pixbuf = Glib::wrap(sp_icon->pb, true);
+ } else if ( GTK_IS_IMAGE(icon->gobj()) ) {
+ _icon_pixbuf = Gtk::Invisible().render_icon(Gtk::StockID(icon_name),
+ Gtk::ICON_SIZE_MENU);
+ }
+ delete icon;
+
+ _gdl_dock_item =
+ gdl_dock_item_new_with_pixbuf_icon(name.c_str(), long_name.c_str(), _icon_pixbuf->gobj(),
+ GDL_DOCK_ITEM_BEH_NORMAL);
+ }
+ } else {
+ _gdl_dock_item =
+ gdl_dock_item_new(name.c_str(), long_name.c_str(), GDL_DOCK_ITEM_BEH_NORMAL);
+ }
+
+ _frame.set_shadow_type(Gtk::SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (_gdl_dock_item), GTK_WIDGET (_frame.gobj()));
+ _frame.add(_dock_item_box);
+ _dock_item_box.set_border_width(3);
+
+ signal_drag_begin().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDragBegin));
+ signal_drag_end().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDragEnd));
+ signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onHide), false);
+ signal_show().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onShow), false);
+ signal_state_changed().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onStateChanged));
+ signal_delete_event().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onDeleteEvent));
+
+ _dock.addItem(*this, (_prev_state == FLOATING_STATE ? FLOATING : TOP));
+
+ show_all();
+}
+
+DockItem::~DockItem()
+{
+ g_free(_gdl_dock_item);
+}
+
+Gtk::Widget&
+DockItem::getWidget()
+{
+ return *Glib::wrap(GTK_WIDGET(_gdl_dock_item));
+}
+
+GtkWidget *
+DockItem::gobj()
+{
+ return _gdl_dock_item;
+}
+
+Gtk::VBox *
+DockItem::get_vbox()
+{
+ return &_dock_item_box;
+}
+
+
+bool
+DockItem::isAttached() const
+{
+ return GDL_DOCK_OBJECT_ATTACHED (_gdl_dock_item);
+}
+
+
+bool
+DockItem::isFloating() const
+{
+ gboolean floating = FALSE;
+ if (GDL_IS_DOCK (gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT (_gdl_dock_item)))) {
+ GdlDock* dock = GDL_DOCK (gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT (_gdl_dock_item)));
+ g_object_get (dock,
+ "floating", &floating,
+ NULL);
+ }
+ return floating;
+}
+
+bool
+DockItem::isIconified() const
+{
+ return GDL_DOCK_ITEM_ICONIFIED (_gdl_dock_item);
+}
+
+DockItem::State
+DockItem::getState() const
+{
+ return (isAttached() ? (isFloating() ? FLOATING_STATE : DOCKED_STATE) : UNATTACHED);
+}
+
+DockItem::State
+DockItem::getPrevState() const
+{
+ return _prev_state;
+}
+
+DockItem::Placement
+DockItem::getPlacement() const
+{
+ GdlDockPlacement placement = (GdlDockPlacement)NONE;
+ gdl_dock_object_child_placement(gdl_dock_object_get_parent_object (GDL_DOCK_OBJECT(_gdl_dock_item)),
+ GDL_DOCK_OBJECT(_gdl_dock_item),
+ &placement);
+ return (Placement)placement;
+}
+
+
+void
+DockItem::addButton(Gtk::Button* button, int response_id)
+{
+ // Create a button box for the response buttons if it's the first button to be added
+ if (!_dock_item_action_area) {
+ _dock_item_action_area = new Gtk::HButtonBox(Gtk::BUTTONBOX_END, 6);
+ _dock_item_box.pack_end(*_dock_item_action_area, Gtk::PACK_SHRINK, 0);
+ _dock_item_action_area->set_border_width(6);
+ }
+
+ _dock_item_action_area->pack_start(*button);
+}
+
+void
+DockItem::hide()
+{
+ gdl_dock_item_hide_item (GDL_DOCK_ITEM(_gdl_dock_item));
+}
+
+void
+DockItem::show()
+{
+ gdl_dock_item_show_item (GDL_DOCK_ITEM(_gdl_dock_item));
+}
+
+void
+DockItem::show_all()
+{
+ gtk_widget_show_all(_gdl_dock_item);
+}
+
+void
+DockItem::present()
+{
+ // iconified
+ if (isIconified()) {
+ show();
+ return;
+ }
+
+ // unattached
+ if (!isAttached()) {
+ gdl_dock_item_show_item (GDL_DOCK_ITEM(_gdl_dock_item));
+ return;
+ }
+
+ // tabbed
+ if (getPlacement() == CENTER) {
+ int i = gtk_notebook_page_num (GTK_NOTEBOOK (_gdl_dock_item->parent),
+ GTK_WIDGET (_gdl_dock_item));
+ if (i >= 0)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (_gdl_dock_item->parent), i);
+ return;
+ }
+
+ // we're already present, do nothing
+}
+
+
+void
+DockItem::get_position(int& x, int& y)
+{
+ if (_getWindow()) {
+ _getWindow()->get_position(x, y);
+ } else {
+ x = _x;
+ y = _y;
+ }
+}
+
+void
+DockItem::get_size(int& width, int& height)
+{
+ if (_window) {
+ _window->get_size(width, height);
+ } else {
+ width = get_vbox()->get_width();
+ height = get_vbox()->get_height();
+ }
+}
+
+
+void
+DockItem::resize(int width, int height)
+{
+ if (_window)
+ _window->resize(width, height);
+}
+
+
+void
+DockItem::move(int x, int y)
+{
+ if (_window)
+ _window->move(x, y);
+}
+
+void
+DockItem::set_position(Gtk::WindowPosition position)
+{
+ if (_window)
+ _window->set_position(position);
+}
+
+void
+DockItem::set_size_request(int width, int height)
+{
+ getWidget().set_size_request(width, height);
+}
+
+void
+DockItem::size_request(Gtk::Requisition& requisition)
+{
+ getWidget().size_request(requisition);
+}
+
+
+void
+DockItem::set_title(Glib::ustring title)
+{
+ g_object_set (_gdl_dock_item,
+ "long-name", title.c_str(),
+ NULL);
+
+ gdl_dock_item_set_tablabel(GDL_DOCK_ITEM(_gdl_dock_item),
+ gtk_label_new (title.c_str()));
+}
+
+/* Signal wrappers */
+
+Glib::SignalProxy0<void>
+DockItem::signal_show()
+{
+ return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_show_proxy);
+}
+
+Glib::SignalProxy0<void>
+DockItem::signal_hide()
+{
+ return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_hide_proxy);
+}
+
+Glib::SignalProxy1<bool, GdkEventAny *>
+DockItem::signal_delete_event()
+{
+ return Glib::SignalProxy1<bool, GdkEventAny *>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_delete_event_proxy);
+}
+
+Glib::SignalProxy1<void, int>
+DockItem::signal_response()
+{
+ return Glib::SignalProxy1<void, int>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_response_proxy);
+}
+
+Glib::SignalProxy0<void>
+DockItem::signal_drag_begin()
+{
+ return Glib::SignalProxy0<void>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_drag_begin_proxy);
+}
+
+Glib::SignalProxy1<void, bool>
+DockItem::signal_drag_end()
+{
+ return Glib::SignalProxy1<void, bool>(Glib::wrap(GTK_WIDGET(_gdl_dock_item)),
+ &_signal_drag_end_proxy);
+}
+
+sigc::signal<void, DockItem::State, DockItem::State>
+DockItem::signal_state_changed()
+{
+ return _signal_state_changed;
+}
+
+void
+DockItem::_onHideWindow()
+{
+ if (_window)
+ _window->get_position(_x, _y);
+}
+
+void
+DockItem::_onHide()
+{
+ _signal_state_changed.emit(UNATTACHED, getState());
+}
+
+void
+DockItem::_onShow()
+{
+ _signal_state_changed.emit(UNATTACHED, getState());
+}
+
+void
+DockItem::_onDragBegin()
+{
+ _prev_state = getState();
+ if (_prev_state == FLOATING_STATE)
+ _dock.toggleDockable(getWidget().get_width(), getWidget().get_height());
+}
+
+void
+DockItem::_onDragEnd(bool)
+{
+ State state = getState();
+
+ if (state != _prev_state)
+ _signal_state_changed.emit(_prev_state, state);
+
+ if (state == FLOATING_STATE) {
+ if (_prev_state == FLOATING_STATE)
+ _dock.toggleDockable();
+ }
+
+ _prev_state = state;
+}
+
+bool
+DockItem::_onKeyPress(GdkEventKey *event)
+{
+ gboolean return_value;
+ g_signal_emit_by_name (_gdl_dock_item, "key_press_event", event, &return_value);
+ return return_value;
+}
+
+void
+DockItem::_onStateChanged(State prev_state, State new_state)
+{
+ _window = _getWindow();
+
+ if (new_state == FLOATING_STATE) {
+ _window->signal_hide().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onHideWindow));
+ _signal_key_press_event_connection =
+ _window->signal_key_press_event().connect(sigc::mem_fun(*this, &Inkscape::UI::Widget::DockItem::_onKeyPress));
+ }
+}
+
+
+bool
+DockItem::_onDeleteEvent(GdkEventAny *event)
+{
+ hide();
+ return false;
+}
+
+
+Gtk::Window *
+DockItem::_getWindow()
+{
+ g_return_val_if_fail(_gdl_dock_item, 0);
+ Gtk::Container *parent = getWidget().get_parent();
+ parent = (parent ? parent->get_parent() : 0);
+ return (parent ? dynamic_cast<Gtk::Window *>(parent) : 0);
+}
+
+const Glib::SignalProxyInfo
+DockItem::_signal_show_proxy =
+{
+ "show",
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
+};
+
+const Glib::SignalProxyInfo
+DockItem::_signal_hide_proxy =
+{
+ "hide",
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
+};
+
+
+const Glib::SignalProxyInfo
+DockItem::_signal_delete_event_proxy =
+{
+ "delete_event",
+ (GCallback) &_signal_delete_event_callback,
+ (GCallback) &_signal_delete_event_callback
+};
+
+
+const Glib::SignalProxyInfo
+DockItem::_signal_response_proxy =
+{
+ "signal_response",
+ (GCallback) &_signal_response_callback,
+ (GCallback) &_signal_response_callback
+};
+
+const Glib::SignalProxyInfo
+DockItem::_signal_drag_begin_proxy =
+{
+ "dock-drag-begin",
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback,
+ (GCallback) &Glib::SignalProxyNormal::slot0_void_callback
+};
+
+
+const Glib::SignalProxyInfo
+DockItem::_signal_drag_end_proxy =
+{
+ "dock_drag_end",
+ (GCallback) &_signal_drag_end_callback,
+ (GCallback) &_signal_drag_end_callback
+};
+
+
+gboolean
+DockItem::_signal_delete_event_callback(GtkWidget *self, GdkEventAny *event, void *data)
+{
+ using namespace Gtk;
+ typedef sigc::slot<bool, GdkEventAny *> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
+ try {
+ if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
+ return static_cast<int>( (*static_cast<SlotType*>(slot))(event) );
+ } catch(...) {
+ Glib::exception_handlers_invoke();
+ }
+ }
+
+ typedef gboolean RType;
+ return RType();
+}
+
+void
+DockItem::_signal_response_callback(GtkWidget *self, gint response_id, void *data)
+{
+ using namespace Gtk;
+ typedef sigc::slot<void, int> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
+ try {
+ if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
+ (*static_cast<SlotType *>(slot))(response_id);
+ } catch(...) {
+ Glib::exception_handlers_invoke();
+ }
+ }
+}
+
+void
+DockItem::_signal_drag_end_callback(GtkWidget *self, gboolean cancelled, void *data)
+{
+ using namespace Gtk;
+ typedef sigc::slot<void, bool> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *) self)) {
+ try {
+ if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot(data))
+ (*static_cast<SlotType *>(slot))(cancelled);
+ } catch(...) {
+ Glib::exception_handlers_invoke();
+ }
+ }
+}
+
+
+} // 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 :
diff --git a/src/ui/widget/dock-item.h b/src/ui/widget/dock-item.h
new file mode 100644
index 000000000..38d13a579
--- /dev/null
+++ b/src/ui/widget/dock-item.h
@@ -0,0 +1,165 @@
+/**
+ * \brief A custom wrapper around gdl-dock-item
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+
+#ifndef INKSCAPE_UI_WIGET_DOCK_ITEM_H
+#define INKSCAPE_UI_WIGET_DOCK_ITEM_H
+
+#include <gtkmm/button.h>
+#include <gtkmm/buttonbox.h>
+#include <gtkmm/frame.h>
+#include <gtkmm/paned.h>
+#include <gtkmm/window.h>
+
+#include "libgdl/libgdl.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class Dock;
+
+class DockItem {
+
+public:
+
+ enum State { UNATTACHED, FLOATING_STATE, DOCKED_STATE };
+
+ enum Placement {
+ NONE = GDL_DOCK_NONE,
+ TOP = GDL_DOCK_TOP,
+ BOTTOM = GDL_DOCK_BOTTOM,
+ RIGHT = GDL_DOCK_RIGHT,
+ LEFT = GDL_DOCK_LEFT,
+ CENTER = GDL_DOCK_CENTER,
+ FLOATING = GDL_DOCK_FLOATING
+ };
+
+ DockItem(Dock& dock, const Glib::ustring& name, const Glib::ustring& long_name,
+ const Glib::ustring& icon_name, State state);
+
+ ~DockItem();
+
+ Gtk::Widget& getWidget();
+ GtkWidget *gobj();
+
+ Gtk::VBox *get_vbox();
+
+ void get_position(int& x, int& y);
+ void get_size(int& width, int& height);
+
+ void resize(int width, int height);
+ void move(int x, int y);
+ void set_position(Gtk::WindowPosition);
+ void set_size_request(int width, int height);
+ void size_request(Gtk::Requisition& requisition);
+ void set_title(Glib::ustring title);
+
+ bool isAttached() const;
+ bool isFloating() const;
+ bool isIconified() const;
+ State getState() const;
+ State getPrevState() const;
+ Placement getPlacement() const;
+
+ void addButton(Gtk::Button *button, int response_id);
+
+ void hide();
+ void show();
+ void show_all();
+
+ void present();
+
+ Glib::SignalProxy0<void> signal_show();
+ Glib::SignalProxy0<void> signal_hide();
+ Glib::SignalProxy1<bool, GdkEventAny *> signal_delete_event();
+ Glib::SignalProxy1<void, int> signal_response();
+ Glib::SignalProxy0<void> signal_drag_begin();
+ Glib::SignalProxy1<void, bool> signal_drag_end();
+
+ sigc::signal<void, State, State> signal_state_changed();
+
+private:
+ Dock &_dock; //< parent dock
+
+ State _prev_state; //< last known state
+
+ int _prev_position;
+
+ Gtk::Window *_window; //< reference to floating window, if any
+ int _x, _y; //< last known position of window, if floating
+
+ GtkWidget *_gdl_dock_item;
+ Glib::RefPtr<Gdk::Pixbuf> _icon_pixbuf;
+
+ /** Interface widgets, will be packed like
+ * gdl_dock_item -> _frame -> _dock_item_box -> (_dock_item_action_area)
+ */
+ Gtk::Frame _frame;
+ Gtk::VBox _dock_item_box;
+ Gtk::HButtonBox *_dock_item_action_area;
+
+ /** Internal signal handlers */
+ void _onHide();
+ void _onHideWindow();
+ void _onShow();
+ void _onResponse(int response_id);
+ void _onDragBegin();
+ void _onDragEnd(bool cancelled);
+ bool _onKeyPress(GdkEventKey *event);
+ void _onStateChanged(State prev_state, State new_state);
+ bool _onDeleteEvent(GdkEventAny *event);
+
+ void _onFoo();
+
+ sigc::connection _signal_key_press_event_connection;
+
+ /** GdlDockItem signal proxy structures */
+ static const Glib::SignalProxyInfo _signal_show_proxy;
+ static const Glib::SignalProxyInfo _signal_hide_proxy;
+ static const Glib::SignalProxyInfo _signal_delete_event_proxy;
+ static const Glib::SignalProxyInfo _signal_response_proxy;
+ static const Glib::SignalProxyInfo _signal_drag_begin_proxy;
+ static const Glib::SignalProxyInfo _signal_drag_end_proxy;
+
+ static gboolean _signal_delete_event_callback(GtkWidget *self, GdkEventAny *event, void *data);
+ static void _signal_drag_end_callback(GtkWidget* self, gboolean p0, void* data);
+
+ /** Internal helpers */
+ Gtk::Window *_getWindow(); //< gives the parent window, if the dock item has one (i.e. it's floating)
+
+ /** In order to emulate a signal_response signal like the one for Gtk::Dialog we inject a new
+ * signal into GdlDockItem. This signal will be emitted when a button in the dock item added
+ * through the addButton(..., response_id) method, is clicked.
+ */
+ static void _signal_response_callback(GtkWidget* self, gint p0, void* data);
+
+ sigc::signal<void, State, State> _signal_state_changed;
+
+ DockItem();
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif // INKSCAPE_UI_WIGET_DOCK_ITEM_H
+
+/*
+ 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 :
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 <broberg@kth.se>
+ *
+ * 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<GtkOrientation>(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<Gtk::Paned *>(parent) : 0);
+}
+
+
+Gtk::Paned *
+Dock::getPaned()
+{
+ return _paned;
+}
+
+
+bool
+Dock::isEmpty() const
+{
+ std::list<const DockItem *>::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 DockItem *>::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<void>
+Dock::signal_layout_changed()
+{
+ return Glib::SignalProxy0<void>(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
diff --git a/src/ui/widget/dock.h b/src/ui/widget/dock.h
new file mode 100644
index 000000000..be0c4ef1d
--- /dev/null
+++ b/src/ui/widget/dock.h
@@ -0,0 +1,97 @@
+/**
+ * \brief A desktop dock pane to dock dialogs, a custom wrapper around gdl-dock.
+ *
+ * Author:
+ * Gustav Broberg <broberg@kth.se>
+ *
+ * Copyright (C) 2007 Authors
+ *
+ * Released under GNU GPL. Read the file 'COPYING' for more information.
+ */
+
+#ifndef INKSCAPE_UI_WIDGET_DOCK_H
+#define INKSCAPE_UI_WIDGET_DOCK_H
+
+#include <gtkmm/scrolledwindow.h>
+#include <gtkmm/box.h>
+#include <gtkmm/paned.h>
+
+#include <list>
+
+#include "ui/widget/dock-item.h"
+
+#include "libgdl/libgdl.h"
+
+namespace Inkscape {
+namespace UI {
+namespace Widget {
+
+class Dock {
+
+public:
+
+ Dock(Gtk::Orientation orientation=Gtk::ORIENTATION_VERTICAL);
+ ~Dock();
+
+ void addItem(DockItem& item, DockItem::Placement placement);
+
+ Gtk::Widget& getWidget(); //< return the top widget
+ Gtk::Paned *getParentPaned();
+
+ Gtk::Paned *getPaned();
+
+ bool isEmpty() const; //< true iff none of the dock's items are in state != UNATTACHED
+ bool hasIconifiedItems() const;
+
+ Glib::SignalProxy0<void> signal_layout_changed();
+
+ void hide();
+ void show();
+
+ /** Toggle size of dock between the previous dimensions and the ones sent as parameters */
+ void toggleDockable(int width=0, int height=0);
+
+protected:
+
+ std::list<const DockItem *> _dock_items; //< added dock items
+
+ /** Interface widgets, will be packed like
+ * _scrolled_window -> (_dock_box -> (_paned -> (_dock -> _filler) | _dock_bar))
+ */
+ Gtk::Box *_dock_box;
+ Gtk::Paned* _paned;
+ GdlDock *_gdl_dock;
+ GdlDockBar *_gdl_dock_bar;
+ Gtk::VBox _filler;
+ Gtk::ScrolledWindow *_scrolled_window;
+
+ /** Internal signal handlers */
+ void _onLayoutChanged();
+
+ void _onFoo();
+
+ /** GdlDock signal proxy structures */
+ static const Glib::SignalProxyInfo _signal_layout_changed_proxy;
+
+ /** Standard widths */
+ static const int _default_empty_width;
+ static const int _default_dock_bar_width;
+};
+
+} // namespace Widget
+} // namespace UI
+} // namespace Inkscape
+
+#endif //INKSCAPE_UI_DIALOG_BEHAVIOUR_H
+
+/*
+ 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
+