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 , beat_resync_button (_(">beat"))
64 , bar_resync_button (_(">bar"))
65 , sustain_button (_("sustain"))
66 , rest_button (_("rest"))
67 , grid_rest_button (_("g-rest"))
68 , channel_adjustment (1, 1, 16, 1, 4)
69 , channel_spinner (channel_adjustment)
70 , octave_adjustment (0, 1, 11, 1, 4)
71 , octave_spinner (octave_adjustment)
72 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
73 , length_divisor_spinner (length_divisor_adjustment)
74 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
75 , velocity_spinner (velocity_adjustment)
76 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
77 , bank_spinner (bank_adjustment)
78 , bank_button (_("+"))
79 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
80 , program_spinner (program_adjustment)
81 , program_button (_("+"))
89 /* set channel selector to first selected channel. if none
90 are selected, it will remain at the value set in its
91 constructor, above (1)
94 uint16_t chn_mask = _mtv->channel_selector().get_selected_channels();
96 for (uint32_t i = 0; i < 16; ++i) {
97 if (chn_mask & (1<<i)) {
98 channel_adjustment.set_value (i+1);
103 RadioButtonGroup length_group = length_1_button.get_group();
104 length_2_button.set_group (length_group);
105 length_4_button.set_group (length_group);
106 length_8_button.set_group (length_group);
107 length_12_button.set_group (length_group);
108 length_16_button.set_group (length_group);
109 length_32_button.set_group (length_group);
110 length_64_button.set_group (length_group);
114 w = manage (new Image (::get_icon (X_("wholenote"))));
116 length_1_button.add (*w);
117 w = manage (new Image (::get_icon (X_("halfnote"))));
119 length_2_button.add (*w);
120 w = manage (new Image (::get_icon (X_("quarternote"))));
122 length_4_button.add (*w);
123 w = manage (new Image (::get_icon (X_("eighthnote"))));
125 length_8_button.add (*w);
126 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
128 length_16_button.add (*w);
129 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
131 length_32_button.add (*w);
132 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
134 length_64_button.add (*w);
138 act = myactions.find_action ("StepEditing/note-length-whole");
139 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
140 act = myactions.find_action ("StepEditing/note-length-half");
141 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
142 act = myactions.find_action ("StepEditing/note-length-quarter");
143 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
144 act = myactions.find_action ("StepEditing/note-length-eighth");
145 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
146 act = myactions.find_action ("StepEditing/note-length-sixteenth");
147 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
148 act = myactions.find_action ("StepEditing/note-length-thirtysecond");
149 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
150 act = myactions.find_action ("StepEditing/note-length-sixtyfourth");
151 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
153 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
154 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
155 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
156 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
157 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
158 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
159 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
160 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
161 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
162 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
163 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
164 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
165 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
166 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
168 length_1_button.property_draw_indicator() = false;
169 length_2_button.property_draw_indicator() = false;
170 length_4_button.property_draw_indicator() = false;
171 length_8_button.property_draw_indicator() = false;
172 length_16_button.property_draw_indicator() = false;
173 length_32_button.property_draw_indicator() = false;
174 length_64_button.property_draw_indicator() = false;
176 note_length_box.pack_start (length_1_button, false, false);
177 note_length_box.pack_start (length_2_button, false, false);
178 note_length_box.pack_start (length_4_button, false, false);
179 note_length_box.pack_start (length_8_button, false, false);
180 note_length_box.pack_start (length_16_button, false, false);
181 note_length_box.pack_start (length_32_button, false, false);
182 note_length_box.pack_start (length_64_button, false, false);
184 ARDOUR_UI::instance()->set_tip (&length_1_button, _("Set note length to a whole note"), "");
185 ARDOUR_UI::instance()->set_tip (&length_2_button, _("Set note length to a half note"), "");
186 ARDOUR_UI::instance()->set_tip (&length_4_button, _("Set note length to a quarter note"), "");
187 ARDOUR_UI::instance()->set_tip (&length_8_button, _("Set note length to a eighth note"), "");
188 ARDOUR_UI::instance()->set_tip (&length_16_button, _("Set note length to a sixteenth note"), "");
189 ARDOUR_UI::instance()->set_tip (&length_32_button, _("Set note length to a thirty-second note"), "");
190 ARDOUR_UI::instance()->set_tip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
192 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
193 velocity_pp_button.set_group (velocity_group);
194 velocity_p_button.set_group (velocity_group);
195 velocity_mp_button.set_group (velocity_group);
196 velocity_mf_button.set_group (velocity_group);
197 velocity_f_button.set_group (velocity_group);
198 velocity_ff_button.set_group (velocity_group);
199 velocity_fff_button.set_group (velocity_group);
201 w = manage (new Image (::get_icon (X_("pianississimo"))));
203 velocity_ppp_button.add (*w);
204 w = manage (new Image (::get_icon (X_("pianissimo"))));
206 velocity_pp_button.add (*w);
207 w = manage (new Image (::get_icon (X_("piano"))));
209 velocity_p_button.add (*w);
210 w = manage (new Image (::get_icon (X_("mezzopiano"))));
212 velocity_mp_button.add (*w);
213 w = manage (new Image (::get_icon (X_("mezzoforte"))));
215 velocity_mf_button.add (*w);
216 w = manage (new Image (::get_icon (X_("forte"))));
218 velocity_f_button.add (*w);
219 w = manage (new Image (::get_icon (X_("fortissimo"))));
221 velocity_ff_button.add (*w);
222 w = manage (new Image (::get_icon (X_("fortississimo"))));
224 velocity_fff_button.add (*w);
226 act = myactions.find_action ("StepEditing/note-velocity-ppp");
227 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
228 act = myactions.find_action ("StepEditing/note-velocity-pp");
229 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
230 act = myactions.find_action ("StepEditing/note-velocity-p");
231 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
232 act = myactions.find_action ("StepEditing/note-velocity-mp");
233 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
234 act = myactions.find_action ("StepEditing/note-velocity-mf");
235 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
236 act = myactions.find_action ("StepEditing/note-velocity-f");
237 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
238 act = myactions.find_action ("StepEditing/note-velocity-ff");
239 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
240 act = myactions.find_action ("StepEditing/note-velocity-fff");
241 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
243 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
244 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
245 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
246 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
247 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
248 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
249 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
250 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
251 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
252 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
253 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
254 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
255 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
256 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
257 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
258 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
260 velocity_ppp_button.property_draw_indicator() = false;
261 velocity_pp_button.property_draw_indicator() = false;
262 velocity_p_button.property_draw_indicator() = false;
263 velocity_mp_button.property_draw_indicator() = false;
264 velocity_mf_button.property_draw_indicator() = false;
265 velocity_f_button.property_draw_indicator() = false;
266 velocity_ff_button.property_draw_indicator() = false;
267 velocity_fff_button.property_draw_indicator() = false;
269 ARDOUR_UI::instance()->set_tip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
270 ARDOUR_UI::instance()->set_tip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
271 ARDOUR_UI::instance()->set_tip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
272 ARDOUR_UI::instance()->set_tip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
273 ARDOUR_UI::instance()->set_tip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
274 ARDOUR_UI::instance()->set_tip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
275 ARDOUR_UI::instance()->set_tip (&velocity_ff_button, _("Set volume (velocity) to forteissimo"), "");
276 ARDOUR_UI::instance()->set_tip (&velocity_fff_button, _("Set volume (velocity) to forteississimo"), "");
278 note_velocity_box.pack_start (velocity_ppp_button, false, false);
279 note_velocity_box.pack_start (velocity_pp_button, false, false);
280 note_velocity_box.pack_start (velocity_p_button, false, false);
281 note_velocity_box.pack_start (velocity_mp_button, false, false);
282 note_velocity_box.pack_start (velocity_mf_button, false, false);
283 note_velocity_box.pack_start (velocity_f_button, false, false);
284 note_velocity_box.pack_start (velocity_ff_button, false, false);
285 note_velocity_box.pack_start (velocity_fff_button, false, false);
287 Label* l = manage (new Label);
288 l->set_markup ("<b><big>.</big></b>");
292 w = manage (new Image (::get_icon (X_("chord"))));
294 chord_button.add (*w);
296 rest_box.pack_start (rest_button, true, false);
297 rest_box.pack_start (grid_rest_button, true, false);
299 resync_box.pack_start (beat_resync_button, true, false);
300 resync_box.pack_start (bar_resync_button, true, false);
302 ARDOUR_UI::instance()->set_tip (&chord_button, _("Stack inserted notes to form a chord"), "");
303 ARDOUR_UI::instance()->set_tip (&sustain_button, _("Extend selected notes by note length"), "");
304 ARDOUR_UI::instance()->set_tip (&dot_button, _("Use dotted note lengths"), "");
305 ARDOUR_UI::instance()->set_tip (&rest_button, _("Insert a note-length's rest"), "");
306 ARDOUR_UI::instance()->set_tip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
307 ARDOUR_UI::instance()->set_tip (&beat_resync_button, _("Insert a rest until the next beat"), "");
308 ARDOUR_UI::instance()->set_tip (&bar_resync_button, _("Insert a rest until the next bar"), "");
309 ARDOUR_UI::instance()->set_tip (&bank_button, _("Insert a bank change message"), "");
310 ARDOUR_UI::instance()->set_tip (&program_button, _("Insert a program change message"), "");
312 upper_box.set_spacing (6);
313 upper_box.pack_start (chord_button, false, false);
314 upper_box.pack_start (note_length_box, false, false, 12);
315 upper_box.pack_start (triplet_button, false, false);
316 upper_box.pack_start (dot_button, false, false);
317 upper_box.pack_start (sustain_button, false, false);
318 upper_box.pack_start (rest_box, false, false);
319 upper_box.pack_start (resync_box, false, false);
320 upper_box.pack_start (note_velocity_box, false, false, 12);
324 v = manage (new VBox);
325 l = manage (new Label (_("Channel")));
327 v->pack_start (*l, false, false);
328 v->pack_start (channel_spinner, false, false);
329 upper_box.pack_start (*v, false, false);
331 v = manage (new VBox);
332 l = manage (new Label (_("1/Note")));
334 v->pack_start (*l, false, false);
335 v->pack_start (length_divisor_spinner, false, false);
336 upper_box.pack_start (*v, false, false);
338 v = manage (new VBox);
339 l = manage (new Label (_("Velocity")));
341 v->pack_start (*l, false, false);
342 v->pack_start (velocity_spinner, false, false);
343 upper_box.pack_start (*v, false, false);
345 v = manage (new VBox);
346 l = manage (new Label (_("Octave")));
348 v->pack_start (*l, false, false);
349 v->pack_start (octave_spinner, false, false);
350 upper_box.pack_start (*v, false, false);
352 v = manage (new VBox);
353 l = manage (new Label (_("Bank")));
355 v->pack_start (*l, false, false);
356 v->pack_start (bank_spinner, false, false);
357 v->pack_start (bank_button, false, false);
358 upper_box.pack_start (*v, false, false);
360 v = manage (new VBox);
361 l = manage (new Label (_("Program")));
363 v->pack_start (*l, false, false);
364 v->pack_start (program_spinner, false, false);
365 v->pack_start (program_button, false, false);
366 upper_box.pack_start (*v, false, false);
368 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
369 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
371 _piano = (PianoKeyboard*) piano_keyboard_new ();
372 piano = wrap ((GtkWidget*) _piano);
374 piano->set_flags (Gtk::CAN_FOCUS);
376 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
377 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
379 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
380 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
381 rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::rest_click));
382 grid_rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::grid_rest_click));
383 chord_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::chord_toggled));
384 triplet_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::triplet_toggled));
385 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
386 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
388 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
390 packer.set_spacing (6);
391 packer.pack_start (upper_box, false, false);
392 packer.pack_start (*piano, false, false);
395 get_vbox()->add (packer);
398 StepEntry::~StepEntry()
403 StepEntry::length_changed ()
405 length_1_button.queue_draw ();
406 length_2_button.queue_draw ();
407 length_4_button.queue_draw ();
408 length_8_button.queue_draw ();
409 length_16_button.queue_draw ();
410 length_32_button.queue_draw ();
411 length_64_button.queue_draw ();
415 StepEntry::on_key_press_event (GdkEventKey* ev)
417 /* focus widget gets first shot, then bindings, otherwise
418 forward to main window
421 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
422 KeyboardKey k (ev->state, ev->keyval);
424 if (bindings.activate (k, KeyboardKey::Press)) {
429 return forward_key_press (ev);
433 StepEntry::on_key_release_event (GdkEventKey* ev)
435 /* focus widget gets first shot, then bindings, otherwise
436 forward to main window
439 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
440 KeyboardKey k (ev->state, ev->keyval);
442 if (bindings.activate (k, KeyboardKey::Release)) {
447 return forward_key_press (ev);
451 StepEntry::rest_event_handler ()
453 _mtv->step_edit_rest (0.0);
457 StepEntry::note_length () const
459 return 1.0 / (Evoral::MusicalTime) length_divisor_adjustment.get_value();
463 StepEntry::note_velocity () const
465 return (Evoral::MusicalTime) velocity_adjustment.get_value();
469 StepEntry::note_channel() const
471 return channel_adjustment.get_value() - 1;
475 StepEntry::note_off_event_handler (int note)
481 StepEntry::rest_click ()
487 StepEntry::grid_rest_click ()
493 StepEntry::triplet_toggled ()
495 if (triplet_button.get_active () != _mtv->step_edit_within_triplet()) {
496 _mtv->step_edit_toggle_triplet ();
501 StepEntry::chord_toggled ()
503 if (chord_button.get_active() != _mtv->step_edit_within_chord ()) {
504 _mtv->step_edit_toggle_chord ();
509 StepEntry::on_show ()
511 ArdourDialog::on_show ();
512 piano->grab_focus ();
516 StepEntry::beat_resync_click ()
518 _mtv->step_edit_beat_sync ();
522 StepEntry::bar_resync_click ()
524 _mtv->step_edit_bar_sync ();
528 StepEntry::register_actions ()
530 /* add named actions for the editor */
532 myactions.register_action ("StepEditing", "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
533 myactions.register_action ("StepEditing", "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
534 myactions.register_action ("StepEditing", "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
535 myactions.register_action ("StepEditing", "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
536 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
537 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
538 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
539 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
540 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
541 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
542 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
543 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
545 RadioAction::Group note_length_group;
547 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
548 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
549 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
550 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
551 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
552 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
553 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
554 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
555 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
556 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
557 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
558 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
559 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
560 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
562 RadioAction::Group note_velocity_group;
564 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
565 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
566 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
567 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
568 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
569 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
570 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
571 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
572 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
573 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
574 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
575 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
576 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
577 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
578 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
579 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
583 StepEntry::load_bindings ()
585 bindings.set_action_map (myactions);
587 sys::path binding_file;
588 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
590 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
591 bindings.load (binding_file.to_string());
596 StepEntry::program_click ()
598 _mtv->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
602 StepEntry::bank_click ()
604 _mtv->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
608 StepEntry::insert_rest ()
610 _mtv->step_edit_rest (note_length());
614 StepEntry::insert_grid_rest ()
616 _mtv->step_edit_rest (0.0);
620 StepEntry::insert_note (uint8_t note)
622 _mtv->step_add_note (note_channel(), note, note_velocity(), note_length());
625 StepEntry::insert_c ()
627 insert_note (0 + (current_octave() * 12));
630 StepEntry::insert_csharp ()
632 insert_note (1 + (current_octave() * 12));
635 StepEntry::insert_d ()
637 insert_note (2 + (current_octave() * 12));
640 StepEntry::insert_dsharp ()
642 insert_note (3 + (current_octave() * 12));
645 StepEntry::insert_e ()
647 insert_note (4 + (current_octave() * 12));
650 StepEntry::insert_f ()
652 insert_note (5 + (current_octave() * 12));
655 StepEntry::insert_fsharp ()
657 insert_note (6 + (current_octave() * 12));
660 StepEntry::insert_g ()
662 insert_note (7 + (current_octave() * 12));
665 StepEntry::insert_gsharp ()
667 insert_note (8 + (current_octave() * 12));
671 StepEntry::insert_a ()
673 insert_note (9 + (current_octave() * 12));
677 StepEntry::insert_asharp ()
679 insert_note (10 + (current_octave() * 12));
682 StepEntry::insert_b ()
684 insert_note (11 + (current_octave() * 12));
688 StepEntry::note_length_change (GtkAction* act)
690 /* it doesn't matter which note length action we look up - we are interested
691 in the current_value which is global across the whole group of note length
692 actions. this method is called twice for every user operation,
693 once for the action that became "inactive" and once for the action that
694 becaome "active". so ... only bother to actually change the value when this
695 is called for the "active" action.
698 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
699 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
700 length_divisor_adjustment.set_value (v);
705 StepEntry::note_velocity_change (GtkAction* act)
707 /* it doesn't matter which note length action we look up - we are interested
708 in the current_value which is global across the whole group of note length
709 actions. this method is called twice for every user operation,
710 once for the action that became "inactive" and once for the action that
711 becaome "active". so ... only bother to actually change the value when this
712 is called for the "active" action.
715 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
716 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
717 cerr << "Velocity reset to " << v << endl;
718 velocity_adjustment.set_value (v);
723 StepEntry::velocity_value_change ()
726 RefPtr<RadioAction> ract;
727 double val = velocity_adjustment.get_value();
728 bool inconsistent = true;
729 vector<const char*> velocity_actions;
731 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
732 velocity_actions.push_back ("StepEditing/note-velocity-pp");
733 velocity_actions.push_back ("StepEditing/note-velocity-p");
734 velocity_actions.push_back ("StepEditing/note-velocity-mp");
735 velocity_actions.push_back ("StepEditing/note-velocity-mf");
736 velocity_actions.push_back ("StepEditing/note-velocity-f");
737 velocity_actions.push_back ("StepEditing/note-velocity-ff");
738 velocity_actions.push_back ("StepEditing/note-velocity-fff");
740 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
742 act = myactions.find_action (*i);
745 ract = RefPtr<RadioAction>::cast_dynamic (act);
748 if (ract->property_value() == val) {
749 ract->set_active (true);
750 inconsistent = false;
757 velocity_ppp_button.set_inconsistent (inconsistent);
758 velocity_pp_button.set_inconsistent (inconsistent);
759 velocity_p_button.set_inconsistent (inconsistent);
760 velocity_mp_button.set_inconsistent (inconsistent);
761 velocity_mf_button.set_inconsistent (inconsistent);
762 velocity_f_button.set_inconsistent (inconsistent);
763 velocity_ff_button.set_inconsistent (inconsistent);
764 velocity_fff_button.set_inconsistent (inconsistent);
768 StepEntry::length_value_change ()
771 RefPtr<RadioAction> ract;
772 double val = length_divisor_adjustment.get_value();
773 bool inconsistent = true;
774 vector<const char*> length_actions;
776 length_actions.push_back ("StepEditing/note-length-whole");
777 length_actions.push_back ("StepEditing/note-length-half");
778 length_actions.push_back ("StepEditing/note-length-quarter");
779 length_actions.push_back ("StepEditing/note-length-eighth");
780 length_actions.push_back ("StepEditing/note-length-sixteenth");
781 length_actions.push_back ("StepEditing/note-length-thirtysecond");
782 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
784 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
786 act = myactions.find_action (*i);
789 ract = RefPtr<RadioAction>::cast_dynamic (act);
792 if (ract->property_value() == val) {
793 ract->set_active (true);
794 inconsistent = false;
801 length_1_button.set_inconsistent (inconsistent);
802 length_2_button.set_inconsistent (inconsistent);
803 length_4_button.set_inconsistent (inconsistent);
804 length_8_button.set_inconsistent (inconsistent);
805 length_16_button.set_inconsistent (inconsistent);
806 length_32_button.set_inconsistent (inconsistent);
807 length_64_button.set_inconsistent (inconsistent);
809 _mtv->set_step_edit_cursor_width (note_length());
813 StepEntry::radio_button_press (GdkEventButton* ev)
815 if (ev->button == 1) {
823 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
825 if (ev->button == 1) {
826 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
829 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);