1 /*
2  * Copyright (C) 2020 Robin Gareus <robin@gareus.org>
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 along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include <glibmm/main.h>
20 
21 #include "ardour/plugin_insert.h"
22 #include "ardour/vst3_plugin.h"
23 
24 #include "gtkmm2ext/gui_thread.h"
25 
26 #include "timers.h"
27 #include "ui_config.h"
28 #include "vst3_plugin_ui.h"
29 
30 using namespace ARDOUR;
31 using namespace Steinberg;
32 
33 #ifdef PLATFORM_WINDOWS
DEF_CLASS_IID(Presonus::IPlugInViewScaling)34 DEF_CLASS_IID (Presonus::IPlugInViewScaling)
35 #endif
36 
37 VST3PluginUI::VST3PluginUI (boost::shared_ptr<PluginInsert> pi, boost::shared_ptr<VST3Plugin> vst3)
38 	: PlugUIBase (pi)
39 	, _pi (pi)
40 	, _vst3 (vst3)
41 	, _req_width (0)
42 	, _req_height (0)
43 	, _resize_in_progress (false)
44 	, _view_realized (false)
45 {
46 	_ardour_buttons_box.set_spacing (6);
47 	_ardour_buttons_box.set_border_width (6);
48 	add_common_widgets (&_ardour_buttons_box);
49 
50 	_vst3->OnResizeView.connect (_resize_connection, invalidator (*this), boost::bind (&VST3PluginUI::resize_callback, this, _1, _2), gui_context());
51 	//pi->plugin()->PresetLoaded.connect (*this, invalidator (*this), boost::bind (&VST3PluginUI::queue_port_update, this), gui_context ());
52 
53 	pack_start (_ardour_buttons_box, false, false);
54 	_ardour_buttons_box.show_all ();
55 }
56 
~VST3PluginUI()57 VST3PluginUI::~VST3PluginUI ()
58 {
59 }
60 
61 gint
get_preferred_height()62 VST3PluginUI::get_preferred_height ()
63 {
64 	IPlugView* view = _vst3->view ();
65 	ViewRect rect;
66 	if (view && view->getSize (&rect) == kResultOk){
67 		return rect.bottom - rect.top;
68 	}
69 	return 0;
70 }
71 
72 gint
get_preferred_width()73 VST3PluginUI::get_preferred_width ()
74 {
75 	IPlugView* view = _vst3->view ();
76 	ViewRect rect;
77 	if (view && view->getSize (&rect) == kResultOk){
78 		return rect.right - rect.left;
79 	}
80 	return 0;
81 }
82 
83 bool
resizable()84 VST3PluginUI::resizable ()
85 {
86 	IPlugView* view = _vst3->view ();
87 	return view && view->canResize () == kResultTrue;
88 }
89 
90 bool
non_gtk_gui() const91 VST3PluginUI::non_gtk_gui() const
92 {
93 	/* return true to enable forward_key_event */
94 	return false;
95 }
96 
97 int
package(Gtk::Window & win)98 VST3PluginUI::package (Gtk::Window& win)
99 {
100 	win.signal_map_event().connect (sigc::mem_fun(*this, &VST3PluginUI::start_updating));
101 	win.signal_unmap_event().connect (sigc::mem_fun(*this, &VST3PluginUI::stop_updating));
102 
103 	IPlugView* view = _vst3->view ();
104 	FUnknownPtr<Presonus::IPlugInViewScaling> vs (view);
105 	if (vs) {
106 		vs->setContentScaleFactor (UIConfiguration::instance().get_ui_scale ());
107 	}
108 
109 	return 0;
110 }
111 
112 bool
start_updating(GdkEventAny *)113 VST3PluginUI::start_updating (GdkEventAny*)
114 {
115 	_update_connection.disconnect();
116 	_update_connection = Timers::super_rapid_connect (sigc::mem_fun(*this, &VST3PluginUI::parameter_update));
117 	return false;
118 }
119 
120 bool
stop_updating(GdkEventAny *)121 VST3PluginUI::stop_updating (GdkEventAny*)
122 {
123 	_update_connection.disconnect();
124 	return false;
125 }
126 
127 void
parameter_update()128 VST3PluginUI::parameter_update ()
129 {
130 	// XXX replicated plugins, too ?!
131 	_vst3->update_contoller_param ();
132 }
133 
134 void
forward_key_event(GdkEventKey * ev)135 VST3PluginUI::forward_key_event (GdkEventKey* ev)
136 {
137 	/* NB VST3NSViewPluginUI overrides this */
138 #if 0 // -> non_gtk_gui () -> true
139 	// TODO: map key-events
140 	IPlugView* view = _vst3->view ();
141 	switch (gdk_key->type) {
142 		case GDK_KEY_PRESS:
143 			/* onKeyDown (char16 key, int16 keyCode, int16 modifiers)
144 			 * key: unicode code of key
145 			 * keyCode: virtual keycode for non ascii keys - see VirtualKeyCodes in keycodes.h
146 			 * modifiers	: any combination of modifiers - see KeyModifier in keycodes.h
147 			 */
148 			view->onKeyDown (ev->keyval, ev->hardware_keycode, ev->state);
149 			break;
150 		case GDK_KEY_RELEASE:
151 			//view->onKeyUp (key, keyCode, modifiers);
152 			break;
153 			break;
154 		default:
155 			return;
156 	}
157 #endif
158 }
159 
160 bool
forward_scroll_event(GdkEventScroll * ev)161 VST3PluginUI::forward_scroll_event (GdkEventScroll* ev)
162 {
163 	IPlugView* view = _vst3->view ();
164 	switch (ev->direction) {
165 		case GDK_SCROLL_UP:
166 		case GDK_SCROLL_LEFT:
167 			return view->onWheel (-1) == kResultTrue;
168 			break;
169 		case GDK_SCROLL_DOWN:
170 		case GDK_SCROLL_RIGHT:
171 			return view->onWheel (-1) == kResultTrue;
172 			break;
173 	}
174 	return false;
175 }
176