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

3
.gitignore vendored
View file

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

View file

@ -19,6 +19,10 @@ add_executable(${TARGET}
${SRC}/ui.cpp ${SRC}/ui.cpp
${SRC}/logger.cpp ${SRC}/logger.cpp
${SRC}/event.cpp ${SRC}/event.cpp
# Pages
${SRC}/pages/page1.cpp
${SRC}/pages/page2.cpp
# Main
${SRC}/main.cpp ${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 <string>
#include <thread> #include <thread>
#include "ui.h"
#include "event.h" #include "event.h"
#include "logger.h"
#include "ui.h"
#include "pages/page1.h"
#include "pages/page2.h"
using namespace ftxui; 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(); UserInterface &ui = UserInterface::GetInstance();
@ -26,11 +31,13 @@ int main(int argc, char **argv)
UserInterface &ui = UserInterface::GetInstance(); UserInterface &ui = UserInterface::GetInstance();
// Page declaration // Page declaration
// ScreenPageDebugger debugger(handler, screen); Page1 page1(handler);
// screen.add_screen(&launcher); Page2 page2(handler);
ui.add_screen(&page1);
ui.add_screen(&page2);
// Event handler function // Event handler function
handler.set_handler(handle); handler.set_handler(loop_event);
// Main logic // Main logic
std::thread t_event(&EventHandler::loop, &handler); 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 "logger.h"
#include "ui.h"
#include "toolBox.h" #include <ctime>
#include <cstring>
#include <cstdint>
#include "ftxui/component/component.hpp" #include "ftxui/component/component.hpp"
#include "ftxui/component/component_base.hpp" #include "ftxui/component/component_base.hpp"
#include "ftxui/component/event.hpp" #include "ftxui/component/event.hpp"
@ -12,8 +15,20 @@
using namespace ftxui; using namespace ftxui;
constexpr uint8_t LOGGER_OFFSET = 7; 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) if (state.is_placeholder)
state.element |= dim; state.element |= dim;
@ -21,60 +36,59 @@ inline ftxui::Element ScreenPageDebugger::transform(ftxui::InputState state)
if (state.focused) if (state.focused)
{ {
state.element |= color(Color::White); state.element |= color(Color::White);
input_selected = true; _input_selected = true;
} }
else else
{ {
input_selected = false; _input_selected = false;
} }
return state.element; return state.element;
} }
inline bool ScreenPageDebugger::catch_event(Event event) inline bool Page1::catch_event(Event event)
{ {
if (event.is_character()) if (event.is_character())
{ {
// Checking if it is a command... // Checking if it is a command...
} }
const int size = _render.get_screen()->dimy(); const int size = ui.get_screen()->dimy();
log_buffer.set_max_size(size - LOGGER_OFFSET); logger.set_max_size(size - LOGGER_OFFSET);
if (event == Event::Return) if (event == Event::Return)
{ {
send_event(EventType::SEND_COMMAND, cmd_str); logger.push_back(_input_str, LoggerType::PRINT);
} }
return (event == Event::Return); return (event == Event::Return);
} }
ftxui::Element ScreenPageDebugger::render_input() ftxui::Element Page1::render_input()
{ {
Element arrow = text("> "); Element arrow = text("> ");
if (input_selected) if (_input_selected)
arrow |= bgcolor(Color::White) | color(Color::Black); arrow |= bgcolor(Color::White) | color(Color::Black);
else else
arrow |= color(Color::Default) | bgcolor(Color::Default); arrow |= color(Color::Default) | bgcolor(Color::Default);
return vbox({separatorEmpty(), return vbox({separatorEmpty(),
text("Send an event"), text("Send a command"),
hbox({arrow, hbox({arrow,
input_event->Render()})}); _input_component->Render()})});
} }
ftxui::Element ScreenPageDebugger::render_log() ftxui::Element Page1::render_log()
{ {
Elements log_lines; Elements log_lines;
for (const auto &logger : log_buffer.get_buffer()) for (const auto &logger : logger.get_buffer())
{ {
if(logger.type == LoggerType::STUB) { if (logger.type == LoggerType::PRINT)
log_lines.push_back(hbox({ {
text(get_time_str(logger.epoch)) | dim, log_lines.push_back(hbox({text(get_time_str(logger.epoch)) | dim,
text(logger.str) text(logger.str)}));
})); }
} else { else if (logger.type == LoggerType::COMMAND)
log_lines.push_back(hbox({ {
text(logger.str) | italic | dim log_lines.push_back(hbox({text(logger.str) | italic | dim}));
}));
} }
} }
@ -86,28 +100,28 @@ ftxui::Element ScreenPageDebugger::render_log()
flex; 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); return window(text("status") | hcenter | bold, text("content") | center | dim, BorderStyle::EMPTY) | flex | size(WIDTH, GREATER_THAN, 30);
} }
ScreenPageDebugger::ScreenPageDebugger(EventHandler &handler, ScreenRender &sr) Page1::Page1(EventHandler &handler)
: ScreenPage(handler), _render(sr), input_selected(false) : Page(handler), _input_selected(false)
{ {
input_option.transform = [&](const InputState state) _input_option.transform = [&](const InputState state)
{ {
return this->transform(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(); }); { return render_input(); });
input |= CatchEvent( input |= CatchEvent(
[&](const Event &event) [&](const Event &event)
{ {
return this->catch_event(event); return catch_event(event);
}); });
Component log = Renderer([&]() Component log = Renderer([&]()
@ -123,8 +137,3 @@ ScreenPageDebugger::ScreenPageDebugger(EventHandler &handler, ScreenRender &sr)
input, input,
}); });
} }
Logger *ScreenPageDebugger::get_logger()
{
return &log_buffer;
}

