Created a UIStack component that handles multiple screens.
This commit is contained in:
parent
d393cf91ab
commit
543928eb36
7 changed files with 121 additions and 18 deletions
2
Makefile
2
Makefile
|
|
@ -65,7 +65,7 @@ debug: build
|
|||
gdb --nx -x .gdbinit --ex run --args builddir/runtests
|
||||
|
||||
debug_run: build
|
||||
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome
|
||||
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/multiscreen
|
||||
|
||||
debug_walk: build test
|
||||
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/under_the_dome t
|
||||
|
|
|
|||
|
|
@ -140,3 +140,11 @@ executable('fragviewer',
|
|||
include_directories: inc_dirs,
|
||||
override_options: exe_defaults,
|
||||
dependencies: dependencies)
|
||||
|
||||
executable('multiscreen',
|
||||
[ 'tools/multiscreen.cpp' ],
|
||||
cpp_args: cpp_args,
|
||||
link_args: link_args,
|
||||
include_directories: inc_dirs,
|
||||
override_options: exe_defaults,
|
||||
dependencies: dependencies)
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@ namespace scene {
|
|||
}
|
||||
|
||||
void Engine::init() {
|
||||
dbc::log($F("initialized scene with background {}", $scene.background));
|
||||
|
||||
$gui.position(SCENE_VIEW_X, SCENE_VIEW_Y, SCENE_VIEW_WIDTH, SCENE_VIEW_HEIGHT);
|
||||
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser, guecs::THEME.TRANSPARENT});
|
||||
auto& background = $gui.get<guecs::Background>($gui.MAIN);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ namespace gui {
|
|||
$main_ui.init();
|
||||
$loot_ui.init();
|
||||
|
||||
for(auto& [name, scene] : $scenes) {
|
||||
scene->init();
|
||||
for(auto& name : $screens.screens.keys()) {
|
||||
$screens.screens[name]->init();
|
||||
}
|
||||
|
||||
// BUG: maybe this is a function on main_ui?
|
||||
|
|
@ -326,8 +326,8 @@ namespace gui {
|
|||
void FSM::mouse_action(guecs::Modifiers mods) {
|
||||
sf::Vector2f pos = mouse_position();
|
||||
|
||||
if($cur_scene != nullptr) {
|
||||
$cur_scene->mouse(pos.x, pos.y, mods);
|
||||
if($screens.is_visible()) {
|
||||
$screens.mouse(pos.x, pos.y, mods);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -415,8 +415,8 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::draw_gui() {
|
||||
if($cur_scene != nullptr) {
|
||||
$cur_scene->render($window);
|
||||
if($screens.is_visible()) {
|
||||
$screens.render($window);
|
||||
} else if($story != nullptr) {
|
||||
$story->render($window);
|
||||
} else {
|
||||
|
|
@ -432,8 +432,8 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::update() {
|
||||
if($cur_scene != nullptr) {
|
||||
$cur_scene->update();
|
||||
if($screens.is_visible()) {
|
||||
$screens.update();
|
||||
} else if($story != nullptr) {
|
||||
$story->update();
|
||||
}
|
||||
|
|
@ -564,12 +564,12 @@ namespace gui {
|
|||
}
|
||||
|
||||
void FSM::show_scene(const std::string& name) {
|
||||
dbc::check($scenes.contains(name), $F("$scenes does not contain {}", name));
|
||||
$cur_scene = $scenes[name];
|
||||
$screens.set_active(name);
|
||||
$screens.set_visible(true);
|
||||
}
|
||||
|
||||
void FSM::close_scene() {
|
||||
$cur_scene = nullptr;
|
||||
$screens.set_visible(false);
|
||||
}
|
||||
|
||||
void FSM::player_died() {
|
||||
|
|
@ -584,7 +584,7 @@ namespace gui {
|
|||
|
||||
if(level.index < levels_to_win) {
|
||||
show_scene("NEXT_LEVEL");
|
||||
$cur_scene->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2));
|
||||
$screens.current_ui()->set_text(fmt::format("ENTERING\nLEVEL\n{}", level.index+2));
|
||||
state(State::NEXT_LEVEL_SCENE);
|
||||
} else {
|
||||
show_scene("WIN");
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "events.hpp"
|
||||
#include "gui/scene_ui.hpp"
|
||||
#include "gui/storyboard.hpp"
|
||||
#include "gui/uistack.hpp"
|
||||
|
||||
namespace gui {
|
||||
enum class State {
|
||||
|
|
@ -43,14 +44,14 @@ namespace gui {
|
|||
gui::routing::Router $router;
|
||||
DNDLoot $dnd_loot;
|
||||
System::Registry $systems;
|
||||
std::unordered_map<std::string, std::shared_ptr<gui::SceneUI>> $scenes{
|
||||
|
||||
gui::UIStack<gui::SceneUI> $screens{.screens={
|
||||
{"STARTING", std::make_shared<gui::SceneUI>("STARTING")},
|
||||
{"DEATH", std::make_shared<gui::SceneUI>("DEATH")},
|
||||
{"WIN", std::make_shared<gui::SceneUI>("WIN")},
|
||||
{"NEXT_LEVEL", std::make_shared<gui::SceneUI>("NEXT_LEVEL")},
|
||||
};
|
||||
}};
|
||||
|
||||
std::shared_ptr<gui::SceneUI> $cur_scene = nullptr;
|
||||
std::shared_ptr<storyboard::UI> $story = nullptr;
|
||||
bool $display_help = false;
|
||||
|
||||
|
|
|
|||
6
src/gui/uistack.cpp
Normal file
6
src/gui/uistack.cpp
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#include "multiscreen.hpp"
|
||||
|
||||
namespace gui {
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
}
|
||||
90
src/gui/uistack.hpp
Normal file
90
src/gui/uistack.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#include <guecs/ui.hpp>
|
||||
#include "dbc.hpp"
|
||||
#include "constants.hpp"
|
||||
#include <flat_map>
|
||||
|
||||
namespace gui {
|
||||
template<typename SCREEN_TYPE>
|
||||
struct UIStack {
|
||||
using UIStackMap = std::flat_map<std::string, std::shared_ptr<SCREEN_TYPE>>;
|
||||
|
||||
UIStackMap screens{};
|
||||
bool visible = false;
|
||||
|
||||
UIStackMap::iterator $current{screens.begin()};
|
||||
SCREEN_TYPE* $active = nullptr;
|
||||
|
||||
void add(const std::string& name, std::shared_ptr<SCREEN_TYPE> 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) {
|
||||
dbc::check(screens.contains(name), $F("screen {} not in stack", 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) {
|
||||
dbc::check($active != nullptr, "you didn't set active");
|
||||
$active->render(target);
|
||||
}
|
||||
|
||||
void update() {
|
||||
dbc::check($active != nullptr, "you didn't set active");
|
||||
$active->update();
|
||||
}
|
||||
|
||||
bool mouse(float x, float y, guecs::Modifiers mods = guecs::NO_MODS) {
|
||||
dbc::check($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& current_name() {
|
||||
dbc::check($active != nullptr, "you didn't set active");
|
||||
return (*$current).first;
|
||||
}
|
||||
|
||||
std::shared_ptr<SCREEN_TYPE> current_ui() {
|
||||
dbc::check($active != nullptr, "you didn't set active");
|
||||
return (*$current).second;
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue