initial versions of Tabbable object
[ardour.git] / libs / gtkmm2ext / tabbable.cc
1 /*
2     Copyright (C) 2015 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 #include <gtkmm/action.h>
21 #include <gtkmm/notebook.h>
22 #include <gtkmm/window.h>
23
24 #include "gtkmm2ext/tabbable.h"
25 #include "gtkmm2ext/visibility_tracker.h"
26
27 using namespace Gtkmm2ext;
28 using namespace Gtk;
29 using std::string;
30
31 Tabbable::Tabbable (Widget& w)
32         : _contents (w)
33 {
34 }
35
36 Tabbable::~Tabbable ()
37 {
38         if (_window) {
39                 delete _window;
40                 _window = 0;
41         }
42 }
43
44 void
45 Tabbable::add_to_notebook (Notebook& notebook, const string& tab_title, int position)
46 {
47         notebook.insert_page (_contents, tab_title, position, false);
48         notebook.set_tab_detachable (_contents);
49
50         _parent_notebook = &notebook;
51         _tab_title = tab_title;
52         _notebook_position = position;
53 }
54
55 Window*
56 Tabbable::use_own_window ()
57 {
58         return get (true);
59 }
60
61 bool
62 Tabbable::window_visible ()
63 {
64         if (!own_window()) {
65                 return false;
66         }
67
68         return visible();
69 }
70
71 Window*
72 Tabbable::get (bool create)
73 {
74         if (_window) {
75                 return _window;
76         }
77
78         if (!create) {
79                 return 0;
80         }
81         
82         if ((_window = new Window (WINDOW_TOPLEVEL)) == 0) {
83                 return 0;
84         }
85
86         /* allow parent window to become the key focus window */
87         _window->set_flags (CAN_FOCUS);
88
89         return _window;
90 }
91
92 void
93 Tabbable::show_window ()
94 {
95         Window* toplevel = dynamic_cast<Window*> (_contents.get_toplevel());
96
97         if (toplevel == _window) {
98                 _window->present ();
99         }
100
101         if (!_visible) { /* was hidden, update status */
102                 set_pos_and_size ();
103         }
104
105         if (toplevel != _window) {
106                 /* not in its own window, just switch parent notebook to show
107                    this Tabbable.
108                 */
109                 if (_parent_notebook) {
110                         _parent_notebook->set_current_page (_notebook_position);
111                 }
112         }
113 }
114
115 bool
116 Tabbable::delete_event_handler (GdkEventAny *ev)
117 {
118         Window* toplevel = dynamic_cast<Window*> (_contents.get_toplevel());
119
120         if (_window == toplevel) {
121
122                 /* unpack Tabbable from parent, put it back in the main tabbed
123                  * notebook
124                  */
125
126                 save_pos_and_size ();
127
128                 _contents.get_parent()->remove (_contents);
129
130                 /* leave the window around */
131
132                 _window->hide ();
133                 
134                 if (_parent_notebook) {
135                         
136                         _parent_notebook->insert_page (_contents, _tab_title, _notebook_position);
137                         _parent_notebook->set_tab_detachable (_contents);
138                 }
139
140                 show_all ();
141
142                 /* don't let anything else handle this */
143                 
144                 return true;
145         } 
146
147         /* nothing to do */
148         return false;
149 }
150
151 bool
152 Tabbable::is_tabbed () const
153 {
154         Window* toplevel = (Window*) _contents.get_toplevel();
155
156         if (_window && (toplevel == _window)) {
157                 return false;
158         }
159
160         if (_parent_notebook) {
161                 return true;
162         }
163         
164         return false;
165 }