ltkx

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

commit 6dd04b169616da62128fa4e952b005d6139c9100
parent 212c90119c1d23d23f18fc5ed5c5ab5af494b79f
Author: lumidify <nobody@lumidify.org>
Date:   Thu, 21 May 2020 20:41:43 +0200

Fix infinite loop in text wrapping; standardize some function names

Diffstat:
Mbutton.c | 21+++++++++++----------
Mbutton.h | 6+++---
Mltk.c | 6++++--
Mtest1.c | 13++++---------
Mtext_buffer.c | 17++++++++++++-----
Mtext_edit.c | 14+++++++-------
Mtext_edit.h | 7+++----
7 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/button.c b/button.c @@ -38,8 +38,8 @@ extern Ltk *ltk_global; -void ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value) -{ +void +ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value) { if (theme->button == NULL) { theme->button = malloc(sizeof(LtkButtonTheme)); } @@ -76,8 +76,8 @@ void ltk_button_ini_handler(LtkTheme *theme, const char *prop, const char *value } } -void ltk_draw_button(LtkButton *button) -{ +void +ltk_button_draw(LtkButton *button) { LtkButtonTheme *theme = ltk_global->theme->button; LtkWindow *window = button->widget.window; LtkRect rect = button->widget.rect; @@ -150,15 +150,15 @@ void ltk_draw_button(LtkButton *button) XPutImage(ltk_global->display, window->xwindow, window->gc, img, 0, 0, text_x, text_y, button->tl->w, button->tl->h); } -LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data) -{ +LtkButton * +ltk_button_create(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data) { LtkButton *button = malloc(sizeof(LtkButton)); if (button == NULL) { ltk_fatal("ERROR: Unable to allocate memory for LtkButton.\n"); } - ltk_fill_widget_defaults(&button->widget, window, &ltk_draw_button, &ltk_destroy_button, 1); + ltk_fill_widget_defaults(&button->widget, window, &ltk_button_draw, &ltk_button_destroy, 1); button->widget.mouse_release = &ltk_button_mouse_release; button->callback = callback; @@ -179,8 +179,8 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac return button; } -void ltk_destroy_button(LtkButton *button) -{ +void +ltk_button_destroy(LtkButton *button) { if (!button) { (void)printf("WARNING: Tried to destroy NULL button.\n"); } @@ -195,7 +195,8 @@ void ltk_destroy_button(LtkButton *button) /* FIXME: is the fixme below supposed to be for the function above? */ /* FIXME: ungrid button if gridded */ -void ltk_button_mouse_release(LtkButton *button, XEvent event) { +void +ltk_button_mouse_release(LtkButton *button, XEvent event) { if (button->widget.state == LTK_HOVERACTIVE && button->callback) { button->callback(button, event, button->data); } diff --git a/button.h b/button.h @@ -61,11 +61,11 @@ typedef struct LtkButtonTheme { XColor fill_disabled; } LtkButtonTheme; -void ltk_draw_button(LtkButton *button); +void ltk_button_draw(LtkButton *button); -LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data); +LtkButton *ltk_button_create(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data); -void ltk_destroy_button(LtkButton *button); +void ltk_button_destroy(LtkButton *button); void ltk_button_mouse_release(LtkButton *button, XEvent event); diff --git a/ltk.c b/ltk.c @@ -185,13 +185,15 @@ void ltk_window_other_event(void *widget, XEvent event) unsigned int w, h; w = event.xconfigure.width; h = event.xconfigure.height; + int orig_w = window->rect.w; + int orig_h = window->rect.h; if (ptr && ptr->resize - && (window->rect.w != w || window->rect.h != h)) { + && (orig_w != w || orig_h != h)) { window->rect.w = w; window->rect.h = h; ptr->rect.w = w; ptr->rect.h = h; - ptr->resize(ptr); + ptr->resize(ptr, orig_w, orig_h); ltk_redraw_window(window); } } diff --git a/test1.c b/test1.c @@ -21,7 +21,6 @@ int main(int argc, char *argv[]) { ltk_init("themes/default.ini"); LtkWindow *window1 = ltk_create_window("Cool Window!", 0, 0, 500, 500); -/* LtkWindow *window2 = ltk_create_window("Cool Window!", 0, 0, 500, 500);*/ LtkGrid *grid1 = ltk_create_grid(window1, 2, 2); window1->root_widget = grid1; ltk_set_row_weight(grid1, 0, 1); @@ -29,18 +28,14 @@ int main(int argc, char *argv[]) ltk_set_column_weight(grid1, 0, 1); ltk_set_column_weight(grid1, 1, 1); /* Test callback functions */ - LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1, NULL); + LtkButton *button1 = ltk_button_create(window1, "I'm a button!", &bob1, NULL); ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT); /* Test manual callback functions */ - LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL, NULL); + LtkButton *button2 = ltk_button_create(window1, "I'm a button!", NULL, NULL); button2->widget.mouse_release = &bob2; ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM); - //LtkButton *button3 = ltk_create_button(window1, "I'm a button!", NULL); - //ltk_grid_widget(button3, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT); - //LtkButton *button4 = ltk_create_button(window1, "I'm a button!", NULL); - //LtkButton *button4 = ltk_create_button(window1, "پَیدایش", NULL); - LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blabla bla"); - LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", &bob3, edit); + LtkTextEdit *edit = ltk_text_edit_create(window1, "ہمارے بارے میں blabla bla"); + LtkButton *button4 = ltk_button_create(window1, "ہمارے بارے میں blablabla", &bob3, edit); ltk_grid_widget(button4, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT); ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM | LTK_STICKY_TOP | LTK_STICKY_RIGHT); ltk_mainloop(); diff --git a/text_buffer.c b/text_buffer.c @@ -77,6 +77,7 @@ ltk_text_line_cleanup_soft_lines(struct ltk_array_line *soft_lines, int old_len) ltk_array_resize_line(soft_lines, soft_lines->len); } +/* FIXME: this is a few pixels off! */ void ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { struct timeval t1, t2; @@ -129,9 +130,11 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { /* 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 (cur->glyphs[j].cluster != glyph->cluster || + j == cur->num_glyphs - 1 || sl->len == 0) { if (j == cur->num_glyphs - 1 && - cur->glyphs[j].cluster == glyph->cluster) { + cur->glyphs[j].cluster == glyph->cluster && + sl->len > 0) { i = j; last_linebreak = cur_start; } else { @@ -172,8 +175,11 @@ ltk_text_line_wrap(struct ltk_text_line *tl, int max_width) { int cur_w = sl->w + glyph->x_abs + glyph->info->w - cur_start; if (cur_w > max_width) { for (int j = i; j >= 0; j--) { - if (cur->glyphs[j].cluster != glyph->cluster || j == 0) { - if (j == 0 && cur->glyphs[j].cluster == glyph->cluster) { + if (cur->glyphs[j].cluster != glyph->cluster || + j == 0 || sl->len == 0) { + if (j == 0 && + cur->glyphs[j].cluster == glyph->cluster && + sl->len > 0) { i = j; last_linebreak = cur_start; } else { @@ -252,7 +258,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 || y < 0 || x < 0) + if (y + i >= img->height || x + j >= img->width || y + i < 0 || x + i < 0) continue; b = (y + i) * img->bytes_per_line + (x + j) * 4; a = glyph->info->alphamap[i * glyph->info->w + j] / 255.0; @@ -263,6 +269,7 @@ ltk_soft_line_draw_glyph(LtkGlyph *glyph, XImage *img, struct ltk_soft_line *sl, } } +/* FIXME: the glyph drawing function sometimes receives negative x positions */ /* FIXME: Fix memory leaks... */ XImage * ltk_text_line_render( diff --git a/text_edit.c b/text_edit.c @@ -40,14 +40,14 @@ extern Ltk *ltk_global; void -ltk_draw_text_edit(LtkTextEdit *te) { +ltk_text_edit_draw(LtkTextEdit *te) { if (!te->img) ltk_text_edit_resize(te, 0, 0); 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; + x += rect.w - te->img->width; 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( @@ -64,7 +64,7 @@ ltk_draw_text_edit(LtkTextEdit *te) { 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) + te->widget.rect.w >= te->img->width && orig_w >= te->img->width) return; XColor fg = ltk_global->theme->window->fg; XColor bg = ltk_global->theme->window->bg; @@ -91,12 +91,12 @@ ltk_text_edit_tmp(LtkTextEdit *te, XEvent event) { #endif LtkTextEdit * -ltk_create_text_edit(LtkWindow *window, const char *text) { +ltk_text_edit_create(LtkWindow *window, const char *text) { LtkTextEdit *te = malloc(sizeof(LtkTextEdit)); if (!te) ltk_fatal("ERROR: Unable to allocate memory for LtkTextEdit.\n"); te->img = NULL; - ltk_fill_widget_defaults(&te->widget, window, &ltk_draw_text_edit, &ltk_destroy_text_edit, 1); + ltk_fill_widget_defaults(&te->widget, window, &ltk_text_edit_draw, &ltk_text_edit_destroy, 1); /*te->widget.mouse_press = &ltk_text_edit_tmp;*/ te->widget.resize = &ltk_text_edit_resize; te->tl = ltk_text_line_create(20); @@ -110,10 +110,10 @@ ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) { 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); + ltk_text_edit_draw(te); } -void ltk_destroy_text_edit(LtkTextEdit *te) { +void ltk_text_edit_destroy(LtkTextEdit *te) { ltk_text_line_destroy(te->tl); if (te->img) XDestroyImage(te->img); free(te); diff --git a/text_edit.h b/text_edit.h @@ -30,11 +30,10 @@ typedef struct { XImage *img; } LtkTextEdit; -/* FIXME: standardize ltk_<widget>_destroy, etc. instead of ltk_destroy_<widget> */ -void ltk_draw_text_edit(LtkTextEdit *te); -LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text); +void ltk_text_edit_draw(LtkTextEdit *te); +LtkTextEdit *ltk_text_edit_create(LtkWindow *window, const char *text); void ltk_text_edit_resize(LtkTextEdit *te, int orig_w, int orig_h); void ltk_text_edit_insert_text(LtkTextEdit *te, const char *text); -void ltk_destroy_text_edit(LtkTextEdit *te); +void ltk_text_edit_destroy(LtkTextEdit *te); #endif /* _LTK_TEXT_EDIT_H_ */