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
62 mOwner.OnParentWindowResize(rect.getWidth(), rect.getHeight());
65 return Steinberg::kResultTrue;
68 Steinberg::tresult PLUGIN_API getSize(Steinberg::ViewRect* pSize)
override
74 *pSize = Steinberg::ViewRect(0, 0, mOwner.GetEditorWidth(), mOwner.GetEditorHeight());
76 return Steinberg::kResultTrue;
80 return Steinberg::kResultFalse;
84 Steinberg::tresult PLUGIN_API canResize()
override
86 if (mOwner.HasUI() && mOwner.GetHostResizeEnabled())
88 return Steinberg::kResultTrue;
91 return Steinberg::kResultFalse;
94 Steinberg::tresult PLUGIN_API checkSizeConstraint(Steinberg::ViewRect* pRect)
override
96 int w = pRect->getWidth();
97 int h = pRect->getHeight();
99 if(!mOwner.ConstrainEditorResize(w, h))
101 pRect->right = pRect->left + w;
102 pRect->bottom = pRect->top + h;
105 return Steinberg::kResultTrue;
108 Steinberg::tresult PLUGIN_API attached(
void* pParent, Steinberg::FIDString type)
override
112 void* pView =
nullptr;
114 if (strcmp(type, Steinberg::kPlatformTypeHWND) == 0)
115 pView = mOwner.OpenWindow(pParent);
117 if (strcmp(type, Steinberg::kPlatformTypeNSView) == 0)
118 pView = mOwner.OpenWindow(pParent);
120 return Steinberg::kResultFalse;
122 return Steinberg::kResultTrue;
125 return Steinberg::kResultFalse;
128 Steinberg::tresult PLUGIN_API removed()
override
131 mOwner.CloseWindow();
133 return CPluginView::removed();
136 Steinberg::tresult PLUGIN_API setContentScaleFactor(ScaleFactor factor)
override
138 mOwner.SetScreenScale(factor);
140 return Steinberg::kResultOk;
143 Steinberg::tresult PLUGIN_API queryInterface(
const Steinberg::TUID _iid,
void** obj)
override
145 QUERY_INTERFACE(_iid, obj, IPlugViewContentScaleSupport::iid, IPlugViewContentScaleSupport)
147 return CPluginView::queryInterface(_iid, obj);
150 Steinberg::tresult PLUGIN_API onKeyDown (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
153 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
155 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
157 iplug::IKeyPress keyPress {
" ",
159 static_cast<bool>(modifiers & Steinberg::kShiftKey),
160 static_cast<bool>(modifiers & Steinberg::kCommandKey),
161 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
163 return mOwner.OnKeyDown(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
167 return Steinberg::kResultFalse;
172 return mOwner.OnKeyDown(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
176 Steinberg::tresult PLUGIN_API onKeyUp (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
override
179 if (mOwner.GetHost() == iplug::EHost::kHostReaper)
181 if (keyMsg == Steinberg::VirtualKeyCodes::KEY_SPACE)
183 iplug::IKeyPress keyPress {
" ", iplug::kVK_SPACE,
184 static_cast<bool>(modifiers & Steinberg::kShiftKey),
185 static_cast<bool>(modifiers & Steinberg::kCommandKey),
186 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
188 return mOwner.OnKeyUp(keyPress) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
192 return Steinberg::kResultFalse;
197 return mOwner.OnKeyUp(TranslateKeyMessage(key, keyMsg, modifiers)) ? Steinberg::kResultTrue : Steinberg::kResultFalse;
201 DELEGATE_REFCOUNT(Steinberg::CPluginView)
205 static int AsciiToVK(
int ascii)
208 HKL layout = GetKeyboardLayout(0);
209 return VkKeyScanExA((CHAR)ascii, layout);
212 if ((ascii >= 0x30 && ascii <= 0x39) || (ascii >= 0x41 && ascii <= 0x5A))
218 if (ascii >= 0x61 && ascii <= 0x7A)
223 return iplug::kVK_NONE;
227 static int VSTKeyCodeToVK (Steinberg::int16 code,
char ascii)
231 if (code == 0 || code == Steinberg::KEY_EQUALS)
233 return AsciiToVK(ascii);
236 using namespace Steinberg;
237 using namespace iplug;
241 case KEY_BACK:
return kVK_BACK;
242 case KEY_TAB:
return kVK_TAB;
243 case KEY_CLEAR:
return kVK_CLEAR;
244 case KEY_RETURN:
return kVK_RETURN;
245 case KEY_PAUSE:
return kVK_PAUSE;
246 case KEY_ESCAPE:
return kVK_ESCAPE;
247 case KEY_SPACE:
return kVK_SPACE;
248 case KEY_NEXT:
return kVK_NEXT;
249 case KEY_END:
return kVK_END;
250 case KEY_HOME:
return kVK_HOME;
251 case KEY_LEFT:
return kVK_LEFT;
252 case KEY_UP:
return kVK_UP;
253 case KEY_RIGHT:
return kVK_RIGHT;
254 case KEY_DOWN:
return kVK_DOWN;
255 case KEY_PAGEUP:
return kVK_PRIOR;
256 case KEY_PAGEDOWN:
return kVK_NEXT;
257 case KEY_SELECT:
return kVK_SELECT;
258 case KEY_PRINT:
return kVK_PRINT;
259 case KEY_ENTER:
return kVK_RETURN;
260 case KEY_SNAPSHOT:
return kVK_SNAPSHOT;
261 case KEY_INSERT:
return kVK_INSERT;
262 case KEY_DELETE:
return kVK_DELETE;
263 case KEY_HELP:
return kVK_HELP;
264 case KEY_NUMPAD0:
return kVK_NUMPAD0;
265 case KEY_NUMPAD1:
return kVK_NUMPAD1;
266 case KEY_NUMPAD2:
return kVK_NUMPAD2;
267 case KEY_NUMPAD3:
return kVK_NUMPAD3;
268 case KEY_NUMPAD4:
return kVK_NUMPAD4;
269 case KEY_NUMPAD5:
return kVK_NUMPAD5;
270 case KEY_NUMPAD6:
return kVK_NUMPAD6;
271 case KEY_NUMPAD7:
return kVK_NUMPAD7;
272 case KEY_NUMPAD8:
return kVK_NUMPAD8;
273 case KEY_NUMPAD9:
return kVK_NUMPAD9;
274 case KEY_MULTIPLY:
return kVK_MULTIPLY;
275 case KEY_ADD:
return kVK_ADD;
276 case KEY_SEPARATOR:
return kVK_SEPARATOR;
277 case KEY_SUBTRACT:
return kVK_SUBTRACT;
278 case KEY_DECIMAL:
return kVK_DECIMAL;
279 case KEY_DIVIDE:
return kVK_DIVIDE;
280 case KEY_F1:
return kVK_F1;
281 case KEY_F2:
return kVK_F2;
282 case KEY_F3:
return kVK_F3;
283 case KEY_F4:
return kVK_F4;
284 case KEY_F5:
return kVK_F5;
285 case KEY_F6:
return kVK_F6;
286 case KEY_F7:
return kVK_F7;
287 case KEY_F8:
return kVK_F8;
288 case KEY_F9:
return kVK_F9;
289 case KEY_F10:
return kVK_F10;
290 case KEY_F11:
return kVK_F11;
291 case KEY_F12:
return kVK_F12;
292 case KEY_NUMLOCK:
return kVK_NUMLOCK;
293 case KEY_SCROLL:
return kVK_SCROLL;
294 case KEY_SHIFT:
return kVK_SHIFT;
295 case KEY_CONTROL:
return kVK_CONTROL;
296 case KEY_ALT:
return kVK_MENU;
297 case KEY_EQUALS:
return kVK_NONE;
300 if(code >= VKEY_FIRST_ASCII)
301 return (code - VKEY_FIRST_ASCII + kVK_0);
306 static iplug::IKeyPress TranslateKeyMessage (Steinberg::char16 key, Steinberg::int16 keyMsg, Steinberg::int16 modifiers)
312 key = Steinberg::VirtualKeyCodeToChar((Steinberg::uint8) keyMsg);
317 Steinberg::String keyStr(STR (
" "));
318 keyStr.setChar16(0, key);
319 keyStr.toMultiByte(Steinberg::kCP_Utf8);
320 if (keyStr.length() == 1)
322 str.Set(keyStr.text8());
326 iplug::IKeyPress keyPress { str.Get(), VSTKeyCodeToVK(keyMsg, str.Get()[0]),
327 static_cast<bool>(modifiers & Steinberg::kShiftKey),
328 static_cast<bool>(modifiers & Steinberg::kCommandKey),
329 static_cast<bool>(modifiers & Steinberg::kAlternateKey)};
334 void Resize(
int w,
int h)
338 Steinberg::ViewRect newSize = Steinberg::ViewRect(0, 0, w, h);
339 plugFrame->resizeView(
this, &newSize);