mirror of
https://github.com/yoboujon/ftxui_template.git
synced 2025-06-08 13:00:50 +02:00
Initial commit.
This commit is contained in:
commit
9c0343d6e7
15 changed files with 620 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
**/build/**
|
43
CMakeLists.txt
Normal file
43
CMakeLists.txt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
cmake_minimum_required(VERSION 3.18)
|
||||||
|
project(
|
||||||
|
ftxui_template
|
||||||
|
DESCRIPTION "FTXUI Template Project"
|
||||||
|
HOMEPAGE_URL "https://www.etheryo.fr/"
|
||||||
|
LANGUAGES CXX C
|
||||||
|
)
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
include(dependencies.cmake)
|
||||||
|
|
||||||
|
set(TARGET rmlui_test)
|
||||||
|
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||||
|
add_executable(${TARGET}
|
||||||
|
${SRC}/ui.cpp
|
||||||
|
${SRC}/logger.cpp
|
||||||
|
${SRC}/event.cpp
|
||||||
|
${SRC}/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Include folders
|
||||||
|
target_include_directories(${TARGET} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
target_include_directories(${TARGET} PRIVATE "${FTXUI_INCLUDE_DIRS}")
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
target_link_libraries(
|
||||||
|
${TARGET} PRIVATE
|
||||||
|
component
|
||||||
|
dom
|
||||||
|
screen
|
||||||
|
)
|
||||||
|
|
||||||
|
# Output folder
|
||||||
|
set_target_properties(${TARGET}
|
||||||
|
PROPERTIES
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
)
|
17
dependencies.cmake
Normal file
17
dependencies.cmake
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
cmake_minimum_required(VERSION 3.22) #FTXUI asks for CMake 3.22 and C++ 17
|
||||||
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(ftxui
|
||||||
|
GIT_REPOSITORY https://github.com/ArthurSonzogni/ftxui
|
||||||
|
GIT_TAG v6.0.2
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_GetProperties(ftxui)
|
||||||
|
if(NOT ftxui_POPULATED)
|
||||||
|
FetchContent_Populate(ftxui)
|
||||||
|
add_subdirectory(${ftxui_SOURCE_DIR} ${ftxui_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
set(FTXUI_INCLUDE_DIRS
|
||||||
|
"${ftxui_SOURCE_DIR}/include"
|
||||||
|
)
|
53
include/event.h
Normal file
53
include/event.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef HEADER_EVENT_FTXUI
|
||||||
|
#define HEADER_EVENT_FTXUI
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <any>
|
||||||
|
#include <functional>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
enum class EventType : uint8_t
|
||||||
|
{
|
||||||
|
SWITCH_SCREEN,
|
||||||
|
SEND_COMMAND,
|
||||||
|
LAUNCH_INSTANCE,
|
||||||
|
STOP,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EventPayload
|
||||||
|
{
|
||||||
|
EventType type;
|
||||||
|
std::any data;
|
||||||
|
};
|
||||||
|
|
||||||
|
class EventHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EventHandler();
|
||||||
|
void set_handler(std::function<void(EventHandler &, const EventPayload &)> function);
|
||||||
|
void loop();
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void add_event(const EventPayload &payload);
|
||||||
|
friend class Event;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _is_running;
|
||||||
|
std::function<void(EventHandler &, const EventPayload &)> _handler;
|
||||||
|
std::deque<EventPayload> _event_buffer;
|
||||||
|
std::mutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Event(EventHandler &eventhandler);
|
||||||
|
void send_event(const EventPayload &payload);
|
||||||
|
void send_event(const EventType &type, std::any data = {});
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventHandler &_event_handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HEADER_EVENT_FTXUI
|
46
include/logger.h
Normal file
46
include/logger.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef HEADER_LOGGER_FTXUI
|
||||||
|
#define HEADER_LOGGER_FTXUI
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
enum class LoggerType : uint8_t
|
||||||
|
{
|
||||||
|
_UNDEFINED,
|
||||||
|
PRINT,
|
||||||
|
COMMAND,
|
||||||
|
// You can add more here
|
||||||
|
_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoggerData
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
uint64_t epoch;
|
||||||
|
LoggerType type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Logger &GetInstance()
|
||||||
|
{
|
||||||
|
static Logger instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
void set_max_size(int size);
|
||||||
|
void push_back(std::string str, LoggerType type = LoggerType::_UNDEFINED);
|
||||||
|
const std::vector<LoggerData> &get_buffer(void) noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Logger();
|
||||||
|
~Logger();
|
||||||
|
void update_view();
|
||||||
|
|
||||||
|
size_t _maxSize;
|
||||||
|
std::vector<LoggerData> _buffer;
|
||||||
|
std::vector<LoggerData> _view;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HEADER_LOGGER_FTXUI
|
24
include/pages/page.h
Normal file
24
include/pages/page.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef HEADER_PAGE_FTXUI
|
||||||
|
#define HEADER_PAGE_FTXUI
|
||||||
|
|
||||||
|
#include <ftxui/component/component_base.hpp>
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
class ScreenPage : public Event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScreenPage(EventHandler &handler)
|
||||||
|
: Event(handler), _page()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Component *getPage()
|
||||||
|
{
|
||||||
|
return &_page;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ftxui::Component _page;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HEADER_PAGE_FTXUI
|
0
include/pages/page1.h
Normal file
0
include/pages/page1.h
Normal file
0
include/pages/page2.h
Normal file
0
include/pages/page2.h
Normal file
39
include/ui.h
Normal file
39
include/ui.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef HEADER_UI_FTXUI
|
||||||
|
#define HEADER_UI_FTXUI
|
||||||
|
|
||||||
|
#include "pages/page.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <ftxui/component/component_base.hpp>
|
||||||
|
#include <ftxui/component/screen_interactive.hpp>
|
||||||
|
#include <ftxui/component/component.hpp>
|
||||||
|
|
||||||
|
class UserInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static UserInterface &GetInstance()
|
||||||
|
{
|
||||||
|
static UserInterface instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::ScreenInteractive *get_screen();
|
||||||
|
void add_screen(ScreenPage *p);
|
||||||
|
void select_screen(size_t index);
|
||||||
|
void select_screen(const ScreenPage *p);
|
||||||
|
void start();
|
||||||
|
void update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
UserInterface();
|
||||||
|
~UserInterface();
|
||||||
|
|
||||||
|
ftxui::ScreenInteractive _screen;
|
||||||
|
std::vector<ScreenPage *> _pages;
|
||||||
|
ftxui::Component _page_container;
|
||||||
|
ftxui::Component _main_container;
|
||||||
|
ftxui::Component _main_renderer;
|
||||||
|
int _page_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HEADER_RENDER_FTXUI
|
63
src/event.cpp
Normal file
63
src/event.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
constexpr int64_t EVENT_LOOP_WAIT_MS = 100;
|
||||||
|
|
||||||
|
// Event
|
||||||
|
|
||||||
|
Event::Event(EventHandler &eventhandler)
|
||||||
|
: _event_handler(eventhandler)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::send_event(const EventPayload &payload)
|
||||||
|
{
|
||||||
|
_event_handler.add_event(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Event::send_event(const EventType &type, std::any data)
|
||||||
|
{
|
||||||
|
_event_handler.add_event({type, data});
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventHandler
|
||||||
|
|
||||||
|
EventHandler::EventHandler()
|
||||||
|
: _is_running(false), _event_buffer({})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandler::set_handler(std::function<void(EventHandler &, const EventPayload &)> function)
|
||||||
|
{
|
||||||
|
_handler = function;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandler::add_event(const EventPayload &payload)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
_event_buffer.push_back(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandler::loop()
|
||||||
|
{
|
||||||
|
_is_running = true;
|
||||||
|
while (_is_running)
|
||||||
|
{
|
||||||
|
if (!_event_buffer.empty())
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
EventPayload evt = _event_buffer.front();
|
||||||
|
_event_buffer.pop_front();
|
||||||
|
_handler(*this, evt);
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(EVENT_LOOP_WAIT_MS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandler::stop()
|
||||||
|
{
|
||||||
|
_is_running = false;
|
||||||
|
}
|
41
src/logger.cpp
Normal file
41
src/logger.cpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include "logger.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
constexpr int MAX_SIZE = 99;
|
||||||
|
|
||||||
|
Logger::Logger()
|
||||||
|
: _maxSize(MAX_SIZE), _buffer({})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::set_max_size(int size)
|
||||||
|
{
|
||||||
|
if (size == _maxSize)
|
||||||
|
return;
|
||||||
|
_maxSize = size;
|
||||||
|
update_view();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::push_back(std::string str, LoggerType type)
|
||||||
|
{
|
||||||
|
const uint64_t now = static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1));
|
||||||
|
_buffer.push_back({str, now, type});
|
||||||
|
update_view();
|
||||||
|
UserInterface::GetInstance().update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::update_view()
|
||||||
|
{
|
||||||
|
typename std::vector<LoggerData>::iterator itBegin = _buffer.begin();
|
||||||
|
if (_buffer.size() >= _maxSize)
|
||||||
|
itBegin = _buffer.end() - _maxSize;
|
||||||
|
|
||||||
|
_view.clear();
|
||||||
|
std::copy(itBegin, _buffer.end(), std::back_inserter(_view));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
const std::vector<LoggerData> &Logger::get_buffer(void) noexcept { return _view; }
|
43
src/main.cpp
Normal file
43
src/main.cpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include "ui.h"
|
||||||
|
#include "event.h"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
std::thread t_instance;
|
||||||
|
|
||||||
|
static inline void handle(EventHandler &handler, const EventPayload &payload)
|
||||||
|
{
|
||||||
|
UserInterface &ui = UserInterface::GetInstance();
|
||||||
|
|
||||||
|
if (payload.type == EventType::STOP)
|
||||||
|
handler.stop();
|
||||||
|
else if (payload.type == EventType::SWITCH_SCREEN)
|
||||||
|
ui.select_screen(std::any_cast<size_t>(payload.data));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
// Event/Screen
|
||||||
|
EventHandler handler;
|
||||||
|
UserInterface &ui = UserInterface::GetInstance();
|
||||||
|
|
||||||
|
// Page declaration
|
||||||
|
// ScreenPageDebugger debugger(handler, screen);
|
||||||
|
// screen.add_screen(&launcher);
|
||||||
|
|
||||||
|
// Event handler function
|
||||||
|
handler.set_handler(handle);
|
||||||
|
|
||||||
|
// Main logic
|
||||||
|
std::thread t_event(&EventHandler::loop, &handler);
|
||||||
|
ui.start();
|
||||||
|
|
||||||
|
// Finish
|
||||||
|
handler.stop();
|
||||||
|
t_event.join();
|
||||||
|
return 0;
|
||||||
|
}
|
130
src/pages/page1.cpp
Normal file
130
src/pages/page1.cpp
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
#include "pages/debugger.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
#include "toolBox.h"
|
||||||
|
|
||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
#include "ftxui/component/component_base.hpp"
|
||||||
|
#include "ftxui/component/event.hpp"
|
||||||
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
|
#include "ftxui/dom/elements.hpp"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
constexpr uint8_t LOGGER_OFFSET = 7;
|
||||||
|
|
||||||
|
inline ftxui::Element ScreenPageDebugger::transform(ftxui::InputState state)
|
||||||
|
{
|
||||||
|
if (state.is_placeholder)
|
||||||
|
state.element |= dim;
|
||||||
|
|
||||||
|
if (state.focused)
|
||||||
|
{
|
||||||
|
state.element |= color(Color::White);
|
||||||
|
input_selected = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
input_selected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.element;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ScreenPageDebugger::catch_event(Event event)
|
||||||
|
{
|
||||||
|
if (event.is_character())
|
||||||
|
{
|
||||||
|
// Checking if it is a command...
|
||||||
|
}
|
||||||
|
|
||||||
|
const int size = _render.get_screen()->dimy();
|
||||||
|
log_buffer.set_max_size(size - LOGGER_OFFSET);
|
||||||
|
if (event == Event::Return)
|
||||||
|
{
|
||||||
|
send_event(EventType::SEND_COMMAND, cmd_str);
|
||||||
|
}
|
||||||
|
return (event == Event::Return);
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Element ScreenPageDebugger::render_input()
|
||||||
|
{
|
||||||
|
Element arrow = text("> ");
|
||||||
|
if (input_selected)
|
||||||
|
arrow |= bgcolor(Color::White) | color(Color::Black);
|
||||||
|
else
|
||||||
|
arrow |= color(Color::Default) | bgcolor(Color::Default);
|
||||||
|
|
||||||
|
return vbox({separatorEmpty(),
|
||||||
|
text("Send an event"),
|
||||||
|
hbox({arrow,
|
||||||
|
input_event->Render()})});
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Element ScreenPageDebugger::render_log()
|
||||||
|
{
|
||||||
|
Elements log_lines;
|
||||||
|
for (const auto &logger : log_buffer.get_buffer())
|
||||||
|
{
|
||||||
|
if(logger.type == LoggerType::STUB) {
|
||||||
|
log_lines.push_back(hbox({
|
||||||
|
text(get_time_str(logger.epoch)) | dim,
|
||||||
|
text(logger.str)
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
log_lines.push_back(hbox({
|
||||||
|
text(logger.str) | italic | dim
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto log_content = vbox(std::move(log_lines)) | yframe;
|
||||||
|
|
||||||
|
return window(
|
||||||
|
text("log") | hcenter | bold,
|
||||||
|
log_content | vscroll_indicator | frame) |
|
||||||
|
flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::Element ScreenPageDebugger::render_status()
|
||||||
|
{
|
||||||
|
return window(text("status") | hcenter | bold, text("content") | center | dim, BorderStyle::EMPTY) | flex | size(WIDTH, GREATER_THAN, 30);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPageDebugger::ScreenPageDebugger(EventHandler &handler, ScreenRender &sr)
|
||||||
|
: ScreenPage(handler), _render(sr), input_selected(false)
|
||||||
|
{
|
||||||
|
input_option.transform = [&](const InputState state)
|
||||||
|
{
|
||||||
|
return this->transform(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
input_event = Input(&cmd_str, "Press 'enter' to send the event. Type '/help' for commands.", input_option);
|
||||||
|
|
||||||
|
Component input = Renderer(input_event, [&]()
|
||||||
|
{ return render_input(); });
|
||||||
|
|
||||||
|
input |= CatchEvent(
|
||||||
|
[&](const Event &event)
|
||||||
|
{
|
||||||
|
return this->catch_event(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
Component log = Renderer([&]()
|
||||||
|
{ return render_log(); });
|
||||||
|
|
||||||
|
Component status = Renderer([&]()
|
||||||
|
{ return render_status(); });
|
||||||
|
|
||||||
|
_page = Container::Vertical({
|
||||||
|
Container::Horizontal({log,
|
||||||
|
status}) |
|
||||||
|
yflex,
|
||||||
|
input,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger *ScreenPageDebugger::get_logger()
|
||||||
|
{
|
||||||
|
return &log_buffer;
|
||||||
|
}
|
57
src/pages/page2.cpp
Normal file
57
src/pages/page2.cpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include "pages/launcher.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
#include "ftxui/component/component_base.hpp"
|
||||||
|
#include "ftxui/component/event.hpp"
|
||||||
|
#include "ftxui/component/screen_interactive.hpp"
|
||||||
|
#include "ftxui/dom/elements.hpp"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
static const std::vector<std::string> _launcher_entries = {
|
||||||
|
"Legacy",
|
||||||
|
"Debug"};
|
||||||
|
|
||||||
|
static const std::vector<std::string> _library_entries = {
|
||||||
|
"Reply",
|
||||||
|
"UDP_IP",
|
||||||
|
"Emit",
|
||||||
|
"BOUCHON",
|
||||||
|
"Push"};
|
||||||
|
|
||||||
|
inline void ScreenPageLauncher::on_launch()
|
||||||
|
{
|
||||||
|
this->send_event(EventType::SWITCH_SCREEN, static_cast<size_t>(1));
|
||||||
|
// const std::string name = get_simple_name(_library_entries[_library_selected]);
|
||||||
|
this->send_event(EventType::LAUNCH_INSTANCE, _library_entries[_library_selected]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenPageLauncher::ScreenPageLauncher(EventHandler &handler)
|
||||||
|
: ScreenPage(handler)
|
||||||
|
{
|
||||||
|
// Will be used later: for now crashes the launcher because it instanciate some values...
|
||||||
|
// _library_entries = get_libraries();
|
||||||
|
_library_selected = 0;
|
||||||
|
_library = Radiobox(&_library_entries, &_library_selected);
|
||||||
|
|
||||||
|
_launcher_selected = 0;
|
||||||
|
_launcher = Radiobox(&_launcher_entries, &_launcher_selected);
|
||||||
|
|
||||||
|
Component library_selection = Renderer(_library, [&]
|
||||||
|
{ return vbox({window(text("Select Library"),
|
||||||
|
_library->Render() | vscroll_indicator | frame) |
|
||||||
|
center | flex}) |
|
||||||
|
xflex_grow; });
|
||||||
|
Component launcher_selection = Renderer(_launcher, [&]
|
||||||
|
{ return vbox({window(text("Select launcher"),
|
||||||
|
_launcher->Render() | vscroll_indicator | frame) |
|
||||||
|
center | flex}); });
|
||||||
|
|
||||||
|
_launch_button = Container::Vertical({Button("Launch", [&]
|
||||||
|
{ return on_launch(); })});
|
||||||
|
Component launch = Renderer(_launch_button, [&]
|
||||||
|
{ return vbox({_launch_button->Render()}) | center | xflex; });
|
||||||
|
|
||||||
|
_page = Container::Vertical({Container::Horizontal({library_selection, launcher_selection, launch}) | flex});
|
||||||
|
}
|
63
src/ui.cpp
Normal file
63
src/ui.cpp
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#include "ui.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include "ftxui/component/component.hpp"
|
||||||
|
|
||||||
|
using namespace ftxui;
|
||||||
|
|
||||||
|
UserInterface::UserInterface()
|
||||||
|
: _screen(ScreenInteractive::Fullscreen()), _pages({}), _page_container(), _main_container(), _main_renderer(), _page_index(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInterface::~UserInterface()
|
||||||
|
{
|
||||||
|
_screen.Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
ftxui::ScreenInteractive *UserInterface::get_screen()
|
||||||
|
{
|
||||||
|
return &_screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::add_screen(ScreenPage *p)
|
||||||
|
{
|
||||||
|
_pages.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::select_screen(size_t index)
|
||||||
|
{
|
||||||
|
_page_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::select_screen(const ScreenPage *p)
|
||||||
|
{
|
||||||
|
const typename std::vector<ScreenPage *>::iterator it = std::find(_pages.begin(), _pages.end(), p);
|
||||||
|
const size_t index = it - _pages.begin();
|
||||||
|
select_screen(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::start()
|
||||||
|
{
|
||||||
|
Components pages_component;
|
||||||
|
for (const auto &p : _pages)
|
||||||
|
pages_component.push_back(*(p->getPage()));
|
||||||
|
_page_container = Container::Tab(pages_component, &_page_index);
|
||||||
|
|
||||||
|
_main_container = Container::Vertical({
|
||||||
|
_page_container | flex,
|
||||||
|
});
|
||||||
|
|
||||||
|
_main_renderer = Renderer(_main_container, [&]
|
||||||
|
{ return vbox({
|
||||||
|
text("FTXUI Template") | inverted | hcenter,
|
||||||
|
separatorEmpty(),
|
||||||
|
_main_container->Render() | yflex_grow,
|
||||||
|
}); });
|
||||||
|
|
||||||
|
_screen.Loop(_main_renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::update()
|
||||||
|
{
|
||||||
|
_screen.PostEvent(ftxui::Event::Custom);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue