2 * Copyright (C) 2010-2015 David Robillard <d@drobilla.net>
3 * Copyright (C) 2010-2018 Paul Davis <paul@linuxaudiosystems.com>
4 * Copyright (C) 2012-2015 Tim Mayberry <mojofunk@gmail.com>
5 * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "pbd/file_utils.h"
26 #include "gtkmm2ext/actions.h"
27 #include "gtkmm2ext/keyboard.h"
29 #include "widgets/tooltips.h"
31 #include "ardour/filesystem_paths.h"
33 #include "midi_channel_selector.h"
34 #include "midi_time_axis.h"
35 #include "step_editor.h"
36 #include "step_entry.h"
44 using namespace Gtkmm2ext;
46 using namespace ARDOUR;
47 using namespace ARDOUR_UI_UTILS;
48 using namespace ArdourWidgets;
50 Gtkmm2ext::Bindings* StepEntry::bindings = 0;
51 StepEntry* StepEntry::_instance = 0;
54 _note_off_event_handler (GtkWidget* /*widget*/, int note, gpointer arg)
56 ((StepEntry*)arg)->note_off_event_handler (note);
60 _rest_event_handler (GtkWidget* /*widget*/, gpointer arg)
62 ((StepEntry*)arg)->rest_event_handler ();
69 _instance = new StepEntry;
75 StepEntry::StepEntry ()
76 : ArdourWindow (string())
77 , _current_note_length (1.0)
78 , _current_note_velocity (64)
79 , triplet_button ("3")
80 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
81 , beat_resync_button (_(">beat"))
82 , bar_resync_button (_(">bar"))
83 , resync_button (_(">EP"))
84 , sustain_button (_("sustain"))
85 , rest_button (_("rest"))
86 , grid_rest_button (_("g-rest"))
87 , back_button (_("back"))
88 , channel_adjustment (1, 1, 16, 1, 4)
89 , channel_spinner (channel_adjustment)
90 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
91 , octave_spinner (octave_adjustment)
92 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
93 , length_divisor_spinner (length_divisor_adjustment)
94 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
95 , velocity_spinner (velocity_adjustment)
96 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
97 , bank_spinner (bank_adjustment)
98 , bank_button (_("+"))
99 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
100 , program_spinner (program_adjustment)
101 , program_button (_("+"))
106 set_data ("ardour-bindings", bindings);
108 RadioButtonGroup length_group = length_1_button.get_group();
109 length_2_button.set_group (length_group);
110 length_4_button.set_group (length_group);
111 length_8_button.set_group (length_group);
112 length_12_button.set_group (length_group);
113 length_16_button.set_group (length_group);
114 length_32_button.set_group (length_group);
115 length_64_button.set_group (length_group);
119 w = manage (new Image (::get_icon (X_("wholenote"))));
121 length_1_button.add (*w);
122 w = manage (new Image (::get_icon (X_("halfnote"))));
124 length_2_button.add (*w);
125 w = manage (new Image (::get_icon (X_("quarternote"))));
127 length_4_button.add (*w);
128 w = manage (new Image (::get_icon (X_("eighthnote"))));
130 length_8_button.add (*w);
131 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
133 length_16_button.add (*w);
134 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
136 length_32_button.add (*w);
137 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
139 length_64_button.add (*w);
143 act = ActionManager::get_action ("StepEditing/note-length-whole");
144 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
145 act = ActionManager::get_action ("StepEditing/note-length-half");
146 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
147 act = ActionManager::get_action ("StepEditing/note-length-quarter");
148 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
149 act = ActionManager::get_action ("StepEditing/note-length-eighth");
150 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
151 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
152 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
153 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
154 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
155 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
156 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
158 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
159 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
160 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
161 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
162 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
163 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
164 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
165 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
166 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
167 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
168 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
169 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
170 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
171 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
173 length_1_button.property_draw_indicator() = false;
174 length_2_button.property_draw_indicator() = false;
175 length_4_button.property_draw_indicator() = false;
176 length_8_button.property_draw_indicator() = false;
177 length_16_button.property_draw_indicator() = false;
178 length_32_button.property_draw_indicator() = false;
179 length_64_button.property_draw_indicator() = false;
181 note_length_box.pack_start (length_1_button, false, false);
182 note_length_box.pack_start (length_2_button, false, false);
183 note_length_box.pack_start (length_4_button, false, false);
184 note_length_box.pack_start (length_8_button, false, false);
185 note_length_box.pack_start (length_16_button, false, false);
186 note_length_box.pack_start (length_32_button, false, false);
187 note_length_box.pack_start (length_64_button, false, false);
189 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
190 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
191 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
192 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
193 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
194 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
195 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
197 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
198 velocity_pp_button.set_group (velocity_group);
199 velocity_p_button.set_group (velocity_group);
200 velocity_mp_button.set_group (velocity_group);
201 velocity_mf_button.set_group (velocity_group);
202 velocity_f_button.set_group (velocity_group);
203 velocity_ff_button.set_group (velocity_group);
204 velocity_fff_button.set_group (velocity_group);
206 w = manage (new Image (::get_icon (X_("pianississimo"))));
208 velocity_ppp_button.add (*w);
209 w = manage (new Image (::get_icon (X_("pianissimo"))));
211 velocity_pp_button.add (*w);
212 w = manage (new Image (::get_icon (X_("piano"))));
214 velocity_p_button.add (*w);
215 w = manage (new Image (::get_icon (X_("mezzopiano"))));
217 velocity_mp_button.add (*w);
218 w = manage (new Image (::get_icon (X_("mezzoforte"))));
220 velocity_mf_button.add (*w);
221 w = manage (new Image (::get_icon (X_("forte"))));
223 velocity_f_button.add (*w);
224 w = manage (new Image (::get_icon (X_("fortissimo"))));
226 velocity_ff_button.add (*w);
227 w = manage (new Image (::get_icon (X_("fortississimo"))));
229 velocity_fff_button.add (*w);
231 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
232 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
233 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
234 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
235 act = ActionManager::get_action ("StepEditing/note-velocity-p");
236 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
237 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
238 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
239 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
240 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
241 act = ActionManager::get_action ("StepEditing/note-velocity-f");
242 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
243 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
244 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
245 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
246 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
248 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
249 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
250 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
251 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
252 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
253 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
254 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
255 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
256 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
257 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
258 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
259 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
260 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
261 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
262 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
263 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
265 velocity_ppp_button.property_draw_indicator() = false;
266 velocity_pp_button.property_draw_indicator() = false;
267 velocity_p_button.property_draw_indicator() = false;
268 velocity_mp_button.property_draw_indicator() = false;
269 velocity_mf_button.property_draw_indicator() = false;
270 velocity_f_button.property_draw_indicator() = false;
271 velocity_ff_button.property_draw_indicator() = false;
272 velocity_fff_button.property_draw_indicator() = false;
274 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
275 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
276 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
277 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
278 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
279 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
280 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
281 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
283 note_velocity_box.pack_start (velocity_ppp_button, false, false);
284 note_velocity_box.pack_start (velocity_pp_button, false, false);
285 note_velocity_box.pack_start (velocity_p_button, false, false);
286 note_velocity_box.pack_start (velocity_mp_button, false, false);
287 note_velocity_box.pack_start (velocity_mf_button, false, false);
288 note_velocity_box.pack_start (velocity_f_button, false, false);
289 note_velocity_box.pack_start (velocity_ff_button, false, false);
290 note_velocity_box.pack_start (velocity_fff_button, false, false);
292 Label* l = manage (new Label);
293 l->set_markup ("<b><big>-</big></b>");
295 dot0_button.add (*l);
297 l = manage (new Label);
298 l->set_markup ("<b><big>.</big></b>");
300 dot1_button.add (*l);
302 l = manage (new Label);
303 l->set_markup ("<b><big>..</big></b>");
305 dot2_button.add (*l);
307 l = manage (new Label);
308 l->set_markup ("<b><big>...</big></b>");
310 dot3_button.add (*l);
312 w = manage (new Image (::get_icon (X_("chord"))));
314 chord_button.add (*w);
316 dot_box1.pack_start (dot0_button, true, false);
317 dot_box1.pack_start (dot1_button, true, false);
318 dot_box2.pack_start (dot2_button, true, false);
319 dot_box2.pack_start (dot3_button, true, false);
321 rest_box.pack_start (rest_button, true, false);
322 rest_box.pack_start (grid_rest_button, true, false);
323 rest_box.pack_start (back_button, true, false);
325 resync_box.pack_start (beat_resync_button, true, false);
326 resync_box.pack_start (bar_resync_button, true, false);
327 resync_box.pack_start (resync_button, true, false);
329 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
330 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
331 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
332 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
333 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
334 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
335 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
336 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
337 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
338 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
339 set_tooltip (&bank_button, _("Insert a bank change message"), "");
340 set_tooltip (&program_button, _("Insert a program change message"), "");
341 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
342 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
344 act = ActionManager::get_action ("StepEditing/back");
345 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
346 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
347 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
348 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
349 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
350 act = ActionManager::get_action ("StepEditing/toggle-triplet");
351 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
352 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
353 act = ActionManager::get_action ("StepEditing/no-dotted");
354 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
355 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
356 act = ActionManager::get_action ("StepEditing/toggle-dotted");
357 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
358 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
359 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
360 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
361 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
362 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
363 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
364 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
365 act = ActionManager::get_action ("StepEditing/toggle-chord");
366 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
367 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
368 act = ActionManager::get_action ("StepEditing/insert-rest");
369 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
370 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
371 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
372 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
373 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
374 act = ActionManager::get_action ("StepEditing/sustain");
375 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
376 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
378 upper_box.set_spacing (6);
379 upper_box.pack_start (chord_button, false, false);
380 upper_box.pack_start (note_length_box, false, false, 12);
381 upper_box.pack_start (triplet_button, false, false);
382 upper_box.pack_start (dot_box1, false, false);
383 upper_box.pack_start (dot_box2, false, false);
384 upper_box.pack_start (sustain_button, false, false);
385 upper_box.pack_start (rest_box, false, false);
386 upper_box.pack_start (resync_box, false, false);
387 upper_box.pack_start (note_velocity_box, false, false, 12);
391 v = manage (new VBox);
392 l = manage (new Label (_("Channel")));
394 v->pack_start (*l, false, false);
395 v->pack_start (channel_spinner, false, false);
396 upper_box.pack_start (*v, false, false);
398 v = manage (new VBox);
399 l = manage (new Label (_("1/Note")));
401 v->pack_start (*l, false, false);
402 v->pack_start (length_divisor_spinner, false, false);
403 upper_box.pack_start (*v, false, false);
405 v = manage (new VBox);
406 l = manage (new Label (_("Velocity")));
408 v->pack_start (*l, false, false);
409 v->pack_start (velocity_spinner, false, false);
410 upper_box.pack_start (*v, false, false);
412 v = manage (new VBox);
413 l = manage (new Label (_("Octave")));
415 v->pack_start (*l, false, false);
416 v->pack_start (octave_spinner, false, false);
417 upper_box.pack_start (*v, false, false);
419 v = manage (new VBox);
420 l = manage (new Label (_("Bank")));
422 v->pack_start (*l, false, false);
423 v->pack_start (bank_spinner, false, false);
424 v->pack_start (bank_button, false, false);
425 upper_box.pack_start (*v, false, false);
427 v = manage (new VBox);
428 l = manage (new Label (_("Program")));
430 v->pack_start (*l, false, false);
431 v->pack_start (program_spinner, false, false);
432 v->pack_start (program_button, false, false);
433 upper_box.pack_start (*v, false, false);
435 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
436 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
437 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
439 _piano = (PianoKeyboard*) piano_keyboard_new ();
440 piano = wrap ((GtkWidget*) _piano);
442 piano->set_flags (Gtk::CAN_FOCUS);
444 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
445 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
447 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
448 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
449 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
450 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
452 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
454 packer.set_spacing (6);
455 packer.pack_start (upper_box, false, false);
456 packer.pack_start (*piano, false, false);
461 /* initial settings: quarter note and mezzo forte */
463 ActionManager::get_radio_action ("StepEditing/note-length-quarter")->set_active (true);
464 ActionManager::get_radio_action ("StepEditing/note-velocity-mf")->set_active (true);
467 StepEntry::~StepEntry()
472 StepEntry::set_step_editor (StepEditor* seditor)
474 if (se && se != seditor) {
475 se->step_entry_done ();
481 set_title (string_compose (_("Step Entry: %1"), se->name()));
483 /* set channel selector to first selected channel. if none
484 are selected, it will remain at the value set in its
485 constructor, above (1)
488 uint16_t chn_mask = se->channel_selector().get_selected_channels();
490 for (uint32_t i = 0; i < 16; ++i) {
491 if (chn_mask & (1<<i)) {
492 channel_adjustment.set_value (i+1);
505 StepEntry::length_changed ()
507 length_1_button.queue_draw ();
508 length_2_button.queue_draw ();
509 length_4_button.queue_draw ();
510 length_8_button.queue_draw ();
511 length_16_button.queue_draw ();
512 length_32_button.queue_draw ();
513 length_64_button.queue_draw ();
517 StepEntry::on_key_press_event (GdkEventKey* ev)
519 /* focus widget gets first shot, then bindings, otherwise
520 forward to main window
523 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
527 return relay_key_press (ev, this);
531 StepEntry::on_key_release_event (GdkEventKey* ev)
533 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
537 /* don't forward releases */
543 StepEntry::rest_event_handler ()
546 se->step_edit_rest (Temporal::Beats());
551 StepEntry::note_length ()
553 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
555 RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ("StepEditing/toggle-triplet");
556 bool triplets = tact->get_active ();
559 base_time *= (2.0/3.0);
562 double dots = dot_adjustment.get_value ();
565 dots = pow (2.0, dots);
566 base_time *= 1 + ((dots - 1.0)/dots);
569 return Temporal::Beats(base_time);
573 StepEntry::note_velocity () const
575 return velocity_adjustment.get_value();
579 StepEntry::note_channel() const
581 return channel_adjustment.get_value() - 1;
585 StepEntry::note_off_event_handler (int note)
592 StepEntry::on_show ()
594 ArdourWindow::on_show ();
595 //piano->grab_focus ();
599 StepEntry::beat_resync_click ()
602 se->step_edit_beat_sync ();
607 StepEntry::bar_resync_click ()
610 se->step_edit_bar_sync ();
615 StepEntry::register_actions ()
617 /* add named actions for the step editor */
619 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (bindings, X_("StepEditing"));
621 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::ptr_fun (&StepEntry::se_insert_a));
622 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::ptr_fun (&StepEntry::se_insert_asharp));
623 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::ptr_fun (&StepEntry::se_insert_b));
624 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::ptr_fun (&StepEntry::se_insert_c));
625 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::ptr_fun (&StepEntry::se_insert_csharp));
626 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::ptr_fun (&StepEntry::se_insert_d));
627 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::ptr_fun (&StepEntry::se_insert_dsharp));
628 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::ptr_fun (&StepEntry::se_insert_e));
629 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::ptr_fun (&StepEntry::se_insert_f));
630 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::ptr_fun (&StepEntry::se_insert_fsharp));
631 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::ptr_fun (&StepEntry::se_insert_g));
632 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::ptr_fun (&StepEntry::se_insert_gsharp));
634 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_rest));
635 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_grid_rest));
637 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_next_octave));
638 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_prev_octave));
640 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::ptr_fun (&StepEntry::se_next_note_length));
641 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::ptr_fun (&StepEntry::se_prev_note_length));
643 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::ptr_fun (&StepEntry::se_inc_note_length));
644 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::ptr_fun (&StepEntry::se_dec_note_length));
646 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::ptr_fun (&StepEntry::se_next_note_velocity));
647 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::ptr_fun (&StepEntry::se_prev_note_velocity));
649 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::ptr_fun (&StepEntry::se_inc_note_velocity));
650 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::ptr_fun (&StepEntry::se_dec_note_velocity));
652 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::ptr_fun (&StepEntry::se_octave_0));
653 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::ptr_fun (&StepEntry::se_octave_1));
654 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::ptr_fun (&StepEntry::se_octave_2));
655 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::ptr_fun (&StepEntry::se_octave_3));
656 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::ptr_fun (&StepEntry::se_octave_4));
657 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::ptr_fun (&StepEntry::se_octave_5));
658 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::ptr_fun (&StepEntry::se_octave_6));
659 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::ptr_fun (&StepEntry::se_octave_7));
660 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::ptr_fun (&StepEntry::se_octave_8));
661 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::ptr_fun (&StepEntry::se_octave_9));
662 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::ptr_fun (&StepEntry::se_octave_10));
664 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"), sigc::ptr_fun (&StepEntry::se_toggle_triplet));
666 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"), sigc::ptr_fun (&StepEntry::se_toggle_chord));
667 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"), sigc::ptr_fun (&StepEntry::se_do_sustain));
669 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"), sigc::ptr_fun (&StepEntry::se_sync_to_edit_point));
670 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"), sigc::ptr_fun (&StepEntry::se_back));
672 RadioAction::Group note_length_group;
674 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
675 _("Set Note Length to Whole"), sigc::ptr_fun (&StepEntry::se_note_length_change), 1);
676 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
677 _("Set Note Length to 1/2"), sigc::ptr_fun (&StepEntry::se_note_length_change), 2);
678 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
679 _("Set Note Length to 1/3"), sigc::ptr_fun (&StepEntry::se_note_length_change), 3);
680 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
681 _("Set Note Length to 1/4"), sigc::ptr_fun (&StepEntry::se_note_length_change), 4);
682 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
683 _("Set Note Length to 1/8"), sigc::ptr_fun (&StepEntry::se_note_length_change), 8);
684 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
685 _("Set Note Length to 1/16"), sigc::ptr_fun (&StepEntry::se_note_length_change), 16);
686 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
687 _("Set Note Length to 1/32"), sigc::ptr_fun (&StepEntry::se_note_length_change), 32);
688 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
689 _("Set Note Length to 1/64"), sigc::ptr_fun (&StepEntry::se_note_length_change), 64);
691 RadioAction::Group note_velocity_group;
693 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
694 _("Set Note Velocity to Pianississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 1);
695 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
696 _("Set Note Velocity to Pianissimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 16);
697 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
698 _("Set Note Velocity to Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 32);
699 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
700 _("Set Note Velocity to Mezzo-Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 64);
701 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
702 _("Set Note Velocity to Mezzo-Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 80);
703 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
704 _("Set Note Velocity to Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 96);
705 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
706 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 112);
707 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
708 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 127);
711 RadioAction::Group dot_group;
713 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 0);
714 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 1);
715 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 2);
716 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 3);
720 StepEntry::setup_actions_and_bindings ()
727 StepEntry::load_bindings ()
729 bindings = Bindings::get_bindings (X_("Step Editing"));
733 StepEntry::toggle_triplet ()
736 se->set_step_edit_cursor_width (note_length());
741 StepEntry::toggle_chord ()
744 se->step_edit_toggle_chord ();
749 StepEntry::dot_change (GtkAction* act)
751 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
752 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
753 dot_adjustment.set_value (v);
758 StepEntry::dot_value_change ()
761 RefPtr<RadioAction> ract;
762 double val = dot_adjustment.get_value();
763 bool inconsistent = true;
764 vector<const char*> dot_actions;
766 dot_actions.push_back ("StepEditing/no-dotted");
767 dot_actions.push_back ("StepEditing/toggle-dotted");
768 dot_actions.push_back ("StepEditing/toggle-double-dotted");
769 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
771 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
773 act = ActionManager::get_action (*i);
776 ract = RefPtr<RadioAction>::cast_dynamic (act);
779 if (ract->property_value() == val) {
780 ract->set_active (true);
781 inconsistent = false;
788 dot1_button.set_inconsistent (inconsistent);
789 dot2_button.set_inconsistent (inconsistent);
790 dot3_button.set_inconsistent (inconsistent);
793 se->set_step_edit_cursor_width (note_length());
798 StepEntry::program_click ()
801 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
806 StepEntry::bank_click ()
809 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
814 StepEntry::insert_rest ()
817 se->step_edit_rest (note_length());
822 StepEntry::insert_grid_rest ()
825 se->step_edit_rest (Temporal::Beats());
830 StepEntry::insert_note (uint8_t note)
837 se->step_add_note (note_channel(), note, note_velocity(), note_length());
841 StepEntry::insert_c ()
843 insert_note (0 + (current_octave() * 12));
846 StepEntry::insert_csharp ()
848 insert_note (1 + (current_octave() * 12));
851 StepEntry::insert_d ()
853 insert_note (2 + (current_octave() * 12));
856 StepEntry::insert_dsharp ()
858 insert_note (3 + (current_octave() * 12));
861 StepEntry::insert_e ()
863 insert_note (4 + (current_octave() * 12));
866 StepEntry::insert_f ()
868 insert_note (5 + (current_octave() * 12));
871 StepEntry::insert_fsharp ()
873 insert_note (6 + (current_octave() * 12));
876 StepEntry::insert_g ()
878 insert_note (7 + (current_octave() * 12));
881 StepEntry::insert_gsharp ()
883 insert_note (8 + (current_octave() * 12));
887 StepEntry::insert_a ()
889 insert_note (9 + (current_octave() * 12));
893 StepEntry::insert_asharp ()
895 insert_note (10 + (current_octave() * 12));
898 StepEntry::insert_b ()
900 insert_note (11 + (current_octave() * 12));
904 StepEntry::note_length_change (GtkAction* act)
906 /* it doesn't matter which note length action we look up - we are interested
907 in the current_value which is global across the whole group of note length
908 actions. this method is called twice for every user operation,
909 once for the action that became "inactive" and once for the action that
910 becaome "active". so ... only bother to actually change the value when this
911 is called for the "active" action.
914 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
915 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
916 length_divisor_adjustment.set_value (v);
921 StepEntry::note_velocity_change (GtkAction* act)
923 /* it doesn't matter which note velocity action we look up - we are interested
924 in the current_value which is global across the whole group of note velocity
925 actions. this method is called twice for every user operation,
926 once for the action that became "inactive" and once for the action that
927 becaome "active". so ... only bother to actually change the value when this
928 is called for the "active" action.
931 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
932 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
933 velocity_adjustment.set_value (v);
938 StepEntry::velocity_value_change ()
941 RefPtr<RadioAction> ract;
942 double val = velocity_adjustment.get_value();
943 bool inconsistent = true;
944 vector<const char*> velocity_actions;
946 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
947 velocity_actions.push_back ("StepEditing/note-velocity-pp");
948 velocity_actions.push_back ("StepEditing/note-velocity-p");
949 velocity_actions.push_back ("StepEditing/note-velocity-mp");
950 velocity_actions.push_back ("StepEditing/note-velocity-mf");
951 velocity_actions.push_back ("StepEditing/note-velocity-f");
952 velocity_actions.push_back ("StepEditing/note-velocity-ff");
953 velocity_actions.push_back ("StepEditing/note-velocity-fff");
955 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
957 act = ActionManager::get_action (*i);
960 ract = RefPtr<RadioAction>::cast_dynamic (act);
963 if (ract->property_value() == val) {
964 ract->set_active (true);
965 inconsistent = false;
972 velocity_ppp_button.set_inconsistent (inconsistent);
973 velocity_pp_button.set_inconsistent (inconsistent);
974 velocity_p_button.set_inconsistent (inconsistent);
975 velocity_mp_button.set_inconsistent (inconsistent);
976 velocity_mf_button.set_inconsistent (inconsistent);
977 velocity_f_button.set_inconsistent (inconsistent);
978 velocity_ff_button.set_inconsistent (inconsistent);
979 velocity_fff_button.set_inconsistent (inconsistent);
983 StepEntry::length_value_change ()
986 RefPtr<RadioAction> ract;
987 bool inconsistent = true;
988 vector<const char*> length_actions;
990 length_actions.push_back ("StepEditing/note-length-whole");
991 length_actions.push_back ("StepEditing/note-length-half");
992 length_actions.push_back ("StepEditing/note-length-quarter");
993 length_actions.push_back ("StepEditing/note-length-eighth");
994 length_actions.push_back ("StepEditing/note-length-sixteenth");
995 length_actions.push_back ("StepEditing/note-length-thirtysecond");
996 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
998 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
1000 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
1002 ract->set_active (true);
1003 inconsistent = false;
1007 length_1_button.set_inconsistent (inconsistent);
1008 length_2_button.set_inconsistent (inconsistent);
1009 length_4_button.set_inconsistent (inconsistent);
1010 length_8_button.set_inconsistent (inconsistent);
1011 length_16_button.set_inconsistent (inconsistent);
1012 length_32_button.set_inconsistent (inconsistent);
1013 length_64_button.set_inconsistent (inconsistent);
1016 se->set_step_edit_cursor_width (note_length());
1021 StepEntry::radio_button_press (GdkEventButton* ev)
1023 if (ev->button == 1) {
1031 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
1033 if (ev->button == 1) {
1034 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
1037 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1047 StepEntry::next_octave ()
1049 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1053 StepEntry::prev_octave ()
1055 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1059 StepEntry::inc_note_length ()
1061 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1065 StepEntry::dec_note_length ()
1067 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1071 StepEntry::prev_note_length ()
1073 double l = length_divisor_adjustment.get_value();
1074 int il = (int) lrintf (l); // round to nearest integer
1075 il = (il/2) * 2; // round to power of 2
1083 length_divisor_adjustment.set_value (il);
1087 StepEntry::next_note_length ()
1089 double l = length_divisor_adjustment.get_value();
1090 int il = (int) lrintf (l); // round to nearest integer
1091 il = (il/2) * 2; // round to power of 2
1100 length_divisor_adjustment.set_value (il);
1105 StepEntry::inc_note_velocity ()
1107 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1111 StepEntry::dec_note_velocity ()
1113 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1117 StepEntry::next_note_velocity ()
1119 double l = velocity_adjustment.get_value ();
1123 } else if (l < 32) {
1125 } else if (l < 48) {
1127 } else if (l < 64) {
1129 } else if (l < 80) {
1131 } else if (l < 96) {
1133 } else if (l < 112) {
1135 } else if (l < 127) {
1139 velocity_adjustment.set_value (l);
1143 StepEntry::prev_note_velocity ()
1145 double l = velocity_adjustment.get_value ();
1149 } else if (l > 96) {
1151 } else if (l > 80) {
1153 } else if (l > 64) {
1155 } else if (l > 48) {
1157 } else if (l > 32) {
1159 } else if (l > 16) {
1165 velocity_adjustment.set_value (l);
1169 StepEntry::octave_n (int n)
1171 octave_adjustment.set_value (n);
1175 StepEntry::do_sustain ()
1178 se->step_edit_sustain (note_length());
1186 se->move_step_edit_beat_pos (-note_length());
1191 StepEntry::sync_to_edit_point ()
1194 se->resync_step_edit_to_edit_point ();