Added page1 and page2 examples.

This commit is contained in:
Yohan Boujon 2025-05-08 17:57:41 +02:00
parent 09528d1b93
commit 7186ad418c
7 changed files with 149 additions and 84 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
**/build/**
.vscode

View file

@ -19,6 +19,10 @@ add_executable(${TARGET}
${SRC}/ui.cpp
${SRC}/logger.cpp
${SRC}/event.cpp
# Pages
${SRC}/pages/page1.cpp
${SRC}/pages/page2.cpp
# Main
${SRC}/main.cpp
)

View file

@ -0,0 +1,28 @@
#ifndef HEADER_PAGE1_FTXUI
#define HEADER_PAGE1_FTXUI
#include "pages/page.h"
#include <string>
#include <ftxui/component/component_options.hpp>
#include <ftxui/component/component_base.hpp>
#include <ftxui/component/event.hpp>
#include <ftxui/dom/node.hpp>
class Page1 : public Page {
public:
Page1(EventHandler &handler);
private:
ftxui::Element transform(ftxui::InputState state);
ftxui::Element render_input();
ftxui::Element render_log();
ftxui::Element render_status();
bool catch_event(ftxui::Event event);
std::string _input_str;
ftxui::InputOption _input_option;
bool _input_selected;
ftxui::Component _input_component;
};
#endif // HEADER_PAGE1_FTXUI

View file

@ -0,0 +1,22 @@
#ifndef HEADER_PAGE2_FTXUI
#define HEADER_PAGE2_FTXUI
#include "pages/page.h"
#include <ftxui/component/component_base.hpp>
#include <ftxui/dom/node.hpp>
class Page2 : public Page {
public:
Page2(EventHandler &handler);
private:
void change_screen();
ftxui::Element render_radiobox();
ftxui::Element render_button();
int _selected;
ftxui::Component _radiobox;
ftxui::Component _button;
};
#endif // HEADER_PAGE2_FTXUI

View file

@ -2,14 +2,19 @@
#include <string>
#include <thread>
#include "ui.h"
#include "event.h"
#include "logger.h"
#include "ui.h"
#include "pages/page1.h"
#include "pages/page2.h"
using namespace ftxui;
std::thread t_instance;
UserInterface& ui = UserInterface::GetInstance();
Logger& logger = Logger::GetInstance();
static inline void handle(EventHandler &handler, const EventPayload &payload)
static inline void loop_event(EventHandler &handler, const EventPayload &payload)
{
UserInterface &ui = UserInterface::GetInstance();
@ -26,11 +31,13 @@ int main(int argc, char **argv)
UserInterface &ui = UserInterface::GetInstance();
// Page declaration
// ScreenPageDebugger debugger(handler, screen);
// screen.add_screen(&launcher);
Page1 page1(handler);
Page2 page2(handler);
ui.add_screen(&page1);
ui.add_screen(&page2);
// Event handler function
handler.set_handler(handle);
handler.set_handler(loop_event);
// Main logic
std::thread t_event(&EventHandler::loop, &handler);

View file

@ -1,8 +1,11 @@
#include "pages/debugger.h"
#include "pages/page1.h"
#include "logger.h"
#include "ui.h"
#include "toolBox.h"
#include <ctime>
#include <cstring>
#include <cstdint>
#include "ftxui/component/component.hpp"
#include "ftxui/component/component_base.hpp"
#include "ftxui/component/event.hpp"
@ -12,8 +15,20 @@
using namespace ftxui;
constexpr uint8_t LOGGER_OFFSET = 7;
static UserInterface &ui = UserInterface::GetInstance();
static Logger &logger = Logger::GetInstance();
static char time_buffer[11];
inline ftxui::Element ScreenPageDebugger::transform(ftxui::InputState state)
inline static const char *get_time_str(uint64_t epoch)
{
std::tm epoch_time;
const std::time_t time_epoch = epoch;
memcpy(&epoch_time, localtime(&time_epoch), sizeof(struct tm));
snprintf(time_buffer, 12, "[%02d:%02d:%02d]", epoch_time.tm_hour, epoch_time.tm_min, epoch_time.tm_sec);
return time_buffer;
}
inline ftxui::Element Page1::transform(ftxui::InputState state)
{
if (state.is_placeholder)
state.element |= dim;
@ -21,60 +36,59 @@ inline ftxui::Element ScreenPageDebugger::transform(ftxui::InputState state)
if (state.focused)
{
state.element |= color(Color::White);
input_selected = true;
_input_selected = true;
}
else
{
input_selected = false;
_input_selected = false;
}
return state.element;
}
inline bool ScreenPageDebugger::catch_event(Event event)
inline bool Page1::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);
const int size = ui.get_screen()->dimy();
logger.set_max_size(size - LOGGER_OFFSET);
if (event == Event::Return)
{
send_event(EventType::SEND_COMMAND, cmd_str);
logger.push_back(_input_str, LoggerType::PRINT);
}
return (event == Event::Return);
}
ftxui::Element ScreenPageDebugger::render_input()
ftxui::Element Page1::render_input()
{
Element arrow = text("> ");
if (input_selected)
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"),
text("Send a command"),
hbox({arrow,
input_event->Render()})});
_input_component->Render()})});
}
ftxui::Element ScreenPageDebugger::render_log()
ftxui::Element Page1::render_log()
{
Elements log_lines;
for (const auto &logger : log_buffer.get_buffer())
for (const auto &logger : logger.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
}));
if (logger.type == LoggerType::PRINT)
{
log_lines.push_back(hbox({text(get_time_str(logger.epoch)) | dim,
text(logger.str)}));
}
else if (logger.type == LoggerType::COMMAND)
{
log_lines.push_back(hbox({text(logger.str) | italic | dim}));
}
}
@ -86,28 +100,28 @@ ftxui::Element ScreenPageDebugger::render_log()
flex;
}
ftxui::Element ScreenPageDebugger::render_status()
ftxui::Element Page1::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)
Page1::Page1(EventHandler &handler)
: Page(handler), _input_selected(false)
{
input_option.transform = [&](const InputState state)
_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);
_input_component = Input(&_input_str, "Press 'enter' to send the text.", _input_option);
Component input = Renderer(input_event, [&]()
Component input = Renderer(_input_component, [&]()
{ return render_input(); });
input |= CatchEvent(
[&](const Event &event)
{
return this->catch_event(event);
return catch_event(event);
});
Component log = Renderer([&]()
@ -123,8 +137,3 @@ ScreenPageDebugger::ScreenPageDebugger(EventHandler &handler, ScreenRender &sr)
input,
});
}
Logger *ScreenPageDebugger::get_logger()
{
return &log_buffer;
}

View file

@ -1,5 +1,4 @@
#include "pages/launcher.h"
#include "loader.h"
#include "pages/page2.h"
#include "ftxui/component/component.hpp"
#include "ftxui/component/component_base.hpp"
@ -9,49 +8,44 @@
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()
inline const std::vector<std::string> create_entries(const size_t num)
{
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]);
std::vector<std::string> ret;
for (size_t i = 0; i < num; i++)
ret.push_back("Sample " + std::to_string(num));
return ret;
}
ScreenPageLauncher::ScreenPageLauncher(EventHandler &handler)
: ScreenPage(handler)
static const std::vector<std::string> _entries = create_entries(50);
inline void Page2::change_screen()
{
// 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});
this->send_event(EventType::SWITCH_SCREEN, static_cast<size_t>(0));
}
inline Element Page2::render_radiobox()
{
return vbox({window(text("Select Sample"),
_radiobox->Render() | vscroll_indicator | frame) |
center | flex}) |
xflex_grow;
}
inline Element Page2::render_button()
{
return vbox({_button->Render()}) | center | xflex;
}
Page2::Page2(EventHandler &handler)
: Page(handler), _selected(0), _radiobox(Radiobox(&_entries, &_selected))
{
Component radiobox_component = Renderer(_radiobox, [&]
{ return render_radiobox(); });
_button = Container::Vertical({Button("Go to Page1", [&]
{ return change_screen(); })});
Component button_component = Renderer(_button, [&]
{ return render_button(); });
_page = Container::Vertical({Container::Horizontal({button_component, radiobox_component}) | flex});
}