replicate the remove-all-trailing whitespace commit(s) in master
[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/bindings.h"
31 #include "gtkmm2ext/window_proxy.h"
32
33 class XMLNode;
34
35 namespace Gtk {
36 class Window;
37 class Action;
38 }
39
40 namespace Gtkmm2ext {
41         class VisibilityTracker;
42 }
43
44 namespace ARDOUR {
45         class Session;
46         class SessionHandlePtr;
47 }
48
49 namespace WM {
50
51 class ProxyBase;
52
53 class Manager : public ARDOUR::SessionHandlePtr
54 {
55   public:
56         static Manager& instance();
57
58         void register_window (ProxyBase*);
59         void remove (const ProxyBase*);
60         void toggle_window (ProxyBase*);
61         void show_visible () const;
62         void set_session (ARDOUR::Session*);
63         void add_state (XMLNode&) const;
64
65         /* HACK HACK HACK */
66         void set_transient_for (Gtk::Window*);
67         Gtk::Window* transient_parent() const { return current_transient_parent; }
68
69                                         private:
70         typedef std::list<ProxyBase*> Windows;
71         Windows _windows;
72         Glib::RefPtr<Gtk::ActionGroup> window_actions;
73         Gtk::Window* current_transient_parent;
74
75         Manager();
76         ~Manager();
77
78         static Manager* _instance;
79 };
80
81 class ProxyBase : public ARDOUR::SessionHandlePtr, public Gtkmm2ext::WindowProxy
82 {
83   public:
84         ProxyBase (const std::string& name, const std::string& menu_name);
85         ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
86
87         virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
88
89   protected:
90         void setup ();
91 };
92
93 class ProxyTemporary: public ProxyBase
94 {
95   public:
96         ProxyTemporary (const std::string& name, Gtk::Window* win);
97         ~ProxyTemporary();
98
99         Gtk::Window* get (bool create = false) {
100                 (void) create;
101                 return _window;
102         }
103
104         Gtk::Window* operator->() {
105                 return _window;
106         }
107
108         ARDOUR::SessionHandlePtr* session_handle ();
109 };
110
111 template<typename T>
112 class ProxyWithConstructor: public ProxyBase
113 {
114   public:
115         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
116                 : ProxyBase (name, menu_name) , creator (c) {}
117
118         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
119                 : ProxyBase (name, menu_name, *node) , creator (c) {}
120
121         Gtk::Window* get (bool create = false) {
122                 if (!_window) {
123                         if (!create) {
124                                 return 0;
125                         }
126
127                         _window = dynamic_cast<Gtk::Window*> (creator ());
128
129                         if (_window) {
130                                 setup ();
131                         }
132                 }
133
134                 return _window;
135         }
136
137         T* operator->() {
138                 return dynamic_cast<T*> (get (true));
139         }
140
141         ARDOUR::SessionHandlePtr* session_handle () {
142                 /* may return null */
143                 return dynamic_cast<T*> (_window);
144         }
145
146         void set_session(ARDOUR::Session *s) {
147                 SessionHandlePtr::set_session (s);
148                 ARDOUR::SessionHandlePtr* sp = session_handle ();
149                 if (sp) {
150                         sp->set_session (s);
151                         dynamic_cast<T*>(_window)->set_session(s);
152                 }
153         }
154
155                                         private:
156         boost::function<T*()>   creator;
157 };
158
159 template<typename T>
160 class Proxy : public ProxyBase
161 {
162   public:
163         Proxy (const std::string& name, const std::string& menu_name)
164                 : ProxyBase (name, menu_name) {}
165
166         Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
167                 : ProxyBase (name, menu_name, *node)  {}
168
169         Gtk::Window* get (bool create = false) {
170                 if (!_window) {
171                         if (!create) {
172                                 return 0;
173                         }
174
175                         _window = new T ();
176
177                         if (_window) {
178                                 setup ();
179                         }
180                 }
181
182                 return _window;
183         }
184
185         T* operator->() {
186                 return dynamic_cast<T*> (get(true));
187         }
188
189         ARDOUR::SessionHandlePtr* session_handle () {
190                 /* may return null */
191                 return dynamic_cast<T*> (_window);
192         }
193
194         void set_session(ARDOUR::Session *s) {
195                 SessionHandlePtr::set_session (s);
196                 ARDOUR::SessionHandlePtr* sp = session_handle ();
197                 if (sp) {
198                         sp->set_session (s);
199                         dynamic_cast<T*>(_window)->set_session(s);
200                 }
201         }
202
203   private:
204         boost::function<T*()>   creator;
205 };
206
207 } /* namespace */
208
209 #endif /* __gtk2_ardour_window_manager_h__ */