make step entry chord & triplet buttons do their thing, or something close to it
[ardour.git] / gtk2_ardour / step_entry.cc
1 /*
2     Copyright (C) 2010 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <iostream>
21
22 #include "midi_time_axis.h"
23 #include "step_entry.h"
24 #include "utils.h"
25
26 #include "i18n.h"
27
28 using namespace Gtk;
29
30 static void
31 _note_off_event_handler (GtkWidget* widget, int note, gpointer arg)
32 {
33         ((StepEntry*)arg)->note_off_event_handler (note);
34 }
35
36
37 StepEntry::StepEntry (MidiTimeAxisView& mtv)
38         : ArdourDialog (_("Step Entry Editor"))
39         , triplet_button ("3")
40         , sustain_button ("sustain")
41         , rest_button ("rest")
42         , channel_adjustment (0, 15, 0, 1, 4)
43         , channel_spinner (channel_adjustment)
44         , _piano (0)
45         , piano (0)
46         , _mtv (&mtv)
47 {
48         RadioButtonGroup length_group = length_1_button.get_group();
49         length_2_button.set_group (length_group);
50         length_4_button.set_group (length_group);
51         length_8_button.set_group (length_group);
52         length_12_button.set_group (length_group);
53         length_16_button.set_group (length_group);
54         length_32_button.set_group (length_group);
55         length_64_button.set_group (length_group);
56
57         Widget* w;
58
59         w = manage (new Image (::get_icon (X_("wholenote"))));
60         w->show();
61         length_1_button.add (*w);
62         w = manage (new Image (::get_icon (X_("halfnote"))));
63         w->show();
64         length_2_button.add (*w);
65         w = manage (new Image (::get_icon (X_("quarternote"))));
66         w->show();
67         length_4_button.add (*w);
68         w = manage (new Image (::get_icon (X_("eighthnote"))));
69         w->show();
70         length_8_button.add (*w);
71         w = manage (new Image (::get_icon (X_("sixteenthnote"))));
72         w->show();
73         length_16_button.add (*w);
74         w = manage (new Image (::get_icon (X_("thirtysecondnote"))));
75         w->show();
76         length_32_button.add (*w);
77         w = manage (new Image (::get_icon (X_("sixtyfourthnote"))));
78         w->show();
79         length_64_button.add (*w);
80
81         length_1_button.property_draw_indicator() = false;
82         length_2_button.property_draw_indicator() = false;
83         length_4_button.property_draw_indicator() = false;
84         length_8_button.property_draw_indicator() = false;
85         length_16_button.property_draw_indicator() = false;
86         length_32_button.property_draw_indicator() = false;
87         length_64_button.property_draw_indicator() = false;
88
89         note_length_box.pack_start (length_1_button, false, false);
90         note_length_box.pack_start (length_2_button, false, false);
91         note_length_box.pack_start (length_4_button, false, false);
92         note_length_box.pack_start (length_8_button, false, false);
93         note_length_box.pack_start (length_16_button, false, false);
94         note_length_box.pack_start (length_32_button, false, false);
95         note_length_box.pack_start (length_64_button, false, false);
96
97         RadioButtonGroup velocity_group = velocity_ppp_button.get_group();
98         velocity_pp_button.set_group (velocity_group);
99         velocity_p_button.set_group (velocity_group);
100         velocity_mp_button.set_group (velocity_group);
101         velocity_mf_button.set_group (velocity_group);
102         velocity_f_button.set_group (velocity_group);
103         velocity_ff_button.set_group (velocity_group);
104         velocity_fff_button.set_group (velocity_group);
105
106         w = manage (new Image (::get_icon (X_("pianississimo"))));
107         w->show();
108         velocity_ppp_button.add (*w);
109         w = manage (new Image (::get_icon (X_("pianissimo"))));
110         w->show();
111         velocity_pp_button.add (*w);
112         w = manage (new Image (::get_icon (X_("piano"))));
113         w->show();
114         velocity_p_button.add (*w);
115         w = manage (new Image (::get_icon (X_("mezzopiano"))));
116         w->show();
117         velocity_mp_button.add (*w);
118         w = manage (new Image (::get_icon (X_("mezzoforte"))));
119         w->show();
120         velocity_mf_button.add (*w);
121         w = manage (new Image (::get_icon (X_("forte"))));
122         w->show();
123         velocity_f_button.add (*w);
124         w = manage (new Image (::get_icon (X_("fortissimo"))));
125         w->show();
126         velocity_ff_button.add (*w);
127         w = manage (new Image (::get_icon (X_("fortississimo"))));
128         w->show();
129         velocity_fff_button.add (*w);
130
131         velocity_ppp_button.property_draw_indicator() = false;
132         velocity_pp_button.property_draw_indicator() = false;
133         velocity_p_button.property_draw_indicator() = false;
134         velocity_mp_button.property_draw_indicator() = false;
135         velocity_mf_button.property_draw_indicator() = false;
136         velocity_f_button.property_draw_indicator() = false;
137         velocity_ff_button.property_draw_indicator() = false;
138         velocity_fff_button.property_draw_indicator() = false;
139
140         note_velocity_box.pack_start (velocity_ppp_button, false, false);
141         note_velocity_box.pack_start (velocity_pp_button, false, false);
142         note_velocity_box.pack_start (velocity_p_button, false, false);
143         note_velocity_box.pack_start (velocity_mp_button, false, false);
144         note_velocity_box.pack_start (velocity_mf_button, false, false);
145         note_velocity_box.pack_start (velocity_f_button, false, false);
146         note_velocity_box.pack_start (velocity_ff_button, false, false);
147         note_velocity_box.pack_start (velocity_fff_button, false, false);
148
149         Label* l = manage (new Label);
150         l->set_markup ("<b><big>.</big></b>");
151         l->show ();
152         dot_button.add (*l);
153
154         w = manage (new Image (::get_icon (X_("chord"))));
155         w->show();
156         chord_button.add (*w);
157
158         upper_box.set_spacing (6);
159         upper_box.pack_start (chord_button, false, false);
160         upper_box.pack_start (note_length_box, false, false, 12);
161         upper_box.pack_start (triplet_button, false, false);
162         upper_box.pack_start (dot_button, false, false);
163         upper_box.pack_start (sustain_button, false, false);
164         upper_box.pack_start (rest_button, false, false);
165         upper_box.pack_start (note_velocity_box, false, false, 12);
166         upper_box.pack_start (channel_spinner, false, false);
167
168         _piano = (PianoKeyboard*) piano_keyboard_new ();
169         piano = Glib::wrap ((GtkWidget*) _piano);
170
171         g_signal_connect(G_OBJECT(_piano), "note-off", G_CALLBACK(_note_off_event_handler), this);
172
173         rest_button.signal_clicked().connect (sigc::mem_fun (*this, &StepEntry::rest_click));
174         chord_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::chord_toggled));
175         triplet_button.signal_toggled().connect (sigc::mem_fun (*this, &StepEntry::triplet_toggled));
176
177         packer.set_spacing (6);
178         packer.pack_start (upper_box, false, false);
179         packer.pack_start (*piano, false, false);
180         packer.show_all ();
181
182         get_vbox()->add (packer);
183 }
184
185 StepEntry::~StepEntry()
186 {
187 }
188
189 void
190 StepEntry::note_off_event_handler (int note)
191 {
192         Evoral::MusicalTime length = 1.0;
193         uint8_t velocity = 64;
194
195         if (length_64_button.get_active()) {
196                 length = 1.0/64.0;
197         } else if (length_32_button.get_active()) {
198                 length = 1.0/32.0;
199         } else if (length_16_button.get_active()) {
200                 length = 1.0/16.0;
201         } else if (length_8_button.get_active()) {
202                 length = 1.0/8.0;
203         } else if (length_4_button.get_active()) {
204                 length = 1.0/4.0;
205         } else if (length_2_button.get_active()) {
206                 length = 1.0/2.0;
207         } else if (length_1_button.get_active()) {
208                 length = 1.0/1.0;
209         }
210
211         if (dot_button.get_active()) {
212                 length *= 0.5;
213         }
214
215         if (velocity_ppp_button.get_active()) {
216                 velocity = 16;
217         } else if (velocity_pp_button.get_active()) {
218                 velocity = 32;
219         } else if (velocity_p_button.get_active()) {
220                 velocity = 48;
221         } else if (velocity_mp_button.get_active()) {
222                 velocity = 64;
223         } else if (velocity_mf_button.get_active()) {
224                 velocity = 80;
225         } else if (velocity_f_button.get_active()) {
226                 velocity = 96;
227         } else if (velocity_ff_button.get_active()) {
228                 velocity = 112;
229         } else if (velocity_fff_button.get_active()) {
230                 velocity = 127;
231         }
232
233         if (_mtv->step_edit_within_triplet()) {
234                 length *= 2.0/3.0;
235         }
236
237         _mtv->step_add_note (channel_adjustment.get_value(), note, velocity, length);
238 }
239
240 void
241 StepEntry::rest_click ()
242 {
243         _mtv->step_edit_rest ();
244 }
245
246 void
247 StepEntry::triplet_toggled ()
248 {
249         if (triplet_button.get_active () != _mtv->step_edit_within_triplet()) {
250                 _mtv->step_edit_toggle_triplet ();
251         }
252 }
253
254 void
255 StepEntry::chord_toggled ()
256 {
257         if (chord_button.get_active() != _mtv->step_edit_within_chord ()) {
258                 _mtv->step_edit_toggle_chord ();
259         }
260 }