Signed-off-by: falkTX <falktx@falktx.com>pull/330/head
| @@ -49,16 +49,16 @@ enum Modifier { | |||
| /** | |||
| Keyboard key codepoints. | |||
| All keys are identified by a Unicode code point in PuglEventKey::key. This | |||
| enumeration defines constants for special keys that do not have a standard | |||
| code point, and some convenience constants for control characters. Note | |||
| that all keys are handled in the same way, this enumeration is just for | |||
| All keys are identified by a Unicode code point in Widget::KeyboardEvent::key. | |||
| This enumeration defines constants for special keys that do not have a standard | |||
| code point, and some convenience constants for control characters. | |||
| Note that all keys are handled in the same way, this enumeration is just for | |||
| convenience when writing hard-coded key bindings. | |||
| Keys that do not have a standard code point use values in the Private Use | |||
| Area in the Basic Multilingual Plane (`U+E000` to `U+F8FF`). Applications | |||
| must take care to not interpret these values beyond key detection, the | |||
| mapping used here is arbitrary and specific to DPF. | |||
| Area in the Basic Multilingual Plane (`U+E000` to `U+F8FF`). | |||
| Applications must take care to not interpret these values beyond key detection, | |||
| the mapping used here is arbitrary and specific to DPF. | |||
| */ | |||
| enum Key { | |||
| // Convenience symbols for ASCII control characters | |||
| @@ -116,7 +116,7 @@ enum Key { | |||
| /** | |||
| Common flags for all events. | |||
| */ | |||
| enum Flag { | |||
| enum EventFlag { | |||
| kFlagSendEvent = 1, ///< Event is synthetic | |||
| kFlagIsHint = 2 ///< Event is a hint (not direct user input) | |||
| }; | |||
| @@ -117,7 +117,6 @@ public: | |||
| protected: | |||
| bool onKeyboard(const KeyboardEvent&) override; | |||
| bool onSpecial(const SpecialEvent&) override; | |||
| bool onCharacterInput(const CharacterInputEvent&) override; | |||
| bool onMouse(const MouseEvent&) override; | |||
| bool onMotion(const MotionEvent&) override; | |||
| @@ -58,7 +58,7 @@ public: | |||
| These are the fields present on all Widget events. | |||
| @a mod Currently active keyboard modifiers, @see Modifier. | |||
| @a mod Event flags, @see Flag. | |||
| @a mod Event flags, @see EventFlag. | |||
| @a time Event timestamp (if any). | |||
| */ | |||
| struct BaseEvent { | |||
| @@ -107,14 +107,10 @@ public: | |||
| /** | |||
| Special keyboard event. | |||
| This event allows the use of keys that do not have unicode points. | |||
| Note that some are non-printable keys. | |||
| @a press True if the key was pressed, false if released. | |||
| @a key The key pressed. | |||
| @see onSpecial | |||
| DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional. | |||
| All events go through KeyboardEvent or CharacterInputEvent, use those instead. | |||
| */ | |||
| struct SpecialEvent : BaseEvent { | |||
| struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent { | |||
| bool press; | |||
| Key key; | |||
| @@ -398,12 +394,6 @@ protected: | |||
| */ | |||
| virtual bool onKeyboard(const KeyboardEvent&); | |||
| /** | |||
| A function called when a special key is pressed or released. | |||
| @return True to stop event propagation, false otherwise. | |||
| */ | |||
| virtual bool onSpecial(const SpecialEvent&); | |||
| /** | |||
| A function called when an UTF-8 character is received. | |||
| @return True to stop event propagation, false otherwise. | |||
| @@ -433,6 +423,19 @@ protected: | |||
| */ | |||
| virtual void onResize(const ResizeEvent&); | |||
| /** | |||
| A function called when a special key is pressed or released. | |||
| DEPRECATED use onKeyboard or onCharacterInput | |||
| */ | |||
| #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460 | |||
| # pragma GCC diagnostic push | |||
| # pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |||
| #endif | |||
| virtual bool onSpecial(const SpecialEvent&) { return false; } | |||
| #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460 | |||
| # pragma GCC diagnostic pop | |||
| #endif | |||
| private: | |||
| struct PrivateData; | |||
| PrivateData* const pData; | |||
| @@ -100,11 +100,6 @@ bool TopLevelWidget::onKeyboard(const KeyboardEvent&) | |||
| return false; | |||
| } | |||
| bool TopLevelWidget::onSpecial(const SpecialEvent&) | |||
| { | |||
| return false; | |||
| } | |||
| bool TopLevelWidget::onCharacterInput(const CharacterInputEvent&) | |||
| { | |||
| return false; | |||
| @@ -50,20 +50,6 @@ bool TopLevelWidget::PrivateData::keyboardEvent(const KeyboardEvent& ev) | |||
| return selfw->pData->giveKeyboardEventForSubWidgets(ev); | |||
| } | |||
| bool TopLevelWidget::PrivateData::specialEvent(const SpecialEvent& ev) | |||
| { | |||
| // ignore event if we are not visible | |||
| if (! selfw->pData->visible) | |||
| return false; | |||
| // give top-level widget chance to catch this event first | |||
| if (self->onSpecial(ev)) | |||
| return true; | |||
| // propagate event to all subwidgets recursively | |||
| return selfw->pData->giveSpecialEventForSubWidgets(ev); | |||
| } | |||
| bool TopLevelWidget::PrivateData::characterInputEvent(const CharacterInputEvent& ev) | |||
| { | |||
| // ignore event if we are not visible | |||
| @@ -34,7 +34,6 @@ struct TopLevelWidget::PrivateData { | |||
| ~PrivateData(); | |||
| void display(); | |||
| bool keyboardEvent(const KeyboardEvent& ev); | |||
| bool specialEvent(const SpecialEvent& ev); | |||
| bool characterInputEvent(const CharacterInputEvent& ev); | |||
| bool mouseEvent(const MouseEvent& ev); | |||
| bool motionEvent(const MotionEvent& ev); | |||
| @@ -167,11 +167,6 @@ bool Widget::onKeyboard(const KeyboardEvent& ev) | |||
| return pData->giveKeyboardEventForSubWidgets(ev); | |||
| } | |||
| bool Widget::onSpecial(const SpecialEvent& ev) | |||
| { | |||
| return pData->giveSpecialEventForSubWidgets(ev); | |||
| } | |||
| bool Widget::onCharacterInput(const CharacterInputEvent& ev) | |||
| { | |||
| return pData->giveCharacterInputEventForSubWidgets(ev); | |||
| @@ -87,24 +87,6 @@ bool Widget::PrivateData::giveKeyboardEventForSubWidgets(const KeyboardEvent& ev | |||
| return false; | |||
| } | |||
| bool Widget::PrivateData::giveSpecialEventForSubWidgets(const SpecialEvent& ev) | |||
| { | |||
| if (! visible) | |||
| return false; | |||
| if (subWidgets.size() == 0) | |||
| return false; | |||
| FOR_EACH_SUBWIDGET_INV(rit) | |||
| { | |||
| SubWidget* const widget(*rit); | |||
| if (widget->isVisible() && widget->onSpecial(ev)) | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| bool Widget::PrivateData::giveCharacterInputEventForSubWidgets(const CharacterInputEvent& ev) | |||
| { | |||
| if (! visible) | |||
| @@ -44,7 +44,6 @@ struct Widget::PrivateData { | |||
| void displaySubWidgets(uint width, uint height, double autoScaleFactor); | |||
| bool giveKeyboardEventForSubWidgets(const KeyboardEvent& ev); | |||
| bool giveSpecialEventForSubWidgets(const SpecialEvent& ev); | |||
| bool giveCharacterInputEventForSubWidgets(const CharacterInputEvent& ev); | |||
| bool giveMouseEventForSubWidgets(MouseEvent& ev); | |||
| bool giveMotionEventForSubWidgets(MotionEvent& ev); | |||
| @@ -820,24 +820,6 @@ void Window::PrivateData::onPuglKey(const Widget::KeyboardEvent& ev) | |||
| #endif | |||
| } | |||
| void Window::PrivateData::onPuglSpecial(const Widget::SpecialEvent& ev) | |||
| { | |||
| DGL_DBGp("onPuglSpecial : %i %u\n", ev.press, ev.key); | |||
| if (modal.child != nullptr) | |||
| return modal.child->focus(); | |||
| #ifndef DPF_TEST_WINDOW_CPP | |||
| FOR_EACH_TOP_LEVEL_WIDGET_INV(rit) | |||
| { | |||
| TopLevelWidget* const widget(*rit); | |||
| if (widget->isVisible() && widget->pData->specialEvent(ev)) | |||
| break; | |||
| } | |||
| #endif | |||
| } | |||
| void Window::PrivateData::onPuglText(const Widget::CharacterInputEvent& ev) | |||
| { | |||
| DGL_DBGp("onPuglText : %u %u %s\n", ev.keycode, ev.character, ev.string); | |||
| @@ -982,7 +964,6 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
| case PUGL_KEY_RELEASE: | |||
| { | |||
| // unused x, y, xRoot, yRoot (double) | |||
| // TODO special keys? | |||
| Widget::KeyboardEvent ev; | |||
| ev.mod = event->key.state; | |||
| ev.flags = event->key.flags; | |||
| @@ -990,8 +971,14 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu | |||
| ev.press = event->type == PUGL_KEY_PRESS; | |||
| ev.key = event->key.key; | |||
| ev.keycode = event->key.keycode; | |||
| if ((ev.mod & kModifierShift) != 0 && ev.key >= 'a' && ev.key <= 'z') | |||
| ev.key -= 'a' - 'A'; // a-z -> A-Z | |||
| // keyboard events must always be lowercase | |||
| if (ev.key >= 'A' && ev.key <= 'Z') | |||
| { | |||
| ev.key += 'a' - 'A'; // A-Z -> a-z | |||
| ev.mod |= kModifierShift; | |||
| } | |||
| pData->onPuglKey(ev); | |||
| break; | |||
| } | |||
| @@ -178,7 +178,6 @@ struct Window::PrivateData : IdleCallback { | |||
| void onPuglClose(); | |||
| void onPuglFocus(bool focus, CrossingMode mode); | |||
| void onPuglKey(const Widget::KeyboardEvent& ev); | |||
| void onPuglSpecial(const Widget::SpecialEvent& ev); | |||
| void onPuglText(const Widget::CharacterInputEvent& ev); | |||
| void onPuglMouse(const Widget::MouseEvent& ev); | |||
| void onPuglMotion(const Widget::MotionEvent& ev); | |||
| @@ -261,7 +261,6 @@ public: | |||
| using namespace DGL_NAMESPACE; | |||
| int special = 0; | |||
| switch (value) | |||
| { | |||
| // convert some VST special values to normal keys | |||
| @@ -304,37 +303,37 @@ public: | |||
| - kKeyCapsLock | |||
| - kKeyPrintScreen | |||
| */ | |||
| 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; | |||
| case 54: special = kKeyShift; break; | |||
| case 55: special = kKeyControl; break; | |||
| case 56: special = kKeyAlt; break; | |||
| case 58: special = kKeyMenu; break; | |||
| case 52: special = kKeyNumLock; break; | |||
| case 53: special = kKeyScrollLock; break; | |||
| case 5: special = kKeyPause; break; | |||
| case 40: index = kKeyF1; break; | |||
| case 41: index = kKeyF2; break; | |||
| case 42: index = kKeyF3; break; | |||
| case 43: index = kKeyF4; break; | |||
| case 44: index = kKeyF5; break; | |||
| case 45: index = kKeyF6; break; | |||
| case 46: index = kKeyF7; break; | |||
| case 47: index = kKeyF8; break; | |||
| case 48: index = kKeyF9; break; | |||
| case 49: index = kKeyF10; break; | |||
| case 50: index = kKeyF11; break; | |||
| case 51: index = kKeyF12; break; | |||
| case 11: index = kKeyLeft; break; | |||
| case 12: index = kKeyUp; break; | |||
| case 13: index = kKeyRight; break; | |||
| case 14: index = kKeyDown; break; | |||
| case 15: index = kKeyPageUp; break; | |||
| case 16: index = kKeyPageDown; break; | |||
| case 10: index = kKeyHome; break; | |||
| case 9: index = kKeyEnd; break; | |||
| case 21: index = kKeyInsert; break; | |||
| case 54: index = kKeyShift; break; | |||
| case 55: index = kKeyControl; break; | |||
| case 56: index = kKeyAlt; break; | |||
| case 58: index = kKeyMenu; break; | |||
| case 52: index = kKeyNumLock; break; | |||
| case 53: index = kKeyScrollLock; break; | |||
| case 5: index = kKeyPause; break; | |||
| } | |||
| switch (special) | |||
| switch (index) | |||
| { | |||
| case kKeyShift: | |||
| if (down) | |||
| @@ -356,15 +355,26 @@ public: | |||
| break; | |||
| } | |||
| if (special != 0) | |||
| { | |||
| fUI.handlePluginSpecial(down, static_cast<Key>(special), fKeyboardModifiers); | |||
| return 1; | |||
| } | |||
| if (index > 0) | |||
| { | |||
| // keyboard events must always be lowercase | |||
| bool needsShiftRevert = false; | |||
| if (index >= 'A' && index <= 'Z') | |||
| { | |||
| index += 'a' - 'A'; // A-Z -> a-z | |||
| if ((fKeyboardModifiers & kModifierShift) == 0x0) | |||
| { | |||
| needsShiftRevert = true; | |||
| fKeyboardModifiers |= kModifierShift; | |||
| } | |||
| } | |||
| fUI.handlePluginKeyboard(down, static_cast<uint>(index), fKeyboardModifiers); | |||
| if (needsShiftRevert) | |||
| fKeyboardModifiers &= ~kModifierShift; | |||
| return 1; | |||
| } | |||
| @@ -260,21 +260,23 @@ public: | |||
| #if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
| bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) | |||
| { | |||
| // TODO also trigger Character input event | |||
| DGL_NAMESPACE::Widget::KeyboardEvent ev; | |||
| ev.mod = mods; | |||
| ev.press = press; | |||
| ev.key = key; | |||
| ev.mod = mods; | |||
| return ui->onKeyboard(ev); | |||
| } | |||
| ev.key = key; | |||
| bool handlePluginSpecial(const bool press, const DGL_NAMESPACE::Key key, const uint16_t mods) | |||
| { | |||
| DGL_NAMESPACE::Widget::SpecialEvent ev; | |||
| ev.press = press; | |||
| ev.key = key; | |||
| ev.mod = mods; | |||
| return ui->onSpecial(ev); | |||
| const bool ret = ui->onKeyboard(ev); | |||
| DGL_NAMESPACE::Widget::CharacterInputEvent cev; | |||
| cev.mod = mods; | |||
| cev.character = key; | |||
| // if shift modifier is on, convert a-z -> A-Z for character input | |||
| if (key >= 'a' && key <= 'z' && (mods & kModifierShift) != 0) | |||
| cev.character -= 'a' - 'A'; | |||
| ui->onCharacterInput(cev); | |||
| return ret; | |||
| } | |||
| #endif | |||