From 478c03adcdc7d76595a311a0dba682917ab97d62 Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Thu, 18 Jul 2019 17:45:38 +0100 Subject: initial commit --- README | 2 + TODO | 9 ++ gramscii.c | 353 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 364 insertions(+) create mode 100644 README create mode 100644 TODO create mode 100644 gramscii.c diff --git a/README b/README new file mode 100644 index 0000000..ae699d4 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Simple tool to draw ascii box plots from the terminal. +No need to use 1 million line of javascript code on a browser. diff --git a/TODO b/TODO new file mode 100644 index 0000000..956af84 --- /dev/null +++ b/TODO @@ -0,0 +1,9 @@ ++ optimize redraws (i.e., avoid to redraw if possible) +- change cursor shape according to action ++ implement box +- implement arrow +- set different box styles ++ add status bar +- get screen geometry +- allow scrolling (both vertical and horizontal) + diff --git a/gramscii.c b/gramscii.c new file mode 100644 index 0000000..40d1f1e --- /dev/null +++ b/gramscii.c @@ -0,0 +1,353 @@ +/* +* +* This is `gramscii`, a simple tool to create ascii box graphs +* +*/ + +#include +#include +#include +#include +#include +#include + +#define MOVE 0x00 +#define BOX 0x01 +#define ARROW 0x02 +#define TEXT 0x04 + + +#define DIR_R 0x01 +#define DIR_U 0x02 +#define DIR_D 0x04 +#define DIR_L 0x08 + + +#define WIDTH 100 +#define HEIGHT 25 + +#define BG ' ' +#define PTR '+' +#define UND '_' +#define LINE_H '-' +#define LINE_V '|' +#define DBLINE_H '=' +#define DBLINE_V 'u' +#define BLDLINE '#' +#define ARR_L '<' +#define ARR_R '>' +#define ARR_U '^' +#define ARR_D 'v' + + +#define MIN(x,y) (x) < (y) ? (x) : (y) +#define MAX(x,y) (x) > (y) ? (x) : (y) + +char screen[HEIGHT][WIDTH+1]; + +int state; +int dir; +int x; +int y; +int step; +char cursor; +char corner; +char box_line_h; +char box_line_v; +char arrow_line_h; +char arrow_line_v; + +struct termios t1, t2; + + +void cleanup(int s){ + + printf("\033[;H\033[2J"); + tcsetattr(0, TCSANOW, &t1); + exit(0); +} + +void show_cursor(){ + printf("\033[%d;%df", y+1, x+1); + //putchar(screen[y][x]); + //printf("\033[%d;%df", y+1, x+2); +} + +void set(char c){ + screen[y][x] = c; +} + +void set_xy(int x, int y, char c){ + /* FIXME: check if x and y are valid!!!! */ + screen[y][x] = c; +} + +void draw_xy(int x, int y, char c){ + /* FIXME: check if x and y are valid!!!! */ + printf("\033[%d;%df",y+1,x+1); + putchar(c); +} + +void clear(){ + screen[y][x] = BG; +} + +void init_screen(){ + int i; + for(i=0; i=WIDTH) x = WIDTH-1; + if (y<0) y=0; + else if (y>=HEIGHT) y = HEIGHT -1; +} + + +void get_text(){ + char c; + int orig_x = x, orig_y = y; + + //cursor = UND; + redraw(); + while((c=getchar())!=EOF && c != 27){ + if(c=='\n'){ + set(BG); + y += 1; + x = orig_x; + } + else { + set(c); + update_current(); + x += 1; + if (x >= WIDTH) + x = orig_x; + } + check_bound(); + status_bar(); + show_cursor(); + } + cursor = PTR; + state=MOVE; +} + + +void fix_box(int x1, int y1){ + + int xmin, ymin, xmax, ymax; + int i; + + xmin = MIN(x, x1); + xmax = MAX(x, x1); + ymin = MIN(y, y1); + ymax = MAX(y, y1); + + + for(i=xmin+1; i<=xmax; i++){ + set_xy(i, ymin, box_line_h); + set_xy(i, ymax, box_line_h); + } + for(i=ymin+1; i<=ymax; i++){ + set_xy(xmin, i, box_line_v); + set_xy(xmax, i, box_line_v); + } + set_xy(xmin, ymin, corner); + set_xy(xmin, ymax, corner); + set_xy(xmax, ymin, corner); + set_xy(xmax, ymax, corner); +} + +void draw_box(int x1, int y1){ + + int xmin, ymin, xmax, ymax; + int i; + + xmin = MIN(x, x1); + xmax = MAX(x, x1); + ymin = MIN(y, y1); + ymax = MAX(y, y1); + + + for(i=xmin+1; i<=xmax; i++){ + draw_xy(i, ymin, box_line_h); + draw_xy(i, ymax, box_line_h); + } + for(i=ymin+1; i<=ymax; i++){ + draw_xy(xmin, i, box_line_v); + draw_xy(xmax, i, box_line_v); + } + draw_xy(xmin, ymin, corner); + draw_xy(xmin, ymax, corner); + draw_xy(xmax, ymin, corner); + draw_xy(xmax, ymax, corner); + show_cursor(); +} + + +void get_box(){ + char c; + int orig_x=x, orig_y=y; + + set(PTR); + redraw(); + while((c=getchar())!=EOF && c != 27){ + switch(c){ + case 'H': step = 5; + case 'h': + x -= step; + break; + case 'J': step = 5; + case 'j': + y += step; + break; + case 'K': step = 5; + case 'k': + y -= step; + break; + case 'L': step = 5; + case 'l': + x += step; + break; + } + check_bound(); + redraw(); + draw_box(orig_x, orig_y); + status_bar(); + show_cursor(); + } + fix_box(orig_x, orig_y); + redraw(); +} + + +int commands(){ + + char c; + while((c=getchar())!=EOF){ + //screen[y][x]=BG; + switch(c){ + case 'H': + step=5; + case 'h': + x-=step; + break; + case 'J': + step=5; + case 'j': + y+=step; + break; + case 'K': + step=5; + case 'k': + y-=step; + break; + case 'L': + step=5; + case 'l': + x+=step; + break; + case 'i': + state = TEXT; + get_text(); + break; + case 'r': + redraw(); + break; + case 'b': + get_box(); + break; + case 'Q': + case 'q': + cleanup(0); + exit(0); + break; + default:; + //statu("got: %d\n", c); + } + check_bound(); + //update(); + //redraw(); + status_bar(); + show_cursor(); + step = 1; + } + +} + + + + +int main(int argc, char *argv[]){ + + init(); + + commands(); + cleanup(0); +} -- cgit v1.2.3