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
139 mOwner.SetScreenScale(factor);
141 return Steinberg::kResultOk;
144 Steinberg::tresult PLUGIN_API queryInterface(
const Steinberg::TUID _iid,
void** obj)
override
146 QUERY_INTERFACE(_iid, obj, IPlugViewContentScaleSupport::iid, IPlugViewContentScaleSupport)
148 return CPluginView::queryInterface(_iid, obj);
151 Steinberg::tresult PLUGIN_API onKeyDown (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
154 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
156 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
158 iplug::IKeyPress keyPress {
" ",
160 static_cast<bool>(modifiers & Steinberg::kShiftKey),
161 static_cast<bool>(modifiers & Steinberg::kCommandKey),
162 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
164 return mOwner.OnKeyDown(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
168 return Steinberg::kResultFalse;
173 return mOwner.OnKeyDown(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
177 Steinberg::tresult PLUGIN_API onKeyUp (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
180 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
182 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
184 iplug::IKeyPress keyPress {
" ", iplug::kVK_SPACE,
185 static_cast<bool>(modifiers & Steinberg::kShiftKey),
186 static_cast<bool>(modifiers & Steinberg::kCommandKey),
187 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
189 return mOwner.OnKeyUp(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
193 return Steinberg::kResultFalse;
198 return mOwner.OnKeyUp(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
202 DELEGATE_REFCOUNT(Steinberg::CPluginView)
206 static int AsciiToVK(
int ascii)
209 HKL layout = GetKeyboardLayout(0);
210 return VkKeyScanExA((CHAR)ascii, layout);
213 if ((ascii >= 0x30 && ascii <= 0x39) || (ascii >= 0x41 && ascii <= 0x5A))
219 if (ascii >= 0x61 && ascii <= 0x7A)
224 return iplug::kVK_NONE;
228 static int VSTKeyCodeToVK (Steinberg::int16 code,
char ascii)
232 if (code == 0 || code == Steinberg::KEY_EQUALS)
234 return AsciiToVK(ascii);
237 using namespace Steinberg;
238 using namespace iplug;
242 case KEY_BACK:
return kVK_BACK;
243 case KEY_TAB:
return kVK_TAB;
244 case KEY_CLEAR:
return kVK_CLEAR;
245 case KEY_RETURN:
return kVK_RETURN;
246 case KEY_PAUSE:
return kVK_PAUSE;
247 case KEY_ESCAPE:
return kVK_ESCAPE;
248 case KEY_SPACE:
return kVK_SPACE;
249 case KEY_NEXT:
return kVK_NEXT;
250 case KEY_END:
return kVK_END;
251 case KEY_HOME:
return kVK_HOME;
252 case KEY_LEFT:
return kVK_LEFT;
253 case KEY_UP:
return kVK_UP;
254 case KEY_RIGHT:
return kVK_RIGHT;
255 case KEY_DOWN:
return kVK_DOWN;
256 case KEY_PAGEUP:
return kVK_PRIOR;
257 case KEY_PAGEDOWN:
return kVK_NEXT;
258 case KEY_SELECT:
return kVK_SELECT;
259 case KEY_PRINT:
return kVK_PRINT;
260 case KEY_ENTER:
return kVK_RETURN;
261 case KEY_SNAPSHOT:
return kVK_SNAPSHOT;
262 case KEY_INSERT:
return kVK_INSERT;
263 case KEY_DELETE:
return kVK_DELETE;
264 case KEY_HELP:
return kVK_HELP;
265 case KEY_NUMPAD0:
return kVK_NUMPAD0;
266 case KEY_NUMPAD1:
return kVK_NUMPAD1;
267 case KEY_NUMPAD2:
return kVK_NUMPAD2;
268 case KEY_NUMPAD3:
return kVK_NUMPAD3;
269 case KEY_NUMPAD4:
return kVK_NUMPAD4;
270 case KEY_NUMPAD5:
return kVK_NUMPAD5;
271 case KEY_NUMPAD6:
return kVK_NUMPAD6;
272 case KEY_NUMPAD7:
return kVK_NUMPAD7;
273 case KEY_NUMPAD8:
return kVK_NUMPAD8;
274 case KEY_NUMPAD9:
return kVK_NUMPAD9;
275 case KEY_MULTIPLY:
return kVK_MULTIPLY;
276 case KEY_ADD:
return kVK_ADD;
277 case KEY_SEPARATOR:
return kVK_SEPARATOR;
278 case KEY_SUBTRACT:
return kVK_SUBTRACT;
279 case KEY_DECIMAL:
return kVK_DECIMAL;
280 case KEY_DIVIDE:
return kVK_DIVIDE;
281 case KEY_F1:
return kVK_F1;
282 case KEY_F2:
return kVK_F2;
283 case KEY_F3:
return kVK_F3;
284 case KEY_F4:
return kVK_F4;
285 case KEY_F5:
return kVK_F5;
286 case KEY_F6:
return kVK_F6;
287 case KEY_F7:
return kVK_F7;
288 case KEY_F8:
return kVK_F8;
289 case KEY_F9:
return kVK_F9;
290 case KEY_F10:
return kVK_F10;
291 case KEY_F11:
return kVK_F11;
292 case KEY_F12:
return kVK_F12;
293 case KEY_NUMLOCK:
return kVK_NUMLOCK;
294 case KEY_SCROLL:
return kVK_SCROLL;
295 case KEY_SHIFT:
return kVK_SHIFT;
296 case KEY_CONTROL:
return kVK_CONTROL;
297 case KEY_ALT:
return kVK_MENU;
298 case KEY_EQUALS:
return kVK_NONE;
301 if(code >= VKEY_FIRST_ASCII)
302 return (code - VKEY_FIRST_ASCII + kVK_0);
307 static iplug::IKeyPress TranslateKeyMessage (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
313 key = Steinberg::VirtualKeyCodeToChar((Steinberg::uint8) keyMsg);
318 Steinberg::String keyStr(STR (
" "));
319 keyStr.setChar16(0, key);
320 keyStr.toMultiByte(Steinberg::kCP_Utf8);
321 if (keyStr.length() == 1)
323 str.Set(keyStr.text8());
327 iplug::IKeyPress keyPress { str.Get(), VSTKeyCodeToVK(keyMsg, str.Get()[0]),
328 static_cast<bool>(modifiers & Steinberg::kShiftKey),
329 static_cast<bool>(modifiers & Steinberg::kCommandKey),
330 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
335 void Resize(
int w,
int h)
339 Steinberg::ViewRect newSize = Steinberg::ViewRect(0, 0, w, h);
340 plugFrame->resizeView(
this, &newSize);