ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

commit 201782e6c6df60ab9082852042d210b5d809f797
parent ba0e522da0cb698021de15f24971b8c661d3941f
Author: lumidify <nobody@lumidify.org>
Date:   Thu, 21 May 2020 19:42:00 +0200

Somewhat handle resize for text edit

Diffstat:
Mgrid.c | 2+-
Mltk.h | 2+-
Mtext_buffer.c | 12+++++++++---
Mtext_edit.c | 34++++++++++++++++++++++++++++------
4 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/grid.c b/grid.c @@ -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); } } diff --git a/ltk.h b/ltk.h @@ -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 *); diff --git a/text_buffer.c b/text_buffer.c @@ -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 && @@ -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); @@ -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; diff --git a/text_edit.c b/text_edit.c @@ -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 @@ -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; } @@ -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); }