summaryrefslogtreecommitdiff
path: root/gtk2_ardour/virtual_keyboard_window.h
blob: f0f6f27bd807af65c98e3ae8f45de3f3489ab0a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (C) 2019 Robin Gareus <robin@gareus.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef _virtual_keyboard_window_h_
#define _virtual_keyboard_window_h_

#include <gtkmm/box.h>
#include <gtkmm/spinbutton.h>

#include "pbd/controllable.h"
#include "pbd/signals.h"

#include "gtkmm2ext/persistent_tooltip.h"

#include "widgets/ardour_button.h"
#include "widgets/ardour_dropdown.h"
#include "widgets/ardour_knob.h"
#include "widgets/slider_controller.h"

#include "ardour_window.h"
#include "pianokeyboard.h"

namespace ARDOUR {
	class Session;
}

class VKBDControl : public PBD::Controllable
{
public:
	VKBDControl (const std::string& name, double normal = 127, double upper = 127)
		: PBD::Controllable (name, Flag (0))
		, _lower (0)
		, _upper (upper)
		, _normal (normal)
		, _value (normal)
	{}

	/* Controllable API */
	void set_value (double v, PBD::Controllable::GroupControlDisposition gcd)
	{
		if (v != _value) {
			_value = std::max (_lower, std::min (_upper, v));
			Changed (true, gcd);        /* EMIT SIGNAL */
			ValueChanged ((int)_value); /* EMIT SIGNAL */
		}
	}

	std::string get_user_string () const
	{
		char buf[32];
		sprintf (buf, "%.0f", get_value ());
		return std::string (buf);
	}

	double get_value () const { return _value; }
	double lower () const { return _lower; }
	double upper () const { return _upper; }
	double normal () const { return _normal; }

	PBD::Signal1<void, int> ValueChanged;

protected:
	double _lower;
	double _upper;
	double _normal;
	double _value;
};

class VirtualKeyboardWindow : public ArdourWindow
{
public:
	VirtualKeyboardWindow ();
	~VirtualKeyboardWindow ();

	void set_session (ARDOUR::Session*);

	XMLNode& get_state ();
	void     set_state (const XMLNode&);

protected:
	bool on_focus_in_event (GdkEventFocus*);

private:
	void on_unmap ();
	bool on_key_press_event (GdkEventKey*);
	bool on_key_release_event (GdkEventKey*);

	void parameter_changed (std::string const&);

	void note_on_event_handler (int, int);
	void note_off_event_handler (int);
	void control_change_event_handler (int, int);
	void control_change_knob_event_handler (int, int);

	void modwheel_update_tooltip (int);
	void modwheel_slider_adjusted ();

	void octave_key_event_handler (bool);
	void pitch_bend_key_event_handler (int, bool);
	bool pitch_bend_timeout ();

	void pitch_bend_event_handler (int);
	void pitch_bend_release ();
	void pitch_bend_update_tooltip (int);
	void pitch_slider_adjusted ();

	void select_keyboard_layout (std::string const&);
	void update_velocity_settings ();
	void update_octave_key ();
	void update_octave_range ();
	void cc_key_changed (size_t);
	void update_cc (size_t, int);
	bool send_panic_message (GdkEventButton*);
	bool on_velocity_scroll_event (GdkEventScroll*);

	APianoKeyboard  _piano;

	ArdourWidgets::ArdourDropdown  _midi_channel;
	ArdourWidgets::ArdourDropdown  _piano_velocity;
	ArdourWidgets::ArdourDropdown  _piano_octave_key;
	ArdourWidgets::ArdourDropdown  _piano_octave_range;
	ArdourWidgets::ArdourDropdown  _transpose_output;
	ArdourWidgets::ArdourButton    _send_panic;

	boost::shared_ptr<VKBDControl>    _pitchbend;
	Gtk::Adjustment                   _pitch_adjustment;
	ArdourWidgets::VSliderController* _pitch_slider;
	Gtkmm2ext::PersistentTooltip*     _pitch_slider_tooltip;

	boost::shared_ptr<VKBDControl>    _modwheel;
	Gtk::Adjustment                   _modwheel_adjustment;
	ArdourWidgets::VSliderController* _modwheel_slider;
	Gtkmm2ext::PersistentTooltip*     _modwheel_tooltip;
#define VKBD_NCTRLS 4

	boost::shared_ptr<VKBDControl> _cc[VKBD_NCTRLS];
	ArdourWidgets::ArdourKnob*     _cc_knob[VKBD_NCTRLS];
	ArdourWidgets::ArdourDropdown  _cc_key[VKBD_NCTRLS];

	PBD::ScopedConnectionList _cc_connections;

	sigc::connection _bender_connection;
	int              _pitch_bend_target;
};

#endif