additional i18n.h changes for push2 branch
[ardour.git] / libs / surfaces / push2 / menu.cc
1 /*
2         Copyright (C) 2016 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 #include <cairomm/context.h>
20 #include <cairomm/surface.h>
21 #include <pangomm/layout.h>
22
23 #include "push2.h"
24 #include "gui.h"
25
26 using namespace ARDOUR;
27 using namespace std;
28 using namespace PBD;
29 using namespace Glib;
30 using namespace ArdourSurface;
31
32 #include "pbd/i18n.h"
33 #include "menu.h"
34
35 Push2Menu::Push2Menu (Cairo::RefPtr<Cairo::Context> context)
36         : _dirty (true)
37 {
38         Pango::FontDescription fd2 ("Sans 10");
39
40         {
41                 Glib::RefPtr<Pango::Layout> throwaway = Pango::Layout::create (context);
42                 throwaway->set_font_description (fd2);
43                 throwaway->set_text (X_("Hg")); /* ascender + descender) */
44                 int h, w;
45                 throwaway->get_pixel_size (w, h);
46                 baseline = h;
47                 nrows = Push2::rows / baseline;
48         }
49
50         for (int n = 0; n < 8; ++n) {
51                 columns[n].layout = Pango::Layout::create (context);
52                 columns[n].layout->set_font_description (fd2);
53                 columns[n].top = -1;
54                 columns[n].active = -1;
55         }
56 }
57
58 void
59 Push2Menu::fill_column (int col, vector<string> v)
60 {
61         if (col < 0 || col > 7) {
62                 return;
63         }
64
65         columns[col].text = v;
66
67         if (v.empty()) {
68                 columns[col].active = -1;
69         } else {
70                 columns[col].active = 0;
71         }
72
73         set_text (col, 0);
74
75         _dirty = true;
76 }
77
78 void
79 Push2Menu::set_text (int col, int top_row)
80 {
81         if (top_row > (int) columns[col].text.size() - nrows || top_row < 0) {
82                 return;
83         }
84
85         if (top_row == columns[col].top) {
86                 return;
87         }
88
89         vector<string>::iterator s = columns[col].text.begin();
90         s += top_row;
91
92         string rows;
93
94         while (true) {
95                 rows += *s;
96                 ++s;
97                 if (s != columns[col].text.end()) {
98                         rows += '\n';
99                 } else {
100                         break;
101                 }
102         }
103
104         columns[col].layout->set_text (rows);
105         columns[col].top = top_row;
106
107         _dirty = true;
108 }
109
110 void
111 Push2Menu::scroll (int col, int dir)
112 {
113         if (dir > 0) {
114                 set_text (col, columns[col].top + 1);
115         } else {
116                 set_text (col, columns[col].top - 1);
117         }
118 }
119
120 void
121 Push2Menu::set_active (int col, int index)
122 {
123         if (col < 0 || col > 7) {
124                 return;
125         }
126
127         if (index < 0 || index > (int) columns[col].text.size()) {
128                 return;
129         }
130
131         columns[col].active = index;
132
133         ActiveChanged (); /* emit signal */
134
135         _dirty = true;
136 }
137
138 void
139 Push2Menu::step_active (int col, int dir)
140 {
141         if (col < 0 || col > 7) {
142                 return;
143         }
144
145         if (columns[col].text.empty()) {
146                 return;
147         }
148
149
150         if (dir < 0) {
151                 if (columns[col].active == -1) {
152                         columns[col].active = 0;
153                 } else {
154                         columns[col].active = columns[col].active - 1;
155                         if (columns[col].active < 0) {
156                                 columns[col].active = columns[col].text.size() - 1;
157                         }
158                 }
159         } else {
160                 if (columns[col].active == -1) {
161                         columns[col].active = 0;
162                 } else {
163                         columns[col].active = columns[col].active + 1;
164                         if (columns[col].active >= (int) columns[col].text.size()) {
165                                 columns[col].active = 0;
166                         }
167                 }
168         }
169
170         if (columns[col].active < nrows/2) {
171                 set_text (col, 0);
172         } else {
173                 set_text (col, columns[col].active - (nrows/2) + 1);
174         }
175
176         _dirty = true;
177 }
178
179 int
180 Push2Menu::get_active (int col)
181 {
182         if (col < 0 || col > 7) {
183                 return -1;
184         }
185
186         return columns[col].active;
187 }
188
189 void
190 Push2Menu::redraw (Cairo::RefPtr<Cairo::Context> context, bool force) const
191 {
192         for (int n = 0; n < 8; ++n) {
193
194                 /* Active: move to column/now, draw background indicator
195                    for active row.
196                 */
197
198                 const double x = 10.0 + (n * 120.0);
199                 const double y = 2.0;
200
201                 if (columns[n].active >= 0) {
202                         int effective_row = columns[n].active - columns[n].top;
203                         context->rectangle (x, y + (effective_row * baseline), 120.0, baseline);
204                         context->set_source_rgb (1.0, 1.0, 1.0);
205                         context->fill ();
206                 }
207
208                 /* now draw all the text, in one go */
209
210                 context->move_to (x, y);
211                 context->set_source_rgb (0.23, 0.0, 0.349);
212                 columns[n].layout->update_from_cairo_context (context);
213                 columns[n].layout->show_in_cairo_context (context);
214
215         }
216
217         _dirty = false;
218 }