// Copyright 2020 Arthur Sonzogni. All rights reserved. // Use of this source code is governed by the MIT license that can be found in // the LICENSE file. #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; ButtonOption Style() { auto option = ButtonOption::Animated(); option.transform = [](const EntryState& s) { auto element = text(s.label); if (s.focused) { element |= bold; } return element | center | borderEmpty | flex; }; return option; } int main() { auto screen = ScreenInteractive::Fullscreen(); screen.TrackMouse(true); vector lines; // Create a component counting the number of frames drawn and event handled. int custom_loop_count = 0; int frame_count = 0; int event_count = 0; float scroll_x = 0.1; float scroll_y = 1.0; int hp = 100; int row = 0; auto hit_button = Button("Hit", [&] { hp -= 1; lines.push_back(fmt::format("You were hit! HP now {}", hp)); }, Style()); auto hard_button = Button("Hard", [&] { hp -= 10; lines.push_back(fmt::format("You were hit HARD! HP now {}", hp)); }, Style()); auto heal_button = Button("Heal", [&] { hp += 10; lines.push_back(fmt::format("You healed! HP now {}", hp)); }, Style()); auto buttons = Container::Horizontal({ hit_button, hard_button, heal_button}, &row); auto status = Renderer([&] { return vbox({ paragraph(fmt::format("HP {} frames {} events {} custom {}", hp, frame_count, event_count, custom_loop_count)), separator(), hbox({ text("HP"), gauge(hp / 100.0f), }), }); }); auto content = Renderer([&] { vector output; for(const auto line : lines) { output.push_back(text(line)); } return vbox(output); }); auto scrollable_content = Renderer(content, [&, content] { return content->Render() | focusPositionRelative(scroll_x, scroll_y) | frame | flex; }); auto component = Renderer(buttons, [&] { frame_count++; return vbox({ status->Render(), separator(), buttons->Render(), scrollable_content->Render() | vscroll_indicator | yframe | size(HEIGHT, LESS_THAN, 20), }) | border; }); component |= CatchEvent([&](Event) -> bool { event_count++; return false; }); Loop loop(&screen, component); while (!loop.HasQuitted()) { custom_loop_count++; loop.RunOnce(); screen.Post(Event::Custom); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } return EXIT_SUCCESS; }