diff options
author | KatolaZ <katolaz@freaknet.org> | 2019-07-18 17:45:38 +0100 |
---|---|---|
committer | KatolaZ <katolaz@freaknet.org> | 2019-07-18 17:45:38 +0100 |
commit | 478c03adcdc7d76595a311a0dba682917ab97d62 (patch) | |
tree | f4680c8d79b4b3bf1d5fe3126896bfaccd464dff /gramscii.c |
initial commit
Diffstat (limited to 'gramscii.c')
-rw-r--r-- | gramscii.c | 353 |
1 files changed, 353 insertions, 0 deletions
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 <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> +#include <signal.h> +#include <string.h> + +#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<HEIGHT; i++){ + memset(screen[i], ' ', WIDTH); + screen[i][WIDTH]='\0'; + } + cursor = PTR; + corner = PTR; + box_line_h = LINE_H; + box_line_v = LINE_V; + arrow_line_h = LINE_H; + arrow_line_v = LINE_V; +} + +char* state_str(){ + switch(state){ + case MOVE: + return "mv "; + case TEXT: + return "txt"; + case BOX: + return "box"; + case ARROW: + return "arr"; + } +} + + +void status_bar(){ + + printf("\033[%d;1f\033[7m", HEIGHT+1); + printf(" x: %d y: %d -- mode: %s", x, y, state_str()); + printf("\033[0m"); +} + +int redraw(){ + int i; + + printf("\033[2J\033[1;1H"); + for (i=0;i<HEIGHT;i++){ + fprintf(stdout,"%s\n",screen[i]); + } + status_bar(); + show_cursor(); + step = 1; +} + +void update_current(){ + printf("\033[%d'%df",y+1,x+1); + putchar(screen[y][x]); +} + + +void init(){ + + signal(SIGHUP, cleanup); + signal(SIGINT, cleanup); + signal(SIGTERM, cleanup); + signal(SIGQUIT, cleanup); + + tcgetattr(0, &t1); + t2 = t1; + t2.c_lflag &= ~(ICANON | ECHO); + tcsetattr(0, TCSANOW, &t2); + + init_screen(); + x = WIDTH/2; + y = HEIGHT/2; + redraw(); +} + +void check_bound(){ + if (x<0) x=0; + else if (x>=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); +} |