#include #include #include #include namespace psemek::ui { namespace { struct opaque_event_interceptor : event_interceptor { bool transparent() const override { return false; } }; } bool spawn(element * root, std::shared_ptr element, math::point const & position) { ui::screen * screen = find_last_parent_of_type(root); if (!screen) return false; auto event_interceptor = std::make_shared(); auto positioner = std::make_shared(); positioner->set_child(element); event_interceptor->set_child(positioner); auto loop = screen->loop(); auto close = [root = event_interceptor.get()]{ auto p = dynamic_cast(root->parent()); if (p) p->remove_child(root); }; event_interceptor->on_mouse_click([loop, close](ui::mouse_click const & e) -> bool { if (e.down && (e.button == ui::mouse_button::right || e.button == ui::mouse_button::left)) { loop->post(close); return true; } return false; }); event_interceptor->on_key_press([loop, close](key_press const & e) -> bool { if (e.down && e.key == SDLK_ESCAPE) { loop->post(close); return true; } return false; }); event_interceptor->on_mouse_move([](mouse_move const &){ return true; }); send_fake_mouse_move_event(event_interceptor.get(), true); positioner->set_position(position, positioner::x_align::left, positioner::y_align::top); screen->add_child(event_interceptor, screen::x_policy::fill, screen::y_policy::fill); return true; } }