#include "gui.hpp" #include // for EXIT_SUCCESS #include // for milliseconds #include #include // for Event #include // for ftxui #include // for text, separator, Element, operator|, vbox, border #include // for allocator, shared_ptr #include // for operator+, to_string #include // for sleep_for #include "ftxui/component/component.hpp" // for CatchEvent, Renderer, operator|= #include "ftxui/component/loop.hpp" // for Loop #include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive #include using namespace ftxui; using namespace std; using namespace fmt; namespace fs = std::filesystem; void GUI::output(const string &msg) { lines.push_back(msg); } int GUI::main_loop(GameEngine &game, std::function runner) { auto screen = ScreenInteractive::Fullscreen(); screen.TrackMouse(true); // Create a component counting the number of frames drawn and event handled. float scroll_x = 0.1; float scroll_y = 1.0; auto status = Renderer([&] { return vbox({ text(fmt::format("HP {}", game.hit_points)), separator(), hbox({ text("HP "), gauge(game.hit_points / 100.0f), }), }); }); auto content = Renderer([&] { vector output; for(const auto line : lines) { output.push_back(text(line)); } return vbox(output); }); auto game_stuff = Renderer([&] { return vbox({ text("Welcome to...Turing's Tarpit!"), separator(), hbox({ text("left") | border | flex , text("middle") | border | flex, text("right") | border | flex, }) | yflex_grow }); }); auto build_log = Renderer(content, [&, content] { return content->Render() | focusPositionRelative(scroll_x, scroll_y) | frame | flex; }); auto component = Renderer(build_log, [&] { return vbox({ game_stuff->Render() | flex, separator(), build_log->Render() | vscroll_indicator | yframe | flex, separator(), status->Render() }) | border; }); component |= CatchEvent([&](Event) -> bool { return false; }); Loop loop(&screen, component); while (!loop.HasQuitted()) { int run_error = runner(); if(run_error != 0) output("RUNNER ERROR!!!! CATASTROPHIC!!!"); loop.RunOnce(); screen.Post(Event::Custom); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } return EXIT_SUCCESS; }