25edb120ae23dc2573664abcb93e05bfa9f4b7cb
[ardour.git] / gtk2_ardour / step_entry.cc
1 /*
2     Copyright (C) 2010 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
20 #include <iostream>
21
22 #include "pbd/file_utils.h"
23
24 #include "gtkmm2ext/actions.h"
25 #include "gtkmm2ext/keyboard.h"
26
27 #include "widgets/tooltips.h"
28
29 #include "ardour/filesystem_paths.h"
30
31 #include "midi_channel_selector.h"
32 #include "midi_time_axis.h"
33 #include "step_editor.h"
34 #include "step_entry.h"
35 #include "utils.h"
36
37 #include "pbd/i18n.h"
38
39 using namespace std;
40 using namespace Gtk;
41 using namespace Glib;
42 using namespace Gtkmm2ext;
43 using namespace PBD;
44 using namespace ARDOUR;
45 using namespace ARDOUR_UI_UTILS;
46 using namespace ArdourWidgets;
47
48 static void
49 _note_off_event_handler (GtkWidget* /*widget*/, int note, gpointer arg)
50 {
51         ((StepEntry*)arg)->note_off_event_handler (note);
52 }
53
54 static void
55 _rest_event_handler (GtkWidget* /*widget*/, gpointer arg)
56 {
57         ((StepEntry*)arg)->rest_event_handler ();
58 }
59
60 StepEntry::StepEntry (StepEditor& seditor)
61         : ArdourWindow (string_compose (_("Step Entry: %1"), seditor.name()))
62         , _current_note_length (1.0)
63         , _current_note_velocity (64)
64         , triplet_button ("3")
65         , dot_adjustment (0.0, 0.0, 3.0, 1.0, 1.0)
66         , beat_resync_button (_(">beat"))
67         , bar_resync_button (_(">bar"))
68         , resync_button (_(">EP"))
69         , sustain_button (_("sustain"))
70         , rest_button (_("rest"))
71         , grid_rest_button (_("g-rest"))
72         , back_button (_("back"))
73         , channel_adjustment (1, 1, 16, 1, 4)
74         , channel_spinner (channel_adjustment)
75         , octave_adjustment (4, 0, 10, 1, 4) // start in octave 4
76         , octave_spinner (octave_adjustment)
77         , length_divisor_adjustment (1.0, 1.0, 128, 1.0, 4.0)
78         , length_divisor_spinner (length_divisor_adjustment)
79         , velocity_adjustment (64.0, 0.0, 127.0, 1.0, 4.0)
80         , velocity_spinner (velocity_adjustment)
81         , bank_adjustment (0, 0.0, 127.0, 1.0, 4.0)
82         , bank_spinner (bank_adjustment)
83         , bank_button (_("+"))
84         , program_adjustment (0, 0.0, 127.0, 1.0, 4.0)
85         , program_spinner (program_adjustment)
86         , program_button (_("+"))
87         , _piano (0)
88         , piano (0)
89         , se (&seditor)
90 {
91         register_actions ();
92         load_bindings ();
93
94 #if 0
95         /* set channel selector to first selected channel. if none
96            are selected, it will remain at the value set in its
97            constructor, above (1)
98         */
99
100         uint16_t chn_mask = se->channel_selector().get_selected_channels();
101
102         for (uint32_t i = 0; i < 16; ++i) {
103                 if (chn_mask & (1<<i)) {
104                         channel_adjustment.set_value (i+1);
105                         break;
106                 }
107         }
108
109 #endif
110
111         RadioButtonGroup length_group = length_1_button.get_group();
112         length_2_button.set_group (length_group);
113         length_4_button.set_group (length_group);
114         length_8_button.set_group (length_group);
115         length_12_button.set_group (length_group);
116         length_16_button.set_group (length_group);
117         length_32_button.set_group (length_group);
118         length_64_button.set_group (length_group);
119
120         Widget* w;
121
122         w = manage (new Image (::get_icon (X_("wholenote"))));
123         w->show();
124         length_1_button.add (*w);
125         w = manage (new Image (::get_icon (X_("halfnote"))));
126         w->show();
127         length_2_button.add (*w);
128         w = manage (new Image (::get_icon (X_("quarternote"))));
129         w->show();
130         length_4_button.add (*w);
131         w = manage (new Image (::get_icon (X_("eighthnote"))));
132         w->show();
133         length_8_button.add (*w);
134         w = manage (new Image (::get_icon (X_("sixteenthnote"))));
135         w->show();
136         length_16_button.add (*w);
137         w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
138         w->show();
139         length_32_button.add (*w);
140         w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
141         w->show();
142         length_64_button.add (*w);
143
144         RefPtr<Action> act;
145
146         act = ActionManager::get_action ("StepEditing/note-length-whole");
147         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_1_button.gobj()), act->gobj());
148         act = ActionManager::get_action ("StepEditing/note-length-half");
149         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_2_button.gobj()), act->gobj());
150         act = ActionManager::get_action ("StepEditing/note-length-quarter");
151         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_4_button.gobj()), act->gobj());
152         act = ActionManager::get_action ("StepEditing/note-length-eighth");
153         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_8_button.gobj()), act->gobj());
154         act = ActionManager::get_action ("StepEditing/note-length-sixteenth");
155         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_16_button.gobj()), act->gobj());
156         act = ActionManager::get_action ("StepEditing/note-length-thirtysecond");
157         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_32_button.gobj()), act->gobj());
158         act = ActionManager::get_action ("StepEditing/note-length-sixtyfourth");
159         gtk_activatable_set_related_action (GTK_ACTIVATABLE (length_64_button.gobj()), act->gobj());
160
161         length_1_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
162         length_1_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 1), false);
163         length_2_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
164         length_2_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 2), false);
165         length_4_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
166         length_4_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 4), false);
167         length_8_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
168         length_8_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 8), false);
169         length_16_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
170         length_16_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 16), false);
171         length_32_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
172         length_32_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 32), false);
173         length_64_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
174         length_64_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &length_1_button, 64), false);
175
176         length_1_button.property_draw_indicator() = false;
177         length_2_button.property_draw_indicator() = false;
178         length_4_button.property_draw_indicator() = false;
179         length_8_button.property_draw_indicator() = false;
180         length_16_button.property_draw_indicator() = false;
181         length_32_button.property_draw_indicator() = false;
182         length_64_button.property_draw_indicator() = false;
183
184         note_length_box.pack_start (length_1_button, false, false);
185         note_length_box.pack_start (length_2_button, false, false);
186         note_length_box.pack_start (length_4_button, false, false);
187         note_length_box.pack_start (length_8_button, false, false);
188         note_length_box.pack_start (length_16_button, false, false);
189         note_length_box.pack_start (length_32_button, false, false);
190         note_length_box.pack_start (length_64_button, false, false);
191
192         set_tooltip (&length_1_button, _("Set note length to a whole note"), "");
193         set_tooltip (&length_2_button, _("Set note length to a half note"), "");
194         set_tooltip (&length_4_button, _("Set note length to a quarter note"), "");
195         set_tooltip (&length_8_button, _("Set note length to a eighth note"), "");
196         set_tooltip (&length_16_button, _("Set note length to a sixteenth note"), "");
197         set_tooltip (&length_32_button, _("Set note length to a thirty-second note"), "");
198         set_tooltip (&length_64_button, _("Set note length to a sixty-fourth note"), "");
199
200         RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
201         velocity_pp_button.set_group (velocity_group);
202         velocity_p_button.set_group (velocity_group);
203         velocity_mp_button.set_group (velocity_group);
204         velocity_mf_button.set_group (velocity_group);
205         velocity_f_button.set_group (velocity_group);
206         velocity_ff_button.set_group (velocity_group);
207         velocity_fff_button.set_group (velocity_group);
208
209         w = manage (new Image (::get_icon (X_("pianississimo"))));
210         w->show();
211         velocity_ppp_button.add (*w);
212         w = manage (new Image (::get_icon (X_("pianissimo"))));
213         w->show();
214         velocity_pp_button.add (*w);
215         w = manage (new Image (::get_icon (X_("piano"))));
216         w->show();
217         velocity_p_button.add (*w);
218         w = manage (new Image (::get_icon (X_("mezzopiano"))));
219         w->show();
220         velocity_mp_button.add (*w);
221         w = manage (new Image (::get_icon (X_("mezzoforte"))));
222         w->show();
223         velocity_mf_button.add (*w);
224         w = manage (new Image (::get_icon (X_("forte"))));
225         w->show();
226         velocity_f_button.add (*w);
227         w = manage (new Image (::get_icon (X_("fortissimo"))));
228         w->show();
229         velocity_ff_button.add (*w);
230         w = manage (new Image (::get_icon (X_("fortississimo"))));
231         w->show();
232         velocity_fff_button.add (*w);
233
234         act = ActionManager::get_action ("StepEditing/note-velocity-ppp");
235         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ppp_button.gobj()), act->gobj());
236         act = ActionManager::get_action ("StepEditing/note-velocity-pp");
237         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_pp_button.gobj()), act->gobj());
238         act = ActionManager::get_action ("StepEditing/note-velocity-p");
239         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_p_button.gobj()), act->gobj());
240         act = ActionManager::get_action ("StepEditing/note-velocity-mp");
241         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mp_button.gobj()), act->gobj());
242         act = ActionManager::get_action ("StepEditing/note-velocity-mf");
243         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_mf_button.gobj()), act->gobj());
244         act = ActionManager::get_action ("StepEditing/note-velocity-f");
245         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_f_button.gobj()), act->gobj());
246         act = ActionManager::get_action ("StepEditing/note-velocity-ff");
247         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_ff_button.gobj()), act->gobj());
248         act = ActionManager::get_action ("StepEditing/note-velocity-fff");
249         gtk_activatable_set_related_action (GTK_ACTIVATABLE (velocity_fff_button.gobj()), act->gobj());
250
251         velocity_ppp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
252         velocity_ppp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ppp_button, 1), false);
253         velocity_pp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
254         velocity_pp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_pp_button, 16), false);
255         velocity_p_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
256         velocity_p_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_p_button, 32), false);
257         velocity_mp_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
258         velocity_mp_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mp_button, 64), false);
259         velocity_mf_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
260         velocity_mf_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_mf_button, 80), false);
261         velocity_f_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
262         velocity_f_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_f_button, 96), false);
263         velocity_ff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
264         velocity_ff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_ff_button, 112), false);
265         velocity_fff_button.signal_button_press_event().connect (sigc::mem_fun (*this, &StepEntry::radio_button_press), false);
266         velocity_fff_button.signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &StepEntry::radio_button_release), &velocity_fff_button, 127), false);
267
268         velocity_ppp_button.property_draw_indicator() = false;
269         velocity_pp_button.property_draw_indicator() = false;
270         velocity_p_button.property_draw_indicator() = false;
271         velocity_mp_button.property_draw_indicator() = false;
272         velocity_mf_button.property_draw_indicator() = false;
273         velocity_f_button.property_draw_indicator() = false;
274         velocity_ff_button.property_draw_indicator() = false;
275         velocity_fff_button.property_draw_indicator() = false;
276
277         set_tooltip (&velocity_ppp_button, _("Set volume (velocity) to pianississimo"), "");
278         set_tooltip (&velocity_pp_button, _("Set volume (velocity) to pianissimo"), "");
279         set_tooltip (&velocity_p_button, _("Set volume (velocity) to piano"), "");
280         set_tooltip (&velocity_mp_button, _("Set volume (velocity) to mezzo-piano"), "");
281         set_tooltip (&velocity_mf_button, _("Set volume (velocity) to mezzo-forte"), "");
282         set_tooltip (&velocity_f_button, _("Set volume (velocity) to forte"), "");
283         set_tooltip (&velocity_ff_button, _("Set volume (velocity) to fortissimo"), "");
284         set_tooltip (&velocity_fff_button, _("Set volume (velocity) to fortississimo"), "");
285
286         note_velocity_box.pack_start (velocity_ppp_button, false, false);
287         note_velocity_box.pack_start (velocity_pp_button, false, false);
288         note_velocity_box.pack_start (velocity_p_button, false, false);
289         note_velocity_box.pack_start (velocity_mp_button, false, false);
290         note_velocity_box.pack_start (velocity_mf_button, false, false);
291         note_velocity_box.pack_start (velocity_f_button, false, false);
292         note_velocity_box.pack_start (velocity_ff_button, false, false);
293         note_velocity_box.pack_start (velocity_fff_button, false, false);
294
295         Label* l = manage (new Label);
296         l->set_markup ("<b><big>-</big></b>");
297         l->show ();
298         dot0_button.add (*l);
299
300         l = manage (new Label);
301         l->set_markup ("<b><big>.</big></b>");
302         l->show ();
303         dot1_button.add (*l);
304
305         l = manage (new Label);
306         l->set_markup ("<b><big>..</big></b>");
307         l->show ();
308         dot2_button.add (*l);
309
310         l = manage (new Label);
311         l->set_markup ("<b><big>...</big></b>");
312         l->show ();
313         dot3_button.add (*l);
314
315         w = manage (new Image (::get_icon (X_("chord"))));
316         w->show();
317         chord_button.add (*w);
318
319         dot_box1.pack_start (dot0_button, true, false);
320         dot_box1.pack_start (dot1_button, true, false);
321         dot_box2.pack_start (dot2_button, true, false);
322         dot_box2.pack_start (dot3_button, true, false);
323
324         rest_box.pack_start (rest_button, true, false);
325         rest_box.pack_start (grid_rest_button, true, false);
326         rest_box.pack_start (back_button, true, false);
327
328         resync_box.pack_start (beat_resync_button, true, false);
329         resync_box.pack_start (bar_resync_button, true, false);
330         resync_box.pack_start (resync_button, true, false);
331
332         set_tooltip (&chord_button, _("Stack inserted notes to form a chord"), "");
333         set_tooltip (&sustain_button, _("Extend selected notes by note length"), "");
334         set_tooltip (&dot0_button, _("Use undotted note lengths"), "");
335         set_tooltip (&dot1_button, _("Use dotted (* 1.5) note lengths"), "");
336         set_tooltip (&dot2_button, _("Use double-dotted (* 1.75) note lengths"), "");
337         set_tooltip (&dot3_button, _("Use triple-dotted (* 1.875) note lengths"), "");
338         set_tooltip (&rest_button, _("Insert a note-length's rest"), "");
339         set_tooltip (&grid_rest_button, _("Insert a grid-unit's rest"), "");
340         set_tooltip (&beat_resync_button, _("Insert a rest until the next beat"), "");
341         set_tooltip (&bar_resync_button, _("Insert a rest until the next bar"), "");
342         set_tooltip (&bank_button, _("Insert a bank change message"), "");
343         set_tooltip (&program_button, _("Insert a program change message"), "");
344         set_tooltip (&back_button, _("Move Insert Position Back by Note Length"), "");
345         set_tooltip (&resync_button, _("Move Insert Position to Edit Point"), "");
346
347         act = ActionManager::get_action ("StepEditing/back");
348         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (back_button.gobj()), false);
349         gtk_activatable_set_related_action (GTK_ACTIVATABLE (back_button.gobj()), act->gobj());
350         act = ActionManager::get_action ("StepEditing/sync-to-edit-point");
351         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (resync_button.gobj()), false);
352         gtk_activatable_set_related_action (GTK_ACTIVATABLE (resync_button.gobj()), act->gobj());
353         act = ActionManager::get_action ("StepEditing/toggle-triplet");
354         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (triplet_button.gobj()), false);
355         gtk_activatable_set_related_action (GTK_ACTIVATABLE (triplet_button.gobj()), act->gobj());
356         act = ActionManager::get_action ("StepEditing/no-dotted");
357         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot0_button.gobj()), false);
358         gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot0_button.gobj()), act->gobj());
359         act = ActionManager::get_action ("StepEditing/toggle-dotted");
360         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot1_button.gobj()), false);
361         gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot1_button.gobj()), act->gobj());
362         act = ActionManager::get_action ("StepEditing/toggle-double-dotted");
363         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot2_button.gobj()), false);
364         gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot2_button.gobj()), act->gobj());
365         act = ActionManager::get_action ("StepEditing/toggle-triple-dotted");
366         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (dot3_button.gobj()), false);
367         gtk_activatable_set_related_action (GTK_ACTIVATABLE (dot3_button.gobj()), act->gobj());
368         act = ActionManager::get_action ("StepEditing/toggle-chord");
369         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (chord_button.gobj()), false);
370         gtk_activatable_set_related_action (GTK_ACTIVATABLE (chord_button.gobj()), act->gobj());
371         act = ActionManager::get_action ("StepEditing/insert-rest");
372         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (rest_button.gobj()), false);
373         gtk_activatable_set_related_action (GTK_ACTIVATABLE (rest_button.gobj()), act->gobj());
374         act = ActionManager::get_action ("StepEditing/insert-snap-rest");
375         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (grid_rest_button.gobj()), false);
376         gtk_activatable_set_related_action (GTK_ACTIVATABLE (grid_rest_button.gobj()), act->gobj());
377         act = ActionManager::get_action ("StepEditing/sustain");
378         gtk_activatable_set_use_action_appearance (GTK_ACTIVATABLE (sustain_button.gobj()), false);
379         gtk_activatable_set_related_action (GTK_ACTIVATABLE (sustain_button.gobj()), act->gobj());
380
381         upper_box.set_spacing (6);
382         upper_box.pack_start (chord_button, false, false);
383         upper_box.pack_start (note_length_box, false, false, 12);
384         upper_box.pack_start (triplet_button, false, false);
385         upper_box.pack_start (dot_box1, false, false);
386         upper_box.pack_start (dot_box2, false, false);
387         upper_box.pack_start (sustain_button, false, false);
388         upper_box.pack_start (rest_box, false, false);
389         upper_box.pack_start (resync_box, false, false);
390         upper_box.pack_start (note_velocity_box, false, false, 12);
391
392         VBox* v;
393
394         v = manage (new VBox);
395         l = manage (new Label (_("Channel")));
396         v->set_spacing (6);
397         v->pack_start (*l, false, false);
398         v->pack_start (channel_spinner, false, false);
399         upper_box.pack_start (*v, false, false);
400
401         v = manage (new VBox);
402         l = manage (new Label (_("1/Note")));
403         v->set_spacing (6);
404         v->pack_start (*l, false, false);
405         v->pack_start (length_divisor_spinner, false, false);
406         upper_box.pack_start (*v, false, false);
407
408         v = manage (new VBox);
409         l = manage (new Label (_("Velocity")));
410         v->set_spacing (6);
411         v->pack_start (*l, false, false);
412         v->pack_start (velocity_spinner, false, false);
413         upper_box.pack_start (*v, false, false);
414
415         v = manage (new VBox);
416         l = manage (new Label (_("Octave")));
417         v->set_spacing (6);
418         v->pack_start (*l, false, false);
419         v->pack_start (octave_spinner, false, false);
420         upper_box.pack_start (*v, false, false);
421
422         v = manage (new VBox);
423         l = manage (new Label (_("Bank")));
424         v->set_spacing (6);
425         v->pack_start (*l, false, false);
426         v->pack_start (bank_spinner, false, false);
427         v->pack_start (bank_button, false, false);
428         upper_box.pack_start (*v, false, false);
429
430         v = manage (new VBox);
431         l = manage (new Label (_("Program")));
432         v->set_spacing (6);
433         v->pack_start (*l, false, false);
434         v->pack_start (program_spinner, false, false);
435         v->pack_start (program_button, false, false);
436         upper_box.pack_start (*v, false, false);
437
438         velocity_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::velocity_value_change));
439         length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_value_change));
440         dot_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::dot_value_change));
441
442         _piano = (PianoKeyboard*) piano_keyboard_new ();
443         piano = wrap ((GtkWidget*) _piano);
444
445         piano->set_flags (Gtk::CAN_FOCUS);
446
447         g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
448         g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
449
450         program_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::program_click));
451         bank_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bank_click));
452         beat_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::beat_resync_click));
453         bar_resync_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::bar_resync_click));
454
455         length_divisor_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &StepEntry::length_changed));
456
457         packer.set_spacing (6);
458         packer.pack_start (upper_box, false, false);
459         packer.pack_start (*piano, false, false);
460         packer.show_all ();
461
462         add (packer);
463
464         /* initial settings: quarter note and mezzo forte */
465
466         act = ActionManager::get_action ("StepEditing/note-length-quarter");
467         RefPtr<RadioAction> r = RefPtr<RadioAction>::cast_dynamic (act);
468         assert (r);
469         r->set_active (true);
470
471         act = ActionManager::get_action ("StepEditing/note-velocity-mf");
472         r = RefPtr<RadioAction>::cast_dynamic (act);
473         assert (r);
474         r->set_active (true);
475 }
476
477 StepEntry::~StepEntry()
478 {
479 }
480
481 void
482 StepEntry::length_changed ()
483 {
484         length_1_button.queue_draw ();
485         length_2_button.queue_draw ();
486         length_4_button.queue_draw ();
487         length_8_button.queue_draw ();
488         length_16_button.queue_draw ();
489         length_32_button.queue_draw ();
490         length_64_button.queue_draw ();
491 }
492
493 bool
494 StepEntry::on_key_press_event (GdkEventKey* ev)
495 {
496         /* focus widget gets first shot, then bindings, otherwise
497            forward to main window
498         */
499
500         if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
501                 return true;
502         }
503
504         return relay_key_press (ev, this);
505 }
506
507 bool
508 StepEntry::on_key_release_event (GdkEventKey* ev)
509 {
510         if (gtk_window_propagate_key_event (GTK_WINDOW(gobj()), ev)) {
511                 return true;
512         }
513
514         /* don't forward releases */
515
516         return true;
517 }
518
519 void
520 StepEntry::rest_event_handler ()
521 {
522         se->step_edit_rest (Temporal::Beats());
523 }
524
525 Temporal::Beats
526 StepEntry::note_length ()
527 {
528         double base_time = 4.0 / (double) length_divisor_adjustment.get_value();
529
530         RefPtr<Action> act = ActionManager::get_action ("StepEditing/toggle-triplet");
531         RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
532         bool triplets = tact->get_active ();
533
534         if (triplets) {
535                 base_time *= (2.0/3.0);
536         }
537
538         double dots = dot_adjustment.get_value ();
539
540         if (dots > 0) {
541                 dots = pow (2.0, dots);
542                 base_time *= 1 + ((dots - 1.0)/dots);
543         }
544
545         return Temporal::Beats(base_time);
546 }
547
548 uint8_t
549 StepEntry::note_velocity () const
550 {
551         return velocity_adjustment.get_value();
552 }
553
554 uint8_t
555 StepEntry::note_channel() const
556 {
557         return channel_adjustment.get_value() - 1;
558 }
559
560 void
561 StepEntry::note_off_event_handler (int note)
562 {
563         insert_note (note);
564 }
565
566
567 void
568 StepEntry::on_show ()
569 {
570         ArdourWindow::on_show ();
571         //piano->grab_focus ();
572 }
573
574 void
575 StepEntry::beat_resync_click ()
576 {
577         se->step_edit_beat_sync ();
578 }
579
580 void
581 StepEntry::bar_resync_click ()
582 {
583         se->step_edit_bar_sync ();
584 }
585
586 void
587 StepEntry::register_actions ()
588 {
589         /* add named actions for the step editor */
590
591         Glib::RefPtr<ActionGroup> group = ActionManager::create_action_group (this, X_("StepEditing"));
592
593         ActionManager::register_action (group, "insert-a", _("Insert Note A"), sigc::mem_fun (*this, &StepEntry::insert_a));
594         ActionManager::register_action (group, "insert-asharp", _("Insert Note A-sharp"), sigc::mem_fun (*this, &StepEntry::insert_asharp));
595         ActionManager::register_action (group, "insert-b", _("Insert Note B"), sigc::mem_fun (*this, &StepEntry::insert_b));
596         ActionManager::register_action (group, "insert-c", _("Insert Note C"), sigc::mem_fun (*this, &StepEntry::insert_c));
597         ActionManager::register_action (group, "insert-csharp", _("Insert Note C-sharp"), sigc::mem_fun (*this, &StepEntry::insert_csharp));
598         ActionManager::register_action (group, "insert-d", _("Insert Note D"), sigc::mem_fun (*this, &StepEntry::insert_d));
599         ActionManager::register_action (group, "insert-dsharp", _("Insert Note D-sharp"), sigc::mem_fun (*this, &StepEntry::insert_dsharp));
600         ActionManager::register_action (group, "insert-e", _("Insert Note E"), sigc::mem_fun (*this, &StepEntry::insert_e));
601         ActionManager::register_action (group, "insert-f", _("Insert Note F"), sigc::mem_fun (*this, &StepEntry::insert_f));
602         ActionManager::register_action (group, "insert-fsharp", _("Insert Note F-sharp"), sigc::mem_fun (*this, &StepEntry::insert_fsharp));
603         ActionManager::register_action (group, "insert-g", _("Insert Note G"), sigc::mem_fun (*this, &StepEntry::insert_g));
604         ActionManager::register_action (group, "insert-gsharp", _("Insert Note G-sharp"), sigc::mem_fun (*this, &StepEntry::insert_gsharp));
605
606         ActionManager::register_action (group, "insert-rest", _("Insert a Note-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_rest));
607         ActionManager::register_action (group, "insert-snap-rest", _("Insert a Snap-length Rest"), sigc::mem_fun (*this, &StepEntry::insert_grid_rest));
608
609         ActionManager::register_action (group, "next-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::next_octave));
610         ActionManager::register_action (group, "prev-octave", _("Move to next octave"), sigc::mem_fun (*this, &StepEntry::prev_octave));
611
612         ActionManager::register_action (group, "next-note-length", _("Move to Next Note Length"), sigc::mem_fun (*this, &StepEntry::next_note_length));
613         ActionManager::register_action (group, "prev-note-length", _("Move to Previous Note Length"), sigc::mem_fun (*this, &StepEntry::prev_note_length));
614
615         ActionManager::register_action (group, "inc-note-length", _("Increase Note Length"), sigc::mem_fun (*this, &StepEntry::inc_note_length));
616         ActionManager::register_action (group, "dec-note-length", _("Decrease Note Length"), sigc::mem_fun (*this, &StepEntry::dec_note_length));
617
618         ActionManager::register_action (group, "next-note-velocity", _("Move to Next Note Velocity"), sigc::mem_fun (*this, &StepEntry::next_note_velocity));
619         ActionManager::register_action (group, "prev-note-velocity", _("Move to Previous Note Velocity"), sigc::mem_fun (*this, &StepEntry::prev_note_velocity));
620
621         ActionManager::register_action (group, "inc-note-velocity", _("Increase Note Velocity"), sigc::mem_fun (*this, &StepEntry::inc_note_velocity));
622         ActionManager::register_action (group, "dec-note-velocity", _("Decrease Note Velocity"), sigc::mem_fun (*this, &StepEntry::dec_note_velocity));
623
624         ActionManager::register_action (group, "octave-0", _("Switch to the 1st octave"), sigc::mem_fun (*this, &StepEntry::octave_0));
625         ActionManager::register_action (group, "octave-1", _("Switch to the 2nd octave"), sigc::mem_fun (*this, &StepEntry::octave_1));
626         ActionManager::register_action (group, "octave-2", _("Switch to the 3rd octave"), sigc::mem_fun (*this, &StepEntry::octave_2));
627         ActionManager::register_action (group, "octave-3", _("Switch to the 4th octave"), sigc::mem_fun (*this, &StepEntry::octave_3));
628         ActionManager::register_action (group, "octave-4", _("Switch to the 5th octave"), sigc::mem_fun (*this, &StepEntry::octave_4));
629         ActionManager::register_action (group, "octave-5", _("Switch to the 6th octave"), sigc::mem_fun (*this, &StepEntry::octave_5));
630         ActionManager::register_action (group, "octave-6", _("Switch to the 7th octave"), sigc::mem_fun (*this, &StepEntry::octave_6));
631         ActionManager::register_action (group, "octave-7", _("Switch to the 8th octave"), sigc::mem_fun (*this, &StepEntry::octave_7));
632         ActionManager::register_action (group, "octave-8", _("Switch to the 9th octave"), sigc::mem_fun (*this, &StepEntry::octave_8));
633         ActionManager::register_action (group, "octave-9", _("Switch to the 10th octave"), sigc::mem_fun (*this, &StepEntry::octave_9));
634         ActionManager::register_action (group, "octave-10", _("Switch to the 11th octave"), sigc::mem_fun (*this, &StepEntry::octave_10));
635
636         ActionManager::register_toggle_action (group, "toggle-triplet", _("Toggle Triple Notes"),
637                                           sigc::mem_fun (*this, &StepEntry::toggle_triplet));
638
639         ActionManager::register_toggle_action (group, "toggle-chord", _("Toggle Chord Entry"),
640                                           sigc::mem_fun (*this, &StepEntry::toggle_chord));
641         ActionManager::register_action (group, "sustain", _("Sustain Selected Notes by Note Length"),
642                                    sigc::mem_fun (*this, &StepEntry::do_sustain));
643
644         ActionManager::register_action (group, "sync-to-edit-point", _("Move Insert Position to Edit Point"),
645                                    sigc::mem_fun (*this, &StepEntry::sync_to_edit_point));
646         ActionManager::register_action (group, "back", _("Move Insert Position Back by Note Length"),
647                                    sigc::mem_fun (*this, &StepEntry::back));
648         RadioAction::Group note_length_group;
649
650         ActionManager::register_radio_action (group, note_length_group, "note-length-whole",
651                                          _("Set Note Length to Whole"), sigc::mem_fun (*this, &StepEntry::note_length_change), 1);
652         ActionManager::register_radio_action (group, note_length_group, "note-length-half",
653                                          _("Set Note Length to 1/2"), sigc::mem_fun (*this, &StepEntry::note_length_change), 2);
654         ActionManager::register_radio_action (group, note_length_group, "note-length-third",
655                                          _("Set Note Length to 1/3"), sigc::mem_fun (*this, &StepEntry::note_length_change), 3);
656         ActionManager::register_radio_action (group, note_length_group, "note-length-quarter",
657                                          _("Set Note Length to 1/4"), sigc::mem_fun (*this, &StepEntry::note_length_change), 4);
658         ActionManager::register_radio_action (group, note_length_group, "note-length-eighth",
659                                          _("Set Note Length to 1/8"), sigc::mem_fun (*this, &StepEntry::note_length_change), 8);
660         ActionManager::register_radio_action (group, note_length_group, "note-length-sixteenth",
661                                          _("Set Note Length to 1/16"), sigc::mem_fun (*this, &StepEntry::note_length_change), 16);
662         ActionManager::register_radio_action (group, note_length_group, "note-length-thirtysecond",
663                                          _("Set Note Length to 1/32"), sigc::mem_fun (*this, &StepEntry::note_length_change), 32);
664         ActionManager::register_radio_action (group, note_length_group, "note-length-sixtyfourth",
665                                          _("Set Note Length to 1/64"), sigc::mem_fun (*this, &StepEntry::note_length_change), 64);
666
667         RadioAction::Group note_velocity_group;
668
669         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ppp",
670                                          _("Set Note Velocity to Pianississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 1);
671         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-pp",
672                                          _("Set Note Velocity to Pianissimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 16);
673         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-p",
674                                          _("Set Note Velocity to Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 32);
675         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mp",
676                                          _("Set Note Velocity to Mezzo-Piano"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 64);
677         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-mf",
678                                          _("Set Note Velocity to Mezzo-Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 80);
679         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-f",
680                                          _("Set Note Velocity to Forte"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 96);
681         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-ff",
682                                          _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 112);
683         ActionManager::register_radio_action (group, note_velocity_group, "note-velocity-fff",
684                                          _("Set Note Velocity to Fortississimo"), sigc::mem_fun (*this, &StepEntry::note_velocity_change), 127);
685
686
687         RadioAction::Group dot_group;
688
689         ActionManager::register_radio_action (group, dot_group, "no-dotted", _("No Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 0);
690         ActionManager::register_radio_action (group, dot_group, "toggle-dotted", _("Toggled Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 1);
691         ActionManager::register_radio_action (group, dot_group, "toggle-double-dotted", _("Toggled Double-Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 2);
692         ActionManager::register_radio_action (group, dot_group, "toggle-triple-dotted", _("Toggled Triple-Dotted Notes"), sigc::mem_fun (*this, &StepEntry::dot_change), 3);
693 }
694
695 void
696 StepEntry::load_bindings ()
697 {
698         bindings = Bindings::get_bindings (X_("Step Editing"));
699         set_data ("ardour-bindings", bindings);
700 }
701
702 void
703 StepEntry::toggle_triplet ()
704 {
705         se->set_step_edit_cursor_width (note_length());
706 }
707
708 void
709 StepEntry::toggle_chord ()
710 {
711         se->step_edit_toggle_chord ();
712 }
713
714 void
715 StepEntry::dot_change (GtkAction* act)
716 {
717         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
718                 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
719                 dot_adjustment.set_value (v);
720         }
721 }
722
723 void
724 StepEntry::dot_value_change ()
725 {
726         RefPtr<Action> act;
727         RefPtr<RadioAction> ract;
728         double val = dot_adjustment.get_value();
729         bool inconsistent = true;
730         vector<const char*> dot_actions;
731
732         dot_actions.push_back ("StepEditing/no-dotted");
733         dot_actions.push_back ("StepEditing/toggle-dotted");
734         dot_actions.push_back ("StepEditing/toggle-double-dotted");
735         dot_actions.push_back ("StepEditing/toggle-triple-dotted");
736
737         for (vector<const char*>::iterator i = dot_actions.begin(); i != dot_actions.end(); ++i) {
738
739                 act = ActionManager::get_action (*i);
740
741                 if (act) {
742                         ract = RefPtr<RadioAction>::cast_dynamic (act);
743
744                         if (ract) {
745                                 if (ract->property_value() == val) {
746                                         ract->set_active (true);
747                                         inconsistent = false;
748                                         break;
749                                 }
750                         }
751                 }
752         }
753
754         dot1_button.set_inconsistent (inconsistent);
755         dot2_button.set_inconsistent (inconsistent);
756         dot3_button.set_inconsistent (inconsistent);
757
758         se->set_step_edit_cursor_width (note_length());
759 }
760
761 void
762 StepEntry::program_click ()
763 {
764         se->step_add_program_change (note_channel(), (int8_t) floor (program_adjustment.get_value()));
765 }
766
767 void
768 StepEntry::bank_click ()
769 {
770         se->step_add_bank_change (note_channel(), (int8_t) floor (bank_adjustment.get_value()));
771 }
772
773 void
774 StepEntry::insert_rest ()
775 {
776         se->step_edit_rest (note_length());
777 }
778
779 void
780 StepEntry::insert_grid_rest ()
781 {
782         se->step_edit_rest (Temporal::Beats());
783 }
784
785 void
786 StepEntry::insert_note (uint8_t note)
787 {
788         if (note > 127) {
789                 return;
790         }
791
792         se->step_add_note (note_channel(), note, note_velocity(), note_length());
793 }
794 void
795 StepEntry::insert_c ()
796 {
797         insert_note (0 + (current_octave() * 12));
798 }
799 void
800 StepEntry::insert_csharp ()
801 {
802         insert_note (1 + (current_octave() * 12));
803 }
804 void
805 StepEntry::insert_d ()
806 {
807         insert_note (2 + (current_octave() * 12));
808 }
809 void
810 StepEntry::insert_dsharp ()
811 {
812         insert_note (3 + (current_octave() * 12));
813 }
814 void
815 StepEntry::insert_e ()
816 {
817         insert_note (4 + (current_octave() * 12));
818 }
819 void
820 StepEntry::insert_f ()
821 {
822         insert_note (5 + (current_octave() * 12));
823 }
824 void
825 StepEntry::insert_fsharp ()
826 {
827         insert_note (6 + (current_octave() * 12));
828 }
829 void
830 StepEntry::insert_g ()
831 {
832         insert_note (7 + (current_octave() * 12));
833 }
834 void
835 StepEntry::insert_gsharp ()
836 {
837         insert_note (8 + (current_octave() * 12));
838 }
839
840 void
841 StepEntry::insert_a ()
842 {
843         insert_note (9 + (current_octave() * 12));
844 }
845
846 void
847 StepEntry::insert_asharp ()
848 {
849         insert_note (10 + (current_octave() * 12));
850 }
851 void
852 StepEntry::insert_b ()
853 {
854         insert_note (11 + (current_octave() * 12));
855 }
856
857 void
858 StepEntry::note_length_change (GtkAction* act)
859 {
860         /* it doesn't matter which note length action we look up - we are interested
861            in the current_value which is global across the whole group of note length
862            actions. this method is called twice for every user operation,
863            once for the action that became "inactive" and once for the action that
864            becaome "active". so ... only bother to actually change the value when this
865            is called for the "active" action.
866         */
867
868         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION(act))) {
869                 gint v = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (act));
870                 length_divisor_adjustment.set_value (v);
871         }
872 }
873
874 void
875 StepEntry::note_velocity_change (GtkAction* act)
876 {
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.
883         */
884
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                 velocity_adjustment.set_value (v);
888         }
889 }
890
891 void
892 StepEntry::velocity_value_change ()
893 {
894         RefPtr<Action> act;
895         RefPtr<RadioAction> ract;
896         double val = velocity_adjustment.get_value();
897         bool inconsistent = true;
898         vector<const char*> velocity_actions;
899
900         velocity_actions.push_back ("StepEditing/note-velocity-ppp");
901         velocity_actions.push_back ("StepEditing/note-velocity-pp");
902         velocity_actions.push_back ("StepEditing/note-velocity-p");
903         velocity_actions.push_back ("StepEditing/note-velocity-mp");
904         velocity_actions.push_back ("StepEditing/note-velocity-mf");
905         velocity_actions.push_back ("StepEditing/note-velocity-f");
906         velocity_actions.push_back ("StepEditing/note-velocity-ff");
907         velocity_actions.push_back ("StepEditing/note-velocity-fff");
908
909         for (vector<const char*>::iterator i = velocity_actions.begin(); i != velocity_actions.end(); ++i) {
910
911                 act = ActionManager::get_action (*i);
912
913                 if (act) {
914                         ract = RefPtr<RadioAction>::cast_dynamic (act);
915
916                         if (ract) {
917                                 if (ract->property_value() == val) {
918                                         ract->set_active (true);
919                                         inconsistent = false;
920                                         break;
921                                 }
922                         }
923                 }
924         }
925
926         velocity_ppp_button.set_inconsistent (inconsistent);
927         velocity_pp_button.set_inconsistent (inconsistent);
928         velocity_p_button.set_inconsistent (inconsistent);
929         velocity_mp_button.set_inconsistent (inconsistent);
930         velocity_mf_button.set_inconsistent (inconsistent);
931         velocity_f_button.set_inconsistent (inconsistent);
932         velocity_ff_button.set_inconsistent (inconsistent);
933         velocity_fff_button.set_inconsistent (inconsistent);
934 }
935
936 void
937 StepEntry::length_value_change ()
938 {
939         RefPtr<Action> act;
940         RefPtr<RadioAction> ract;
941         double val = length_divisor_adjustment.get_value();
942         bool inconsistent = true;
943         vector<const char*> length_actions;
944
945         length_actions.push_back ("StepEditing/note-length-whole");
946         length_actions.push_back ("StepEditing/note-length-half");
947         length_actions.push_back ("StepEditing/note-length-quarter");
948         length_actions.push_back ("StepEditing/note-length-eighth");
949         length_actions.push_back ("StepEditing/note-length-sixteenth");
950         length_actions.push_back ("StepEditing/note-length-thirtysecond");
951         length_actions.push_back ("StepEditing/note-length-sixtyfourth");
952
953         for (vector<const char*>::iterator i = length_actions.begin(); i != length_actions.end(); ++i) {
954
955                 Glib::RefPtr<RadioAction> ract = ActionManager::get_radio_action (*i);
956
957                 ract->set_active (true);
958                 inconsistent = false;
959                 break;
960         }
961
962         length_1_button.set_inconsistent (inconsistent);
963         length_2_button.set_inconsistent (inconsistent);
964         length_4_button.set_inconsistent (inconsistent);
965         length_8_button.set_inconsistent (inconsistent);
966         length_16_button.set_inconsistent (inconsistent);
967         length_32_button.set_inconsistent (inconsistent);
968         length_64_button.set_inconsistent (inconsistent);
969
970         se->set_step_edit_cursor_width (note_length());
971 }
972
973 bool
974 StepEntry::radio_button_press (GdkEventButton* ev)
975 {
976         if (ev->button == 1) {
977                 return true;
978         }
979
980         return false;
981 }
982
983 bool
984 StepEntry::radio_button_release (GdkEventButton* ev, RadioButton* btn, int v)
985 {
986         if (ev->button == 1) {
987                 GtkAction* act = gtk_activatable_get_related_action (GTK_ACTIVATABLE (btn->gobj()));
988
989                 if (act) {
990                         gtk_radio_action_set_current_value (GTK_RADIO_ACTION(act), v);
991                 }
992
993                 return true;
994         }
995
996         return false;
997 }
998
999 void
1000 StepEntry::next_octave ()
1001 {
1002         octave_adjustment.set_value (octave_adjustment.get_value() + 1.0);
1003 }
1004
1005 void
1006 StepEntry::prev_octave ()
1007 {
1008         octave_adjustment.set_value (octave_adjustment.get_value() - 1.0);
1009 }
1010
1011 void
1012 StepEntry::inc_note_length ()
1013 {
1014         length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() - 1.0);
1015 }
1016
1017 void
1018 StepEntry::dec_note_length ()
1019 {
1020         length_divisor_adjustment.set_value (length_divisor_adjustment.get_value() + 1.0);
1021 }
1022
1023 void
1024 StepEntry::prev_note_length ()
1025 {
1026         double l = length_divisor_adjustment.get_value();
1027         int il = (int) lrintf (l); // round to nearest integer
1028         il = (il/2) * 2; // round to power of 2
1029
1030         if (il == 0) {
1031                 il = 1;
1032         }
1033
1034         il *= 2; // double
1035
1036         length_divisor_adjustment.set_value (il);
1037 }
1038
1039 void
1040 StepEntry::next_note_length ()
1041 {
1042         double l = length_divisor_adjustment.get_value();
1043         int il = (int) lrintf (l); // round to nearest integer
1044         il = (il/2) * 2; // round to power of 2
1045
1046         if (il == 0) {
1047                 il = 1;
1048         }
1049
1050         il /= 2; // half
1051
1052         if (il > 0) {
1053                 length_divisor_adjustment.set_value (il);
1054         }
1055 }
1056
1057 void
1058 StepEntry::inc_note_velocity ()
1059 {
1060         velocity_adjustment.set_value (velocity_adjustment.get_value() + 1.0);
1061 }
1062
1063 void
1064 StepEntry::dec_note_velocity ()
1065 {
1066         velocity_adjustment.set_value (velocity_adjustment.get_value() - 1.0);
1067 }
1068
1069 void
1070 StepEntry::next_note_velocity ()
1071 {
1072         double l = velocity_adjustment.get_value ();
1073
1074         if (l < 16) {
1075                 l = 16;
1076         } else if (l < 32) {
1077                 l = 32;
1078         } else if (l < 48) {
1079                 l = 48;
1080         } else if (l < 64) {
1081                 l = 64;
1082         } else if (l < 80) {
1083                 l = 80;
1084         } else if (l < 96) {
1085                 l = 96;
1086         } else if (l < 112) {
1087                 l = 112;
1088         } else if (l < 127) {
1089                 l = 127;
1090         }
1091
1092         velocity_adjustment.set_value (l);
1093 }
1094
1095 void
1096 StepEntry::prev_note_velocity ()
1097 {
1098         double l = velocity_adjustment.get_value ();
1099
1100         if (l > 112) {
1101                 l = 112;
1102         } else if (l > 96) {
1103                 l = 96;
1104         } else if (l > 80) {
1105                 l = 80;
1106         } else if (l > 64) {
1107                 l = 64;
1108         } else if (l > 48) {
1109                 l = 48;
1110         } else if (l > 32) {
1111                 l = 32;
1112         } else if (l > 16) {
1113                 l = 16;
1114         } else {
1115                 l = 1;
1116         }
1117
1118         velocity_adjustment.set_value (l);
1119 }
1120
1121 void
1122 StepEntry::octave_n (int n)
1123 {
1124         octave_adjustment.set_value (n);
1125 }
1126
1127 void
1128 StepEntry::do_sustain ()
1129 {
1130         se->step_edit_sustain (note_length());
1131 }
1132
1133 void
1134 StepEntry::back ()
1135 {
1136         se->move_step_edit_beat_pos (-note_length());
1137 }
1138
1139 void
1140 StepEntry::sync_to_edit_point ()
1141 {
1142         se->resync_step_edit_to_edit_point ();
1143 }