diff --git a/Graphics/public/EventHandler.hpp b/Graphics/public/EventHandler.hpp index c62bd89..ea35c89 100644 --- a/Graphics/public/EventHandler.hpp +++ b/Graphics/public/EventHandler.hpp @@ -87,6 +87,7 @@ namespace tp { [[nodiscard]] halnf getPointerPressure() const; void setEnableKeyEvents(bool); + [[nodiscard]] bool isKeyEventsEnabled() const { return mEnableKeyEvents; } private: void processEventUnguarded(); diff --git a/Widgets/examples/Example.cpp b/Widgets/examples/Example.cpp index 45b5331..b29d341 100644 --- a/Widgets/examples/Example.cpp +++ b/Widgets/examples/Example.cpp @@ -13,7 +13,7 @@ using namespace tp; class Example : public WidgetApplication { public: Example() { - examplePopup(); + exampleNestedMenus(); } void exampleAll() { diff --git a/Widgets/private/RootWidget.cpp b/Widgets/private/RootWidget.cpp index 2de6ea2..78f2c17 100644 --- a/Widgets/private/RootWidget.cpp +++ b/Widgets/private/RootWidget.cpp @@ -58,7 +58,9 @@ void RootWidget::processFrame(EventHandler* events, const RectF& screenArea) { updateAreaCache(&mRoot, false); // trigger some widgets by moise pointer - mUpdateManager.handleFocusChanges(&mRoot, *events); + auto prevFocus = mUpdateManager.getFocusWidget(); + auto newFocus = mUpdateManager.findFocusWidget(&mRoot, *events); + mUpdateManager.handleFocusChanges(newFocus, prevFocus); // check triggered widgets for removal mUpdateManager.clean(); diff --git a/Widgets/private/managers/DebugManager.cpp b/Widgets/private/managers/DebugManager.cpp index 921f7e1..bd0de0a 100644 --- a/Widgets/private/managers/DebugManager.cpp +++ b/Widgets/private/managers/DebugManager.cpp @@ -113,14 +113,17 @@ void DebugManager::recursiveDraw(Canvas& canvas, Widget* active, const Vec2F& po canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color); } + if (active == mRootWidget->mUpdateManager.mFocusLockWidget) { + canvas.frame(area, { 0, 1, 0, 1 }); + } + if (active->mFlags.get(Widget::IN_FOCUS)) { if (active->isUpdate()) { canvas.circle(pos + active->mDebug.pLocal, 5, active->mDebug.col); canvas.circle(active->mDebug.pGlobal, 15, active->mDebug.col); } - RGBA color = { 1, 0, 0, 0.3f }; - canvas.debugCross(area, color); + canvas.debugCross(area, { 0, 1, 0, 1 }); } int orderIdx = 0; diff --git a/Widgets/private/managers/UpdateManager.cpp b/Widgets/private/managers/UpdateManager.cpp index 57e8475..c02c8e7 100644 --- a/Widgets/private/managers/UpdateManager.cpp +++ b/Widgets/private/managers/UpdateManager.cpp @@ -69,14 +69,11 @@ void UpdateManager::getWidgetPath(Widget* widget, std::vector& out) { } } -void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { - auto prevFocus = mInFocusWidget; - +Widget* UpdateManager::findFocusWidget(Widget* root, EventHandler& events) { events.setCursorOrigin({ 0, 0 }); mInFocusWidget = nullptr; - - findFocusWidget(root, &mInFocusWidget, events.getPointer()); + findMouseFocusWidget(root, &mInFocusWidget, events.getPointer()); if (mFocusLockWidget) { bool hasLockedWidget = false; @@ -91,13 +88,17 @@ void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { } } - // if (mInFocusWidget == prevFocus) return; - if (mInFocusWidget) scheduleUpdate(mInFocusWidget, "focus entered"); + return mInFocusWidget; +} - if (!mInFocusWidget && !prevFocus) return; +void UpdateManager::handleFocusChanges(Widget* active, Widget* prevActive) { + // if (mInFocusWidget == prevFocus) return; + if (active) scheduleUpdate(active, "focus entered"); + + if (!active && !prevActive) return; std::vector path2; - getWidgetPath(mInFocusWidget, path2); + getWidgetPath(active, path2); size_t propLen2 = path2.size(); for (auto i = 0; i < path2.size(); i++) { if (!path2[i]->propagateEventsToChildren()) { @@ -107,7 +108,7 @@ void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { } std::vector path1; - getWidgetPath(prevFocus, path1); + getWidgetPath(prevActive, path1); size_t propLen1 = path1.size(); for (auto i = 0; i < path1.size(); i++) { if (!path1[i]->propagateEventsToChildren()) { @@ -135,7 +136,7 @@ void UpdateManager::handleFocusChanges(Widget* root, EventHandler& events) { } } -void UpdateManager::findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { +void UpdateManager::findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer) { if (!iter->mArea.getTargetRect().isInside(pointer) || !iter->mFlags.get(Widget::ENABLED)) return; if (iter->processesEvents()) { @@ -143,7 +144,7 @@ void UpdateManager::findFocusWidget(Widget* iter, Widget** focus, const Vec2F& p } for (auto child = iter->mDepthOrder.lastNode(); child; child = child->prev) { - findFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); + findMouseFocusWidget(child->data, focus, pointer - iter->mArea.getTargetRect().pos); } } @@ -215,6 +216,6 @@ void UpdateManager::lockFocus(tp::Widget* widget) { } void UpdateManager::freeFocus(tp::Widget* widget) { - // DEBUG_ASSERT(mFocusLockWidget == widget) + DEBUG_ASSERT(mFocusLockWidget == widget) mFocusLockWidget = nullptr; } \ No newline at end of file diff --git a/Widgets/private/widgets/ScrollableWidget.cpp b/Widgets/private/widgets/ScrollableWidget.cpp index e67f0fa..81836c1 100644 --- a/Widgets/private/widgets/ScrollableWidget.cpp +++ b/Widgets/private/widgets/ScrollableWidget.cpp @@ -7,9 +7,10 @@ using namespace tp; void ScrollableBarWidget::process(const EventHandler& events) { // all content is visible no need to process anything if (mSizeFactor >= 1) { + if (mScrolling) freeFocus(); + mScrolling = false; mPosFactor = mSizeFactor / 2.f; - freeFocus(); return; } diff --git a/Widgets/public/Widget.hpp b/Widgets/public/Widget.hpp index 6c3ca28..40f7207 100644 --- a/Widgets/public/Widget.hpp +++ b/Widgets/public/Widget.hpp @@ -31,6 +31,8 @@ namespace tp { using DFSAction = std::function; + protected: + enum Flags : int1 { ENABLED = 0, NEEDS_UPDATE, diff --git a/Widgets/public/mangers/DebugManager.hpp b/Widgets/public/mangers/DebugManager.hpp index 0b4ce92..6c84ef8 100644 --- a/Widgets/public/mangers/DebugManager.hpp +++ b/Widgets/public/mangers/DebugManager.hpp @@ -87,7 +87,7 @@ namespace tp { bool mDebug = false; bool mDebugStopProcessing = false; bool mDebugRedrawAlways = false; - bool mDetailed = false; + bool mDetailed = true; std::set mProcBreakpoints; std::set mLayBreakpoints; diff --git a/Widgets/public/mangers/UpdateManager.hpp b/Widgets/public/mangers/UpdateManager.hpp index 33c5ecf..f97ba62 100644 --- a/Widgets/public/mangers/UpdateManager.hpp +++ b/Widgets/public/mangers/UpdateManager.hpp @@ -25,13 +25,16 @@ namespace tp { void clean(); void updateTreeToProcess(Widget* root); - void handleFocusChanges(Widget* root, EventHandler& events); + void handleFocusChanges(Widget* active, Widget* prevActive); + Widget* findFocusWidget(Widget* root, EventHandler& events); - void findFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); + void findMouseFocusWidget(Widget* iter, Widget** focus, const Vec2F& pointer); static void getWidgetPath(Widget* widget, std::vector& out); void processActiveTree(Widget* iter, EventHandler& events, Vec2F pos); void processFocusItems(EventHandler& events); + Widget* getFocusWidget() { return mInFocusWidget; } + private: static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false);