/* Copyright (C) 2013 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __gtk2_ardour_window_manager_h__ #define __gtk2_ardour_window_manager_h__ #include #include #include #include #include #include "gtkmm2ext/bindings.h" #include "gtkmm2ext/window_proxy.h" class XMLNode; namespace Gtk { class Window; class Action; } namespace Gtkmm2ext { class VisibilityTracker; } namespace ARDOUR { class Session; class SessionHandlePtr; } namespace WM { class ProxyBase; class Manager : public ARDOUR::SessionHandlePtr { public: static Manager& instance(); void register_window (ProxyBase*); void remove (const ProxyBase*); void toggle_window (ProxyBase*); void show_visible () const; void set_session (ARDOUR::Session*); void add_state (XMLNode&) const; /* HACK HACK HACK */ void set_transient_for (Gtk::Window*); Gtk::Window* transient_parent() const { return current_transient_parent; } private: typedef std::list Windows; Windows _windows; Glib::RefPtr window_actions; Gtk::Window* current_transient_parent; Manager(); ~Manager(); static Manager* _instance; private: void window_proxy_was_mapped (ProxyBase*); void window_proxy_was_unmapped (ProxyBase*); }; class ProxyBase : public ARDOUR::SessionHandlePtr, public Gtkmm2ext::WindowProxy { public: ProxyBase (const std::string& name, const std::string& menu_name); ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&); virtual ARDOUR::SessionHandlePtr* session_handle () = 0; protected: 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 = dynamic_cast (creator ()); if (_window) { setup (); } } return _window; } T* operator->() { return dynamic_cast (get (true)); } ARDOUR::SessionHandlePtr* session_handle () { /* may return null */ return dynamic_cast (_window); } void set_session(ARDOUR::Session *s) { SessionHandlePtr::set_session (s); ARDOUR::SessionHandlePtr* sp = session_handle (); if (sp) { sp->set_session (s); dynamic_cast(_window)->set_session(s); } } 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); } void set_session(ARDOUR::Session *s) { SessionHandlePtr::set_session (s); ARDOUR::SessionHandlePtr* sp = session_handle (); if (sp) { sp->set_session (s); dynamic_cast(_window)->set_session(s); } } private: boost::function creator; }; } /* namespace */ #endif /* __gtk2_ardour_window_manager_h__ */