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