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