Use the same menu for the editor route group list and the editor group tabs.
[ardour.git] / gtk2_ardour / group_tabs.cc
1 /*
2     Copyright (C) 2009 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/stock.h>
21 #include "ardour/session.h"
22 #include "ardour/route_group.h"
23 #include "route_group_dialog.h"
24 #include "group_tabs.h"
25 #include "i18n.h"
26
27 using namespace std;
28 using namespace Gtk;
29 using namespace ARDOUR;
30
31 GroupTabs::GroupTabs ()
32         : _session (0),
33           _dragging (0)
34 {
35
36 }
37
38 void
39 GroupTabs::set_session (Session* s)
40 {
41         _session = s;
42         s->RouteGroupChanged.connect (mem_fun (*this, &GroupTabs::set_dirty));
43 }
44
45
46 /** Handle a size request.
47  *  @param req GTK requisition
48  */
49 void
50 GroupTabs::on_size_request (Gtk::Requisition *req)
51 {
52         /* Use a dummy, small width and the actual height that we want */
53         req->width = 16;
54         req->height = 16;
55 }
56
57 bool
58 GroupTabs::on_button_press_event (GdkEventButton* ev)
59 {
60         using namespace Menu_Helpers;
61
62         double const p = primary_coordinate (ev->x, ev->y);
63
64         Tab* prev;
65         Tab* next;
66         Tab* t = click_to_tab (p, &prev, &next);
67         if (t == 0) {
68                 return false;
69         }
70
71         if (ev->button == 1) {
72
73                 _dragging = t;
74                 _drag_moved = false;
75                 _drag_last = p;
76
77                 double const h = (t->from + t->to) / 2;
78                 _drag_from = p < h;
79
80                 if (_drag_from) {
81                         _drag_limit = prev ? prev->to : 0;
82                 } else {
83                         _drag_limit = next ? next->from : extent ();
84                 }
85
86         } else if (ev->button == 3) {
87
88                 get_menu(t->group)->popup (ev->button, ev->time);
89                 
90         }
91
92         return true;
93 }
94
95
96 bool
97 GroupTabs::on_motion_notify_event (GdkEventMotion* ev)
98 {
99         if (_dragging == 0) {
100                 return false;
101         }
102
103         double const p = primary_coordinate (ev->x, ev->y);
104         
105         if (p != _drag_last) {
106                 _drag_moved = true;
107         }
108
109         if (_drag_from) {
110                 
111                 double f = _dragging->from + p - _drag_last;
112                 
113                 if (f < _drag_limit) {
114                         f = _drag_limit;
115                 }
116
117                 double const t = _dragging->to - _dragging->last_ui_size;
118                 if (f > t) {
119                         f = t;
120                 }
121                 
122                 _dragging->from = f;
123                 
124         } else {
125                 
126                 double t = _dragging->to + p - _drag_last;
127
128                 if (t > _drag_limit) {
129                         t = _drag_limit;
130                 }
131
132                 double const f = _dragging->from + _dragging->first_ui_size;
133                 if (t < f) {
134                         t = f;
135                 }
136                 
137                 _dragging->to = t;
138         }
139
140         set_dirty ();
141         queue_draw ();
142
143         _drag_last = p;
144         
145         return true;
146 }
147
148
149 bool
150 GroupTabs::on_button_release_event (GdkEventButton* ev)
151 {
152         if (_dragging == 0) {
153                 return false;
154         }
155
156         if (!_drag_moved) {
157                 _dragging->group->set_active (!_dragging->group->is_active (), this);
158                 _dragging = 0;
159         } else {
160                 _dragging = 0;
161                 reflect_tabs (_tabs);
162                 set_dirty ();
163                 queue_draw ();
164         }
165
166         return true;
167 }
168
169 void
170 GroupTabs::render (cairo_t* cr)
171 {
172         if (_dragging == 0) {
173                 _tabs = compute_tabs ();
174         }
175
176         /* background */
177         
178         cairo_set_source_rgb (cr, 0, 0, 0);
179         cairo_rectangle (cr, 0, 0, _width, _height);
180         cairo_fill (cr);
181
182         /* tabs */
183
184         for (list<Tab>::const_iterator i = _tabs.begin(); i != _tabs.end(); ++i) {
185                 draw_tab (cr, *i);
186         }       
187 }
188
189
190 GroupTabs::Tab *
191 GroupTabs::click_to_tab (double c, Tab** prev, Tab** next)
192 {
193         list<Tab>::iterator i = _tabs.begin ();
194         while (i != _tabs.end() && (c < i->from || c > i->to)) {
195                 *prev = &(*i);
196                 ++i;
197         }
198
199         if (i == _tabs.end()) {
200                 *next = 0;
201                 return 0;
202         }
203
204         list<Tab>::iterator j = i;
205         ++j;
206         if (j == _tabs.end()) {
207                 *next = 0;
208         } else {
209                 *next = &(*j);
210         }
211
212         return &(*i);
213 }
214