a bunch of tweaks for the step entry process (computer keyboard input now works,...
[ardour2.git] / gtk2_ardour / step_entry.cc
blobf585cba057b4ee07c4a430975791be6559c6cc18
1 /*
2 Copyright (C) 2010 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <iostream>
22 #include "gtkmm2ext/keyboard.h"
24 #include "midi_time_axis.h"
25 #include "step_entry.h"
26 #include "utils.h"
28 #include "i18n.h"
30 using namespace Gtk;
32 static void
33 _note_off_event_handler (GtkWidget* widget, int note, gpointer arg)
35 ((StepEntry*)arg)->note_off_event_handler (note);
38 static void
39 _rest_event_handler (GtkWidget* widget, gpointer arg)
41 ((StepEntry*)arg)->rest_event_handler ();
44 StepEntry::StepEntry (MidiTimeAxisView& mtv)
45 : ArdourDialog (string_compose (_("Step Entry: %1"), mtv.name()))
46 , triplet_button ("3")
47 , sustain_button ("sustain")
48 , rest_button ("rest")
49 , channel_adjustment (0, 15, 0, 1, 4)
50 , channel_spinner (channel_adjustment)
51 , _piano (0)
52 , piano (0)
53 , _mtv (&mtv)
55 RadioButtonGroup length_group = length_1_button.get_group();
56 length_2_button.set_group (length_group);
57 length_4_button.set_group (length_group);
58 length_8_button.set_group (length_group);
59 length_12_button.set_group (length_group);
60 length_16_button.set_group (length_group);
61 length_32_button.set_group (length_group);
62 length_64_button.set_group (length_group);
64 Widget* w;
66 w = manage (new Image (::get_icon (X_("wholenote"))));
67 w->show();
68 length_1_button.add (*w);
69 w = manage (new Image (::get_icon (X_("halfnote"))));
70 w->show();
71 length_2_button.add (*w);
72 w = manage (new Image (::get_icon (X_("quarternote"))));
73 w->show();
74 length_4_button.add (*w);
75 w = manage (new Image (::get_icon (X_("eighthnote"))));
76 w->show();
77 length_8_button.add (*w);
78 w = manage (new Image (::get_icon (X_("sixteenthnote"))));
79 w->show();
80 length_16_button.add (*w);
81 w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
82 w->show();
83 length_32_button.add (*w);
84 w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
85 w->show();
86 length_64_button.add (*w);
88 length_1_button.property_draw_indicator() = false;
89 length_2_button.property_draw_indicator() = false;
90 length_4_button.property_draw_indicator() = false;
91 length_8_button.property_draw_indicator() = false;
92 length_16_button.property_draw_indicator() = false;
93 length_32_button.property_draw_indicator() = false;
94 length_64_button.property_draw_indicator() = false;
96 note_length_box.pack_start (length_1_button, false, false);
97 note_length_box.pack_start (length_2_button, false, false);
98 note_length_box.pack_start (length_4_button, false, false);
99 note_length_box.pack_start (length_8_button, false, false);
100 note_length_box.pack_start (length_16_button, false, false);
101 note_length_box.pack_start (length_32_button, false, false);
102 note_length_box.pack_start (length_64_button, false, false);
104 RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
105 velocity_pp_button.set_group (velocity_group);
106 velocity_p_button.set_group (velocity_group);
107 velocity_mp_button.set_group (velocity_group);
108 velocity_mf_button.set_group (velocity_group);
109 velocity_f_button.set_group (velocity_group);
110 velocity_ff_button.set_group (velocity_group);
111 velocity_fff_button.set_group (velocity_group);
113 w = manage (new Image (::get_icon (X_("pianississimo"))));
114 w->show();
115 velocity_ppp_button.add (*w);
116 w = manage (new Image (::get_icon (X_("pianissimo"))));
117 w->show();
118 velocity_pp_button.add (*w);
119 w = manage (new Image (::get_icon (X_("piano"))));
120 w->show();
121 velocity_p_button.add (*w);
122 w = manage (new Image (::get_icon (X_("mezzopiano"))));
123 w->show();
124 velocity_mp_button.add (*w);
125 w = manage (new Image (::get_icon (X_("mezzoforte"))));
126 w->show();
127 velocity_mf_button.add (*w);
128 w = manage (new Image (::get_icon (X_("forte"))));
129 w->show();
130 velocity_f_button.add (*w);
131 w = manage (new Image (::get_icon (X_("fortissimo"))));
132 w->show();
133 velocity_ff_button.add (*w);
134 w = manage (new Image (::get_icon (X_("fortississimo"))));
135 w->show();
136 velocity_fff_button.add (*w);
138 velocity_ppp_button.property_draw_indicator() = false;
139 velocity_pp_button.property_draw_indicator() = false;
140 velocity_p_button.property_draw_indicator() = false;
141 velocity_mp_button.property_draw_indicator() = false;
142 velocity_mf_button.property_draw_indicator() = false;
143 velocity_f_button.property_draw_indicator() = false;
144 velocity_ff_button.property_draw_indicator() = false;
145 velocity_fff_button.property_draw_indicator() = false;
147 note_velocity_box.pack_start (velocity_ppp_button, false, false);
148 note_velocity_box.pack_start (velocity_pp_button, false, false);
149 note_velocity_box.pack_start (velocity_p_button, false, false);
150 note_velocity_box.pack_start (velocity_mp_button, false, false);
151 note_velocity_box.pack_start (velocity_mf_button, false, false);
152 note_velocity_box.pack_start (velocity_f_button, false, false);
153 note_velocity_box.pack_start (velocity_ff_button, false, false);
154 note_velocity_box.pack_start (velocity_fff_button, false, false);
156 Label* l = manage (new Label);
157 l->set_markup ("<b><big>.</big></b>");
158 l->show ();
159 dot_button.add (*l);
161 w = manage (new Image (::get_icon (X_("chord"))));
162 w->show();
163 chord_button.add (*w);
165 upper_box.set_spacing (6);
166 upper_box.pack_start (chord_button, false, false);
167 upper_box.pack_start (note_length_box, false, false, 12);
168 upper_box.pack_start (triplet_button, false, false);
169 upper_box.pack_start (dot_button, false, false);
170 upper_box.pack_start (sustain_button, false, false);
171 upper_box.pack_start (rest_button, false, false);
172 upper_box.pack_start (note_velocity_box, false, false, 12);
173 upper_box.pack_start (channel_spinner, false, false);
175 _piano = (PianoKeyboard*) piano_keyboard_new ();
176 piano_keyboard_set_keyboard_cue (PIANO_KEYBOARD(_piano), 1);
178 piano = Glib::wrap ((GtkWidget*) _piano);
180 piano->set_flags (Gtk::CAN_FOCUS);
181 piano->signal_enter_notify_event().connect (sigc::mem_fun (*this, &StepEntry::piano_enter_notify_event), false);
183 g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
184 g_signal_connect(G_OBJECT(_piano), "rest", G_CALLBACK(_rest_event_handler), this);
186 rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::rest_click));
187 chord_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::chord_toggled));
188 triplet_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::triplet_toggled));
190 packer.set_spacing (6);
191 packer.pack_start (upper_box, false, false);
192 packer.pack_start (*piano, false, false);
193 packer.show_all ();
195 get_vbox()->add (packer);
198 StepEntry::~StepEntry()
202 bool
203 StepEntry::on_key_press_event (GdkEventKey* ev)
205 int ret;
206 g_signal_emit_by_name (G_OBJECT(_piano), "key-press-event", ev, &ret);
207 return ret;
210 bool
211 StepEntry::on_key_release_event (GdkEventKey* ev)
213 int ret;
214 g_signal_emit_by_name (G_OBJECT(_piano), "key-release-event", ev, &ret);
215 return ret;
218 void
219 StepEntry::rest_event_handler ()
221 _mtv->step_edit_rest();
224 void
225 StepEntry::note_off_event_handler (int note)
227 Evoral::MusicalTime length = 1.0;
228 uint8_t velocity = 64;
230 if (length_64_button.get_active()) {
231 length = 1.0/64.0;
232 } else if (length_32_button.get_active()) {
233 length = 1.0/32.0;
234 } else if (length_16_button.get_active()) {
235 length = 1.0/16.0;
236 } else if (length_8_button.get_active()) {
237 length = 1.0/8.0;
238 } else if (length_4_button.get_active()) {
239 length = 1.0/4.0;
240 } else if (length_2_button.get_active()) {
241 length = 1.0/2.0;
242 } else if (length_1_button.get_active()) {
243 length = 1.0/1.0;
246 if (dot_button.get_active()) {
247 length *= 0.5;
250 if (velocity_ppp_button.get_active()) {
251 velocity = 16;
252 } else if (velocity_pp_button.get_active()) {
253 velocity = 32;
254 } else if (velocity_p_button.get_active()) {
255 velocity = 48;
256 } else if (velocity_mp_button.get_active()) {
257 velocity = 64;
258 } else if (velocity_mf_button.get_active()) {
259 velocity = 80;
260 } else if (velocity_f_button.get_active()) {
261 velocity = 96;
262 } else if (velocity_ff_button.get_active()) {
263 velocity = 112;
264 } else if (velocity_fff_button.get_active()) {
265 velocity = 127;
268 if (_mtv->step_edit_within_triplet()) {
269 length *= 2.0/3.0;
272 _mtv->step_add_note (channel_adjustment.get_value(), note, velocity, length);
275 void
276 StepEntry::rest_click ()
278 _mtv->step_edit_rest ();
281 void
282 StepEntry::triplet_toggled ()
284 if (triplet_button.get_active () != _mtv->step_edit_within_triplet()) {
285 _mtv->step_edit_toggle_triplet ();
289 void
290 StepEntry::chord_toggled ()
292 if (chord_button.get_active() != _mtv->step_edit_within_chord ()) {
293 _mtv->step_edit_toggle_chord ();
297 bool
298 StepEntry::piano_enter_notify_event (GdkEventCrossing *ev)
300 piano->grab_focus ();
301 return false;