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