the big rework of window management. probably not complete at thsi point, but this...
[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 drop_window ();
72         void use_window (Gtk::Window&);
73
74         virtual Gtk::Window* get (bool create = false) = 0;
75
76         virtual void toggle ();
77
78         void set_state (const XMLNode&);
79         XMLNode& get_state () const;
80
81         virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
82
83         operator bool() const { return _window != 0; }
84
85       protected:
86         std::string  _name;
87         std::string  _menu_name;
88         Glib::RefPtr<Gtk::Action> _action;
89         Gtk::Window* _window;
90         mutable bool _visible; ///< true if the window should be visible on startup
91         mutable int  _x_off; ///< x position
92         mutable int  _y_off; ///< y position
93         mutable int  _width; ///< width
94         mutable int  _height; ///< height
95         Gtkmm2ext::VisibilityTracker* vistracker;
96
97         void setup ();
98     };
99
100     template<typename T>
101     class ProxyWithConstructor: public ProxyBase {
102       public:
103         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
104                 : ProxyBase (name, menu_name) , creator (c) {}
105         
106         ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
107                 : ProxyBase (name, menu_name, node) , creator (c) {}
108         
109         Gtk::Window* get (bool create = false) { 
110                 if (!_window) {
111                         if (!create) {
112                                 return 0;
113                         }
114
115                         _window = creator ();
116
117                         if (_window) {
118                                 setup ();
119                         }       
120                 }
121
122                 return _window;
123         }
124
125         T* operator->() { 
126                 return dynamic_cast<T*> (get (true));
127         }
128
129         ARDOUR::SessionHandlePtr* session_handle () {
130                 /* may return null */
131                 return dynamic_cast<T*> (_window);
132         }
133
134       private:
135         boost::function<T*()>   creator;
136     };
137
138     template<typename T>
139     class Proxy : public ProxyBase {
140       public:
141         Proxy (const std::string& name, const std::string& menu_name)
142                 : ProxyBase (name, menu_name) {}
143
144         Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
145                 : ProxyBase (name, menu_name, node)  {}
146         
147         Gtk::Window* get (bool create = false) { 
148                 if (!_window) {
149                         if (!create) {
150                                 return 0;
151                         }
152
153                         _window = new T ();
154
155                         if (_window) {
156                                 setup ();
157                         }       
158                 }
159
160                 return _window;
161         }
162
163         T* operator->() { 
164                 /* make return null */
165                 return dynamic_cast<T*> (_window);
166         }
167
168         ARDOUR::SessionHandlePtr* session_handle () {
169                 return dynamic_cast<T*> (get());
170         }
171
172       private:
173         boost::function<T*()>   creator;
174     };
175     
176     void register_window (ProxyBase*);
177     void remove (const ProxyBase*);
178     void toggle_window (ProxyBase*);
179     void show_visible () const;
180     void set_session (ARDOUR::Session*);
181     void add_state (XMLNode&) const;
182
183   private:
184     typedef std::list<ProxyBase*> Windows;
185     Windows _windows;
186     Glib::RefPtr<Gtk::ActionGroup> window_actions;
187
188     WindowManager();
189     ~WindowManager();
190
191     static WindowManager* _instance;
192 };
193
194 #endif /* __gtk2_ardour_window_manager_h__ */