From 6141c42abab22c74ea2656accd135968725b954d Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Thu, 10 Nov 2016 22:40:15 -0500 Subject: [PATCH] started restructuring to use view data structures instead one global screen module --- Makefile | 1 - inc/edit.h | 46 ++++++------- libedit/mouse.c | 144 --------------------------------------- xedit.c | 175 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 172 insertions(+), 194 deletions(-) delete mode 100644 libedit/mouse.c diff --git a/Makefile b/Makefile index c849c62..ae1e2b4 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,6 @@ INCS = -Iinc/ LIBEDIT_OBJS = \ libedit/buf.o \ libedit/charset.o \ - libedit/mouse.o \ libedit/screen.o \ libedit/utf8.o \ libedit/utils.o \ diff --git a/inc/edit.h b/inc/edit.h index 4a0d16a..2de0519 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -121,30 +121,6 @@ void utf8save(Buf* buf, FILE* file); void binload(Buf* buf, FMap file); void binsave(Buf* buf, FILE* file); -/* Input Handling - *****************************************************************************/ -/* Define the mouse buttons used for input */ -typedef struct { - enum { - MouseUp, - MouseDown, - MouseMove - } type; - enum { - MOUSE_LEFT = 0, - MOUSE_MIDDLE, - MOUSE_RIGHT, - MOUSE_WHEELUP, - MOUSE_WHEELDOWN, - MOUSE_NONE - } button; - int x; - int y; -} MouseEvent; - -void handle_key(Rune key); -void handle_mouse(MouseEvent* mevnt); - /* Screen management functions *****************************************************************************/ typedef struct { @@ -153,12 +129,28 @@ typedef struct { } UGlyph; typedef struct { - unsigned off; /* offset of the first rune in the row */ - unsigned rlen; /* number of runes displayed in the row */ - unsigned len; /* number of screen columns taken up by row */ + size_t off; /* offset of the first rune in the row */ + size_t rlen; /* number of runes displayed in the row */ + size_t len; /* number of screen columns taken up by row */ UGlyph cols[]; /* row data */ } Row; +typedef struct { + size_t nrows; /* number of rows in the view */ + size_t ncols; /* number of columns in the view */ + Row** rows; /* array of row data structures */ + Buf buffer; /* the buffer used to populate the view */ +} View; + +void view_update(View* view, unsigned crsr, unsigned* csrx, unsigned* csry); +size_t view_getoff(View* view, unsigned pos, unsigned row, unsigned col); +void view_setsize(View* view, unsigned nrows, unsigned ncols); +void view_getsize(View* view, unsigned* nrows, unsigned* ncols); +Row* view_getrow(View* view, unsigned row); +void view_clearrow(View* view, unsigned row); +size_t view_setcell(View* view, unsigned row, unsigned col, uint32_t attr, Rune r); +UGlyph* view_getglyph(View* view, unsigned row, unsigned col, unsigned* scrwidth); + void screen_update(Buf* buf, unsigned crsr, unsigned* csrx, unsigned* csry); unsigned screen_getoff(Buf* buf, unsigned pos, unsigned row, unsigned col); void screen_setsize(Buf* buf, unsigned nrows, unsigned ncols); diff --git a/libedit/mouse.c b/libedit/mouse.c deleted file mode 100644 index b910f15..0000000 --- a/libedit/mouse.c +++ /dev/null @@ -1,144 +0,0 @@ -#include -#include -#include - -void unused(MouseEvent* mevnt) { - (void)mevnt; -} - -void move_cursor(MouseEvent* mevnt) { - if (mevnt->y == 0) return; - SelBeg = SelEnd = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x); - TargetCol = buf_getcol(&Buffer, SelEnd); -} - -void bigword(MouseEvent* mevnt) { - (void)mevnt; - unsigned mbeg = SelEnd, mend = SelEnd; - for (; !risblank(buf_get(&Buffer, mbeg-1)); mbeg--); - for (; !risblank(buf_get(&Buffer, mend)); mend++); - SelBeg = mbeg, SelEnd = mend-1; -} - -void selection(MouseEvent* mevnt) { - (void)mevnt; - unsigned bol = buf_bol(&Buffer, SelEnd); - Rune r = buf_get(&Buffer, SelEnd); - if (SelEnd == bol || r == '\n' || r == RUNE_CRLF) { - SelBeg = bol; - SelEnd = buf_eol(&Buffer, SelEnd); - } else if (risword(r)) { - SelBeg = buf_bow(&Buffer, SelEnd); - SelEnd = buf_eow(&Buffer, SelEnd); - SelEnd++; - } else if (r == '(' || r == ')') { - SelBeg = buf_lscan(&Buffer, SelEnd, '('); - SelEnd = buf_rscan(&Buffer, SelEnd, ')'); - SelEnd++; - } else if (r == '[' || r == ']') { - SelBeg = buf_lscan(&Buffer, SelEnd, '['); - SelEnd = buf_rscan(&Buffer, SelEnd, ']'); - SelEnd++; - } else if (r == '{' || r == '}') { - SelBeg = buf_lscan(&Buffer, SelEnd, '{'); - SelEnd = buf_rscan(&Buffer, SelEnd, '}'); - SelEnd++; - } else { - bigword(mevnt); - } -} - -void search(MouseEvent* mevnt) { - unsigned clickpos = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x); - if (clickpos < SelBeg || clickpos > SelEnd) { - move_cursor(mevnt); - selection(mevnt); - } else { - buf_find(&Buffer, &SelBeg, &SelEnd); - } - unsigned x, y; - screen_update(&Buffer, SelEnd, &x, &y); - extern void move_pointer(unsigned x, unsigned y); - move_pointer(x, y); - -} - -void scrollup(MouseEvent* mevnt) { - (void)mevnt; - SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, -ScrollLines); -} - -void scrolldn(MouseEvent* mevnt) { - (void)mevnt; - SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, ScrollLines); -} - -/*****************************************************************************/ -enum { - SINGLE_CLICK = 0, - DOUBLE_CLICK, - TRIPLE_CLICK -}; - -struct { - uint32_t time; - uint32_t count; -} Buttons[5] = { {0,0}, {0,0}, {0,0} }; - -void (*Actions[5][3])(MouseEvent* mevnt) = { - [MOUSE_LEFT] = { - [SINGLE_CLICK] = move_cursor, - [DOUBLE_CLICK] = selection, - [TRIPLE_CLICK] = bigword, - }, - [MOUSE_MIDDLE] = { - [SINGLE_CLICK] = unused, - [DOUBLE_CLICK] = unused, - [TRIPLE_CLICK] = unused, - }, - [MOUSE_RIGHT] = { - [SINGLE_CLICK] = search, - [DOUBLE_CLICK] = search, - [TRIPLE_CLICK] = search, - }, - [MOUSE_WHEELUP] = { - [SINGLE_CLICK] = scrollup, - [DOUBLE_CLICK] = scrollup, - [TRIPLE_CLICK] = scrollup, - }, - [MOUSE_WHEELDOWN] = { - [SINGLE_CLICK] = scrolldn, - [DOUBLE_CLICK] = scrolldn, - [TRIPLE_CLICK] = scrolldn, - }, -}; - -static void handle_click(MouseEvent* mevnt) { - if (mevnt->button >= 5) return; - /* update the number of clicks */ - uint32_t now = getmillis(); - uint32_t elapsed = now - Buttons[mevnt->button].time; - if (elapsed <= 250) - Buttons[mevnt->button].count++; - else - Buttons[mevnt->button].count = 1; - Buttons[mevnt->button].time = now; - /* execute the click action */ - uint32_t nclicks = Buttons[mevnt->button].count; - nclicks = (nclicks > 3 ? 1 : nclicks); - Actions[mevnt->button][nclicks-1](mevnt); -} - -static void handle_drag(MouseEvent* mevnt) { - if (mevnt->y == 0 || mevnt->button != MOUSE_LEFT) return; - SelEnd = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x); - TargetCol = buf_getcol(&Buffer, SelEnd); -} - -void handle_mouse(MouseEvent* mevnt) { - if (mevnt->type == MouseDown) { - handle_click(mevnt); - } else if (mevnt->type == MouseMove) { - handle_drag(mevnt); - } -} diff --git a/xedit.c b/xedit.c index 6535ce7..df6c528 100644 --- a/xedit.c +++ b/xedit.c @@ -11,9 +11,13 @@ static void key_handler(Rune key); /* Global Data *****************************************************************************/ Buf Buffer; +Buf TagBuffer; unsigned TargetCol = 0; unsigned SelBeg = 0; unsigned SelEnd = 0; +static unsigned ScrRows = 0; +static unsigned ScrCols = 0; +static bool TagWinExpanded = false; static XFont Fonts; static XConfig Config = { .redraw = redraw, @@ -22,6 +26,11 @@ static XConfig Config = { .palette = COLOR_PALETTE }; +/* new view globals */ +static View TagView; +static View EditView; +static View* Active = &EditView; + /* Keyboard Actions *****************************************************************************/ static void delete(void) { @@ -113,6 +122,10 @@ static void cursor_eol(void) { TargetCol = (unsigned)-1; } +static void tagwin(void) { + TagWinExpanded = !TagWinExpanded; +} + /* Keyboard Bindings *****************************************************************************/ typedef struct { @@ -123,6 +136,7 @@ typedef struct { static KeyBinding_T Insert[] = { { KEY_CTRL_Q, quit }, { KEY_CTRL_S, write }, + { KEY_CTRL_T, tagwin }, { KEY_CTRL_Z, undo }, { KEY_CTRL_Y, redo }, { KEY_CTRL_X, cut }, @@ -167,6 +181,121 @@ static void key_handler(Rune key) { process_table(Insert, key); } +/* Mouse Actions + *****************************************************************************/ +void unused(int x, int y) { +} + +void move_cursor(int x, int y) { + if (y == 0) return; + SelBeg = SelEnd = screen_getoff(&Buffer, SelEnd, y-1, x); + TargetCol = buf_getcol(&Buffer, SelEnd); +} + +void bigword(int x, int y) { + unsigned mbeg = SelEnd, mend = SelEnd; + for (; !risblank(buf_get(&Buffer, mbeg-1)); mbeg--); + for (; !risblank(buf_get(&Buffer, mend)); mend++); + SelBeg = mbeg, SelEnd = mend-1; +} + +void selection(int x, int y) { + unsigned bol = buf_bol(&Buffer, SelEnd); + Rune r = buf_get(&Buffer, SelEnd); + if (SelEnd == bol || r == '\n' || r == RUNE_CRLF) { + SelBeg = bol; + SelEnd = buf_eol(&Buffer, SelEnd); + } else if (risword(r)) { + SelBeg = buf_bow(&Buffer, SelEnd); + SelEnd = buf_eow(&Buffer, SelEnd++); + } else if (r == '(' || r == ')') { + SelBeg = buf_lscan(&Buffer, SelEnd, '('); + SelEnd = buf_rscan(&Buffer, SelEnd++, ')'); + } else if (r == '[' || r == ']') { + SelBeg = buf_lscan(&Buffer, SelEnd, '['); + SelEnd = buf_rscan(&Buffer, SelEnd++, ']'); + } else if (r == '{' || r == '}') { + SelBeg = buf_lscan(&Buffer, SelEnd, '{'); + SelEnd = buf_rscan(&Buffer, SelEnd++, '}'); + } else { + bigword(x,y); + } +} + +void search(int x, int y) { + unsigned clickpos = screen_getoff(&Buffer, SelEnd, y-1, x); + if (clickpos < SelBeg || clickpos > SelEnd) { + move_cursor(x,y); + selection(x,y); + } else { + buf_find(&Buffer, &SelBeg, &SelEnd); + } + unsigned c, r; + screen_update(&Buffer, SelEnd, &c, &r); + extern void move_pointer(unsigned c, unsigned r); + move_pointer(c, r); + +} + +void scrollup(int x, int y) { + SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, -ScrollLines); +} + +void scrolldn(int x, int y) { + SelBeg = SelEnd = buf_byline(&Buffer, SelEnd, ScrollLines); +} + +/* Mouse Input Handler + *****************************************************************************/ +struct { + uint32_t time; + uint32_t count; +} Buttons[5] = { 0 }; + +void (*Actions[5][3])(int x, int y) = { + /* Single Double Triple */ + [MOUSE_BTN_LEFT] = { move_cursor, selection, bigword, }, + [MOUSE_BTN_MIDDLE] = { unused, unused, unused, }, + [MOUSE_BTN_RIGHT] = { search, search, search, }, + [MOUSE_BTN_WHEELUP] = { scrollup, scrollup, scrollup, }, + [MOUSE_BTN_WHEELDOWN] = { scrolldn, scrolldn, scrolldn, }, +}; + +static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) { + unsigned row = y / Fonts.base.height; + unsigned col = x / Fonts.base.width; + unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1); + + //if (row == 0) { + // puts("status"); + //} else if (row >= 1 && row <= twsz) { + // puts("tagwin"); + //} else { + // puts("editwin"); + //} + + if (act == MOUSE_ACT_DOWN) { + //if (mevnt->button >= 5) return; + ///* update the number of clicks */ + //uint32_t now = getmillis(); + //uint32_t elapsed = now - Buttons[mevnt->button].time; + //if (elapsed <= 250) + // Buttons[mevnt->button].count++; + //else + // Buttons[mevnt->button].count = 1; + //Buttons[mevnt->button].time = now; + ///* execute the click action */ + //uint32_t nclicks = Buttons[mevnt->button].count; + //nclicks = (nclicks > 3 ? 1 : nclicks); + //Actions[mevnt->button][nclicks-1](mevnt); + } else if (act == MOUSE_ACT_MOVE) { + //if (mevnt->y == 0 || mevnt->button != MOUSE_LEFT) return; + //SelEnd = screen_getoff(&Buffer, SelEnd, mevnt->y-1, mevnt->x); + //TargetCol = buf_getcol(&Buffer, SelEnd); + } +} + + /* Screen Redraw *****************************************************************************/ static void draw_runes(unsigned x, unsigned y, int fg, int bg, UGlyph* glyphs, size_t rlen) { @@ -222,43 +351,45 @@ static void draw_status(int fg, unsigned ncols) { draw_runes(0, 0, fg, 0, glyphs, status - glyphs); } -static void redraw(int width, int height) { - /* update the screen size if needed */ - screen_setsize(&Buffer, - height / Fonts.base.height - 1, - width / Fonts.base.width); - /* draw the background colors */ - x11_draw_rect(CLR_BASE03, 0, 0, width, height); - x11_draw_rect(CLR_BASE02, 79 * Fonts.base.width, 0, Fonts.base.width, height); - x11_draw_rect(CLR_BASE02, 0, 0, width, Fonts.base.height); - x11_draw_rect(CLR_BASE01, 0, Fonts.base.height, width, 1); +static void draw_tagwin(unsigned off, unsigned rows, unsigned cols) { + //screen_setsize(&TagBuffer, rows, cols); +} + +static void draw_bufwin(unsigned off, unsigned rows, unsigned cols) { + screen_setsize(&Buffer, rows, cols); /* update the screen buffer and retrieve cursor coordinates */ unsigned csrx, csry; screen_update(&Buffer, SelEnd, &csrx, &csry); - /* flush the screen buffer */ unsigned nrows, ncols; screen_getsize(&nrows, &ncols); draw_status(CLR_BASE2, ncols); for (unsigned y = 0; y < nrows; y++) { Row* row = screen_getrow(y); - draw_glyphs(0, (y+2) * Fonts.base.height, row->cols, row->rlen, row->len); + draw_glyphs(0, off + ((y+1) * Fonts.base.height), row->cols, row->rlen, row->len); } - /* Place cursor on screen */ - x11_draw_rect(CLR_BASE3, csrx * Fonts.base.width, (csry+1) * Fonts.base.height, 1, Fonts.base.height); + x11_draw_rect(CLR_BASE3, csrx * Fonts.base.width, off + (csry * Fonts.base.height), 1, Fonts.base.height); } -static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) { - MouseEvent evnt = { - .type = act, - .button = btn, - .x = x / Fonts.base.width, - .y = y / Fonts.base.height - }; - handle_mouse(&evnt); +static void redraw(int width, int height) { + unsigned fheight = Fonts.base.height; + unsigned fwidth = Fonts.base.width; + ScrRows = height / Fonts.base.height; + ScrCols = width / Fonts.base.width; + /* clear background and draw status */ + x11_draw_rect(CLR_BASE03, 0, 0, width, height); + draw_status(CLR_BASE2, ScrCols); + /* draw the tag window */ + unsigned twsz = (TagWinExpanded ? ((ScrRows - 1) / 4) : 1); + x11_draw_rect(CLR_BASE02, 0, fheight, width, twsz * fheight); + x11_draw_rect(CLR_BASE01, 0, fheight, width, 1); + draw_tagwin(fheight, twsz, ScrCols); + /* draw the file window */ + x11_draw_rect(CLR_BASE01, 0, (twsz+1) * fheight, width, 1); + draw_bufwin((twsz+1) * fheight, ScrRows - (twsz), ScrCols); } int main(int argc, char** argv) { -- 2.52.0