#include #include #include namespace gui { template struct UIStack { using UIStackMap = std::flat_map>; UIStackMap screens{}; bool visible = false; UIStackMap::iterator $current{screens.begin()}; SCREEN_TYPE* $active = nullptr; void add(const std::string& name, std::shared_ptr screen) { screens.insert_or_assign(name, screen); update_active(screens.begin()); } void update_active(const UIStackMap::iterator& itr) { $current = itr; $active = (*$current).second.get(); } void set_active(const std::string& name) { assert(screens.contains(name) && "no screen with that name"); update_active(screens.find(name)); } void set_visible(bool new_value) { visible = new_value; } bool is_visible() { return visible; } void render(sf::RenderTarget& target) { assert($active != nullptr && "you didn't set active"); $active->render(target); } void update() { assert($active != nullptr && "you didn't set active"); $active->update(); } bool mouse(float x, float y, guecs::Modifiers mods = guecs::NO_MODS) { assert($active != nullptr && "you didn't set active"); return $active->mouse(x, y, mods); } bool move(const UIStackMap::iterator& itr, const UIStackMap::iterator& avoid, const UIStackMap::iterator& result) { if(itr != avoid) { update_active(result); return true; } else { return false; } } bool next() { return move($current + 1, screens.end(), $current + 1); } bool prev() { return move($current, screens.begin(), $current - 1); } void first() { update_active(screens.begin()); } void last() { update_active(screens.end() - 1); } const std::string& active_name() { assert($active != nullptr && "you didn't set active"); return (*$current).first; } std::shared_ptr active_ui() { assert($active != nullptr && "you didn't set active"); return (*$current).second; } std::shared_ptr at(const std::string& name) { return screens.at(name); } const UIStackMap::key_container_type& names() { return screens.keys(); } }; }