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)
83 /* set channel selector to first selected channel. if none
84 are selected, it will remain at the value set in its
85 constructor, above (1)
88 uint16_t chn_mask = _mtv->channel_selector().get_selected_channels();
90 for (uint32_t i = 0; i < 16; ++i) {
91 if (chn_mask & (1<<i)) {
92 channel_adjustment.set_value (i+1);
97 RadioButtonGroup length_group = length_1_button.get_group();
98 length_2_button.set_group (length_group);
99 length_4_button.set_group (length_group);
100 length_8_button.set_group (length_group);
101 length_12_button.set_group (length_group);
102 length_16_button.set_group (length_group);
103 length_32_button.set_group (length_group);
104 length_64_button.set_group (length_group);
108 w = manage (new Image (::get_icon (X_("wholenote"))));
110 length_1_button.add (*w);
111 w = manage (new Image (::get_icon (X_("halfnote"))));
113 length_2_button.add (*w);
114 w = manage (new Image (::get_icon (X_("quarternote"))));
116 length_4_button.add (*w);
117 w = manage (new Image (::get_icon (X_("eighthnote"))));
119 length_8_button.add (*w);
120 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
122 length_16_button.add (*w);
123 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
125 length_32_button.add (*w);
126 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
128 length_64_button.add (*w);
132 act = myactions.find_action ("StepEditing/note-length-whole");
133 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
134 act = myactions.find_action ("StepEditing/note-length-half");
135 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
136 act = myactions.find_action ("StepEditing/note-length-quarter");
137 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
138 act = myactions.find_action ("StepEditing/note-length-eighth");
139 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
140 act = myactions.find_action ("StepEditing/note-length-sixteenth");
141 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
142 act = myactions.find_action ("StepEditing/note-length-thirtysecond");
143 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
144 act = myactions.find_action ("StepEditing/note-length-sixtyfourth");
145 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
147 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
148 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
149 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
150 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
151 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
152 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
153 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
154 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
155 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
156 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
157 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
158 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
159 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
160 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
162 length_1_button.property_draw_indicator() = false;
163 length_2_button.property_draw_indicator() = false;
164 length_4_button.property_draw_indicator() = false;
165 length_8_button.property_draw_indicator() = false;
166 length_16_button.property_draw_indicator() = false;
167 length_32_button.property_draw_indicator() = false;
168 length_64_button.property_draw_indicator() = false;
170 note_length_box.pack_start (length_1_button, false, false);
171 note_length_box.pack_start (length_2_button, false, false);
172 note_length_box.pack_start (length_4_button, false, false);
173 note_length_box.pack_start (length_8_button, false, false);
174 note_length_box.pack_start (length_16_button, false, false);
175 note_length_box.pack_start (length_32_button, false, false);
176 note_length_box.pack_start (length_64_button, false, false);
178 ARDOUR_UI::instance()->set_tip (&length_1_button, _("Set note length to a whole note"), "");
179 ARDOUR_UI::instance()->set_tip (&length_2_button, _("Set note length to a half note"), "");
180 ARDOUR_UI::instance()->set_tip (&length_4_button, _("Set note length to a quarter note"), "");
181 ARDOUR_UI::instance()->set_tip (&length_8_button, _("Set note length to a eighth note"), "");
182 ARDOUR_UI::instance()->set_tip (&length_16_button, _("Set note length to a sixteenth note"), "");
183 ARDOUR_UI::instance()->set_tip (&length_32_button, _("Set note length to a thirty-second note"), "");
184 ARDOUR_UI::instance()->set_tip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
186 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
187 velocity_pp_button.set_group (velocity_group);
188 velocity_p_button.set_group (velocity_group);
189 velocity_mp_button.set_group (velocity_group);
190 velocity_mf_button.set_group (velocity_group);
191 velocity_f_button.set_group (velocity_group);
192 velocity_ff_button.set_group (velocity_group);
193 velocity_fff_button.set_group (velocity_group);
195 w = manage (new Image (::get_icon (X_("pianississimo"))));
197 velocity_ppp_button.add (*w);
198 w = manage (new Image (::get_icon (X_("pianissimo"))));
200 velocity_pp_button.add (*w);
201 w = manage (new Image (::get_icon (X_("piano"))));
203 velocity_p_button.add (*w);
204 w = manage (new Image (::get_icon (X_("mezzopiano"))));
206 velocity_mp_button.add (*w);
207 w = manage (new Image (::get_icon (X_("mezzoforte"))));
209 velocity_mf_button.add (*w);
210 w = manage (new Image (::get_icon (X_("forte"))));
212 velocity_f_button.add (*w);
213 w = manage (new Image (::get_icon (X_("fortissimo"))));
215 velocity_ff_button.add (*w);
216 w = manage (new Image (::get_icon (X_("fortississimo"))));
218 velocity_fff_button.add (*w);
220 act = myactions.find_action ("StepEditing/note-velocity-ppp");
221 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
222 act = myactions.find_action ("StepEditing/note-velocity-pp");
223 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
224 act = myactions.find_action ("StepEditing/note-velocity-p");
225 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
226 act = myactions.find_action ("StepEditing/note-velocity-mp");
227 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
228 act = myactions.find_action ("StepEditing/note-velocity-mf");
229 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
230 act = myactions.find_action ("StepEditing/note-velocity-f");
231 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
232 act = myactions.find_action ("StepEditing/note-velocity-ff");
233 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
234 act = myactions.find_action ("StepEditing/note-velocity-fff");
235 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
237 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
238 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
239 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
240 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
241 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
242 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
243 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
244 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
245 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
246 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
247 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
248 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
249 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
250 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
251 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
252 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
254 velocity_ppp_button.property_draw_indicator() = false;
255 velocity_pp_button.property_draw_indicator() = false;
256 velocity_p_button.property_draw_indicator() = false;
257 velocity_mp_button.property_draw_indicator() = false;
258 velocity_mf_button.property_draw_indicator() = false;
259 velocity_f_button.property_draw_indicator() = false;
260 velocity_ff_button.property_draw_indicator() = false;
261 velocity_fff_button.property_draw_indicator() = false;
263 ARDOUR_UI::instance()->set_tip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
264 ARDOUR_UI::instance()->set_tip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
265 ARDOUR_UI::instance()->set_tip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
266 ARDOUR_UI::instance()->set_tip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
267 ARDOUR_UI::instance()->set_tip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
268 ARDOUR_UI::instance()->set_tip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
269 ARDOUR_UI::instance()->set_tip (&velocity_ff_button, _("Set volume (velocity) to forteissimo"), "");
270 ARDOUR_UI::instance()->set_tip (&velocity_fff_button, _("Set volume (velocity) to forteississimo"), "");
272 note_velocity_box.pack_start (velocity_ppp_button, false, false);
273 note_velocity_box.pack_start (velocity_pp_button, false, false);
274 note_velocity_box.pack_start (velocity_p_button, false, false);
275 note_velocity_box.pack_start (velocity_mp_button, false, false);
276 note_velocity_box.pack_start (velocity_mf_button, false, false);
277 note_velocity_box.pack_start (velocity_f_button, false, false);
278 note_velocity_box.pack_start (velocity_ff_button, false, false);
279 note_velocity_box.pack_start (velocity_fff_button, false, false);
281 Label* l = manage (new Label);
282 l->set_markup ("<b><big>.</big></b>");
286 w = manage (new Image (::get_icon (X_("chord"))));
288 chord_button.add (*w);
290 rest_box.pack_start (rest_button, false, false);
291 rest_box.pack_start (grid_rest_button, false, false);
293 resync_box.pack_start (beat_resync_button, false, false);
294 resync_box.pack_start (bar_resync_button, false, false);
296 ARDOUR_UI::instance()->set_tip (&chord_button, _("Stack inserted notes to form a chord"), "");
297 ARDOUR_UI::instance()->set_tip (&sustain_button, _("Extend selected notes by note length"), "");
298 ARDOUR_UI::instance()->set_tip (&dot_button, _("Use dotted note lengths"), "");
299 ARDOUR_UI::instance()->set_tip (&rest_button, _("Insert a note-length's rest"), "");
300 ARDOUR_UI::instance()->set_tip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
301 ARDOUR_UI::instance()->set_tip (&beat_resync_button, _("Insert a rest until the next beat"), "");
302 ARDOUR_UI::instance()->set_tip (&bar_resync_button, _("Insert a rest until the next bar"), "");
304 upper_box.set_spacing (6);
305 upper_box.pack_start (chord_button, false, false);
306 upper_box.pack_start (note_length_box, false, false, 12);
307 upper_box.pack_start (triplet_button, false, false);
308 upper_box.pack_start (dot_button, false, false);
309 upper_box.pack_start (sustain_button, false, false);
310 upper_box.pack_start (rest_box, false, false);
311 upper_box.pack_start (resync_box, false, false);
312 upper_box.pack_start (note_velocity_box, false, false, 12);
314 VBox* v = manage (new VBox);
315 l = manage (new Label (_("Channel")));
317 v->pack_start (*l, false, false);
318 v->pack_start (channel_spinner, false, false);
319 upper_box.pack_start (*v, false, false);
321 upper_box.pack_start (length_divisor_spinner, false, false);
322 upper_box.pack_start (velocity_spinner, false, false);
323 upper_box.pack_start (octave_spinner, false, false);
325 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
326 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
328 _piano = (PianoKeyboard*) piano_keyboard_new ();
329 piano = wrap ((GtkWidget*) _piano);
331 piano->set_flags (Gtk::CAN_FOCUS);
333 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
334 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
336 rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::rest_click));
337 grid_rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::grid_rest_click));
338 chord_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::chord_toggled));
339 triplet_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::triplet_toggled));
340 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
341 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
343 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
345 packer.set_spacing (6);
346 packer.pack_start (upper_box, false, false);
347 packer.pack_start (*piano, false, false);
350 get_vbox()->add (packer);
353 StepEntry::~StepEntry()
358 StepEntry::length_changed ()
360 length_1_button.queue_draw ();
361 length_2_button.queue_draw ();
362 length_4_button.queue_draw ();
363 length_8_button.queue_draw ();
364 length_16_button.queue_draw ();
365 length_32_button.queue_draw ();
366 length_64_button.queue_draw ();
370 StepEntry::on_key_press_event (GdkEventKey* ev)
372 /* focus widget gets first shot, then bindings, otherwise
373 forward to main window
376 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
377 KeyboardKey k (ev->state, ev->keyval);
379 if (bindings.activate (k, KeyboardKey::Press)) {
384 return forward_key_press (ev);
388 StepEntry::on_key_release_event (GdkEventKey* ev)
390 /* focus widget gets first shot, then bindings, otherwise
391 forward to main window
394 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
395 KeyboardKey k (ev->state, ev->keyval);
397 if (bindings.activate (k, KeyboardKey::Release)) {
402 return forward_key_press (ev);
406 StepEntry::rest_event_handler ()
408 _mtv->step_edit_rest (0.0);
412 StepEntry::note_length () const
414 return 1.0 / (Evoral::MusicalTime) length_divisor_adjustment.get_value();
418 StepEntry::note_velocity () const
420 return (Evoral::MusicalTime) velocity_adjustment.get_value();
424 StepEntry::note_channel() const
426 return channel_adjustment.get_value() - 1;
430 StepEntry::note_off_event_handler (int note)
436 StepEntry::rest_click ()
442 StepEntry::grid_rest_click ()
448 StepEntry::triplet_toggled ()
450 if (triplet_button.get_active () != _mtv->step_edit_within_triplet()) {
451 _mtv->step_edit_toggle_triplet ();
456 StepEntry::chord_toggled ()
458 if (chord_button.get_active() != _mtv->step_edit_within_chord ()) {
459 _mtv->step_edit_toggle_chord ();
464 StepEntry::on_show ()
466 ArdourDialog::on_show ();
467 piano->grab_focus ();
471 StepEntry::beat_resync_click ()
473 _mtv->step_edit_beat_sync ();
477 StepEntry::bar_resync_click ()
479 _mtv->step_edit_bar_sync ();
483 StepEntry::register_actions ()
485 /* add named actions for the editor */
487 myactions.register_action ("StepEditing", "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
488 myactions.register_action ("StepEditing", "insert-bsharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
489 myactions.register_action ("StepEditing", "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
490 myactions.register_action ("StepEditing", "insert-bsharp", _("Insert Note B-sharp"), sigc::mem_fun (*this, &StepEntry::insert_bsharp));
491 myactions.register_action ("StepEditing", "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
492 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
493 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
494 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
495 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
496 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
497 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
498 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
499 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
501 RadioAction::Group note_length_group;
503 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
504 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
505 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
506 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
507 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
508 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
509 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
510 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
511 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
512 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
513 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
514 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
515 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
516 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
518 RadioAction::Group note_velocity_group;
520 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
521 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
522 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
523 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
524 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
525 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
526 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
527 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
528 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
529 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
530 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
531 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
532 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
533 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
534 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
535 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
539 StepEntry::load_bindings ()
541 bindings.set_action_map (myactions);
543 sys::path binding_file;
544 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
546 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
547 bindings.load (binding_file.to_string());
552 StepEntry::insert_rest ()
554 _mtv->step_edit_rest (note_length());
558 StepEntry::insert_grid_rest ()
560 _mtv->step_edit_rest (0.0);
564 StepEntry::insert_note (uint8_t note)
566 _mtv->step_add_note (note_channel(), note, note_velocity(), note_length());
569 StepEntry::insert_c ()
571 insert_note (0 + (current_octave() * 12));
574 StepEntry::insert_csharp ()
576 insert_note (1 + (current_octave() * 12));
579 StepEntry::insert_d ()
581 insert_note (2 + (current_octave() * 12));
584 StepEntry::insert_dsharp ()
586 insert_note (3 + (current_octave() * 12));
589 StepEntry::insert_e ()
591 insert_note (4 + (current_octave() * 12));
594 StepEntry::insert_f ()
596 insert_note (5 + (current_octave() * 12));
599 StepEntry::insert_fsharp ()
601 insert_note (6 + (current_octave() * 12));
604 StepEntry::insert_g ()
606 insert_note (7 + (current_octave() * 12));
609 StepEntry::insert_gsharp ()
611 insert_note (8 + (current_octave() * 12));
615 StepEntry::insert_a ()
617 insert_note (9 + (current_octave() * 12));
621 StepEntry::insert_asharp ()
623 insert_note (10 + (current_octave() * 12));
626 StepEntry::insert_b ()
628 insert_note (11 + (current_octave() * 12));
632 StepEntry::insert_bsharp ()
634 insert_note (12 + (current_octave() * 12));
638 StepEntry::note_length_change (GtkAction* act)
640 /* it doesn't matter which note length action we look up - we are interested
641 in the current_value which is global across the whole group of note length
642 actions. this method is called twice for every user operation,
643 once for the action that became "inactive" and once for the action that
644 becaome "active". so ... only bother to actually change the value when this
645 is called for the "active" action.
648 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
649 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
650 length_divisor_adjustment.set_value (v);
655 StepEntry::note_velocity_change (GtkAction* act)
657 /* it doesn't matter which note length action we look up - we are interested
658 in the current_value which is global across the whole group of note length
659 actions. this method is called twice for every user operation,
660 once for the action that became "inactive" and once for the action that
661 becaome "active". so ... only bother to actually change the value when this
662 is called for the "active" action.
665 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
666 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
667 cerr << "Velocity reset to " << v << endl;
668 velocity_adjustment.set_value (v);
673 StepEntry::velocity_value_change ()
676 RefPtr<RadioAction> ract;
677 double val = velocity_adjustment.get_value();
678 bool inconsistent = true;
679 vector<const char*> velocity_actions;
681 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
682 velocity_actions.push_back ("StepEditing/note-velocity-pp");
683 velocity_actions.push_back ("StepEditing/note-velocity-p");
684 velocity_actions.push_back ("StepEditing/note-velocity-mp");
685 velocity_actions.push_back ("StepEditing/note-velocity-mf");
686 velocity_actions.push_back ("StepEditing/note-velocity-f");
687 velocity_actions.push_back ("StepEditing/note-velocity-ff");
688 velocity_actions.push_back ("StepEditing/note-velocity-fff");
690 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
692 act = myactions.find_action (*i);
695 ract = RefPtr<RadioAction>::cast_dynamic (act);
698 if (ract->property_value() == val) {
699 ract->set_active (true);
700 inconsistent = false;
707 velocity_ppp_button.set_inconsistent (inconsistent);
708 velocity_pp_button.set_inconsistent (inconsistent);
709 velocity_p_button.set_inconsistent (inconsistent);
710 velocity_mp_button.set_inconsistent (inconsistent);
711 velocity_mf_button.set_inconsistent (inconsistent);
712 velocity_f_button.set_inconsistent (inconsistent);
713 velocity_ff_button.set_inconsistent (inconsistent);
714 velocity_fff_button.set_inconsistent (inconsistent);
718 StepEntry::length_value_change ()
721 RefPtr<RadioAction> ract;
722 double val = length_divisor_adjustment.get_value();
723 bool inconsistent = true;
724 vector<const char*> length_actions;
726 length_actions.push_back ("StepEditing/note-length-whole");
727 length_actions.push_back ("StepEditing/note-length-half");
728 length_actions.push_back ("StepEditing/note-length-quarter");
729 length_actions.push_back ("StepEditing/note-length-eighth");
730 length_actions.push_back ("StepEditing/note-length-sixteenth");
731 length_actions.push_back ("StepEditing/note-length-thirtysecond");
732 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
734 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
736 act = myactions.find_action (*i);
739 ract = RefPtr<RadioAction>::cast_dynamic (act);
742 if (ract->property_value() == val) {
743 ract->set_active (true);
744 inconsistent = false;
751 length_1_button.set_inconsistent (inconsistent);
752 length_2_button.set_inconsistent (inconsistent);
753 length_4_button.set_inconsistent (inconsistent);
754 length_8_button.set_inconsistent (inconsistent);
755 length_16_button.set_inconsistent (inconsistent);
756 length_32_button.set_inconsistent (inconsistent);
757 length_64_button.set_inconsistent (inconsistent);
761 StepEntry::radio_button_press (GdkEventButton* ev)
763 if (ev->button == 1) {
771 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
773 if (ev->button == 1) {
774 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
777 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);