URI: 
       tSomewhat handle resize for text edit - ltkx - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltkx.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 201782e6c6df60ab9082852042d210b5d809f797
   DIR parent ba0e522da0cb698021de15f24971b8c661d3941f
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Thu, 21 May 2020 19:42:00 +0200
       
       Somewhat handle resize for text edit
       
       Diffstat:
         M grid.c                              |       2 +-
         M ltk.h                               |       2 +-
         M text_buffer.c                       |      12 +++++++++---
         M text_edit.c                         |      34 +++++++++++++++++++++++++------
       
       4 files changed, 39 insertions(+), 11 deletions(-)
       ---
   DIR diff --git a/grid.c b/grid.c
       t@@ -174,7 +174,7 @@ void ltk_recalculate_grid(LtkGrid *grid)
                                }
                                if (orig_width != ptr->rect.w || orig_height != ptr->rect.h) {
                                        if (ptr->resize) {
       -                                        ptr->resize(ptr);
       +                                        ptr->resize(ptr, orig_width, orig_height);
                                        }
                                }
        
   DIR diff --git a/ltk.h b/ltk.h
       t@@ -65,7 +65,7 @@ typedef struct LtkWidget {
                void (*mouse_release) (void *, XEvent event);
                void (*motion_notify) (void *, XEvent event);
        
       -        void (*resize) (void *);
       +        void (*resize) (void *, int, int);
                void (*draw) (void *);
                void (*destroy) (void *);
        
   DIR diff --git a/text_buffer.c b/text_buffer.c
       t@@ -126,7 +126,8 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
                                        glyph = &cur->glyphs[i];
                                        int cur_w = sl->w + cur_start - glyph->x_abs;
                                        if (cur_w > max_width) {
       -                                        /* FIXME: fix behavior when line isn't wide enough for single char */
       +                                        /* FIXME: fix behavior when line isn't wide enough for single char
       +                                           (currently causes infinite loop) */
                                                for (int j = i; j < cur->num_glyphs; j++) {
                                                        if (cur->glyphs[j].cluster != glyph->cluster || j == cur->num_glyphs - 1) {
                                                                if (j == cur->num_glyphs - 1 &&
       t@@ -210,7 +211,12 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) {
                        cur = par_is_rtl ? cur->last : cur->next;
                }
                ltk_text_line_cleanup_soft_lines(tl->soft_lines, old_len);
       -        tl->w_wrapped = max_width;
       +        /* if it fits on one line, don't waste all the space to the end of
       +           the line, just use the actual width of the text */
       +        if (tl->soft_lines->len == 1)
       +                tl->w_wrapped = tl->soft_lines->buf[0]->w;
       +        else
       +                tl->w_wrapped = max_width;
                tl->h_wrapped = tl->soft_lines->len * tl->h;
        
                gettimeofday(&t2, NULL);
       t@@ -246,7 +252,7 @@ ltk_soft_line_draw_glyph(LtkGlyph *glyph, XImage *img, struct ltk_soft_line *sl,
                int b;
                for (int i = 0; i < glyph->info->h; i++) {
                        for (int j = 0; j < glyph->info->w; j++) {
       -                        if (y + i >= img->height || x + j >= img->width)
       +                        if (y + i >= img->height || x + j >= img->width || y < 0 || x < 0)
                                        continue;
                                b = (y + i) * img->bytes_per_line + (x + j) * 4;
                                a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0;
   DIR diff --git a/text_edit.c b/text_edit.c
       t@@ -41,15 +41,35 @@ extern Ltk *ltk_global;
        
        void
        ltk_draw_text_edit(LtkTextEdit *te) {
       +        /* FIXME: this requires img to be non-null */
       +        LtkRect rect = te->widget.rect;
       +        LtkWindow *window = te->widget.window;
       +        int x = rect.x;
       +        if (te->tl->dir == HB_DIRECTION_RTL)
       +                x += rect.w - te->tl->w_wrapped;
       +        XSetForeground(ltk_global->display, window->gc, ltk_global->theme->window->bg.pixel);
       +        XFillRectangle(ltk_global->display, window->xwindow, window->gc, rect.x, rect.y, rect.w, rect.h);
       +        XPutImage(
       +            ltk_global->display,
       +            window->xwindow,
       +            window->gc,
       +            te->tl->img,
       +            0, 0,
       +            x, rect.y,
       +            te->tl->w_wrapped, te->tl->h_wrapped
       +        );
       +}
       +
       +void
       +ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h) {
       +        if (te->tl->soft_lines->len == 1 &&
       +            te->widget.rect.w >= te->tl->w_wrapped && orig_w >= te->tl->w_wrapped)
       +                return;
                XColor fg = ltk_global->theme->window->fg;
                XColor bg = ltk_global->theme->window->bg;
       -        LtkRect rect = te->widget.rect;
                LtkWindow *window = te->widget.window;
       -        /* FIXME: need special "resize" function called by grid, etc.
       -           to avoid recalculating everything when it really only has to drawn */
       -        ltk_text_line_wrap(te->tl, rect.w);
       +        ltk_text_line_wrap(te->tl, te->widget.rect.w);
                ltk_text_line_render(te->tl, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg);
       -        XPutImage(ltk_global->display, window->xwindow, window->gc, te->tl->img, 0, 0, rect.x, rect.y, rect.w, rect.h);
        }
        
        #if 0
       t@@ -75,8 +95,9 @@ ltk_create_text_edit(LtkWindow *window, const char *text) {
                        ltk_fatal("ERROR: Unable to allocate memory for LtkTextEdit.\n");
                ltk_fill_widget_defaults(&te->widget, window, &ltk_draw_text_edit, &ltk_destroy_text_edit, 1);
                /*te->widget.mouse_press = &ltk_text_edit_tmp;*/
       +        te->widget.resize = &ltk_text_edit_resize;
                te->tl = ltk_text_line_create();
       -        ltk_text_line_insert_utf8(te->tl, 0, text);
       +        ltk_text_edit_insert_text(te, text);
                return te;
        }
        
       t@@ -84,6 +105,7 @@ void
        ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) {
                /* FIXME */
                ltk_text_line_insert_utf8(te->tl, 0, text);
       +        ltk_text_edit_resize(te, 0, 0);
                /* FIXME: Need to "queue redraw" for whole window */
                ltk_draw_text_edit(te);
        }