2 Copyright (C) 2010 Paul Davis
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.
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.
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.
22 #include "pbd/file_utils.h"
24 #include "gtkmm2ext/actions.h"
25 #include "gtkmm2ext/keyboard.h"
27 #include "widgets/tooltips.h"
29 #include "ardour/filesystem_paths.h"
31 #include "midi_channel_selector.h"
32 #include "midi_time_axis.h"
33 #include "step_editor.h"
34 #include "step_entry.h"
42 using namespace Gtkmm2ext;
44 using namespace ARDOUR;
45 using namespace ARDOUR_UI_UTILS;
46 using namespace ArdourWidgets;
49 _note_off_event_handler (GtkWidget* /*widget*/, int note, gpointer arg)
51 ((StepEntry*)arg)->note_off_event_handler (note);
55 _rest_event_handler (GtkWidget* /*widget*/, gpointer arg)
57 ((StepEntry*)arg)->rest_event_handler ();
60 StepEntry::StepEntry (StepEditor& seditor)
61 : ArdourWindow (string_compose (_("Step Entry: %1"), seditor.name()))
62 , _current_note_length (1.0)
63 , _current_note_velocity (64)
64 , triplet_button ("3")
65 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
66 , beat_resync_button (_(">beat"))
67 , bar_resync_button (_(">bar"))
68 , resync_button (_(">EP"))
69 , sustain_button (_("sustain"))
70 , rest_button (_("rest"))
71 , grid_rest_button (_("g-rest"))
72 , back_button (_("back"))
73 , channel_adjustment (1, 1, 16, 1, 4)
74 , channel_spinner (channel_adjustment)
75 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
76 , octave_spinner (octave_adjustment)
77 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
78 , length_divisor_spinner (length_divisor_adjustment)
79 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
80 , velocity_spinner (velocity_adjustment)
81 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
82 , bank_spinner (bank_adjustment)
83 , bank_button (_("+"))
84 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
85 , program_spinner (program_adjustment)
86 , program_button (_("+"))
95 /* set channel selector to first selected channel. if none
96 are selected, it will remain at the value set in its
97 constructor, above (1)
100 uint16_t chn_mask = se->channel_selector().get_selected_channels();
102 for (uint32_t i = 0; i < 16; ++i) {
103 if (chn_mask & (1<<i)) {
104 channel_adjustment.set_value (i+1);
111 RadioButtonGroup length_group = length_1_button.get_group();
112 length_2_button.set_group (length_group);
113 length_4_button.set_group (length_group);
114 length_8_button.set_group (length_group);
115 length_12_button.set_group (length_group);
116 length_16_button.set_group (length_group);
117 length_32_button.set_group (length_group);
118 length_64_button.set_group (length_group);
122 w = manage (new Image (::get_icon (X_("wholenote"))));
124 length_1_button.add (*w);
125 w = manage (new Image (::get_icon (X_("halfnote"))));
127 length_2_button.add (*w);
128 w = manage (new Image (::get_icon (X_("quarternote"))));
130 length_4_button.add (*w);
131 w = manage (new Image (::get_icon (X_("eighthnote"))));
133 length_8_button.add (*w);
134 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
136 length_16_button.add (*w);
137 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
139 length_32_button.add (*w);
140 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
142 length_64_button.add (*w);
146 act = ActionManager::get_action ("StepEditing/note-length-whole");
147 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
148 act = ActionManager::get_action ("StepEditing/note-length-half");
149 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
150 act = ActionManager::get_action ("StepEditing/note-length-quarter");
151 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
152 act = ActionManager::get_action ("StepEditing/note-length-eighth");
153 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
154 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
155 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
156 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
157 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
158 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
159 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
161 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
162 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
163 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
164 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
165 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
166 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
167 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
168 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
169 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
170 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
171 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
172 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
173 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
174 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
176 length_1_button.property_draw_indicator() = false;
177 length_2_button.property_draw_indicator() = false;
178 length_4_button.property_draw_indicator() = false;
179 length_8_button.property_draw_indicator() = false;
180 length_16_button.property_draw_indicator() = false;
181 length_32_button.property_draw_indicator() = false;
182 length_64_button.property_draw_indicator() = false;
184 note_length_box.pack_start (length_1_button, false, false);
185 note_length_box.pack_start (length_2_button, false, false);
186 note_length_box.pack_start (length_4_button, false, false);
187 note_length_box.pack_start (length_8_button, false, false);
188 note_length_box.pack_start (length_16_button, false, false);
189 note_length_box.pack_start (length_32_button, false, false);
190 note_length_box.pack_start (length_64_button, false, false);
192 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
193 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
194 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
195 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
196 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
197 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
198 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
200 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
201 velocity_pp_button.set_group (velocity_group);
202 velocity_p_button.set_group (velocity_group);
203 velocity_mp_button.set_group (velocity_group);
204 velocity_mf_button.set_group (velocity_group);
205 velocity_f_button.set_group (velocity_group);
206 velocity_ff_button.set_group (velocity_group);
207 velocity_fff_button.set_group (velocity_group);
209 w = manage (new Image (::get_icon (X_("pianississimo"))));
211 velocity_ppp_button.add (*w);
212 w = manage (new Image (::get_icon (X_("pianissimo"))));
214 velocity_pp_button.add (*w);
215 w = manage (new Image (::get_icon (X_("piano"))));
217 velocity_p_button.add (*w);
218 w = manage (new Image (::get_icon (X_("mezzopiano"))));
220 velocity_mp_button.add (*w);
221 w = manage (new Image (::get_icon (X_("mezzoforte"))));
223 velocity_mf_button.add (*w);
224 w = manage (new Image (::get_icon (X_("forte"))));
226 velocity_f_button.add (*w);
227 w = manage (new Image (::get_icon (X_("fortissimo"))));
229 velocity_ff_button.add (*w);
230 w = manage (new Image (::get_icon (X_("fortississimo"))));
232 velocity_fff_button.add (*w);
234 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
235 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
236 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
237 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
238 act = ActionManager::get_action ("StepEditing/note-velocity-p");
239 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
240 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
241 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
242 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
243 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
244 act = ActionManager::get_action ("StepEditing/note-velocity-f");
245 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
246 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
247 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
248 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
249 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
251 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
252 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
253 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
254 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
255 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
256 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
257 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
258 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
259 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
260 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
261 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
262 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
263 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
264 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
265 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
266 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
268 velocity_ppp_button.property_draw_indicator() = false;
269 velocity_pp_button.property_draw_indicator() = false;
270 velocity_p_button.property_draw_indicator() = false;
271 velocity_mp_button.property_draw_indicator() = false;
272 velocity_mf_button.property_draw_indicator() = false;
273 velocity_f_button.property_draw_indicator() = false;
274 velocity_ff_button.property_draw_indicator() = false;
275 velocity_fff_button.property_draw_indicator() = false;
277 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
278 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
279 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
280 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
281 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
282 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
283 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
284 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
286 note_velocity_box.pack_start (velocity_ppp_button, false, false);
287 note_velocity_box.pack_start (velocity_pp_button, false, false);
288 note_velocity_box.pack_start (velocity_p_button, false, false);
289 note_velocity_box.pack_start (velocity_mp_button, false, false);
290 note_velocity_box.pack_start (velocity_mf_button, false, false);
291 note_velocity_box.pack_start (velocity_f_button, false, false);
292 note_velocity_box.pack_start (velocity_ff_button, false, false);
293 note_velocity_box.pack_start (velocity_fff_button, false, false);
295 Label* l = manage (new Label);
296 l->set_markup ("<b><big>-</big></b>");
298 dot0_button.add (*l);
300 l = manage (new Label);
301 l->set_markup ("<b><big>.</big></b>");
303 dot1_button.add (*l);
305 l = manage (new Label);
306 l->set_markup ("<b><big>..</big></b>");
308 dot2_button.add (*l);
310 l = manage (new Label);
311 l->set_markup ("<b><big>...</big></b>");
313 dot3_button.add (*l);
315 w = manage (new Image (::get_icon (X_("chord"))));
317 chord_button.add (*w);
319 dot_box1.pack_start (dot0_button, true, false);
320 dot_box1.pack_start (dot1_button, true, false);
321 dot_box2.pack_start (dot2_button, true, false);
322 dot_box2.pack_start (dot3_button, true, false);
324 rest_box.pack_start (rest_button, true, false);
325 rest_box.pack_start (grid_rest_button, true, false);
326 rest_box.pack_start (back_button, true, false);
328 resync_box.pack_start (beat_resync_button, true, false);
329 resync_box.pack_start (bar_resync_button, true, false);
330 resync_box.pack_start (resync_button, true, false);
332 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
333 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
334 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
335 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
336 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
337 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
338 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
339 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
340 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
341 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
342 set_tooltip (&bank_button, _("Insert a bank change message"), "");
343 set_tooltip (&program_button, _("Insert a program change message"), "");
344 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
345 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
347 act = ActionManager::get_action ("StepEditing/back");
348 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
349 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
350 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
351 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
352 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
353 act = ActionManager::get_action ("StepEditing/toggle-triplet");
354 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
355 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
356 act = ActionManager::get_action ("StepEditing/no-dotted");
357 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
358 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
359 act = ActionManager::get_action ("StepEditing/toggle-dotted");
360 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
361 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
362 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
363 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
364 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
365 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
366 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
367 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
368 act = ActionManager::get_action ("StepEditing/toggle-chord");
369 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
370 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
371 act = ActionManager::get_action ("StepEditing/insert-rest");
372 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
373 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
374 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
375 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
376 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
377 act = ActionManager::get_action ("StepEditing/sustain");
378 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
379 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
381 upper_box.set_spacing (6);
382 upper_box.pack_start (chord_button, false, false);
383 upper_box.pack_start (note_length_box, false, false, 12);
384 upper_box.pack_start (triplet_button, false, false);
385 upper_box.pack_start (dot_box1, false, false);
386 upper_box.pack_start (dot_box2, false, false);
387 upper_box.pack_start (sustain_button, false, false);
388 upper_box.pack_start (rest_box, false, false);
389 upper_box.pack_start (resync_box, false, false);
390 upper_box.pack_start (note_velocity_box, false, false, 12);
394 v = manage (new VBox);
395 l = manage (new Label (_("Channel")));
397 v->pack_start (*l, false, false);
398 v->pack_start (channel_spinner, false, false);
399 upper_box.pack_start (*v, false, false);
401 v = manage (new VBox);
402 l = manage (new Label (_("1/Note")));
404 v->pack_start (*l, false, false);
405 v->pack_start (length_divisor_spinner, false, false);
406 upper_box.pack_start (*v, false, false);
408 v = manage (new VBox);
409 l = manage (new Label (_("Velocity")));
411 v->pack_start (*l, false, false);
412 v->pack_start (velocity_spinner, false, false);
413 upper_box.pack_start (*v, false, false);
415 v = manage (new VBox);
416 l = manage (new Label (_("Octave")));
418 v->pack_start (*l, false, false);
419 v->pack_start (octave_spinner, false, false);
420 upper_box.pack_start (*v, false, false);
422 v = manage (new VBox);
423 l = manage (new Label (_("Bank")));
425 v->pack_start (*l, false, false);
426 v->pack_start (bank_spinner, false, false);
427 v->pack_start (bank_button, false, false);
428 upper_box.pack_start (*v, false, false);
430 v = manage (new VBox);
431 l = manage (new Label (_("Program")));
433 v->pack_start (*l, false, false);
434 v->pack_start (program_spinner, false, false);
435 v->pack_start (program_button, false, false);
436 upper_box.pack_start (*v, false, false);
438 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
439 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
440 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
442 _piano = (PianoKeyboard*) piano_keyboard_new ();
443 piano = wrap ((GtkWidget*) _piano);
445 piano->set_flags (Gtk::CAN_FOCUS);
447 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
448 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
450 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
451 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
452 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
453 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
455 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
457 packer.set_spacing (6);
458 packer.pack_start (upper_box, false, false);
459 packer.pack_start (*piano, false, false);
464 /* initial settings: quarter note and mezzo forte */
466 act = ActionManager::get_action ("StepEditing/note-length-quarter");
467 RefPtr<RadioAction> r = RefPtr<RadioAction>::cast_dynamic (act);
469 r->set_active (true);
471 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
472 r = RefPtr<RadioAction>::cast_dynamic (act);
474 r->set_active (true);
477 StepEntry::~StepEntry()
482 StepEntry::length_changed ()
484 length_1_button.queue_draw ();
485 length_2_button.queue_draw ();
486 length_4_button.queue_draw ();
487 length_8_button.queue_draw ();
488 length_16_button.queue_draw ();
489 length_32_button.queue_draw ();
490 length_64_button.queue_draw ();
494 StepEntry::on_key_press_event (GdkEventKey* ev)
496 /* focus widget gets first shot, then bindings, otherwise
497 forward to main window
500 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
504 return relay_key_press (ev, this);
508 StepEntry::on_key_release_event (GdkEventKey* ev)
510 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
514 /* don't forward releases */
520 StepEntry::rest_event_handler ()
522 se->step_edit_rest (Temporal::Beats());
526 StepEntry::note_length ()
528 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
530 RefPtr<Action> act = ActionManager::get_action ("StepEditing/toggle-triplet");
531 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
532 bool triplets = tact->get_active ();
535 base_time *= (2.0/3.0);
538 double dots = dot_adjustment.get_value ();
541 dots = pow (2.0, dots);
542 base_time *= 1 + ((dots - 1.0)/dots);
545 return Temporal::Beats(base_time);
549 StepEntry::note_velocity () const
551 return velocity_adjustment.get_value();
555 StepEntry::note_channel() const
557 return channel_adjustment.get_value() - 1;
561 StepEntry::note_off_event_handler (int note)
568 StepEntry::on_show ()
570 ArdourWindow::on_show ();
571 //piano->grab_focus ();
575 StepEntry::beat_resync_click ()
577 se->step_edit_beat_sync ();
581 StepEntry::bar_resync_click ()
583 se->step_edit_bar_sync ();
587 StepEntry::register_actions ()
589 /* add named actions for the step editor */
591 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (this, X_("StepEditing"));
593 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
594 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
595 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
596 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
597 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
598 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
599 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
600 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
601 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
602 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
603 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
604 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
606 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_rest));
607 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_grid_rest));
609 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::next_octave));
610 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::prev_octave));
612 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::mem_fun (*this, &StepEntry::next_note_length));
613 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::mem_fun (*this, &StepEntry::prev_note_length));
615 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::mem_fun (*this, &StepEntry::inc_note_length));
616 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::mem_fun (*this, &StepEntry::dec_note_length));
618 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::mem_fun (*this, &StepEntry::next_note_velocity));
619 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::mem_fun (*this, &StepEntry::prev_note_velocity));
621 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::mem_fun (*this, &StepEntry::inc_note_velocity));
622 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::mem_fun (*this, &StepEntry::dec_note_velocity));
624 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::mem_fun (*this, &StepEntry::octave_0));
625 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::mem_fun (*this, &StepEntry::octave_1));
626 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::mem_fun (*this, &StepEntry::octave_2));
627 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::mem_fun (*this, &StepEntry::octave_3));
628 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::mem_fun (*this, &StepEntry::octave_4));
629 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::mem_fun (*this, &StepEntry::octave_5));
630 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::mem_fun (*this, &StepEntry::octave_6));
631 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::mem_fun (*this, &StepEntry::octave_7));
632 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::mem_fun (*this, &StepEntry::octave_8));
633 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::mem_fun (*this, &StepEntry::octave_9));
634 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::mem_fun (*this, &StepEntry::octave_10));
636 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"),
637 sigc::mem_fun (*this, &StepEntry::toggle_triplet));
639 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"),
640 sigc::mem_fun (*this, &StepEntry::toggle_chord));
641 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"),
642 sigc::mem_fun (*this, &StepEntry::do_sustain));
644 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"),
645 sigc::mem_fun (*this, &StepEntry::sync_to_edit_point));
646 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"),
647 sigc::mem_fun (*this, &StepEntry::back));
648 RadioAction::Group note_length_group;
650 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
651 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
652 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
653 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
654 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
655 _("Set Note Length to 1/3"), sigc::mem_fun (*this, &StepEntry::note_length_change), 3);
656 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
657 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
658 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
659 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
660 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
661 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
662 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
663 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
664 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
665 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
667 RadioAction::Group note_velocity_group;
669 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
670 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
671 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
672 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
673 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
674 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
675 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
676 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
677 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
678 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
679 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
680 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
681 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
682 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
683 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
684 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
687 RadioAction::Group dot_group;
689 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 0);
690 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 1);
691 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 2);
692 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 3);
696 StepEntry::load_bindings ()
698 bindings = Bindings::get_bindings (X_("Step Editing"));
699 set_data ("ardour-bindings", bindings);
703 StepEntry::toggle_triplet ()
705 se->set_step_edit_cursor_width (note_length());
709 StepEntry::toggle_chord ()
711 se->step_edit_toggle_chord ();
715 StepEntry::dot_change (GtkAction* act)
717 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
718 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
719 dot_adjustment.set_value (v);
724 StepEntry::dot_value_change ()
727 RefPtr<RadioAction> ract;
728 double val = dot_adjustment.get_value();
729 bool inconsistent = true;
730 vector<const char*> dot_actions;
732 dot_actions.push_back ("StepEditing/no-dotted");
733 dot_actions.push_back ("StepEditing/toggle-dotted");
734 dot_actions.push_back ("StepEditing/toggle-double-dotted");
735 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
737 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
739 act = ActionManager::get_action (*i);
742 ract = RefPtr<RadioAction>::cast_dynamic (act);
745 if (ract->property_value() == val) {
746 ract->set_active (true);
747 inconsistent = false;
754 dot1_button.set_inconsistent (inconsistent);
755 dot2_button.set_inconsistent (inconsistent);
756 dot3_button.set_inconsistent (inconsistent);
758 se->set_step_edit_cursor_width (note_length());
762 StepEntry::program_click ()
764 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
768 StepEntry::bank_click ()
770 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
774 StepEntry::insert_rest ()
776 se->step_edit_rest (note_length());
780 StepEntry::insert_grid_rest ()
782 se->step_edit_rest (Temporal::Beats());
786 StepEntry::insert_note (uint8_t note)
792 se->step_add_note (note_channel(), note, note_velocity(), note_length());
795 StepEntry::insert_c ()
797 insert_note (0 + (current_octave() * 12));
800 StepEntry::insert_csharp ()
802 insert_note (1 + (current_octave() * 12));
805 StepEntry::insert_d ()
807 insert_note (2 + (current_octave() * 12));
810 StepEntry::insert_dsharp ()
812 insert_note (3 + (current_octave() * 12));
815 StepEntry::insert_e ()
817 insert_note (4 + (current_octave() * 12));
820 StepEntry::insert_f ()
822 insert_note (5 + (current_octave() * 12));
825 StepEntry::insert_fsharp ()
827 insert_note (6 + (current_octave() * 12));
830 StepEntry::insert_g ()
832 insert_note (7 + (current_octave() * 12));
835 StepEntry::insert_gsharp ()
837 insert_note (8 + (current_octave() * 12));
841 StepEntry::insert_a ()
843 insert_note (9 + (current_octave() * 12));
847 StepEntry::insert_asharp ()
849 insert_note (10 + (current_octave() * 12));
852 StepEntry::insert_b ()
854 insert_note (11 + (current_octave() * 12));
858 StepEntry::note_length_change (GtkAction* act)
860 /* it doesn't matter which note length action we look up - we are interested
861 in the current_value which is global across the whole group of note length
862 actions. this method is called twice for every user operation,
863 once for the action that became "inactive" and once for the action that
864 becaome "active". so ... only bother to actually change the value when this
865 is called for the "active" action.
868 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
869 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
870 length_divisor_adjustment.set_value (v);
875 StepEntry::note_velocity_change (GtkAction* act)
877 /* it doesn't matter which note length action we look up - we are interested
878 in the current_value which is global across the whole group of note length
879 actions. this method is called twice for every user operation,
880 once for the action that became "inactive" and once for the action that
881 becaome "active". so ... only bother to actually change the value when this
882 is called for the "active" action.
885 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
886 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
887 velocity_adjustment.set_value (v);
892 StepEntry::velocity_value_change ()
895 RefPtr<RadioAction> ract;
896 double val = velocity_adjustment.get_value();
897 bool inconsistent = true;
898 vector<const char*> velocity_actions;
900 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
901 velocity_actions.push_back ("StepEditing/note-velocity-pp");
902 velocity_actions.push_back ("StepEditing/note-velocity-p");
903 velocity_actions.push_back ("StepEditing/note-velocity-mp");
904 velocity_actions.push_back ("StepEditing/note-velocity-mf");
905 velocity_actions.push_back ("StepEditing/note-velocity-f");
906 velocity_actions.push_back ("StepEditing/note-velocity-ff");
907 velocity_actions.push_back ("StepEditing/note-velocity-fff");
909 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
911 act = ActionManager::get_action (*i);
914 ract = RefPtr<RadioAction>::cast_dynamic (act);
917 if (ract->property_value() == val) {
918 ract->set_active (true);
919 inconsistent = false;
926 velocity_ppp_button.set_inconsistent (inconsistent);
927 velocity_pp_button.set_inconsistent (inconsistent);
928 velocity_p_button.set_inconsistent (inconsistent);
929 velocity_mp_button.set_inconsistent (inconsistent);
930 velocity_mf_button.set_inconsistent (inconsistent);
931 velocity_f_button.set_inconsistent (inconsistent);
932 velocity_ff_button.set_inconsistent (inconsistent);
933 velocity_fff_button.set_inconsistent (inconsistent);
937 StepEntry::length_value_change ()
940 RefPtr<RadioAction> ract;
941 double val = length_divisor_adjustment.get_value();
942 bool inconsistent = true;
943 vector<const char*> length_actions;
945 length_actions.push_back ("StepEditing/note-length-whole");
946 length_actions.push_back ("StepEditing/note-length-half");
947 length_actions.push_back ("StepEditing/note-length-quarter");
948 length_actions.push_back ("StepEditing/note-length-eighth");
949 length_actions.push_back ("StepEditing/note-length-sixteenth");
950 length_actions.push_back ("StepEditing/note-length-thirtysecond");
951 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
953 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
955 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
957 ract->set_active (true);
958 inconsistent = false;
962 length_1_button.set_inconsistent (inconsistent);
963 length_2_button.set_inconsistent (inconsistent);
964 length_4_button.set_inconsistent (inconsistent);
965 length_8_button.set_inconsistent (inconsistent);
966 length_16_button.set_inconsistent (inconsistent);
967 length_32_button.set_inconsistent (inconsistent);
968 length_64_button.set_inconsistent (inconsistent);
970 se->set_step_edit_cursor_width (note_length());
974 StepEntry::radio_button_press (GdkEventButton* ev)
976 if (ev->button == 1) {
984 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
986 if (ev->button == 1) {
987 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
990 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1000 StepEntry::next_octave ()
1002 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1006 StepEntry::prev_octave ()
1008 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1012 StepEntry::inc_note_length ()
1014 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1018 StepEntry::dec_note_length ()
1020 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1024 StepEntry::prev_note_length ()
1026 double l = length_divisor_adjustment.get_value();
1027 int il = (int) lrintf (l); // round to nearest integer
1028 il = (il/2) * 2; // round to power of 2
1036 length_divisor_adjustment.set_value (il);
1040 StepEntry::next_note_length ()
1042 double l = length_divisor_adjustment.get_value();
1043 int il = (int) lrintf (l); // round to nearest integer
1044 il = (il/2) * 2; // round to power of 2
1053 length_divisor_adjustment.set_value (il);
1058 StepEntry::inc_note_velocity ()
1060 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1064 StepEntry::dec_note_velocity ()
1066 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1070 StepEntry::next_note_velocity ()
1072 double l = velocity_adjustment.get_value ();
1076 } else if (l < 32) {
1078 } else if (l < 48) {
1080 } else if (l < 64) {
1082 } else if (l < 80) {
1084 } else if (l < 96) {
1086 } else if (l < 112) {
1088 } else if (l < 127) {
1092 velocity_adjustment.set_value (l);
1096 StepEntry::prev_note_velocity ()
1098 double l = velocity_adjustment.get_value ();
1102 } else if (l > 96) {
1104 } else if (l > 80) {
1106 } else if (l > 64) {
1108 } else if (l > 48) {
1110 } else if (l > 32) {
1112 } else if (l > 16) {
1118 velocity_adjustment.set_value (l);
1122 StepEntry::octave_n (int n)
1124 octave_adjustment.set_value (n);
1128 StepEntry::do_sustain ()
1130 se->step_edit_sustain (note_length());
1136 se->move_step_edit_beat_pos (-note_length());
1140 StepEntry::sync_to_edit_point ()
1142 se->resync_step_edit_to_edit_point ();