]> git.mdlowis.com Git - projs/tide.git/commitdiff
refactored view handling. stripped down to the studs. Will rebuild with support for...
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 14 Apr 2018 01:57:48 +0000 (21:57 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 14 Apr 2018 01:57:48 +0000 (21:57 -0400)
inc/edit.h
lib/view.c
lib/x11.c

index 8b3b8f1a89eb71f05b252f0caee5a39d6d1d65c9..0e71be85dd94a32c8e15efd8ef1edd748ef35609 100644 (file)
@@ -73,13 +73,13 @@ char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off);
 /* Screen management functions
  *****************************************************************************/
 typedef struct {
-    Rune rune;     /* rune value for the cell */
+    size_t width; /* width of the glyph on screen */
+    Rune rune;    /* rune value for the cell */
 } UGlyph;
 
 typedef struct {
     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 */
+    size_t len;    /* number of runes displayed in the row */
     UGlyph cols[]; /* row data */
 } Row;
 
@@ -88,9 +88,9 @@ typedef struct {
         CURSOR = (1 << 0),
         CENTER = (1 << 1),
     } sync_flags;
-    Buf buffer;          /* the buffer used to populate the view */
-    size_t nrows, ncols; /* number of rows and columns in the view */
-    Row** rows;          /* array of row data structures */
+    Buf buffer;   /* the buffer used to populate the view */
+    size_t nrows; /* number of rows and columns in the view */
+    Row** rows;   /* array of row data structures */
 } View;
 
 enum {
@@ -102,9 +102,8 @@ enum {
 
 void view_init(View* view, char* file);
 void view_reload(View* view);
-size_t view_limitrows(View* view, size_t maxrows, size_t ncols);
-void view_resize(View* view, size_t nrows, size_t ncols);
-void view_update(View* view, int clrnor, int clrsel, size_t* csrx, size_t* csry);
+void view_resize(View* view, size_t width, size_t nrows);
+void view_update(View* view, size_t* csrx, size_t* csry);
 Row* view_getrow(View* view, size_t row);
 void view_byrune(View* view, int move, bool extsel);
 void view_byword(View* view, int move, bool extsel);
index a9ef06e1926b289dc3af8e595b29650597fd0605..cc9d10dc58db04b35478de16870cbfab5fe94bbb 100644 (file)
@@ -8,18 +8,51 @@
 
 typedef size_t (*movefn_t)(Buf* buf, size_t pos, int count);
 
-static void move_selection(View* view, bool extsel, int move, movefn_t bything);
-static void move_to(View* view, bool extsel, size_t off);
-static bool selection_visible(View* view);
-static void find_cursor(View* view, size_t* csrx, size_t* csry);
-static void clearrow(View* view, size_t row);
-static size_t setcell(View* view, size_t row, size_t col, Rune r);
-static size_t fill_row(View* view, unsigned row, size_t pos);
-static unsigned prev_screen_line(View* view, unsigned bol, unsigned off);
-static unsigned scroll_up(View* view);
-static unsigned scroll_dn(View* view);
-static void sync_center(View* view, size_t csr);
-static size_t getoffset(View* view, size_t row, size_t col);
+static void move_selection(View* view, bool extsel, int move, movefn_t bything) {
+    view->sync_flags |= CURSOR;
+    if (buf_selsz(BUF) && !extsel) {
+        buf_selclr(BUF, move);
+    } else {
+        CSRPOS = bything(BUF, CSRPOS, move);
+        if (bything == buf_byline)
+            buf_setcol(BUF);
+        if (!extsel)
+            buf_selclr(BUF, RIGHT);
+    }
+    /* only update column if not moving vertically */
+    if (bything != buf_byline)
+        buf_getcol(BUF);
+}
+
+static void move_to(View* view, bool extsel, size_t off) {
+    Buf* buf = BUF;
+    CSRPOS = (off > buf_end(buf) ? buf_end(buf) : off);
+    if (!extsel)
+        buf_selclr(BUF, RIGHT);
+    buf_getcol(buf);
+    view->sync_flags |= CURSOR;
+}
+
+static bool selection_visible(View* view) {
+    if (!view->nrows) return true;
+    size_t csr = CSRPOS;
+    size_t beg = view->rows[0]->off;
+    size_t end = view->rows[view->nrows-1]->off +
+                 view->rows[view->nrows-1]->len;
+    return (beg <= csr && csr <= end);
+}
+
+static void find_cursor(View* view, size_t* csrx, size_t* csry) {
+    size_t csr = CSRPOS;
+    for (size_t y = 0; y < view->nrows; y++) {
+        size_t start = view->rows[y]->off;
+        size_t end   = view->rows[y]->off + view->rows[y]->len - 1;
+        if (start <= csr && csr <= end) {
+            size_t pos = start;
+            break;
+        }
+    }
+}
 
 static Sel* getsel(View* view) {
     return &(view->buffer.selection);
@@ -47,52 +80,13 @@ void view_reload(View* view) {
 }
 
 size_t view_limitrows(View* view, size_t maxrows, size_t ncols) {
-    size_t nrows = 1, pos = 0, col = 0;
-    while (nrows < maxrows && pos < buf_end(BUF)) {
-        Rune r = buf_getrat(BUF, pos++);
-        col += runewidth(col, r);
-        if (col >= ncols || r == '\n')
-            col = 0, nrows++;
-    }
-    return nrows;
+    return 1;
 }
 
-void view_resize(View* view, size_t nrows, size_t ncols) {
-#if 1
-    size_t off = 0;
-    if (view->nrows == nrows && view->ncols == ncols) return;
-    /* free the old row data */
-    if (view->nrows) {
-        off  = view->rows[0]->off;
-        for (size_t i = 0; i < view->nrows; i++)
-            free(view->rows[i]);
-        free(view->rows);
-    }
-    /* create the new row data */
-    view->rows = calloc(nrows, sizeof(Row*));
-    for (unsigned i = 0; i < nrows; i++)
-        view->rows[i] = calloc(1, sizeof(Row) + (ncols * sizeof(UGlyph)));
-    /* update dimensions */
-    view->rows[0]->off = off;
-    view->nrows = nrows;
-    view->ncols = ncols;
-#endif
-}
-
-void view_update(View* view, int clrnor, int clrsel, size_t* csrx, size_t* csry) {
-#if 1
-    if (!view->nrows) return;
-    size_t csr = CSRPOS;
-    /* scroll the view and reflow the screen lines */
-    size_t pos = view->rows[0]->off;
-    /* fill the view and scroll if needed */
-    for (size_t y = 0; y < view->nrows; y++)
-        pos = fill_row(view, y, pos);
-    if (view->sync_flags)
-        view_scrollto(view, csr);
-    /* locate the cursor if visible */
-    find_cursor(view, csrx, csry);
-#endif
+void view_resize(View* view, size_t width, size_t nrows) {
+}
+
+void view_update(View* view, size_t* csrx, size_t* csry) {
 }
 
 Row* view_getrow(View* view, size_t row) {
@@ -112,9 +106,6 @@ void view_byline(View* view, int move, bool extsel) {
 }
 
 void view_setcursor(View* view, size_t row, size_t col, bool extsel) {
-    size_t off = getoffset(view, row, col);
-    if (off != SIZE_MAX)
-        view_jumpto(view, extsel, off);
 }
 
 void view_selword(View* view, size_t row, size_t col) {
@@ -140,10 +131,10 @@ size_t view_selsize(View* view) {
 }
 
 char* view_fetch(View* view, size_t row, size_t col, bool (*isword)(Rune)) {
-   char* str = NULL;
-    size_t off = getoffset(view, row, col);
-    if (off != SIZE_MAX)
-        str = buf_fetch(BUF, isword, off);
+    char* str = NULL;
+//    size_t off = getoffset(view, row, col);
+//    if (off != SIZE_MAX)
+//        str = buf_fetch(BUF, isword, off);
     return str;
 }
 
@@ -241,10 +232,10 @@ void view_scroll(View* view, int move) {
     int dir = (move < 0 ? -1 : 1);
     move *= dir;
     for (int i = 0; i < move; i++) {
-        if (dir < 0)
-            scroll_up(view);
-        else
-            scroll_dn(view);
+//        if (dir < 0)
+//            scroll_up(view);
+//        else
+//            scroll_dn(view);
     }
 }
 
@@ -258,16 +249,6 @@ Rune view_getrune(View* view) {
 }
 
 void view_scrollto(View* view, size_t csr) {
-    if (!view->nrows) return;
-    unsigned first = view->rows[0]->off;
-    unsigned last  = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
-    while (csr < first)
-        first = scroll_up(view);
-    while (csr > last && last < buf_end(BUF))
-        last = scroll_dn(view);
-    if (view->sync_flags & CENTER)
-        sync_center(view, csr);
-    view->sync_flags = 0;
 }
 
 void view_selectall(View* view) {
@@ -280,179 +261,4 @@ void view_selectobj(View* view, bool (*istype)(Rune)) {
     view->sync_flags |= CURSOR;
 }
 
-static void move_selection(View* view, bool extsel, int move, movefn_t bything) {
-    view->sync_flags |= CURSOR;
-    if (buf_selsz(BUF) && !extsel) {
-        buf_selclr(BUF, move);
-    } else {
-        CSRPOS = bything(BUF, CSRPOS, move);
-        if (bything == buf_byline)
-            buf_setcol(BUF);
-        if (!extsel)
-            buf_selclr(BUF, RIGHT);
-    }
-    /* only update column if not moving vertically */
-    if (bything != buf_byline)
-        buf_getcol(BUF);
-}
-
-static void move_to(View* view, bool extsel, size_t off) {
-    Buf* buf = BUF;
-    CSRPOS = (off > buf_end(buf) ? buf_end(buf) : off);
-    if (!extsel)
-        buf_selclr(BUF, RIGHT);
-    buf_getcol(buf);
-    view->sync_flags |= CURSOR;
-}
-
-static bool selection_visible(View* view) {
-    if (!view->nrows) return true;
-    size_t csr = CSRPOS;
-    size_t beg = view->rows[0]->off;
-    size_t end = view->rows[view->nrows-1]->off +
-                 view->rows[view->nrows-1]->rlen;
-    return (beg <= csr && csr <= end);
-}
 
-static void find_cursor(View* view, size_t* csrx, size_t* csry) {
-    size_t csr = CSRPOS;
-    for (size_t y = 0; y < view->nrows; y++) {
-        size_t start = view->rows[y]->off;
-        size_t end   = view->rows[y]->off + view->rows[y]->rlen - 1;
-        if (start <= csr && csr <= end) {
-            size_t pos = start;
-            for (size_t x = 0; x < view->ncols;) {
-                if (pos == csr) {
-                    *csry = y, *csrx = x;
-                    break;
-                }
-                x += runewidth(x, buf_getrat(BUF, pos++));
-            }
-            break;
-        }
-    }
-}
-
-static void clearrow(View* view, size_t row) {
-    Row* scrrow = view_getrow(view, row);
-    if (!scrrow) return;
-    for (size_t i = 0; i < view->ncols; i++)
-        scrrow->cols[i].rune = (Rune)' ';
-    scrrow->rlen = 0;
-    scrrow->len  = 0;
-}
-
-static size_t setcell(View* view, size_t row, size_t col, Rune r) {
-    if (row >= view->nrows || col >= view->ncols) return 0;
-    Row* scrrow = view_getrow(view, row);
-    int ncols = runewidth(col, r);
-    /* write the rune to the screen buf */
-    if (r == '\t')
-        scrrow->cols[col].rune = ' ';
-    else
-        scrrow->cols[col].rune = r;
-    /* Update lengths */
-    scrrow->rlen += 1;
-    for (int i = 1; i < ncols; i++) {
-        scrrow->cols[col+i].rune = '\0';
-    }
-    if ((col + ncols) > scrrow->len)
-        scrrow->len = col + ncols;
-    return ncols;
-}
-
-static size_t fill_row(View* view, unsigned row, size_t pos) {
-    view_getrow(view, row)->off  = pos;
-    clearrow(view, row);
-    for (size_t x = 0; x < view->ncols;) {
-        Rune r = buf_getrat(BUF, pos++);
-        x += setcell(view, row, x, r);
-        if (buf_iseol(BUF, pos-1)) {
-            break;
-        }
-    }
-    return pos;
-}
-
-static unsigned prev_screen_line(View* view, unsigned bol, unsigned off) {
-    unsigned pos = bol;
-    while (true) {
-        unsigned x;
-        for (x = 0; x < view->ncols && (pos + x) < off; x++)
-            x += runewidth(x, buf_getrat(BUF, pos+x));
-        if ((pos + x) >= off) break;
-        pos += x;
-    }
-    return pos;
-}
-
-static unsigned scroll_up(View* view) {
-    size_t first   = view->rows[0]->off;
-    size_t bol     = buf_bol(BUF, first);
-    size_t prevln  = (first == bol ? buf_byline(BUF, bol, UP) : bol);
-    if (!first) return first;
-    prevln = prev_screen_line(view, prevln, first);
-    /* delete the last row and shift the others */
-    free(view->rows[view->nrows - 1]);
-    memmove(&view->rows[1], &view->rows[0], sizeof(Row*) * (view->nrows-1));
-    view->rows[0] = calloc(1, sizeof(Row) + (view->ncols * sizeof(UGlyph)));
-    view->rows[0]->off = prevln;
-    /* fill in row content */
-    fill_row(view, 0, view->rows[0]->off);
-    return view->rows[0]->off;
-}
-
-static unsigned scroll_dn(View* view) {
-    size_t last = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
-    if (last >= buf_end(BUF)) return last;
-    /* delete the first row and shift the others */
-    if (view->nrows > 1) {
-        free(view->rows[0]);
-        memmove(&view->rows[0], &view->rows[1], sizeof(Row*) * (view->nrows-1));
-        view->rows[view->nrows-1] = calloc(1, sizeof(Row) + (view->ncols * sizeof(UGlyph)));
-        view->rows[view->nrows-1]->off = (view->rows[view->nrows-2]->off + view->rows[view->nrows-2]->rlen);
-        /* fill in row content */
-        fill_row(view, view->nrows-1, view->rows[view->nrows-1]->off);
-    } else {
-        view->rows[0]->off += view->rows[0]->rlen;
-        fill_row(view, 0, view->rows[0]->off);
-    }
-    return view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen - 1;
-}
-
-static void sync_center(View* view, size_t csr) {
-    /* determine the screenline containing the cursor */
-    size_t scrln = 0;
-    for (; scrln < view->nrows; scrln++) {
-        unsigned first = view->rows[scrln]->off;
-        unsigned last  = first + view->rows[scrln]->rlen - 1;
-        if (csr >= first && csr <= last)
-            break;
-    }
-    /* find the middle row and scroll until the cursor is on that row */
-    unsigned midrow = view->nrows / 2;
-    int move = (scrln - midrow);
-    unsigned count = (move < 0 ? -move : move);
-    for (; count > 0; count--)
-        (move < 0 ? scroll_up : scroll_dn)(view);
-}
-
-static size_t getoffset(View* view, size_t row, size_t col) {
-    Row* scrrow = view_getrow(view, row);
-    if (!scrrow) return SIZE_MAX;
-    size_t pos = scrrow->off;
-    if (col >= scrrow->len) {
-        pos = (scrrow->off + scrrow->rlen - 1);
-    } else {
-        /* multi column runes are followed by \0 slots so if we clicked on a \0
-           slot, slide backwards to the real rune. */
-        for (; !scrrow->cols[col].rune && col > 0; col--);
-        /* now lets count the number of runes up to the one we clicked on */
-        for (unsigned i = 0; i < col; i++)
-            if (scrrow->cols[i].rune)
-                pos++;
-    }
-    if (pos >= buf_end(BUF))
-        return buf_end(BUF);
-    return pos;
-}
index 1b0a8c53d9bdaa6e59d8ac212a55055d84af7cef..ddb03d152f2e2b356e2fa1167f159418146120e8 100644 (file)
--- a/lib/x11.c
+++ b/lib/x11.c
@@ -315,7 +315,8 @@ static void place_glyphs(int fg, XGlyphSpec* specs, size_t nspecs, bool eol) {
     XftColorFree(X.display, X.visual, X.colormap, &fgc);
 }
 
-static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t ncols) {
+static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t len) {
+#if 0
     XGlyphSpec specs[rlen];
     size_t i = 0;
     bool eol = false;
@@ -340,6 +341,7 @@ static void draw_glyphs(size_t x, size_t y, UGlyph* glyphs, size_t rlen, size_t
         place_glyphs(EditFg, specs, numspecs, eol);
         eol = false, rlen -= numspecs;
     }
+#endif
 }
 
 static void draw_view(int i, size_t nrows, drawcsr* csr, int bg, int fg, int sel) {
@@ -348,12 +350,12 @@ static void draw_view(int i, size_t nrows, drawcsr* csr, int bg, int fg, int sel
     size_t csrx = SIZE_MAX, csry = SIZE_MAX;
     /* draw the view to the window */
     View* view = win_view(i);
-    view_resize(view, nrows, (csr->w - csr->x) / fwidth);
-    view_update(view, (bg << 8 | fg), (sel << 8 | fg), &csrx, &csry);
+    view_resize(view, (csr->w - csr->x), nrows);
+    view_update(view, &csrx, &csry);
     draw_rect(bg, csr->x, csr->y, csr->w, (nrows * fheight) + 9);
     for (size_t y = 0; y < view->nrows; y++) {
         Row* row = view_getrow(view, y);
-        draw_glyphs(csr->x + 2, csr->y + 2 + ((y+1) * fheight), row->cols, row->rlen, row->len);
+        draw_glyphs(csr->x + 2, csr->y + 2 + ((y+1) * fheight), row->cols, row->len);
     }
     /* place the cursor on screen */
     if (!view_selsize(view) && csrx != SIZE_MAX && csry != SIZE_MAX) {
@@ -379,7 +381,7 @@ static void draw_scroll(drawcsr* csr) {
     if (bend == 0) bend = 1;
     if (!view->rows) return;
     size_t vbeg = view->rows[0]->off;
-    size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->rlen;
+    size_t vend = view->rows[view->nrows-1]->off + view->rows[view->nrows-1]->len;
     double scroll_vis = (double)(vend - vbeg) / (double)bend;
     double scroll_off = ((double)vbeg / (double)bend);
     size_t thumbreg = (csr->y - Divider) + 4;
@@ -542,7 +544,7 @@ static void xupdate(Job* job) {
     drawcsr csr = { .w = X.width, .h = X.height };
     size_t maxtagrows = ((X.height - 2) / 4) / fheight;
     size_t tagcols    = csr.w / fwidth;
-    size_t tagrows    = view_limitrows(win_view(TAGS), maxtagrows, tagcols);
+    size_t tagrows    = 1;
     size_t editrows   = ((X.height - 7) / fheight) - tagrows;
     /* draw the regions to the window */
     draw_view(TAGS, tagrows, &csr, TagsBg, TagsFg, TagsSel);