/* * Copyright (C) 2024 Tristan Riehs * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include "disp.h" #include "calc_data.h" #include "input.h" static struct calc_data calcs[CALC_COUNT] = {0}; static int current_idx = 0; static WINDOW *win; static void draw_res(void) { int j = loop_backwards(current_idx); int drawn = 0; while ((calcs[j].ms != 0) && (drawn < CALC_COUNT)) { printw("%d + %d = %d\t%s\t%dms\n", calcs[j].x, calcs[j].y, calcs[j].input, calcs[j].right ? "RIGHT" : "WRONG", calcs[j].ms); j = loop_backwards(j); drawn++; } } static void draw_calc(void) { printw("%d + %d = %d", calcs[current_idx].x, calcs[current_idx].y, calcs[current_idx].input); } static void redraw(void) { clear(); move(0, 0); draw_res(); draw_calc(); refresh(); } void tui_init(void) { win = initscr(); noecho(); clear(); redraw(); } void tui_display_calc(int x, int y) { current_idx = next_calc(current_idx); calcs[current_idx].x = x; calcs[current_idx].y = y; calcs[current_idx].input = 0; calcs[current_idx].ms = 0; redraw(); } #define case_digit(digit) \ case digit: \ calcs[current_idx].input = \ add_input_digit(calcs[current_idx].input, digit - '0'); \ redraw(); \ break; int tui_read_input(void) { int c = getch(); while (c != ERR) { switch(c) { #ifndef NDEBUG case 'g': case 'r': return DISP_RELOAD; #endif case 'q': return DISP_QUIT; case '\n': case KEY_ENTER: return calcs[current_idx].input; case KEY_BACKSPACE: case 0177: /* ASCII DEL character */ calcs[current_idx].input = rm_input_digit(calcs[current_idx].input); redraw(); break; case_digit ('0') case_digit ('1') case_digit ('2') case_digit ('3') case_digit ('4') case_digit ('5') case_digit ('6') case_digit ('7') case_digit ('8') case_digit ('9') default: break; } c = getch(); } return DISP_ERR; } void tui_display_res(bool right, int ms) { calcs[current_idx].right = right; calcs[current_idx].ms = ms; redraw(); } void tui_destroy(void) { endwin(); } #ifndef NDEBUG void * tui_pre_reload(void) { char *data = malloc(sizeof(calcs) + sizeof(current_idx)); memcpy(data, &calcs, sizeof(calcs)); memcpy(data + sizeof(calcs), ¤t_idx, sizeof(current_idx)); endwin(); return data; } void tui_post_reload(void *state) { char *data = state; memcpy(&calcs, data, sizeof(calcs)); memcpy(¤t_idx, data + sizeof(calcs), sizeof(current_idx)); free(data); tui_init(); redraw(); } #endif #ifdef NDEBUG static struct disp __tui_disp = { .init = tui_init, .display_calc = tui_display_calc, .read_input = tui_read_input, .display_res = tui_display_res, .destroy = tui_destroy }; struct disp *tui_disp = &__tui_disp; #endif