1 /*
2  * Copyright (C) 2010-2018 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2011-2015 David Robillard <d@drobilla.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #ifndef __gtk2_ardour_step_entry_h__
21 #define __gtk2_ardour_step_entry_h__
22 
23 #include <gtkmm/togglebutton.h>
24 #include <gtkmm/radiobutton.h>
25 #include <gtkmm/spinbutton.h>
26 #include <gtkmm/box.h>
27 #include <gtkmm/adjustment.h>
28 #include <gtkmm2ext/bindings.h>
29 
30 #include "ardour_window.h"
31 #include "pianokeyboard.h"
32 
33 class StepEditor;
34 
35 /** StepEntry is a singleton class which presents a GUI to the user to allow
36  * them to carry out step editing. It does not understand the details of making
37  * changes to the model directly, but instead calls into a StepEditor object to
38  * accomplish that.
39  *
40  * The StepEntry is a singleton, used over and over each time the user wants to
41  * step edit; the StepEditor is owned by a MidiTimeAxisView and re-used for any
42  * step editing in the MidiTrack for which the MidiTimeAxisView is a view.
43  */
44 
45 class StepEntry : public ArdourWindow
46 {
47   public:
48 	static StepEntry& instance();
49 
50 	~StepEntry ();
51 
52 	void set_step_editor (StepEditor*);
53 
54 	Temporal::Beats note_length();
55 	uint8_t note_velocity() const;
56 	uint8_t note_channel() const;
57 
current_octave()58 	int current_octave () const { return (int) floor (octave_adjustment.get_value()); }
59 
60 	static void setup_actions_and_bindings ();
61 
62   private:
63 	static StepEntry* _instance;
64 	StepEntry ();
65 
66 	void note_off_event_handler (int note);
67 	void rest_event_handler ();
68 
69 	Temporal::Beats _current_note_length;
70 	uint8_t _current_note_velocity;
71 
72 	Gtk::VBox packer;
73 	Gtk::HBox upper_box;
74 	Gtk::HBox note_length_box;
75 	Gtk::HBox note_velocity_box;
76 
77 	Gtk::ToggleButton chord_button;
78 	Gtk::ToggleButton triplet_button;
79 	Gtk::ToggleButton dot0_button;
80 	Gtk::ToggleButton dot1_button;
81 	Gtk::ToggleButton dot2_button;
82 	Gtk::ToggleButton dot3_button;
83 	Gtk::Adjustment   dot_adjustment;
84 	Gtk::VBox dot_box1;
85 	Gtk::VBox dot_box2;
86 	Gtk::ToggleButton restart_button;
87 
88 	Gtk::VBox   resync_box;
89 	Gtk::Button beat_resync_button;
90 	Gtk::Button bar_resync_button;
91 	Gtk::Button resync_button;
92 
93 	Gtk::Button sustain_button;
94 	Gtk::Button rest_button;
95 	Gtk::Button grid_rest_button;
96 	Gtk::VBox   rest_box;
97 
98 	Gtk::Button back_button;
99 
100 	Gtk::RadioButton length_1_button;
101 	Gtk::RadioButton length_2_button;
102 	Gtk::RadioButton length_4_button;
103 	Gtk::RadioButton length_8_button;
104 	Gtk::RadioButton length_12_button;
105 	Gtk::RadioButton length_16_button;
106 	Gtk::RadioButton length_32_button;
107 	Gtk::RadioButton length_64_button;
108 
109 	Gtk::RadioButton velocity_ppp_button;
110 	Gtk::RadioButton velocity_pp_button;
111 	Gtk::RadioButton velocity_p_button;
112 	Gtk::RadioButton velocity_mp_button;
113 	Gtk::RadioButton velocity_mf_button;
114 	Gtk::RadioButton velocity_f_button;
115 	Gtk::RadioButton velocity_ff_button;
116 	Gtk::RadioButton velocity_fff_button;
117 
118 	Gtk::Adjustment channel_adjustment;
119 	Gtk::SpinButton channel_spinner;
120 
121 	Gtk::Adjustment octave_adjustment;
122 	Gtk::SpinButton octave_spinner;
123 
124 	Gtk::Adjustment length_divisor_adjustment;
125 	Gtk::SpinButton length_divisor_spinner;
126 
127 	Gtk::Adjustment velocity_adjustment;
128 	Gtk::SpinButton velocity_spinner;
129 
130 	Gtk::Adjustment bank_adjustment;
131 	Gtk::SpinButton bank_spinner;
132 	Gtk::Button     bank_button;
133 
134 	Gtk::Adjustment program_adjustment;
135 	Gtk::SpinButton program_spinner;
136 	Gtk::Button     program_button;
137 
138 	void length_changed ();
139 	void velocity_changed ();
140 	void velocity_value_change ();
141 	void length_value_change ();
142 
143 	APianoKeyboard _piano;
144 
145 	StepEditor*   se;
146 
147 	void bank_click ();
148 	void program_click ();
149 	void beat_resync_click ();
150 	void bar_resync_click ();
151 
152 	bool piano_enter_notify_event (GdkEventCrossing *ev);
153 	bool on_key_release_event (GdkEventKey*);
154 	bool on_key_press_event (GdkEventKey*);
155 
156 	void on_show ();
157 
158 	/* actions */
159 
160 	void insert_note (uint8_t);
161 	void insert_rest ();
162 	void insert_grid_rest ();
163 	void insert_a ();
164 	void insert_asharp ();
165 	void insert_b ();
166 	void insert_c ();
167 	void insert_csharp ();
168 	void insert_d ();
169 	void insert_dsharp ();
170 	void insert_e ();
171 	void insert_f ();
172 	void insert_fsharp ();
173 	void insert_g ();
174 	void insert_gsharp ();
175 	void note_length_change (GtkAction*);
176 	void note_velocity_change (GtkAction*);
177 	bool radio_button_press (GdkEventButton*);
178 	bool radio_button_release (GdkEventButton*, Gtk::RadioButton*, int);
179 	void inc_note_velocity ();
180 	void dec_note_velocity ();
181 	void next_note_velocity ();
182 	void prev_note_velocity ();
183 	void inc_note_length ();
184 	void dec_note_length ();
185 	void next_note_length ();
186 	void prev_note_length ();
187 	void next_octave ();
188 	void prev_octave ();
189 	void octave_n (int n);
octave_0()190 	void octave_0 () { octave_n (0); }
octave_1()191 	void octave_1 () { octave_n (1); }
octave_2()192 	void octave_2 () { octave_n (2); }
octave_3()193 	void octave_3 () { octave_n (3); }
octave_4()194 	void octave_4 () { octave_n (4); }
octave_5()195 	void octave_5 () { octave_n (5); }
octave_6()196 	void octave_6 () { octave_n (6); }
octave_7()197 	void octave_7 () { octave_n (7); }
octave_8()198 	void octave_8 () { octave_n (8); }
octave_9()199 	void octave_9 () { octave_n (9); }
octave_10()200 	void octave_10 () { octave_n (10); }
201 	void dot_change (GtkAction*);
202 	void dot_value_change ();
203 	void toggle_triplet();
204 	void toggle_chord();
205 	void do_sustain ();
206 	void back();
207 	void sync_to_edit_point ();
208 
209 	/* static versions of action methods, so that we can register actions without
210 	   having an actual StepEntry object.
211 	*/
212 
se_insert_rest()213 	static void se_insert_rest () { if (_instance) { _instance->insert_rest (); } }
se_insert_grid_rest()214 	static void se_insert_grid_rest () { if (_instance) { _instance->insert_grid_rest (); } }
se_insert_a()215 	static void se_insert_a () { if (_instance) { _instance->insert_a (); } }
se_insert_asharp()216 	static void se_insert_asharp () { if (_instance) { _instance->insert_asharp (); } }
se_insert_b()217 	static void se_insert_b () { if (_instance) { _instance->insert_b (); } }
se_insert_c()218 	static void se_insert_c () { if (_instance) { _instance->insert_c (); } }
se_insert_csharp()219 	static void se_insert_csharp () { if (_instance) { _instance->insert_csharp (); } }
se_insert_d()220 	static void se_insert_d () { if (_instance) { _instance->insert_d (); } }
se_insert_dsharp()221 	static void se_insert_dsharp () { if (_instance) { _instance->insert_dsharp (); } }
se_insert_e()222 	static void se_insert_e () { if (_instance) { _instance->insert_e (); } }
se_insert_f()223 	static void se_insert_f () { if (_instance) { _instance->insert_f (); } }
se_insert_fsharp()224 	static void se_insert_fsharp () { if (_instance) { _instance->insert_fsharp (); } }
se_insert_g()225 	static void se_insert_g () { if (_instance) { _instance->insert_g (); } }
se_insert_gsharp()226 	static void se_insert_gsharp () { if (_instance) { _instance->insert_gsharp (); } }
se_note_length_change(GtkAction * act)227 	static void se_note_length_change (GtkAction* act) { if (_instance) { _instance->note_length_change (act); } }
se_note_velocity_change(GtkAction * act)228 	static void se_note_velocity_change (GtkAction* act) { if (_instance) { _instance->note_velocity_change (act); } }
se_radio_button_press(GdkEventButton * ev)229 	static bool se_radio_button_press (GdkEventButton* ev) { if (_instance) { return _instance->radio_button_press (ev); } return false; }
se_radio_button_release(GdkEventButton * ev,Gtk::RadioButton * rb,int n)230 	static bool se_radio_button_release (GdkEventButton* ev, Gtk::RadioButton* rb, int n) { if (_instance) { return  _instance->radio_button_release (ev, rb, n); } return false; }
se_inc_note_velocity()231 	static void se_inc_note_velocity () { if (_instance) { _instance->inc_note_velocity (); } }
se_dec_note_velocity()232 	static void se_dec_note_velocity () { if (_instance) { _instance->dec_note_velocity (); } }
se_next_note_velocity()233 	static void se_next_note_velocity () { if (_instance) { _instance->next_note_velocity (); } }
se_prev_note_velocity()234 	static void se_prev_note_velocity () { if (_instance) { _instance->prev_note_velocity (); } }
se_inc_note_length()235 	static void se_inc_note_length () { if (_instance) { _instance->inc_note_length (); } }
se_dec_note_length()236 	static void se_dec_note_length () { if (_instance) { _instance->dec_note_length (); } }
se_next_note_length()237 	static void se_next_note_length () { if (_instance) { _instance->next_note_length (); } }
se_prev_note_length()238 	static void se_prev_note_length () { if (_instance) { _instance->prev_note_length (); } }
se_next_octave()239 	static void se_next_octave () { if (_instance) { _instance->next_octave (); } }
se_prev_octave()240 	static void se_prev_octave () { if (_instance) { _instance->prev_octave (); } }
se_octave_n(int n)241 	static void se_octave_n (int n) { if (_instance) { _instance->octave_n (n); } }
se_octave_0()242 	static void se_octave_0 () { if (_instance) { _instance->octave_0 (); } }
se_octave_1()243 	static void se_octave_1 () { if (_instance) { _instance->octave_1 (); } }
se_octave_2()244 	static void se_octave_2 () { if (_instance) { _instance->octave_2 (); } }
se_octave_3()245 	static void se_octave_3 () { if (_instance) { _instance->octave_3 (); } }
se_octave_4()246 	static void se_octave_4 () { if (_instance) { _instance->octave_4 (); } }
se_octave_5()247 	static void se_octave_5 () { if (_instance) { _instance->octave_5 (); } }
se_octave_6()248 	static void se_octave_6 () { if (_instance) { _instance->octave_6 (); } }
se_octave_7()249 	static void se_octave_7 () { if (_instance) { _instance->octave_7 (); } }
se_octave_8()250 	static void se_octave_8 () { if (_instance) { _instance->octave_8 (); } }
se_octave_9()251 	static void se_octave_9 () { if (_instance) { _instance->octave_9 (); } }
se_octave_10()252 	static void se_octave_10 () { if (_instance) { _instance->octave_10 (); } }
se_dot_change(GtkAction * act)253 	static void se_dot_change (GtkAction* act) { if (_instance) { _instance->dot_change (act); } }
se_dot_value_change()254 	static void se_dot_value_change () { if (_instance) { _instance->dot_value_change (); } }
se_toggle_triplet()255 	static void se_toggle_triplet() { if (_instance) { _instance->toggle_triplet (); } }
se_toggle_chord()256 	static void se_toggle_chord() { if (_instance) { _instance->toggle_chord (); } }
se_do_sustain()257 	static void se_do_sustain () { if (_instance) { _instance->do_sustain (); } }
se_back()258 	static void se_back() { if (_instance) { _instance->back (); } }
se_sync_to_edit_point()259 	static void se_sync_to_edit_point () { if (_instance) { _instance->sync_to_edit_point (); } }
260 
261 	static void load_bindings ();
262 	static Gtkmm2ext::Bindings*  bindings;
263 	static void register_actions ();
264 };
265 
266 #endif /* __gtk2_ardour_step_entry_h__ */
267