1 /*
2 * Copyright (C) 2010-2015 David Robillard <d@drobilla.net>
3 * Copyright (C) 2010-2018 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2012-2015 Tim Mayberry <mojofunk@gmail.com>
5 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <iostream>
23
24 #include "pbd/file_utils.h"
25
26 #include "gtkmm2ext/actions.h"
27 #include "gtkmm2ext/keyboard.h"
28
29 #include "widgets/tooltips.h"
30
31 #include "ardour/filesystem_paths.h"
32
33 #include "midi_channel_selector.h"
34 #include "midi_time_axis.h"
35 #include "step_editor.h"
36 #include "step_entry.h"
37 #include "utils.h"
38
39 #include "pbd/i18n.h"
40
41 using namespace std;
42 using namespace Gtk;
43 using namespace Glib;
44 using namespace Gtkmm2ext;
45 using namespace PBD;
46 using namespace ARDOUR;
47 using namespace ARDOUR_UI_UTILS;
48 using namespace ArdourWidgets;
49
50 Gtkmm2ext::Bindings* StepEntry::bindings = 0;
51 StepEntry* StepEntry::_instance = 0;
52
53 StepEntry&
instance()54 StepEntry::instance()
55 {
56 if (!_instance) {
57 _instance = new StepEntry;
58 }
59
60 return *_instance;
61 }
62
StepEntry()63 StepEntry::StepEntry ()
64 : ArdourWindow (string())
65 , _current_note_length (1.0)
66 , _current_note_velocity (64)
67 , triplet_button ("3")
68 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
69 , beat_resync_button (_(">beat"))
70 , bar_resync_button (_(">bar"))
71 , resync_button (_(">EP"))
72 , sustain_button (_("sustain"))
73 , rest_button (_("rest"))
74 , grid_rest_button (_("g-rest"))
75 , back_button (_("back"))
76 , channel_adjustment (1, 1, 16, 1, 4)
77 , channel_spinner (channel_adjustment)
78 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
79 , octave_spinner (octave_adjustment)
80 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
81 , length_divisor_spinner (length_divisor_adjustment)
82 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
83 , velocity_spinner (velocity_adjustment)
84 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
85 , bank_spinner (bank_adjustment)
86 , bank_button (_("+"))
87 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
88 , program_spinner (program_adjustment)
89 , program_button (_("+"))
90 , se (0)
91 {
92 set_data ("ardour-bindings", bindings);
93
94 RadioButtonGroup length_group = length_1_button.get_group();
95 length_2_button.set_group (length_group);
96 length_4_button.set_group (length_group);
97 length_8_button.set_group (length_group);
98 length_12_button.set_group (length_group);
99 length_16_button.set_group (length_group);
100 length_32_button.set_group (length_group);
101 length_64_button.set_group (length_group);
102
103 Widget* w;
104
105 w = manage (new Image (::get_icon (X_("wholenote"))));
106 w->show();
107 length_1_button.add (*w);
108 w = manage (new Image (::get_icon (X_("halfnote"))));
109 w->show();
110 length_2_button.add (*w);
111 w = manage (new Image (::get_icon (X_("quarternote"))));
112 w->show();
113 length_4_button.add (*w);
114 w = manage (new Image (::get_icon (X_("eighthnote"))));
115 w->show();
116 length_8_button.add (*w);
117 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
118 w->show();
119 length_16_button.add (*w);
120 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
121 w->show();
122 length_32_button.add (*w);
123 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
124 w->show();
125 length_64_button.add (*w);
126
127 RefPtr<Action> act;
128
129 act = ActionManager::get_action ("StepEditing/note-length-whole");
130 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
131 act = ActionManager::get_action ("StepEditing/note-length-half");
132 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
133 act = ActionManager::get_action ("StepEditing/note-length-quarter");
134 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
135 act = ActionManager::get_action ("StepEditing/note-length-eighth");
136 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
137 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
138 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
139 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
140 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
141 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
142 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
143
144 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
145 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
146 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
147 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
148 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
149 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
150 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
151 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
152 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
153 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
154 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
155 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
156 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
157 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
158
159 length_1_button.property_draw_indicator() = false;
160 length_2_button.property_draw_indicator() = false;
161 length_4_button.property_draw_indicator() = false;
162 length_8_button.property_draw_indicator() = false;
163 length_16_button.property_draw_indicator() = false;
164 length_32_button.property_draw_indicator() = false;
165 length_64_button.property_draw_indicator() = false;
166
167 note_length_box.pack_start (length_1_button, false, false);
168 note_length_box.pack_start (length_2_button, false, false);
169 note_length_box.pack_start (length_4_button, false, false);
170 note_length_box.pack_start (length_8_button, false, false);
171 note_length_box.pack_start (length_16_button, false, false);
172 note_length_box.pack_start (length_32_button, false, false);
173 note_length_box.pack_start (length_64_button, false, false);
174
175 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
176 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
177 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
178 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
179 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
180 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
181 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
182
183 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
184 velocity_pp_button.set_group (velocity_group);
185 velocity_p_button.set_group (velocity_group);
186 velocity_mp_button.set_group (velocity_group);
187 velocity_mf_button.set_group (velocity_group);
188 velocity_f_button.set_group (velocity_group);
189 velocity_ff_button.set_group (velocity_group);
190 velocity_fff_button.set_group (velocity_group);
191
192 w = manage (new Image (::get_icon (X_("pianississimo"))));
193 w->show();
194 velocity_ppp_button.add (*w);
195 w = manage (new Image (::get_icon (X_("pianissimo"))));
196 w->show();
197 velocity_pp_button.add (*w);
198 w = manage (new Image (::get_icon (X_("piano"))));
199 w->show();
200 velocity_p_button.add (*w);
201 w = manage (new Image (::get_icon (X_("mezzopiano"))));
202 w->show();
203 velocity_mp_button.add (*w);
204 w = manage (new Image (::get_icon (X_("mezzoforte"))));
205 w->show();
206 velocity_mf_button.add (*w);
207 w = manage (new Image (::get_icon (X_("forte"))));
208 w->show();
209 velocity_f_button.add (*w);
210 w = manage (new Image (::get_icon (X_("fortissimo"))));
211 w->show();
212 velocity_ff_button.add (*w);
213 w = manage (new Image (::get_icon (X_("fortississimo"))));
214 w->show();
215 velocity_fff_button.add (*w);
216
217 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
218 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
219 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
220 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
221 act = ActionManager::get_action ("StepEditing/note-velocity-p");
222 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
223 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
224 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
225 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
226 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
227 act = ActionManager::get_action ("StepEditing/note-velocity-f");
228 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
229 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
230 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
231 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
232 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
233
234 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
235 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
236 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
237 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
238 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
239 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
240 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
241 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
242 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
243 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
244 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
245 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
246 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
247 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
248 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
249 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
250
251 velocity_ppp_button.property_draw_indicator() = false;
252 velocity_pp_button.property_draw_indicator() = false;
253 velocity_p_button.property_draw_indicator() = false;
254 velocity_mp_button.property_draw_indicator() = false;
255 velocity_mf_button.property_draw_indicator() = false;
256 velocity_f_button.property_draw_indicator() = false;
257 velocity_ff_button.property_draw_indicator() = false;
258 velocity_fff_button.property_draw_indicator() = false;
259
260 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
261 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
262 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
263 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
264 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
265 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
266 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
267 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
268
269 note_velocity_box.pack_start (velocity_ppp_button, false, false);
270 note_velocity_box.pack_start (velocity_pp_button, false, false);
271 note_velocity_box.pack_start (velocity_p_button, false, false);
272 note_velocity_box.pack_start (velocity_mp_button, false, false);
273 note_velocity_box.pack_start (velocity_mf_button, false, false);
274 note_velocity_box.pack_start (velocity_f_button, false, false);
275 note_velocity_box.pack_start (velocity_ff_button, false, false);
276 note_velocity_box.pack_start (velocity_fff_button, false, false);
277
278 Label* l = manage (new Label);
279 l->set_markup ("<b><big>-</big></b>");
280 l->show ();
281 dot0_button.add (*l);
282
283 l = manage (new Label);
284 l->set_markup ("<b><big>.</big></b>");
285 l->show ();
286 dot1_button.add (*l);
287
288 l = manage (new Label);
289 l->set_markup ("<b><big>..</big></b>");
290 l->show ();
291 dot2_button.add (*l);
292
293 l = manage (new Label);
294 l->set_markup ("<b><big>...</big></b>");
295 l->show ();
296 dot3_button.add (*l);
297
298 w = manage (new Image (::get_icon (X_("chord"))));
299 w->show();
300 chord_button.add (*w);
301
302 dot_box1.pack_start (dot0_button, true, false);
303 dot_box1.pack_start (dot1_button, true, false);
304 dot_box2.pack_start (dot2_button, true, false);
305 dot_box2.pack_start (dot3_button, true, false);
306
307 rest_box.pack_start (rest_button, true, false);
308 rest_box.pack_start (grid_rest_button, true, false);
309 rest_box.pack_start (back_button, true, false);
310
311 resync_box.pack_start (beat_resync_button, true, false);
312 resync_box.pack_start (bar_resync_button, true, false);
313 resync_box.pack_start (resync_button, true, false);
314
315 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
316 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
317 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
318 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
319 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
320 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
321 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
322 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
323 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
324 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
325 set_tooltip (&bank_button, _("Insert a bank change message"), "");
326 set_tooltip (&program_button, _("Insert a program change message"), "");
327 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
328 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
329
330 act = ActionManager::get_action ("StepEditing/back");
331 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
332 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
333 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
334 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
335 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
336 act = ActionManager::get_action ("StepEditing/toggle-triplet");
337 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
338 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
339 act = ActionManager::get_action ("StepEditing/no-dotted");
340 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
341 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
342 act = ActionManager::get_action ("StepEditing/toggle-dotted");
343 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
344 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
345 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
346 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
347 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
348 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
349 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
350 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
351 act = ActionManager::get_action ("StepEditing/toggle-chord");
352 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
353 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
354 act = ActionManager::get_action ("StepEditing/insert-rest");
355 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
356 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
357 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
358 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
359 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
360 act = ActionManager::get_action ("StepEditing/sustain");
361 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
362 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
363
364 upper_box.set_spacing (6);
365 upper_box.pack_start (chord_button, false, false);
366 upper_box.pack_start (note_length_box, false, false, 12);
367 upper_box.pack_start (triplet_button, false, false);
368 upper_box.pack_start (dot_box1, false, false);
369 upper_box.pack_start (dot_box2, false, false);
370 upper_box.pack_start (sustain_button, false, false);
371 upper_box.pack_start (rest_box, false, false);
372 upper_box.pack_start (resync_box, false, false);
373 upper_box.pack_start (note_velocity_box, false, false, 12);
374
375 VBox* v;
376
377 v = manage (new VBox);
378 l = manage (new Label (_("Channel")));
379 v->set_spacing (6);
380 v->pack_start (*l, false, false);
381 v->pack_start (channel_spinner, false, false);
382 upper_box.pack_start (*v, false, false);
383
384 v = manage (new VBox);
385 l = manage (new Label (_("1/Note")));
386 v->set_spacing (6);
387 v->pack_start (*l, false, false);
388 v->pack_start (length_divisor_spinner, false, false);
389 upper_box.pack_start (*v, false, false);
390
391 v = manage (new VBox);
392 l = manage (new Label (_("Velocity")));
393 v->set_spacing (6);
394 v->pack_start (*l, false, false);
395 v->pack_start (velocity_spinner, false, false);
396 upper_box.pack_start (*v, false, false);
397
398 v = manage (new VBox);
399 l = manage (new Label (_("Octave")));
400 v->set_spacing (6);
401 v->pack_start (*l, false, false);
402 v->pack_start (octave_spinner, false, false);
403 upper_box.pack_start (*v, false, false);
404
405 v = manage (new VBox);
406 l = manage (new Label (_("Bank")));
407 v->set_spacing (6);
408 v->pack_start (*l, false, false);
409 v->pack_start (bank_spinner, false, false);
410 v->pack_start (bank_button, false, false);
411 upper_box.pack_start (*v, false, false);
412
413 v = manage (new VBox);
414 l = manage (new Label (_("Program")));
415 v->set_spacing (6);
416 v->pack_start (*l, false, false);
417 v->pack_start (program_spinner, false, false);
418 v->pack_start (program_button, false, false);
419 upper_box.pack_start (*v, false, false);
420
421 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
422 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
423 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
424
425 _piano.set_flags (Gtk::CAN_FOCUS);
426
427 _piano.NoteOff.connect (sigc::mem_fun (*this, &StepEntry::note_off_event_handler));
428 _piano.Rest.connect (sigc::mem_fun (*this, &StepEntry::rest_event_handler));
429
430 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
431 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
432 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
433 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
434
435 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
436
437 packer.set_spacing (6);
438 packer.pack_start (upper_box, false, false);
439 packer.pack_start (_piano, false, false);
440 packer.show_all ();
441
442 add (packer);
443
444 /* initial settings: quarter note and mezzo forte */
445
446 ActionManager::get_radio_action ("StepEditing/note-length-quarter")->set_active (true);
447 ActionManager::get_radio_action ("StepEditing/note-velocity-mf")->set_active (true);
448 }
449
~StepEntry()450 StepEntry::~StepEntry()
451 {
452 }
453
454 void
set_step_editor(StepEditor * seditor)455 StepEntry::set_step_editor (StepEditor* seditor)
456 {
457 if (se && se != seditor) {
458 se->step_entry_done ();
459 }
460
461 se = seditor;
462
463 if (se) {
464 set_title (string_compose (_("Step Entry: %1"), se->name()));
465 #if 0
466 /* set channel selector to first selected channel. if none
467 are selected, it will remain at the value set in its
468 constructor, above (1)
469 */
470
471 uint16_t chn_mask = se->channel_selector().get_selected_channels();
472
473 for (uint32_t i = 0; i < 16; ++i) {
474 if (chn_mask & (1<<i)) {
475 channel_adjustment.set_value (i+1);
476 break;
477 }
478 }
479
480 #endif
481 } else {
482 hide ();
483 }
484 }
485
486
487 void
length_changed()488 StepEntry::length_changed ()
489 {
490 length_1_button.queue_draw ();
491 length_2_button.queue_draw ();
492 length_4_button.queue_draw ();
493 length_8_button.queue_draw ();
494 length_16_button.queue_draw ();
495 length_32_button.queue_draw ();
496 length_64_button.queue_draw ();
497 }
498
499 bool
on_key_press_event(GdkEventKey * ev)500 StepEntry::on_key_press_event (GdkEventKey* ev)
501 {
502 /* focus widget gets first shot, then bindings, otherwise
503 forward to main window
504 */
505
506 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
507 return true;
508 }
509
510 return relay_key_press (ev, this);
511 }
512
513 bool
on_key_release_event(GdkEventKey * ev)514 StepEntry::on_key_release_event (GdkEventKey* ev)
515 {
516 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
517 return true;
518 }
519
520 /* don't forward releases */
521
522 return true;
523 }
524
525 void
rest_event_handler()526 StepEntry::rest_event_handler ()
527 {
528 if (se) {
529 se->step_edit_rest (Temporal::Beats());
530 }
531 }
532
533 Temporal::Beats
note_length()534 StepEntry::note_length ()
535 {
536 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
537
538 RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ("StepEditing/toggle-triplet");
539 bool triplets = tact->get_active ();
540
541 if (triplets) {
542 base_time *= (2.0/3.0);
543 }
544
545 double dots = dot_adjustment.get_value ();
546
547 if (dots > 0) {
548 dots = pow (2.0, dots);
549 base_time *= 1 + ((dots - 1.0)/dots);
550 }
551
552 return Temporal::Beats(base_time);
553 }
554
555 uint8_t
note_velocity() const556 StepEntry::note_velocity () const
557 {
558 return velocity_adjustment.get_value();
559 }
560
561 uint8_t
note_channel() const562 StepEntry::note_channel() const
563 {
564 return channel_adjustment.get_value() - 1;
565 }
566
567 void
note_off_event_handler(int note)568 StepEntry::note_off_event_handler (int note)
569 {
570 insert_note (note);
571 }
572
573
574 void
on_show()575 StepEntry::on_show ()
576 {
577 ArdourWindow::on_show ();
578 //_piano->grab_focus ();
579 }
580
581 void
beat_resync_click()582 StepEntry::beat_resync_click ()
583 {
584 if (se) {
585 se->step_edit_beat_sync ();
586 }
587 }
588
589 void
bar_resync_click()590 StepEntry::bar_resync_click ()
591 {
592 if (se) {
593 se->step_edit_bar_sync ();
594 }
595 }
596
597 void
register_actions()598 StepEntry::register_actions ()
599 {
600 /* add named actions for the step editor */
601
602 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (bindings, X_("StepEditing"));
603
604 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::ptr_fun (&StepEntry::se_insert_a));
605 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::ptr_fun (&StepEntry::se_insert_asharp));
606 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::ptr_fun (&StepEntry::se_insert_b));
607 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::ptr_fun (&StepEntry::se_insert_c));
608 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::ptr_fun (&StepEntry::se_insert_csharp));
609 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::ptr_fun (&StepEntry::se_insert_d));
610 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::ptr_fun (&StepEntry::se_insert_dsharp));
611 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::ptr_fun (&StepEntry::se_insert_e));
612 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::ptr_fun (&StepEntry::se_insert_f));
613 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::ptr_fun (&StepEntry::se_insert_fsharp));
614 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::ptr_fun (&StepEntry::se_insert_g));
615 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::ptr_fun (&StepEntry::se_insert_gsharp));
616
617 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_rest));
618 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_grid_rest));
619
620 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_next_octave));
621 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_prev_octave));
622
623 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::ptr_fun (&StepEntry::se_next_note_length));
624 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::ptr_fun (&StepEntry::se_prev_note_length));
625
626 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::ptr_fun (&StepEntry::se_inc_note_length));
627 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::ptr_fun (&StepEntry::se_dec_note_length));
628
629 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::ptr_fun (&StepEntry::se_next_note_velocity));
630 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::ptr_fun (&StepEntry::se_prev_note_velocity));
631
632 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::ptr_fun (&StepEntry::se_inc_note_velocity));
633 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::ptr_fun (&StepEntry::se_dec_note_velocity));
634
635 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::ptr_fun (&StepEntry::se_octave_0));
636 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::ptr_fun (&StepEntry::se_octave_1));
637 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::ptr_fun (&StepEntry::se_octave_2));
638 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::ptr_fun (&StepEntry::se_octave_3));
639 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::ptr_fun (&StepEntry::se_octave_4));
640 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::ptr_fun (&StepEntry::se_octave_5));
641 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::ptr_fun (&StepEntry::se_octave_6));
642 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::ptr_fun (&StepEntry::se_octave_7));
643 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::ptr_fun (&StepEntry::se_octave_8));
644 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::ptr_fun (&StepEntry::se_octave_9));
645 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::ptr_fun (&StepEntry::se_octave_10));
646
647 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"), sigc::ptr_fun (&StepEntry::se_toggle_triplet));
648
649 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"), sigc::ptr_fun (&StepEntry::se_toggle_chord));
650 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"), sigc::ptr_fun (&StepEntry::se_do_sustain));
651
652 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"), sigc::ptr_fun (&StepEntry::se_sync_to_edit_point));
653 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"), sigc::ptr_fun (&StepEntry::se_back));
654
655 RadioAction::Group note_length_group;
656
657 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
658 _("Set Note Length to Whole"), sigc::ptr_fun (&StepEntry::se_note_length_change), 1);
659 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
660 _("Set Note Length to 1/2"), sigc::ptr_fun (&StepEntry::se_note_length_change), 2);
661 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
662 _("Set Note Length to 1/3"), sigc::ptr_fun (&StepEntry::se_note_length_change), 3);
663 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
664 _("Set Note Length to 1/4"), sigc::ptr_fun (&StepEntry::se_note_length_change), 4);
665 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
666 _("Set Note Length to 1/8"), sigc::ptr_fun (&StepEntry::se_note_length_change), 8);
667 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
668 _("Set Note Length to 1/16"), sigc::ptr_fun (&StepEntry::se_note_length_change), 16);
669 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
670 _("Set Note Length to 1/32"), sigc::ptr_fun (&StepEntry::se_note_length_change), 32);
671 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
672 _("Set Note Length to 1/64"), sigc::ptr_fun (&StepEntry::se_note_length_change), 64);
673
674 RadioAction::Group note_velocity_group;
675
676 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
677 _("Set Note Velocity to Pianississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 1);
678 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
679 _("Set Note Velocity to Pianissimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 16);
680 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
681 _("Set Note Velocity to Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 32);
682 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
683 _("Set Note Velocity to Mezzo-Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 64);
684 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
685 _("Set Note Velocity to Mezzo-Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 80);
686 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
687 _("Set Note Velocity to Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 96);
688 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
689 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 112);
690 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
691 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 127);
692
693
694 RadioAction::Group dot_group;
695
696 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 0);
697 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 1);
698 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 2);
699 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 3);
700 }
701
702 void
setup_actions_and_bindings()703 StepEntry::setup_actions_and_bindings ()
704 {
705 load_bindings ();
706 register_actions ();
707 }
708
709 void
load_bindings()710 StepEntry::load_bindings ()
711 {
712 bindings = Bindings::get_bindings (X_("Step Editing"));
713 }
714
715 void
toggle_triplet()716 StepEntry::toggle_triplet ()
717 {
718 if (se) {
719 se->set_step_edit_cursor_width (note_length());
720 }
721 }
722
723 void
toggle_chord()724 StepEntry::toggle_chord ()
725 {
726 if (se) {
727 se->step_edit_toggle_chord ();
728 }
729 }
730
731 void
dot_change(GtkAction * act)732 StepEntry::dot_change (GtkAction* act)
733 {
734 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
735 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
736 dot_adjustment.set_value (v);
737 }
738 }
739
740 void
dot_value_change()741 StepEntry::dot_value_change ()
742 {
743 RefPtr<Action> act;
744 RefPtr<RadioAction> ract;
745 double val = dot_adjustment.get_value();
746 bool inconsistent = true;
747 vector<const char*> dot_actions;
748
749 dot_actions.push_back ("StepEditing/no-dotted");
750 dot_actions.push_back ("StepEditing/toggle-dotted");
751 dot_actions.push_back ("StepEditing/toggle-double-dotted");
752 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
753
754 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
755
756 act = ActionManager::get_action (*i);
757
758 if (act) {
759 ract = RefPtr<RadioAction>::cast_dynamic (act);
760
761 if (ract) {
762 if (ract->property_value() == val) {
763 ract->set_active (true);
764 inconsistent = false;
765 break;
766 }
767 }
768 }
769 }
770
771 dot1_button.set_inconsistent (inconsistent);
772 dot2_button.set_inconsistent (inconsistent);
773 dot3_button.set_inconsistent (inconsistent);
774
775 if (se) {
776 se->set_step_edit_cursor_width (note_length());
777 }
778 }
779
780 void
program_click()781 StepEntry::program_click ()
782 {
783 if (se) {
784 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
785 }
786 }
787
788 void
bank_click()789 StepEntry::bank_click ()
790 {
791 if (se) {
792 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
793 }
794 }
795
796 void
insert_rest()797 StepEntry::insert_rest ()
798 {
799 if (se) {
800 se->step_edit_rest (note_length());
801 }
802 }
803
804 void
insert_grid_rest()805 StepEntry::insert_grid_rest ()
806 {
807 if (se) {
808 se->step_edit_rest (Temporal::Beats());
809 }
810 }
811
812 void
insert_note(uint8_t note)813 StepEntry::insert_note (uint8_t note)
814 {
815 if (note > 127) {
816 return;
817 }
818
819 if (se) {
820 se->step_add_note (note_channel(), note, note_velocity(), note_length());
821 }
822 }
823 void
insert_c()824 StepEntry::insert_c ()
825 {
826 insert_note (0 + (current_octave() * 12));
827 }
828 void
insert_csharp()829 StepEntry::insert_csharp ()
830 {
831 insert_note (1 + (current_octave() * 12));
832 }
833 void
insert_d()834 StepEntry::insert_d ()
835 {
836 insert_note (2 + (current_octave() * 12));
837 }
838 void
insert_dsharp()839 StepEntry::insert_dsharp ()
840 {
841 insert_note (3 + (current_octave() * 12));
842 }
843 void
insert_e()844 StepEntry::insert_e ()
845 {
846 insert_note (4 + (current_octave() * 12));
847 }
848 void
insert_f()849 StepEntry::insert_f ()
850 {
851 insert_note (5 + (current_octave() * 12));
852 }
853 void
insert_fsharp()854 StepEntry::insert_fsharp ()
855 {
856 insert_note (6 + (current_octave() * 12));
857 }
858 void
insert_g()859 StepEntry::insert_g ()
860 {
861 insert_note (7 + (current_octave() * 12));
862 }
863 void
insert_gsharp()864 StepEntry::insert_gsharp ()
865 {
866 insert_note (8 + (current_octave() * 12));
867 }
868
869 void
insert_a()870 StepEntry::insert_a ()
871 {
872 insert_note (9 + (current_octave() * 12));
873 }
874
875 void
insert_asharp()876 StepEntry::insert_asharp ()
877 {
878 insert_note (10 + (current_octave() * 12));
879 }
880 void
insert_b()881 StepEntry::insert_b ()
882 {
883 insert_note (11 + (current_octave() * 12));
884 }
885
886 void
note_length_change(GtkAction * act)887 StepEntry::note_length_change (GtkAction* act)
888 {
889 /* it doesn't matter which note length action we look up - we are interested
890 in the current_value which is global across the whole group of note length
891 actions. this method is called twice for every user operation,
892 once for the action that became "inactive" and once for the action that
893 becaome "active". so ... only bother to actually change the value when this
894 is called for the "active" action.
895 */
896
897 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
898 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
899 length_divisor_adjustment.set_value (v);
900 }
901 }
902
903 void
note_velocity_change(GtkAction * act)904 StepEntry::note_velocity_change (GtkAction* act)
905 {
906 /* it doesn't matter which note velocity action we look up - we are interested
907 in the current_value which is global across the whole group of note velocity
908 actions. this method is called twice for every user operation,
909 once for the action that became "inactive" and once for the action that
910 becaome "active". so ... only bother to actually change the value when this
911 is called for the "active" action.
912 */
913
914 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
915 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
916 velocity_adjustment.set_value (v);
917 }
918 }
919
920 void
velocity_value_change()921 StepEntry::velocity_value_change ()
922 {
923 RefPtr<Action> act;
924 RefPtr<RadioAction> ract;
925 double val = velocity_adjustment.get_value();
926 bool inconsistent = true;
927 vector<const char*> velocity_actions;
928
929 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
930 velocity_actions.push_back ("StepEditing/note-velocity-pp");
931 velocity_actions.push_back ("StepEditing/note-velocity-p");
932 velocity_actions.push_back ("StepEditing/note-velocity-mp");
933 velocity_actions.push_back ("StepEditing/note-velocity-mf");
934 velocity_actions.push_back ("StepEditing/note-velocity-f");
935 velocity_actions.push_back ("StepEditing/note-velocity-ff");
936 velocity_actions.push_back ("StepEditing/note-velocity-fff");
937
938 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
939
940 act = ActionManager::get_action (*i);
941
942 if (act) {
943 ract = RefPtr<RadioAction>::cast_dynamic (act);
944
945 if (ract) {
946 if (ract->property_value() == val) {
947 ract->set_active (true);
948 inconsistent = false;
949 break;
950 }
951 }
952 }
953 }
954
955 velocity_ppp_button.set_inconsistent (inconsistent);
956 velocity_pp_button.set_inconsistent (inconsistent);
957 velocity_p_button.set_inconsistent (inconsistent);
958 velocity_mp_button.set_inconsistent (inconsistent);
959 velocity_mf_button.set_inconsistent (inconsistent);
960 velocity_f_button.set_inconsistent (inconsistent);
961 velocity_ff_button.set_inconsistent (inconsistent);
962 velocity_fff_button.set_inconsistent (inconsistent);
963 }
964
965 void
length_value_change()966 StepEntry::length_value_change ()
967 {
968 RefPtr<Action> act;
969 RefPtr<RadioAction> ract;
970 bool inconsistent = true;
971 vector<const char*> length_actions;
972
973 length_actions.push_back ("StepEditing/note-length-whole");
974 length_actions.push_back ("StepEditing/note-length-half");
975 length_actions.push_back ("StepEditing/note-length-quarter");
976 length_actions.push_back ("StepEditing/note-length-eighth");
977 length_actions.push_back ("StepEditing/note-length-sixteenth");
978 length_actions.push_back ("StepEditing/note-length-thirtysecond");
979 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
980
981 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
982
983 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
984
985 ract->set_active (true);
986 inconsistent = false;
987 break;
988 }
989
990 length_1_button.set_inconsistent (inconsistent);
991 length_2_button.set_inconsistent (inconsistent);
992 length_4_button.set_inconsistent (inconsistent);
993 length_8_button.set_inconsistent (inconsistent);
994 length_16_button.set_inconsistent (inconsistent);
995 length_32_button.set_inconsistent (inconsistent);
996 length_64_button.set_inconsistent (inconsistent);
997
998 if (se) {
999 se->set_step_edit_cursor_width (note_length());
1000 }
1001 }
1002
1003 bool
radio_button_press(GdkEventButton * ev)1004 StepEntry::radio_button_press (GdkEventButton* ev)
1005 {
1006 if (ev->button == 1) {
1007 return true;
1008 }
1009
1010 return false;
1011 }
1012
1013 bool
radio_button_release(GdkEventButton * ev,RadioButton * btn,int v)1014 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
1015 {
1016 if (ev->button == 1) {
1017 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
1018
1019 if (act) {
1020 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1021 }
1022
1023 return true;
1024 }
1025
1026 return false;
1027 }
1028
1029 void
next_octave()1030 StepEntry::next_octave ()
1031 {
1032 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1033 }
1034
1035 void
prev_octave()1036 StepEntry::prev_octave ()
1037 {
1038 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1039 }
1040
1041 void
inc_note_length()1042 StepEntry::inc_note_length ()
1043 {
1044 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1045 }
1046
1047 void
dec_note_length()1048 StepEntry::dec_note_length ()
1049 {
1050 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1051 }
1052
1053 void
prev_note_length()1054 StepEntry::prev_note_length ()
1055 {
1056 double l = length_divisor_adjustment.get_value();
1057 int il = (int) lrintf (l); // round to nearest integer
1058 il = (il/2) * 2; // round to power of 2
1059
1060 if (il == 0) {
1061 il = 1;
1062 }
1063
1064 il *= 2; // double
1065
1066 length_divisor_adjustment.set_value (il);
1067 }
1068
1069 void
next_note_length()1070 StepEntry::next_note_length ()
1071 {
1072 double l = length_divisor_adjustment.get_value();
1073 int il = (int) lrintf (l); // round to nearest integer
1074 il = (il/2) * 2; // round to power of 2
1075
1076 if (il == 0) {
1077 il = 1;
1078 }
1079
1080 il /= 2; // half
1081
1082 if (il > 0) {
1083 length_divisor_adjustment.set_value (il);
1084 }
1085 }
1086
1087 void
inc_note_velocity()1088 StepEntry::inc_note_velocity ()
1089 {
1090 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1091 }
1092
1093 void
dec_note_velocity()1094 StepEntry::dec_note_velocity ()
1095 {
1096 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1097 }
1098
1099 void
next_note_velocity()1100 StepEntry::next_note_velocity ()
1101 {
1102 double l = velocity_adjustment.get_value ();
1103
1104 if (l < 16) {
1105 l = 16;
1106 } else if (l < 32) {
1107 l = 32;
1108 } else if (l < 48) {
1109 l = 48;
1110 } else if (l < 64) {
1111 l = 64;
1112 } else if (l < 80) {
1113 l = 80;
1114 } else if (l < 96) {
1115 l = 96;
1116 } else if (l < 112) {
1117 l = 112;
1118 } else if (l < 127) {
1119 l = 127;
1120 }
1121
1122 velocity_adjustment.set_value (l);
1123 }
1124
1125 void
prev_note_velocity()1126 StepEntry::prev_note_velocity ()
1127 {
1128 double l = velocity_adjustment.get_value ();
1129
1130 if (l > 112) {
1131 l = 112;
1132 } else if (l > 96) {
1133 l = 96;
1134 } else if (l > 80) {
1135 l = 80;
1136 } else if (l > 64) {
1137 l = 64;
1138 } else if (l > 48) {
1139 l = 48;
1140 } else if (l > 32) {
1141 l = 32;
1142 } else if (l > 16) {
1143 l = 16;
1144 } else {
1145 l = 1;
1146 }
1147
1148 velocity_adjustment.set_value (l);
1149 }
1150
1151 void
octave_n(int n)1152 StepEntry::octave_n (int n)
1153 {
1154 octave_adjustment.set_value (n);
1155 }
1156
1157 void
do_sustain()1158 StepEntry::do_sustain ()
1159 {
1160 if (se) {
1161 se->step_edit_sustain (note_length());
1162 }
1163 }
1164
1165 void
back()1166 StepEntry::back ()
1167 {
1168 if (se) {
1169 se->move_step_edit_beat_pos (-note_length());
1170 }
1171 }
1172
1173 void
sync_to_edit_point()1174 StepEntry::sync_to_edit_point ()
1175 {
1176 if (se) {
1177 se->resync_step_edit_to_edit_point ();
1178 }
1179 }
1180