From 474831329dccad88293befab5732b6e3a2ead673 Mon Sep 17 00:00:00 2001 From: fy59 Date: Thu, 6 Aug 2026 14:20:36 +0200 Subject: [PATCH] feat: add modular Lardon3D TUI layout --- README.md | 6 +-- include/lardon3d/app.h | 6 +++ include/lardon3d/layout.h | 8 +++ include/lardon3d/tui.h | 10 ++++ include/scan3d/app.h | 14 ----- include/scan3d/tui.h | 18 ------- meson.build | 5 +- src/app.c | 17 +++--- src/layout.c | 106 ++++++++++++++++++++++++++++++++++++++ src/main.c | 4 +- src/tui.c | 62 +++------------------- 11 files changed, 156 insertions(+), 100 deletions(-) create mode 100644 include/lardon3d/app.h create mode 100644 include/lardon3d/layout.h create mode 100644 include/lardon3d/tui.h delete mode 100644 include/scan3d/app.h delete mode 100644 include/scan3d/tui.h create mode 100644 src/layout.c diff --git a/README.md b/README.md index 6dbfd3b..14757c0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Scan3D Vulkan +# Lardon3D -Scan3D Vulkan est une application terminal interactive dédiée à la reconstruction 3D. Cette première interface TUI utilise tout l'espace du terminal et s'adapte à son redimensionnement. +Lardon3D est une application terminal interactive dédiée à la reconstruction 3D. Son interface TUI utilise tout l'espace du terminal et s'adapte à son redimensionnement. Une vue Vulkan séparée sera ajoutée ultérieurement pour afficher la scène 3D. L'application actuelle n'ouvre aucune fenêtre graphique. @@ -22,7 +22,7 @@ meson compile -C build -j8 ## Exécution ```sh -./build/scan3d-vulkan +./build/lardon3d ``` La TUI s'affiche directement dans le terminal courant. Appuyez sur `q` ou `Q` pour quitter proprement. diff --git a/include/lardon3d/app.h b/include/lardon3d/app.h new file mode 100644 index 0000000..437757d --- /dev/null +++ b/include/lardon3d/app.h @@ -0,0 +1,6 @@ +#ifndef LARDON3D_APP_H +#define LARDON3D_APP_H + +int lardon3d_app_run(void); + +#endif diff --git a/include/lardon3d/layout.h b/include/lardon3d/layout.h new file mode 100644 index 0000000..4ef2026 --- /dev/null +++ b/include/lardon3d/layout.h @@ -0,0 +1,8 @@ +#ifndef LARDON3D_LAYOUT_H +#define LARDON3D_LAYOUT_H + +#include + +bool lardon3d_layout_draw(void); + +#endif diff --git a/include/lardon3d/tui.h b/include/lardon3d/tui.h new file mode 100644 index 0000000..88de4ce --- /dev/null +++ b/include/lardon3d/tui.h @@ -0,0 +1,10 @@ +#ifndef LARDON3D_TUI_H +#define LARDON3D_TUI_H + +#include + +bool lardon3d_tui_init(void); +bool lardon3d_tui_run(void); +void lardon3d_tui_shutdown(void); + +#endif diff --git a/include/scan3d/app.h b/include/scan3d/app.h deleted file mode 100644 index 729aee3..0000000 --- a/include/scan3d/app.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef SCAN3D_APP_H -#define SCAN3D_APP_H - -#ifdef __cplusplus -extern "C" { -#endif - -int scan3d_app_run(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SCAN3D_APP_H */ diff --git a/include/scan3d/tui.h b/include/scan3d/tui.h deleted file mode 100644 index 21058a4..0000000 --- a/include/scan3d/tui.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef SCAN3D_TUI_H -#define SCAN3D_TUI_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -bool scan3d_tui_init(void); -bool scan3d_tui_run(void); -void scan3d_tui_shutdown(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SCAN3D_TUI_H */ diff --git a/meson.build b/meson.build index 66926d4..416f934 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project( - 'scan3d-vulkan', + 'lardon3d', 'c', version: '0.1.0', license: 'MIT', @@ -20,11 +20,12 @@ add_project_arguments( ncursesw = dependency('ncursesw', required: true) executable( - 'scan3d-vulkan', + 'lardon3d', sources: [ 'src/main.c', 'src/app.c', 'src/tui.c', + 'src/layout.c', ], include_directories: include_directories('include'), dependencies: [ncursesw], diff --git a/src/app.c b/src/app.c index e8bf0bb..4791ece 100644 --- a/src/app.c +++ b/src/app.c @@ -1,17 +1,22 @@ +#include #include -#include -#include +#include +#include int -scan3d_app_run(void) +lardon3d_app_run(void) { - if (!scan3d_tui_init()) { + if (!setlocale(LC_ALL, "")) { return EXIT_FAILURE; } - bool success = scan3d_tui_run(); - scan3d_tui_shutdown(); + if (!lardon3d_tui_init()) { + return EXIT_FAILURE; + } + + bool success = lardon3d_tui_run(); + lardon3d_tui_shutdown(); return success ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/src/layout.c b/src/layout.c new file mode 100644 index 0000000..6e16485 --- /dev/null +++ b/src/layout.c @@ -0,0 +1,106 @@ +#include +#include +#include + +#include + +enum { + MINIMUM_ROWS = 20, + MINIMUM_COLUMNS = 72, +}; + +static void +draw_text(int row, int column, int available, const char *text) +{ + if (available <= 0) { + return; + } + + size_t length = strlen(text); + int displayed = length < (size_t)available ? (int)length : available; + (void)mvaddnstr(row, column, text, displayed); +} + +static void +draw_too_small(int rows, int columns) +{ + static const char message[] = "Terminal trop petit"; + int row = rows > 0 ? rows / 2 : 0; + int column = columns > (int)(sizeof(message) - 1) + ? (columns - (int)(sizeof(message) - 1)) / 2 + : 0; + + draw_text(row, column, columns, message); +} + +static void +draw_frame(int rows, int columns) +{ + int middle_column = columns / 2; + int journal_row = rows / 2; + int footer_row = rows - 3; + + (void)box(stdscr, 0, 0); + (void)mvhline(2, 1, ACS_HLINE, columns - 2); + (void)mvhline(journal_row, 1, ACS_HLINE, columns - 2); + (void)mvhline(footer_row, 1, ACS_HLINE, columns - 2); + (void)mvvline(3, middle_column, ACS_VLINE, journal_row - 3); + + (void)mvaddch(2, 0, ACS_LTEE); + (void)mvaddch(2, middle_column, ACS_TTEE); + (void)mvaddch(2, columns - 1, ACS_RTEE); + (void)mvaddch(journal_row, 0, ACS_LTEE); + (void)mvaddch(journal_row, middle_column, ACS_BTEE); + (void)mvaddch(journal_row, columns - 1, ACS_RTEE); + (void)mvaddch(footer_row, 0, ACS_LTEE); + (void)mvaddch(footer_row, columns - 1, ACS_RTEE); +} + +static void +draw_content(int rows, int columns) +{ + int middle_column = columns / 2; + int journal_row = rows / 2; + + draw_text(1, 2, middle_column - 3, "Lardon3D"); + draw_text(1, columns - 7, 5, "Heure"); + + draw_text(3, 2, middle_column - 3, "Projet"); + draw_text(5, 4, middle_column - 5, "Aucun projet chargé."); + + draw_text(3, middle_column + 2, columns - middle_column - 3, "Informations"); + draw_text(5, middle_column + 4, columns - middle_column - 5, "Lardon3D"); + draw_text(6, middle_column + 4, columns - middle_column - 5, "Reconstruction 3D"); + draw_text(7, middle_column + 4, columns - middle_column - 5, "Version 0.1"); + + draw_text(journal_row + 1, 2, columns - 4, "Journal"); + draw_text(journal_row + 3, 4, columns - 6, "Bienvenue dans Lardon3D"); + + draw_text( + rows - 2, + 2, + columns - 4, + "F1 Aide F2 Projet F3 Import F4 Viewer Q Quit" + ); +} + +bool +lardon3d_layout_draw(void) +{ + int rows; + int columns; + getmaxyx(stdscr, rows, columns); + + if (erase() == ERR) { + return false; + } + + if (rows < MINIMUM_ROWS || columns < MINIMUM_COLUMNS) { + draw_too_small(rows, columns); + } else { + draw_frame(rows, columns); + draw_content(rows, columns); + } + + return refresh() != ERR; +} diff --git a/src/main.c b/src/main.c index 8904ed1..9317df5 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ -#include +#include int main(void) { - return scan3d_app_run(); + return lardon3d_app_run(); } diff --git a/src/tui.c b/src/tui.c index ac79f45..ed98e9e 100644 --- a/src/tui.c +++ b/src/tui.c @@ -1,59 +1,11 @@ #include #include -#include -#include -#include - -static void -draw_centered(int row, int rows, int columns, const char *text) -{ - if (row < 0 || row >= rows || columns <= 2) { - return; - } - - int length = (int)strlen(text); - int available = columns - 2; - int displayed = length < available ? length : available; - int column = (columns - displayed) / 2; - - (void)mvaddnstr(row, column, text, displayed); -} - -static bool -draw_interface(void) -{ - int rows; - int columns; - getmaxyx(stdscr, rows, columns); - - if (erase() == ERR) { - return false; - } - - if (rows >= 2 && columns >= 2) { - (void)box(stdscr, 0, 0); - } - - draw_centered(1, rows, columns, "Scan3D Vulkan"); - draw_centered(3, rows, columns, "Projet de reconstruction 3D"); - - char dimensions[64]; - (void)snprintf( - dimensions, - sizeof(dimensions), - "Terminal : %d x %d", - columns, - rows - ); - draw_centered(5, rows, columns, dimensions); - draw_centered(rows - 2, rows, columns, "q : quitter"); - - return refresh() != ERR; -} +#include +#include bool -scan3d_tui_init(void) +lardon3d_tui_init(void) { if (!initscr()) { return false; @@ -69,9 +21,9 @@ scan3d_tui_init(void) } bool -scan3d_tui_run(void) +lardon3d_tui_run(void) { - if (!draw_interface()) { + if (!lardon3d_layout_draw()) { return false; } @@ -83,14 +35,14 @@ scan3d_tui_run(void) if (key == ERR) { return false; } - if (key == KEY_RESIZE && !draw_interface()) { + if (key == KEY_RESIZE && !lardon3d_layout_draw()) { return false; } } } void -scan3d_tui_shutdown(void) +lardon3d_tui_shutdown(void) { endwin(); }