diff --git a/libs/ui/source/selector.cpp b/libs/ui/source/selector.cpp index 6b8e46c7..8d85778d 100644 --- a/libs/ui/source/selector.cpp +++ b/libs/ui/source/selector.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -246,6 +247,12 @@ namespace psemek::ui : event_interceptor { bool transparent() const override { return false; } + + ~opaque_event_interceptor() + { + int fuck = 42; + (void)fuck; + } }; } @@ -256,11 +263,13 @@ namespace psemek::ui if (!screen) return false; - auto event_interceptor= std::make_shared(); + auto event_interceptor = std::make_shared(); auto positioner = std::make_shared(); positioner->set_child(selector); event_interceptor->set_child(positioner); + auto loop = screen->loop(); + auto close = [selector_root = event_interceptor.get(), selector = selector.get(), on_canceled]{ if (on_canceled) on_canceled(); @@ -270,43 +279,53 @@ namespace psemek::ui p->remove_child(selector_root); }; - auto patch_callback = [&](struct selector * target){ + std::vector> old_callbacks; + + util::recursive([&](auto && self, struct selector * target) -> void{ + old_callbacks.push_back({target, target->on_selected()}); + for (std::size_t i = 0; i < target->size(); ++i) + if (auto s = target->submenu(i)) + self(s.get()); + })(selector.get()); + + auto revert_callbacks = [old_callbacks = util::to_shared(std::move(old_callbacks))]{ + for (auto & p : *old_callbacks) + p.first->on_selected(std::move(p.second)); + }; + + auto cancel = [close, revert_callbacks]{ + close(); + revert_callbacks(); + }; + + auto patch_callback_recursive = util::recursive([&](auto && self, struct selector * target) -> void { target->on_selected([target, close, cb = target->on_selected()](std::size_t index){ close(); if (cb) cb(index); target->on_selected(cb); }); - }; - auto patch_callback_recursive = util::recursive([&](auto && self, struct selector * target) -> void { - patch_callback(target); for (std::size_t i = 0; i < target->size(); ++i) if (auto s = target->submenu(i)) self(s.get()); }); patch_callback_recursive(selector.get()); - selector->on_selected([close, cb = selector->on_selected()](std::size_t index){ - close(); - if (cb) - cb(index); - }); - - event_interceptor->on_mouse_click([close](ui::mouse_click const & e) -> bool { + event_interceptor->on_mouse_click([loop, cancel](ui::mouse_click const & e) -> bool { if (e.down && (e.button == ui::mouse_button::right || e.button == ui::mouse_button::left)) { - close(); + loop->post(cancel); return true; } return false; }); - event_interceptor->on_key_press([close](key_press const & e) -> bool { + event_interceptor->on_key_press([loop, cancel](key_press const & e) -> bool { if (e.down && e.key == SDLK_ESCAPE) { - close(); + loop->post(cancel); return true; }