12#include "base/source/fstring.h"
13#include "pluginterfaces/gui/iplugviewcontentscalesupport.h"
14#include "pluginterfaces/base/keycodes.h"
16#include "IPlugStructs.h"
20class IPlugVST3View :
public Steinberg::CPluginView
21 ,
public Steinberg::IPlugViewContentScaleSupport
24 IPlugVST3View(T& owner)
35 IPlugVST3View(
const IPlugVST3View&) =
delete;
36 IPlugVST3View& operator=(
const IPlugVST3View&) =
delete;
38 Steinberg::tresult PLUGIN_API isPlatformTypeSupported(Steinberg::FIDString type)
override
43 if (strcmp(type, Steinberg::kPlatformTypeHWND) == 0)
44 return Steinberg::kResultTrue;
47 if (strcmp(type, Steinberg::kPlatformTypeNSView) == 0)
48 return Steinberg::kResultTrue;
52 return Steinberg::kResultFalse;
55 Steinberg::tresult PLUGIN_API onSize(Steinberg::ViewRect* pSize)
override
59 if (pSize && mOwner.GetHostResizeEnabled())
62 mOwner.OnParentWindowResize(rect.getWidth(), rect.getHeight());
63 return Steinberg::kResultTrue;
66 return Steinberg::kResultFalse;
69 Steinberg::tresult PLUGIN_API getSize(Steinberg::ViewRect* pSize)
override
75 *pSize = Steinberg::ViewRect(0, 0, mOwner.GetEditorWidth(), mOwner.GetEditorHeight());
77 return Steinberg::kResultTrue;
81 return Steinberg::kResultFalse;
85 Steinberg::tresult PLUGIN_API canResize()
override
87 if (mOwner.HasUI() && mOwner.GetHostResizeEnabled())
89 return Steinberg::kResultTrue;
92 return Steinberg::kResultFalse;
95 Steinberg::tresult PLUGIN_API checkSizeConstraint(Steinberg::ViewRect* pRect)
override
97 int w = pRect->getWidth();
98 int h = pRect->getHeight();
100 if(!mOwner.ConstrainEditorResize(w, h))
102 pRect->right = pRect->left + w;
103 pRect->bottom = pRect->top + h;
106 return Steinberg::kResultTrue;
109 Steinberg::tresult PLUGIN_API attached(
void* pParent, Steinberg::FIDString type)
override
113 void* pView =
nullptr;
115 if (strcmp(type, Steinberg::kPlatformTypeHWND) == 0)
116 pView = mOwner.OpenWindow(pParent);
118 if (strcmp(type, Steinberg::kPlatformTypeNSView) == 0)
119 pView = mOwner.OpenWindow(pParent);
121 return Steinberg::kResultFalse;
123 return Steinberg::kResultTrue;
126 return Steinberg::kResultFalse;
129 Steinberg::tresult PLUGIN_API removed()
override
132 mOwner.CloseWindow();
134 return CPluginView::removed();
137 Steinberg::tresult PLUGIN_API setContentScaleFactor(ScaleFactor factor)
override
140 mOwner.SetScreenScale(factor);
143 return Steinberg::kResultOk;
146 Steinberg::tresult PLUGIN_API queryInterface(
const Steinberg::TUID _iid,
void** obj)
override
148 QUERY_INTERFACE(_iid, obj, IPlugViewContentScaleSupport::iid, IPlugViewContentScaleSupport)
150 return CPluginView::queryInterface(_iid, obj);
153 Steinberg::tresult PLUGIN_API onKeyDown (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
156 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
158 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
160 iplug::IKeyPress keyPress {
" ",
162 static_cast<bool>(modifiers & Steinberg::kShiftKey),
163 static_cast<bool>(modifiers & Steinberg::kCommandKey),
164 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
166 return mOwner.OnKeyDown(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
170 return Steinberg::kResultFalse;
175 return mOwner.OnKeyDown(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
179 Steinberg::tresult PLUGIN_API onKeyUp (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
182 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
184 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
186 iplug::IKeyPress keyPress {
" ", iplug::kVK_SPACE,
187 static_cast<bool>(modifiers & Steinberg::kShiftKey),
188 static_cast<bool>(modifiers & Steinberg::kCommandKey),
189 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
191 return mOwner.OnKeyUp(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
195 return Steinberg::kResultFalse;
200 return mOwner.OnKeyUp(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
204 DELEGATE_REFCOUNT(Steinberg::CPluginView)
208 static int AsciiToVK(
int ascii)
211 HKL layout = GetKeyboardLayout(0);
212 return VkKeyScanExA((CHAR)ascii, layout);
215 if ((ascii >= 0x30 && ascii <= 0x39) || (ascii >= 0x41 && ascii <= 0x5A))
221 if (ascii >= 0x61 && ascii <= 0x7A)
226 return iplug::kVK_NONE;
230 static int VSTKeyCodeToVK (Steinberg::int16 code,
char ascii)
234 if (code == 0 || code == Steinberg::KEY_EQUALS)
236 return AsciiToVK(ascii);
239 using namespace Steinberg;
240 using namespace iplug;
244 case KEY_BACK:
return kVK_BACK;
245 case KEY_TAB:
return kVK_TAB;
246 case KEY_CLEAR:
return kVK_CLEAR;
247 case KEY_RETURN:
return kVK_RETURN;
248 case KEY_PAUSE:
return kVK_PAUSE;
249 case KEY_ESCAPE:
return kVK_ESCAPE;
250 case KEY_SPACE:
return kVK_SPACE;
251 case KEY_NEXT:
return kVK_NEXT;
252 case KEY_END:
return kVK_END;
253 case KEY_HOME:
return kVK_HOME;
254 case KEY_LEFT:
return kVK_LEFT;
255 case KEY_UP:
return kVK_UP;
256 case KEY_RIGHT:
return kVK_RIGHT;
257 case KEY_DOWN:
return kVK_DOWN;
258 case KEY_PAGEUP:
return kVK_PRIOR;
259 case KEY_PAGEDOWN:
return kVK_NEXT;
260 case KEY_SELECT:
return kVK_SELECT;
261 case KEY_PRINT:
return kVK_PRINT;
262 case KEY_ENTER:
return kVK_RETURN;
263 case KEY_SNAPSHOT:
return kVK_SNAPSHOT;
264 case KEY_INSERT:
return kVK_INSERT;
265 case KEY_DELETE:
return kVK_DELETE;
266 case KEY_HELP:
return kVK_HELP;
267 case KEY_NUMPAD0:
return kVK_NUMPAD0;
268 case KEY_NUMPAD1:
return kVK_NUMPAD1;
269 case KEY_NUMPAD2:
return kVK_NUMPAD2;
270 case KEY_NUMPAD3:
return kVK_NUMPAD3;
271 case KEY_NUMPAD4:
return kVK_NUMPAD4;
272 case KEY_NUMPAD5:
return kVK_NUMPAD5;
273 case KEY_NUMPAD6:
return kVK_NUMPAD6;
274 case KEY_NUMPAD7:
return kVK_NUMPAD7;
275 case KEY_NUMPAD8:
return kVK_NUMPAD8;
276 case KEY_NUMPAD9:
return kVK_NUMPAD9;
277 case KEY_MULTIPLY:
return kVK_MULTIPLY;
278 case KEY_ADD:
return kVK_ADD;
279 case KEY_SEPARATOR:
return kVK_SEPARATOR;
280 case KEY_SUBTRACT:
return kVK_SUBTRACT;
281 case KEY_DECIMAL:
return kVK_DECIMAL;
282 case KEY_DIVIDE:
return kVK_DIVIDE;
283 case KEY_F1:
return kVK_F1;
284 case KEY_F2:
return kVK_F2;
285 case KEY_F3:
return kVK_F3;
286 case KEY_F4:
return kVK_F4;
287 case KEY_F5:
return kVK_F5;
288 case KEY_F6:
return kVK_F6;
289 case KEY_F7:
return kVK_F7;
290 case KEY_F8:
return kVK_F8;
291 case KEY_F9:
return kVK_F9;
292 case KEY_F10:
return kVK_F10;
293 case KEY_F11:
return kVK_F11;
294 case KEY_F12:
return kVK_F12;
295 case KEY_NUMLOCK:
return kVK_NUMLOCK;
296 case KEY_SCROLL:
return kVK_SCROLL;
297 case KEY_SHIFT:
return kVK_SHIFT;
298 case KEY_CONTROL:
return kVK_CONTROL;
299 case KEY_ALT:
return kVK_MENU;
300 case KEY_EQUALS:
return kVK_NONE;
303 if(code >= VKEY_FIRST_ASCII)
304 return (code - VKEY_FIRST_ASCII + kVK_0);
309 static iplug::IKeyPress TranslateKeyMessage (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
315 key = Steinberg::VirtualKeyCodeToChar((Steinberg::uint8) keyMsg);
320 Steinberg::String keyStr(STR (
" "));
321 keyStr.setChar16(0, key);
322 keyStr.toMultiByte(Steinberg::kCP_Utf8);
323 if (keyStr.length() == 1)
325 str.Set(keyStr.text8());
329 iplug::IKeyPress keyPress { str.Get(), VSTKeyCodeToVK(keyMsg, str.Get()[0]),
330 static_cast<bool>(modifiers & Steinberg::kShiftKey),
331 static_cast<bool>(modifiers & Steinberg::kCommandKey),
332 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
337 void Resize(
int w,
int h)
341 Steinberg::ViewRect newSize = Steinberg::ViewRect(0, 0, w, h);
342 plugFrame->resizeView(
this, &newSize);