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 (4, 1, 11, 1, 4) // start in octave 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 act = myactions.find_action ("StepEditing/toggle-triplet");
313 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
314 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
315 act = myactions.find_action ("StepEditing/toggle-dotted");
316 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot_button.gobj()), false);
317 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot_button.gobj()), act->gobj());
318 act = myactions.find_action ("StepEditing/toggle-chord");
319 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
320 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
321 act = myactions.find_action ("StepEditing/insert-rest");
322 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
323 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
324 act = myactions.find_action ("StepEditing/insert-snap-rest");
325 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
326 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
327 act = myactions.find_action ("StepEditing/sustain");
328 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
329 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
331 upper_box.set_spacing (6);
332 upper_box.pack_start (chord_button, false, false);
333 upper_box.pack_start (note_length_box, false, false, 12);
334 upper_box.pack_start (triplet_button, false, false);
335 upper_box.pack_start (dot_button, false, false);
336 upper_box.pack_start (sustain_button, false, false);
337 upper_box.pack_start (rest_box, false, false);
338 upper_box.pack_start (resync_box, false, false);
339 upper_box.pack_start (note_velocity_box, false, false, 12);
343 v = manage (new VBox);
344 l = manage (new Label (_("Channel")));
346 v->pack_start (*l, false, false);
347 v->pack_start (channel_spinner, false, false);
348 upper_box.pack_start (*v, false, false);
350 v = manage (new VBox);
351 l = manage (new Label (_("1/Note")));
353 v->pack_start (*l, false, false);
354 v->pack_start (length_divisor_spinner, false, false);
355 upper_box.pack_start (*v, false, false);
357 v = manage (new VBox);
358 l = manage (new Label (_("Velocity")));
360 v->pack_start (*l, false, false);
361 v->pack_start (velocity_spinner, false, false);
362 upper_box.pack_start (*v, false, false);
364 v = manage (new VBox);
365 l = manage (new Label (_("Octave")));
367 v->pack_start (*l, false, false);
368 v->pack_start (octave_spinner, false, false);
369 upper_box.pack_start (*v, false, false);
371 v = manage (new VBox);
372 l = manage (new Label (_("Bank")));
374 v->pack_start (*l, false, false);
375 v->pack_start (bank_spinner, false, false);
376 v->pack_start (bank_button, false, false);
377 upper_box.pack_start (*v, false, false);
379 v = manage (new VBox);
380 l = manage (new Label (_("Program")));
382 v->pack_start (*l, false, false);
383 v->pack_start (program_spinner, false, false);
384 v->pack_start (program_button, false, false);
385 upper_box.pack_start (*v, false, false);
387 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
388 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
390 _piano = (PianoKeyboard*) piano_keyboard_new ();
391 piano = wrap ((GtkWidget*) _piano);
393 piano->set_flags (Gtk::CAN_FOCUS);
395 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
396 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
398 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
399 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
400 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
401 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
403 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
405 packer.set_spacing (6);
406 packer.pack_start (upper_box, false, false);
407 packer.pack_start (*piano, false, false);
410 get_vbox()->add (packer);
413 StepEntry::~StepEntry()
418 StepEntry::length_changed ()
420 length_1_button.queue_draw ();
421 length_2_button.queue_draw ();
422 length_4_button.queue_draw ();
423 length_8_button.queue_draw ();
424 length_16_button.queue_draw ();
425 length_32_button.queue_draw ();
426 length_64_button.queue_draw ();
430 StepEntry::on_key_press_event (GdkEventKey* ev)
432 /* focus widget gets first shot, then bindings, otherwise
433 forward to main window
436 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
437 KeyboardKey k (ev->state, ev->keyval);
439 if (bindings.activate (k, KeyboardKey::Press)) {
444 return forward_key_press (ev);
448 StepEntry::on_key_release_event (GdkEventKey* ev)
450 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
451 KeyboardKey k (ev->state, ev->keyval);
453 if (bindings.activate (k, KeyboardKey::Release)) {
458 /* don't forward releases */
464 StepEntry::rest_event_handler ()
466 _mtv->step_edit_rest (0.0);
470 StepEntry::note_length ()
472 Evoral::MusicalTime base_time = 1.0 / (Evoral::MusicalTime) length_divisor_adjustment.get_value();
474 RefPtr<Action> act = myactions.find_action ("StepEditing/toggle-triplet");
475 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
476 bool triplets = tact->get_active ();
478 act = myactions.find_action ("StepEditing/toggle-dotted");
479 tact = RefPtr<ToggleAction>::cast_dynamic (act);
480 bool dotted = tact->get_active ();
483 base_time *= (2.0/3.0);
487 base_time *= 1.5; // add support for multiple dots sometime
494 StepEntry::note_velocity () const
496 return (Evoral::MusicalTime) velocity_adjustment.get_value();
500 StepEntry::note_channel() const
502 return channel_adjustment.get_value() - 1;
506 StepEntry::note_off_event_handler (int note)
513 StepEntry::on_show ()
515 ArdourDialog::on_show ();
516 //piano->grab_focus ();
520 StepEntry::beat_resync_click ()
522 _mtv->step_edit_beat_sync ();
526 StepEntry::bar_resync_click ()
528 _mtv->step_edit_bar_sync ();
532 StepEntry::register_actions ()
534 /* add named actions for the editor */
536 myactions.register_action ("StepEditing", "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
537 myactions.register_action ("StepEditing", "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
538 myactions.register_action ("StepEditing", "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
539 myactions.register_action ("StepEditing", "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
540 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
541 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
542 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
543 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
544 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
545 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
546 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
547 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
549 myactions.register_action ("StepEditing", "insert-rest", _("Insert a Note-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_rest));
550 myactions.register_action ("StepEditing", "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_grid_rest));
552 myactions.register_action ("StepEditing", "next-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::next_octave));
553 myactions.register_action ("StepEditing", "prev-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::prev_octave));
555 myactions.register_action ("StepEditing", "next-note-length", _("Move to Next Note Length"), sigc::mem_fun (*this, &StepEntry::next_note_length));
556 myactions.register_action ("StepEditing", "prev-note-length", _("Move to Previous Note Length"), sigc::mem_fun (*this, &StepEntry::prev_note_length));
558 myactions.register_action ("StepEditing", "inc-note-length", _("Increase Note Length"), sigc::mem_fun (*this, &StepEntry::inc_note_length));
559 myactions.register_action ("StepEditing", "dec-note-length", _("Decrease Note Length"), sigc::mem_fun (*this, &StepEntry::dec_note_length));
561 myactions.register_action ("StepEditing", "next-note-velocity", _("Move to Next Note Velocity"), sigc::mem_fun (*this, &StepEntry::next_note_velocity));
562 myactions.register_action ("StepEditing", "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::mem_fun (*this, &StepEntry::prev_note_velocity));
564 myactions.register_action ("StepEditing", "inc-note-velocity", _("Increase Note Velocity"), sigc::mem_fun (*this, &StepEntry::inc_note_velocity));
565 myactions.register_action ("StepEditing", "dec-note-velocity", _("Decrease Note Velocity"), sigc::mem_fun (*this, &StepEntry::dec_note_velocity));
567 myactions.register_action ("StepEditing", "octave-0", _("Switch to the 1st octave"), sigc::mem_fun (*this, &StepEntry::octave_0));
568 myactions.register_action ("StepEditing", "octave-1", _("Switch to the 2nd octave"), sigc::mem_fun (*this, &StepEntry::octave_1));
569 myactions.register_action ("StepEditing", "octave-2", _("Switch to the 3rd octave"), sigc::mem_fun (*this, &StepEntry::octave_2));
570 myactions.register_action ("StepEditing", "octave-3", _("Switch to the 4th octave"), sigc::mem_fun (*this, &StepEntry::octave_3));
571 myactions.register_action ("StepEditing", "octave-4", _("Switch to the 5th octave"), sigc::mem_fun (*this, &StepEntry::octave_4));
572 myactions.register_action ("StepEditing", "octave-5", _("Switch to the 6th octave"), sigc::mem_fun (*this, &StepEntry::octave_5));
573 myactions.register_action ("StepEditing", "octave-6", _("Switch to the 7th octave"), sigc::mem_fun (*this, &StepEntry::octave_6));
574 myactions.register_action ("StepEditing", "octave-7", _("Switch to the 8th octave"), sigc::mem_fun (*this, &StepEntry::octave_7));
575 myactions.register_action ("StepEditing", "octave-8", _("Switch to the 9th octave"), sigc::mem_fun (*this, &StepEntry::octave_8));
576 myactions.register_action ("StepEditing", "octave-9", _("Switch to the 10th octave"), sigc::mem_fun (*this, &StepEntry::octave_9));
577 myactions.register_action ("StepEditing", "octave-10", _("Switch to the 11th octave"), sigc::mem_fun (*this, &StepEntry::octave_10));
580 RadioAction::Group note_length_group;
582 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
583 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
584 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
585 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
586 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
587 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
588 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
589 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
590 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
591 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
592 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
593 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
594 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
595 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
597 RadioAction::Group note_velocity_group;
599 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
600 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
601 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
602 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
603 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
604 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
605 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
606 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
607 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
608 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
609 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
610 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
611 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
612 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
613 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
614 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
616 myactions.register_toggle_action ("StepEditing", "toggle-triplet", _("Toggle Triple Notes"),
617 sigc::mem_fun (*this, &StepEntry::toggle_dotted));
618 myactions.register_toggle_action ("StepEditing", "toggle-dotted", _("Toggled Dotted Notes"),
619 sigc::mem_fun (*this, &StepEntry::toggle_triplet));
620 myactions.register_toggle_action ("StepEditing", "toggle-chord", _("Toggle Chord Entry"),
621 sigc::mem_fun (*this, &StepEntry::toggle_chord));
622 myactions.register_action ("StepEditing", "sustain", _("Sustain Selected Notes by Note Length"),
623 sigc::mem_fun (*this, &StepEntry::do_sustain));
627 StepEntry::load_bindings ()
629 /* XXX move this to a better place */
630 KeyboardKey::set_ignored_state (GDK_LOCK_MASK|GDK_MOD2_MASK|GDK_MOD3_MASK);
632 bindings.set_action_map (myactions);
634 sys::path binding_file;
635 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
637 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
638 bindings.load (binding_file.to_string());
643 StepEntry::toggle_triplet ()
649 StepEntry::toggle_chord ()
651 _mtv->step_edit_toggle_chord ();
655 StepEntry::toggle_dotted ()
661 StepEntry::program_click ()
663 _mtv->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
667 StepEntry::bank_click ()
669 _mtv->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
673 StepEntry::insert_rest ()
675 _mtv->step_edit_rest (note_length());
679 StepEntry::insert_grid_rest ()
681 _mtv->step_edit_rest (0.0);
685 StepEntry::insert_note (uint8_t note)
687 _mtv->step_add_note (note_channel(), note, note_velocity(), note_length());
690 StepEntry::insert_c ()
692 insert_note (0 + (current_octave() * 12));
695 StepEntry::insert_csharp ()
697 insert_note (1 + (current_octave() * 12));
700 StepEntry::insert_d ()
702 insert_note (2 + (current_octave() * 12));
705 StepEntry::insert_dsharp ()
707 insert_note (3 + (current_octave() * 12));
710 StepEntry::insert_e ()
712 insert_note (4 + (current_octave() * 12));
715 StepEntry::insert_f ()
717 insert_note (5 + (current_octave() * 12));
720 StepEntry::insert_fsharp ()
722 insert_note (6 + (current_octave() * 12));
725 StepEntry::insert_g ()
727 insert_note (7 + (current_octave() * 12));
730 StepEntry::insert_gsharp ()
732 insert_note (8 + (current_octave() * 12));
736 StepEntry::insert_a ()
738 insert_note (9 + (current_octave() * 12));
742 StepEntry::insert_asharp ()
744 insert_note (10 + (current_octave() * 12));
747 StepEntry::insert_b ()
749 insert_note (11 + (current_octave() * 12));
753 StepEntry::note_length_change (GtkAction* act)
755 /* it doesn't matter which note length action we look up - we are interested
756 in the current_value which is global across the whole group of note length
757 actions. this method is called twice for every user operation,
758 once for the action that became "inactive" and once for the action that
759 becaome "active". so ... only bother to actually change the value when this
760 is called for the "active" action.
763 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
764 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
765 length_divisor_adjustment.set_value (v);
770 StepEntry::note_velocity_change (GtkAction* act)
772 /* it doesn't matter which note length action we look up - we are interested
773 in the current_value which is global across the whole group of note length
774 actions. this method is called twice for every user operation,
775 once for the action that became "inactive" and once for the action that
776 becaome "active". so ... only bother to actually change the value when this
777 is called for the "active" action.
780 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
781 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
782 velocity_adjustment.set_value (v);
787 StepEntry::velocity_value_change ()
790 RefPtr<RadioAction> ract;
791 double val = velocity_adjustment.get_value();
792 bool inconsistent = true;
793 vector<const char*> velocity_actions;
795 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
796 velocity_actions.push_back ("StepEditing/note-velocity-pp");
797 velocity_actions.push_back ("StepEditing/note-velocity-p");
798 velocity_actions.push_back ("StepEditing/note-velocity-mp");
799 velocity_actions.push_back ("StepEditing/note-velocity-mf");
800 velocity_actions.push_back ("StepEditing/note-velocity-f");
801 velocity_actions.push_back ("StepEditing/note-velocity-ff");
802 velocity_actions.push_back ("StepEditing/note-velocity-fff");
804 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
806 act = myactions.find_action (*i);
809 ract = RefPtr<RadioAction>::cast_dynamic (act);
812 if (ract->property_value() == val) {
813 ract->set_active (true);
814 inconsistent = false;
821 velocity_ppp_button.set_inconsistent (inconsistent);
822 velocity_pp_button.set_inconsistent (inconsistent);
823 velocity_p_button.set_inconsistent (inconsistent);
824 velocity_mp_button.set_inconsistent (inconsistent);
825 velocity_mf_button.set_inconsistent (inconsistent);
826 velocity_f_button.set_inconsistent (inconsistent);
827 velocity_ff_button.set_inconsistent (inconsistent);
828 velocity_fff_button.set_inconsistent (inconsistent);
832 StepEntry::length_value_change ()
835 RefPtr<RadioAction> ract;
836 double val = length_divisor_adjustment.get_value();
837 bool inconsistent = true;
838 vector<const char*> length_actions;
840 length_actions.push_back ("StepEditing/note-length-whole");
841 length_actions.push_back ("StepEditing/note-length-half");
842 length_actions.push_back ("StepEditing/note-length-quarter");
843 length_actions.push_back ("StepEditing/note-length-eighth");
844 length_actions.push_back ("StepEditing/note-length-sixteenth");
845 length_actions.push_back ("StepEditing/note-length-thirtysecond");
846 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
848 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
850 act = myactions.find_action (*i);
853 ract = RefPtr<RadioAction>::cast_dynamic (act);
856 if (ract->property_value() == val) {
857 ract->set_active (true);
858 inconsistent = false;
865 length_1_button.set_inconsistent (inconsistent);
866 length_2_button.set_inconsistent (inconsistent);
867 length_4_button.set_inconsistent (inconsistent);
868 length_8_button.set_inconsistent (inconsistent);
869 length_16_button.set_inconsistent (inconsistent);
870 length_32_button.set_inconsistent (inconsistent);
871 length_64_button.set_inconsistent (inconsistent);
873 _mtv->set_step_edit_cursor_width (note_length());
877 StepEntry::radio_button_press (GdkEventButton* ev)
879 if (ev->button == 1) {
887 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
889 if (ev->button == 1) {
890 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
893 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
903 StepEntry::next_octave ()
905 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
909 StepEntry::prev_octave ()
911 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
915 StepEntry::inc_note_length ()
917 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
921 StepEntry::dec_note_length ()
923 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
927 StepEntry::prev_note_length ()
929 double l = length_divisor_adjustment.get_value();
930 int il = (int) lrintf (l); // round to nearest integer
931 il = (il/2) * 2; // round to power of 2
939 length_divisor_adjustment.set_value (il);
943 StepEntry::next_note_length ()
945 double l = length_divisor_adjustment.get_value();
946 int il = (int) lrintf (l); // round to nearest integer
947 il = (il/2) * 2; // round to power of 2
956 length_divisor_adjustment.set_value (il);
961 StepEntry::inc_note_velocity ()
963 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
967 StepEntry::dec_note_velocity ()
969 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
973 StepEntry::next_note_velocity ()
975 double l = velocity_adjustment.get_value ();
989 } else if (l < 112) {
991 } else if (l < 127) {
995 velocity_adjustment.set_value (l);
999 StepEntry::prev_note_velocity ()
1001 double l = velocity_adjustment.get_value ();
1005 } else if (l > 96) {
1007 } else if (l > 80) {
1009 } else if (l > 64) {
1011 } else if (l > 48) {
1013 } else if (l > 32) {
1015 } else if (l > 16) {
1021 velocity_adjustment.set_value (l);
1025 StepEntry::octave_n (int n)
1027 octave_adjustment.set_value (n);
1031 StepEntry::do_sustain ()
1033 _mtv->step_edit_sustain (note_length());