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