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