ltkx

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

commit 0e40d68a8b98ca331bfad96d3293d9c01c5875ca
parent 440540f9caf405888a176c460cffff8669478b9e
Author: lumidify <nobody@lumidify.org>
Date:   Fri, 15 May 2020 09:39:58 +0200

Fix errors with resizing arrays; test inserting text

Diffstat:
Marray.h | 7++++---
Mbutton.c | 9+++++----
Mbutton.h | 5+++--
Mtest1.c | 14+++++++++-----
Mtext-hb.c | 4----
Mtext_buffer.c | 37+++++++++++++++++++------------------
Mtext_edit.c | 13++++++++++++-
Mtext_edit.h | 1+
8 files changed, 53 insertions(+), 37 deletions(-)

diff --git a/array.h b/array.h @@ -82,16 +82,17 @@ ltk_array_prepare_gap_##name(struct ltk_array_##name *ar, size_t index, size_t l } \ ltk_array_resize_##name(ar, ar->len + len); \ ar->len += len; \ - if (ar->len == index) \ + if (ar->len - len == index) \ return; \ - memmove(ar->buf + index + len, ar->buf + index, ar->len - index); \ + memmove(ar->buf + index + len, ar->buf + index, \ + (ar->len - len - index) * sizeof(type)); \ } \ \ void \ ltk_array_insert_##name(struct ltk_array_##name *ar, size_t index, \ type *elem, size_t len) { \ ltk_array_prepare_gap_##name(ar, index, len); \ - ltk_array_resize_##name(ar, ar->len + len); \ + /*ltk_array_resize_##name(ar, ar->len + len);*/ \ for (int i = 0; i < len; i++) { \ ar->buf[index + i] = elem[i]; \ } \ diff --git a/button.c b/button.c @@ -21,6 +21,7 @@ * SOFTWARE. */ +#include <stdio.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include "khash.h" @@ -147,7 +148,7 @@ 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)) +LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callback) (void *, XEvent, void *), void *data) { LtkButton *button = malloc(sizeof(LtkButton)); @@ -159,6 +160,7 @@ LtkButton *ltk_create_button(LtkWindow *window, const char *text, void (*callbac button->widget.mouse_release = &ltk_button_mouse_release; button->callback = callback; + button->data = data; LtkTheme *theme = ltk_global->theme; button->tl = ltk_create_text_line(ltk_global->tm, text, ltk_global->tm->default_font, theme->button->font_size); button->widget.rect.w = button->tl->w + (theme->button->border_width + theme->button->pad) * 2; @@ -188,9 +190,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->callback(button, event, button->data); } } diff --git a/button.h b/button.h @@ -28,7 +28,8 @@ typedef struct { LtkWidget widget; - void (*callback) (void); + void (*callback) (void *, XEvent, void *); + void *data; LtkTextLine *tl; XImage *text; XImage *text_hover; @@ -61,7 +62,7 @@ typedef struct LtkButtonTheme { void ltk_draw_button(LtkButton *button); -LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void)); +LtkButton *ltk_create_button(LtkWindow * window, const char *text, void (*callback) (void *, XEvent, void *), void *data); void ltk_destroy_button(LtkButton *button); diff --git a/test1.c b/test1.c @@ -1,11 +1,11 @@ #include "ltkx.h" -void bob1(void) +void bob1(void *widget, XEvent event, void *data) { printf("bob\n"); } -void bob2(void *widget, XEvent event) +void bob2(void *widget, XEvent event, void *data) { LtkButton *button = widget; if (button->widget.state == LTK_HOVERACTIVE) { @@ -13,6 +13,10 @@ void bob2(void *widget, XEvent event) } } +void bob3(LtkButton *button, XEvent event, LtkTextEdit *edit) { + ltk_text_edit_insert_text(edit, "asd"); +} + int main(int argc, char *argv[]) { ltk_init("themes/default.ini"); @@ -25,18 +29,18 @@ 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); + LtkButton *button1 = ltk_create_button(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); + LtkButton *button2 = ltk_create_button(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, "ہمارے بارے میں blablabla", NULL); //LtkButton *button4 = ltk_create_button(window1, "پَیدایش", NULL); LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blablabla"); + LtkButton *button4 = ltk_create_button(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_mainloop(); diff --git a/text-hb.c b/text-hb.c @@ -226,10 +226,6 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui hb_buffer_set_direction(buf, dir); hb_buffer_set_script(buf, script); hb_buffer_add_utf32(buf, ts->str, len, 0, len); - for (int i = 0; i < len; i++) { - printf("%d\n", ts->str[i]); - } - printf("\n"); /* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html * this should be level 1 clustering instead of level 0 */ hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); diff --git a/text_buffer.c b/text_buffer.c @@ -146,6 +146,7 @@ ltk_render_text_line_new( index = par_is_rtl ? cur->num_glyphs - k - 1 : k; glyph = &cur->glyphs[index]; x = par_is_rtl ? max_width - ((tl->w - glyph->x_abs) - cur_line_x) : glyph->x_abs - cur_line_x; + /* FIXME: use the computed indeces from above */ if (par_is_rtl && x < 0) { cur_line++; cur_line_x = (tl->w - glyph->x_abs - glyph->info->w); @@ -339,9 +340,6 @@ ltk_text_line_itemize(struct ltk_text_line *tl) { size_t end_index; hb_direction_t dir; int par_is_rtl = FRIBIDI_IS_RTL(tl->dir); - for (int i = 0; i < tl->len; i++) { - printf("%d, %d, %d, %d\n", tl->bidi_levels->buf[i], tl->scripts->buf[i], tl->log2vis->buf[i], tl->vis2log->buf[i]); - } while (start_index < tl->len) { end_index = start_index; cur_level = last_level = tl->bidi_levels->buf[tl->vis2log->buf[start_index]]; @@ -358,8 +356,12 @@ ltk_text_line_itemize(struct ltk_text_line *tl) { dir = HB_DIRECTION_LTR; if (FRIBIDI_LEVEL_IS_RTL(last_level)) dir = HB_DIRECTION_RTL; + size_t start_log = tl->vis2log->buf[start_index]; + size_t end_log = tl->vis2log->buf[end_index - 1]; + if (start_log > end_log) + start_log = end_log; new = ltk_text_run_create( - start_index, end_index - start_index, last_script, dir); + start_log, end_index - start_index, last_script, dir); if (!first_run) { first_run = new; } else { @@ -397,12 +399,15 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, buf = hb_buffer_create(); /* Harfbuzz requires the original, non-reversed text. - Yes, I know this is a bit hacky */ + Yes, I know this is a bit hacky + Update: This is now done in the ltk_text_line_itemize already */ + /* size_t start_index = tl->vis2log->buf[tr->start_index]; size_t end_index = tl->vis2log->buf[tr->start_index + tr->len - 1]; if (start_index > end_index) start_index = end_index; - hb_buffer_add_utf32(buf, tl->log_buf->buf, tl->len, start_index, tr->len); + */ + hb_buffer_add_utf32(buf, tl->log_buf->buf, tl->len, tr->start_index, tr->len); hb_buffer_set_direction(buf, tr->dir); hb_buffer_set_script(buf, tr->script); /* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html @@ -412,10 +417,6 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, ginf = hb_buffer_get_glyph_infos(buf, &tr->num_glyphs); gpos = hb_buffer_get_glyph_positions(buf, &tr->num_glyphs); float scale = stbtt_ScaleForMappingEmToPixels(&tr->font->info, font_size); - for (int i = start_index; i < start_index + tr->len; i++) { - printf("%d %d\n", tl->log_buf->buf[i], tr->len); - } - printf("\n"); int x_min = INT_MAX, x_max = INT_MIN, y_min = INT_MAX, y_max = INT_MIN; int x_abs = 0, y_abs = 0, x1_abs, y1_abs, x2_abs, y2_abs; @@ -476,7 +477,8 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { tl->w = tl->h = 0; int x_max, y_max; while (run) { - FcPattern *pat = FcPatternDuplicate(tm->fcpattern); + /* Question: Why does this not work with Duplicate? */ + FcPattern *pat = FcPatternCreate();//FcPatternDuplicate(tm->fcpattern); FcPattern *match; FcResult result; FcPatternAddBool(pat, FC_SCALABLE, 1); @@ -484,7 +486,7 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { FcDefaultSubstitute(pat); FcCharSet *cs = FcCharSetCreate(); for (size_t i = run->start_index; i < run->start_index + run->len; i++) { - FcCharSetAddChar(cs, tl->vis_buf->buf[i]); + FcCharSetAddChar(cs, tl->log_buf->buf[i]); } FcPatternAddCharSet(pat, FC_CHARSET, cs); match = FcFontMatch(NULL, pat, &result); @@ -493,7 +495,6 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { uint16_t font_id = ltk_get_font(tm, file); khint_t k = kh_get(fontstruct, tm->font_cache, font_id); run->font = kh_value(tm->font_cache, k); - fflush(stdout); FcPatternDestroy(match); FcPatternDestroy(pat); ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max); @@ -588,12 +589,12 @@ ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len) hb_unicode_funcs_t *ufuncs = hb_unicode_funcs_get_default(); for (int i = 0; i < len; i++) tl->scripts->buf[tl->cursor_pos + i] = hb_unicode_script(ufuncs, text[i]); - ltk_array_resize_uint32(tl->vis_buf, tl->vis_buf->len + len); - ltk_array_resize_int(tl->log2vis, tl->log2vis->len + len); - ltk_array_resize_int(tl->vis2log, tl->vis2log->len + len); - ltk_array_resize_level(tl->bidi_levels, tl->bidi_levels->len + len); + ltk_array_resize_uint32(tl->vis_buf, tl->len + len); + ltk_array_resize_int(tl->log2vis, tl->len + len); + ltk_array_resize_int(tl->vis2log, tl->len + len); + ltk_array_resize_level(tl->bidi_levels, tl->len + len); tl->len += len; - tl->cursor_pos += len; + /*tl->cursor_pos += len;*/ /* FIXME */ /* FIXME: Why am I passing tm? It's global anyways */ ltk_text_line_recalculate(ltk_global->tm, tl); } diff --git a/text_edit.c b/text_edit.c @@ -49,7 +49,8 @@ ltk_draw_text_edit(LtkTextEdit *te) { XPutImage(ltk_global->display, window->xwindow, window->gc, te->img, 0, 0, rect.x, rect.y, te->img->width, te->img->height); } -LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) { +LtkTextEdit * +ltk_create_text_edit(LtkWindow *window, const char *text) { LtkTextEdit *te = malloc(sizeof(LtkTextEdit)); if (!te) ltk_fatal("ERROR: Unable to allocate memory for LtkTextEdit.\n"); @@ -59,6 +60,16 @@ LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) { te->img = NULL; return te; } + +void +ltk_text_edit_insert_text(LtkTextEdit *te, const char *text) { + ltk_text_line_insert_utf8(te->tl, text); + if (te->img) XDestroyImage(te->img); + te->img = NULL; + /* FIXME: Need to "queue redraw" for whole window */ + ltk_draw_text_edit(te); +} + void ltk_destroy_text_edit(LtkTextEdit *te) { ltk_text_line_destroy(te->tl); if (te->img) XDestroyImage(te->img); diff --git a/text_edit.h b/text_edit.h @@ -33,6 +33,7 @@ typedef struct { /* 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_insert_text(LtkTextEdit *te, const char *text); void ltk_destroy_text_edit(LtkTextEdit *te); #endif /* _LTK_TEXT_EDIT_H_ */