From 1a7aeb6c3b6b3a0683ca948ca54d63d06099acad Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 3 Jan 2019 15:17:14 -0500 Subject: [PATCH] Create event context for each event that is triggered --- include/app/ParamWidget.hpp | 1 + include/context.hpp | 4 +- include/event.hpp | 22 ++++++++--- include/ui/MenuOverlay.hpp | 4 +- include/ui/ScrollWidget.hpp | 2 +- include/ui/Slider.hpp | 2 +- include/widgets/OpaqueWidget.hpp | 28 +++++++------- include/widgets/Widget.hpp | 26 ++++++++++--- src/Core/MIDICCToCVInterface.cpp | 6 +-- src/Core/MIDITriggerToCVInterface.cpp | 2 +- src/app/Knob.cpp | 2 + src/app/LedDisplay.cpp | 2 +- src/app/ModuleBrowser.cpp | 26 +++++++------ src/app/ModuleWidget.cpp | 16 ++++---- src/app/ParamWidget.cpp | 6 +++ src/app/PortWidget.cpp | 2 +- src/app/RackWidget.cpp | 2 +- src/app/Scene.cpp | 24 ++++++------ src/app/Toolbar.cpp | 4 +- src/event.cpp | 56 ++++++++++++++++++--------- src/main.cpp | 2 +- src/ui/MenuItem.cpp | 6 ++- src/ui/TextField.cpp | 8 ++-- 23 files changed, 156 insertions(+), 97 deletions(-) diff --git a/include/app/ParamWidget.hpp b/include/app/ParamWidget.hpp index 382c6d04..47b06c3d 100644 --- a/include/app/ParamWidget.hpp +++ b/include/app/ParamWidget.hpp @@ -20,6 +20,7 @@ struct ParamWidget : OpaqueWidget { /** For legacy patch loading */ void fromJson(json_t *rootJ); void onButton(event::Button &e) override; + void onDragMove(event::DragMove &e) override; }; diff --git a/include/context.hpp b/include/context.hpp index a41cf1d9..097e6ce1 100644 --- a/include/context.hpp +++ b/include/context.hpp @@ -6,7 +6,7 @@ namespace rack { namespace event { - struct Context; + struct State; } struct Scene; @@ -15,7 +15,7 @@ struct Window; struct Context { - event::Context *event = NULL; + event::State *event = NULL; Scene *scene = NULL; Engine *engine = NULL; Window *window = NULL; diff --git a/include/event.hpp b/include/event.hpp index a46e54d4..416ae212 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -13,13 +13,25 @@ struct Widget; namespace event { -/** Base event class */ -struct Event { +struct Context { /** The Widget that consumes the event. - Set to `this` in your event handler method if consumed. This stops propagation of the event if applicable. */ - Widget *target = NULL; + Widget *consumed = NULL; +}; + + +/** Base event class */ +struct Event { + Context *context = NULL; + + void consume(Widget *w) const { + if (context) + context->consumed = w; + } + Widget *getConsumed() const { + return context ? context->consumed : NULL; + } }; @@ -208,7 +220,7 @@ struct Zoom : Event { }; -struct Context { +struct State { /** State widgets Don't set these directly unless you know what you're doing. Use the set*() methods instead. */ diff --git a/include/ui/MenuOverlay.hpp b/include/ui/MenuOverlay.hpp index d3fd9d00..c7daae79 100644 --- a/include/ui/MenuOverlay.hpp +++ b/include/ui/MenuOverlay.hpp @@ -23,7 +23,7 @@ struct MenuOverlay : OpaqueWidget { void onButton(event::Button &e) override { OpaqueWidget::onButton(e); - if (e.target == this && e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) { + if (e.getConsumed() == this && e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_LEFT) { requestedDelete = true; } } @@ -31,7 +31,7 @@ struct MenuOverlay : OpaqueWidget { void onHoverKey(event::HoverKey &e) override { OpaqueWidget::onHoverKey(e); - if (e.target == this && e.action == GLFW_PRESS && e.key == GLFW_KEY_ESCAPE) { + if (e.getConsumed() == this && e.action == GLFW_PRESS && e.key == GLFW_KEY_ESCAPE) { requestedDelete = true; } } diff --git a/include/ui/ScrollWidget.hpp b/include/ui/ScrollWidget.hpp index b7fea028..c1a05c5d 100644 --- a/include/ui/ScrollWidget.hpp +++ b/include/ui/ScrollWidget.hpp @@ -140,7 +140,7 @@ struct ScrollWidget : OpaqueWidget { void onHoverScroll(event::HoverScroll &e) override { offset = offset.minus(e.scrollDelta); - e.target = this; + e.consume(this); } }; diff --git a/include/ui/Slider.hpp b/include/ui/Slider.hpp index 9d0a4aaa..04448d44 100644 --- a/include/ui/Slider.hpp +++ b/include/ui/Slider.hpp @@ -51,7 +51,7 @@ struct Slider : OpaqueWidget { if (quantity) quantity->reset(); } - e.target = this; + e.consume(this); } }; diff --git a/include/widgets/OpaqueWidget.hpp b/include/widgets/OpaqueWidget.hpp index c5e2783d..74a29712 100644 --- a/include/widgets/OpaqueWidget.hpp +++ b/include/widgets/OpaqueWidget.hpp @@ -12,38 +12,38 @@ You may also call OpaqueWidget::on*() from the overridden method to continue rec struct OpaqueWidget : virtual Widget { void onHover(event::Hover &e) override { Widget::onHover(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onButton(event::Button &e) override { Widget::onButton(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onHoverKey(event::HoverKey &e) override { Widget::onHoverKey(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onHoverText(event::HoverText &e) override { Widget::onHoverText(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onHoverScroll(event::HoverScroll &e) override { Widget::onHoverScroll(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onDragHover(event::DragHover &e) override { Widget::onDragHover(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } void onPathDrop(event::PathDrop &e) override { Widget::onPathDrop(e); - if (!e.target) - e.target = this; + if (!e.getConsumed()) + e.consume(this); } }; diff --git a/include/widgets/Widget.hpp b/include/widgets/Widget.hpp index 937cf5e4..8d65c170 100644 --- a/include/widgets/Widget.hpp +++ b/include/widgets/Widget.hpp @@ -74,6 +74,22 @@ struct Widget { // Events + template + void recurseEvent(TMethod f, TEvent &e) { + for (auto it = children.rbegin(); it != children.rend(); it++) { + Widget *child = *it; + // Filter child by visibility + if (!child->visible) + continue; + + // Call child event handler + (child->*f)(e); + // Stop iterating if consumed + if (e.getConsumed()) + break; + } + } + template void recursePositionEvent(TMethod f, TEvent &e) { for (auto it = children.rbegin(); it != children.rend(); it++) { @@ -84,16 +100,14 @@ struct Widget { if (!child->box.contains(e.pos)) continue; - // Clone event so modifications do not up-propagate + // Clone event and adjust its position TEvent e2 = e; e2.pos = e.pos.minus(child->box.pos); // Call child event handler (child->*f)(e2); - // Up-propagate target if consumed - if (e2.target) { - e.target = e2.target; + // Stop iterating if consumed + if (e.getConsumed()) break; - } } } @@ -121,7 +135,7 @@ struct Widget { virtual void onPathDrop(event::PathDrop &e) {recursePositionEvent(&Widget::onPathDrop, e);} virtual void onAction(event::Action &e) {} virtual void onChange(event::Change &e) {} - virtual void onZoom(event::Zoom &e) {} + virtual void onZoom(event::Zoom &e) {recurseEvent(&Widget::onZoom, e);} }; diff --git a/src/Core/MIDICCToCVInterface.cpp b/src/Core/MIDICCToCVInterface.cpp index 5f51df1f..fdab3a55 100644 --- a/src/Core/MIDICCToCVInterface.cpp +++ b/src/Core/MIDICCToCVInterface.cpp @@ -135,7 +135,7 @@ struct MidiCcChoice : GridChoice { } void onSelect(event::Select &e) override { - e.target = this; + e.consume(this); module->learningId = id; focusCc = -1; } @@ -154,7 +154,7 @@ struct MidiCcChoice : GridChoice { focusCc = 0; focusCc = focusCc * 10 + (c - '0'); } - e.target = this; + e.consume(this); } void onSelectKey(event::SelectKey &e) override { @@ -163,7 +163,7 @@ struct MidiCcChoice : GridChoice { event::Deselect eDeselect; onDeselect(eDeselect); context()->event->selectedWidget = NULL; - e.target = this; + e.consume(this); } } } diff --git a/src/Core/MIDITriggerToCVInterface.cpp b/src/Core/MIDITriggerToCVInterface.cpp index 31fc173b..f206e35d 100644 --- a/src/Core/MIDITriggerToCVInterface.cpp +++ b/src/Core/MIDITriggerToCVInterface.cpp @@ -179,7 +179,7 @@ struct MidiTrigChoice : GridChoice { } void onSelect(event::Select &e) override { - e.target = this; + e.consume(this); module->learningId = id; } diff --git a/src/app/Knob.cpp b/src/app/Knob.cpp index 7f9fcff3..55ac1d61 100644 --- a/src/app/Knob.cpp +++ b/src/app/Knob.cpp @@ -38,6 +38,8 @@ void Knob::onDragMove(event::DragMove &e) { delta /= 16.f; quantity->moveValue(delta); } + + ParamWidget::onDragMove(e); } diff --git a/src/app/LedDisplay.cpp b/src/app/LedDisplay.cpp index 28fb34cd..cfdfc6a7 100644 --- a/src/app/LedDisplay.cpp +++ b/src/app/LedDisplay.cpp @@ -58,7 +58,7 @@ void LedDisplayChoice::onButton(event::Button &e) { if (e.action == GLFW_PRESS && (e.button == GLFW_MOUSE_BUTTON_LEFT || e.button == GLFW_MOUSE_BUTTON_RIGHT)) { event::Action eAction; onAction(eAction); - e.target = this; + e.consume(this); } } diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index caf14fd8..efc3fcf4 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -110,10 +110,12 @@ struct BrowserListItem : OpaqueWidget { } void doAction() { + event::Context eActionContext; event::Action eAction; - eAction.target = this; + eAction.context = &eActionContext; + eAction.consume(this); onAction(eAction); - if (eAction.target) { + if (eActionContext.consumed) { MenuOverlay *overlay = getAncestorOfType(); overlay->requestedDelete = true; } @@ -462,7 +464,7 @@ void AuthorItem::onAction(event::Action &e) { sAuthorFilter = author; moduleBrowser->clearSearch(); moduleBrowser->refreshSearch(); - e.target = this; + e.consume(this); } void TagItem::onAction(event::Action &e) { @@ -470,7 +472,7 @@ void TagItem::onAction(event::Action &e) { sTagFilter = tag; moduleBrowser->clearSearch(); moduleBrowser->refreshSearch(); - e.target = this; + e.consume(this); } void ClearFilterItem::onAction(event::Action &e) { @@ -478,7 +480,7 @@ void ClearFilterItem::onAction(event::Action &e) { sAuthorFilter = ""; sTagFilter = ""; moduleBrowser->refreshSearch(); - e.target = this; + e.consume(this); } void FavoriteRadioButton::onAction(event::Action &e) { @@ -515,40 +517,40 @@ void SearchModuleField::onSelectKey(event::SelectKey &e) { case GLFW_KEY_ESCAPE: { MenuOverlay *overlay = getAncestorOfType(); overlay->requestedDelete = true; - e.target = this; + e.consume(this); return; } break; case GLFW_KEY_UP: { moduleBrowser->moduleList->incrementSelection(-1); moduleBrowser->moduleList->scrollSelected(); - e.target = this; + e.consume(this); } break; case GLFW_KEY_DOWN: { moduleBrowser->moduleList->incrementSelection(1); moduleBrowser->moduleList->scrollSelected(); - e.target = this; + e.consume(this); } break; case GLFW_KEY_PAGE_UP: { moduleBrowser->moduleList->incrementSelection(-5); moduleBrowser->moduleList->scrollSelected(); - e.target = this; + e.consume(this); } break; case GLFW_KEY_PAGE_DOWN: { moduleBrowser->moduleList->incrementSelection(5); moduleBrowser->moduleList->scrollSelected(); - e.target = this; + e.consume(this); } break; case GLFW_KEY_ENTER: { BrowserListItem *item = moduleBrowser->moduleList->getSelectedItem(); if (item) { item->doAction(); - e.target = this; + e.consume(this); } } break; } } - if (!e.target) + if (!e.getConsumed()) TextField::onSelectKey(e); } diff --git a/src/app/ModuleWidget.cpp b/src/app/ModuleWidget.cpp index 3c424e3c..511b5a27 100644 --- a/src/app/ModuleWidget.cpp +++ b/src/app/ModuleWidget.cpp @@ -329,7 +329,7 @@ void ModuleWidget::onHover(event::Hover &e) { void ModuleWidget::onButton(event::Button &e) { OpaqueWidget::onButton(e); - if (e.target == this) { + if (e.getConsumed() == this) { if (e.button == 1) { createContextMenu(); } @@ -342,43 +342,43 @@ void ModuleWidget::onHoverKey(event::HoverKey &e) { case GLFW_KEY_I: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { reset(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_R: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { randomize(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_C: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { copyClipboard(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_V: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { pasteClipboard(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_D: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { context()->scene->rackWidget->cloneModule(this); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_U: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { disconnect(); - e.target = this; + e.consume(this); } } break; } } - if (!e.target) + if (!e.getConsumed()) OpaqueWidget::onHoverKey(e); } diff --git a/src/app/ParamWidget.cpp b/src/app/ParamWidget.cpp index cf1dbb04..85749983 100644 --- a/src/app/ParamWidget.cpp +++ b/src/app/ParamWidget.cpp @@ -39,5 +39,11 @@ void ParamWidget::onButton(event::Button &e) { OpaqueWidget::onButton(e); } +void ParamWidget::onDragMove(event::DragMove &e) { + if (quantity) { + DEBUG("%s", quantity->getString().c_str()); + } +} + } // namespace rack diff --git a/src/app/PortWidget.cpp b/src/app/PortWidget.cpp index 2aa4aaee..44362627 100644 --- a/src/app/PortWidget.cpp +++ b/src/app/PortWidget.cpp @@ -59,7 +59,7 @@ void PortWidget::onButton(event::Button &e) { // event::DragEnter eDragEnter; // onDragEnter(eDragEnter); } - e.target = this; + e.consume(this); } void PortWidget::onDragStart(event::DragStart &e) { diff --git a/src/app/RackWidget.cpp b/src/app/RackWidget.cpp index 0cbc7cd8..1db99fb1 100644 --- a/src/app/RackWidget.cpp +++ b/src/app/RackWidget.cpp @@ -551,7 +551,7 @@ void RackWidget::onDragHover(event::DragHover &e) { void RackWidget::onButton(event::Button &e) { OpaqueWidget::onButton(e); - if (e.target == this) { + if (e.getConsumed() == this) { if (e.action == GLFW_PRESS && e.button == GLFW_MOUSE_BUTTON_RIGHT) { moduleBrowserCreate(); } diff --git a/src/app/Scene.cpp b/src/app/Scene.cpp index c945c4ec..0eeb5b48 100644 --- a/src/app/Scene.cpp +++ b/src/app/Scene.cpp @@ -72,54 +72,54 @@ void Scene::onHoverKey(event::HoverKey &e) { case GLFW_KEY_N: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { rackWidget->reset(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_Q: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { context()->window->close(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_O: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { rackWidget->loadDialog(); - e.target = this; + e.consume(this); } if (context()->window->isModPressed() && context()->window->isShiftPressed()) { rackWidget->revert(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_S: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { rackWidget->saveDialog(); - e.target = this; + e.consume(this); } if (context()->window->isModPressed() && context()->window->isShiftPressed()) { rackWidget->saveAsDialog(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_V: { if (context()->window->isModPressed() && !context()->window->isShiftPressed()) { rackWidget->pastePresetClipboard(); - e.target = this; + e.consume(this); } } break; case GLFW_KEY_ENTER: case GLFW_KEY_KP_ENTER: { moduleBrowserCreate(); - e.target = this; + e.consume(this); } break; case GLFW_KEY_F11: { context()->window->setFullScreen(!context()->window->isFullScreen()); - e.target = this; + e.consume(this); } } } - if (!e.target) + if (!e.getConsumed()) OpaqueWidget::onHoverKey(e); } @@ -128,11 +128,11 @@ void Scene::onPathDrop(event::PathDrop &e) { const std::string &path = e.paths[0]; if (string::extension(path) == "vcv") { rackWidget->load(path); - e.target = this; + e.consume(this); } } - if (!e.target) + if (!e.getConsumed()) OpaqueWidget::onPathDrop(e); } diff --git a/src/app/Toolbar.cpp b/src/app/Toolbar.cpp index df855b56..579847b6 100644 --- a/src/app/Toolbar.cpp +++ b/src/app/Toolbar.cpp @@ -280,7 +280,7 @@ struct AccountEmailField : TextField { void onSelectKey(event::SelectKey &e) override { if (e.action == GLFW_PRESS && e.key == GLFW_KEY_TAB) { context()->event->selectedWidget = passwordField; - e.target = this; + e.consume(this); return; } TextField::onSelectKey(e); @@ -296,7 +296,7 @@ struct AccountPasswordField : PasswordField { void onSelectKey(event::SelectKey &e) override { if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) { logInItem->doAction(); - e.target = this; + e.consume(this); return; } PasswordField::onSelectKey(e); diff --git a/src/event.cpp b/src/event.cpp index b393815a..6f0601f5 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -6,7 +6,7 @@ namespace rack { namespace event { -void Context::setHovered(Widget *w) { +void State::setHovered(Widget *w) { if (w == hoveredWidget) return; @@ -25,7 +25,7 @@ void Context::setHovered(Widget *w) { } } -void Context::setDragged(Widget *w) { +void State::setDragged(Widget *w) { if (w == draggedWidget) return; @@ -44,7 +44,7 @@ void Context::setDragged(Widget *w) { } } -void Context::setDragHovered(Widget *w) { +void State::setDragHovered(Widget *w) { if (w == dragHoveredWidget) return; @@ -65,7 +65,7 @@ void Context::setDragHovered(Widget *w) { } } -void Context::setSelected(Widget *w) { +void State::setSelected(Widget *w) { if (w == selectedWidget) return; @@ -84,7 +84,7 @@ void Context::setSelected(Widget *w) { } } -void Context::finalizeWidget(Widget *w) { +void State::finalizeWidget(Widget *w) { if (hoveredWidget == w) setHovered(NULL); if (draggedWidget == w) setDragged(NULL); if (dragHoveredWidget == w) setDragHovered(NULL); @@ -92,15 +92,17 @@ void Context::finalizeWidget(Widget *w) { if (scrollWidget == w) scrollWidget = NULL; } -void Context::handleButton(math::Vec pos, int button, int action, int mods) { +void State::handleButton(math::Vec pos, int button, int action, int mods) { // event::Button + event::Context eButtonContext; event::Button eButton; + eButton.context = &eButtonContext; eButton.pos = pos; eButton.button = button; eButton.action = action; eButton.mods = mods; rootWidget->onButton(eButton); - Widget *clickedWidget = eButton.target; + Widget *clickedWidget = eButtonContext.consumed; if (button == GLFW_MOUSE_BUTTON_LEFT) { if (action == GLFW_PRESS) { @@ -135,7 +137,7 @@ void Context::handleButton(math::Vec pos, int button, int action, int mods) { // } } -void Context::handleHover(math::Vec pos, math::Vec mouseDelta) { +void State::handleHover(math::Vec pos, math::Vec mouseDelta) { if (draggedWidget) { // event::DragMove event::DragMove eDragMove; @@ -143,13 +145,15 @@ void Context::handleHover(math::Vec pos, math::Vec mouseDelta) { draggedWidget->onDragMove(eDragMove); // event::DragHover + event::Context eDragHoverContext; event::DragHover eDragHover; + eDragHover.context = &eDragHoverContext; eDragHover.pos = pos; eDragHover.mouseDelta = mouseDelta; eDragHover.origin = draggedWidget; rootWidget->onDragHover(eDragHover); - setDragHovered(eDragHover.target); + setDragHovered(eDragHoverContext.consumed); return; } @@ -163,67 +167,81 @@ void Context::handleHover(math::Vec pos, math::Vec mouseDelta) { // } // event::Hover + event::Context eHoverContext; event::Hover eHover; + eHover.context = &eHoverContext; eHover.pos = pos; eHover.mouseDelta = mouseDelta; rootWidget->onHover(eHover); - setHovered(eHover.target); + setHovered(eHoverContext.consumed); } -void Context::handleLeave() { +void State::handleLeave() { setDragHovered(NULL); setHovered(NULL); } -void Context::handleScroll(math::Vec pos, math::Vec scrollDelta) { +void State::handleScroll(math::Vec pos, math::Vec scrollDelta) { // event::HoverScroll + event::Context eHoverScrollContext; event::HoverScroll eHoverScroll; + eHoverScroll.context = &eHoverScrollContext; eHoverScroll.pos = pos; eHoverScroll.scrollDelta = scrollDelta; rootWidget->onHoverScroll(eHoverScroll); } -void Context::handleDrop(math::Vec pos, std::vector paths) { +void State::handleDrop(math::Vec pos, std::vector paths) { // event::PathDrop + event::Context ePathDropContext; event::PathDrop ePathDrop; + ePathDrop.context = &ePathDropContext; ePathDrop.pos = pos; ePathDrop.paths = paths; rootWidget->onPathDrop(ePathDrop); } -void Context::handleText(math::Vec pos, int codepoint) { +void State::handleText(math::Vec pos, int codepoint) { if (selectedWidget) { // event::SelectText + event::Context eSelectTextContext; event::SelectText eSelectText; + eSelectText.context = &eSelectTextContext; eSelectText.codepoint = codepoint; selectedWidget->onSelectText(eSelectText); - if (eSelectText.target) + if (eSelectTextContext.consumed) return; } // event::HoverText + event::Context eHoverTextContext; event::HoverText eHoverText; + eHoverText.context = &eHoverTextContext; eHoverText.pos = pos; eHoverText.codepoint = codepoint; rootWidget->onHoverText(eHoverText); } -void Context::handleKey(math::Vec pos, int key, int scancode, int action, int mods) { +void State::handleKey(math::Vec pos, int key, int scancode, int action, int mods) { if (selectedWidget) { // event::SelectKey + event::Context eSelectKeyContext; event::SelectKey eSelectKey; + eSelectKey.context = &eSelectKeyContext; eSelectKey.key = key; eSelectKey.scancode = scancode; eSelectKey.action = action; eSelectKey.mods = mods; selectedWidget->onSelectKey(eSelectKey); - if (eSelectKey.target) + if (eSelectKeyContext.consumed) return; } // event::HoverKey + event::Context eHoverKeyContext; event::HoverKey eHoverKey; + eHoverKey.context = &eHoverKeyContext; eHoverKey.pos = pos; eHoverKey.key = key; eHoverKey.scancode = scancode; @@ -232,9 +250,11 @@ void Context::handleKey(math::Vec pos, int key, int scancode, int action, int mo rootWidget->onHoverKey(eHoverKey); } -void Context::handleZoom() { +void State::handleZoom() { // event::Zoom + event::Context eZoomContext; event::Zoom eZoom; + eZoom.context = &eZoomContext; rootWidget->onZoom(eZoom); } diff --git a/src/main.cpp b/src/main.cpp index 590caee3..dcccecc9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -79,7 +79,7 @@ int main(int argc, char *argv[]) { // Initialize app context()->engine = new Engine; - context()->event = new event::Context; + context()->event = new event::State; context()->scene = new Scene; context()->scene->devMode = devMode; context()->event->rootWidget = context()->scene; diff --git a/src/ui/MenuItem.cpp b/src/ui/MenuItem.cpp index 496f10af..a7e6063e 100644 --- a/src/ui/MenuItem.cpp +++ b/src/ui/MenuItem.cpp @@ -61,11 +61,13 @@ void MenuItem::doAction() { if (disabled) return; + event::Context eActionContext; event::Action eAction; + eAction.context = &eActionContext; // Consume event by default, but allow action to un-consume it to prevent the menu from being removed. - eAction.target = this; + eAction.consume(this); onAction(eAction); - if (!eAction.target) + if (!eActionContext.consumed) return; Widget *overlay = getAncestorOfType(); diff --git a/src/ui/TextField.cpp b/src/ui/TextField.cpp index f6a13e35..b6dc4e38 100644 --- a/src/ui/TextField.cpp +++ b/src/ui/TextField.cpp @@ -47,7 +47,7 @@ void TextField::onHover(event::Hover &e) { } void TextField::onEnter(event::Enter &e) { - e.target = this; + e.consume(this); } void TextField::onSelectText(event::SelectText &e) { @@ -55,11 +55,11 @@ void TextField::onSelectText(event::SelectText &e) { std::string newText(1, (char) e.codepoint); insertText(newText); } - e.target = this; + e.consume(this); } void TextField::onSelectKey(event::SelectKey &e) { - if (e.action == GLFW_PRESS) { + if (e.action == GLFW_PRESS || e.action == GLFW_REPEAT) { switch (e.key) { case GLFW_KEY_BACKSPACE: { if (cursor == selection) { @@ -172,7 +172,7 @@ void TextField::onSelectKey(event::SelectKey &e) { cursor = math::clamp(cursor, 0, (int) text.size()); selection = math::clamp(selection, 0, (int) text.size()); - e.target = this; + e.consume(this); } }