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/file_utils.h"
24 #include "gtkmm2ext/actions.h"
25 #include "gtkmm2ext/keyboard.h"
27 #include "widgets/tooltips.h"
29 #include "ardour/filesystem_paths.h"
31 #include "midi_channel_selector.h"
32 #include "midi_time_axis.h"
33 #include "step_editor.h"
34 #include "step_entry.h"
42 using namespace Gtkmm2ext;
44 using namespace ARDOUR;
45 using namespace ARDOUR_UI_UTILS;
46 using namespace ArdourWidgets;
48 Gtkmm2ext::Bindings* StepEntry::bindings = 0;
49 StepEntry* StepEntry::_current_step_entry = 0;
52 _note_off_event_handler (GtkWidget* /*widget*/, int note, gpointer arg)
54 ((StepEntry*)arg)->note_off_event_handler (note);
58 _rest_event_handler (GtkWidget* /*widget*/, gpointer arg)
60 ((StepEntry*)arg)->rest_event_handler ();
63 StepEntry::StepEntry (StepEditor& seditor)
64 : ArdourWindow (string_compose (_("Step Entry: %1"), seditor.name()))
65 , _current_note_length (1.0)
66 , _current_note_velocity (64)
67 , triplet_button ("3")
68 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
69 , beat_resync_button (_(">beat"))
70 , bar_resync_button (_(">bar"))
71 , resync_button (_(">EP"))
72 , sustain_button (_("sustain"))
73 , rest_button (_("rest"))
74 , grid_rest_button (_("g-rest"))
75 , back_button (_("back"))
76 , channel_adjustment (1, 1, 16, 1, 4)
77 , channel_spinner (channel_adjustment)
78 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
79 , octave_spinner (octave_adjustment)
80 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
81 , length_divisor_spinner (length_divisor_adjustment)
82 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
83 , velocity_spinner (velocity_adjustment)
84 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
85 , bank_spinner (bank_adjustment)
86 , bank_button (_("+"))
87 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
88 , program_spinner (program_adjustment)
89 , program_button (_("+"))
94 set_data ("ardour-bindings", bindings);
97 /* set channel selector to first selected channel. if none
98 are selected, it will remain at the value set in its
99 constructor, above (1)
102 uint16_t chn_mask = se->channel_selector().get_selected_channels();
104 for (uint32_t i = 0; i < 16; ++i) {
105 if (chn_mask & (1<<i)) {
106 channel_adjustment.set_value (i+1);
113 RadioButtonGroup length_group = length_1_button.get_group();
114 length_2_button.set_group (length_group);
115 length_4_button.set_group (length_group);
116 length_8_button.set_group (length_group);
117 length_12_button.set_group (length_group);
118 length_16_button.set_group (length_group);
119 length_32_button.set_group (length_group);
120 length_64_button.set_group (length_group);
124 w = manage (new Image (::get_icon (X_("wholenote"))));
126 length_1_button.add (*w);
127 w = manage (new Image (::get_icon (X_("halfnote"))));
129 length_2_button.add (*w);
130 w = manage (new Image (::get_icon (X_("quarternote"))));
132 length_4_button.add (*w);
133 w = manage (new Image (::get_icon (X_("eighthnote"))));
135 length_8_button.add (*w);
136 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
138 length_16_button.add (*w);
139 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
141 length_32_button.add (*w);
142 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
144 length_64_button.add (*w);
148 act = ActionManager::get_action ("StepEditing/note-length-whole");
149 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
150 act = ActionManager::get_action ("StepEditing/note-length-half");
151 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
152 act = ActionManager::get_action ("StepEditing/note-length-quarter");
153 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
154 act = ActionManager::get_action ("StepEditing/note-length-eighth");
155 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
156 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
157 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
158 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
159 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
160 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
161 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
163 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
164 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
165 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
166 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
167 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
168 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
169 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
170 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
171 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
172 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
173 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
174 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
175 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
176 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
178 length_1_button.property_draw_indicator() = false;
179 length_2_button.property_draw_indicator() = false;
180 length_4_button.property_draw_indicator() = false;
181 length_8_button.property_draw_indicator() = false;
182 length_16_button.property_draw_indicator() = false;
183 length_32_button.property_draw_indicator() = false;
184 length_64_button.property_draw_indicator() = false;
186 note_length_box.pack_start (length_1_button, false, false);
187 note_length_box.pack_start (length_2_button, false, false);
188 note_length_box.pack_start (length_4_button, false, false);
189 note_length_box.pack_start (length_8_button, false, false);
190 note_length_box.pack_start (length_16_button, false, false);
191 note_length_box.pack_start (length_32_button, false, false);
192 note_length_box.pack_start (length_64_button, false, false);
194 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
195 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
196 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
197 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
198 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
199 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
200 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
202 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
203 velocity_pp_button.set_group (velocity_group);
204 velocity_p_button.set_group (velocity_group);
205 velocity_mp_button.set_group (velocity_group);
206 velocity_mf_button.set_group (velocity_group);
207 velocity_f_button.set_group (velocity_group);
208 velocity_ff_button.set_group (velocity_group);
209 velocity_fff_button.set_group (velocity_group);
211 w = manage (new Image (::get_icon (X_("pianississimo"))));
213 velocity_ppp_button.add (*w);
214 w = manage (new Image (::get_icon (X_("pianissimo"))));
216 velocity_pp_button.add (*w);
217 w = manage (new Image (::get_icon (X_("piano"))));
219 velocity_p_button.add (*w);
220 w = manage (new Image (::get_icon (X_("mezzopiano"))));
222 velocity_mp_button.add (*w);
223 w = manage (new Image (::get_icon (X_("mezzoforte"))));
225 velocity_mf_button.add (*w);
226 w = manage (new Image (::get_icon (X_("forte"))));
228 velocity_f_button.add (*w);
229 w = manage (new Image (::get_icon (X_("fortissimo"))));
231 velocity_ff_button.add (*w);
232 w = manage (new Image (::get_icon (X_("fortississimo"))));
234 velocity_fff_button.add (*w);
236 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
237 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
238 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
239 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
240 act = ActionManager::get_action ("StepEditing/note-velocity-p");
241 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
242 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
243 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
244 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
245 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
246 act = ActionManager::get_action ("StepEditing/note-velocity-f");
247 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
248 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
249 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
250 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
251 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
253 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
254 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
255 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
256 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
257 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
258 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
259 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
260 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
261 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
262 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
263 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
264 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
265 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
266 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
267 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
268 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
270 velocity_ppp_button.property_draw_indicator() = false;
271 velocity_pp_button.property_draw_indicator() = false;
272 velocity_p_button.property_draw_indicator() = false;
273 velocity_mp_button.property_draw_indicator() = false;
274 velocity_mf_button.property_draw_indicator() = false;
275 velocity_f_button.property_draw_indicator() = false;
276 velocity_ff_button.property_draw_indicator() = false;
277 velocity_fff_button.property_draw_indicator() = false;
279 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
280 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
281 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
282 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
283 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
284 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
285 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
286 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
288 note_velocity_box.pack_start (velocity_ppp_button, false, false);
289 note_velocity_box.pack_start (velocity_pp_button, false, false);
290 note_velocity_box.pack_start (velocity_p_button, false, false);
291 note_velocity_box.pack_start (velocity_mp_button, false, false);
292 note_velocity_box.pack_start (velocity_mf_button, false, false);
293 note_velocity_box.pack_start (velocity_f_button, false, false);
294 note_velocity_box.pack_start (velocity_ff_button, false, false);
295 note_velocity_box.pack_start (velocity_fff_button, false, false);
297 Label* l = manage (new Label);
298 l->set_markup ("<b><big>-</big></b>");
300 dot0_button.add (*l);
302 l = manage (new Label);
303 l->set_markup ("<b><big>.</big></b>");
305 dot1_button.add (*l);
307 l = manage (new Label);
308 l->set_markup ("<b><big>..</big></b>");
310 dot2_button.add (*l);
312 l = manage (new Label);
313 l->set_markup ("<b><big>...</big></b>");
315 dot3_button.add (*l);
317 w = manage (new Image (::get_icon (X_("chord"))));
319 chord_button.add (*w);
321 dot_box1.pack_start (dot0_button, true, false);
322 dot_box1.pack_start (dot1_button, true, false);
323 dot_box2.pack_start (dot2_button, true, false);
324 dot_box2.pack_start (dot3_button, true, false);
326 rest_box.pack_start (rest_button, true, false);
327 rest_box.pack_start (grid_rest_button, true, false);
328 rest_box.pack_start (back_button, true, false);
330 resync_box.pack_start (beat_resync_button, true, false);
331 resync_box.pack_start (bar_resync_button, true, false);
332 resync_box.pack_start (resync_button, true, false);
334 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
335 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
336 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
337 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
338 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
339 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
340 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
341 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
342 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
343 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
344 set_tooltip (&bank_button, _("Insert a bank change message"), "");
345 set_tooltip (&program_button, _("Insert a program change message"), "");
346 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
347 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
349 act = ActionManager::get_action ("StepEditing/back");
350 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
351 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
352 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
353 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
354 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
355 act = ActionManager::get_action ("StepEditing/toggle-triplet");
356 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
357 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
358 act = ActionManager::get_action ("StepEditing/no-dotted");
359 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
360 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
361 act = ActionManager::get_action ("StepEditing/toggle-dotted");
362 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
363 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
364 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
365 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
366 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
367 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
368 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
369 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
370 act = ActionManager::get_action ("StepEditing/toggle-chord");
371 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
372 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
373 act = ActionManager::get_action ("StepEditing/insert-rest");
374 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
375 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
376 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
377 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
378 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
379 act = ActionManager::get_action ("StepEditing/sustain");
380 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
381 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
383 upper_box.set_spacing (6);
384 upper_box.pack_start (chord_button, false, false);
385 upper_box.pack_start (note_length_box, false, false, 12);
386 upper_box.pack_start (triplet_button, false, false);
387 upper_box.pack_start (dot_box1, false, false);
388 upper_box.pack_start (dot_box2, false, false);
389 upper_box.pack_start (sustain_button, false, false);
390 upper_box.pack_start (rest_box, false, false);
391 upper_box.pack_start (resync_box, false, false);
392 upper_box.pack_start (note_velocity_box, false, false, 12);
396 v = manage (new VBox);
397 l = manage (new Label (_("Channel")));
399 v->pack_start (*l, false, false);
400 v->pack_start (channel_spinner, false, false);
401 upper_box.pack_start (*v, false, false);
403 v = manage (new VBox);
404 l = manage (new Label (_("1/Note")));
406 v->pack_start (*l, false, false);
407 v->pack_start (length_divisor_spinner, false, false);
408 upper_box.pack_start (*v, false, false);
410 v = manage (new VBox);
411 l = manage (new Label (_("Velocity")));
413 v->pack_start (*l, false, false);
414 v->pack_start (velocity_spinner, false, false);
415 upper_box.pack_start (*v, false, false);
417 v = manage (new VBox);
418 l = manage (new Label (_("Octave")));
420 v->pack_start (*l, false, false);
421 v->pack_start (octave_spinner, false, false);
422 upper_box.pack_start (*v, false, false);
424 v = manage (new VBox);
425 l = manage (new Label (_("Bank")));
427 v->pack_start (*l, false, false);
428 v->pack_start (bank_spinner, false, false);
429 v->pack_start (bank_button, false, false);
430 upper_box.pack_start (*v, false, false);
432 v = manage (new VBox);
433 l = manage (new Label (_("Program")));
435 v->pack_start (*l, false, false);
436 v->pack_start (program_spinner, false, false);
437 v->pack_start (program_button, false, false);
438 upper_box.pack_start (*v, false, false);
440 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
441 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
442 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
444 _piano = (PianoKeyboard*) piano_keyboard_new ();
445 piano = wrap ((GtkWidget*) _piano);
447 piano->set_flags (Gtk::CAN_FOCUS);
449 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
450 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
452 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
453 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
454 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
455 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
457 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
459 packer.set_spacing (6);
460 packer.pack_start (upper_box, false, false);
461 packer.pack_start (*piano, false, false);
466 /* initial settings: quarter note and mezzo forte */
468 ActionManager::get_radio_action ("StepEditing/note-length-quarter")->set_active (true);
469 ActionManager::get_radio_action ("StepEditing/note-velocity-mf")->set_active (true);
472 StepEntry::~StepEntry()
477 StepEntry::length_changed ()
479 length_1_button.queue_draw ();
480 length_2_button.queue_draw ();
481 length_4_button.queue_draw ();
482 length_8_button.queue_draw ();
483 length_16_button.queue_draw ();
484 length_32_button.queue_draw ();
485 length_64_button.queue_draw ();
489 StepEntry::on_key_press_event (GdkEventKey* ev)
491 /* focus widget gets first shot, then bindings, otherwise
492 forward to main window
495 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
499 return relay_key_press (ev, this);
503 StepEntry::on_key_release_event (GdkEventKey* ev)
505 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
509 /* don't forward releases */
515 StepEntry::rest_event_handler ()
517 se->step_edit_rest (Temporal::Beats());
521 StepEntry::note_length ()
523 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
525 RefPtr<Action> act = ActionManager::get_action ("StepEditing/toggle-triplet");
526 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
527 bool triplets = tact->get_active ();
530 base_time *= (2.0/3.0);
533 double dots = dot_adjustment.get_value ();
536 dots = pow (2.0, dots);
537 base_time *= 1 + ((dots - 1.0)/dots);
540 return Temporal::Beats(base_time);
544 StepEntry::note_velocity () const
546 return velocity_adjustment.get_value();
550 StepEntry::note_channel() const
552 return channel_adjustment.get_value() - 1;
556 StepEntry::note_off_event_handler (int note)
563 StepEntry::on_show ()
565 ArdourWindow::on_show ();
566 //piano->grab_focus ();
570 StepEntry::beat_resync_click ()
572 se->step_edit_beat_sync ();
576 StepEntry::bar_resync_click ()
578 se->step_edit_bar_sync ();
582 StepEntry::register_actions ()
584 /* add named actions for the step editor */
586 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (bindings, X_("StepEditing"));
588 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::ptr_fun (&StepEntry::se_insert_a));
589 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::ptr_fun (&StepEntry::se_insert_asharp));
590 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::ptr_fun (&StepEntry::se_insert_b));
591 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::ptr_fun (&StepEntry::se_insert_c));
592 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::ptr_fun (&StepEntry::se_insert_csharp));
593 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::ptr_fun (&StepEntry::se_insert_d));
594 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::ptr_fun (&StepEntry::se_insert_dsharp));
595 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::ptr_fun (&StepEntry::se_insert_e));
596 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::ptr_fun (&StepEntry::se_insert_f));
597 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::ptr_fun (&StepEntry::se_insert_fsharp));
598 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::ptr_fun (&StepEntry::se_insert_g));
599 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::ptr_fun (&StepEntry::se_insert_gsharp));
601 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_rest));
602 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_grid_rest));
604 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_next_octave));
605 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_prev_octave));
607 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::ptr_fun (&StepEntry::se_next_note_length));
608 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::ptr_fun (&StepEntry::se_prev_note_length));
610 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::ptr_fun (&StepEntry::se_inc_note_length));
611 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::ptr_fun (&StepEntry::se_dec_note_length));
613 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::ptr_fun (&StepEntry::se_next_note_velocity));
614 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::ptr_fun (&StepEntry::se_prev_note_velocity));
616 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::ptr_fun (&StepEntry::se_inc_note_velocity));
617 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::ptr_fun (&StepEntry::se_dec_note_velocity));
619 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::ptr_fun (&StepEntry::se_octave_0));
620 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::ptr_fun (&StepEntry::se_octave_1));
621 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::ptr_fun (&StepEntry::se_octave_2));
622 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::ptr_fun (&StepEntry::se_octave_3));
623 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::ptr_fun (&StepEntry::se_octave_4));
624 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::ptr_fun (&StepEntry::se_octave_5));
625 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::ptr_fun (&StepEntry::se_octave_6));
626 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::ptr_fun (&StepEntry::se_octave_7));
627 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::ptr_fun (&StepEntry::se_octave_8));
628 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::ptr_fun (&StepEntry::se_octave_9));
629 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::ptr_fun (&StepEntry::se_octave_10));
631 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"), sigc::ptr_fun (&StepEntry::se_toggle_triplet));
633 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"), sigc::ptr_fun (&StepEntry::se_toggle_chord));
634 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"), sigc::ptr_fun (&StepEntry::se_do_sustain));
636 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"), sigc::ptr_fun (&StepEntry::se_sync_to_edit_point));
637 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"), sigc::ptr_fun (&StepEntry::se_back));
639 RadioAction::Group note_length_group;
641 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
642 _("Set Note Length to Whole"), sigc::ptr_fun (&StepEntry::se_note_length_change), 1);
643 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
644 _("Set Note Length to 1/2"), sigc::ptr_fun (&StepEntry::se_note_length_change), 2);
645 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
646 _("Set Note Length to 1/3"), sigc::ptr_fun (&StepEntry::se_note_length_change), 3);
647 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
648 _("Set Note Length to 1/4"), sigc::ptr_fun (&StepEntry::se_note_length_change), 4);
649 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
650 _("Set Note Length to 1/8"), sigc::ptr_fun (&StepEntry::se_note_length_change), 8);
651 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
652 _("Set Note Length to 1/16"), sigc::ptr_fun (&StepEntry::se_note_length_change), 16);
653 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
654 _("Set Note Length to 1/32"), sigc::ptr_fun (&StepEntry::se_note_length_change), 32);
655 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
656 _("Set Note Length to 1/64"), sigc::ptr_fun (&StepEntry::se_note_length_change), 64);
658 RadioAction::Group note_velocity_group;
660 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
661 _("Set Note Velocity to Pianississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 1);
662 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
663 _("Set Note Velocity to Pianissimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 16);
664 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
665 _("Set Note Velocity to Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 32);
666 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
667 _("Set Note Velocity to Mezzo-Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 64);
668 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
669 _("Set Note Velocity to Mezzo-Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 80);
670 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
671 _("Set Note Velocity to Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 96);
672 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
673 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 112);
674 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
675 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 127);
678 RadioAction::Group dot_group;
680 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 0);
681 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 1);
682 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 2);
683 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 3);
687 StepEntry::setup_actions_and_bindings ()
694 StepEntry::load_bindings ()
696 bindings = Bindings::get_bindings (X_("Step Editing"));
700 StepEntry::toggle_triplet ()
702 se->set_step_edit_cursor_width (note_length());
706 StepEntry::toggle_chord ()
708 se->step_edit_toggle_chord ();
712 StepEntry::dot_change (GtkAction* act)
714 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
715 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
716 dot_adjustment.set_value (v);
721 StepEntry::dot_value_change ()
724 RefPtr<RadioAction> ract;
725 double val = dot_adjustment.get_value();
726 bool inconsistent = true;
727 vector<const char*> dot_actions;
729 dot_actions.push_back ("StepEditing/no-dotted");
730 dot_actions.push_back ("StepEditing/toggle-dotted");
731 dot_actions.push_back ("StepEditing/toggle-double-dotted");
732 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
734 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
736 act = ActionManager::get_action (*i);
739 ract = RefPtr<RadioAction>::cast_dynamic (act);
742 if (ract->property_value() == val) {
743 ract->set_active (true);
744 inconsistent = false;
751 dot1_button.set_inconsistent (inconsistent);
752 dot2_button.set_inconsistent (inconsistent);
753 dot3_button.set_inconsistent (inconsistent);
755 se->set_step_edit_cursor_width (note_length());
759 StepEntry::program_click ()
761 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
765 StepEntry::bank_click ()
767 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
771 StepEntry::insert_rest ()
773 se->step_edit_rest (note_length());
777 StepEntry::insert_grid_rest ()
779 se->step_edit_rest (Temporal::Beats());
783 StepEntry::insert_note (uint8_t note)
789 se->step_add_note (note_channel(), note, note_velocity(), note_length());
792 StepEntry::insert_c ()
794 insert_note (0 + (current_octave() * 12));
797 StepEntry::insert_csharp ()
799 insert_note (1 + (current_octave() * 12));
802 StepEntry::insert_d ()
804 insert_note (2 + (current_octave() * 12));
807 StepEntry::insert_dsharp ()
809 insert_note (3 + (current_octave() * 12));
812 StepEntry::insert_e ()
814 insert_note (4 + (current_octave() * 12));
817 StepEntry::insert_f ()
819 insert_note (5 + (current_octave() * 12));
822 StepEntry::insert_fsharp ()
824 insert_note (6 + (current_octave() * 12));
827 StepEntry::insert_g ()
829 insert_note (7 + (current_octave() * 12));
832 StepEntry::insert_gsharp ()
834 insert_note (8 + (current_octave() * 12));
838 StepEntry::insert_a ()
840 insert_note (9 + (current_octave() * 12));
844 StepEntry::insert_asharp ()
846 insert_note (10 + (current_octave() * 12));
849 StepEntry::insert_b ()
851 insert_note (11 + (current_octave() * 12));
855 StepEntry::note_length_change (GtkAction* act)
857 /* it doesn't matter which note length action we look up - we are interested
858 in the current_value which is global across the whole group of note length
859 actions. this method is called twice for every user operation,
860 once for the action that became "inactive" and once for the action that
861 becaome "active". so ... only bother to actually change the value when this
862 is called for the "active" action.
865 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
866 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
867 length_divisor_adjustment.set_value (v);
872 StepEntry::note_velocity_change (GtkAction* act)
874 /* it doesn't matter which note velocity action we look up - we are interested
875 in the current_value which is global across the whole group of note velocity
876 actions. this method is called twice for every user operation,
877 once for the action that became "inactive" and once for the action that
878 becaome "active". so ... only bother to actually change the value when this
879 is called for the "active" action.
882 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
883 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
884 velocity_adjustment.set_value (v);
889 StepEntry::velocity_value_change ()
892 RefPtr<RadioAction> ract;
893 double val = velocity_adjustment.get_value();
894 bool inconsistent = true;
895 vector<const char*> velocity_actions;
897 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
898 velocity_actions.push_back ("StepEditing/note-velocity-pp");
899 velocity_actions.push_back ("StepEditing/note-velocity-p");
900 velocity_actions.push_back ("StepEditing/note-velocity-mp");
901 velocity_actions.push_back ("StepEditing/note-velocity-mf");
902 velocity_actions.push_back ("StepEditing/note-velocity-f");
903 velocity_actions.push_back ("StepEditing/note-velocity-ff");
904 velocity_actions.push_back ("StepEditing/note-velocity-fff");
906 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
908 act = ActionManager::get_action (*i);
911 ract = RefPtr<RadioAction>::cast_dynamic (act);
914 if (ract->property_value() == val) {
915 ract->set_active (true);
916 inconsistent = false;
923 velocity_ppp_button.set_inconsistent (inconsistent);
924 velocity_pp_button.set_inconsistent (inconsistent);
925 velocity_p_button.set_inconsistent (inconsistent);
926 velocity_mp_button.set_inconsistent (inconsistent);
927 velocity_mf_button.set_inconsistent (inconsistent);
928 velocity_f_button.set_inconsistent (inconsistent);
929 velocity_ff_button.set_inconsistent (inconsistent);
930 velocity_fff_button.set_inconsistent (inconsistent);
934 StepEntry::length_value_change ()
937 RefPtr<RadioAction> ract;
938 double val = length_divisor_adjustment.get_value();
939 bool inconsistent = true;
940 vector<const char*> length_actions;
942 length_actions.push_back ("StepEditing/note-length-whole");
943 length_actions.push_back ("StepEditing/note-length-half");
944 length_actions.push_back ("StepEditing/note-length-quarter");
945 length_actions.push_back ("StepEditing/note-length-eighth");
946 length_actions.push_back ("StepEditing/note-length-sixteenth");
947 length_actions.push_back ("StepEditing/note-length-thirtysecond");
948 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
950 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
952 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
954 ract->set_active (true);
955 inconsistent = false;
959 length_1_button.set_inconsistent (inconsistent);
960 length_2_button.set_inconsistent (inconsistent);
961 length_4_button.set_inconsistent (inconsistent);
962 length_8_button.set_inconsistent (inconsistent);
963 length_16_button.set_inconsistent (inconsistent);
964 length_32_button.set_inconsistent (inconsistent);
965 length_64_button.set_inconsistent (inconsistent);
967 se->set_step_edit_cursor_width (note_length());
971 StepEntry::radio_button_press (GdkEventButton* ev)
973 if (ev->button == 1) {
981 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
983 if (ev->button == 1) {
984 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
987 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
997 StepEntry::next_octave ()
999 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1003 StepEntry::prev_octave ()
1005 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1009 StepEntry::inc_note_length ()
1011 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1015 StepEntry::dec_note_length ()
1017 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1021 StepEntry::prev_note_length ()
1023 double l = length_divisor_adjustment.get_value();
1024 int il = (int) lrintf (l); // round to nearest integer
1025 il = (il/2) * 2; // round to power of 2
1033 length_divisor_adjustment.set_value (il);
1037 StepEntry::next_note_length ()
1039 double l = length_divisor_adjustment.get_value();
1040 int il = (int) lrintf (l); // round to nearest integer
1041 il = (il/2) * 2; // round to power of 2
1050 length_divisor_adjustment.set_value (il);
1055 StepEntry::inc_note_velocity ()
1057 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1061 StepEntry::dec_note_velocity ()
1063 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1067 StepEntry::next_note_velocity ()
1069 double l = velocity_adjustment.get_value ();
1073 } else if (l < 32) {
1075 } else if (l < 48) {
1077 } else if (l < 64) {
1079 } else if (l < 80) {
1081 } else if (l < 96) {
1083 } else if (l < 112) {
1085 } else if (l < 127) {
1089 velocity_adjustment.set_value (l);
1093 StepEntry::prev_note_velocity ()
1095 double l = velocity_adjustment.get_value ();
1099 } else if (l > 96) {
1101 } else if (l > 80) {
1103 } else if (l > 64) {
1105 } else if (l > 48) {
1107 } else if (l > 32) {
1109 } else if (l > 16) {
1115 velocity_adjustment.set_value (l);
1119 StepEntry::octave_n (int n)
1121 octave_adjustment.set_value (n);
1125 StepEntry::do_sustain ()
1127 se->step_edit_sustain (note_length());
1133 se->move_step_edit_beat_pos (-note_length());
1137 StepEntry::sync_to_edit_point ()
1139 se->resync_step_edit_to_edit_point ();
1143 StepEntry::on_focus_in_event (GdkEventFocus* ev)
1145 _current_step_entry = this;
1146 return ArdourWindow::on_focus_in_event (ev);
1150 StepEntry::on_focus_out_event (GdkEventFocus* ev)
1152 _current_step_entry = 0;
1153 return ArdourWindow::on_focus_out_event (ev);