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-asharp", _("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-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
491 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
492 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
493 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
494 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
495 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
496 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
497 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
498 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
500 RadioAction::Group note_length_group;
502 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
503 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
504 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
505 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
506 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
507 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
508 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
509 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
510 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
511 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
512 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
513 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
514 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
515 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
517 RadioAction::Group note_velocity_group;
519 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
520 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
521 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
522 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
523 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
524 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
525 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
526 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
527 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
528 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
529 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
530 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
531 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
532 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
533 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
534 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
538 StepEntry::load_bindings ()
540 bindings.set_action_map (myactions);
542 sys::path binding_file;
543 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
545 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
546 bindings.load (binding_file.to_string());
551 StepEntry::insert_rest ()
553 _mtv->step_edit_rest (note_length());
557 StepEntry::insert_grid_rest ()
559 _mtv->step_edit_rest (0.0);
563 StepEntry::insert_note (uint8_t note)
565 _mtv->step_add_note (note_channel(), note, note_velocity(), note_length());
568 StepEntry::insert_c ()
570 insert_note (0 + (current_octave() * 12));
573 StepEntry::insert_csharp ()
575 insert_note (1 + (current_octave() * 12));
578 StepEntry::insert_d ()
580 insert_note (2 + (current_octave() * 12));
583 StepEntry::insert_dsharp ()
585 insert_note (3 + (current_octave() * 12));
588 StepEntry::insert_e ()
590 insert_note (4 + (current_octave() * 12));
593 StepEntry::insert_f ()
595 insert_note (5 + (current_octave() * 12));
598 StepEntry::insert_fsharp ()
600 insert_note (6 + (current_octave() * 12));
603 StepEntry::insert_g ()
605 insert_note (7 + (current_octave() * 12));
608 StepEntry::insert_gsharp ()
610 insert_note (8 + (current_octave() * 12));
614 StepEntry::insert_a ()
616 insert_note (9 + (current_octave() * 12));
620 StepEntry::insert_asharp ()
622 insert_note (10 + (current_octave() * 12));
625 StepEntry::insert_b ()
627 insert_note (11 + (current_octave() * 12));
631 StepEntry::note_length_change (GtkAction* act)
633 /* it doesn't matter which note length action we look up - we are interested
634 in the current_value which is global across the whole group of note length
635 actions. this method is called twice for every user operation,
636 once for the action that became "inactive" and once for the action that
637 becaome "active". so ... only bother to actually change the value when this
638 is called for the "active" action.
641 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
642 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
643 length_divisor_adjustment.set_value (v);
648 StepEntry::note_velocity_change (GtkAction* act)
650 /* it doesn't matter which note length action we look up - we are interested
651 in the current_value which is global across the whole group of note length
652 actions. this method is called twice for every user operation,
653 once for the action that became "inactive" and once for the action that
654 becaome "active". so ... only bother to actually change the value when this
655 is called for the "active" action.
658 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
659 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
660 cerr << "Velocity reset to " << v << endl;
661 velocity_adjustment.set_value (v);
666 StepEntry::velocity_value_change ()
669 RefPtr<RadioAction> ract;
670 double val = velocity_adjustment.get_value();
671 bool inconsistent = true;
672 vector<const char*> velocity_actions;
674 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
675 velocity_actions.push_back ("StepEditing/note-velocity-pp");
676 velocity_actions.push_back ("StepEditing/note-velocity-p");
677 velocity_actions.push_back ("StepEditing/note-velocity-mp");
678 velocity_actions.push_back ("StepEditing/note-velocity-mf");
679 velocity_actions.push_back ("StepEditing/note-velocity-f");
680 velocity_actions.push_back ("StepEditing/note-velocity-ff");
681 velocity_actions.push_back ("StepEditing/note-velocity-fff");
683 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
685 act = myactions.find_action (*i);
688 ract = RefPtr<RadioAction>::cast_dynamic (act);
691 if (ract->property_value() == val) {
692 ract->set_active (true);
693 inconsistent = false;
700 velocity_ppp_button.set_inconsistent (inconsistent);
701 velocity_pp_button.set_inconsistent (inconsistent);
702 velocity_p_button.set_inconsistent (inconsistent);
703 velocity_mp_button.set_inconsistent (inconsistent);
704 velocity_mf_button.set_inconsistent (inconsistent);
705 velocity_f_button.set_inconsistent (inconsistent);
706 velocity_ff_button.set_inconsistent (inconsistent);
707 velocity_fff_button.set_inconsistent (inconsistent);
711 StepEntry::length_value_change ()
714 RefPtr<RadioAction> ract;
715 double val = length_divisor_adjustment.get_value();
716 bool inconsistent = true;
717 vector<const char*> length_actions;
719 length_actions.push_back ("StepEditing/note-length-whole");
720 length_actions.push_back ("StepEditing/note-length-half");
721 length_actions.push_back ("StepEditing/note-length-quarter");
722 length_actions.push_back ("StepEditing/note-length-eighth");
723 length_actions.push_back ("StepEditing/note-length-sixteenth");
724 length_actions.push_back ("StepEditing/note-length-thirtysecond");
725 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
727 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
729 act = myactions.find_action (*i);
732 ract = RefPtr<RadioAction>::cast_dynamic (act);
735 if (ract->property_value() == val) {
736 ract->set_active (true);
737 inconsistent = false;
744 length_1_button.set_inconsistent (inconsistent);
745 length_2_button.set_inconsistent (inconsistent);
746 length_4_button.set_inconsistent (inconsistent);
747 length_8_button.set_inconsistent (inconsistent);
748 length_16_button.set_inconsistent (inconsistent);
749 length_32_button.set_inconsistent (inconsistent);
750 length_64_button.set_inconsistent (inconsistent);
754 StepEntry::radio_button_press (GdkEventButton* ev)
756 if (ev->button == 1) {
764 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
766 if (ev->button == 1) {
767 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
770 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);