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