ltk

Socket-based GUI for X11 (WIP)
git clone git://lumidify.org/ltk.git (fast, but not encrypted)
git clone https://lumidify.org/git/ltk.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit 8e162e7755e980a1f9bb03541201482b15fd89eb
parent dd010d6ac6864d58107799eb3625cdd4660684a1
Author: lumidify <nobody@lumidify.org>
Date:   Sun, 24 Jan 2021 17:24:30 +0100

Make button clipping work somewhat

Diffstat:
Mbutton.c | 52+++++++++++++++++++++++++++++++++++++++++-----------
Mbutton.h | 2+-
Mdraw.c | 11++++-------
Mltk.h | 1+
Mltkd.c | 3+++
Mtext.h | 2+-
Mtext_pango.c | 4++--
Mtext_stb.c | 5++++-
8 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/button.c b/button.c @@ -132,6 +132,15 @@ ltk_button_draw(ltk_button *button, ltk_rect clip) { /* no idea why it would be less than 0, but whatever */ if (clip_final.w <= 0 || clip_final.h <= 0) return; + XCopyArea(window->dpy, button->pixmap, window->xwindow, window->gc, + clip_final.x - rect.x, clip_final.y - rect.y, + clip_final.w, clip_final.h, clip_final.x, clip_final.y); +} + +static void +ltk_button_redraw_pixmap(ltk_button *button) { + ltk_window *window = button->widget.window; + ltk_rect rect = button->widget.rect; int bw = theme.border_width; LtkColor *border; LtkColor *fill; @@ -156,25 +165,42 @@ ltk_button_draw(ltk_button *button, ltk_rect clip) { ltk_fatal("No style found for button!\n"); } XSetForeground(window->dpy, window->gc, fill->xcolor.pixel); - XFillRectangle(window->dpy, window->xwindow, window->gc, clip_final.x, - clip_final.y, clip_final.w, clip_final.h); + XFillRectangle(window->dpy, button->pixmap, window->gc, 0, 0, rect.w, rect.h); /* FIXME: Why did I do this? */ if (bw < 1) return; - /* FIXME: Maybe draw to tmp pixmap first, so this can be done properly? */ - /* XSetForeground(window->dpy, window->gc, border->xcolor.pixel); XSetLineAttributes(window->dpy, window->gc, bw, LineSolid, CapButt, JoinMiter); - XDrawRectangle(window->dpy, window->xwindow, window->gc, - rect.x + bw / 2, rect.y + bw / 2, rect.w - bw, rect.h - bw); - */ + XDrawRectangle(window->dpy, button->pixmap, window->gc, + bw / 2, bw / 2, rect.w - bw, rect.h - bw); int text_w, text_h; ltk_text_line_get_size(button->tl, &text_w, &text_h); - int text_x = rect.x + (rect.w - text_w) / 2; - int text_y = rect.y + (rect.h - text_h) / 2; - /* FIXME: Actually use button->text_pixmap */ - ltk_text_line_draw(button->tl, window->gc, text_x, text_y, clip_final); + int text_x = (rect.w - text_w) / 2; + int text_y = (rect.h - text_h) / 2; + /* FIXME: Remove clipping rect from text line - this is just used here as a dummy + because it is completely ignored */ + ltk_text_line_draw(button->tl, button->pixmap, window->gc, text_x, text_y, rect); +} + +/* FIXME: Make this amortised constant; make it generic for all widgets */ +static void +ltk_button_resize(ltk_button *button) { + Window win; + int x, y, w, h, bw, d; + int new_w, new_h; + ltk_window *window = button->widget.window; + ltk_rect rect = button->widget.rect; + XGetGeometry(window->dpy, button->pixmap, &win, &x, &y, &w, &h, &bw, &d); + + new_w = w < rect.w ? rect.w : w; + new_h = h < rect.h ? rect.h : h; + if (new_w < w && new_h < h) + return; + XFreePixmap(window->dpy, button->pixmap); + button->pixmap = XCreatePixmap(window->dpy, window->xwindow, + new_w, new_h, window->depth); + ltk_button_redraw_pixmap(button); } static void @@ -198,6 +224,7 @@ ltk_button_change_state(ltk_button *button) { ltk_fatal("No style found for button!\n"); } ltk_text_line_render(button->tl, fill, &theme.text_color); + ltk_button_redraw_pixmap(button); } static int @@ -215,6 +242,7 @@ ltk_button_create(ltk_window *window, const char *id, const char *text) { ltk_fill_widget_defaults(&button->widget, id, window, &ltk_button_draw, &ltk_button_change_state, &ltk_button_destroy, 1, LTK_BUTTON); button->widget.mouse_release = &ltk_button_mouse_release; + button->widget.resize = &ltk_button_resize; uint16_t font_size = window->theme.font_size; text_copy = strdup(text); if (!text_copy) @@ -224,6 +252,8 @@ ltk_button_create(ltk_window *window, const char *id, const char *text) { ltk_text_line_get_size(button->tl, &text_w, &text_h); button->widget.ideal_w = text_w + theme.border_width * 2 + theme.pad * 2; button->widget.ideal_h = text_h + theme.border_width * 2 + theme.pad * 2; + button->pixmap = XCreatePixmap(window->dpy, window->xwindow, + button->widget.ideal_w, button->widget.ideal_h, window->depth); /* render text */ ltk_button_change_state(button); diff --git a/button.h b/button.h @@ -29,7 +29,7 @@ typedef struct { ltk_widget widget; LtkTextLine *tl; - Pixmap text_pixmap; + Pixmap pixmap; } ltk_button; void ltk_button_setup_theme_defaults(ltk_window *window); diff --git a/draw.c b/draw.c @@ -37,7 +37,7 @@ static void ltk_draw_draw(ltk_draw *draw); static ltk_draw *ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *color); -static void ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h); +static void ltk_draw_resize(ltk_draw *draw); static void ltk_draw_destroy(ltk_draw *draw, int shallow); static void ltk_draw_clear(ltk_window *window, ltk_draw *draw); static void ltk_draw_set_color(ltk_window *window, ltk_draw *draw, const char *color); @@ -79,7 +79,6 @@ ltk_draw_draw(ltk_draw *draw) { static ltk_draw * ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *color) { - XWindowAttributes attrs; ltk_draw *draw = malloc(sizeof(ltk_draw)); if (!draw) ltk_fatal_errno("Unable to allocate memory for ltk_draw.\n"); @@ -88,9 +87,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co draw->widget.resize = &ltk_draw_resize; draw->widget.rect.w = w; draw->widget.rect.h = h; - XGetWindowAttributes(window->dpy, window->xwindow, &attrs); - draw->depth = attrs.depth; - draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, draw->depth); + draw->pix = XCreatePixmap(window->dpy, window->xwindow, w, h, window->depth); if (!ltk_create_xcolor(window, color, &draw->bg)) { free(draw); ltk_fatal_errno("Unable to allocate XColor.\n"); @@ -103,7 +100,7 @@ ltk_draw_create(ltk_window *window, const char *id, int w, int h, const char *co } static void -ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h) { +ltk_draw_resize(ltk_draw *draw) { Window win; int x, y, w, h, bw, d; int new_w, new_h; @@ -116,7 +113,7 @@ ltk_draw_resize(ltk_draw *draw, int orig_w, int orig_h) { if (new_w < w && new_h < h) return; Pixmap tmp = XCreatePixmap(window->dpy, window->xwindow, - new_w, new_h, draw->depth); + new_w, new_h, window->depth); XSetForeground(window->dpy, window->gc, draw->bg.pixel); XFillRectangle(window->dpy, tmp, window->gc, 0, 0, new_w, new_h); XCopyArea(window->dpy, draw->pix, tmp, window->gc, diff --git a/ltk.h b/ltk.h @@ -139,6 +139,7 @@ typedef struct ltk_window { int screen; Atom wm_delete_msg; Window xwindow; + int depth; ltk_widget *root_widget; ltk_widget *active_widget; ltk_widget *pressed_widget; diff --git a/ltkd.c b/ltkd.c @@ -581,6 +581,7 @@ ltk_window_other_event(ltk_window *window, XEvent event) { static ltk_window * ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int h) { char *theme_path; + XWindowAttributes attrs; ltk_window *window = malloc(sizeof(ltk_window)); if (!window) @@ -601,6 +602,8 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int XCreateSimpleWindow(window->dpy, DefaultRootWindow(window->dpy), x, y, w, h, window->theme.border_width, window->theme.fg.xcolor.pixel, window->theme.bg.xcolor.pixel); + XGetWindowAttributes(window->dpy, window->xwindow, &attrs); + window->depth = attrs.depth; window->gc = XCreateGC(window->dpy, window->xwindow, 0, 0); XSetForeground(window->dpy, window->gc, window->theme.fg.xcolor.pixel); XSetBackground(window->dpy, window->gc, window->theme.bg.xcolor.pixel); diff --git a/text.h b/text.h @@ -10,7 +10,7 @@ void ltk_init_text(const char *default_font, Display *dpy, int screen, Colormap void ltk_cleanup_text(void); LtkTextLine *ltk_text_line_create(Window window, uint16_t font_size, char *text, int width); void ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg); -void ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip); +void ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip); void ltk_text_line_set_width(LtkTextLine *tl, int width); void ltk_text_line_get_size(LtkTextLine *tl, int *w, int *h); void ltk_text_line_destroy(LtkTextLine *tl); diff --git a/text_pango.c b/text_pango.c @@ -98,8 +98,8 @@ ltk_text_line_render(LtkTextLine *tl, LtkColor *bg, LtkColor *fg) { } void -ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) { - XCopyArea(tm.dpy, tl->pixmap, tl->window, gc, 0, 0, tl->w, tl->h, x, y); +ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip) { + XCopyArea(tm.dpy, tl->pixmap, d, gc, 0, 0, tl->w, tl->h, x, y); } void diff --git a/text_stb.c b/text_stb.c @@ -534,7 +534,8 @@ ltk_text_line_render( /* FIXME: error checking if img is rendered yet, tm initialized, etc. */ void -ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) { +ltk_text_line_draw(LtkTextLine *tl, Drawable d, GC gc, int x, int y, ltk_rect clip) { + /* int xoff = clip.x - x; int yoff = clip.y - y; xoff = xoff >= 0 ? xoff : 0; @@ -542,6 +543,8 @@ ltk_text_line_draw(LtkTextLine *tl, GC gc, int x, int y, ltk_rect clip) { int w = clip.w > tl->w - xoff ? tl->w - xoff : clip.w; int h = clip.h > tl->h - yoff ? tl->h - yoff : clip.h; XPutImage(tm.dpy, tl->window, gc, tl->img, xoff, yoff, x + xoff, y + yoff, w, h); + */ + XPutImage(tm.dpy, d, gc, tl->img, 0, 0, x, y, tl->w, tl->h); } void