donstranding

Don Stranding
git clone git://git.kocotian.pl/donstranding.git
Log | Files | Refs | Submodules | README | LICENSE

commit 86798607288bbb21d4667d32f5d4e4291f446d2c
parent a9ebbc4b16d2444a1dfd08103eb01033fb6d77ae
Author: kocotian <kocotian@kocotian.pl>
Date:   Sun,  2 May 2021 21:51:26 +0200

Simple main menu

Diffstat:
Aconfig.h | 10++++++++++
Mdonstranding.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ainclude/tui.h | 10++++++++++
Atui.c | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atui.o | 0
5 files changed, 174 insertions(+), 0 deletions(-)

diff --git a/config.h b/config.h @@ -0,0 +1,10 @@ +typedef enum Colorscheme { + ColorBlack = 0x000000, ColorLBlack = 0x928374, + ColorRed = 0xcc241d, ColorLRed = 0xfb4934, + ColorGreen = 0x98971a, ColorLGreen = 0xb8bb26, + ColorYellow = 0xd79921, ColorLYellow = 0xfabd2f, + ColorBlue = 0x458588, ColorLBlue = 0x83a598, + ColorMagenta = 0xb16286, ColorLMagenta = 0xd3869b, + ColorCyan = 0x689d6a, ColorLCyan = 0x8ec07c, + ColorWhite = 0xa89984, ColorLWhite = 0xebdbb2, +} Colorscheme; diff --git a/donstranding.c b/donstranding.c @@ -1,7 +1,97 @@ #include <stdio.h> +#include <string.h> + +#include <tui.h> +#include <util.h> + +#include "config.h" + +typedef enum { + MSSingle, MSMulti, MSQuit, + MSLen +} MenuSelections; + +static void drawoption(int w, int y, const char *label, int focused); +static void drawmenu(void); +static int mainmenu(void); + +static const char *title[] = { + " ____ ____ _ __ _______________ ___ _ ______ _____ ________", + " / __ \\/ __ \\/ | / / / ___/_ __/ __ \\/ | / | / / __ \\/ _/ | / / ____/", + " / / / / / / / |/ / \\__ \\ / / / /_/ / /| | / |/ / / / // // |/ / / __ ", + " / /_/ / /_/ / /| / ___/ // / / _, _/ ___ |/ /| / /_/ // // /| / /_/ / ", + "/_____/\\____/_/ |_/ /____//_/ /_/ |_/_/ |_/_/ |_/_____/___/_/ |_/\\____/ ", + NULL +}; + +static const char *modes[] = { + [MSSingle] = "single don mode", + [MSMulti] = "army of dons mode", + [MSQuit] = "slp slp", + NULL +}; + +static int selmode; + +static void +drawoption(int w, int y, const char *label, int focused) +{ + tui_print(label, ((w - 2) / 2) - ((int)strlen(label) / 2), + y, focused ? ColorLWhite | TB_BOLD : ColorWhite, ColorBlack); +} + +static void +drawmenu(void) +{ + int i, bh; + tui_drawbox(0, 0, tb_width(), tb_height(), ColorWhite, ColorBlack, 1); + i = -1; + while (title[++i] != NULL) { + tui_print(title[i], ((tb_width() - 2) / 2) - ((int)strlen(title[i]) / 2), + 2 + i, ColorYellow, ColorBlack); + } + bh = ++i; + i = -1; + while (modes[++i] != NULL) { + drawoption(tb_width(), 2 + bh + i, modes[i], i == selmode); + } + tb_present(); +} + +static int +mainmenu(void) +{ + struct tb_event event; + selmode = 0; + while (1) { + drawmenu(); + tb_poll_event(&event); + if (event.key == TB_KEY_ESC) { + return 0; + } else if (event.key == TB_KEY_ARROW_UP || event.ch == (uint32_t)'k') { + if (selmode > 0) --selmode; + } else if (event.key == TB_KEY_ARROW_DOWN || event.ch == (uint32_t)'j') { + if (selmode < MSLen - 1) ++selmode; + } + } +} int main(void) { + if (tb_init() < 0) + die("termbox init failed"); + + tb_select_input_mode(TB_INPUT_ESC); + tb_select_output_mode(TB_OUTPUT_TRUECOLOR); + + if (tb_width() < 69 || tb_height() < 24) + die("terminal is too small: %dx%d, expected %dx%d", + tb_width(), tb_height(), 69, 24); + + tb_clear(); + while (mainmenu()); + + tb_shutdown(); return 0; } diff --git a/include/tui.h b/include/tui.h @@ -0,0 +1,10 @@ +#ifndef _TUI_H +#define _TUI_H + +#include <termbox.h> + +void tui_print(const char *s, int x, int y, uint32_t fg, uint32_t bg); +void tui_printf(const char *s, int x, int y, uint32_t fg, uint32_t bg, ...); +void tui_drawbox(int x, int y, int w, int h, uint32_t fg, uint32_t bg, int filled); + +#endif diff --git a/tui.c b/tui.c @@ -0,0 +1,64 @@ +#include <stdarg.h> +#include <stdio.h> + +#include <tui.h> + +void +tui_print(const char *s, int x, int y, uint32_t fg, uint32_t bg) +{ + int i = -1; + while (s[++i]) + tb_change_cell(x + i, y, (uint32_t)s[i], fg, bg); +} + +void +tui_printf(const char *s, int x, int y, uint32_t fg, uint32_t bg, ...) +{ + va_list ap; + char buf[640 * 1024], *bptr = buf, *t = bptr--; + va_start(ap, bg); + vsnprintf(buf, 640 * 1024, s, ap); + va_end(ap); + while (*(++bptr)) + tb_change_cell(x + (int)(bptr - t), y, (uint32_t)*bptr, fg, bg); +} + +void +tui_drawbox(int x, int y, int w, int h, uint32_t fg, uint32_t bg, int filled) +{ + int i; + + /* + 0x250C => ┌ + 0x2510 => ┐ + 0x2514 => └ + 0x2518 => ┘ + 0x2502 => │ + 0x2500 => ─ + */ + + tb_change_cell(x, y, 0x250C, fg, bg); + tb_change_cell(x + (w - 1), y, 0x2510, fg, bg); + tb_change_cell(x, y + (h - 1), 0x2514, fg, bg); + tb_change_cell(x + (w - 1), y + (h - 1), 0x2518, fg, bg); + + for (i = x + 1; i < x + w - 1; ++i) { + tb_change_cell(i, y, 0x2500, fg, bg); + tb_change_cell(i, y + (h - 1), 0x2500, fg, bg); + } + + for (i = y + 1; i < y + h - 1; ++i) { + tb_change_cell(x, i, 0x2502, fg, bg); + tb_change_cell(x + (w - 1), i, 0x2502, fg, bg); + } + + if (filled) { + for (i = x + 1; i < x + w - 1; ++i) { +#define j filled + for (j = y + 1; j < y + h - 1; ++j) { + tb_change_cell(i, j, (uint32_t)' ', fg, bg); + } +#undef j + } + } +} diff --git a/tui.o b/tui.o Binary files differ.