From f495ce029cb3a9b4c8309e4456e494f8b6b09967 Mon Sep 17 00:00:00 2001 From: ArthurSonzogni Date: Fri, 26 Jan 2024 18:32:44 +0100 Subject: [PATCH] Add example to use system ftxui Fixed: https://github.com/ArthurSonzogni/FTXUI/issues/814 --- doc/mainpage.md | 65 ++++++++-------- examples/component/button.cpp | 139 ++++++++++++++++++++-------------- 2 files changed, 116 insertions(+), 88 deletions(-) diff --git a/doc/mainpage.md b/doc/mainpage.md index 244989b..59494b9 100644 --- a/doc/mainpage.md +++ b/doc/mainpage.md @@ -50,42 +50,17 @@ int main(void) { └────┘└────────────────────────────────────┘└─────┘ ``` -# Build {#build} +## Configure {#configure} +### Using CMake and find_package {#build-cmake-find-package} -## Using CMake {#build-cmake} +Assuming FTXUI is available or installed on the system. -This is an example configuration for your **CMakeLists.txt** - -CMakeLists.txt +**CMakeLists.txt** ```cmake cmake_minimum_required (VERSION 3.11) - -# --- Fetch FTXUI -------------------------------------------------------------- -include(FetchContent) - -set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE) -FetchContent_Declare(ftxui - GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui - # Important: Specify a GIT_TAG XXXXX here. - GIT_TAG main -) - -FetchContent_GetProperties(ftxui) -if(NOT ftxui_POPULATED) - FetchContent_Populate(ftxui) - add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL) -endif() - -# ------------------------------------------------------------------------------ - -project(ftxui-starter - LANGUAGES CXX - VERSION 1.0.0 -) - +find_package(ftxui 5 REQUIRED) +project(ftxui-starter LANGUAGES CXX VERSION 1.0.0) add_executable(ftxui-starter src/main.cpp) -target_include_directories(ftxui-starter PRIVATE src) - target_link_libraries(ftxui-starter PRIVATE ftxui::screen PRIVATE ftxui::dom @@ -94,7 +69,33 @@ target_link_libraries(ftxui-starter ``` -Subsequently, you build the project in the standard fashion as follows: +### Using CMake and FetchContent {#build-cmake} + +If you want to fetch FTXUI using cmake: + +**CMakeLists.txt** +```cmake +cmake_minimum_required (VERSION 3.11) + +include(FetchContent) +set(FETCHCONTENT_UPDATES_DISCONNECTED TRUE) +FetchContent_Declare(ftxui + GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui + GIT_TAG main # Important: Specify a version or a commit hash here. +) +FetchContent_MakeAvailable(ftxui) + +project(ftxui-starter LANGUAGES CXX VERSION 1.0.0) +add_executable(ftxui-starter src/main.cpp) +target_link_libraries(ftxui-starter + PRIVATE ftxui::screen + PRIVATE ftxui::dom + PRIVATE ftxui::component # Not needed for this example. +) +``` + +## Build + ```bash mkdir build && cd build cmake .. diff --git a/examples/component/button.cpp b/examples/component/button.cpp index dda9dd3..86ff8f9 100644 --- a/examples/component/button.cpp +++ b/examples/component/button.cpp @@ -1,65 +1,92 @@ -// 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 shared_ptr, __shared_ptr_access -#include // for operator+, to_string +#include +#include +#include +#include -#include "ftxui/component/captured_mouse.hpp" // for ftxui -#include "ftxui/component/component.hpp" // for Button, Horizontal, Renderer -#include "ftxui/component/component_base.hpp" // for ComponentBase -#include "ftxui/component/screen_interactive.hpp" // for ScreenInteractive -#include "ftxui/dom/elements.hpp" // for separator, gauge, text, Element, operator|, vbox, border +#include +#include +#include using namespace ftxui; +using namespace std; -// This is a helper function to create a button with a custom style. -// The style is defined by a lambda function that takes an EntryState and -// returns an Element. -// We are using `center` to center the text inside the button, then `border` to -// add a border around the button, and finally `flex` to make the button fill -// the available space. -ButtonOption ButtonStyle() { - 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; -} +enum class ConnectionMethod { ByName, ByAddress }; + +void promptForConnectionMethod(); + +void promptForServerName(); +void promptForServerAddress(); +void promptForServerManager(); int main() { - int value = 50; + promptForConnectionMethod(); - // The tree of components. This defines how to navigate using the keyboard. - auto buttons = Container::Vertical({ - Container::Horizontal({ - Button( - "-1", [&] { value--; }, ButtonStyle()), - Button( - "+1", [&] { value++; }, ButtonStyle()), - }) | flex, - Container::Horizontal({ - Button( - "-10", [&] { value -= 10; }, ButtonStyle()), - Button( - "+10", [&] { value += 10; }, ButtonStyle()), - }) | flex, - }); - - // Modify the way to render them on screen: - auto component = Renderer(buttons, [&] { - return vbox({ - text("value = " + std::to_string(value)), - separator(), - buttons->Render() | flex, - }) | - flex | border; - }); - - auto screen = ScreenInteractive::Fullscreen(); - screen.Loop(component); return 0; } + +void promptForConnectionMethod() { + auto screen = ScreenInteractive::TerminalOutput(); + std::vector connect_choice{ + "Connect by name...", + "Connect by address and port...", + "Exit", + }; + int selected = 0; + MenuOption option; + option.on_enter = [&] { + if (selected == 0) { + promptForServerManager(); + } else if (selected == 1) { + promptForServerAddress(); + } else if (selected == 2) { + screen.Exit(); + } + }; + + auto connect_menu = Menu(&connect_choice, &selected, option); + + auto renderer = Renderer(connect_menu, [&] { + return vbox({ + text("Welcome, my client!") | color(Color::Red3Bis) | bold | + center, + text(""), + text("Selected = " + std::to_string(selected)) | + color(Color::LightGreenBis) | bold | center, + + text(""), + text("Welcome to my first working multiplayer game, Medium " + "Boxes.") | + color(Color::LightSkyBlue1), + text(""), + text("Now, choose how you'd prefer to connect to a server!") | + color(Color::LightCyan3) | center, + text(""), + connect_menu->Render() | border, + }) | + center; + }); + + screen.Loop(renderer); +} + +void promptForServerName() {} + +void promptForServerAddress() { + auto screen = ScreenInteractive::TerminalOutput(); +} + +void promptForServerManager() { + auto screen = ScreenInteractive::TerminalOutput(); + auto renderer = Renderer([&] { + return vbox({ + text("Now, please enter the server manager's address and " + "port, so that you'll be able to see all the available " + "public servers!") | + color(Color::LightGreenBis), + gauge(0), + }) | + center; + }); + + screen.Loop(renderer); +}