From c524ece546df1daefb94f1449215a9da48c43db9 Mon Sep 17 00:00:00 2001 From: Alexander Zhylin Date: Wed, 26 Nov 2025 17:57:34 +0200 Subject: [PATCH] ncurses template --- Makefile | 10 ++++- TODO.md | 1 + src/main.c | 87 ++++++++++++++++++++++++++++++++++------ src/ui/app.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/app.h | 32 +++++++++++++++ 5 files changed, 225 insertions(+), 14 deletions(-) create mode 100644 src/ui/app.c create mode 100644 src/ui/app.h diff --git a/Makefile b/Makefile index 9491643..9dc6ff5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS := -ggdb -Wall -pedantic +CFLAGS := -ggdb -Wall -pedantic -lcurses SRC_DIR := src OBJ_DIR := src/obj @@ -7,9 +7,15 @@ BIN_DIR := bin SRCS := $(wildcard $(SRC_DIR)/*.c) OBJS := $(SRCS:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) +UI_SRCS := $(wildcard $(SRC_DIR)/ui/*.c $(SRC_DIR)/ui/**/*.c) +OBJS += $(UI_SRCS:$(SRC_DIR)/ui/%.c=$(OBJ_DIR)/ui/%.o) + $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/main.h $(CC) $(CFLAGS) -c $< -o $@ +$(OBJ_DIR)/ui/%.o: $(SRC_DIR)/ui/%.c $(SRC_DIR)/ui/%.h + $(CC) $(CFLAGS) -c $< -o $@ + bbs-client: $(OBJS) $(CC) $(CFLAGS) $^ -o $(BIN_DIR)/$@ @@ -21,7 +27,7 @@ deps.mk: $(SRCS) $(CC) -MM $^ > $(SRC_DIR)/$@ clean: - rm -f $(OBJ_DIR)/*.o $(BIN_DIR)/bbs-client + rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/**/*.o $(BIN_DIR)/bbs-client run: $(BIN_DIR)/bbs-client diff --git a/TODO.md b/TODO.md index 349a124..5c3d246 100644 --- a/TODO.md +++ b/TODO.md @@ -1,2 +1,3 @@ TODO: +- [ ] More universal Makefile - [ ] Check and fix registration and login \ No newline at end of file diff --git a/src/main.c b/src/main.c index 4240e1f..43a80c3 100644 --- a/src/main.c +++ b/src/main.c @@ -1,23 +1,86 @@ #include "main.h" #include #include +#include #include #include #include #include #include -/* TODO: перед загрузкой файла спрашивать права доступа - TODO: сделать при интерфес выбора по пунктам меню */ +#include "ui/app.h" +#include + +void event_loop(app_t *app); + +int main(int argc, char **argv) { + app_t *app; + app = calloc(1, sizeof(app_t)); + + init_nc(); + + app = init_app(); + + wrefresh(app->menu_win); + wrefresh(app->action_win); + + event_loop(app); + + destroy_app(app); + endwin(); -int main(int argc, char *argv[]) { - params_t params; - init_params(¶ms); - analyze_args(argc, argv, ¶ms); - get_missing_params(¶ms); - int sd = init_client(); - connect_to_server(sd, ¶ms); - query_loop(sd, ¶ms); - clear_params(¶ms); return 0; -} \ No newline at end of file +} + +void event_loop(app_t *app) { + int c; + + for (;;) { + c = wgetch(app->win); + + switch (c) { + // 113 is q key. This exits the program + case 113: + return; + case KEY_F(9): + return; + case 'e': + // ac_edit(app); + break; + // 27 is ESC key. Usage of ESC is not recommended, but for now this clears + // the menus + case 27: + // app->menu_bar->selected_menu = -1; + break; + // 9 or \t is horizontal tab + case 9: + // if (app->active == N_MENU) { + // app->active = N_ACTION; + // } else { + // app->active = N_MENU; + // } + break; + default: + break; + } + + draw_borders(app); + + wnoutrefresh(app->win); + wnoutrefresh(app->menu_win); + wnoutrefresh(app->action_win); + doupdate(); + }; +} + +// int main(int argc, char *argv[]) { +// params_t params; +// init_params(¶ms); +// analyze_args(argc, argv, ¶ms); +// get_missing_params(¶ms); +// int sd = init_client(); +// connect_to_server(sd, ¶ms); +// query_loop(sd, ¶ms); +// clear_params(¶ms); +// return 0; +// } \ No newline at end of file diff --git a/src/ui/app.c b/src/ui/app.c new file mode 100644 index 0000000..5dc7c0e --- /dev/null +++ b/src/ui/app.c @@ -0,0 +1,109 @@ +#include "app.h" +// #include "action.h" +#include + +void ac_file(WINDOW *win, int is_action_w); + +app_t *init_app() { + // get values from terminal size + int y_max, x_max; + getmaxyx(stdscr, y_max, x_max); + + // allocate app struct memory + app_t *_app = calloc(1, sizeof(app_t)); + + // associate values for screen size + _app->cur_y = y_max; + _app->cur_x = x_max; + + _app->win = newwin(_app->cur_y, _app->cur_x, 0, 0); + + // define the width for each sub window + int menu_w_x = x_max / 6; + int action_w_x = x_max - menu_w_x - 2; + + // create the menu window + _app->menu_win = newwin(y_max - 4, menu_w_x, 2, 1); + + // create the action window + _app->action_win = newwin(y_max - 4, action_w_x, 2, menu_w_x + 1); + + // dialogue + _app->modal.win = NULL; + + // print decorative bars + print_bars(_app); + + // here goes box borders + draw_borders(_app); + + // init menus +// _app->menus = malloc(3 * sizeof(menu_t)); +// _app->menus[0] = init_menu("(F)ile", 'f'); +// _app->menus[1] = init_menu("(E)dit", 'e'); +// _app->menus[2] = init_menu("(A)bout", 'a'); + + // set active window by default +// _app->active = N_MENU; + + // call the action window content by default +// ac_file(_app->action_win, _app->active); + + // refresh the windows + wnoutrefresh(_app->win); + wnoutrefresh(_app->menu_win); + wnoutrefresh(_app->action_win); + doupdate(); + + return _app; +} + +void init_nc() { + initscr(); + noecho(); + curs_set(0); + keypad(stdscr, TRUE); + + if (!has_colors()) { + printf("Your terminal does not support color\n"); + } else { + start_color(); + init_pair(1, COLOR_RED, COLOR_BLACK); + init_pair(2, COLOR_GREEN, COLOR_BLACK); + } +} + +void draw_borders(app_t *app) { + clear(); + box(app->win, 0, 0); + + // refresh the windows + wnoutrefresh(app->win); + wnoutrefresh(app->menu_win); + wnoutrefresh(app->action_win); + doupdate(); +} + +void print_bars(app_t *app) { + wattrset(app->win, A_REVERSE); + + // print top and bottom bars + for (int i = 1; i < app->cur_x - 1; i++) { + mvwprintw(app->win, 1, i, " "); + mvwprintw(app->win, app->cur_y - 2, i, " "); + } + + // add content to the top bar + mvwprintw(app->win, 1, 2, "example curses app | "); + mvwprintw(app->win, 1, 20, "size %d, %d", app->cur_x, app->cur_y); + + // add content to the bottom bar + mvwprintw(app->win, app->cur_y - 2, 2, "F1 - Help | F9 - Quit"); + + wattroff(app->win, A_REVERSE); +} + +void destroy_app(app_t *app) { + delwin(app->win); + free(app); +} diff --git a/src/ui/app.h b/src/ui/app.h new file mode 100644 index 0000000..9f4b37e --- /dev/null +++ b/src/ui/app.h @@ -0,0 +1,32 @@ +#ifndef N_APP_H +#define N_APP_H + +#include + +typedef enum { + none = 0, + login = 1, +} dialogue_e; + +typedef struct { + WINDOW *win; + WINDOW *menu_win; + WINDOW *action_win; + struct { + dialogue_e active; + WINDOW *win; + } modal; + + // menu_bar_t *menu_bar; + // menu_t *menus; + // active_win_e active; + int cur_y, cur_x; +} app_t; + +app_t *init_app(); +void init_nc(); +void destroy_app(app_t *app); +void draw_borders(app_t *app); +void print_bars(app_t *app); + +#endif // N_APP_H \ No newline at end of file