commit 8e162e7755e980a1f9bb03541201482b15fd89eb
parent dd010d6ac6864d58107799eb3625cdd4660684a1
Author: lumidify <nobody@lumidify.org>
Date: Sun, 24 Jan 2021 17:24:30 +0100
Make button clipping work somewhat
Diffstat:
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,
<k_button_draw, <k_button_change_state, <k_button_destroy, 1, LTK_BUTTON);
button->widget.mouse_release = <k_button_mouse_release;
+ button->widget.resize = <k_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 = <k_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