1 /* 2 * Copyright (C) 2013-2016 John Emmas <john@creativepost.co.uk> 3 * Copyright (C) 2013-2016 Paul Davis <paul@linuxaudiosystems.com> 4 * Copyright (C) 2013-2018 Robin Gareus <robin@gareus.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 */ 20 21 #ifndef __gtk2_ardour_window_manager_h__ 22 #define __gtk2_ardour_window_manager_h__ 23 24 #include <string> 25 #include <map> 26 27 #include <boost/function.hpp> 28 #include <glibmm/refptr.h> 29 #include <sigc++/trackable.h> 30 31 #include "gtkmm2ext/bindings.h" 32 #include "gtkmm2ext/window_proxy.h" 33 34 class XMLNode; 35 36 namespace Gtk { 37 class Window; 38 class Action; 39 } 40 41 namespace Gtkmm2ext { 42 class VisibilityTracker; 43 } 44 45 namespace ARDOUR { 46 class Session; 47 class SessionHandlePtr; 48 } 49 50 namespace WM { 51 52 class ProxyBase; 53 54 class Manager : public ARDOUR::SessionHandlePtr 55 { 56 public: 57 static Manager& instance(); 58 59 void register_window (ProxyBase*); 60 void remove (const ProxyBase*); 61 void toggle_window (ProxyBase*); 62 void show_visible () const; 63 void set_session (ARDOUR::Session*); 64 void add_state (XMLNode&) const; 65 66 /* HACK HACK HACK */ 67 void set_transient_for (Gtk::Window*); transient_parent()68 Gtk::Window* transient_parent() const { return current_transient_parent; } 69 70 private: 71 typedef std::list<ProxyBase*> Windows; 72 Windows _windows; 73 Glib::RefPtr<Gtk::ActionGroup> window_actions; 74 Gtk::Window* current_transient_parent; 75 76 Manager(); 77 ~Manager(); 78 79 static Manager* _instance; 80 private: 81 void window_proxy_was_mapped (ProxyBase*); 82 void window_proxy_was_unmapped (ProxyBase*); 83 }; 84 85 class ProxyBase : public ARDOUR::SessionHandlePtr, public Gtkmm2ext::WindowProxy 86 { 87 public: 88 ProxyBase (const std::string& name, const std::string& menu_name); 89 ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&); 90 91 virtual ARDOUR::SessionHandlePtr* session_handle () = 0; 92 93 protected: 94 void setup (); 95 }; 96 97 class ProxyTemporary: public ProxyBase 98 { 99 public: 100 ProxyTemporary (const std::string& name, Gtk::Window* win); 101 102 Gtk::Window* get (bool create = false) { 103 (void) create; 104 return _window; 105 } 106 107 Gtk::Window* operator->() { 108 return _window; 109 } 110 111 ARDOUR::SessionHandlePtr* session_handle (); 112 explicit_delete()113 void explicit_delete () { _window = 0 ; delete this; } 114 }; 115 116 template<typename T> 117 class ProxyWithConstructor: public ProxyBase 118 { 119 public: ProxyWithConstructor(const std::string & name,const std::string & menu_name,const boost::function<T * ()> & c)120 ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c) 121 : ProxyBase (name, menu_name) , creator (c) {} 122 ProxyWithConstructor(const std::string & name,const std::string & menu_name,const boost::function<T * ()> & c,const XMLNode * node)123 ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node) 124 : ProxyBase (name, menu_name, *node) , creator (c) {} 125 126 Gtk::Window* get (bool create = false) { 127 if (!_window) { 128 if (!create) { 129 return 0; 130 } 131 132 _window = dynamic_cast<Gtk::Window*> (creator ()); 133 134 if (_window) { 135 setup (); 136 } 137 } 138 139 return _window; 140 } 141 142 T* operator->() { 143 return dynamic_cast<T*> (get (true)); 144 } 145 session_handle()146 ARDOUR::SessionHandlePtr* session_handle () { 147 /* may return null */ 148 return dynamic_cast<T*> (_window); 149 } 150 set_session(ARDOUR::Session * s)151 void set_session(ARDOUR::Session *s) { 152 SessionHandlePtr::set_session (s); 153 ARDOUR::SessionHandlePtr* sp = session_handle (); 154 if (sp) { 155 sp->set_session (s); 156 dynamic_cast<T*>(_window)->set_session(s); 157 } 158 } 159 160 private: 161 boost::function<T*()> creator; 162 }; 163 164 template<typename T> 165 class Proxy : public ProxyBase 166 { 167 public: Proxy(const std::string & name,const std::string & menu_name)168 Proxy (const std::string& name, const std::string& menu_name) 169 : ProxyBase (name, menu_name) {} 170 Proxy(const std::string & name,const std::string & menu_name,const XMLNode * node)171 Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node) 172 : ProxyBase (name, menu_name, *node) {} 173 174 Gtk::Window* get (bool create = false) { 175 if (!_window) { 176 if (!create) { 177 return 0; 178 } 179 180 _window = new T (); 181 182 if (_window) { 183 setup (); 184 } 185 } 186 187 return _window; 188 } 189 190 T* operator->() { 191 return dynamic_cast<T*> (get(true)); 192 } 193 session_handle()194 ARDOUR::SessionHandlePtr* session_handle () { 195 /* may return null */ 196 return dynamic_cast<T*> (_window); 197 } 198 set_session(ARDOUR::Session * s)199 void set_session(ARDOUR::Session *s) { 200 SessionHandlePtr::set_session (s); 201 ARDOUR::SessionHandlePtr* sp = session_handle (); 202 if (sp) { 203 sp->set_session (s); 204 dynamic_cast<T*>(_window)->set_session(s); 205 } 206 } 207 208 private: 209 boost::function<T*()> creator; 210 }; 211 212 } /* namespace */ 213 214 #endif /* __gtk2_ardour_window_manager_h__ */ 215