From bedc7b170eb72f1b9aaaf3872c7160aa1661a4e1 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 7 May 2013 22:09:16 -0400 Subject: change namespace/naming of WindowManager classes; register all ArdourDialog and ArdourWindow classes as ProxyTemporary windows so that transient-for can be set for all such windows --- gtk2_ardour/ardour_dialog.cc | 8 +- gtk2_ardour/ardour_dialog.h | 5 + gtk2_ardour/ardour_ui.cc | 32 ++--- gtk2_ardour/ardour_ui.h | 28 ++-- gtk2_ardour/ardour_ui_dialogs.cc | 6 +- gtk2_ardour/ardour_ui_ed.cc | 2 +- gtk2_ardour/ardour_window.cc | 9 +- gtk2_ardour/ardour_window.h | 7 +- gtk2_ardour/processor_box.cc | 8 +- gtk2_ardour/processor_box.h | 2 +- gtk2_ardour/window_manager.cc | 93 ++++++++----- gtk2_ardour/window_manager.h | 283 +++++++++++++++++++++------------------ 12 files changed, 277 insertions(+), 206 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/ardour_dialog.cc b/gtk2_ardour/ardour_dialog.cc index c8a25f1874..3690ee023b 100644 --- a/gtk2_ardour/ardour_dialog.cc +++ b/gtk2_ardour/ardour_dialog.cc @@ -27,6 +27,7 @@ #include "keyboard.h" #include "splash.h" #include "utils.h" +#include "window_manager.h" using namespace std; using namespace Gtk; @@ -34,6 +35,7 @@ using namespace Gtkmm2ext; ArdourDialog::ArdourDialog (string title, bool modal, bool use_seperator) : Dialog (title, modal, use_seperator) + , proxy (0) , _splash_pushed (false) { init (); @@ -57,6 +59,7 @@ ArdourDialog::~ArdourDialog () spl->pop_front(); } } + WM::Manager::instance().remove (proxy); } bool @@ -115,11 +118,14 @@ ArdourDialog::init () set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG); - Gtk::Window* parent = WindowManager::instance().transient_parent(); + Gtk::Window* parent = WM::Manager::instance().transient_parent(); if (parent) { set_transient_for (*parent); } ARDOUR_UI::CloseAllDialogs.connect (sigc::bind (sigc::mem_fun (*this, &ArdourDialog::response), RESPONSE_CANCEL)); + + proxy = new WM::ProxyTemporary (get_title(), this); + WM::Manager::instance().register_window (proxy); } diff --git a/gtk2_ardour/ardour_dialog.h b/gtk2_ardour/ardour_dialog.h index 40472f20c0..d994c0a6d1 100644 --- a/gtk2_ardour/ardour_dialog.h +++ b/gtk2_ardour/ardour_dialog.h @@ -25,6 +25,10 @@ #include "ardour/session_handle.h" +namespace WM { + class ProxyTemporary; +} + /* * This virtual parent class is so that each dialog box uses the * same mechanism to declare its closing. It shares a common @@ -46,6 +50,7 @@ class ArdourDialog : public Gtk::Dialog, public ARDOUR::SessionHandlePtr void on_show (); private: + WM::ProxyTemporary* proxy; bool _splash_pushed; void init (); diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 3540dc30f2..250a94baa4 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -344,20 +344,20 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) midi_port_matrix.set_state (*ui_xml); } - WindowManager::instance().register_window (&theme_manager); - WindowManager::instance().register_window (&key_editor); - WindowManager::instance().register_window (&rc_option_editor); - WindowManager::instance().register_window (&session_option_editor); - WindowManager::instance().register_window (&speaker_config_window); - WindowManager::instance().register_window (&about); - WindowManager::instance().register_window (&add_route_dialog); - WindowManager::instance().register_window (&add_video_dialog); - WindowManager::instance().register_window (&route_params); - WindowManager::instance().register_window (&bundle_manager); - WindowManager::instance().register_window (&location_ui); - WindowManager::instance().register_window (&big_clock_window); - WindowManager::instance().register_window (&audio_port_matrix); - WindowManager::instance().register_window (&midi_port_matrix); + WM::Manager::instance().register_window (&theme_manager); + WM::Manager::instance().register_window (&key_editor); + WM::Manager::instance().register_window (&rc_option_editor); + WM::Manager::instance().register_window (&session_option_editor); + WM::Manager::instance().register_window (&speaker_config_window); + WM::Manager::instance().register_window (&about); + WM::Manager::instance().register_window (&add_route_dialog); + WM::Manager::instance().register_window (&add_video_dialog); + WM::Manager::instance().register_window (&route_params); + WM::Manager::instance().register_window (&bundle_manager); + WM::Manager::instance().register_window (&location_ui); + WM::Manager::instance().register_window (&big_clock_window); + WM::Manager::instance().register_window (&audio_port_matrix); + WM::Manager::instance().register_window (&midi_port_matrix); /* We need to instantiate the theme manager because it loads our theme files. This should really change so that its window @@ -753,7 +753,7 @@ ARDOUR_UI::startup () goto_editor_window (); - WindowManager::instance().show_visible (); + WM::Manager::instance().show_visible (); /* We have to do this here since goto_editor_window() ends up calling show_all() on the * editor window, and we may want stuff to be hidden. @@ -2336,7 +2336,7 @@ ARDOUR_UI::save_state (const string & name, bool switch_to_it) { XMLNode* node = new XMLNode (X_("UI")); - WindowManager::instance().add_state (*node); + WM::Manager::instance().add_state (*node); node->add_child_nocopy (gui_object_state->get_state()); diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 4d624377c6..0ed5d145b4 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -572,23 +572,23 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr /* Dialogs that can be created via new */ - WindowManager::Proxy speaker_config_window; - WindowManager::Proxy theme_manager; - WindowManager::Proxy key_editor; - WindowManager::Proxy rc_option_editor; - WindowManager::Proxy add_route_dialog; - WindowManager::Proxy about; - WindowManager::Proxy location_ui; - WindowManager::Proxy route_params; + WM::Proxy speaker_config_window; + WM::Proxy theme_manager; + WM::Proxy key_editor; + WM::Proxy rc_option_editor; + WM::Proxy add_route_dialog; + WM::Proxy about; + WM::Proxy location_ui; + WM::Proxy route_params; /* Windows/Dialogs that require a creator method */ - WindowManager::ProxyWithConstructor session_option_editor; - WindowManager::ProxyWithConstructor add_video_dialog; - WindowManager::ProxyWithConstructor bundle_manager; - WindowManager::ProxyWithConstructor big_clock_window; - WindowManager::ProxyWithConstructor audio_port_matrix; - WindowManager::ProxyWithConstructor midi_port_matrix; + WM::ProxyWithConstructor session_option_editor; + WM::ProxyWithConstructor add_video_dialog; + WM::ProxyWithConstructor bundle_manager; + WM::ProxyWithConstructor big_clock_window; + WM::ProxyWithConstructor audio_port_matrix; + WM::ProxyWithConstructor midi_port_matrix; /* creator methods */ diff --git a/gtk2_ardour/ardour_ui_dialogs.cc b/gtk2_ardour/ardour_ui_dialogs.cc index ad469ff160..3ff625a207 100644 --- a/gtk2_ardour/ardour_ui_dialogs.cc +++ b/gtk2_ardour/ardour_ui_dialogs.cc @@ -95,7 +95,7 @@ ARDOUR_UI::set_session (Session *s) } AutomationWatch::instance().set_session (s); - WindowManager::instance().set_session (s); + WM::Manager::instance().set_session (s); if (shuttle_box) { shuttle_box->set_session (s); @@ -269,7 +269,7 @@ ARDOUR_UI::goto_editor_window () editor->show_window (); editor->present (); /* mixer should now be on top */ - WindowManager::instance().set_transient_for (editor); + WM::Manager::instance().set_transient_for (editor); _mixer_on_top = false; } @@ -298,7 +298,7 @@ ARDOUR_UI::goto_mixer_window () mixer->show_window (); mixer->present (); /* mixer should now be on top */ - WindowManager::instance().set_transient_for (mixer); + WM::Manager::instance().set_transient_for (mixer); _mixer_on_top = true; } diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc index 9d1e8c3d8a..84f73391a4 100644 --- a/gtk2_ardour/ardour_ui_ed.cc +++ b/gtk2_ardour/ardour_ui_ed.cc @@ -612,7 +612,7 @@ ARDOUR_UI::save_ardour_state () /* Windows */ - WindowManager::instance().add_state (*window_node); + WM::Manager::instance().add_state (*window_node); /* tearoffs */ diff --git a/gtk2_ardour/ardour_window.cc b/gtk2_ardour/ardour_window.cc index 532d9828fe..3d33b14e60 100644 --- a/gtk2_ardour/ardour_window.cc +++ b/gtk2_ardour/ardour_window.cc @@ -51,6 +51,7 @@ ArdourWindow::ArdourWindow (Gtk::Window& parent, string /*title*/) ArdourWindow::~ArdourWindow () { + WM::Manager::instance().remove (proxy); } bool @@ -103,20 +104,20 @@ ArdourWindow::init () */ if (ARDOUR_UI::instance()->config()->all_floating_windows_are_dialogs.get()) { - cerr << "AW " << get_title() << " => dialog\n"; set_type_hint (Gdk::WINDOW_TYPE_HINT_DIALOG); } else { - cerr << "AW " << get_title() << " => utility\n"; set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY); } - Gtk::Window* parent = WindowManager::instance().transient_parent(); + Gtk::Window* parent = WM::Manager::instance().transient_parent(); if (parent) { - cerr << "\tmarked as transient for " << parent->get_title() << endl; set_transient_for (*parent); } ARDOUR_UI::CloseAllDialogs.connect (sigc::mem_fun (*this, &ArdourWindow::hide)); + + proxy = new WM::ProxyTemporary (get_title(), this); + WM::Manager::instance().register_window (proxy); } diff --git a/gtk2_ardour/ardour_window.h b/gtk2_ardour/ardour_window.h index e113f724c8..c90eb3c049 100644 --- a/gtk2_ardour/ardour_window.h +++ b/gtk2_ardour/ardour_window.h @@ -27,6 +27,10 @@ #include "ardour/session_handle.h" +namespace WM { + class ProxyTemporary; +} + /** * This virtual parent class is so that each window uses the * same mechanism to declare its closing. It shares a common @@ -47,7 +51,8 @@ class ArdourWindow : public Gtk::Window, public ARDOUR::SessionHandlePtr, public void on_unmap (); private: - void init (); + WM::ProxyTemporary* proxy; + void init (); }; #endif // __ardour_window_h__ diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index 07bb0cadde..2782d2cff8 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -1378,7 +1378,7 @@ ProcessorBox::redisplay_processors () ++j; if (!(*i)->marked) { - WindowManager::instance().remove (*i); + WM::Manager::instance().remove (*i); delete *i; _processor_window_info.erase (i); } @@ -1451,7 +1451,7 @@ ProcessorBox::maybe_add_processor_to_ui_list (boost::weak_ptr w) } _processor_window_info.push_back (wp); - WindowManager::instance().register_window (wp); + WM::Manager::instance().register_window (wp); } void @@ -2624,7 +2624,7 @@ ProcessorBox::update_gui_object_state (ProcessorEntry* entry) } ProcessorWindowProxy::ProcessorWindowProxy (string const & name, ProcessorBox* box, boost::weak_ptr processor) - : WindowManager::ProxyBase (name, string()) + : WM::ProxyBase (name, string()) , marked (false) , _processor_box (box) , _processor (processor) @@ -2678,5 +2678,5 @@ ProcessorWindowProxy::toggle () drop_window (); } - WindowManager::ProxyBase::toggle (); + WM::ProxyBase::toggle (); } diff --git a/gtk2_ardour/processor_box.h b/gtk2_ardour/processor_box.h index 44d6a0ab6a..c279ffa917 100644 --- a/gtk2_ardour/processor_box.h +++ b/gtk2_ardour/processor_box.h @@ -75,7 +75,7 @@ namespace ARDOUR { class ProcessorBox; -class ProcessorWindowProxy : public WindowManager::ProxyBase +class ProcessorWindowProxy : public WM::ProxyBase { public: ProcessorWindowProxy (std::string const &, ProcessorBox *, boost::weak_ptr); diff --git a/gtk2_ardour/window_manager.cc b/gtk2_ardour/window_manager.cc index 1859eb85f1..90345acff0 100644 --- a/gtk2_ardour/window_manager.cc +++ b/gtk2_ardour/window_manager.cc @@ -25,30 +25,33 @@ #include "gtkmm2ext/visibility_tracker.h" #include "actions.h" +#include "ardour_dialog.h" +#include "ardour_window.h" #include "window_manager.h" #include "i18n.h" using std::string; +using namespace WM; -WindowManager* WindowManager::_instance = 0; +Manager* Manager::_instance = 0; -WindowManager& -WindowManager::instance () +Manager& +Manager::instance () { if (!_instance) { - _instance = new WindowManager; + _instance = new Manager; } return *_instance; } -WindowManager::WindowManager () +Manager::Manager () : current_transient_parent (0) { } void -WindowManager::register_window (ProxyBase* info) +Manager::register_window (ProxyBase* info) { _windows.push_back (info); @@ -60,12 +63,12 @@ WindowManager::register_window (ProxyBase* info) } info->set_action (ActionManager::register_action (window_actions, info->action_name().c_str(), info->menu_name().c_str(), - sigc::bind (sigc::mem_fun (*this, &WindowManager::toggle_window), info))); + sigc::bind (sigc::mem_fun (*this, &Manager::toggle_window), info))); } } void -WindowManager::remove (const ProxyBase* info) +Manager::remove (const ProxyBase* info) { for (Windows::iterator i = _windows.begin(); i != _windows.end(); ++i) { if ((*i) == info) { @@ -76,7 +79,7 @@ WindowManager::remove (const ProxyBase* info) } void -WindowManager::toggle_window (ProxyBase* proxy) +Manager::toggle_window (ProxyBase* proxy) { if (proxy) { proxy->toggle (); @@ -84,7 +87,7 @@ WindowManager::toggle_window (ProxyBase* proxy) } void -WindowManager::show_visible() const +Manager::show_visible() const { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { if ((*i)->visible()) { @@ -95,15 +98,20 @@ WindowManager::show_visible() const } void -WindowManager::add_state (XMLNode& root) const +Manager::add_state (XMLNode& root) const { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { + /* don't save state for temporary proxy windows + */ + if (dynamic_cast (*i)) { + continue; + } root.add_child_nocopy ((*i)->get_state()); } } void -WindowManager::set_session (ARDOUR::Session* s) +Manager::set_session (ARDOUR::Session* s) { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { ARDOUR::SessionHandlePtr* sp = (*i)->session_handle (); @@ -114,12 +122,13 @@ WindowManager::set_session (ARDOUR::Session* s) } void -WindowManager::set_transient_for (Gtk::Window* parent) +Manager::set_transient_for (Gtk::Window* parent) { if (parent) { for (Windows::const_iterator i = _windows.begin(); i != _windows.end(); ++i) { Gtk::Window* win = (*i)->get(); if (win) { + std::cerr << "marked " << win->get_title() << " as transient of " << parent->get_title() << std::endl; win->set_transient_for (*parent); } } @@ -131,13 +140,13 @@ WindowManager::set_transient_for (Gtk::Window* parent) } } } - + current_transient_parent = parent; } -/*-----------------------*/ +/*-------------------------*/ -WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name) +ProxyBase::ProxyBase (const string& name, const std::string& menu_name) : _name (name) , _menu_name (menu_name) , _window (0) @@ -150,7 +159,7 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu { } -WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node) +ProxyBase::ProxyBase (const string& name, const std::string& menu_name, const XMLNode& node) : _name (name) , _menu_name (menu_name) , _window (0) @@ -164,13 +173,13 @@ WindowManager::ProxyBase::ProxyBase (const string& name, const std::string& menu set_state (node); } -WindowManager::ProxyBase::~ProxyBase () +ProxyBase::~ProxyBase () { delete vistracker; } void -WindowManager::ProxyBase::set_state (const XMLNode& node) +ProxyBase::set_state (const XMLNode& node) { XMLNodeList children = node.children (); @@ -215,19 +224,19 @@ WindowManager::ProxyBase::set_state (const XMLNode& node) } void -WindowManager::ProxyBase::set_action (Glib::RefPtr act) +ProxyBase::set_action (Glib::RefPtr act) { _action = act; } std::string -WindowManager::ProxyBase::action_name() const +ProxyBase::action_name() const { return string_compose (X_("toggle-%1"), _name); } void -WindowManager::ProxyBase::toggle() +ProxyBase::toggle() { if (!_window) { (void) get (true); @@ -244,7 +253,7 @@ WindowManager::ProxyBase::toggle() } XMLNode& -WindowManager::ProxyBase::get_state () const +ProxyBase::get_state () const { XMLNode* node = new XMLNode (X_("Window")); char buf[32]; @@ -275,7 +284,7 @@ WindowManager::ProxyBase::get_state () const } void -WindowManager::ProxyBase::drop_window () +ProxyBase::drop_window () { if (_window) { _window->hide (); @@ -287,7 +296,7 @@ WindowManager::ProxyBase::drop_window () } void -WindowManager::ProxyBase::use_window (Gtk::Window& win) +ProxyBase::use_window (Gtk::Window& win) { drop_window (); _window = &win; @@ -295,7 +304,7 @@ WindowManager::ProxyBase::use_window (Gtk::Window& win) } void -WindowManager::ProxyBase::setup () +ProxyBase::setup () { assert (_window); @@ -316,14 +325,14 @@ WindowManager::ProxyBase::setup () } void -WindowManager::ProxyBase::show () +ProxyBase::show () { Gtk::Window* win = get (true); win->show (); } void -WindowManager::ProxyBase::maybe_show () +ProxyBase::maybe_show () { if (_visible) { show (); @@ -331,7 +340,7 @@ WindowManager::ProxyBase::maybe_show () } void -WindowManager::ProxyBase::show_all () +ProxyBase::show_all () { Gtk::Window* win = get (true); win->show_all (); @@ -339,7 +348,7 @@ WindowManager::ProxyBase::show_all () void -WindowManager::ProxyBase::present () +ProxyBase::present () { Gtk::Window* win = get (true); win->show_all (); @@ -350,7 +359,7 @@ WindowManager::ProxyBase::present () } void -WindowManager::ProxyBase::hide () +ProxyBase::hide () { Gtk::Window* win = get (false); if (win) { @@ -358,3 +367,25 @@ WindowManager::ProxyBase::hide () } } +/*-----------------------*/ + +ProxyTemporary::ProxyTemporary (const string& name, Gtk::Window* win) + : ProxyBase (name, string()) +{ + _window = win; +} + +ProxyTemporary::~ProxyTemporary () +{ +} + +ARDOUR::SessionHandlePtr* +ProxyTemporary::session_handle() +{ + /* may return null */ + ArdourWindow* aw = dynamic_cast (_window); + if (aw) { return aw; } + ArdourDialog* ad = dynamic_cast (_window); + if (ad) { return ad; } + return 0; +} diff --git a/gtk2_ardour/window_manager.h b/gtk2_ardour/window_manager.h index 1b1b2566ab..7138a95e7b 100644 --- a/gtk2_ardour/window_manager.h +++ b/gtk2_ardour/window_manager.h @@ -43,136 +43,15 @@ namespace ARDOUR { class SessionHandlePtr; } -class WindowManager -{ - public: - static WindowManager& instance(); - - class ProxyBase : public sigc::trackable { - public: - ProxyBase (const std::string& name, const std::string& menu_name); - ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&); - virtual ~ProxyBase(); - - void show (); - void show_all (); - void hide (); - void present (); - void maybe_show (); - - bool visible() const { return _visible; } - const std::string& name() const { return _name; } - const std::string& menu_name() const { return _menu_name; } - - std::string action_name() const; - void set_action (Glib::RefPtr); - Glib::RefPtr action() const { return _action; }; - - void drop_window (); - void use_window (Gtk::Window&); - - virtual Gtk::Window* get (bool create = false) = 0; - - virtual void toggle (); - - void set_state (const XMLNode&); - XMLNode& get_state () const; - - virtual ARDOUR::SessionHandlePtr* session_handle () = 0; - - operator bool() const { return _window != 0; } +namespace WM { - protected: - std::string _name; - std::string _menu_name; - Glib::RefPtr _action; - Gtk::Window* _window; - mutable bool _visible; ///< true if the window should be visible on startup - mutable int _x_off; ///< x position - mutable int _y_off; ///< y position - mutable int _width; ///< width - mutable int _height; ///< height - Gtkmm2ext::VisibilityTracker* vistracker; +class ProxyBase; - void setup (); - }; +class Manager +{ + public: + static Manager& instance(); - template - class ProxyWithConstructor: public ProxyBase { - public: - ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function& c) - : ProxyBase (name, menu_name) , creator (c) {} - - ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function& c, const XMLNode* node) - : ProxyBase (name, menu_name, node) , creator (c) {} - - Gtk::Window* get (bool create = false) { - if (!_window) { - if (!create) { - return 0; - } - - _window = creator (); - - if (_window) { - setup (); - } - } - - return _window; - } - - T* operator->() { - return dynamic_cast (get (true)); - } - - ARDOUR::SessionHandlePtr* session_handle () { - /* may return null */ - return dynamic_cast (_window); - } - - private: - boost::function creator; - }; - - template - class Proxy : public ProxyBase { - public: - Proxy (const std::string& name, const std::string& menu_name) - : ProxyBase (name, menu_name) {} - - Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node) - : ProxyBase (name, menu_name, node) {} - - Gtk::Window* get (bool create = false) { - if (!_window) { - if (!create) { - return 0; - } - - _window = new T (); - - if (_window) { - setup (); - } - } - - return _window; - } - - T* operator->() { - return dynamic_cast (get(true)); - } - - ARDOUR::SessionHandlePtr* session_handle () { - /* may return null */ - return dynamic_cast (_window); - } - - private: - boost::function creator; - }; - void register_window (ProxyBase*); void remove (const ProxyBase*); void toggle_window (ProxyBase*); @@ -190,10 +69,154 @@ class WindowManager Glib::RefPtr window_actions; Gtk::Window* current_transient_parent; - WindowManager(); - ~WindowManager(); + Manager(); + ~Manager(); - static WindowManager* _instance; + static Manager* _instance; +}; + +class ProxyBase : public sigc::trackable { + public: + ProxyBase (const std::string& name, const std::string& menu_name); + ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&); + virtual ~ProxyBase(); + + void show (); + void show_all (); + void hide (); + void present (); + void maybe_show (); + + bool visible() const { return _visible; } + const std::string& name() const { return _name; } + const std::string& menu_name() const { return _menu_name; } + + std::string action_name() const; + void set_action (Glib::RefPtr); + Glib::RefPtr action() const { return _action; }; + + void drop_window (); + void use_window (Gtk::Window&); + + virtual Gtk::Window* get (bool create = false) = 0; + + virtual void toggle (); + + void set_state (const XMLNode&); + XMLNode& get_state () const; + + virtual ARDOUR::SessionHandlePtr* session_handle () = 0; + + operator bool() const { return _window != 0; } + + protected: + std::string _name; + std::string _menu_name; + Glib::RefPtr _action; + Gtk::Window* _window; + mutable bool _visible; ///< true if the window should be visible on startup + mutable int _x_off; ///< x position + mutable int _y_off; ///< y position + mutable int _width; ///< width + mutable int _height; ///< height + Gtkmm2ext::VisibilityTracker* vistracker; + + void setup (); }; + +class ProxyTemporary: public ProxyBase { + public: + ProxyTemporary (const std::string& name, Gtk::Window* win); + ~ProxyTemporary(); + + Gtk::Window* get (bool create = false) { + (void) create; + return _window; + } + + Gtk::Window* operator->() { + return _window; + } + + ARDOUR::SessionHandlePtr* session_handle (); +}; + +template +class ProxyWithConstructor: public ProxyBase { + public: + ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function& c) + : ProxyBase (name, menu_name) , creator (c) {} + + ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function& c, const XMLNode* node) + : ProxyBase (name, menu_name, node) , creator (c) {} + + Gtk::Window* get (bool create = false) { + if (!_window) { + if (!create) { + return 0; + } + + _window = creator (); + + if (_window) { + setup (); + } + } + + return _window; + } + + T* operator->() { + return dynamic_cast (get (true)); + } + + ARDOUR::SessionHandlePtr* session_handle () { + /* may return null */ + return dynamic_cast (_window); + } + + private: + boost::function creator; +}; + +template +class Proxy : public ProxyBase { + public: + Proxy (const std::string& name, const std::string& menu_name) + : ProxyBase (name, menu_name) {} + + Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node) + : ProxyBase (name, menu_name, node) {} + + Gtk::Window* get (bool create = false) { + if (!_window) { + if (!create) { + return 0; + } + + _window = new T (); + + if (_window) { + setup (); + } + } + + return _window; + } + + T* operator->() { + return dynamic_cast (get(true)); + } + + ARDOUR::SessionHandlePtr* session_handle () { + /* may return null */ + return dynamic_cast (_window); + } + + private: + boost::function creator; +}; + +} /* namespace */ #endif /* __gtk2_ardour_window_manager_h__ */ -- cgit v1.2.3