View file

@ -1,5 +1,4 @@
#include "pages/launcher.h" #include "pages/page2.h"
#include "loader.h"
#include "ftxui/component/component.hpp" #include "ftxui/component/component.hpp"
#include "ftxui/component/component_base.hpp" #include "ftxui/component/component_base.hpp"
@ -9,49 +8,44 @@
using namespace ftxui; using namespace ftxui;
static const std::vector<std::string> _launcher_entries = { inline const std::vector<std::string> create_entries(const size_t num)
"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)); std::vector<std::string> ret;
// const std::string name = get_simple_name(_library_entries[_library_selected]); for (size_t i = 0; i < num; i++)
this->send_event(EventType::LAUNCH_INSTANCE, _library_entries[_library_selected]); ret.push_back("Sample " + std::to_string(num));
return ret;
} }
ScreenPageLauncher::ScreenPageLauncher(EventHandler &handler) static const std::vector<std::string> _entries = create_entries(50);
: ScreenPage(handler)
inline void Page2::change_screen()
{ {
// Will be used later: for now crashes the launcher because it instanciate some values... this->send_event(EventType::SWITCH_SCREEN, static_cast<size_t>(0));
// _library_entries = get_libraries(); }
_library_selected = 0;
_library = Radiobox(&_library_entries, &_library_selected);
_launcher_selected = 0; inline Element Page2::render_radiobox()
_launcher = Radiobox(&_launcher_entries, &_launcher_selected); {
return vbox({window(text("Select Sample"),
_radiobox->Render() | vscroll_indicator | frame) |
center | flex}) |
xflex_grow;
}
Component library_selection = Renderer(_library, [&] inline Element Page2::render_button()
{ return vbox({window(text("Select Library"), {
_library->Render() | vscroll_indicator | frame) | return vbox({_button->Render()}) | center | xflex;
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", [&] Page2::Page2(EventHandler &handler)
{ return on_launch(); })}); : Page(handler), _selected(0), _radiobox(Radiobox(&_entries, &_selected))
Component launch = Renderer(_launch_button, [&] {
{ return vbox({_launch_button->Render()}) | center | xflex; }); Component radiobox_component = Renderer(_radiobox, [&]
{ return render_radiobox(); });
_page = Container::Vertical({Container::Horizontal({library_selection, launcher_selection, launch}) | flex}); _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});
}