focus locking stack

This commit is contained in:
IlyaShurupov 2024-11-05 20:32:59 +03:00
parent 1bbce78a2e
commit b5e490a0f8
7 changed files with 34 additions and 15 deletions

View file

@ -19,4 +19,4 @@ add_executable(Sketch3DApp ./applications/Entry.cpp)
target_link_libraries(Sketch3DApp ${PROJECT_NAME}) target_link_libraries(Sketch3DApp ${PROJECT_NAME})
file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")
file(COPY "applications/Font.ttf" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/") file(COPY "../Graphics/rsc" DESTINATION "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/")

Binary file not shown.

View file

@ -150,9 +150,11 @@ void RootWidget::openPopup(Widget* widget) {
} }
void RootWidget::closePopup(Widget* widget) { void RootWidget::closePopup(Widget* widget) {
mPopups.removeChild(widget); if (mUpdateManager.canRemoveWidget(widget)) {
mUpdateManager.freeFocus(widget); mPopups.removeChild(widget);
mUpdateManager.removeWidget(widget);
}
} }
void RootWidget::lockFocus(Widget* widget) { mUpdateManager.lockFocus(widget); } void RootWidget::lockFocus(Widget* widget) { mUpdateManager.lockFocus(widget); }
void RootWidget::freeFocus(Widget* widget) { mUpdateManager.freeFocus(widget); } void RootWidget::freeFocus(Widget* widget) { mUpdateManager.freeFocus(widget); }

View file

@ -113,8 +113,8 @@ 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); canvas.text((active->mDebug.id + ":" + std::to_string(depthOrder)).c_str(), area, 22, Canvas::Align::LC, 2, color);
} }
if (active == mRootWidget->mUpdateManager.mFocusLockWidget) { if (mRootWidget->mUpdateManager.mFocusLockStack.find(active)) {
canvas.frame(area, { 0, 1, 0, 1 }); canvas.frame(area, { 0, 1, 0, 0.5f });
} }
if (active->mFlags.get(Widget::IN_FOCUS)) { if (active->mFlags.get(Widget::IN_FOCUS)) {

View file

@ -75,16 +75,16 @@ Widget* UpdateManager::findFocusWidget(Widget* root, EventHandler& events) {
mInFocusWidget = nullptr; mInFocusWidget = nullptr;
findMouseFocusWidget(root, &mInFocusWidget, events.getPointer()); findMouseFocusWidget(root, &mInFocusWidget, events.getPointer());
if (mFocusLockWidget) { if (mFocusLockStack.size()) {
bool hasLockedWidget = false; bool hasLockedWidget = false;
for (auto iter = mInFocusWidget; iter; iter = iter->mParent) { for (auto iter = mInFocusWidget; iter; iter = iter->mParent) {
if (iter == mFocusLockWidget) { if (iter == mFocusLockStack.last()) {
hasLockedWidget = true; hasLockedWidget = true;
break; break;
} }
} }
if (!hasLockedWidget) { if (!hasLockedWidget) {
mInFocusWidget = mFocusLockWidget; mInFocusWidget = mFocusLockStack.last();
} }
} }
@ -212,10 +212,24 @@ void UpdateManager::procWidget(Widget* widget, EventHandler& events, bool withEv
} }
void UpdateManager::lockFocus(tp::Widget* widget) { void UpdateManager::lockFocus(tp::Widget* widget) {
mFocusLockWidget = widget; DEBUG_ASSERT(mFocusLockStack.find(widget) == nullptr)
// TODO : check that widget is a child of top of the stack
mFocusLockStack.pushBack(widget);
} }
void UpdateManager::freeFocus(tp::Widget* widget) { void UpdateManager::freeFocus(tp::Widget* widget) {
DEBUG_ASSERT(mFocusLockWidget == widget) DEBUG_ASSERT(mFocusLockStack.last() == widget)
mFocusLockWidget = nullptr; mFocusLockStack.popBack();
} }
bool UpdateManager::canRemoveWidget(Widget* widget) const {
if (auto node = mFocusLockStack.find(widget)) {
if (node->next) return false;
}
return true;
}
void UpdateManager::removeWidget(Widget* widget) {
freeFocus(widget);
}

View file

@ -86,7 +86,7 @@ void DockWidget::process(const EventHandler& events) {
} }
} else if (events.isReleased(InputID::MOUSE1)) { } else if (events.isReleased(InputID::MOUSE1)) {
layout()->endResize(); layout()->endResize();
freeFocus(); if (layout()->isResizing()) freeFocus();
} }
if (layout()->isResizing()) { if (layout()->isResizing()) {

View file

@ -35,13 +35,16 @@ namespace tp {
Widget* getFocusWidget() { return mInFocusWidget; } Widget* getFocusWidget() { return mInFocusWidget; }
bool canRemoveWidget(Widget* widget) const;
void removeWidget(Widget* widget);
private: private:
static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false); static void procWidget(Widget* widget, EventHandler& events, bool withEvents = false);
private: private:
std::map<Widget*, bool> mTriggeredWidgets; std::map<Widget*, bool> mTriggeredWidgets;
Widget* mInFocusWidget = nullptr; Widget* mInFocusWidget = nullptr;
Widget* mFocusLockWidget = nullptr; List<Widget*> mFocusLockStack;
private: private:
int mDebugWidgetsToProcess = 0; int mDebugWidgetsToProcess = 0;