]> git.mdlowis.com Git - projs/tide.git/commitdiff
finished reworking layout code
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 15 Nov 2016 20:23:29 +0000 (15:23 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 15 Nov 2016 20:23:29 +0000 (15:23 -0500)
Makefile
inc/edit.h
inc/x11.h
libx/x11.c
xedit.c

index 31d3567c307cac2e0e387e7ed8e138d28e8c0da4..3208b11eee82264d5636df5c4b13c0aa11a43bea 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,6 @@ INCS = -Iinc/
 LIBEDIT_OBJS =         \
        libedit/buf.o      \
        libedit/charset.o  \
-       libedit/screen.o   \
        libedit/utf8.o     \
        libedit/utils.o    \
        libedit/exec.o     \
index d684a3f3285092319552ef810821ac75ae38d4c7..01043efad75986b87113dd71bb0e2a11fc5cebbd 100644 (file)
@@ -213,10 +213,24 @@ enum ColorId {
 
 /* Global State
  *****************************************************************************/
-extern Buf Buffer;
-extern unsigned TargetCol;
-extern unsigned SelBeg;
-extern unsigned SelEnd;
+typedef struct {
+    Rune key;
+    void (*action)(void);
+} KeyBinding;
+
+typedef struct {
+    uint32_t time;
+    uint8_t count;
+    bool pressed;
+} ButtonState;
+
+typedef struct {
+    size_t x;
+    size_t y;
+    size_t height;
+    size_t width;
+    View view;
+} Region;
 
 /* Configuration
  *****************************************************************************/
index 6926efe71a1d25a6336eacd91cc13a29ed18fb88..aed8feef2f5763f736e98eb4608d00c03d3c3d29 100644 (file)
--- a/inc/x11.h
+++ b/inc/x11.h
@@ -5,12 +5,13 @@ typedef enum {
 } MouseAct;
 
 typedef enum {
-    MOUSE_BTN_LEFT = 0,
-    MOUSE_BTN_MIDDLE,
-    MOUSE_BTN_RIGHT,
-    MOUSE_BTN_WHEELUP,
-    MOUSE_BTN_WHEELDOWN,
-    MOUSE_BTN_NONE
+    MOUSE_BTN_LEFT      = 0,
+    MOUSE_BTN_MIDDLE    = 1,
+    MOUSE_BTN_RIGHT     = 2,
+    MOUSE_BTN_WHEELUP   = 3,
+    MOUSE_BTN_WHEELDOWN = 4,
+    MOUSE_BTN_NONE      = 5,
+    MOUSE_BTN_COUNT     = 5
 } MouseBtn;
 
 typedef struct {
index 87babf4cc280f8cfe9f5cb9ede593364e5a31c24..af194e6d05597c1d2e8e24f2aa8ad1f54e16b47b 100644 (file)
@@ -187,7 +187,7 @@ static void handle_mouse(XEvent* e) {
         x      = e->xmotion.x;
         y      = e->xmotion.y;
     } else {
-        action = (e->type = ButtonPress ? MOUSE_ACT_DOWN : MOUSE_ACT_UP);
+        action = (e->type == ButtonPress ? MOUSE_ACT_DOWN : MOUSE_ACT_UP);
         /* set the button id */
         switch (e->xbutton.button) {
             case Button1: button = MOUSE_BTN_LEFT;      break;
@@ -212,11 +212,12 @@ void x11_loop(void) {
             XNextEvent(X.display, &e);
             if (!XFilterEvent(&e, None))
                 switch (e.type) {
-                    case FocusIn:      if (X.xic) XSetICFocus(X.xic);   break;
-                    case FocusOut:     if (X.xic) XUnsetICFocus(X.xic); break;
-                    case KeyPress:     Config->handle_key(getkey(&e));  break;
-                    case ButtonPress:  handle_mouse(&e);                break;
-                    case MotionNotify: handle_mouse(&e);                break;
+                    case FocusIn:       if (X.xic) XSetICFocus(X.xic);   break;
+                    case FocusOut:      if (X.xic) XUnsetICFocus(X.xic); break;
+                    case KeyPress:      Config->handle_key(getkey(&e));  break;
+                    case ButtonRelease: handle_mouse(&e);                break;
+                    case ButtonPress:   handle_mouse(&e);                break;
+                    case MotionNotify:  handle_mouse(&e);                break;
                     case ConfigureNotify: // Resize the window
                         if (e.xconfigure.width != X.width || e.xconfigure.height != X.height) {
                             X.width  = e.xconfigure.width;
@@ -339,7 +340,7 @@ void x11_font_getglyph(XFont fnt, XGlyphSpec* spec, uint32_t rune) {
 
 size_t x11_font_getglyphs(XGlyphSpec* specs, const XGlyph* glyphs, int len, XFont fnt, int x, int y) {
     struct XFont* font = fnt;
-    int winx = x * font->base.width, winy = y * font->base.ascent;
+    int winx = x, winy = y;
     size_t numspecs = 0;
     for (int i = 0, xp = winx, yp = winy + font->base.ascent; i < len;) {
         x11_font_getglyph(font, &(specs[numspecs]), glyphs[i].rune);
diff --git a/xedit.c b/xedit.c
index 67bc7ff419e07910407107ffc19822a4c41877ff..0357aafbb1d9689e0b9e5635acc5061c3666c697 100644 (file)
--- a/xedit.c
+++ b/xedit.c
@@ -10,19 +10,15 @@ 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 XFont Fonts;
-
+static enum RegionId {
+    STATUS   = 0,
+    TAGS     = 1,
+    EDIT     = 2,
+    NREGIONS = 3
+} Focused = EDIT;
+static Region Regions[NREGIONS] = { 0 };
 static bool TagWinExpanded = false;
-static View TagView;
-static View BufView;
-static View* Focused = &BufView;
+static ButtonState MouseBtns[MOUSE_BTN_COUNT] = { 0 };
 static XFont Font;
 static XConfig Config = {
     .redraw       = redraw,
@@ -31,49 +27,110 @@ static XConfig Config = {
     .palette      = COLOR_PALETTE
 };
 
+/* Region Utils
+ *****************************************************************************/
+static View* getview(enum RegionId id) {
+    return &(Regions[id].view);
+}
+
+static Buf* getbuf(enum RegionId id) {
+    return &(getview(id)->buffer);
+}
+
+static View* currview(void) {
+    return getview(Focused);
+}
+
+static Buf* currbuf(void) {
+    return getbuf(Focused);
+}
+
 /* UI Callbacks
  *****************************************************************************/
 static void cursor_up(void) {
-    view_byline(Focused, -1);
+    view_byline(currview(), -1);
 }
 
 static void cursor_dn(void) {
-    view_byline(Focused, +1);
+    view_byline(currview(), +1);
 }
 
 static void cursor_left(void) {
-    view_byrune(Focused, -1);
+    view_byrune(currview(), -1);
 }
 
 static void cursor_right(void) {
-    view_byrune(Focused, +1);
+    view_byrune(currview(), +1);
 }
 
 static void change_focus(void) {
-    if (Focused == &TagView) {
+    if (Focused == TAGS) {
         if (TagWinExpanded)
             TagWinExpanded = false;
-        Focused = &BufView;
+        Focused = EDIT;
     } else {
-        Focused = &TagView;
+        Focused = TAGS;
         TagWinExpanded = true;
     }
 }
 
-/* UI Callbacks
+/* Mouse Handling
  *****************************************************************************/
-static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) {
+static void mouse_select(size_t x, size_t y) {
+    printf("select: %lu, %lu\n", x, y);
+}
+
+static void mouse_exec(size_t x, size_t y) {
+    printf("exec: %lu, %lu\n", x, y);
+}
+
+static void mouse_fetch(size_t x, size_t y) {
+    printf("fetch: %lu, %lu\n", x, y);
+}
+
+static void mouse_wheelup(size_t x, size_t y) {
+    printf("scroll up: %lu, %lu\n", x, y);
+}
 
+static void mouse_wheeldn(size_t x, size_t y) {
+    printf("scroll down: %lu, %lu\n", x, y);
+}
+
+void (*MouseActs[MOUSE_BTN_COUNT])(size_t x, size_t y) = {
+    [MOUSE_BTN_LEFT]      = mouse_select,
+    [MOUSE_BTN_MIDDLE]    = mouse_exec,
+    [MOUSE_BTN_RIGHT]     = mouse_fetch,
+    [MOUSE_BTN_WHEELUP]   = mouse_wheelup,
+    [MOUSE_BTN_WHEELDOWN] = mouse_wheeldn,
+};
+
+static void mouse_handler(MouseAct act, MouseBtn btn, int x, int y) {
+    printf("%d %d\n", act, btn);
+    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);
+    } else {
+        MouseBtns[btn].pressed = (act == MOUSE_ACT_DOWN);
+        if (MouseBtns[btn].pressed) {
+            /* update the number of clicks and click time */
+            uint32_t now = getmillis();
+            uint32_t elapsed = now - MouseBtns[btn].time;
+            MouseBtns[btn].time = now;
+            if (elapsed <= 250)
+                MouseBtns[btn].count++;
+            else
+                MouseBtns[btn].count = 1;
+        } else {
+            /* execute the action on button release */
+            MouseActs[btn](x,y);
+        }
+    }
 }
 
 /* Keyboard Bindings
  *****************************************************************************/
-typedef struct {
-    Rune key;
-    void (*action)(void);
-} KeyBinding_T;
-
-static KeyBinding_T Insert[] = {
+static KeyBinding Insert[] = {
     { KEY_UP,        cursor_up     },
     { KEY_DOWN,      cursor_dn     },
     { KEY_LEFT,      cursor_left   },
@@ -93,7 +150,7 @@ static KeyBinding_T Insert[] = {
     { 0,             NULL          }
 };
 
-static void process_table(KeyBinding_T* bindings, Rune key) {
+static void process_table(KeyBinding* bindings, Rune key) {
     while (bindings->key) {
         if (key == bindings->key) {
             bindings->action();
@@ -104,7 +161,7 @@ static void process_table(KeyBinding_T* bindings, Rune key) {
     /* fallback to just inserting the rune if it doesnt fall in the private use area.
      * the private use area is used to encode special keys */
     if (key < 0xE000 || key > 0xF8FF)
-        view_insert(Focused, key);
+        view_insert(currview(), key);
 }
 
 static void key_handler(Rune key) {
@@ -112,7 +169,7 @@ static void key_handler(Rune key) {
     if (key == RUNE_ERR) return;
     /* handle the proper line endings */
     if (key == '\r') key = '\n';
-    if (key == '\n' && Focused->buffer.crlf) key = RUNE_CRLF;
+    if (key == '\n' && currview()->buffer.crlf) key = RUNE_CRLF;
     /* handle the key */
     process_table(Insert, key);
 }
@@ -154,12 +211,13 @@ static void draw_glyphs(unsigned x, unsigned y, UGlyph* glyphs, size_t rlen, siz
 }
 
 static void draw_status(int fg, unsigned ncols) {
+    View* view = &(Regions[EDIT].view);
     UGlyph glyphs[ncols], *status = glyphs;
-    (status++)->rune = (BufView.buffer.charset == BINARY ? 'B' : 'U');
-    (status++)->rune = (BufView.buffer.crlf ? 'C' : 'N');
-    (status++)->rune = (BufView.buffer.modified ? '*' : ' ');
+    (status++)->rune = (view->buffer.charset == BINARY ? 'B' : 'U');
+    (status++)->rune = (view->buffer.crlf ? 'C' : 'N');
+    (status++)->rune = (view->buffer.modified ? '*' : ' ');
     (status++)->rune = ' ';
-    char* path = (BufView.buffer.path ? BufView.buffer.path : "*scratch*");
+    char* path = (view->buffer.path ? view->buffer.path : "*scratch*");
     size_t len = strlen(path);
     if (len > ncols-4) {
         (status++)->rune = '.';
@@ -169,60 +227,69 @@ static void draw_status(int fg, unsigned ncols) {
     }
     while(*path)
         (status++)->rune = *path++;
-    draw_runes(0, 0, fg, 0, glyphs, status - glyphs);
+    draw_runes(2, 2, fg, 0, glyphs, status - glyphs);
 }
 
-static size_t stackvert(size_t off, size_t rows) {
-    return (off + 4 + (rows * x11_font_height(Font)));
-}
-
-static size_t draw_view(size_t off, View* view, size_t rows, size_t width) {
+static void draw_region(enum RegionId id) {
     size_t fheight = x11_font_height(Font);
     size_t fwidth  = x11_font_width(Font);
-    size_t cols    = (width - 4) / fwidth;
-    view_resize(view, rows, cols);
     /* update the screen buffer and retrieve cursor coordinates */
+    View* view = &(Regions[id].view);
     size_t csrx, csry;
     view_update(view, &csrx, &csry);
-    /* flush the screen buffer */
-    for (size_t y = 0; y < rows; y++) {
+    /* draw the region to the frame buffer */
+    if (id == TAGS)
+        x11_draw_rect(CLR_BASE02, Regions[id].x-2, Regions[id].y-2, Regions[id].width+4, Regions[id].height+4);
+    x11_draw_rect(CLR_BASE01, 0, Regions[id].y - 3, Regions[id].width + 4, 1);
+    for (size_t y = 0; y < view->nrows; y++) {
         Row* row = view_getrow(view, y);
-        draw_glyphs(2, off + ((y+1) * fheight), row->cols, row->rlen, row->len);
+        draw_glyphs(2, Regions[id].y + ((y+1) * fheight), row->cols, row->rlen, row->len);
     }
     /* Place cursor on screen */
-    if (view == Focused || view == &BufView)
-        x11_draw_rect(CLR_BASE3, 2 + csrx * fwidth, off + (csry * fheight), 1, fheight);
-    return (off + 4 + (rows * x11_font_height(Font)));
+    if (id == Focused || id == EDIT)
+        x11_draw_rect(CLR_BASE3, 2 + csrx * fwidth, Regions[id].y + (csry * fheight), 1, fheight);
+}
+
+static void layout(int width, int height) {
+    /* initialize all of the regions to overlap the status region */
+    size_t fheight = x11_font_height(Font);
+    size_t fwidth  = x11_font_width(Font);
+    for (int i = 0; i < NREGIONS; i++) {
+        Regions[i].x      = 2;
+        Regions[i].y      = 2;
+        Regions[i].width  = (width - 4);
+        Regions[i].height = fheight;
+    }
+    /* Place the tag region relative to status */
+    Regions[TAGS].y      = 5 + Regions[STATUS].y + Regions[STATUS].height;
+    size_t maxtagrows    = ((height - Regions[TAGS].y - 5) / 4) / fheight;
+    size_t tagrows       = (TagWinExpanded ? maxtagrows : 1);
+    Regions[TAGS].height = tagrows * fheight;
+    view_resize(&(Regions[TAGS].view), tagrows, Regions[TAGS].width / fwidth);
+    /* Place the edit region relative to status */
+    Regions[EDIT].y      = 5 + Regions[TAGS].y + Regions[TAGS].height;
+    Regions[EDIT].height = fheight * ((height - Regions[EDIT].y - 5) / 4);
+    view_resize(&(Regions[EDIT].view), Regions[EDIT].height / fheight, Regions[EDIT].width / fwidth);
 }
 
 static void redraw(int width, int height) {
-    size_t vmargin = 2;
-    size_t hmargin = 2;
     size_t fheight = x11_font_height(Font);
     size_t fwidth  = x11_font_width(Font);
-    /* clear background and draw status */
-    size_t vpos = 0;
-    x11_draw_rect(CLR_BASE03, 0, vpos, width, height);
-    draw_status(CLR_BASE3, width / fwidth);
-    /* draw the tag buffer */
-    vpos = stackvert(vpos, 1);
-    x11_draw_rect(CLR_BASE01, 0, vpos++, width, 1);
-    size_t totrows = (height - vpos - 9) / fheight;
-    size_t tagrows = (TagWinExpanded ? (totrows / 4) : 1);
-    size_t bufrows = totrows - tagrows;
-    vpos = draw_view(3+vpos, &TagView, tagrows, width);
-    /* draw thee dit buffer */
-    x11_draw_rect(CLR_BASE01, 0, ++vpos, width, 1);
-    vpos = draw_view(3+vpos, &BufView, bufrows, width);
+    layout(width, height);
+    x11_draw_rect(CLR_BASE03, 0, 0, width, height);
+    x11_draw_rect(CLR_BASE02, (79 * fwidth) + 2, Regions[EDIT].y-2, fwidth, height - Regions[EDIT].y + 2);
+    draw_status(CLR_BASE3, (width - 4) / x11_font_width(Font));
+    draw_region(TAGS);
+    draw_region(EDIT);
 }
 
 /* Main Routine
  *****************************************************************************/
 int main(int argc, char** argv) {
     /* load the buffer views */
-    view_init(&TagView, NULL);
-    view_init(&BufView, (argc > 1 ? argv[1] : NULL));
-    buf_putstr(&(TagView.buffer), 0, 0, DEFAULT_TAGS);
+    view_init(getview(TAGS), NULL);
+    view_init(getview(EDIT), (argc > 1 ? argv[1] : NULL));
+    buf_putstr(getbuf(TAGS), 0, 0, DEFAULT_TAGS);
     /* initialize the display engine */
     x11_init(&Config);
     x11_window("edit", Width, Height);
@@ -387,11 +454,6 @@ void scrolldn(int x, int y) {
 #endif
 /* Mouse Input Handler
  *****************************************************************************/
-struct {
-    uint32_t time;
-    uint32_t count;
-} Buttons[5] = { 0 };
-
 void (*Actions[5][3])(int x, int y) = { 0
                           /*  Single       Double     Triple    */
     //[MOUSE_BTN_LEFT]      = { move_cursor, selection, bigword,  },