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