Add a couple of missing attach_buffers() calls after _ports has been changed. I...
[ardour2.git] / gtk2_ardour / step_entry.cc
blob8c26e1d20ee98c4ea35f4665c6b5164a0c1e1341
1 /*
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.
20 #include <iostream>
22 #include "pbd/filesystem.h"
23 #include "pbd/file_utils.h"
25 #include "gtkmm2ext/keyboard.h"
26 #include "gtkmm2ext/actions.h"
27 #include "gtkmm2ext/bindings.h"
29 #include "ardour/filesystem_paths.h"
31 #include "ardour_ui.h"
32 #include "midi_channel_selector.h"
33 #include "midi_time_axis.h"
34 #include "step_editor.h"
35 #include "step_entry.h"
36 #include "utils.h"
38 #include "i18n.h"
40 using namespace std;
41 using namespace Gtk;
42 using namespace Glib;
43 using namespace Gtkmm2ext;
44 using namespace PBD;
45 using namespace ARDOUR;
47 static void
48 _note_off_event_handler (GtkWidget* /*widget*/, int note, gpointer arg)
50 ((StepEntry*)arg)->note_off_event_handler (note);
53 static void
54 _rest_event_handler (GtkWidget* /*widget*/, gpointer arg)
56 ((StepEntry*)arg)->rest_event_handler ();
59 StepEntry::StepEntry (StepEditor& seditor)
60 : ArdourDialog (string_compose (_("Step Entry: %1"), seditor.name()))
61 , _current_note_length (1.0)
62 , _current_note_velocity (64)
63 , triplet_button ("3")
64 , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
65 , beat_resync_button (_(">beat"))
66 , bar_resync_button (_(">bar"))
67 , resync_button (_(">EP"))
68 , sustain_button (_("sustain"))
69 , rest_button (_("rest"))
70 , grid_rest_button (_("g-rest"))
71 , back_button (_("back"))
72 , channel_adjustment (1, 1, 16, 1, 4)
73 , channel_spinner (channel_adjustment)
74 , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
75 , octave_spinner (octave_adjustment)
76 , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
77 , length_divisor_spinner (length_divisor_adjustment)
78 , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
79 , velocity_spinner (velocity_adjustment)
80 , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
81 , bank_spinner (bank_adjustment)
82 , bank_button (_("+"))
83 , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
84 , program_spinner (program_adjustment)
85 , program_button (_("+"))
86 , _piano (0)
87 , piano (0)
88 , se (&seditor)
90 register_actions ();
91 load_bindings ();
93 #if 0
94 /* set channel selector to first selected channel. if none
95 are selected, it will remain at the value set in its
96 constructor, above (1)
99 uint16_t chn_mask = se->channel_selector().get_selected_channels();
101 for (uint32_t i = 0; i < 16; ++i) {
102 if (chn_mask & (1<<i)) {
103 channel_adjustment.set_value (i+1);
104 break;
108 #endif
110 RadioButtonGroup length_group = length_1_button.get_group();
111 length_2_button.set_group (length_group);
112 length_4_button.set_group (length_group);
113 length_8_button.set_group (length_group);
114 length_12_button.set_group (length_group);
115 length_16_button.set_group (length_group);
116 length_32_button.set_group (length_group);
117 length_64_button.set_group (length_group);
119 Widget* w;
121 w = manage (new Image (::get_icon (X_("wholenote"))));
122 w->show();
123 length_1_button.add (*w);
124 w = manage (new Image (::get_icon (X_("halfnote"))));
125 w->show();
126 length_2_button.add (*w);
127 w = manage (new Image (::get_icon (X_("quarternote"))));
128 w->show();
129 length_4_button.add (*w);
130 w = manage (new Image (::get_icon (X_("eighthnote"))));
131 w->show();
132 length_8_button.add (*w);
133 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
134 w->show();
135 length_16_button.add (*w);
136 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
137 w->show();
138 length_32_button.add (*w);
139 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
140 w->show();
141 length_64_button.add (*w);
143 RefPtr<Action> act;
145 act = myactions.find_action ("StepEditing/note-length-whole");
146 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
147 act = myactions.find_action ("StepEditing/note-length-half");
148 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
149 act = myactions.find_action ("StepEditing/note-length-quarter");
150 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
151 act = myactions.find_action ("StepEditing/note-length-eighth");
152 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
153 act = myactions.find_action ("StepEditing/note-length-sixteenth");
154 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
155 act = myactions.find_action ("StepEditing/note-length-thirtysecond");
156 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
157 act = myactions.find_action ("StepEditing/note-length-sixtyfourth");
158 gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
160 length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
161 length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
162 length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
163 length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
164 length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
165 length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
166 length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
167 length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
168 length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
169 length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
170 length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
171 length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
172 length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
173 length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
175 length_1_button.property_draw_indicator() = false;
176 length_2_button.property_draw_indicator() = false;
177 length_4_button.property_draw_indicator() = false;
178 length_8_button.property_draw_indicator() = false;
179 length_16_button.property_draw_indicator() = false;
180 length_32_button.property_draw_indicator() = false;
181 length_64_button.property_draw_indicator() = false;
183 note_length_box.pack_start (length_1_button, false, false);
184 note_length_box.pack_start (length_2_button, false, false);
185 note_length_box.pack_start (length_4_button, false, false);
186 note_length_box.pack_start (length_8_button, false, false);
187 note_length_box.pack_start (length_16_button, false, false);
188 note_length_box.pack_start (length_32_button, false, false);
189 note_length_box.pack_start (length_64_button, false, false);
191 ARDOUR_UI::instance()->set_tip (&length_1_button, _("Set note length to a whole note"), "");
192 ARDOUR_UI::instance()->set_tip (&length_2_button, _("Set note length to a half note"), "");
193 ARDOUR_UI::instance()->set_tip (&length_4_button, _("Set note length to a quarter note"), "");
194 ARDOUR_UI::instance()->set_tip (&length_8_button, _("Set note length to a eighth note"), "");
195 ARDOUR_UI::instance()->set_tip (&length_16_button, _("Set note length to a sixteenth note"), "");
196 ARDOUR_UI::instance()->set_tip (&length_32_button, _("Set note length to a thirty-second note"), "");
197 ARDOUR_UI::instance()->set_tip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
199 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
200 velocity_pp_button.set_group (velocity_group);
201 velocity_p_button.set_group (velocity_group);
202 velocity_mp_button.set_group (velocity_group);
203 velocity_mf_button.set_group (velocity_group);
204 velocity_f_button.set_group (velocity_group);
205 velocity_ff_button.set_group (velocity_group);
206 velocity_fff_button.set_group (velocity_group);
208 w = manage (new Image (::get_icon (X_("pianississimo"))));
209 w->show();
210 velocity_ppp_button.add (*w);
211 w = manage (new Image (::get_icon (X_("pianissimo"))));
212 w->show();
213 velocity_pp_button.add (*w);
214 w = manage (new Image (::get_icon (X_("piano"))));
215 w->show();
216 velocity_p_button.add (*w);
217 w = manage (new Image (::get_icon (X_("mezzopiano"))));
218 w->show();
219 velocity_mp_button.add (*w);
220 w = manage (new Image (::get_icon (X_("mezzoforte"))));
221 w->show();
222 velocity_mf_button.add (*w);
223 w = manage (new Image (::get_icon (X_("forte"))));
224 w->show();
225 velocity_f_button.add (*w);
226 w = manage (new Image (::get_icon (X_("fortissimo"))));
227 w->show();
228 velocity_ff_button.add (*w);
229 w = manage (new Image (::get_icon (X_("fortississimo"))));
230 w->show();
231 velocity_fff_button.add (*w);
233 act = myactions.find_action ("StepEditing/note-velocity-ppp");
234 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
235 act = myactions.find_action ("StepEditing/note-velocity-pp");
236 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
237 act = myactions.find_action ("StepEditing/note-velocity-p");
238 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
239 act = myactions.find_action ("StepEditing/note-velocity-mp");
240 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
241 act = myactions.find_action ("StepEditing/note-velocity-mf");
242 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
243 act = myactions.find_action ("StepEditing/note-velocity-f");
244 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
245 act = myactions.find_action ("StepEditing/note-velocity-ff");
246 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
247 act = myactions.find_action ("StepEditing/note-velocity-fff");
248 gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
250 velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
251 velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
252 velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
253 velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
254 velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
255 velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
256 velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
257 velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
258 velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
259 velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
260 velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
261 velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
262 velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
263 velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
264 velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
265 velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
267 velocity_ppp_button.property_draw_indicator() = false;
268 velocity_pp_button.property_draw_indicator() = false;
269 velocity_p_button.property_draw_indicator() = false;
270 velocity_mp_button.property_draw_indicator() = false;
271 velocity_mf_button.property_draw_indicator() = false;
272 velocity_f_button.property_draw_indicator() = false;
273 velocity_ff_button.property_draw_indicator() = false;
274 velocity_fff_button.property_draw_indicator() = false;
276 ARDOUR_UI::instance()->set_tip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
277 ARDOUR_UI::instance()->set_tip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
278 ARDOUR_UI::instance()->set_tip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
279 ARDOUR_UI::instance()->set_tip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
280 ARDOUR_UI::instance()->set_tip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
281 ARDOUR_UI::instance()->set_tip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
282 ARDOUR_UI::instance()->set_tip (&velocity_ff_button, _("Set volume (velocity) to forteissimo"), "");
283 ARDOUR_UI::instance()->set_tip (&velocity_fff_button, _("Set volume (velocity) to forteississimo"), "");
285 note_velocity_box.pack_start (velocity_ppp_button, false, false);
286 note_velocity_box.pack_start (velocity_pp_button, false, false);
287 note_velocity_box.pack_start (velocity_p_button, false, false);
288 note_velocity_box.pack_start (velocity_mp_button, false, false);
289 note_velocity_box.pack_start (velocity_mf_button, false, false);
290 note_velocity_box.pack_start (velocity_f_button, false, false);
291 note_velocity_box.pack_start (velocity_ff_button, false, false);
292 note_velocity_box.pack_start (velocity_fff_button, false, false);
294 Label* l = manage (new Label);
295 l->set_markup ("<b><big>-</big></b>");
296 l->show ();
297 dot0_button.add (*l);
299 l = manage (new Label);
300 l->set_markup ("<b><big>.</big></b>");
301 l->show ();
302 dot1_button.add (*l);
304 l = manage (new Label);
305 l->set_markup ("<b><big>..</big></b>");
306 l->show ();
307 dot2_button.add (*l);
309 l = manage (new Label);
310 l->set_markup ("<b><big>...</big></b>");
311 l->show ();
312 dot3_button.add (*l);
314 w = manage (new Image (::get_icon (X_("chord"))));
315 w->show();
316 chord_button.add (*w);
318 dot_box1.pack_start (dot0_button, true, false);
319 dot_box1.pack_start (dot1_button, true, false);
320 dot_box2.pack_start (dot2_button, true, false);
321 dot_box2.pack_start (dot3_button, true, false);
323 rest_box.pack_start (rest_button, true, false);
324 rest_box.pack_start (grid_rest_button, true, false);
325 rest_box.pack_start (back_button, true, false);
327 resync_box.pack_start (beat_resync_button, true, false);
328 resync_box.pack_start (bar_resync_button, true, false);
329 resync_box.pack_start (resync_button, true, false);
331 ARDOUR_UI::instance()->set_tip (&chord_button, _("Stack inserted notes to form a chord"), "");
332 ARDOUR_UI::instance()->set_tip (&sustain_button, _("Extend selected notes by note length"), "");
333 ARDOUR_UI::instance()->set_tip (&dot0_button, _("Use undotted note lengths"), "");
334 ARDOUR_UI::instance()->set_tip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
335 ARDOUR_UI::instance()->set_tip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
336 ARDOUR_UI::instance()->set_tip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
337 ARDOUR_UI::instance()->set_tip (&rest_button, _("Insert a note-length's rest"), "");
338 ARDOUR_UI::instance()->set_tip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
339 ARDOUR_UI::instance()->set_tip (&beat_resync_button, _("Insert a rest until the next beat"), "");
340 ARDOUR_UI::instance()->set_tip (&bar_resync_button, _("Insert a rest until the next bar"), "");
341 ARDOUR_UI::instance()->set_tip (&bank_button, _("Insert a bank change message"), "");
342 ARDOUR_UI::instance()->set_tip (&program_button, _("Insert a program change message"), "");
343 ARDOUR_UI::instance()->set_tip (&back_button, _("Move Insert Position Back by Note Length"), "");
344 ARDOUR_UI::instance()->set_tip (&resync_button, _("Move Insert Position to Edit Point"), "");
346 act = myactions.find_action ("StepEditing/back");
347 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
348 gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
349 act = myactions.find_action ("StepEditing/sync-to-edit-point");
350 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
351 gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
352 act = myactions.find_action ("StepEditing/toggle-triplet");
353 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
354 gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
355 act = myactions.find_action ("StepEditing/no-dotted");
356 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
357 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
358 act = myactions.find_action ("StepEditing/toggle-dotted");
359 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
360 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
361 act = myactions.find_action ("StepEditing/toggle-double-dotted");
362 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
363 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
364 act = myactions.find_action ("StepEditing/toggle-triple-dotted");
365 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
366 gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
367 act = myactions.find_action ("StepEditing/toggle-chord");
368 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
369 gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
370 act = myactions.find_action ("StepEditing/insert-rest");
371 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
372 gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
373 act = myactions.find_action ("StepEditing/insert-snap-rest");
374 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
375 gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
376 act = myactions.find_action ("StepEditing/sustain");
377 gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
378 gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
380 upper_box.set_spacing (6);
381 upper_box.pack_start (chord_button, false, false);
382 upper_box.pack_start (note_length_box, false, false, 12);
383 upper_box.pack_start (triplet_button, false, false);
384 upper_box.pack_start (dot_box1, false, false);
385 upper_box.pack_start (dot_box2, false, false);
386 upper_box.pack_start (sustain_button, false, false);
387 upper_box.pack_start (rest_box, false, false);
388 upper_box.pack_start (resync_box, false, false);
389 upper_box.pack_start (note_velocity_box, false, false, 12);
391 VBox* v;
393 v = manage (new VBox);
394 l = manage (new Label (_("Channel")));
395 v->set_spacing (6);
396 v->pack_start (*l, false, false);
397 v->pack_start (channel_spinner, false, false);
398 upper_box.pack_start (*v, false, false);
400 v = manage (new VBox);
401 l = manage (new Label (_("1/Note")));
402 v->set_spacing (6);
403 v->pack_start (*l, false, false);
404 v->pack_start (length_divisor_spinner, false, false);
405 upper_box.pack_start (*v, false, false);
407 v = manage (new VBox);
408 l = manage (new Label (_("Velocity")));
409 v->set_spacing (6);
410 v->pack_start (*l, false, false);
411 v->pack_start (velocity_spinner, false, false);
412 upper_box.pack_start (*v, false, false);
414 v = manage (new VBox);
415 l = manage (new Label (_("Octave")));
416 v->set_spacing (6);
417 v->pack_start (*l, false, false);
418 v->pack_start (octave_spinner, false, false);
419 upper_box.pack_start (*v, false, false);
421 v = manage (new VBox);
422 l = manage (new Label (_("Bank")));
423 v->set_spacing (6);
424 v->pack_start (*l, false, false);
425 v->pack_start (bank_spinner, false, false);
426 v->pack_start (bank_button, false, false);
427 upper_box.pack_start (*v, false, false);
429 v = manage (new VBox);
430 l = manage (new Label (_("Program")));
431 v->set_spacing (6);
432 v->pack_start (*l, false, false);
433 v->pack_start (program_spinner, false, false);
434 v->pack_start (program_button, false, false);
435 upper_box.pack_start (*v, false, false);
437 velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
438 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
439 dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
441 _piano = (PianoKeyboard*) piano_keyboard_new ();
442 piano = wrap ((GtkWidget*) _piano);
444 piano->set_flags (Gtk::CAN_FOCUS);
446 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
447 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
449 program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
450 bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
451 beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
452 bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
454 length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
456 packer.set_spacing (6);
457 packer.pack_start (upper_box, false, false);
458 packer.pack_start (*piano, false, false);
459 packer.show_all ();
461 get_vbox()->add (packer);
463 /* initial settings: quarter note and mezzo forte */
465 act = myactions.find_action ("StepEditing/note-length-quarter");
466 RefPtr<RadioAction> r = RefPtr<RadioAction>::cast_dynamic (act);
467 assert (r);
468 r->set_active (true);
470 act = myactions.find_action ("StepEditing/note-velocity-mf");
471 r = RefPtr<RadioAction>::cast_dynamic (act);
472 assert (r);
473 r->set_active (true);
476 StepEntry::~StepEntry()
480 void
481 StepEntry::length_changed ()
483 length_1_button.queue_draw ();
484 length_2_button.queue_draw ();
485 length_4_button.queue_draw ();
486 length_8_button.queue_draw ();
487 length_16_button.queue_draw ();
488 length_32_button.queue_draw ();
489 length_64_button.queue_draw ();
492 bool
493 StepEntry::on_key_press_event (GdkEventKey* ev)
495 /* focus widget gets first shot, then bindings, otherwise
496 forward to main window
499 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
500 KeyboardKey k (ev->state, ev->keyval);
502 if (bindings.activate (k, Bindings::Press)) {
503 return true;
507 return forward_key_press (ev);
510 bool
511 StepEntry::on_key_release_event (GdkEventKey* ev)
513 if (!gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
514 KeyboardKey k (ev->state, ev->keyval);
516 if (bindings.activate (k, Bindings::Release)) {
517 return true;
521 /* don't forward releases */
523 return true;
526 void
527 StepEntry::rest_event_handler ()
529 se->step_edit_rest (0.0);
532 Evoral::MusicalTime
533 StepEntry::note_length ()
535 Evoral::MusicalTime base_time = 4.0 / (Evoral::MusicalTime) length_divisor_adjustment.get_value();
537 RefPtr<Action> act = myactions.find_action ("StepEditing/toggle-triplet");
538 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
539 bool triplets = tact->get_active ();
541 if (triplets) {
542 base_time *= (2.0/3.0);
545 double dots = dot_adjustment.get_value ();
547 if (dots > 0) {
548 dots = pow (2.0, dots);
549 base_time *= 1 + ((dots - 1.0)/dots);
552 return base_time;
555 uint8_t
556 StepEntry::note_velocity () const
558 return (Evoral::MusicalTime) velocity_adjustment.get_value();
561 uint8_t
562 StepEntry::note_channel() const
564 return channel_adjustment.get_value() - 1;
567 void
568 StepEntry::note_off_event_handler (int note)
570 insert_note (note);
574 void
575 StepEntry::on_show ()
577 ArdourDialog::on_show ();
578 //piano->grab_focus ();
581 void
582 StepEntry::beat_resync_click ()
584 se->step_edit_beat_sync ();
587 void
588 StepEntry::bar_resync_click ()
590 se->step_edit_bar_sync ();
593 void
594 StepEntry::register_actions ()
596 /* add named actions for the editor */
598 myactions.register_action ("StepEditing", "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
599 myactions.register_action ("StepEditing", "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
600 myactions.register_action ("StepEditing", "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
601 myactions.register_action ("StepEditing", "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
602 myactions.register_action ("StepEditing", "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
603 myactions.register_action ("StepEditing", "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
604 myactions.register_action ("StepEditing", "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
605 myactions.register_action ("StepEditing", "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
606 myactions.register_action ("StepEditing", "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
607 myactions.register_action ("StepEditing", "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
608 myactions.register_action ("StepEditing", "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
609 myactions.register_action ("StepEditing", "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
611 myactions.register_action ("StepEditing", "insert-rest", _("Insert a Note-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_rest));
612 myactions.register_action ("StepEditing", "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_grid_rest));
614 myactions.register_action ("StepEditing", "next-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::next_octave));
615 myactions.register_action ("StepEditing", "prev-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::prev_octave));
617 myactions.register_action ("StepEditing", "next-note-length", _("Move to Next Note Length"), sigc::mem_fun (*this, &StepEntry::next_note_length));
618 myactions.register_action ("StepEditing", "prev-note-length", _("Move to Previous Note Length"), sigc::mem_fun (*this, &StepEntry::prev_note_length));
620 myactions.register_action ("StepEditing", "inc-note-length", _("Increase Note Length"), sigc::mem_fun (*this, &StepEntry::inc_note_length));
621 myactions.register_action ("StepEditing", "dec-note-length", _("Decrease Note Length"), sigc::mem_fun (*this, &StepEntry::dec_note_length));
623 myactions.register_action ("StepEditing", "next-note-velocity", _("Move to Next Note Velocity"), sigc::mem_fun (*this, &StepEntry::next_note_velocity));
624 myactions.register_action ("StepEditing", "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::mem_fun (*this, &StepEntry::prev_note_velocity));
626 myactions.register_action ("StepEditing", "inc-note-velocity", _("Increase Note Velocity"), sigc::mem_fun (*this, &StepEntry::inc_note_velocity));
627 myactions.register_action ("StepEditing", "dec-note-velocity", _("Decrease Note Velocity"), sigc::mem_fun (*this, &StepEntry::dec_note_velocity));
629 myactions.register_action ("StepEditing", "octave-0", _("Switch to the 1st octave"), sigc::mem_fun (*this, &StepEntry::octave_0));
630 myactions.register_action ("StepEditing", "octave-1", _("Switch to the 2nd octave"), sigc::mem_fun (*this, &StepEntry::octave_1));
631 myactions.register_action ("StepEditing", "octave-2", _("Switch to the 3rd octave"), sigc::mem_fun (*this, &StepEntry::octave_2));
632 myactions.register_action ("StepEditing", "octave-3", _("Switch to the 4th octave"), sigc::mem_fun (*this, &StepEntry::octave_3));
633 myactions.register_action ("StepEditing", "octave-4", _("Switch to the 5th octave"), sigc::mem_fun (*this, &StepEntry::octave_4));
634 myactions.register_action ("StepEditing", "octave-5", _("Switch to the 6th octave"), sigc::mem_fun (*this, &StepEntry::octave_5));
635 myactions.register_action ("StepEditing", "octave-6", _("Switch to the 7th octave"), sigc::mem_fun (*this, &StepEntry::octave_6));
636 myactions.register_action ("StepEditing", "octave-7", _("Switch to the 8th octave"), sigc::mem_fun (*this, &StepEntry::octave_7));
637 myactions.register_action ("StepEditing", "octave-8", _("Switch to the 9th octave"), sigc::mem_fun (*this, &StepEntry::octave_8));
638 myactions.register_action ("StepEditing", "octave-9", _("Switch to the 10th octave"), sigc::mem_fun (*this, &StepEntry::octave_9));
639 myactions.register_action ("StepEditing", "octave-10", _("Switch to the 11th octave"), sigc::mem_fun (*this, &StepEntry::octave_10));
641 RadioAction::Group note_length_group;
643 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-whole",
644 _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
645 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-half",
646 _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
647 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-third",
648 _("Set Note Length to 1/3"), sigc::mem_fun (*this, &StepEntry::note_length_change), 3);
649 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-quarter",
650 _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
651 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-eighth",
652 _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
653 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixteenth",
654 _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
655 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-thirtysecond",
656 _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
657 myactions.register_radio_action ("StepEditing", note_length_group, "note-length-sixtyfourth",
658 _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
660 RadioAction::Group note_velocity_group;
662 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ppp",
663 _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
664 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-pp",
665 _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
666 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-p",
667 _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
668 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mp",
669 _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
670 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-mf",
671 _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
672 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-f",
673 _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
674 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-ff",
675 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
676 myactions.register_radio_action ("StepEditing", note_velocity_group, "note-velocity-fff",
677 _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
679 myactions.register_toggle_action ("StepEditing", "toggle-triplet", _("Toggle Triple Notes"),
680 sigc::mem_fun (*this, &StepEntry::toggle_triplet));
682 RadioAction::Group dot_group;
684 myactions.register_radio_action ("StepEditing", dot_group, "no-dotted", _("No Dotted Notes"),
685 sigc::mem_fun (*this, &StepEntry::dot_change), 0);
686 myactions.register_radio_action ("StepEditing", dot_group, "toggle-dotted", _("Toggled Dotted Notes"),
687 sigc::mem_fun (*this, &StepEntry::dot_change), 1);
688 myactions.register_radio_action ("StepEditing", dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"),
689 sigc::mem_fun (*this, &StepEntry::dot_change), 2);
690 myactions.register_radio_action ("StepEditing", dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"),
691 sigc::mem_fun (*this, &StepEntry::dot_change), 3);
693 myactions.register_toggle_action ("StepEditing", "toggle-chord", _("Toggle Chord Entry"),
694 sigc::mem_fun (*this, &StepEntry::toggle_chord));
695 myactions.register_action ("StepEditing", "sustain", _("Sustain Selected Notes by Note Length"),
696 sigc::mem_fun (*this, &StepEntry::do_sustain));
698 myactions.register_action ("StepEditing", "sync-to-edit-point", _("Move Insert Position to Edit Point"),
699 sigc::mem_fun (*this, &StepEntry::sync_to_edit_point));
700 myactions.register_action ("StepEditing", "back", _("Move Insert Position Back by Note Length"),
701 sigc::mem_fun (*this, &StepEntry::back));
704 void
705 StepEntry::load_bindings ()
707 /* XXX move this to a better place */
709 bindings.set_action_map (myactions);
711 sys::path binding_file;
712 SearchPath spath = ardour_search_path() + user_config_directory() + system_config_search_path();
714 if (find_file_in_search_path (spath, "step_editing.bindings", binding_file)) {
715 bindings.load (binding_file.to_string());
719 void
720 StepEntry::toggle_triplet ()
722 se->set_step_edit_cursor_width (note_length());
725 void
726 StepEntry::toggle_chord ()
728 se->step_edit_toggle_chord ();
731 void
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);
740 void
741 StepEntry::dot_value_change ()
743 RefPtr<Action> act;
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 = myactions.find_action (*i);
758 if (act) {
759 ract = RefPtr<RadioAction>::cast_dynamic (act);
761 if (ract) {
762 if (ract->property_value() == val) {
763 ract->set_active (true);
764 inconsistent = false;
765 break;
771 dot1_button.set_inconsistent (inconsistent);
772 dot2_button.set_inconsistent (inconsistent);
773 dot3_button.set_inconsistent (inconsistent);
775 se->set_step_edit_cursor_width (note_length());
778 void
779 StepEntry::program_click ()
781 se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
784 void
785 StepEntry::bank_click ()
787 se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
790 void
791 StepEntry::insert_rest ()
793 se->step_edit_rest (note_length());
796 void
797 StepEntry::insert_grid_rest ()
799 se->step_edit_rest (0.0);
802 void
803 StepEntry::insert_note (uint8_t note)
805 if (note > 127) {
806 return;
809 se->step_add_note (note_channel(), note, note_velocity(), note_length());
811 void
812 StepEntry::insert_c ()
814 insert_note (0 + (current_octave() * 12));
816 void
817 StepEntry::insert_csharp ()
819 insert_note (1 + (current_octave() * 12));
821 void
822 StepEntry::insert_d ()
824 insert_note (2 + (current_octave() * 12));
826 void
827 StepEntry::insert_dsharp ()
829 insert_note (3 + (current_octave() * 12));
831 void
832 StepEntry::insert_e ()
834 insert_note (4 + (current_octave() * 12));
836 void
837 StepEntry::insert_f ()
839 insert_note (5 + (current_octave() * 12));
841 void
842 StepEntry::insert_fsharp ()
844 insert_note (6 + (current_octave() * 12));
846 void
847 StepEntry::insert_g ()
849 insert_note (7 + (current_octave() * 12));
851 void
852 StepEntry::insert_gsharp ()
854 insert_note (8 + (current_octave() * 12));
857 void
858 StepEntry::insert_a ()
860 insert_note (9 + (current_octave() * 12));
863 void
864 StepEntry::insert_asharp ()
866 insert_note (10 + (current_octave() * 12));
868 void
869 StepEntry::insert_b ()
871 insert_note (11 + (current_octave() * 12));
874 void
875 StepEntry::note_length_change (GtkAction* act)
877 /* it doesn't matter which note length action we look up - we are interested
878 in the current_value which is global across the whole group of note length
879 actions. this method is called twice for every user operation,
880 once for the action that became "inactive" and once for the action that
881 becaome "active". so ... only bother to actually change the value when this
882 is called for the "active" action.
885 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
886 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
887 length_divisor_adjustment.set_value (v);
891 void
892 StepEntry::note_velocity_change (GtkAction* act)
894 /* it doesn't matter which note length action we look up - we are interested
895 in the current_value which is global across the whole group of note length
896 actions. this method is called twice for every user operation,
897 once for the action that became "inactive" and once for the action that
898 becaome "active". so ... only bother to actually change the value when this
899 is called for the "active" action.
902 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
903 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
904 velocity_adjustment.set_value (v);
908 void
909 StepEntry::velocity_value_change ()
911 RefPtr<Action> act;
912 RefPtr<RadioAction> ract;
913 double val = velocity_adjustment.get_value();
914 bool inconsistent = true;
915 vector<const char*> velocity_actions;
917 velocity_actions.push_back ("StepEditing/note-velocity-ppp");
918 velocity_actions.push_back ("StepEditing/note-velocity-pp");
919 velocity_actions.push_back ("StepEditing/note-velocity-p");
920 velocity_actions.push_back ("StepEditing/note-velocity-mp");
921 velocity_actions.push_back ("StepEditing/note-velocity-mf");
922 velocity_actions.push_back ("StepEditing/note-velocity-f");
923 velocity_actions.push_back ("StepEditing/note-velocity-ff");
924 velocity_actions.push_back ("StepEditing/note-velocity-fff");
926 for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
928 act = myactions.find_action (*i);
930 if (act) {
931 ract = RefPtr<RadioAction>::cast_dynamic (act);
933 if (ract) {
934 if (ract->property_value() == val) {
935 ract->set_active (true);
936 inconsistent = false;
937 break;
943 velocity_ppp_button.set_inconsistent (inconsistent);
944 velocity_pp_button.set_inconsistent (inconsistent);
945 velocity_p_button.set_inconsistent (inconsistent);
946 velocity_mp_button.set_inconsistent (inconsistent);
947 velocity_mf_button.set_inconsistent (inconsistent);
948 velocity_f_button.set_inconsistent (inconsistent);
949 velocity_ff_button.set_inconsistent (inconsistent);
950 velocity_fff_button.set_inconsistent (inconsistent);
953 void
954 StepEntry::length_value_change ()
956 RefPtr<Action> act;
957 RefPtr<RadioAction> ract;
958 double val = length_divisor_adjustment.get_value();
959 bool inconsistent = true;
960 vector<const char*> length_actions;
962 length_actions.push_back ("StepEditing/note-length-whole");
963 length_actions.push_back ("StepEditing/note-length-half");
964 length_actions.push_back ("StepEditing/note-length-quarter");
965 length_actions.push_back ("StepEditing/note-length-eighth");
966 length_actions.push_back ("StepEditing/note-length-sixteenth");
967 length_actions.push_back ("StepEditing/note-length-thirtysecond");
968 length_actions.push_back ("StepEditing/note-length-sixtyfourth");
970 for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
972 act = myactions.find_action (*i);
974 if (act) {
975 ract = RefPtr<RadioAction>::cast_dynamic (act);
977 if (ract) {
978 if (ract->property_value() == val) {
979 ract->set_active (true);
980 inconsistent = false;
981 break;
987 length_1_button.set_inconsistent (inconsistent);
988 length_2_button.set_inconsistent (inconsistent);
989 length_4_button.set_inconsistent (inconsistent);
990 length_8_button.set_inconsistent (inconsistent);
991 length_16_button.set_inconsistent (inconsistent);
992 length_32_button.set_inconsistent (inconsistent);
993 length_64_button.set_inconsistent (inconsistent);
995 se->set_step_edit_cursor_width (note_length());
998 bool
999 StepEntry::radio_button_press (GdkEventButton* ev)
1001 if (ev->button == 1) {
1002 return true;
1005 return false;
1008 bool
1009 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
1011 if (ev->button == 1) {
1012 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
1014 if (act) {
1015 gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
1018 return true;
1021 return false;
1024 void
1025 StepEntry::next_octave ()
1027 octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1030 void
1031 StepEntry::prev_octave ()
1033 octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1036 void
1037 StepEntry::inc_note_length ()
1039 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1042 void
1043 StepEntry::dec_note_length ()
1045 length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1048 void
1049 StepEntry::prev_note_length ()
1051 double l = length_divisor_adjustment.get_value();
1052 int il = (int) lrintf (l); // round to nearest integer
1053 il = (il/2) * 2; // round to power of 2
1055 if (il == 0) {
1056 il = 1;
1059 il *= 2; // double
1061 length_divisor_adjustment.set_value (il);
1064 void
1065 StepEntry::next_note_length ()
1067 double l = length_divisor_adjustment.get_value();
1068 int il = (int) lrintf (l); // round to nearest integer
1069 il = (il/2) * 2; // round to power of 2
1071 if (il == 0) {
1072 il = 1;
1075 il /= 2; // half
1077 if (il > 0) {
1078 length_divisor_adjustment.set_value (il);
1082 void
1083 StepEntry::inc_note_velocity ()
1085 velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1088 void
1089 StepEntry::dec_note_velocity ()
1091 velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1094 void
1095 StepEntry::next_note_velocity ()
1097 double l = velocity_adjustment.get_value ();
1099 if (l < 16) {
1100 l = 16;
1101 } else if (l < 32) {
1102 l = 32;
1103 } else if (l < 48) {
1104 l = 48;
1105 } else if (l < 64) {
1106 l = 64;
1107 } else if (l < 80) {
1108 l = 80;
1109 } else if (l < 96) {
1110 l = 96;
1111 } else if (l < 112) {
1112 l = 112;
1113 } else if (l < 127) {
1114 l = 127;
1117 velocity_adjustment.set_value (l);
1120 void
1121 StepEntry::prev_note_velocity ()
1123 double l = velocity_adjustment.get_value ();
1125 if (l > 112) {
1126 l = 112;
1127 } else if (l > 96) {
1128 l = 96;
1129 } else if (l > 80) {
1130 l = 80;
1131 } else if (l > 64) {
1132 l = 64;
1133 } else if (l > 48) {
1134 l = 48;
1135 } else if (l > 32) {
1136 l = 32;
1137 } else if (l > 16) {
1138 l = 16;
1139 } else {
1140 l = 1;
1143 velocity_adjustment.set_value (l);
1146 void
1147 StepEntry::octave_n (int n)
1149 octave_adjustment.set_value (n);
1152 void
1153 StepEntry::do_sustain ()
1155 se->step_edit_sustain (note_length());
1158 void
1159 StepEntry::back ()
1161 se->move_step_edit_beat_pos (-note_length());
1164 void
1165 StepEntry::sync_to_edit_point ()
1167 se->resync_step_edit_to_edit_point ();