fix merge conflicts with master
[ardour.git] / gtk2_ardour / editor_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 "gtkmm2ext/utils.h"
21
22 #include "ardour/route_group.h"
23 #include "editor_group_tabs.h"
24 #include "editor.h"
25 #include "route_time_axis.h"
26 #include "utils.h"
27 #include "editor_route_groups.h"
28 #include "editor_routes.h"
29 #include "i18n.h"
30
31 using namespace std;
32 using namespace ARDOUR;
33
34 EditorGroupTabs::EditorGroupTabs (Editor* e)
35         : EditorComponent (e)
36 {
37
38 }
39
40 list<GroupTabs::Tab>
41 EditorGroupTabs::compute_tabs () const
42 {
43         list<Tab> tabs;
44
45         Tab tab;
46         tab.from = 0;
47         tab.group = 0;
48
49         int32_t y = 0;
50         for (TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
51
52                 if ((*i)->marked_for_display() == false) {
53                         continue;
54                 }
55
56                 RouteGroup* g = (*i)->route_group ();
57
58                 if (g != tab.group) {
59                         if (tab.group) {
60                                 tab.to = y;
61                                 tabs.push_back (tab);
62                         }
63
64                         tab.from = y;
65                         tab.group = g;
66                         if (g) {
67                                 tab.color = group_color (g);
68                         }
69                 }
70
71                 y += (*i)->effective_height ();
72         }
73
74         if (tab.group) {
75                 tab.to = y;
76                 tabs.push_back (tab);
77         }
78
79         return tabs;
80 }
81
82 void
83 EditorGroupTabs::draw_tab (cairo_t* cr, Tab const & tab) const
84 {
85         double const arc_radius = get_width();
86
87         if (tab.group && tab.group->is_active()) {
88                 cairo_set_source_rgba (cr, tab.color.get_red_p (), tab.color.get_green_p (), tab.color.get_blue_p (), 1);
89         } else {
90                 cairo_set_source_rgba (cr, 1, 1, 1, 0.2);
91         }
92
93         cairo_move_to (cr, 0, tab.from + arc_radius);
94         cairo_arc (cr, get_width(), tab.from + arc_radius, arc_radius, M_PI, 3 * M_PI / 2);
95         cairo_line_to (cr, get_width(), tab.to);
96         cairo_arc (cr, get_width(), tab.to - arc_radius, arc_radius, M_PI / 2, M_PI);
97         cairo_line_to (cr, 0, tab.from + arc_radius);
98         cairo_fill (cr);
99
100         if (tab.group) {
101                 pair<string, double> const f = Gtkmm2ext::fit_to_pixels (cr, tab.group->name(), tab.to - tab.from - arc_radius * 2);
102
103                 cairo_text_extents_t ext;
104                 cairo_text_extents (cr, tab.group->name().c_str(), &ext);
105
106                 cairo_set_source_rgb (cr, 1, 1, 1);
107                 cairo_move_to (cr, get_width() - ext.height / 2, tab.from + (f.second + tab.to - tab.from) / 2);
108                 cairo_save (cr);
109                 cairo_rotate (cr, - M_PI / 2);
110                 cairo_show_text (cr, f.first.c_str());
111                 cairo_restore (cr);
112         }
113 }
114
115 double
116 EditorGroupTabs::primary_coordinate (double, double y) const
117 {
118         return y;
119 }
120
121 RouteList
122 EditorGroupTabs::routes_for_tab (Tab const * t) const
123 {
124         RouteList routes;
125         int32_t y = 0;
126
127         for (TrackViewList::iterator i = _editor->track_views.begin(); i != _editor->track_views.end(); ++i) {
128
129                 if ((*i)->marked_for_display() == false) {
130                         continue;
131                 }
132
133                 RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
134                 if (rtv) {
135
136                         if (y >= t->to) {
137                                 /* tab finishes before this track starts */
138                                 break;
139                         }
140
141                         double const h = y + (*i)->effective_height() / 2;
142
143                         if (t->from < h && t->to > h) {
144                                 routes.push_back (rtv->route ());
145                         }
146                 }
147
148                 y += (*i)->effective_height ();
149         }
150
151         return routes;
152 }
153
154
155 void
156 EditorGroupTabs::add_menu_items (Gtk::Menu* m, RouteGroup* g)
157 {
158         using namespace Gtk::Menu_Helpers;
159
160         if (g) {
161                 MenuList& items = m->items ();
162                 items.push_back (MenuElem (_("Fit to Window"), sigc::bind (sigc::mem_fun (*_editor, &Editor::fit_route_group), g)));
163         }
164 }
165
166 PBD::PropertyList
167 EditorGroupTabs::default_properties () const
168 {
169         PBD::PropertyList plist;
170
171         plist.add (Properties::active, true);
172         plist.add (Properties::mute, true);
173         plist.add (Properties::solo, true);
174         plist.add (Properties::recenable, true);
175
176         return plist;
177 }
178
179 RouteList
180 EditorGroupTabs::selected_routes () const
181 {
182         RouteList rl;
183
184         for (TrackSelection::iterator i = _editor->get_selection().tracks.begin(); i != _editor->get_selection().tracks.end(); ++i) {
185                 RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
186                 if (rtv) {
187                         rl.push_back (rtv->route());
188                 }
189         }
190
191         return rl;
192 }
193
194 void
195 EditorGroupTabs::sync_order_keys ()
196 {
197         _editor->_routes->sync_order_keys_from_treeview ();
198 }