AU: mark preset dirty when parameter changes
[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 private:
80         void window_proxy_was_mapped (ProxyBase*);
81         void window_proxy_was_unmapped (ProxyBase*);
82 };
83
84 class ProxyBase : public ARDOUR::SessionHandlePtr, public Gtkmm2ext::WindowProxy
85 {
86 public:
87         ProxyBase (const std::string& name, const std::string& menu_name);
88         ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
89
90         virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
91
92 protected:
93         void setup ();
94 };
95
96 class ProxyTemporary: public ProxyBase
97 {
98 public:
99         ProxyTemporary (const std::string& name, Gtk::Window* win);
100
101         Gtk::Window* get (bool create = false) {
102                 (void) create;
103                 return _window;
104         }
105
106         Gtk::Window* operator->() {
107                 return _window;
108         }
109
110         ARDOUR::SessionHandlePtr* session_handle ();
111
112         void explicit_delete () { _window = 0 ; delete this; }
113 };
114
115 template<typename T>
116 class ProxyWithConstructor: public ProxyBase
117 {
118 public:
119         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
120                 : ProxyBase (name, menu_name) , creator (c) {}
121
122         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
123                 : ProxyBase (name, menu_name, *node) , creator (c) {}
124
125         Gtk::Window* get (bool create = false) {
126                 if (!_window) {
127                         if (!create) {
128                                 return 0;
129                         }
130
131                         _window = dynamic_cast<Gtk::Window*> (creator ());
132
133                         if (_window) {
134                                 setup ();
135                         }
136                 }
137
138                 return _window;
139         }
140
141         T* operator->() {
142                 return dynamic_cast<T*> (get (true));
143         }
144
145         ARDOUR::SessionHandlePtr* session_handle () {
146                 /* may return null */
147                 return dynamic_cast<T*> (_window);
148         }
149
150         void set_session(ARDOUR::Session *s) {
151                 SessionHandlePtr::set_session (s);
152                 ARDOUR::SessionHandlePtr* sp = session_handle ();
153                 if (sp) {
154                         sp->set_session (s);
155                         dynamic_cast<T*>(_window)->set_session(s);
156                 }
157         }
158
159 private:
160         boost::function<T*()>   creator;
161 };
162
163 template<typename T>
164 class Proxy : public ProxyBase
165 {
166 public:
167         Proxy (const std::string& name, const std::string& menu_name)
168                 : ProxyBase (name, menu_name) {}
169
170         Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
171                 : ProxyBase (name, menu_name, *node)  {}
172
173         Gtk::Window* get (bool create = false) {
174                 if (!_window) {
175                         if (!create) {
176                                 return 0;
177                         }
178
179                         _window = new T ();
180
181                         if (_window) {
182                                 setup ();
183                         }
184                 }
185
186                 return _window;
187         }
188
189         T* operator->() {
190                 return dynamic_cast<T*> (get(true));
191         }
192
193         ARDOUR::SessionHandlePtr* session_handle () {
194                 /* may return null */
195                 return dynamic_cast<T*> (_window);
196         }
197
198         void set_session(ARDOUR::Session *s) {
199                 SessionHandlePtr::set_session (s);
200                 ARDOUR::SessionHandlePtr* sp = session_handle ();
201                 if (sp) {
202                         sp->set_session (s);
203                         dynamic_cast<T*>(_window)->set_session(s);
204                 }
205         }
206
207 private:
208         boost::function<T*()>   creator;
209 };
210
211 } /* namespace */
212
213 #endif /* __gtk2_ardour_window_manager_h__ */