summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--gramscii.c461
2 files changed, 249 insertions, 214 deletions
diff --git a/TODO b/TODO
index a6110e4..2119199 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
+ optimize redraws (i.e., avoid to redraw if possible)
- (?) change cursor shape according to action
- auto-arrow 'A' (automatic end-char)
-- load from file
- read file at point
- visual selection
- crop
@@ -13,6 +12,7 @@
(also do not print unmanaged chars!)
- get screen geometry
- allow scrolling (both vertical and horizontal)
+* load from file
* check if modified on exit
* write to new file / default file
* delete -- 'x'
diff --git a/gramscii.c b/gramscii.c
index ade73ee..fb2efa4 100644
--- a/gramscii.c
+++ b/gramscii.c
@@ -89,6 +89,70 @@ void cleanup(int s){
exit(0);
}
+/*** Status bar ***/
+
+char* state_str(){
+ switch(state){
+ case MOVE:
+ return "mov";
+ case TEXT:
+ return "txt";
+ case BOX:
+ return "box";
+ case ARROW:
+ return "arr";
+ case DEL:
+ return "del";
+ default:
+ return "ERR";
+ }
+ return "ERR";
+}
+
+
+void status_bar(){
+
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ printf("%100s", " ");
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ printf(" x: %3d y: %3d -- mode: %4s hl: %c vl: %c cn: %c <: %c >: %c %10s",
+ x, y, state_str(), line_h, line_v, corner, mark_st, mark_end, "");
+ printf(" [%s]", fname );
+ printf("\033[0m");
+}
+
+char get_key(char *s){
+
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ printf("%100s", " ");
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ printf("%s ", s);
+ printf("\033[0m");
+ return getchar();
+}
+
+void get_string(char *msg, char *s, int sz){
+
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ printf("%100s", " ");
+ printf("\033[%d;1f\033[7m", HEIGHT+1);
+ /* We must activate echo now */
+ t3 = t2;
+ t3.c_lflag |= (ECHO | ICANON);
+ tcsetattr(0, TCSANOW, &t3);
+ printf("%s", msg);
+ printf("\033[0m");
+ fgets(s, sz, stdin);
+ s[strlen(s)-1] = '\0';
+ tcsetattr(0, TCSANOW, &t2);
+}
+
+int is_yes(char c){
+ return c=='y' ? 1 : c == 'Y'? 1 : 0;
+}
+
+/*** Screen management ***/
+
void show_cursor(){
printf("\033[%d;%df", y+1, x+1);
}
@@ -108,6 +172,31 @@ void draw_xy(int x, int y, char c){
putchar(c);
}
+void update_current(){
+ printf("\033[%d'%df",y+1,x+1);
+ putchar(screen[y][x]);
+}
+
+void erase_line(char *s){
+ while(*s){
+ *s++ = BG;
+ }
+}
+
+void erase_screen(){
+ int i;
+ for(i=0;i<HEIGHT; i++)
+ erase_line(screen[i]);
+}
+
+
+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 init_screen(){
int i;
for(i=0; i<HEIGHT; i++){
@@ -124,36 +213,6 @@ void init_screen(){
mark_end = end_marks[cur_end];
}
-char* state_str(){
- switch(state){
- case MOVE:
- return "mov";
- case TEXT:
- return "txt";
- case BOX:
- return "box";
- case ARROW:
- return "arr";
- case DEL:
- return "del";
- default:
- return "ERR";
- }
- return "ERR";
-}
-
-
-void status_bar(){
-
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- printf("%100s", " ");
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- printf(" x: %3d y: %3d -- mode: %4s hl: %c vl: %c cn: %c <: %c >: %c %10s",
- x, y, state_str(), line_h, line_v, corner, mark_st, mark_end, "");
- printf(" [%s]", fname );
- printf("\033[0m");
-}
-
void redraw(){
int i;
@@ -165,12 +224,99 @@ void redraw(){
show_cursor();
}
-void update_current(){
- printf("\033[%d'%df",y+1,x+1);
- putchar(screen[y][x]);
+int move_around(char c){
+
+ switch(c){
+ case 'H': step = 5;
+ case 'h':
+ dir = DIR_L;
+ x -= step;
+ break;
+ case 'J': step = 5;
+ case 'j':
+ dir = DIR_D;
+ y += step;
+ break;
+ case 'K': step = 5;
+ case 'k':
+ dir = DIR_U;
+ y -= step;
+ break;
+ case 'L': step = 5;
+ case 'l':
+ dir = DIR_R;
+ x += step;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+void go_to(int where){
+ switch(where){
+ case HOME:
+ x = y = 0;
+ break;
+ case END:
+ x = WIDTH-1;
+ y = HEIGHT-1;
+ break;
+ case MIDDLE:
+ x = WIDTH/2;
+ y = HEIGHT/2;
+ break;
+ }
+ check_bound();
+ show_cursor();
+}
+
+int progr_x(int dir){
+ return dir == DIR_L ? -1 : dir == DIR_R ? 1: 0;
}
+int progr_y(int dir){
+ return dir == DIR_U ? -1 : dir == DIR_D ? 1: 0;
+}
+
+/*** Lines and markers ***/
+
+void toggle_hline(){
+
+ cur_hl = (cur_hl + 1) % hlines_sz;
+ line_h = hlines[cur_hl];
+
+}
+
+void toggle_corner(){
+
+ cur_corn = (cur_corn + 1 ) % corners_sz;
+ corner = corners[cur_corn];
+
+}
+
+void toggle_vline(){
+
+ cur_vl = (cur_vl + 1) % vlines_sz;
+ line_v = vlines[cur_vl];
+
+}
+
+void toggle_st_mark(){
+
+ cur_start = (cur_start + 1 ) % stmarks_sz;
+ mark_st = st_marks[cur_start];
+}
+
+void toggle_end_mark(){
+
+ cur_end = (cur_end+ 1 ) % endmarks_sz;
+ mark_end = end_marks[cur_end];
+}
+
+
+
void init(){
signal(SIGHUP, cleanup);
@@ -191,13 +337,6 @@ void init(){
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;
-}
-
/***** text, box, arrows *****/
@@ -215,6 +354,7 @@ void get_text(){
else {
set(c);
update_current();
+ modified = 1;
x += 1;
if (x >= WIDTH)
x = orig_x;
@@ -259,35 +399,6 @@ void draw_box(int x1, int y1, int fix){
}
-int move_around(char c){
-
- switch(c){
- case 'H': step = 5;
- case 'h':
- dir = DIR_L;
- x -= step;
- break;
- case 'J': step = 5;
- case 'j':
- dir = DIR_D;
- y += step;
- break;
- case 'K': step = 5;
- case 'k':
- dir = DIR_U;
- y -= step;
- break;
- case 'L': step = 5;
- case 'l':
- dir = DIR_R;
- x += step;
- break;
- default:
- return 1;
- }
- return 0;
-}
-
void get_box(){
char c;
@@ -296,7 +407,7 @@ void get_box(){
step = 1;
draw_box(x,y,NOFIX);
while((c=getchar())!=EOF && c != 27 && c!= 'b'){
- if (move_around(c)) continue;
+ if (!move_around(c)) continue;
check_bound();
redraw();
step = 1;
@@ -312,17 +423,6 @@ void get_box(){
state = MOVE;
}
-
-int progr_x(int dir){
- return dir == DIR_L ? -1 : dir == DIR_R ? 1: 0;
-}
-
-
-int progr_y(int dir){
- return dir == DIR_U ? -1 : dir == DIR_D ? 1: 0;
-}
-
-
void draw_arrow(int x, int y, char *a, int a_len, int fix){
int i, j, cur_dir;
@@ -381,7 +481,7 @@ void get_arrow(){
step = 1;
draw_arrow(x,y, arrow, 0, NOFIX);
while((c=getchar())!=EOF && c != 27 && c!= 'a'){
- if (move_around(c)) continue;
+ if (!move_around(c)) continue;
check_bound();
/* FIXME: if we are out of bound, do nothing? */
if (arrow_len == arrow_sz){
@@ -404,112 +504,6 @@ void get_arrow(){
state = MOVE;
}
-char get_key(char *s){
-
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- printf("%100s", " ");
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- printf("%s ", s);
- printf("\033[0m");
- return getchar();
-}
-
-void get_string(char *s, int sz){
-
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- printf("%100s", " ");
- printf("\033[%d;1f\033[7m", HEIGHT+1);
- /* We must activate echo now */
- t3 = t2;
- t3.c_lflag |= (ECHO | ICANON);
- tcsetattr(0, TCSANOW, &t3);
- printf("Write to: ");
- printf("\033[0m");
- fgets(s, sz, stdin);
- s[strlen(s)-1] = '\0';
- tcsetattr(0, TCSANOW, &t2);
-}
-
-int is_yes(char c){
- return c=='y' ? 1 : c == 'Y'? 1 : 0;
-}
-
-void write_file(){
- FILE *f;
- int i;
-
- if (!fname[0] || force_new){
- get_string(fname, 255);
- if (f=fopen(fname, "r")){
- if (!is_yes(get_key("File exists. Overwrite [y/n]?")) ){
- fclose(f);
- return;
- }
- fclose(f);
- }
- }
- if((f=fopen(fname, "w"))==NULL){
- get_key("Error opening file.");
- return;
- }
- for (i=0; i<HEIGHT; i++){
- fprintf(f, "%s\n", screen[i]);
- }
- fclose(f);
- modified = 0;
- get_key("File saved.");
-}
-
-void toggle_hline(){
-
- cur_hl = (cur_hl + 1) % hlines_sz;
- line_h = hlines[cur_hl];
-
-}
-
-void toggle_corner(){
-
- cur_corn = (cur_corn + 1 ) % corners_sz;
- corner = corners[cur_corn];
-
-}
-
-void toggle_vline(){
-
- cur_vl = (cur_vl + 1) % vlines_sz;
- line_v = vlines[cur_vl];
-
-}
-
-void toggle_st_mark(){
-
- cur_start = (cur_start + 1 ) % stmarks_sz;
- mark_st = st_marks[cur_start];
-}
-
-void toggle_end_mark(){
-
- cur_end = (cur_end+ 1 ) % endmarks_sz;
- mark_end = end_marks[cur_end];
-}
-
-void go_to(int where){
- switch(where){
- case HOME:
- x = y = 0;
- break;
- case END:
- x = WIDTH-1;
- y = HEIGHT-1;
- break;
- case MIDDLE:
- x = WIDTH/2;
- y = HEIGHT/2;
- break;
- }
- check_bound();
- show_cursor();
-}
void do_delete(int x1, int y1){
int i;
@@ -536,7 +530,7 @@ void delete(){
status_bar();
show_cursor();
while((c=getchar())!=EOF && c!=27 && c!= 'x'){
- if (move_around(c)) continue;
+ if (!move_around(c)) continue;
check_bound();
step = 1;
do_delete(orig_x, orig_y);
@@ -550,6 +544,34 @@ void delete(){
state = MOVE;
}
+/*** File management ***/
+
+void write_file(){
+ FILE *f;
+ int i;
+
+ if (!fname[0] || force_new){
+ get_string("Write to: ", fname, 255);
+ if (f=fopen(fname, "r")){
+ if (!is_yes(get_key("File exists. Overwrite [y/n]?")) ){
+ fclose(f);
+ return;
+ }
+ fclose(f);
+ }
+ }
+ if((f=fopen(fname, "w"))==NULL){
+ get_key("Error opening file.");
+ return;
+ }
+ for (i=0; i<HEIGHT; i++){
+ fprintf(f, "%s\n", screen[i]);
+ }
+ fclose(f);
+ modified = 0;
+ get_key("File saved.");
+}
+
void check_modified(){
if (modified){
@@ -560,34 +582,41 @@ void check_modified(){
}
}
+void load_file(){
+
+ char newfname[256];
+ FILE *f;
+ int i;
+
+ get_string("Load file: ", newfname, 255);
+ if ((f=fopen(newfname, "r")) != NULL){
+ i = 0;
+ while((fgets(screen[i], WIDTH+2, f)) != NULL && i<HEIGHT)
+ screen[i++][WIDTH-1]='\0';
+ for(;i<HEIGHT; i++){
+ erase_line(screen[i]);
+ }
+ fclose(f);
+ }
+ strcpy(fname, newfname);
+ modified=0;
+ redraw();
+}
+void new_file(){
+ check_modified();
+ erase_screen();
+ go_to(MIDDLE);
+ redraw();
+ fname[0] = '\0';
+ modified=0;
+}
void 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;
+ if (!move_around(c)) switch(c){
case 'i':
state = TEXT;
get_text();
@@ -608,6 +637,14 @@ void commands(){
case 'w':
write_file();
break;
+ case 'e':
+ check_modified();
+ case 'E':
+ load_file();
+ break;
+ case 'N':
+ new_file();
+ break;
case 'g':
go_to(HOME);
break;
@@ -642,8 +679,6 @@ void commands(){
cleanup(0);
exit(0);
break;
- default:;
- //statu("got: %d\n", c);
}
check_bound();
status_bar();