Completely untested right nowpull/24/head
@@ -19,6 +19,10 @@ | |||||
#include "Geometry.hpp" | #include "Geometry.hpp" | ||||
START_NAMESPACE_DISTRHO | |||||
class UIExporter; | |||||
END_NAMESPACE_DISTRHO | |||||
START_NAMESPACE_DGL | START_NAMESPACE_DGL | ||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
@@ -119,11 +123,15 @@ private: | |||||
friend class Application; | friend class Application; | ||||
friend class Widget; | friend class Widget; | ||||
friend class StandaloneWindow; | friend class StandaloneWindow; | ||||
friend class DISTRHO_NAMESPACE::UIExporter; | |||||
virtual void _addWidget(Widget* const widget); | virtual void _addWidget(Widget* const widget); | ||||
virtual void _removeWidget(Widget* const widget); | virtual void _removeWidget(Widget* const widget); | ||||
void _idle(); | 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) | 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; | Application& fApp; | ||||
Window* fSelf; | Window* fSelf; | ||||
PuglView* fView; | 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() | StandaloneWindow::StandaloneWindow() | ||||
@@ -52,6 +52,8 @@ | |||||
#define effGetProgramNameIndexed 29 | #define effGetProgramNameIndexed 29 | ||||
#define effGetPlugCategory 35 | #define effGetPlugCategory 35 | ||||
#define effIdle 53 | #define effIdle 53 | ||||
#define effEditKeyDown 59 | |||||
#define effEditKeyUp 60 | |||||
#define kPlugCategEffect 1 | #define kPlugCategEffect 1 | ||||
#define kPlugCategSynth 2 | #define kPlugCategSynth 2 | ||||
#define kVstVersion 2400 | #define kVstVersion 2400 | ||||
@@ -167,6 +169,56 @@ public: | |||||
} | } | ||||
# endif | # 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: | protected: | ||||
@@ -499,6 +551,16 @@ public: | |||||
if (fVstUI != nullptr) | if (fVstUI != nullptr) | ||||
fVstUI->idle(); | fVstUI->idle(); | ||||
break; | 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 | #endif // DISTRHO_PLUGIN_HAS_UI | ||||
#if DISTRHO_PLUGIN_WANT_STATE | #if DISTRHO_PLUGIN_WANT_STATE | ||||
@@ -416,6 +416,16 @@ public: | |||||
return ! glApp.isQuiting(); | 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 | #else | ||||
void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | void setWindowSize(const uint width, const uint height, const bool updateUI = false) {} | ||||
void setWindowTransientWinId(const uintptr_t winId) {} | void setWindowTransientWinId(const uintptr_t winId) {} | ||||