Created
September 18, 2020 09:47
-
-
Save cjgajard/aaaf0bff27b19a873f43be8e7dfe9975 to your computer and use it in GitHub Desktop.
Template for command line with ncurses in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ctype.h> | |
#include <curses.h> | |
#include <locale.h> | |
#include <string.h> | |
#include <time.h> | |
#define CTRL(c) ((c) & 0x1f) | |
#define FPS 30 | |
static int columns = 80; | |
static int lines = 24; | |
static char character = 'A'; | |
static char boxsiz = 5; | |
#define BOXWY ((lines - boxsiz) / 2) | |
#define BOXWX ((columns - boxsiz) / 2) | |
char input[512] = {0}; | |
size_t ix = 0; | |
size_t ilen = 0; | |
time_t pvtime = 0; | |
int main (void) | |
{ | |
/* SETUP */ | |
setlocale(LC_ALL, ""); | |
initscr(); | |
noecho(); | |
nonl(); | |
getmaxyx(stdscr, lines, columns); | |
bool boxw_dirty = TRUE; | |
WINDOW *boxw = newwin(boxsiz, 2 * boxsiz, BOXWY, BOXWX); | |
bool inputw_dirty = TRUE; | |
WINDOW *inputw = newwin(1, columns, lines - 1, 0); | |
nodelay(inputw, TRUE); | |
keypad(inputw, TRUE); | |
pvtime = time(NULL); | |
while (1) { | |
/* DRAW */ | |
curs_set(FALSE); | |
if (boxw_dirty) { | |
wbkgdset(boxw, character); | |
wclear(boxw); | |
wrefresh(boxw); | |
boxw_dirty = FALSE; | |
} | |
if (inputw_dirty) { | |
mvwprintw(inputw, 0, 0, ":%s", input); | |
wclrtoeol(inputw); | |
wrefresh(inputw); | |
inputw_dirty = FALSE; | |
} | |
wmove(inputw, 0, ix + 1); | |
curs_set(TRUE); | |
/* EVENT */ | |
bool exec_flag = FALSE; | |
int byte; | |
while ((byte = wgetch(inputw)) != ERR) { | |
if (byte == EOF) { | |
break; | |
} | |
else if (byte == CTRL('m') || byte == '\n') { | |
exec_flag = TRUE; | |
break; | |
} | |
else if (byte == 0x7F /* ascii-DEL */) { | |
if (ix > 0) | |
input[--ix] = 0; | |
boxw_dirty = TRUE; | |
continue; | |
} | |
else if (byte == KEY_RESIZE) { | |
clear(); | |
refresh(); | |
getmaxyx(stdscr, lines, columns); | |
mvwin(boxw, BOXWY, BOXWX); | |
boxw_dirty = TRUE; | |
mvwin(inputw, lines - 1, 0); | |
inputw_dirty = TRUE; | |
continue; | |
} | |
else if (!isprint(byte)) { | |
continue; | |
} | |
if (ix >= sizeof(input) - 1) { | |
continue; | |
} | |
input[ix++] = (char)byte & 0xff; | |
input[ix] = 0; | |
ilen++; | |
inputw_dirty = TRUE; | |
} | |
if (exec_flag) { | |
if (!strcmp(input, "q")) | |
break; | |
if (!strcmp(input, "quit")) | |
break; | |
ix = ilen = 0; | |
input[ix] = 0; | |
inputw_dirty = TRUE; | |
} | |
/* NEXT */ | |
napms(1000.0 / FPS); | |
/* UPDATE */ | |
time_t t = time(NULL); | |
if (t - pvtime >= 1) { | |
if (++character > 'Z') | |
character = 'A'; | |
pvtime = t; | |
boxw_dirty = TRUE; | |
} | |
} | |
/* CLOSE */ | |
delwin(boxw); | |
delwin(inputw); | |
endwin(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment