merge with master
[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 namespace WM {
47
48 class ProxyBase;
49
50 class Manager 
51 {
52   public:
53     static Manager& instance();
54
55     void register_window (ProxyBase*);
56     void remove (const ProxyBase*);
57     void toggle_window (ProxyBase*);
58     void show_visible () const;
59     void set_session (ARDOUR::Session*);
60     void add_state (XMLNode&) const;
61
62     /* HACK HACK HACK */
63     void set_transient_for (Gtk::Window*);
64     Gtk::Window* transient_parent() const { return current_transient_parent; }
65
66   private:
67     typedef std::list<ProxyBase*> Windows;
68     Windows _windows;
69     Glib::RefPtr<Gtk::ActionGroup> window_actions;
70     Gtk::Window* current_transient_parent;
71
72     Manager();
73     ~Manager();
74
75     static Manager* _instance;
76 };
77         
78 class ProxyBase : public sigc::trackable {
79   public:
80     ProxyBase (const std::string& name, const std::string& menu_name);
81     ProxyBase (const std::string& name, const std::string& menu_name, const XMLNode&);
82     virtual ~ProxyBase();
83     
84     void show ();
85     void show_all ();
86     void hide ();
87     void present ();
88     void maybe_show ();
89     
90     bool visible() const { return _visible; }
91     const std::string& name() const { return _name; }
92     const std::string& menu_name() const { return _menu_name; }
93     
94     std::string action_name() const;
95     void set_action (Glib::RefPtr<Gtk::Action>);
96     Glib::RefPtr<Gtk::Action> action() const { return _action; };
97     
98     void drop_window ();
99     void use_window (Gtk::Window&);
100     
101     virtual Gtk::Window* get (bool create = false) = 0;
102     
103     virtual void toggle ();
104     
105     void set_state (const XMLNode&);
106     XMLNode& get_state () const;
107     
108     virtual ARDOUR::SessionHandlePtr* session_handle () = 0;
109     
110     operator bool() const { return _window != 0; }
111     
112   protected:
113     std::string  _name;
114     std::string  _menu_name;
115     Glib::RefPtr<Gtk::Action> _action;
116     Gtk::Window* _window;
117     mutable bool _visible; ///< true if the window should be visible on startup
118     mutable int  _x_off; ///< x position
119     mutable int  _y_off; ///< y position
120     mutable int  _width; ///< width
121     mutable int  _height; ///< height
122     Gtkmm2ext::VisibilityTracker* vistracker;
123     
124     void setup ();
125 };
126         
127 class ProxyTemporary: public ProxyBase {
128   public:
129     ProxyTemporary (const std::string& name, Gtk::Window* win);
130     ~ProxyTemporary();
131     
132     Gtk::Window* get (bool create = false) { 
133             (void) create;
134             return _window;
135     }
136     
137     Gtk::Window* operator->() { 
138             return _window;
139     }
140     
141     ARDOUR::SessionHandlePtr* session_handle ();
142 };
143         
144 template<typename T>
145 class ProxyWithConstructor: public ProxyBase {
146   public:
147     ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c)
148             : ProxyBase (name, menu_name) , creator (c) {}
149         
150     ProxyWithConstructor (const std::string& name, const std::string& menu_name, const boost::function<T*()>& c, const XMLNode* node)
151             : ProxyBase (name, menu_name, node) , creator (c) {}
152         
153     Gtk::Window* get (bool create = false) { 
154             if (!_window) {
155                     if (!create) {
156                             return 0;
157                     }
158
159                     _window = creator ();
160
161                     if (_window) {
162                             setup ();
163                     }   
164             }
165
166             return _window;
167     }
168
169     T* operator->() { 
170             return dynamic_cast<T*> (get (true));
171     }
172
173     ARDOUR::SessionHandlePtr* session_handle () {
174             /* may return null */
175             return dynamic_cast<T*> (_window);
176     }
177
178   private:
179     boost::function<T*()>       creator;
180 };
181
182 template<typename T>
183 class Proxy : public ProxyBase {
184   public:
185     Proxy (const std::string& name, const std::string& menu_name)
186             : ProxyBase (name, menu_name) {}
187
188     Proxy (const std::string& name, const std::string& menu_name, const XMLNode* node)
189             : ProxyBase (name, menu_name, node)  {}
190         
191     Gtk::Window* get (bool create = false) { 
192             if (!_window) {
193                     if (!create) {
194                             return 0;
195                     }
196
197                     _window = new T ();
198
199                     if (_window) {
200                             setup ();
201                     }   
202             }
203
204             return _window;
205     }
206
207     T* operator->() { 
208             return dynamic_cast<T*> (get(true));
209     }
210
211     ARDOUR::SessionHandlePtr* session_handle () {
212             /* may return null */
213             return dynamic_cast<T*> (_window);
214     }
215
216   private:
217     boost::function<T*()>       creator;
218 };
219     
220 } /* namespace */
221
222 #endif /* __gtk2_ardour_window_manager_h__ */