first compilable version of tabbable design.
[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 >>>>>>> first compilable version of tabbable design.
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__ */