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::_instance = 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 ();
67 _instance = new StepEntry;
73 StepEntry::StepEntry ()
74 : ArdourWindow (string())
75 , _current_note_length (1.0)
76 , _current_note_velocity (64)
77 , triplet_button ("3")
78 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
79 , beat_resync_button (_(">beat"))
80 , bar_resync_button (_(">bar"))
81 , resync_button (_(">EP"))
82 , sustain_button (_("sustain"))
83 , rest_button (_("rest"))
84 , grid_rest_button (_("g-rest"))
85 , back_button (_("back"))
86 , channel_adjustment (1, 1, 16, 1, 4)
87 , channel_spinner (channel_adjustment)
88 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
89 , octave_spinner (octave_adjustment)
90 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
91 , length_divisor_spinner (length_divisor_adjustment)
92 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
93 , velocity_spinner (velocity_adjustment)
94 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
95 , bank_spinner (bank_adjustment)
96 , bank_button (_("+"))
97 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
98 , program_spinner (program_adjustment)
99 , program_button (_("+"))
104 set_data ("ardour-bindings", bindings);
106 RadioButtonGroup length_group = length_1_button.get_group();
107 length_2_button.set_group (length_group);
108 length_4_button.set_group (length_group);
109 length_8_button.set_group (length_group);
110 length_12_button.set_group (length_group);
111 length_16_button.set_group (length_group);
112 length_32_button.set_group (length_group);
113 length_64_button.set_group (length_group);
117 w = manage (new Image (::get_icon (X_("wholenote"))));
119 length_1_button.add (*w);
120 w = manage (new Image (::get_icon (X_("halfnote"))));
122 length_2_button.add (*w);
123 w = manage (new Image (::get_icon (X_("quarternote"))));
125 length_4_button.add (*w);
126 w = manage (new Image (::get_icon (X_("eighthnote"))));
128 length_8_button.add (*w);
129 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
131 length_16_button.add (*w);
132 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
134 length_32_button.add (*w);
135 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
137 length_64_button.add (*w);
141 act = ActionManager::get_action ("StepEditing/note-length-whole");
142 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
143 act = ActionManager::get_action ("StepEditing/note-length-half");
144 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
145 act = ActionManager::get_action ("StepEditing/note-length-quarter");
146 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
147 act = ActionManager::get_action ("StepEditing/note-length-eighth");
148 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
149 act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
150 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
151 act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
152 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
153 act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
154 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
156 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
157 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
158 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
159 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
160 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
161 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
162 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
163 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
164 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
165 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
166 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
167 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
168 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
169 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
171 length_1_button.property_draw_indicator() = false;
172 length_2_button.property_draw_indicator() = false;
173 length_4_button.property_draw_indicator() = false;
174 length_8_button.property_draw_indicator() = false;
175 length_16_button.property_draw_indicator() = false;
176 length_32_button.property_draw_indicator() = false;
177 length_64_button.property_draw_indicator() = false;
179 note_length_box.pack_start (length_1_button, false, false);
180 note_length_box.pack_start (length_2_button, false, false);
181 note_length_box.pack_start (length_4_button, false, false);
182 note_length_box.pack_start (length_8_button, false, false);
183 note_length_box.pack_start (length_16_button, false, false);
184 note_length_box.pack_start (length_32_button, false, false);
185 note_length_box.pack_start (length_64_button, false, false);
187 set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
188 set_tooltip (&length_2_button, _("Set note length to a half note"), "");
189 set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
190 set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
191 set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
192 set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
193 set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
195 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
196 velocity_pp_button.set_group (velocity_group);
197 velocity_p_button.set_group (velocity_group);
198 velocity_mp_button.set_group (velocity_group);
199 velocity_mf_button.set_group (velocity_group);
200 velocity_f_button.set_group (velocity_group);
201 velocity_ff_button.set_group (velocity_group);
202 velocity_fff_button.set_group (velocity_group);
204 w = manage (new Image (::get_icon (X_("pianississimo"))));
206 velocity_ppp_button.add (*w);
207 w = manage (new Image (::get_icon (X_("pianissimo"))));
209 velocity_pp_button.add (*w);
210 w = manage (new Image (::get_icon (X_("piano"))));
212 velocity_p_button.add (*w);
213 w = manage (new Image (::get_icon (X_("mezzopiano"))));
215 velocity_mp_button.add (*w);
216 w = manage (new Image (::get_icon (X_("mezzoforte"))));
218 velocity_mf_button.add (*w);
219 w = manage (new Image (::get_icon (X_("forte"))));
221 velocity_f_button.add (*w);
222 w = manage (new Image (::get_icon (X_("fortissimo"))));
224 velocity_ff_button.add (*w);
225 w = manage (new Image (::get_icon (X_("fortississimo"))));
227 velocity_fff_button.add (*w);
229 act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
230 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
231 act = ActionManager::get_action ("StepEditing/note-velocity-pp");
232 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
233 act = ActionManager::get_action ("StepEditing/note-velocity-p");
234 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
235 act = ActionManager::get_action ("StepEditing/note-velocity-mp");
236 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
237 act = ActionManager::get_action ("StepEditing/note-velocity-mf");
238 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
239 act = ActionManager::get_action ("StepEditing/note-velocity-f");
240 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
241 act = ActionManager::get_action ("StepEditing/note-velocity-ff");
242 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
243 act = ActionManager::get_action ("StepEditing/note-velocity-fff");
244 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
246 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
247 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
248 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
249 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
250 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
251 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
252 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
253 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
254 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
255 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
256 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
257 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
258 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
259 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
260 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
261 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
263 velocity_ppp_button.property_draw_indicator() = false;
264 velocity_pp_button.property_draw_indicator() = false;
265 velocity_p_button.property_draw_indicator() = false;
266 velocity_mp_button.property_draw_indicator() = false;
267 velocity_mf_button.property_draw_indicator() = false;
268 velocity_f_button.property_draw_indicator() = false;
269 velocity_ff_button.property_draw_indicator() = false;
270 velocity_fff_button.property_draw_indicator() = false;
272 set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
273 set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
274 set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
275 set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
276 set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
277 set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
278 set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
279 set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
281 note_velocity_box.pack_start (velocity_ppp_button, false, false);
282 note_velocity_box.pack_start (velocity_pp_button, false, false);
283 note_velocity_box.pack_start (velocity_p_button, false, false);
284 note_velocity_box.pack_start (velocity_mp_button, false, false);
285 note_velocity_box.pack_start (velocity_mf_button, false, false);
286 note_velocity_box.pack_start (velocity_f_button, false, false);
287 note_velocity_box.pack_start (velocity_ff_button, false, false);
288 note_velocity_box.pack_start (velocity_fff_button, false, false);
290 Label* l = manage (new Label);
291 l->set_markup ("<b><big>-</big></b>");
293 dot0_button.add (*l);
295 l = manage (new Label);
296 l->set_markup ("<b><big>.</big></b>");
298 dot1_button.add (*l);
300 l = manage (new Label);
301 l->set_markup ("<b><big>..</big></b>");
303 dot2_button.add (*l);
305 l = manage (new Label);
306 l->set_markup ("<b><big>...</big></b>");
308 dot3_button.add (*l);
310 w = manage (new Image (::get_icon (X_("chord"))));
312 chord_button.add (*w);
314 dot_box1.pack_start (dot0_button, true, false);
315 dot_box1.pack_start (dot1_button, true, false);
316 dot_box2.pack_start (dot2_button, true, false);
317 dot_box2.pack_start (dot3_button, true, false);
319 rest_box.pack_start (rest_button, true, false);
320 rest_box.pack_start (grid_rest_button, true, false);
321 rest_box.pack_start (back_button, true, false);
323 resync_box.pack_start (beat_resync_button, true, false);
324 resync_box.pack_start (bar_resync_button, true, false);
325 resync_box.pack_start (resync_button, true, false);
327 set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
328 set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
329 set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
330 set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
331 set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
332 set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
333 set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
334 set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
335 set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
336 set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
337 set_tooltip (&bank_button, _("Insert a bank change message"), "");
338 set_tooltip (&program_button, _("Insert a program change message"), "");
339 set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
340 set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
342 act = ActionManager::get_action ("StepEditing/back");
343 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
344 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
345 act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
346 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
347 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
348 act = ActionManager::get_action ("StepEditing/toggle-triplet");
349 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
350 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
351 act = ActionManager::get_action ("StepEditing/no-dotted");
352 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
353 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
354 act = ActionManager::get_action ("StepEditing/toggle-dotted");
355 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
356 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
357 act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
358 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
359 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
360 act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
361 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
362 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
363 act = ActionManager::get_action ("StepEditing/toggle-chord");
364 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
365 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
366 act = ActionManager::get_action ("StepEditing/insert-rest");
367 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
368 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
369 act = ActionManager::get_action ("StepEditing/insert-snap-rest");
370 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
371 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
372 act = ActionManager::get_action ("StepEditing/sustain");
373 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
374 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
376 upper_box.set_spacing (6);
377 upper_box.pack_start (chord_button, false, false);
378 upper_box.pack_start (note_length_box, false, false, 12);
379 upper_box.pack_start (triplet_button, false, false);
380 upper_box.pack_start (dot_box1, false, false);
381 upper_box.pack_start (dot_box2, false, false);
382 upper_box.pack_start (sustain_button, false, false);
383 upper_box.pack_start (rest_box, false, false);
384 upper_box.pack_start (resync_box, false, false);
385 upper_box.pack_start (note_velocity_box, false, false, 12);
389 v = manage (new VBox);
390 l = manage (new Label (_("Channel")));
392 v->pack_start (*l, false, false);
393 v->pack_start (channel_spinner, false, false);
394 upper_box.pack_start (*v, false, false);
396 v = manage (new VBox);
397 l = manage (new Label (_("1/Note")));
399 v->pack_start (*l, false, false);
400 v->pack_start (length_divisor_spinner, false, false);
401 upper_box.pack_start (*v, false, false);
403 v = manage (new VBox);
404 l = manage (new Label (_("Velocity")));
406 v->pack_start (*l, false, false);
407 v->pack_start (velocity_spinner, false, false);
408 upper_box.pack_start (*v, false, false);
410 v = manage (new VBox);
411 l = manage (new Label (_("Octave")));
413 v->pack_start (*l, false, false);
414 v->pack_start (octave_spinner, false, false);
415 upper_box.pack_start (*v, false, false);
417 v = manage (new VBox);
418 l = manage (new Label (_("Bank")));
420 v->pack_start (*l, false, false);
421 v->pack_start (bank_spinner, false, false);
422 v->pack_start (bank_button, false, false);
423 upper_box.pack_start (*v, false, false);
425 v = manage (new VBox);
426 l = manage (new Label (_("Program")));
428 v->pack_start (*l, false, false);
429 v->pack_start (program_spinner, false, false);
430 v->pack_start (program_button, false, false);
431 upper_box.pack_start (*v, false, false);
433 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
434 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
435 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
437 _piano = (PianoKeyboard*) piano_keyboard_new ();
438 piano = wrap ((GtkWidget*) _piano);
440 piano->set_flags (Gtk::CAN_FOCUS);
442 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
443 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
445 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
446 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
447 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
448 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
450 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
452 packer.set_spacing (6);
453 packer.pack_start (upper_box, false, false);
454 packer.pack_start (*piano, false, false);
459 /* initial settings: quarter note and mezzo forte */
461 ActionManager::get_radio_action ("StepEditing/note-length-quarter")->set_active (true);
462 ActionManager::get_radio_action ("StepEditing/note-velocity-mf")->set_active (true);
465 StepEntry::~StepEntry()
470 StepEntry::set_step_editor (StepEditor* seditor)
475 set_title (string_compose (_("Step Entry: %1"), se->name()));
477 /* set channel selector to first selected channel. if none
478 are selected, it will remain at the value set in its
479 constructor, above (1)
482 uint16_t chn_mask = se->channel_selector().get_selected_channels();
484 for (uint32_t i = 0; i < 16; ++i) {
485 if (chn_mask & (1<<i)) {
486 channel_adjustment.set_value (i+1);
499 StepEntry::length_changed ()
501 length_1_button.queue_draw ();
502 length_2_button.queue_draw ();
503 length_4_button.queue_draw ();
504 length_8_button.queue_draw ();
505 length_16_button.queue_draw ();
506 length_32_button.queue_draw ();
507 length_64_button.queue_draw ();
511 StepEntry::on_key_press_event (GdkEventKey* ev)
513 /* focus widget gets first shot, then bindings, otherwise
514 forward to main window
517 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
521 return relay_key_press (ev, this);
525 StepEntry::on_key_release_event (GdkEventKey* ev)
527 if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
531 /* don't forward releases */
537 StepEntry::rest_event_handler ()
540 se->step_edit_rest (Temporal::Beats());
545 StepEntry::note_length ()
547 double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
549 RefPtr<Action> act = ActionManager::get_action ("StepEditing/toggle-triplet");
550 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
551 bool triplets = tact->get_active ();
554 base_time *= (2.0/3.0);
557 double dots = dot_adjustment.get_value ();
560 dots = pow (2.0, dots);
561 base_time *= 1 + ((dots - 1.0)/dots);
564 return Temporal::Beats(base_time);
568 StepEntry::note_velocity () const
570 return velocity_adjustment.get_value();
574 StepEntry::note_channel() const
576 return channel_adjustment.get_value() - 1;
580 StepEntry::note_off_event_handler (int note)
587 StepEntry::on_show ()
589 ArdourWindow::on_show ();
590 //piano->grab_focus ();
594 StepEntry::beat_resync_click ()
597 se->step_edit_beat_sync ();
602 StepEntry::bar_resync_click ()
605 se->step_edit_bar_sync ();
610 StepEntry::register_actions ()
612 /* add named actions for the step editor */
614 Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (bindings, X_("StepEditing"));
616 ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::ptr_fun (&StepEntry::se_insert_a));
617 ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::ptr_fun (&StepEntry::se_insert_asharp));
618 ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::ptr_fun (&StepEntry::se_insert_b));
619 ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::ptr_fun (&StepEntry::se_insert_c));
620 ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::ptr_fun (&StepEntry::se_insert_csharp));
621 ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::ptr_fun (&StepEntry::se_insert_d));
622 ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::ptr_fun (&StepEntry::se_insert_dsharp));
623 ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::ptr_fun (&StepEntry::se_insert_e));
624 ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::ptr_fun (&StepEntry::se_insert_f));
625 ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::ptr_fun (&StepEntry::se_insert_fsharp));
626 ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::ptr_fun (&StepEntry::se_insert_g));
627 ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::ptr_fun (&StepEntry::se_insert_gsharp));
629 ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_rest));
630 ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::ptr_fun (&StepEntry::se_insert_grid_rest));
632 ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_next_octave));
633 ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::ptr_fun (&StepEntry::se_prev_octave));
635 ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::ptr_fun (&StepEntry::se_next_note_length));
636 ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::ptr_fun (&StepEntry::se_prev_note_length));
638 ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::ptr_fun (&StepEntry::se_inc_note_length));
639 ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::ptr_fun (&StepEntry::se_dec_note_length));
641 ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::ptr_fun (&StepEntry::se_next_note_velocity));
642 ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::ptr_fun (&StepEntry::se_prev_note_velocity));
644 ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::ptr_fun (&StepEntry::se_inc_note_velocity));
645 ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::ptr_fun (&StepEntry::se_dec_note_velocity));
647 ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::ptr_fun (&StepEntry::se_octave_0));
648 ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::ptr_fun (&StepEntry::se_octave_1));
649 ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::ptr_fun (&StepEntry::se_octave_2));
650 ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::ptr_fun (&StepEntry::se_octave_3));
651 ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::ptr_fun (&StepEntry::se_octave_4));
652 ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::ptr_fun (&StepEntry::se_octave_5));
653 ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::ptr_fun (&StepEntry::se_octave_6));
654 ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::ptr_fun (&StepEntry::se_octave_7));
655 ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::ptr_fun (&StepEntry::se_octave_8));
656 ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::ptr_fun (&StepEntry::se_octave_9));
657 ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::ptr_fun (&StepEntry::se_octave_10));
659 ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"), sigc::ptr_fun (&StepEntry::se_toggle_triplet));
661 ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"), sigc::ptr_fun (&StepEntry::se_toggle_chord));
662 ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"), sigc::ptr_fun (&StepEntry::se_do_sustain));
664 ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"), sigc::ptr_fun (&StepEntry::se_sync_to_edit_point));
665 ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"), sigc::ptr_fun (&StepEntry::se_back));
667 RadioAction::Group note_length_group;
669 ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
670 _("Set Note Length to Whole"), sigc::ptr_fun (&StepEntry::se_note_length_change), 1);
671 ActionManager::register_radio_action (group, note_length_group, "note-length-half",
672 _("Set Note Length to 1/2"), sigc::ptr_fun (&StepEntry::se_note_length_change), 2);
673 ActionManager::register_radio_action (group, note_length_group, "note-length-third",
674 _("Set Note Length to 1/3"), sigc::ptr_fun (&StepEntry::se_note_length_change), 3);
675 ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
676 _("Set Note Length to 1/4"), sigc::ptr_fun (&StepEntry::se_note_length_change), 4);
677 ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
678 _("Set Note Length to 1/8"), sigc::ptr_fun (&StepEntry::se_note_length_change), 8);
679 ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
680 _("Set Note Length to 1/16"), sigc::ptr_fun (&StepEntry::se_note_length_change), 16);
681 ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
682 _("Set Note Length to 1/32"), sigc::ptr_fun (&StepEntry::se_note_length_change), 32);
683 ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
684 _("Set Note Length to 1/64"), sigc::ptr_fun (&StepEntry::se_note_length_change), 64);
686 RadioAction::Group note_velocity_group;
688 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
689 _("Set Note Velocity to Pianississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 1);
690 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
691 _("Set Note Velocity to Pianissimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 16);
692 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
693 _("Set Note Velocity to Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 32);
694 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
695 _("Set Note Velocity to Mezzo-Piano"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 64);
696 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
697 _("Set Note Velocity to Mezzo-Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 80);
698 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
699 _("Set Note Velocity to Forte"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 96);
700 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
701 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 112);
702 ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
703 _("Set Note Velocity to Fortississimo"), sigc::ptr_fun (&StepEntry::se_note_velocity_change), 127);
706 RadioAction::Group dot_group;
708 ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 0);
709 ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 1);
710 ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 2);
711 ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::ptr_fun (&StepEntry::se_dot_change), 3);
715 StepEntry::setup_actions_and_bindings ()
722 StepEntry::load_bindings ()
724 bindings = Bindings::get_bindings (X_("Step Editing"));
728 StepEntry::toggle_triplet ()
731 se->set_step_edit_cursor_width (note_length());
736 StepEntry::toggle_chord ()
739 se->step_edit_toggle_chord ();
744 StepEntry::dot_change (GtkAction* act)
746 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
747 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
748 dot_adjustment.set_value (v);
753 StepEntry::dot_value_change ()
756 RefPtr<RadioAction> ract;
757 double val = dot_adjustment.get_value();
758 bool inconsistent = true;
759 vector<const char*> dot_actions;
761 dot_actions.push_back ("StepEditing/no-dotted");
762 dot_actions.push_back ("StepEditing/toggle-dotted");
763 dot_actions.push_back ("StepEditing/toggle-double-dotted");
764 dot_actions.push_back ("StepEditing/toggle-triple-dotted");
766 for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
768 act = ActionManager::get_action (*i);
771 ract = RefPtr<RadioAction>::cast_dynamic (act);
774 if (ract->property_value() == val) {
775 ract->set_active (true);
776 inconsistent = false;
783 dot1_button.set_inconsistent (inconsistent);
784 dot2_button.set_inconsistent (inconsistent);
785 dot3_button.set_inconsistent (inconsistent);
788 se->set_step_edit_cursor_width (note_length());
793 StepEntry::program_click ()
796 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
801 StepEntry::bank_click ()
804 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
809 StepEntry::insert_rest ()
812 se->step_edit_rest (note_length());
817 StepEntry::insert_grid_rest ()
820 se->step_edit_rest (Temporal::Beats());
825 StepEntry::insert_note (uint8_t note)
832 se->step_add_note (note_channel(), note, note_velocity(), note_length());
836 StepEntry::insert_c ()
838 insert_note (0 + (current_octave() * 12));
841 StepEntry::insert_csharp ()
843 insert_note (1 + (current_octave() * 12));
846 StepEntry::insert_d ()
848 insert_note (2 + (current_octave() * 12));
851 StepEntry::insert_dsharp ()
853 insert_note (3 + (current_octave() * 12));
856 StepEntry::insert_e ()
858 insert_note (4 + (current_octave() * 12));
861 StepEntry::insert_f ()
863 insert_note (5 + (current_octave() * 12));
866 StepEntry::insert_fsharp ()
868 insert_note (6 + (current_octave() * 12));
871 StepEntry::insert_g ()
873 insert_note (7 + (current_octave() * 12));
876 StepEntry::insert_gsharp ()
878 insert_note (8 + (current_octave() * 12));
882 StepEntry::insert_a ()
884 insert_note (9 + (current_octave() * 12));
888 StepEntry::insert_asharp ()
890 insert_note (10 + (current_octave() * 12));
893 StepEntry::insert_b ()
895 insert_note (11 + (current_octave() * 12));
899 StepEntry::note_length_change (GtkAction* act)
901 /* it doesn't matter which note length action we look up - we are interested
902 in the current_value which is global across the whole group of note length
903 actions. this method is called twice for every user operation,
904 once for the action that became "inactive" and once for the action that
905 becaome "active". so ... only bother to actually change the value when this
906 is called for the "active" action.
909 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
910 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
911 length_divisor_adjustment.set_value (v);
916 StepEntry::note_velocity_change (GtkAction* act)
918 /* it doesn't matter which note velocity action we look up - we are interested
919 in the current_value which is global across the whole group of note velocity
920 actions. this method is called twice for every user operation,
921 once for the action that became "inactive" and once for the action that
922 becaome "active". so ... only bother to actually change the value when this
923 is called for the "active" action.
926 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
927 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
928 velocity_adjustment.set_value (v);
933 StepEntry::velocity_value_change ()
936 RefPtr<RadioAction> ract;
937 double val = velocity_adjustment.get_value();
938 bool inconsistent = true;
939 vector<const char*> velocity_actions;
941 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
942 velocity_actions.push_back ("StepEditing/note-velocity-pp");
943 velocity_actions.push_back ("StepEditing/note-velocity-p");
944 velocity_actions.push_back ("StepEditing/note-velocity-mp");
945 velocity_actions.push_back ("StepEditing/note-velocity-mf");
946 velocity_actions.push_back ("StepEditing/note-velocity-f");
947 velocity_actions.push_back ("StepEditing/note-velocity-ff");
948 velocity_actions.push_back ("StepEditing/note-velocity-fff");
950 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
952 act = ActionManager::get_action (*i);
955 ract = RefPtr<RadioAction>::cast_dynamic (act);
958 if (ract->property_value() == val) {
959 ract->set_active (true);
960 inconsistent = false;
967 velocity_ppp_button.set_inconsistent (inconsistent);
968 velocity_pp_button.set_inconsistent (inconsistent);
969 velocity_p_button.set_inconsistent (inconsistent);
970 velocity_mp_button.set_inconsistent (inconsistent);
971 velocity_mf_button.set_inconsistent (inconsistent);
972 velocity_f_button.set_inconsistent (inconsistent);
973 velocity_ff_button.set_inconsistent (inconsistent);
974 velocity_fff_button.set_inconsistent (inconsistent);
978 StepEntry::length_value_change ()
981 RefPtr<RadioAction> ract;
982 bool inconsistent = true;
983 vector<const char*> length_actions;
985 length_actions.push_back ("StepEditing/note-length-whole");
986 length_actions.push_back ("StepEditing/note-length-half");
987 length_actions.push_back ("StepEditing/note-length-quarter");
988 length_actions.push_back ("StepEditing/note-length-eighth");
989 length_actions.push_back ("StepEditing/note-length-sixteenth");
990 length_actions.push_back ("StepEditing/note-length-thirtysecond");
991 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
993 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
995 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
997 ract->set_active (true);
998 inconsistent = false;
1002 length_1_button.set_inconsistent (inconsistent);
1003 length_2_button.set_inconsistent (inconsistent);
1004 length_4_button.set_inconsistent (inconsistent);
1005 length_8_button.set_inconsistent (inconsistent);
1006 length_16_button.set_inconsistent (inconsistent);
1007 length_32_button.set_inconsistent (inconsistent);
1008 length_64_button.set_inconsistent (inconsistent);
1011 se->set_step_edit_cursor_width (note_length());
1016 StepEntry::radio_button_press (GdkEventButton* ev)
1018 if (ev->button == 1) {
1026 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
1028 if (ev->button == 1) {
1029 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
1032 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1042 StepEntry::next_octave ()
1044 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1048 StepEntry::prev_octave ()
1050 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1054 StepEntry::inc_note_length ()
1056 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1060 StepEntry::dec_note_length ()
1062 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1066 StepEntry::prev_note_length ()
1068 double l = length_divisor_adjustment.get_value();
1069 int il = (int) lrintf (l); // round to nearest integer
1070 il = (il/2) * 2; // round to power of 2
1078 length_divisor_adjustment.set_value (il);
1082 StepEntry::next_note_length ()
1084 double l = length_divisor_adjustment.get_value();
1085 int il = (int) lrintf (l); // round to nearest integer
1086 il = (il/2) * 2; // round to power of 2
1095 length_divisor_adjustment.set_value (il);
1100 StepEntry::inc_note_velocity ()
1102 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1106 StepEntry::dec_note_velocity ()
1108 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1112 StepEntry::next_note_velocity ()
1114 double l = velocity_adjustment.get_value ();
1118 } else if (l < 32) {
1120 } else if (l < 48) {
1122 } else if (l < 64) {
1124 } else if (l < 80) {
1126 } else if (l < 96) {
1128 } else if (l < 112) {
1130 } else if (l < 127) {
1134 velocity_adjustment.set_value (l);
1138 StepEntry::prev_note_velocity ()
1140 double l = velocity_adjustment.get_value ();
1144 } else if (l > 96) {
1146 } else if (l > 80) {
1148 } else if (l > 64) {
1150 } else if (l > 48) {
1152 } else if (l > 32) {
1154 } else if (l > 16) {
1160 velocity_adjustment.set_value (l);
1164 StepEntry::octave_n (int n)
1166 octave_adjustment.set_value (n);
1170 StepEntry::do_sustain ()
1173 se->step_edit_sustain (note_length());
1181 se->move_step_edit_beat_pos (-note_length());
1186 StepEntry::sync_to_edit_point ()
1189 se->resync_step_edit_to_edit_point ();