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 | |||