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/filesystem.h"
23 #include "pbd/file_utils.h"
25 #include "gtkmm2ext/keyboard.h"
26 #include "gtkmm2ext/actions.h"
27 #include "gtkmm2ext/bindings.h"
29 #include "ardour/filesystem_paths.h"
31 #include "ardour_ui.h"
32 #include "midi_channel_selector.h"
33 #include "midi_time_axis.h"
34 #include "step_entry.h"
42 using namespace Gtkmm2ext;
44 using namespace ARDOUR;
47 _note_off_event_handler (GtkWidget* widget, int note, gpointer arg)
49 ((StepEntry*)arg)->note_off_event_handler (note);
53 _rest_event_handler (GtkWidget* widget, gpointer arg)
55 ((StepEntry*)arg)->rest_event_handler ();
58 StepEntry::StepEntry (MidiTimeAxisView& mtv)
59 : ArdourDialog (string_compose (_("Step Entry: %1"), mtv.name()))
60 , _current_note_length (1.0)
61 , _current_note_velocity (64)
62 , triplet_button ("3")
63 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
64 , beat_resync_button (_(">beat"))
65 , bar_resync_button (_(">bar"))
66 , resync_button (_(">EP"))
67 , sustain_button (_("sustain"))
68 , rest_button (_("rest"))
69 , grid_rest_button (_("g-rest"))
70 , back_button (_("back"))
71 , channel_adjustment (1, 1, 16, 1, 4)
72 , channel_spinner (channel_adjustment)
73 , octave_adjustment (4, 1, 11, 1, 4) // start in octave 4
74 , octave_spinner (octave_adjustment)
75 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
76 , length_divisor_spinner (length_divisor_adjustment)
77 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
78 , velocity_spinner (velocity_adjustment)
79 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
80 , bank_spinner (bank_adjustment)
81 , bank_button (_("+"))
82 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
83 , program_spinner (program_adjustment)
84 , program_button (_("+"))
92 /* set channel selector to first selected channel. if none
93 are selected, it will remain at the value set in its
94 constructor, above (1)
97 uint16_t chn_mask = _mtv->channel_selector().get_selected_channels();
99 for (uint32_t i = 0; i < 16; ++i) {
100 if (chn_mask & (1<<i)) {
101 channel_adjustment.set_value (i+1);
106 RadioButtonGroup length_group = length_1_button.get_group();
107 length_2_button.set_group (length_group);
108 length_4_button.set_group (length_group);
109 length_8_button.set_group (length_group);
110 length_12_button.set_group (length_group);
111 length_16_button.set_group (length_group);
112 length_32_button.set_group (length_group);
113 length_64_button.set_group (length_group);
117 w = manage (new Image (::get_icon (X_("wholenote"))));
119 length_1_button.add (*w);
120 w = manage (new Image (::get_icon (X_("halfnote"))));
122 length_2_button.add (*w);
123 w = manage (new Image (::get_icon (X_("quarternote"))));
125 length_4_button.add (*w);
126 w = manage (new Image (::get_icon (X_("eighthnote"))));
128 length_8_button.add (*w);
129 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
131 length_16_button.add (*w);
132 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
134 length_32_button.add (*w);
135 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
137 length_64_button.add (*w);
141 act = myactions.find_action ("StepEditing/note-length-whole");
142 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
143 act = myactions.find_action ("StepEditing/note-length-half");
144 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
145 act = myactions.find_action ("StepEditing/note-length-quarter");
146 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
147 act = myactions.find_action ("StepEditing/note-length-eighth");
148 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
149 act = myactions.find_action ("StepEditing/note-length-sixteenth");
150 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
151 act = myactions.find_action ("StepEditing/note-length-thirtysecond");
152 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
153 act = myactions.find_action ("StepEditing/note-length-sixtyfourth");
154 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
156 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
157 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
158 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
159 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
160 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
161 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
162 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
163 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
164 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
165 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
166 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
167 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
168 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
169 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
171 length_1_button.property_draw_indicator() = false;
172 length_2_button.property_draw_indicator() = false;
173 length_4_button.property_draw_indicator() = false;
174 length_8_button.property_draw_indicator() = false;
175 length_16_button.property_draw_indicator() = false;
176 length_32_button.property_draw_indicator() = false;
177 length_64_button.property_draw_indicator() = false;
179 note_length_box.pack_start (length_1_button, false, false);
180 note_length_box.pack_start (length_2_button, false, false);
181 note_length_box.pack_start (length_4_button, false, false);
182 note_length_box.pack_start (length_8_button, false, false);
183 note_length_box.pack_start (length_16_button, false, false);
184 note_length_box.pack_start (length_32_button, false, false);
185 note_length_box.pack_start (length_64_button, false, false);
187 ARDOUR_UI::instance()->set_tip (&length_1_button, _("Set note length to a whole note"), "");
188 ARDOUR_UI::instance()->set_tip (&length_2_button, _("Set note length to a half note"), "");
189 ARDOUR_UI::instance()->set_tip (&length_4_button, _("Set note length to a quarter note"), "");
190 ARDOUR_UI::instance()->set_tip (&length_8_button, _("Set note length to a eighth note"), "");
191 ARDOUR_UI::instance()->set_tip (&length_16_button, _("Set note length to a sixteenth note"), "");
192 ARDOUR_UI::instance()->set_tip (&length_32_button, _("Set note length to a thirty-second note"), "");
193 ARDOUR_UI::instance()->set_tip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
195 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
196 velocity_pp_button.set_group (velocity_group);
197 velocity_p_button.set_group (velocity_group);
198 velocity_mp_button.set_group (velocity_group);
199 velocity_mf_button.set_group (velocity_group);
200 velocity_f_button.set_group (velocity_group);
201 velocity_ff_button.set_group (velocity_group);
202 velocity_fff_button.set_group (velocity_group);
204 w = manage (new Image (::get_icon (X_("pianississimo"))));
206 velocity_ppp_button.add (*w);
207 w = manage (new Image (::get_icon (X_("pianissimo"))));
209 velocity_pp_button.add (*w);
210 w = manage (new Image (::get_icon (X_("piano"))));
212 velocity_p_button.add (*w);
213 w = manage (new Image (::get_icon (X_("mezzopiano"))));
215 velocity_mp_button.add (*w);
216 w = manage (new Image (::get_icon (X_("mezzoforte"))));
218 velocity_mf_button.add (*w);
219 w = manage (new Image (::get_icon (X_("forte"))));
221 velocity_f_button.add (*w);
222 w = manage (new Image (::get_icon (X_("fortissimo"))));
224 velocity_ff_button.add (*w);
225 w = manage (new Image (::get_icon (X_("fortississimo"))));
227 velocity_fff_button.add (*w);
229 act = myactions.find_action ("StepEditing/note-velocity-ppp");
230 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
231 act = myactions.find_action ("StepEditing/note-velocity-pp");
232 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
233 act = myactions.find_action ("StepEditing/note-velocity-p");
234 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
235 act = myactions.find_action ("StepEditing/note-velocity-mp");
236 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
237 act = myactions.find_action ("StepEditing/note-velocity-mf");
238 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
239 act = myactions.find_action ("StepEditing/note-velocity-f");
240 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
241 act = myactions.find_action ("StepEditing/note-velocity-ff");
242 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
243 act = myactions.find_action ("StepEditing/note-velocity-fff");
244 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
246 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
247 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
248 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
249 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
250 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
251 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
252 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
253 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
254 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
255 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
256 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
257 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
258 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
259 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
260 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
261 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
263 velocity_ppp_button.property_draw_indicator() = false;
264 velocity_pp_button.property_draw_indicator() = false;
265 velocity_p_button.property_draw_indicator() = false;
266 velocity_mp_button.property_draw_indicator() = false;
267 velocity_mf_button.property_draw_indicator() = false;
268 velocity_f_button.property_draw_indicator() = false;
269 velocity_ff_button.property_draw_indicator() = false;
270 velocity_fff_button.property_draw_indicator() = false;
272 ARDOUR_UI::instance()->set_tip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
273 ARDOUR_UI::instance()->set_tip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
274 ARDOUR_UI::instance()->set_tip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
275 ARDOUR_UI::instance()->set_tip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
276 ARDOUR_UI::instance()->set_tip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
277 ARDOUR_UI::instance()->set_tip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
278 ARDOUR_UI::instance()->set_tip (&velocity_ff_button, _("Set volume (velocity) to forteissimo"), "");
279 ARDOUR_UI::instance()->set_tip (&velocity_fff_button, _("Set volume (velocity) to forteississimo"), "");
281 note_velocity_box.pack_start (velocity_ppp_button, false, false);
282 note_velocity_box.pack_start (velocity_pp_button, false, false);
283 note_velocity_box.pack_start (velocity_p_button, false, false);
284 note_velocity_box.pack_start (velocity_mp_button, false, false);
285 note_velocity_box.pack_start (velocity_mf_button, false, false);
286 note_velocity_box.pack_start (velocity_f_button, false, false);
287 note_velocity_box.pack_start (velocity_ff_button, false, false);
288 note_velocity_box.pack_start (velocity_fff_button, false, false);
290 Label* l = manage (new Label);
291 l->set_markup ("<b><big>-</big></b>");
293 dot0_button.add (*l);
295 l = manage (new Label);
296 l->set_markup ("<b><big>.</big></b>");
298 dot1_button.add (*l);
300 l = manage (new Label);
301 l->set_markup ("<b><big>..</big></b>");
303 dot2_button.add (*l);
305 l = manage (new Label);
306 l->set_markup ("<b><big>...</big></b>");
308 dot3_button.add (*l);
310 w = manage (new Image (::get_icon (X_("chord"))));
312 chord_button.add (*w);
314 dot_box1.pack_start (dot0_button, true, false);
315 dot_box1.pack_start (dot1_button, true, false);
316 dot_box2.pack_start (dot2_button, true, false);
317 dot_box2.pack_start (dot3_button, true, false);
319 rest_box.pack_start (rest_button, true, false);
320 rest_box.pack_start (grid_rest_button, true, false);
321 rest_box.pack_start (back_button, true, false);
323 resync_box.pack_start (beat_resync_button, true, false);
324 resync_box.pack_start (bar_resync_button, true, false);
325 resync_box.pack_start (resync_button, true, false);
327 ARDOUR_UI::instance()->set_tip (&chord_button, _("Stack inserted notes to form a chord"), "");
328 ARDOUR_UI::instance()->set_tip (&sustain_button, _("Extend selected notes by note length"), "");
329 ARDOUR_UI::instance()->set_tip (&dot0_button, _("Use undotted note lengths"), "");
330 ARDOUR_UI::instance()->set_tip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
331 ARDOUR_UI::instance()->set_tip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
332 ARDOUR_UI::instance()->set_tip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
333 ARDOUR_UI::instance()->set_tip (&rest_button, _("Insert a note-length's rest"), "");
334 ARDOUR_UI::instance()->set_tip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
335 ARDOUR_UI::instance()->set_tip (&beat_resync_button, _("Insert a rest until the next beat"), "");
336 ARDOUR_UI::instance()->set_tip (&bar_resync_button, _("Insert a rest until the next bar"), "");
337 ARDOUR_UI::instance()->set_tip (&bank_button, _("Insert a bank change message"), "");
338 ARDOUR_UI::instance()->set_tip (&program_button, _("Insert a program change message"), "");
339 ARDOUR_UI::instance()->set_tip (&back_button, _("Move Insert Position Back by Note Length"), "");
340 ARDOUR_UI::instance()->set_tip (&resync_button, _("Move Insert Position to Edit Point"), "");
342 act = myactions.find_action ("StepEditing/back");
343 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
344 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
345 act = myactions.find_action ("StepEditing/sync-to-edit-point");
346 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
347 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
348 act = myactions.find_action ("StepEditing/toggle-triplet");
349 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
350 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
351 act = myactions.find_action ("StepEditing/no-dotted");
352 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
353 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
354 act = myactions.find_action ("StepEditing/toggle-dotted");
355 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
356 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
357 act = myactions.find_action ("StepEditing/toggle-double-dotted");
358 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
359 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
360 act = myactions.find_action ("StepEditing/toggle-triple-dotted");
361 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
362 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
363 act = myactions.find_action ("StepEditing/toggle-chord");
364 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
365 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
366 act = myactions.find_action ("StepEditing/insert-rest");
367 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
368 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
369 act = myactions.find_action ("StepEditing/insert-snap-rest");
370 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
371 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
372 act = myactions.find_action ("StepEditing/sustain");
373 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
374 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
376 upper_box.set_spacing (6);
377 upper_box.pack_start (chord_button, false, false);
378 upper_box.pack_start (note_length_box, false, false, 12);
379 upper_box.pack_start (triplet_button, false, false);
380 upper_box.pack_start (dot_box1, false, false);
381 upper_box.pack_start (dot_box2, false, false);
382 upper_box.pack_start (sustain_button, false, false);
383 upper_box.pack_start (rest_box, false, false);
384 upper_box.pack_start (resync_box, false, false);
385 upper_box.pack_start (note_velocity_box, false, false, 12);
389 v = manage (new VBox);
390 l = manage (new Label (_("Channel")));
392 v->pack_start (*l, false, false);
393 v->pack_start (channel_spinner, false, false);
394 upper_box.pack_start (*v, false, false);
396 v = manage (new VBox);
397 l = manage (new Label (_("1/Note")));
399 v->pack_start (*l, false, false);
400 v->pack_start (length_divisor_spinner, false, false);
401 upper_box.pack_start (*v, false, false);
403 v = manage (new VBox);
404 l = manage (new Label (_("Velocity")));
406 v->pack_start (*l, false, false);
407 v->pack_start (velocity_spinner, false, false);
408 upper_box.pack_start (*v, false, false);
410 v = manage (new VBox);
411 l = manage (new Label (_("Octave")));
413 v->pack_start (*l, false, false);
414 v->pack_start (octave_spinner, false, false);
415 upper_box.pack_start (*v, false, false);
417 v = manage (new VBox);
418 l = manage (new Label (_("Bank")));
420 v->pack_start (*l, false, false);
421 v->pack_start (bank_spinner, false, false);
422 v->pack_start (bank_button, false, false);
423 upper_box.pack_start (*v, false, false);
425 v = manage (new VBox);
426 l = manage (new Label (_("Program")));
428 v->pack_start (*l, false, false);
429 v->pack_start (program_spinner, false, false);
430 v->pack_start (program_button, false, false);
431 upper_box.pack_start (*v, false, false);
433 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
434 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
435 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
437 _piano = (PianoKeyboard*) piano_keyboard_new ();
438 piano = wrap ((GtkWidget*) _piano);
440 piano->set_flags (Gtk::CAN_FOCUS);
442 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
443 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
445 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
446 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
447 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
448 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
450 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
452 packer.set_spacing (6);
453 packer.pack_start (upper_box, false, false);
454 packer.pack_start (*piano, false, false);
457 get_vbox()->add (packer);
460 StepEntry::~StepEntry()
465 StepEntry::length_changed ()
467 length_1_button.queue_draw ();
468 length_2_button.queue_draw ();
469 length_4_button.queue_draw ();
470 length_8_button.queue_draw ();
471 length_16_button.queue_draw ();
472 length_32_button.queue_draw ();
473 length_64_button.queue_draw ();
477 StepEntry::on_key_press_event (GdkEventKey* ev)
479 /* focus widget gets first shot, then bindings, otherwise
480 forward to main window
483 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
484 KeyboardKey k (ev->state, ev->keyval);
486 if (bindings.activate (k, KeyboardKey::Press)) {
491 return forward_key_press (ev);
495 StepEntry::on_key_release_event (GdkEventKey* ev)
497 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
498 KeyboardKey k (ev->state, ev->keyval);
500 if (bindings.activate (k, KeyboardKey::Release)) {
505 /* don't forward releases */
511 StepEntry::rest_event_handler ()
513 _mtv->step_edit_rest (0.0);
517 StepEntry::note_length ()
519 Evoral::MusicalTime base_time = 1.0 / (Evoral::MusicalTime) length_divisor_adjustment.get_value();
521 RefPtr<Action> act = myactions.find_action ("StepEditing/toggle-triplet");
522 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
523 bool triplets = tact->get_active ();
526 base_time *= (2.0/3.0);
529 double dots = dot_adjustment.get_value ();
532 dots = pow (2.0, dots);
533 base_time *= 1 + ((dots - 1.0)/dots);
540 StepEntry::note_velocity () const
542 return (Evoral::MusicalTime) velocity_adjustment.get_value();
546 StepEntry::note_channel() const
548 return channel_adjustment.get_value() - 1;
552 StepEntry::note_off_event_handler (int note)
559 StepEntry::on_show ()
561 ArdourDialog::on_show ();
562 //piano->grab_focus ();
566 StepEntry::beat_resync_click ()
568 _mtv->step_edit_beat_sync ();
572 StepEntry::bar_resync_click ()
574 _mtv->step_edit_bar_sync ();
578 StepEntry::register_actions ()
580 /* add named actions for the editor */
582 myactions.register_action ("StepEditing", "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
583 myactions.register_action ("StepEditing", "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
584 myactions.register_action ("StepEditing", "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
585 myactions.register_action ("StepEditing", "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
586 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
587 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
588 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
589 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
590 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
591 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
592 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
593 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
595 myactions.register_action ("StepEditing", "insert-rest", _("Insert a Note-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_rest));
596 myactions.register_action ("StepEditing", "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_grid_rest));
598 myactions.register_action ("StepEditing", "next-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::next_octave));
599 myactions.register_action ("StepEditing", "prev-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::prev_octave));
601 myactions.register_action ("StepEditing", "next-note-length", _("Move to Next Note Length"), sigc::mem_fun (*this, &StepEntry::next_note_length));
602 myactions.register_action ("StepEditing", "prev-note-length", _("Move to Previous Note Length"), sigc::mem_fun (*this, &StepEntry::prev_note_length));
604 myactions.register_action ("StepEditing", "inc-note-length", _("Increase Note Length"), sigc::mem_fun (*this, &StepEntry::inc_note_length));
605 myactions.register_action ("StepEditing", "dec-note-length", _("Decrease Note Length"), sigc::mem_fun (*this, &StepEntry::dec_note_length));
607 myactions.register_action ("StepEditing", "next-note-velocity", _("Move to Next Note Velocity"), sigc::mem_fun (*this, &StepEntry::next_note_velocity));
608 myactions.register_action ("StepEditing", "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::mem_fun (*this, &StepEntry::prev_note_velocity));
610 myactions.register_action ("StepEditing", "inc-note-velocity", _("Increase Note Velocity"), sigc::mem_fun (*this, &StepEntry::inc_note_velocity));
611 myactions.register_action ("StepEditing", "dec-note-velocity", _("Decrease Note Velocity"), sigc::mem_fun (*this, &StepEntry::dec_note_velocity));
613 myactions.register_action ("StepEditing", "octave-0", _("Switch to the 1st octave"), sigc::mem_fun (*this, &StepEntry::octave_0));
614 myactions.register_action ("StepEditing", "octave-1", _("Switch to the 2nd octave"), sigc::mem_fun (*this, &StepEntry::octave_1));
615 myactions.register_action ("StepEditing", "octave-2", _("Switch to the 3rd octave"), sigc::mem_fun (*this, &StepEntry::octave_2));
616 myactions.register_action ("StepEditing", "octave-3", _("Switch to the 4th octave"), sigc::mem_fun (*this, &StepEntry::octave_3));
617 myactions.register_action ("StepEditing", "octave-4", _("Switch to the 5th octave"), sigc::mem_fun (*this, &StepEntry::octave_4));
618 myactions.register_action ("StepEditing", "octave-5", _("Switch to the 6th octave"), sigc::mem_fun (*this, &StepEntry::octave_5));
619 myactions.register_action ("StepEditing", "octave-6", _("Switch to the 7th octave"), sigc::mem_fun (*this, &StepEntry::octave_6));
620 myactions.register_action ("StepEditing", "octave-7", _("Switch to the 8th octave"), sigc::mem_fun (*this, &StepEntry::octave_7));
621 myactions.register_action ("StepEditing", "octave-8", _("Switch to the 9th octave"), sigc::mem_fun (*this, &StepEntry::octave_8));
622 myactions.register_action ("StepEditing", "octave-9", _("Switch to the 10th octave"), sigc::mem_fun (*this, &StepEntry::octave_9));
623 myactions.register_action ("StepEditing", "octave-10", _("Switch to the 11th octave"), sigc::mem_fun (*this, &StepEntry::octave_10));
626 RadioAction::Group note_length_group;
628 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
629 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
630 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
631 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
632 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
633 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
634 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
635 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
636 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
637 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
638 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
639 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
640 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
641 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
643 RadioAction::Group note_velocity_group;
645 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
646 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
647 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
648 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
649 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
650 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
651 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
652 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
653 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
654 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
655 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
656 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
657 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
658 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
659 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
660 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
662 myactions.register_toggle_action ("StepEditing", "toggle-triplet", _("Toggle Triple Notes"),
663 sigc::mem_fun (*this, &StepEntry::toggle_triplet));
665 RadioAction::Group dot_group;
667 myactions.register_radio_action ("StepEditing", dot_group, "no-dotted", _("No Dotted Notes"),
668 sigc::mem_fun (*this, &StepEntry::dot_change), 0);
669 myactions.register_radio_action ("StepEditing", dot_group, "toggle-dotted", _("Toggled Dotted Notes"),
670 sigc::mem_fun (*this, &StepEntry::dot_change), 1);
671 myactions.register_radio_action ("StepEditing", dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"),
672 sigc::mem_fun (*this, &StepEntry::dot_change), 2);
673 myactions.register_radio_action ("StepEditing", dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"),
674 sigc::mem_fun (*this, &StepEntry::dot_change), 3);
676 myactions.register_toggle_action ("StepEditing", "toggle-chord", _("Toggle Chord Entry"),
677 sigc::mem_fun (*this, &StepEntry::toggle_chord));
678 myactions.register_action ("StepEditing", "sustain", _("Sustain Selected Notes by Note Length"),
679 sigc::mem_fun (*this, &StepEntry::do_sustain));
681 myactions.register_action ("StepEditing", "sync-to-edit-point", _("Move Insert Position to Edit Point"),
682 sigc::mem_fun (*this, &StepEntry::sync_to_edit_point));
683 myactions.register_action ("StepEditing", "back", _("Move Insert Position Back by Note Length"),
684 sigc::mem_fun (*this, &StepEntry::back));
688 StepEntry::load_bindings ()
690 /* XXX move this to a better place */
691 KeyboardKey::set_ignored_state (GDK_LOCK_MASK|GDK_MOD2_MASK|GDK_MOD3_MASK);
693 bindings.set_action_map (myactions);
695 sys::path binding_file;
696 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
698 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
699 bindings.load (binding_file.to_string());
704 StepEntry::toggle_triplet ()
706 _mtv->set_step_edit_cursor_width (note_length());
710 StepEntry::toggle_chord ()
712 _mtv->step_edit_toggle_chord ();
716 StepEntry::dot_change (GtkAction* act)
718 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
719 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
720 dot_adjustment.set_value (v);
725 StepEntry::dot_value_change ()
728 RefPtr<RadioAction> ract;
729 double val = dot_adjustment.get_value();
730 bool inconsistent = true;
731 vector<const char*> dot_actions;
733 dot_actions.push_back ("StepEditing/no-dotted");
734 dot_actions.push_back ("StepEditing/toggle-dotted");
735 dot_actions.push_back ("StepEditing/toggle-double-dotted");
736 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
738 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
740 act = myactions.find_action (*i);
743 ract = RefPtr<RadioAction>::cast_dynamic (act);
746 if (ract->property_value() == val) {
747 ract->set_active (true);
748 inconsistent = false;
755 dot1_button.set_inconsistent (inconsistent);
756 dot2_button.set_inconsistent (inconsistent);
757 dot3_button.set_inconsistent (inconsistent);
759 _mtv->set_step_edit_cursor_width (note_length());
763 StepEntry::program_click ()
765 _mtv->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
769 StepEntry::bank_click ()
771 _mtv->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
775 StepEntry::insert_rest ()
777 _mtv->step_edit_rest (note_length());
781 StepEntry::insert_grid_rest ()
783 _mtv->step_edit_rest (0.0);
787 StepEntry::insert_note (uint8_t note)
789 _mtv->step_add_note (note_channel(), note, note_velocity(), note_length());
792 StepEntry::insert_c ()
794 insert_note (0 + (current_octave() * 12));
797 StepEntry::insert_csharp ()
799 insert_note (1 + (current_octave() * 12));
802 StepEntry::insert_d ()
804 insert_note (2 + (current_octave() * 12));
807 StepEntry::insert_dsharp ()
809 insert_note (3 + (current_octave() * 12));
812 StepEntry::insert_e ()
814 insert_note (4 + (current_octave() * 12));
817 StepEntry::insert_f ()
819 insert_note (5 + (current_octave() * 12));
822 StepEntry::insert_fsharp ()
824 insert_note (6 + (current_octave() * 12));
827 StepEntry::insert_g ()
829 insert_note (7 + (current_octave() * 12));
832 StepEntry::insert_gsharp ()
834 insert_note (8 + (current_octave() * 12));
838 StepEntry::insert_a ()
840 insert_note (9 + (current_octave() * 12));
844 StepEntry::insert_asharp ()
846 insert_note (10 + (current_octave() * 12));
849 StepEntry::insert_b ()
851 insert_note (11 + (current_octave() * 12));
855 StepEntry::note_length_change (GtkAction* act)
857 /* it doesn't matter which note length action we look up - we are interested
858 in the current_value which is global across the whole group of note length
859 actions. this method is called twice for every user operation,
860 once for the action that became "inactive" and once for the action that
861 becaome "active". so ... only bother to actually change the value when this
862 is called for the "active" action.
865 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
866 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
867 length_divisor_adjustment.set_value (v);
872 StepEntry::note_velocity_change (GtkAction* act)
874 /* it doesn't matter which note length action we look up - we are interested
875 in the current_value which is global across the whole group of note length
876 actions. this method is called twice for every user operation,
877 once for the action that became "inactive" and once for the action that
878 becaome "active". so ... only bother to actually change the value when this
879 is called for the "active" action.
882 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
883 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
884 velocity_adjustment.set_value (v);
889 StepEntry::velocity_value_change ()
892 RefPtr<RadioAction> ract;
893 double val = velocity_adjustment.get_value();
894 bool inconsistent = true;
895 vector<const char*> velocity_actions;
897 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
898 velocity_actions.push_back ("StepEditing/note-velocity-pp");
899 velocity_actions.push_back ("StepEditing/note-velocity-p");
900 velocity_actions.push_back ("StepEditing/note-velocity-mp");
901 velocity_actions.push_back ("StepEditing/note-velocity-mf");
902 velocity_actions.push_back ("StepEditing/note-velocity-f");
903 velocity_actions.push_back ("StepEditing/note-velocity-ff");
904 velocity_actions.push_back ("StepEditing/note-velocity-fff");
906 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
908 act = myactions.find_action (*i);
911 ract = RefPtr<RadioAction>::cast_dynamic (act);
914 if (ract->property_value() == val) {
915 ract->set_active (true);
916 inconsistent = false;
923 velocity_ppp_button.set_inconsistent (inconsistent);
924 velocity_pp_button.set_inconsistent (inconsistent);
925 velocity_p_button.set_inconsistent (inconsistent);
926 velocity_mp_button.set_inconsistent (inconsistent);
927 velocity_mf_button.set_inconsistent (inconsistent);
928 velocity_f_button.set_inconsistent (inconsistent);
929 velocity_ff_button.set_inconsistent (inconsistent);
930 velocity_fff_button.set_inconsistent (inconsistent);
934 StepEntry::length_value_change ()
937 RefPtr<RadioAction> ract;
938 double val = length_divisor_adjustment.get_value();
939 bool inconsistent = true;
940 vector<const char*> length_actions;
942 length_actions.push_back ("StepEditing/note-length-whole");
943 length_actions.push_back ("StepEditing/note-length-half");
944 length_actions.push_back ("StepEditing/note-length-quarter");
945 length_actions.push_back ("StepEditing/note-length-eighth");
946 length_actions.push_back ("StepEditing/note-length-sixteenth");
947 length_actions.push_back ("StepEditing/note-length-thirtysecond");
948 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
950 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
952 act = myactions.find_action (*i);
955 ract = RefPtr<RadioAction>::cast_dynamic (act);
958 if (ract->property_value() == val) {
959 ract->set_active (true);
960 inconsistent = false;
967 length_1_button.set_inconsistent (inconsistent);
968 length_2_button.set_inconsistent (inconsistent);
969 length_4_button.set_inconsistent (inconsistent);
970 length_8_button.set_inconsistent (inconsistent);
971 length_16_button.set_inconsistent (inconsistent);
972 length_32_button.set_inconsistent (inconsistent);
973 length_64_button.set_inconsistent (inconsistent);
975 _mtv->set_step_edit_cursor_width (note_length());
979 StepEntry::radio_button_press (GdkEventButton* ev)
981 if (ev->button == 1) {
989 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
991 if (ev->button == 1) {
992 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
995 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1005 StepEntry::next_octave ()
1007 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1011 StepEntry::prev_octave ()
1013 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1017 StepEntry::inc_note_length ()
1019 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1023 StepEntry::dec_note_length ()
1025 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1029 StepEntry::prev_note_length ()
1031 double l = length_divisor_adjustment.get_value();
1032 int il = (int) lrintf (l); // round to nearest integer
1033 il = (il/2) * 2; // round to power of 2
1041 length_divisor_adjustment.set_value (il);
1045 StepEntry::next_note_length ()
1047 double l = length_divisor_adjustment.get_value();
1048 int il = (int) lrintf (l); // round to nearest integer
1049 il = (il/2) * 2; // round to power of 2
1058 length_divisor_adjustment.set_value (il);
1063 StepEntry::inc_note_velocity ()
1065 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1069 StepEntry::dec_note_velocity ()
1071 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1075 StepEntry::next_note_velocity ()
1077 double l = velocity_adjustment.get_value ();
1081 } else if (l < 32) {
1083 } else if (l < 48) {
1085 } else if (l < 64) {
1087 } else if (l < 80) {
1089 } else if (l < 96) {
1091 } else if (l < 112) {
1093 } else if (l < 127) {
1097 velocity_adjustment.set_value (l);
1101 StepEntry::prev_note_velocity ()
1103 double l = velocity_adjustment.get_value ();
1107 } else if (l > 96) {
1109 } else if (l > 80) {
1111 } else if (l > 64) {
1113 } else if (l > 48) {
1115 } else if (l > 32) {
1117 } else if (l > 16) {
1123 velocity_adjustment.set_value (l);
1127 StepEntry::octave_n (int n)
1129 octave_adjustment.set_value (n);
1133 StepEntry::do_sustain ()
1135 _mtv->step_edit_sustain (note_length());
1141 _mtv->move_step_edit_beat_pos (-note_length());
1145 StepEntry::sync_to_edit_point ()
1147 _mtv->resync_step_edit_to_edit_point ();