VisibilityTracker needs to inherit from sigc::tracker so that it can be used without...
[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 class XMLNode;
31
32 namespace Gtk {
33         class Window;
34         class Action;
35 }
36
37 namespace Gtkmm2ext {
38         class VisibilityTracker;
39 }
40
41 namespace ARDOUR {
42         class Session;
43         class SessionHandlePtr;
44 }
45
46 class WindowManager 
47 {
48   public:
49     static WindowManager& instance();
50
51     class ProxyBase : public sigc::trackable {
52       public:
53         ProxyBase (const std::string& name, const std::string& menu_name);
54         ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
55         virtual ~ProxyBase();
56
57         void show ();
58         void show_all ();
59         void hide ();
60         void present ();
61         void maybe_show ();
62
63         bool visible() const { return _visible; }
64         const std::string& name() const { return _name; }
65         const std::string& menu_name() const { return _menu_name; }
66
67         std::string action_name() const;
68         void set_action (Glib::RefPtr<Gtk::Action>);
69         Glib::RefPtr<Gtk::Action> action() const { return _action; };
70         
71         void clear ();
72         void use_window (Gtk::Window&);
73
74         virtual Gtk::Window* get (bool create = false) = 0;
75
76         virtual bool rc_configured() const { return true; }
77         virtual void toggle ();
78
79         void set_state (const XMLNode&);
80         XMLNode& get_state () const;
81
82         virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
83
84         operator bool() const { return _window != 0; }
85
86       protected:
87         std::string  _name;
88         std::string  _menu_name;
89         Glib::RefPtr<Gtk::Action> _action;
90         Gtk::Window* _window;
91         bool         _visible; ///< true if the window should be visible on startup
92         int          _x_off; ///< x position
93         int          _y_off; ///< y position
94         int          _width; ///< width
95         int          _height; ///< height
96         Gtkmm2ext::VisibilityTracker* vistracker;
97         sigc::connection configure_connection;
98
99         void setup ();
100         bool configured (GdkEventConfigure*);
101     };
102
103     template<typename T>
104     class ProxyWithConstructor: public ProxyBase {
105       public:
106         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
107                 : ProxyBase (name, menu_name) , creator (c) {}
108         
109         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
110                 : ProxyBase (name, menu_name, node) , creator (c) {}
111         
112         Gtk::Window* get (bool create = false) { 
113                 if (!_window) {
114                         if (!create) {
115                                 return 0;
116                         }
117
118                         _window = creator ();
119
120                         if (_window) {
121                                 setup ();
122                         }       
123                 }
124
125                 return _window;
126         }
127
128         T* operator->() { 
129                 return dynamic_cast<T*> (get (true));
130         }
131
132         ARDOUR::SessionHandlePtr* session_handle () {
133                 /* may return null */
134                 return dynamic_cast<T*> (_window);
135         }
136
137       private:
138         boost::function<T*()>   creator;
139     };
140
141     template<typename T>
142     class Proxy : public ProxyBase {
143       public:
144         Proxy (const std::string& name, const std::string& menu_name)
145                 : ProxyBase (name, menu_name) {}
146
147         Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
148                 : ProxyBase (name, menu_name, node)  {}
149         
150         Gtk::Window* get (bool create = false) { 
151                 if (!_window) {
152                         if (!create) {
153                                 return 0;
154                         }
155
156                         _window = new T ();
157
158                         if (_window) {
159                                 setup ();
160                         }       
161                 }
162
163                 return _window;
164         }
165
166         T* operator->() { 
167                 /* make return null */
168                 return dynamic_cast<T*> (_window);
169         }
170
171         ARDOUR::SessionHandlePtr* session_handle () {
172                 return dynamic_cast<T*> (get());
173         }
174
175       private:
176         boost::function<T*()>   creator;
177     };
178     
179     void register_window (ProxyBase*);
180     void remove (const ProxyBase*);
181     void toggle_window (ProxyBase*);
182     void show_visible () const;
183     void set_session (ARDOUR::Session*);
184     void add_state (XMLNode&) const;
185
186   private:
187     typedef std::list<ProxyBase*> Windows;
188     Windows _windows;
189     Glib::RefPtr<Gtk::ActionGroup> window_actions;
190
191     WindowManager();
192     ~WindowManager();
193
194     static WindowManager* _instance;
195 };
196
197 #endif /* __gtk2_ardour_window_manager_h__ */