Completely untested right nowpull/24/head
@@ -19,6 +19,10 @@ | |||
#include "Geometry.hpp" | |||
START_NAMESPACE_DISTRHO | |||
class UIExporter; | |||
END_NAMESPACE_DISTRHO | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
@@ -119,11 +123,15 @@ private: | |||
friend class Application; | |||
friend class Widget; | |||
friend class StandaloneWindow; | |||
friend class DISTRHO_NAMESPACE::UIExporter; | |||
virtual void _addWidget(Widget* const widget); | |||
virtual void _removeWidget(Widget* const widget); | |||
void _idle(); | |||
bool handlePluginKeyboard(const bool press, const uint key); | |||
bool handlePluginSpecial(const bool press, const Key key); | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window) | |||
}; | |||
@@ -845,6 +845,90 @@ struct Window::PrivateData { | |||
// ------------------------------------------------------------------- | |||
bool handlePluginKeyboard(const bool press, const uint key) | |||
{ | |||
DBGp("PUGL: handlePluginKeyboard : %i %i\n", press, key); | |||
if (fModal.childFocus != nullptr) | |||
{ | |||
fModal.childFocus->focus(); | |||
return true; | |||
} | |||
Widget::KeyboardEvent ev; | |||
ev.press = press; | |||
ev.key = key; | |||
ev.mod = static_cast<Modifier>(fView->mods); | |||
ev.time = 0; | |||
if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z') | |||
ev.key -= 'a' - 'A'; // a-z -> A-Z | |||
FOR_EACH_WIDGET_INV(rit) | |||
{ | |||
Widget* const widget(*rit); | |||
if (widget->isVisible() && widget->onKeyboard(ev)) | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool handlePluginSpecial(const bool press, const Key key) | |||
{ | |||
DBGp("PUGL: handlePluginSpecial : %i %i\n", press, key); | |||
if (fModal.childFocus != nullptr) | |||
{ | |||
fModal.childFocus->focus(); | |||
return true; | |||
} | |||
int mods = 0x0; | |||
switch (key) | |||
{ | |||
case kKeyShift: | |||
mods |= kModifierShift; | |||
break; | |||
case kKeyControl: | |||
mods |= kModifierControl; | |||
break; | |||
case kKeyAlt: | |||
mods |= kModifierAlt; | |||
break; | |||
default: | |||
break; | |||
} | |||
if (mods != 0x0) | |||
{ | |||
if (press) | |||
fView->mods |= mods; | |||
else | |||
fView->mods &= ~(mods); | |||
} | |||
Widget::SpecialEvent ev; | |||
ev.press = press; | |||
ev.key = key; | |||
ev.mod = static_cast<Modifier>(fView->mods); | |||
ev.time = 0; | |||
FOR_EACH_WIDGET_INV(rit) | |||
{ | |||
Widget* const widget(*rit); | |||
if (widget->isVisible() && widget->onSpecial(ev)) | |||
return true; | |||
} | |||
return false; | |||
} | |||
// ------------------------------------------------------------------- | |||
Application& fApp; | |||
Window* fSelf; | |||
PuglView* fView; | |||
@@ -1200,6 +1284,16 @@ void Window::fileBrowserSelected(const char*) | |||
{ | |||
} | |||
bool Window::handlePluginKeyboard(const bool press, const uint key) | |||
{ | |||
return pData->handlePluginKeyboard(press, key); | |||
} | |||
bool Window::handlePluginSpecial(const bool press, const Key key) | |||
{ | |||
return pData->handlePluginSpecial(press, key); | |||
} | |||
// ----------------------------------------------------------------------- | |||
StandaloneWindow::StandaloneWindow() | |||
@@ -52,6 +52,8 @@ | |||
#define effGetProgramNameIndexed 29 | |||
#define effGetPlugCategory 35 | |||
#define effIdle 53 | |||
#define effEditKeyDown 59 | |||
#define effEditKeyUp 60 | |||
#define kPlugCategEffect 1 | |||
#define kPlugCategSynth 2 | |||
#define kVstVersion 2400 | |||
@@ -167,6 +169,56 @@ public: | |||
} | |||
# endif | |||
int handlePluginKeyEvent(const bool down, int32_t index, const intptr_t value) | |||
{ | |||
d_stdout("handlePluginKeyEvent %i %i %li\n", down, index, (long int)value); | |||
int special = 0; | |||
switch (value) | |||
{ | |||
// special casing (can be combined with normal keys) | |||
case 54: fUI.handlePluginSpecial(down, kKeyShift); break; | |||
case 55: fUI.handlePluginSpecial(down, kKeyControl); break; | |||
case 56: fUI.handlePluginSpecial(down, kKeyAlt); break; | |||
// convert some specials to normal keys | |||
case 1: index = kCharBackspace; break; | |||
case 6: index = kCharEscape; break; | |||
case 22: index = kCharDelete; break; | |||
// handle rest of special keys | |||
case 40: special = kKeyF1; break; | |||
case 41: special = kKeyF2; break; | |||
case 42: special = kKeyF3; break; | |||
case 43: special = kKeyF4; break; | |||
case 44: special = kKeyF5; break; | |||
case 45: special = kKeyF6; break; | |||
case 46: special = kKeyF7; break; | |||
case 47: special = kKeyF8; break; | |||
case 48: special = kKeyF9; break; | |||
case 49: special = kKeyF10; break; | |||
case 50: special = kKeyF11; break; | |||
case 51: special = kKeyF12; break; | |||
case 11: special = kKeyLeft; break; | |||
case 12: special = kKeyUp; break; | |||
case 13: special = kKeyRight; break; | |||
case 14: special = kKeyDown; break; | |||
case 15: special = kKeyPageUp; break; | |||
case 16: special = kKeyPageDown; break; | |||
case 10: special = kKeyHome; break; | |||
case 9: special = kKeyEnd; break; | |||
case 21: special = kKeyInsert; break; | |||
} | |||
if (special != 0) | |||
return fUI.handlePluginSpecial(down, static_cast<Key>(special)); | |||
if (index >= 0) | |||
return fUI.handlePluginKeyboard(down, static_cast<uint>(index)); | |||
return 0; | |||
} | |||
// ------------------------------------------------------------------- | |||
protected: | |||
@@ -499,6 +551,16 @@ public: | |||
if (fVstUI != nullptr) | |||
fVstUI->idle(); | |||
break; | |||
case effEditKeyDown: | |||
if (fVstUI != nullptr) | |||
return fVstUI->handlePluginKeyEvent(true, index, value); | |||
break; | |||
case effEditKeyUp: | |||
if (fVstUI != nullptr) | |||
return fVstUI->handlePluginKeyEvent(false, index, value); | |||
break; | |||
#endif // DISTRHO_PLUGIN_HAS_UI | |||
#if DISTRHO_PLUGIN_WANT_STATE | |||
@@ -416,6 +416,16 @@ public: | |||
return ! glApp.isQuiting(); | |||
} | |||
bool handlePluginKeyboard(const bool press, const uint key) | |||
{ | |||
return glWindow.handlePluginKeyboard(press, key); | |||
} | |||
bool handlePluginSpecial(const bool press, const Key key) | |||
{ | |||
return glWindow.handlePluginKeyboard(press, key); | |||
} | |||
#else | |||
void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | |||
void setWindowTransientWinId(const uintptr_t winId) {} | |||