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