diff --git a/page.c b/page.c index 52332fd..b454a09 100644 --- a/page.c +++ b/page.c @@ -12,6 +12,9 @@ void init_page(PAGE *p, char *filename, int size) strcpy(p->filename, filename); p->numlines = 0; p->size = size; + p->x = 0; + p->y = 0; + p->saved = 1; } // init_page void dest_page(PAGE *p) @@ -77,21 +80,49 @@ void expand_page(PAGE *p) } // expand_page // NOTE: This moves the cursor to the end of the displayed text -void print_page(const PAGE *p, int start, int end) +void print_page(WINDOW *win, WINDOW *lnos, const PAGE *p, int start, int end) { int i, line; - for(i = start, line = 0; i < p->numlines && i < end; i++, line++) + for(i = start, line = 0; i < p->numlines && i < end; i++) { - move(line, 0); - clrtoeol(); - printw(" %s", p->text[i].line); + + + int linesinline = strlen(p->text[i].line) / 75; + if (strlen(p->text[i].line) % 75) linesinline++; + + if (linesinline > 0) { + for (int j=0;j < linesinline; j++) { + wmove(lnos, line, 0); + wclrtoeol(lnos); + if (j == 0) { + wprintw(lnos, "%5d", i + 1); + } + wmove(win, line++, 0); + wclrtoeol(win); + wprintw(win, "%.*s", strlen(&p->text[i].line[j * 75]) < 75 ? strlen(&p->text[i].line[j * 75]) : 75, &p->text[i].line[j * 75]); + } + } else { + wmove(lnos, line, 0); + wclrtoeol(lnos); + wprintw(lnos, "%5d", i + 1); + wmove(win, line++, 0); + wclrtoeol(win); + } + } + + for (int j=line; j < 23; j++) { + wmove(lnos, j, 0); + wclrtoeol(lnos); + } + if(start < end) { - move(line, 0); - clrtoeol(); // if we deleted a line this may be necessary - move(line-1, 1); + wmove(win, line, 0); + wclrtoeol(win); // if we deleted a line this may be necessary + wmove(win, line-1, 1); } - refresh(); + wrefresh(lnos); + //refresh(); } // print_page diff --git a/page.h b/page.h index 612a93e..4c38925 100644 --- a/page.h +++ b/page.h @@ -15,6 +15,8 @@ typedef struct LINE *text; // lines of text int numlines; int size; // size of array + int x, y; + int saved; } PAGE; void init_page(PAGE *p, char *filename, int size); @@ -22,6 +24,6 @@ void dest_page(PAGE *p); void insert_line(PAGE *p, int index); void remove_line(PAGE *p, int index); void expand_page(PAGE *p); -void print_page(const PAGE *p, int start, int end); +void print_page(WINDOW *win, WINDOW *lnos, const PAGE *p, int start, int end); #endif diff --git a/text.c b/text.c index 5ea1b7d..f6b9ca0 100644 --- a/text.c +++ b/text.c @@ -8,20 +8,108 @@ * -Loading **/ +int winx, winy; + int y_offset = 0; // TODO: move to local scope int tab_offset = 0; extern void convert_xpm(char **xpm, unsigned char **buffer); extern unsigned char *QUINN_Icon; -// #define DEBUG + +#define EDITOR_SIZE (WIN_SIZE - 2) + +WINDOW *menu; +WINDOW *editor; +WINDOW *linenos; + +short curs_color(int fg) +{ + switch (7 & fg) { /* RGB */ + case 0: /* 000 */ + return (COLOR_BLACK); + case 1: /* 001 */ + return (COLOR_BLUE); + case 2: /* 010 */ + return (COLOR_GREEN); + case 3: /* 011 */ + return (COLOR_CYAN); + case 4: /* 100 */ + return (COLOR_RED); + case 5: /* 101 */ + return (COLOR_MAGENTA); + case 6: /* 110 */ + return (COLOR_YELLOW); + case 7: /* 111 */ + return (COLOR_WHITE); + } +} + +void init_colorpairs(void) +{ + int fg, bg; + int colorpair; + + for (bg = 0; bg <= 7; bg++) { + for (fg = 0; fg <= 7; fg++) { + colorpair = colornum(fg, bg); + init_pair(colorpair, curs_color(fg), curs_color(bg)); + } + } +} + + + +int colornum(int fg, int bg) +{ + int B, bbb, ffff; + + B = 1 << 7; + bbb = (7 & bg) << 4; + ffff = 7 & fg; + + return (B | bbb | ffff); +} + + +void setcolor(int fg, int bg) +{ + /* set the color pair (colornum) and bold/bright (A_BOLD) */ + + attron(COLOR_PAIR(colornum(fg, bg))); + if (is_bold(fg)) { + attron(A_BOLD); + } +} + +void unsetcolor(int fg, int bg) +{ + /* unset the color pair (colornum) and + bold/bright (A_BOLD) */ + + attroff(COLOR_PAIR(colornum(fg, bg))); + if (is_bold(fg)) { + attroff(A_BOLD); + } +} + +int is_bold(int fg) +{ + /* return the intensity bit */ + + int i; + + i = 1 << 3; + return (i & fg); +} + void print_loc(int x, int y) { - #ifdef DEBUG int oldx, oldy; getyx(stdscr, oldy, oldx); - mvprintw(0, COLS - 20, "x: %d y: %d o: %d", x, y, y_offset); + wmove(menu, 0, COLS - 20); + wprintw(menu, "X: %d Y: %d ", x, y + y_offset + 1); + wclrtoeol(menu); move(oldy, oldx); - #endif } int main(int argc, char *argv[]) @@ -53,91 +141,111 @@ int main(int argc, char *argv[]) noecho(); keypad(stdscr, 1); + start_color(); + init_colorpairs(); + + winx = 0; + winy = 0; + + menu = subwin(stdscr, 2, 80, 23, 0); + wbkgd(menu, COLOR_PAIR(colornum(COLOR_BLACK, COLOR_CYAN))); + + editor = subwin(stdscr, 23, 75, 0, 5); + wbkgd(editor, COLOR_PAIR(colornum(COLOR_WHITE, COLOR_BLUE))); + + linenos = subwin(stdscr, 23, 5, 0, 0); + wbkgd(linenos, COLOR_PAIR(colornum(COLOR_BLUE, COLOR_WHITE))); + int beg = 0; - int end = WIN_SIZE; - int y, x; // position on screen - int i; - + int end = EDITOR_SIZE; + int i; - update_status(page.filename, ""); + update_status(&page, ""); - print_page(&page, beg, end); - getyx(stdscr, y, x); - + print_page(editor, linenos, &page, beg, end); + wmove(editor, winy, winx); while(1) { - print_loc(x, y); + beg = 0 + y_offset; - end = WIN_SIZE + y_offset; - int ch = getch(); - update_status(page.filename, ""); // default text + end = EDITOR_SIZE + y_offset; + int ch = wgetch(editor); + update_status(&page, ""); // default text switch(ch) { case KEY_F(4): if(prompt_yesno("Are you sure you want to quit?")) goto endnc; - print_page(&page, beg, end); + print_page(editor, linenos, &page, beg, end); break; case KEY_F(5): save_file(&page); - update_status(page.filename, "Saved!"); + update_status(&page, "Saved!"); break; case KEY_F(6): prompt_string("Save As:", page.filename, NAME_LIMIT); save_file(&page); - print_page(&page, beg, end); - update_status(page.filename, "Saved!"); + print_page(editor, linenos, &page, beg, end); + update_status(&page, "Saved!"); break; case KEY_UP: - move_up(&page, &x, &y); + move_up(&page); break; case KEY_DOWN: - move_down(&page, &x, &y); + move_down(&page); break; case KEY_LEFT: - move_left(&x, &y); + move_left(&page); break; case KEY_RIGHT: - move_right(&page, &x, &y); + move_right(&page); break; + case KEY_END: + move_to_eol(&page); case KEY_DC: case 127: // backspace key... case KEY_BACKSPACE: case '\b': - if(strlen(page.text[y + y_offset].line) == 0) + if(strlen(page.text[page.y].line) == 0) { // can only delete blank lines for now - remove_line(&page, y + y_offset); - move_up(&page, &x, &y); + remove_line(&page, page.y); + move_up(&page); } - else if( x > 1 ) + else if( page.x > 0 ) { - remove_char(&page.text[y + y_offset], x - 2); // delete - move_left(&x, &y); // char behind cursor + remove_char(&page.text[page.y], page.x - 1); // delete + move_left(&page); // char behind cursor } - print_page(&page, beg, end); - move(y, x); + print_page(editor, linenos, &page, beg, end); + wmove(editor, winy, winx); + page.saved = 0; break; case '\t': for(i = 0; i < TAB_WIDTH; i++) { - insert_char(&page.text[y + y_offset], ' ', x - 1); - print_page(&page, beg, end); - move_right(&page, &x, &y); + insert_char(&page.text[page.y], ' ', page.x); + print_page(editor, linenos, &page, beg, end); + move_right(&page); } + page.saved = 0; break; case '\n': // newline - insert_line(&page, y + y_offset + 1); - print_page(&page, beg, end); - move_down(&page, &x, &y); + insert_line(&page, page.y + 1); + print_page(editor, linenos, &page, beg, end); + move_down(&page); break; default: // all other chars if( isprint(ch) ) { - insert_char(&page.text[y + y_offset], ch, x - 1); - print_page(&page, beg, end); - move_right(&page, &x, &y); + insert_char(&page.text[page.y], ch, page.x); + print_page(editor, linenos, &page, beg, end); + move_right(&page); + page.saved = 0; } } + print_loc(page.x, page.y); + wrefresh(menu); + wrefresh(editor); } endnc: /* end curses */ @@ -147,76 +255,147 @@ endnc: } // main // prints a message at the bottom of the window -void update_status(char *filename, char *info) +void update_status(PAGE *p, char *info) { - int oldy, oldx; getyx(stdscr, oldy, oldx); - char status[81]; char title[61]; - snprintf(title, 60, "Text: %s", filename); + snprintf(title, 60, "Text: %s%c", p->filename, p->saved == 1 ? ' ' : '*'); PDC_set_title(title); - - snprintf(status, 80, "F4: Quit F5: Save F6: Save As File: %-25.25s %s", filename, info); - - attron(A_REVERSE); - move(LINES - 1, 0); - clrtoeol(); - printw(status); - attroff(A_REVERSE); - - move(oldy, oldx); + wmove(menu, 0, 0); + wprintw(menu, "%s", info); + wmove(menu, 1, 0); + wprintw(menu, "F4: Quit F5: Save F6: Save As "); + wrefresh(menu); } // update_status /* movement */ -void move_left(int *x, int *y) + +void move_to_eol(PAGE *p) { - if(*x - 1 > 0) move(*y, --(*x)); + while (p->x <= strlen(p->text[p->y].line)) { + move_right(p); + } +} + +void move_left(PAGE *p) +{ + if(p->x - 1 > 0) { + p->x--; + winx--; + winy = 0; + + if (p->x > 75) { + winx = p->x % 75; + winy = p->x / 75; + } else { + winx = p->x; + } + + for (int j = y_offset; j < p->y; j++) { + if (strlen(p->text[j].line) > 75) { + int linesinline = strlen(p->text[j].line) / 75; + if (strlen(p->text[j].line) % 75) linesinline++; + winy += linesinline; + } else { + winy++; + } + } + + wmove(editor, winy, winx); + } else if (p->x - 1 == 0){ + p->x = 0; + winx = 0; + } } -void move_right(PAGE *p, int *x, int *y) +void move_right(PAGE *p) { - if(*x <= strlen(p->text[*y + y_offset].line)) + if(p->x <= strlen(p->text[p->y].line)) { - if(p->text[*y + y_offset].line[*x + tab_offset] == '\t') { - move(*y, ++(*x)); - } else { - move(*y, ++(*x)); - } + p->x++; + winy = 0; + + if (p->x > 75) { + winx = p->x % 75; + winy = p->x / 75; + } else { + winx++; + } + + for (int j = y_offset; j < p->y; j++) { + if (strlen(p->text[j].line) > 75) { + int linesinline = strlen(p->text[j].line) / 75; + if (strlen(p->text[j].line) % 75) linesinline++; + winy += linesinline; + } else { + winy++; + } + } + + wmove(editor, winy, winx); } } -void move_up(PAGE *p, int *x, int *y) +void move_up(PAGE *p) { - if( *y > 0 ) - { - --(*y); + int linesinline = 1; + + if (p->y > 0) { + if (strlen(p->text[p->y - 1].line) / 75 >= 1) { + linesinline = strlen(p->text[p->y - 1].line) / 75; + if (strlen(p->text[p->y - 1].line) % 75) linesinline++; + } + + if( p->y - y_offset >= linesinline) + { + p->y--; + winy -= linesinline; + } + else if (y_offset > 0) + { + p->y--; + --(y_offset); + print_page(editor, linenos, p, 0 + y_offset, EDITOR_SIZE + y_offset); + } else { + p->y--; + winy -= linesinline; + } + if( p->x > strlen(p->text[p->y].line) ) { // cursor adjusts + p->x = strlen(p->text[p->y].line); // to smaller lines + winx = p->x; + } + + wmove(editor, winy, winx); } - else if (y_offset > 0) - { - --(y_offset); - print_page(p, 0 + y_offset, WIN_SIZE + y_offset); - } - if( *x > strlen(p->text[*y + y_offset].line) + 1 ) // cursor adjusts - *x = strlen(p->text[*y + y_offset].line) + 1; // to smaller lines - move(*y, *x); } -void move_down(PAGE *p, int *x, int *y) +void move_down(PAGE *p) { - if( *y < WIN_SIZE - 1 && *y < p->numlines - 1 ) - { - ++(*y); + int linesinline = 1; + + if (strlen(p->text[p->y].line) / 75 >= 1) { + linesinline = strlen(p->text[p->y].line) / 75; + if (strlen(p->text[p->y].line) % 75) linesinline++; } - else if ( *y + y_offset < p->numlines - 1 ) + if( p->y - y_offset < EDITOR_SIZE - 1 && p->y -y_offset < p->numlines - 1 ) { + p->y++; + winy += linesinline; + } + else if ( p->y < p->numlines - 1 ) + { + p->y++; ++(y_offset); - print_page(p, 0 + y_offset, WIN_SIZE + y_offset); + print_page(editor, linenos, p, 0 + y_offset, EDITOR_SIZE + y_offset); } - if( *x > strlen(p->text[*y + y_offset].line) + 1 ) - *x = strlen(p->text[*y + y_offset].line) + 1; - move(*y, *x); + if( p->x > strlen(p->text[p->y].line)) { + p->x = strlen(p->text[p->y].line); + winx = p->x; + } + wmove(editor, winy, winx); + } /* movement */ @@ -296,7 +475,7 @@ void save_file(PAGE *p) } fclose(fp); - + p->saved = 1; } // save_file int file_exists(char *filename) diff --git a/text.h b/text.h index 104fea4..d090d20 100644 --- a/text.h +++ b/text.h @@ -10,17 +10,18 @@ #include "page.h" #include "prompt.h" -void update_status(char *filename, char *info); +void update_status(PAGE *p, char *info); int count_lines(FILE *fp); void load_file(PAGE *p, char* filename); void save_file(PAGE *p); int file_exists(char *filename); -void move_left(int *x, int *y); -void move_right(PAGE *p, int *x, int *y); -void move_up(PAGE *p, int *x, int *y); -void move_down(PAGE *p, int *x, int *y); +void move_to_eol(PAGE *p); +void move_left(PAGE *p); +void move_right(PAGE *p); +void move_up(PAGE *p); +void move_down(PAGE *p); #endif