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;
57 _instance = new StepEntry;
63 StepEntry::StepEntry ()
64 : ArdourWindow (string())
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 (_("+"))
92 set_data ("ardour-bindings", bindings);
94 RadioButtonGroup length_group = length_1_button.get_group();
95 length_2_button.set_group (length_group);
96 length_4_button.set_group (length_group);
97 length_8_button.set_group (length_group);
98 length_12_button.set_group (length_group);
99 length_16_button.set_group (length_group);
100 length_32_button.set_group (length_group);
101 length_64_button.set_group (length_group);
105 w = manage (new Image (::get_icon (X_("wholenote"))));
107 length_1_button.add (*w);
108 w = manage (new Image (::get_icon (X_("halfnote"))));
110 length_2_button.add (*w);
111 w = manage (new Image (::get_icon (X_("quarternote"))));
113 length_4_button.add (*w);
114 w = manage (new Image (::get_icon (X_("eighthnote"))));
116 length_8_button.add (*w);
117 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
119 length_16_button.add (*w);
120 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
122 length_32_button.add (*w);
123 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
125 length_64_button.add (*w);
129 act = ActionManager::get_action ("StepEditing/note-length-whole");
130 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
131 act = ActionManager::get_action ("StepEditing/note-length-half");
132 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
133 act = ActionManager::get_action ("StepEditing/note-length-quarter");
134 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
135 act = ActionManager::get_action ("StepEditing/note-length-eighth");
136 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
137 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
138 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
139 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
140 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
141 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
142 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
144 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
145 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
146 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
147 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
148 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
149 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
150 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
151 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
152 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
153 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
154 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
155 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
156 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
157 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
159 length_1_button.property_draw_indicator() = false;
160 length_2_button.property_draw_indicator() = false;
161 length_4_button.property_draw_indicator() = false;
162 length_8_button.property_draw_indicator() = false;
163 length_16_button.property_draw_indicator() = false;
164 length_32_button.property_draw_indicator() = false;
165 length_64_button.property_draw_indicator() = false;
167 note_length_box.pack_start (length_1_button, false, false);
168 note_length_box.pack_start (length_2_button, false, false);
169 note_length_box.pack_start (length_4_button, false, false);
170 note_length_box.pack_start (length_8_button, false, false);
171 note_length_box.pack_start (length_16_button, false, false);
172 note_length_box.pack_start (length_32_button, false, false);
173 note_length_box.pack_start (length_64_button, false, false);
175 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
176 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
177 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
178 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
179 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
180 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
181 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
183 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
184 velocity_pp_button.set_group (velocity_group);
185 velocity_p_button.set_group (velocity_group);
186 velocity_mp_button.set_group (velocity_group);
187 velocity_mf_button.set_group (velocity_group);
188 velocity_f_button.set_group (velocity_group);
189 velocity_ff_button.set_group (velocity_group);
190 velocity_fff_button.set_group (velocity_group);
192 w = manage (new Image (::get_icon (X_("pianississimo"))));
194 velocity_ppp_button.add (*w);
195 w = manage (new Image (::get_icon (X_("pianissimo"))));
197 velocity_pp_button.add (*w);
198 w = manage (new Image (::get_icon (X_("piano"))));
200 velocity_p_button.add (*w);
201 w = manage (new Image (::get_icon (X_("mezzopiano"))));
203 velocity_mp_button.add (*w);
204 w = manage (new Image (::get_icon (X_("mezzoforte"))));
206 velocity_mf_button.add (*w);
207 w = manage (new Image (::get_icon (X_("forte"))));
209 velocity_f_button.add (*w);
210 w = manage (new Image (::get_icon (X_("fortissimo"))));
212 velocity_ff_button.add (*w);
213 w = manage (new Image (::get_icon (X_("fortississimo"))));
215 velocity_fff_button.add (*w);
217 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
218 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
219 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
220 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
221 act = ActionManager::get_action ("StepEditing/note-velocity-p");
222 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
223 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
224 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
225 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
226 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
227 act = ActionManager::get_action ("StepEditing/note-velocity-f");
228 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
229 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
230 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
231 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
232 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
234 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
235 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
236 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
237 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
238 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
239 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
240 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
241 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
242 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
243 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
244 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
245 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
246 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
247 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
248 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
249 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
251 velocity_ppp_button.property_draw_indicator() = false;
252 velocity_pp_button.property_draw_indicator() = false;
253 velocity_p_button.property_draw_indicator() = false;
254 velocity_mp_button.property_draw_indicator() = false;
255 velocity_mf_button.property_draw_indicator() = false;
256 velocity_f_button.property_draw_indicator() = false;
257 velocity_ff_button.property_draw_indicator() = false;
258 velocity_fff_button.property_draw_indicator() = false;
260 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
261 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
262 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
263 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
264 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
265 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
266 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
267 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
269 note_velocity_box.pack_start (velocity_ppp_button, false, false);
270 note_velocity_box.pack_start (velocity_pp_button, false, false);
271 note_velocity_box.pack_start (velocity_p_button, false, false);
272 note_velocity_box.pack_start (velocity_mp_button, false, false);
273 note_velocity_box.pack_start (velocity_mf_button, false, false);
274 note_velocity_box.pack_start (velocity_f_button, false, false);
275 note_velocity_box.pack_start (velocity_ff_button, false, false);
276 note_velocity_box.pack_start (velocity_fff_button, false, false);
278 Label* l = manage (new Label);
279 l->set_markup ("<b><big>-</big></b>");
281 dot0_button.add (*l);
283 l = manage (new Label);
284 l->set_markup ("<b><big>.</big></b>");
286 dot1_button.add (*l);
288 l = manage (new Label);
289 l->set_markup ("<b><big>..</big></b>");
291 dot2_button.add (*l);
293 l = manage (new Label);
294 l->set_markup ("<b><big>...</big></b>");
296 dot3_button.add (*l);
298 w = manage (new Image (::get_icon (X_("chord"))));
300 chord_button.add (*w);
302 dot_box1.pack_start (dot0_button, true, false);
303 dot_box1.pack_start (dot1_button, true, false);
304 dot_box2.pack_start (dot2_button, true, false);
305 dot_box2.pack_start (dot3_button, true, false);
307 rest_box.pack_start (rest_button, true, false);
308 rest_box.pack_start (grid_rest_button, true, false);
309 rest_box.pack_start (back_button, true, false);
311 resync_box.pack_start (beat_resync_button, true, false);
312 resync_box.pack_start (bar_resync_button, true, false);
313 resync_box.pack_start (resync_button, true, false);
315 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
316 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
317 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
318 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
319 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
320 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
321 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
322 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
323 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
324 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
325 set_tooltip (&bank_button, _("Insert a bank change message"), "");
326 set_tooltip (&program_button, _("Insert a program change message"), "");
327 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
328 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
330 act = ActionManager::get_action ("StepEditing/back");
331 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
332 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
333 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
334 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
335 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
336 act = ActionManager::get_action ("StepEditing/toggle-triplet");
337 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
338 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
339 act = ActionManager::get_action ("StepEditing/no-dotted");
340 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
341 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
342 act = ActionManager::get_action ("StepEditing/toggle-dotted");
343 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
344 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
345 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
346 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
347 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
348 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
349 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
350 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
351 act = ActionManager::get_action ("StepEditing/toggle-chord");
352 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
353 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
354 act = ActionManager::get_action ("StepEditing/insert-rest");
355 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
356 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
357 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
358 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
359 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
360 act = ActionManager::get_action ("StepEditing/sustain");
361 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
362 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
364 upper_box.set_spacing (6);
365 upper_box.pack_start (chord_button, false, false);
366 upper_box.pack_start (note_length_box, false, false, 12);
367 upper_box.pack_start (triplet_button, false, false);
368 upper_box.pack_start (dot_box1, false, false);
369 upper_box.pack_start (dot_box2, false, false);
370 upper_box.pack_start (sustain_button, false, false);
371 upper_box.pack_start (rest_box, false, false);
372 upper_box.pack_start (resync_box, false, false);
373 upper_box.pack_start (note_velocity_box, false, false, 12);
377 v = manage (new VBox);
378 l = manage (new Label (_("Channel")));
380 v->pack_start (*l, false, false);
381 v->pack_start (channel_spinner, false, false);
382 upper_box.pack_start (*v, false, false);
384 v = manage (new VBox);
385 l = manage (new Label (_("1/Note")));
387 v->pack_start (*l, false, false);
388 v->pack_start (length_divisor_spinner, false, false);
389 upper_box.pack_start (*v, false, false);
391 v = manage (new VBox);
392 l = manage (new Label (_("Velocity")));
394 v->pack_start (*l, false, false);
395 v->pack_start (velocity_spinner, false, false);
396 upper_box.pack_start (*v, false, false);
398 v = manage (new VBox);
399 l = manage (new Label (_("Octave")));
401 v->pack_start (*l, false, false);
402 v->pack_start (octave_spinner, false, false);
403 upper_box.pack_start (*v, false, false);
405 v = manage (new VBox);
406 l = manage (new Label (_("Bank")));
408 v->pack_start (*l, false, false);
409 v->pack_start (bank_spinner, false, false);
410 v->pack_start (bank_button, false, false);
411 upper_box.pack_start (*v, false, false);
413 v = manage (new VBox);
414 l = manage (new Label (_("Program")));
416 v->pack_start (*l, false, false);
417 v->pack_start (program_spinner, false, false);
418 v->pack_start (program_button, false, false);
419 upper_box.pack_start (*v, false, false);
421 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
422 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
423 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
425 _piano.set_flags (Gtk::CAN_FOCUS);
427 _piano.NoteOff.connect (sigc::mem_fun (*this, &StepEntry::note_off_event_handler));
428 _piano.Rest.connect (sigc::mem_fun (*this, &StepEntry::rest_event_handler));
430 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
431 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
432 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
433 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
435 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
437 packer.set_spacing (6);
438 packer.pack_start (upper_box, false, false);
439 packer.pack_start (_piano, false, false);
444 /* initial settings: quarter note and mezzo forte */
446 ActionManager::get_radio_action ("StepEditing/note-length-quarter")->set_active (true);
447 ActionManager::get_radio_action ("StepEditing/note-velocity-mf")->set_active (true);
450 StepEntry::~StepEntry()
455 StepEntry::set_step_editor (StepEditor* seditor)
457 if (se && se != seditor) {
458 se->step_entry_done ();
464 set_title (string_compose (_("Step Entry: %1"), se->name()));
466 /* set channel selector to first selected channel. if none
467 are selected, it will remain at the value set in its
468 constructor, above (1)
471 uint16_t chn_mask = se->channel_selector().get_selected_channels();
473 for (uint32_t i = 0; i < 16; ++i) {
474 if (chn_mask & (1<<i)) {
475 channel_adjustment.set_value (i+1);
488 StepEntry::length_changed ()
490 length_1_button.queue_draw ();
491 length_2_button.queue_draw ();
492 length_4_button.queue_draw ();
493 length_8_button.queue_draw ();
494 length_16_button.queue_draw ();
495 length_32_button.queue_draw ();
496 length_64_button.queue_draw ();
500 StepEntry::on_key_press_event (GdkEventKey* ev)
502 /* focus widget gets first shot, then bindings, otherwise
503 forward to main window
506 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
510 return relay_key_press (ev, this);
514 StepEntry::on_key_release_event (GdkEventKey* ev)
516 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
520 /* don't forward releases */
526 StepEntry::rest_event_handler ()
529 se->step_edit_rest (Temporal::Beats());
534 StepEntry::note_length ()
536 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
538 RefPtr<ToggleAction> tact = ActionManager::get_toggle_action ("StepEditing/toggle-triplet");
539 bool triplets = tact->get_active ();
542 base_time *= (2.0/3.0);
545 double dots = dot_adjustment.get_value ();
548 dots = pow (2.0, dots);
549 base_time *= 1 + ((dots - 1.0)/dots);
552 return Temporal::Beats(base_time);
556 StepEntry::note_velocity () const
558 return velocity_adjustment.get_value();
562 StepEntry::note_channel() const
564 return channel_adjustment.get_value() - 1;
568 StepEntry::note_off_event_handler (int note)
575 StepEntry::on_show ()
577 ArdourWindow::on_show ();
578 //_piano->grab_focus ();
582 StepEntry::beat_resync_click ()
585 se->step_edit_beat_sync ();
590 StepEntry::bar_resync_click ()
593 se->step_edit_bar_sync ();
598 StepEntry::register_actions ()
600 /* add named actions for the step editor */
602 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (bindings, X_("StepEditing"));
604 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::ptr_fun (&StepEntry::se_insert_a));
605 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::ptr_fun (&StepEntry::se_insert_asharp));
606 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::ptr_fun (&StepEntry::se_insert_b));
607 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::ptr_fun (&StepEntry::se_insert_c));
608 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::ptr_fun (&StepEntry::se_insert_csharp));
609 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::ptr_fun (&StepEntry::se_insert_d));
610 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::ptr_fun (&StepEntry::se_insert_dsharp));
611 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::ptr_fun (&StepEntry::se_insert_e));
612 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::ptr_fun (&StepEntry::se_insert_f));
613 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::ptr_fun (&StepEntry::se_insert_fsharp));
614 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::ptr_fun (&StepEntry::se_insert_g));
615 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::ptr_fun (&StepEntry::se_insert_gsharp));
617 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_rest));
618 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_grid_rest));
620 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_next_octave));
621 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_prev_octave));
623 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::ptr_fun (&StepEntry::se_next_note_length));
624 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::ptr_fun (&StepEntry::se_prev_note_length));
626 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::ptr_fun (&StepEntry::se_inc_note_length));
627 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::ptr_fun (&StepEntry::se_dec_note_length));
629 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::ptr_fun (&StepEntry::se_next_note_velocity));
630 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::ptr_fun (&StepEntry::se_prev_note_velocity));
632 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::ptr_fun (&StepEntry::se_inc_note_velocity));
633 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::ptr_fun (&StepEntry::se_dec_note_velocity));
635 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::ptr_fun (&StepEntry::se_octave_0));
636 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::ptr_fun (&StepEntry::se_octave_1));
637 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::ptr_fun (&StepEntry::se_octave_2));
638 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::ptr_fun (&StepEntry::se_octave_3));
639 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::ptr_fun (&StepEntry::se_octave_4));
640 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::ptr_fun (&StepEntry::se_octave_5));
641 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::ptr_fun (&StepEntry::se_octave_6));
642 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::ptr_fun (&StepEntry::se_octave_7));
643 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::ptr_fun (&StepEntry::se_octave_8));
644 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::ptr_fun (&StepEntry::se_octave_9));
645 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::ptr_fun (&StepEntry::se_octave_10));
647 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"), sigc::ptr_fun (&StepEntry::se_toggle_triplet));
649 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"), sigc::ptr_fun (&StepEntry::se_toggle_chord));
650 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"), sigc::ptr_fun (&StepEntry::se_do_sustain));
652 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"), sigc::ptr_fun (&StepEntry::se_sync_to_edit_point));
653 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"), sigc::ptr_fun (&StepEntry::se_back));
655 RadioAction::Group note_length_group;
657 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
658 _("Set Note Length to Whole"), sigc::ptr_fun (&StepEntry::se_note_length_change), 1);
659 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
660 _("Set Note Length to 1/2"), sigc::ptr_fun (&StepEntry::se_note_length_change), 2);
661 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
662 _("Set Note Length to 1/3"), sigc::ptr_fun (&StepEntry::se_note_length_change), 3);
663 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
664 _("Set Note Length to 1/4"), sigc::ptr_fun (&StepEntry::se_note_length_change), 4);
665 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
666 _("Set Note Length to 1/8"), sigc::ptr_fun (&StepEntry::se_note_length_change), 8);
667 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
668 _("Set Note Length to 1/16"), sigc::ptr_fun (&StepEntry::se_note_length_change), 16);
669 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
670 _("Set Note Length to 1/32"), sigc::ptr_fun (&StepEntry::se_note_length_change), 32);
671 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
672 _("Set Note Length to 1/64"), sigc::ptr_fun (&StepEntry::se_note_length_change), 64);
674 RadioAction::Group note_velocity_group;
676 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
677 _("Set Note Velocity to Pianississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 1);
678 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
679 _("Set Note Velocity to Pianissimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 16);
680 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
681 _("Set Note Velocity to Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 32);
682 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
683 _("Set Note Velocity to Mezzo-Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 64);
684 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
685 _("Set Note Velocity to Mezzo-Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 80);
686 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
687 _("Set Note Velocity to Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 96);
688 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
689 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 112);
690 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
691 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 127);
694 RadioAction::Group dot_group;
696 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 0);
697 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 1);
698 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 2);
699 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 3);
703 StepEntry::setup_actions_and_bindings ()
710 StepEntry::load_bindings ()
712 bindings = Bindings::get_bindings (X_("Step Editing"));
716 StepEntry::toggle_triplet ()
719 se->set_step_edit_cursor_width (note_length());
724 StepEntry::toggle_chord ()
727 se->step_edit_toggle_chord ();
732 StepEntry::dot_change (GtkAction* act)
734 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
735 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
736 dot_adjustment.set_value (v);
741 StepEntry::dot_value_change ()
744 RefPtr<RadioAction> ract;
745 double val = dot_adjustment.get_value();
746 bool inconsistent = true;
747 vector<const char*> dot_actions;
749 dot_actions.push_back ("StepEditing/no-dotted");
750 dot_actions.push_back ("StepEditing/toggle-dotted");
751 dot_actions.push_back ("StepEditing/toggle-double-dotted");
752 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
754 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
756 act = ActionManager::get_action (*i);
759 ract = RefPtr<RadioAction>::cast_dynamic (act);
762 if (ract->property_value() == val) {
763 ract->set_active (true);
764 inconsistent = false;
771 dot1_button.set_inconsistent (inconsistent);
772 dot2_button.set_inconsistent (inconsistent);
773 dot3_button.set_inconsistent (inconsistent);
776 se->set_step_edit_cursor_width (note_length());
781 StepEntry::program_click ()
784 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
789 StepEntry::bank_click ()
792 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
797 StepEntry::insert_rest ()
800 se->step_edit_rest (note_length());
805 StepEntry::insert_grid_rest ()
808 se->step_edit_rest (Temporal::Beats());
813 StepEntry::insert_note (uint8_t note)
820 se->step_add_note (note_channel(), note, note_velocity(), note_length());
824 StepEntry::insert_c ()
826 insert_note (0 + (current_octave() * 12));
829 StepEntry::insert_csharp ()
831 insert_note (1 + (current_octave() * 12));
834 StepEntry::insert_d ()
836 insert_note (2 + (current_octave() * 12));
839 StepEntry::insert_dsharp ()
841 insert_note (3 + (current_octave() * 12));
844 StepEntry::insert_e ()
846 insert_note (4 + (current_octave() * 12));
849 StepEntry::insert_f ()
851 insert_note (5 + (current_octave() * 12));
854 StepEntry::insert_fsharp ()
856 insert_note (6 + (current_octave() * 12));
859 StepEntry::insert_g ()
861 insert_note (7 + (current_octave() * 12));
864 StepEntry::insert_gsharp ()
866 insert_note (8 + (current_octave() * 12));
870 StepEntry::insert_a ()
872 insert_note (9 + (current_octave() * 12));
876 StepEntry::insert_asharp ()
878 insert_note (10 + (current_octave() * 12));
881 StepEntry::insert_b ()
883 insert_note (11 + (current_octave() * 12));
887 StepEntry::note_length_change (GtkAction* act)
889 /* it doesn't matter which note length action we look up - we are interested
890 in the current_value which is global across the whole group of note length
891 actions. this method is called twice for every user operation,
892 once for the action that became "inactive" and once for the action that
893 becaome "active". so ... only bother to actually change the value when this
894 is called for the "active" action.
897 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
898 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
899 length_divisor_adjustment.set_value (v);
904 StepEntry::note_velocity_change (GtkAction* act)
906 /* it doesn't matter which note velocity action we look up - we are interested
907 in the current_value which is global across the whole group of note velocity
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 velocity_adjustment.set_value (v);
921 StepEntry::velocity_value_change ()
924 RefPtr<RadioAction> ract;
925 double val = velocity_adjustment.get_value();
926 bool inconsistent = true;
927 vector<const char*> velocity_actions;
929 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
930 velocity_actions.push_back ("StepEditing/note-velocity-pp");
931 velocity_actions.push_back ("StepEditing/note-velocity-p");
932 velocity_actions.push_back ("StepEditing/note-velocity-mp");
933 velocity_actions.push_back ("StepEditing/note-velocity-mf");
934 velocity_actions.push_back ("StepEditing/note-velocity-f");
935 velocity_actions.push_back ("StepEditing/note-velocity-ff");
936 velocity_actions.push_back ("StepEditing/note-velocity-fff");
938 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
940 act = ActionManager::get_action (*i);
943 ract = RefPtr<RadioAction>::cast_dynamic (act);
946 if (ract->property_value() == val) {
947 ract->set_active (true);
948 inconsistent = false;
955 velocity_ppp_button.set_inconsistent (inconsistent);
956 velocity_pp_button.set_inconsistent (inconsistent);
957 velocity_p_button.set_inconsistent (inconsistent);
958 velocity_mp_button.set_inconsistent (inconsistent);
959 velocity_mf_button.set_inconsistent (inconsistent);
960 velocity_f_button.set_inconsistent (inconsistent);
961 velocity_ff_button.set_inconsistent (inconsistent);
962 velocity_fff_button.set_inconsistent (inconsistent);
966 StepEntry::length_value_change ()
969 RefPtr<RadioAction> ract;
970 bool inconsistent = true;
971 vector<const char*> length_actions;
973 length_actions.push_back ("StepEditing/note-length-whole");
974 length_actions.push_back ("StepEditing/note-length-half");
975 length_actions.push_back ("StepEditing/note-length-quarter");
976 length_actions.push_back ("StepEditing/note-length-eighth");
977 length_actions.push_back ("StepEditing/note-length-sixteenth");
978 length_actions.push_back ("StepEditing/note-length-thirtysecond");
979 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
981 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
983 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
985 ract->set_active (true);
986 inconsistent = false;
990 length_1_button.set_inconsistent (inconsistent);
991 length_2_button.set_inconsistent (inconsistent);
992 length_4_button.set_inconsistent (inconsistent);
993 length_8_button.set_inconsistent (inconsistent);
994 length_16_button.set_inconsistent (inconsistent);
995 length_32_button.set_inconsistent (inconsistent);
996 length_64_button.set_inconsistent (inconsistent);
999 se->set_step_edit_cursor_width (note_length());
1004 StepEntry::radio_button_press (GdkEventButton* ev)
1006 if (ev->button == 1) {
1014 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
1016 if (ev->button == 1) {
1017 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
1020 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1030 StepEntry::next_octave ()
1032 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1036 StepEntry::prev_octave ()
1038 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1042 StepEntry::inc_note_length ()
1044 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1048 StepEntry::dec_note_length ()
1050 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1054 StepEntry::prev_note_length ()
1056 double l = length_divisor_adjustment.get_value();
1057 int il = (int) lrintf (l); // round to nearest integer
1058 il = (il/2) * 2; // round to power of 2
1066 length_divisor_adjustment.set_value (il);
1070 StepEntry::next_note_length ()
1072 double l = length_divisor_adjustment.get_value();
1073 int il = (int) lrintf (l); // round to nearest integer
1074 il = (il/2) * 2; // round to power of 2
1083 length_divisor_adjustment.set_value (il);
1088 StepEntry::inc_note_velocity ()
1090 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1094 StepEntry::dec_note_velocity ()
1096 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1100 StepEntry::next_note_velocity ()
1102 double l = velocity_adjustment.get_value ();
1106 } else if (l < 32) {
1108 } else if (l < 48) {
1110 } else if (l < 64) {
1112 } else if (l < 80) {
1114 } else if (l < 96) {
1116 } else if (l < 112) {
1118 } else if (l < 127) {
1122 velocity_adjustment.set_value (l);
1126 StepEntry::prev_note_velocity ()
1128 double l = velocity_adjustment.get_value ();
1132 } else if (l > 96) {
1134 } else if (l > 80) {
1136 } else if (l > 64) {
1138 } else if (l > 48) {
1140 } else if (l > 32) {
1142 } else if (l > 16) {
1148 velocity_adjustment.set_value (l);
1152 StepEntry::octave_n (int n)
1154 octave_adjustment.set_value (n);
1158 StepEntry::do_sustain ()
1161 se->step_edit_sustain (note_length());
1169 se->move_step_edit_beat_pos (-note_length());
1174 StepEntry::sync_to_edit_point ()
1177 se->resync_step_edit_to_edit_point ();