From 87d8b0ceb349e101b693cf43336a98647f4b92dc Mon Sep 17 00:00:00 2001 From: lonkaars Date: Sun, 29 May 2022 22:34:19 +0200 Subject: garbage ui functions + janky status bar --- client/i18n.h | 7 ++++ client/i18n/en_us.h | 6 +++ client/main.h | 5 +++ client/serial.c | 15 ++++++- client/setup.c | 3 ++ client/term.h | 7 ++++ client/term_linux.c | 29 +++++++++++++ client/ui.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++-- client/ui.h | 8 ++-- 9 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 client/i18n.h create mode 100644 client/i18n/en_us.h create mode 100644 client/term.h create mode 100644 client/term_linux.c (limited to 'client') diff --git a/client/i18n.h b/client/i18n.h new file mode 100644 index 0000000..11fd576 --- /dev/null +++ b/client/i18n.h @@ -0,0 +1,7 @@ +#pragma once + +#ifndef W2_LANG_DEFAULT +#define W2_LANG_DEFAULT +#include "i18n/en_us.h" +#endif + diff --git a/client/i18n/en_us.h b/client/i18n/en_us.h new file mode 100644 index 0000000..4117ef6 --- /dev/null +++ b/client/i18n/en_us.h @@ -0,0 +1,6 @@ +#pragma once + +#define W2_UI_CONN_STAT_CONNECTED "connected" +#define W2_UI_CONN_STAT_DISCONNECTED "disconnected" +#define W2_UI_CONN_STAT_PING "ping" +#define W2_UI_BATT_STAT_BATTERY "battery" diff --git a/client/main.h b/client/main.h index 462da73..693db91 100644 --- a/client/main.h +++ b/client/main.h @@ -5,6 +5,11 @@ typedef struct { unsigned int ping; uint8_t ping_id; + bool ping_received; + + bool connected; + uint8_t battery_level; + w2_s_cmd_info_tx info; w2_s_cmd_sens_tx io; } w2_s_client_state; diff --git a/client/serial.c b/client/serial.c index 0d0bca7..9efb966 100644 --- a/client/serial.c +++ b/client/serial.c @@ -1,3 +1,5 @@ +#include + #include "serial.h" #include "../shared/protocol.h" #include "../shared/serial_parse.h" @@ -10,16 +12,25 @@ void w2_serial_main() { } void w2_cmd_ping_tx(w2_s_bin *data) { - // TODO: check ping id + W2_CAST_BIN(w2_s_cmd_ping_tx, data, cast); + + if (g_w2_state.ping_received) return; + if (g_w2_state.ping_id != cast->id) return; g_w2_state.ping = w2_timer_end(W2_TIMER_PING); + g_w2_state.ping_received = true; + printf("ping measured, %ims\n", g_w2_state.ping); } + void w2_cmd_expt_tx(w2_s_bin *data) { printf("w2_cmd_expt_tx()\n"); } void w2_cmd_mode_tx(w2_s_bin *data) { printf("w2_cmd_mode_tx()\n"); } void w2_cmd_cord_tx(w2_s_bin *data) { printf("w2_cmd_cord_tx()\n"); } void w2_cmd_bomd_tx(w2_s_bin *data) { printf("w2_cmd_bomd_tx()\n"); } void w2_cmd_sens_tx(w2_s_bin *data) { printf("w2_cmd_sens_tx()\n"); } -void w2_cmd_info_tx(w2_s_bin *data) { printf("w2_cmd_info_tx()\n"); } + +void w2_cmd_info_tx(w2_s_bin *data) { + memcpy(&g_w2_state.info, data->data, sizeof(w2_s_cmd_info_tx)); +} void w2_cmd_ping_rx(w2_s_bin *data) { return; } void w2_cmd_mode_rx(w2_s_bin *data) { return; } diff --git a/client/setup.c b/client/setup.c index 2e8cce7..5eb6c13 100644 --- a/client/setup.c +++ b/client/setup.c @@ -6,6 +6,7 @@ #include "commands.h" #include "serial.h" #include "setup.h" +#include "term.h" // pointers for endianness check static const uint16_t _test = 1; @@ -23,6 +24,8 @@ void w2_client_setup(int argc, char **argv) { exit(1); } + w2_term_raw_mode(); + w2_cmd_setup_handlers(); w2_send_info(); diff --git a/client/term.h b/client/term.h new file mode 100644 index 0000000..a60dc2c --- /dev/null +++ b/client/term.h @@ -0,0 +1,7 @@ +#pragma once + +/** set terminal to raw mode */ +void w2_term_raw_mode(); +/** set ui canvas props */ +void w2_term_props(); + diff --git a/client/term_linux.c b/client/term_linux.c new file mode 100644 index 0000000..2a88d6c --- /dev/null +++ b/client/term_linux.c @@ -0,0 +1,29 @@ +#ifdef W2_HOST_LINUX + +#include +#include +#include +#include + +#include "term.h" +#include "ui.h" + +void w2_term_raw_mode() { + fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); + struct termios term; + tcgetattr(STDIN_FILENO, &term); + term.c_lflag &= ~(ECHO | ICANON); + term.c_cc[VTIME] = 0; + term.c_cc[VMIN] = 1; + tcsetattr(STDIN_FILENO, 0, &term); +} + +void w2_term_props() { + struct winsize window; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &window); + + g_w2_ui_canvas.width = window.ws_col; + g_w2_ui_canvas.height = window.ws_row; +} + +#endif diff --git a/client/ui.c b/client/ui.c index 239065c..84408bb 100644 --- a/client/ui.c +++ b/client/ui.c @@ -1,4 +1,13 @@ +#include + +#include "../shared/util.h" +#include "../shared/bin.h" +#include "i18n.h" +#include "main.h" #include "ui.h" +#include "term.h" + +w2_s_ui_tty_canvas g_w2_ui_canvas; void w2_ui_main() { w2_ui_update(); @@ -6,9 +15,108 @@ void w2_ui_main() { } void w2_ui_update() { - // measure terminal width and height + w2_term_props(); +} + +void w2_ui_paint() { + w2_ui_paint_statusbar(); +} + +void w2_ui_align(char* text, w2_e_alignment align, unsigned int length) { + unsigned int padding = 0; + + switch(align) { + case W2_UI_ALIGN_LEFT: { + break; + } + case W2_UI_ALIGN_CENTER: { + unsigned int middle = length / 2; + unsigned int offset = strlen(text) / 2; + padding = W2_MAX(0, middle - offset); + break; + } + case W2_UI_ALIGN_RIGHT: { + unsigned int right = length; + unsigned int offset = strlen(text); + padding = W2_MAX(0, right - offset); + break; + } + } + + char* temp = calloc(length, 1); + sprintf(temp, "%*s%s", padding, "", text); + memcpy(text, temp, length); + free(temp); +} + +char* w2_ui_pt_sb_con_sts() { + char* connected = g_w2_state.connected ? W2_UI_CONN_STAT_CONNECTED : W2_UI_CONN_STAT_DISCONNECTED; + char* out = calloc(g_w2_ui_canvas.width, 1); + sprintf(out, "%s, %ims %s", connected, g_w2_state.ping, W2_UI_CONN_STAT_PING); + w2_ui_align(out, W2_UI_ALIGN_LEFT, g_w2_ui_canvas.width); + return out; +} +char* w2_ui_pt_sb_ver_num() { + char* out = calloc(g_w2_ui_canvas.width, 1); + sprintf(out, "(%s)", g_w2_state.info.build_str); + w2_ui_align(out, W2_UI_ALIGN_CENTER, g_w2_ui_canvas.width); + return out; +} +char* w2_ui_pt_sb_bat_sts() { + char* out = calloc(g_w2_ui_canvas.width, 1); + sprintf(out, "%s %i%%", W2_UI_BATT_STAT_BATTERY, g_w2_state.battery_level); + w2_ui_align(out, W2_UI_ALIGN_RIGHT, g_w2_ui_canvas.width); + return out; } -void w2_ui_paint() { w2_ui_paint_statusbar(); } +void w2_ui_nullsub(char* str, unsigned int length) { + for (int i = 0; i < length; i++) if (str[i] == 0x00) str[i] = ' '; +} + +void w2_ui_overlay(char *bottom, char *top, unsigned int length) { + w2_ui_nullsub(bottom, length); + w2_ui_nullsub(top, length); + + unsigned int start = 0; + for (int i = 0; i < length; i++) { + start = i; + if (top[start] != ' ') break; + } + unsigned int stop = 0; + for (int i = 0; i < length; i++) { + stop = length - i; + if (top[stop] != ' ') break; + } + + for (int i = 0; i < length; i++) { + if (i >= start && i <= stop) bottom[i] = top[i]; + } +} + +// char* w2_ui_pt_sb_logic_mode() {} +// char* w2_ui_pt_sb_exceptions() {} +// char* w2_ui_pt_sb_tabbar() {} + +void w2_ui_paint_statusbar() { + char top_row[g_w2_ui_canvas.width]; + + char* con_sts = w2_ui_pt_sb_con_sts(); + char* ver_num = w2_ui_pt_sb_ver_num(); + char* bat_sts = w2_ui_pt_sb_bat_sts(); + + w2_ui_overlay(top_row, con_sts, g_w2_ui_canvas.width); + w2_ui_overlay(top_row, ver_num, g_w2_ui_canvas.width); + w2_ui_overlay(top_row, bat_sts, g_w2_ui_canvas.width); + + printf("%s", top_row); + + free(con_sts); + free(ver_num); + free(bat_sts); + + // w2_ui_pt_sb_connection_status(); + // w2_ui_pt_sb_connection_status(); + // w2_ui_pt_sb_connection_status(); + printf("\n"); +} -void w2_ui_paint_statusbar() {} diff --git a/client/ui.h b/client/ui.h index afb0817..36266ba 100644 --- a/client/ui.h +++ b/client/ui.h @@ -42,10 +42,10 @@ void w2_ui_paint_statusbar(); /** update and paint */ void w2_ui_main(); -/** echo ansi color code for foreground color */ -void w2_ui_set_fg(w2_e_colors color); -/** echo ansi color code for background color */ -void w2_ui_set_bg(w2_e_colors color); +/** get ansi color code for foreground color */ +char* w2_ui_set_fg(w2_e_colors color); +/** get ansi color code for background color */ +char* w2_ui_set_bg(w2_e_colors color); /** align `text` `align` with `text` buffer length `length` */ void w2_ui_align(char *text, w2_e_alignment align, unsigned int length); -- cgit v1.2.3