commit 2ed1efbf50d122e1120e32416b71c9838d9c3880
parent b0338320849b8d570511491a73dee2d75aff5fd9
Author: lumidify <nobody@lumidify.org>
Date: Tue, 19 Jan 2021 22:24:35 +0100
Continue adding very broken scrollbar support
Diffstat:
M | box.c | | | 4 | +++- |
M | ltk.h | | | 1 | + |
M | ltkd.c | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
M | scrollbar.c | | | 13 | ++++++++----- |
4 files changed, 79 insertions(+), 46 deletions(-)
diff --git a/box.c b/box.c
@@ -296,7 +296,9 @@ ltk_box_mouse_event(ltk_box *box, XEvent event, void (*handler)(ltk_widget *, XE
ltk_widget *widget;
int old_sc_pos = box->sc->cur_pos;
- if (ltk_collide_rect(box->sc->widget.rect, event.xbutton.x, event.xbutton.y)) {
+ /* FIXME: THIS IS A HACK! */
+ if ((handler == <k_widget_motion_notify_event && box->sc->widget.state == LTK_PRESSED) ||
+ (ltk_collide_rect(box->sc->widget.rect, event.xbutton.x, event.xbutton.y))) {
handler(box->sc, event);
if (old_sc_pos != box->sc->cur_pos) {
ltk_recalculate_box(box);
diff --git a/ltk.h b/ltk.h
@@ -141,6 +141,7 @@ typedef struct ltk_window {
Window xwindow;
ltk_widget *root_widget;
ltk_widget *active_widget;
+ ltk_widget *pressed_widget;
void (*other_event) (ltk_window *, XEvent event);
ltk_rect rect;
ltk_window_theme theme;
diff --git a/ltkd.c b/ltkd.c
@@ -187,7 +187,8 @@ ltk_mainloop(ltk_window *window) {
maxfd = listenfd;
printf("%d", window->xwindow);
- daemonize();
+ fflush(stdout);
+ /*daemonize();*/
while (running) {
rfds = rallfds;
@@ -607,6 +608,8 @@ ltk_create_window(const char *title, int x, int y, unsigned int w, unsigned int
NULL, 0, NULL);
XSetWMProtocols(window->dpy, window->xwindow, &window->wm_delete_msg, 1);
window->root_widget = NULL;
+ window->active_widget = NULL;
+ window->pressed_widget = NULL;
ltk_init_text(window->theme.font, window->dpy, window->screen, window->cm);
@@ -722,6 +725,14 @@ ltk_collide_rect(ltk_rect rect, int x, int y) {
&& (rect.y + rect.h) >= y);
}
+static void
+ltk_widget_change_state(ltk_widget *widget) {
+ if (widget->change_state)
+ widget->change_state(widget);
+ if (widget->needs_redraw)
+ ltk_window_invalidate_rect(widget->window, widget->rect);
+}
+
void
ltk_window_remove_active_widget(ltk_window *window) {
ltk_widget *widget = window->active_widget;
@@ -729,10 +740,7 @@ ltk_window_remove_active_widget(ltk_window *window) {
while (widget) {
widget->state = LTK_NORMAL;
widget->active_widget = NULL;
- if (widget->change_state)
- widget->change_state(widget);
- if (widget->needs_redraw)
- ltk_window_invalidate_rect(window, widget->rect);
+ ltk_widget_change_state(widget);
widget = widget->parent;
}
window->active_widget = NULL;
@@ -742,12 +750,14 @@ void
ltk_window_set_active_widget(ltk_widget *widget) {
widget->window->active_widget = widget;
ltk_widget *parent = widget->parent;
- widget->state = LTK_ACTIVE;
- while (parent) {
+ while (widget) {
widget->state = LTK_ACTIVE;
- parent->active_widget = widget;
+ ltk_widget_change_state(widget);
+ if (parent)
+ parent->active_widget = widget;
widget = parent;
- parent = widget->parent;
+ if (parent)
+ parent = widget->parent;
}
}
@@ -801,60 +811,77 @@ ltk_fill_widget_defaults(ltk_widget *widget, const char *id, ltk_window *window,
}
void
-ltk_widget_mouse_press_event(ltk_widget *widget, XEvent event) {
- if (!widget || widget->state == LTK_DISABLED)
- return;
- if (event.xbutton.button == 1) {
- /* ltk_widget *parent = widget->parent; FIXME: set pressed widget hierarchy */
+ltk_widget_set_pressed(ltk_window *window, ltk_widget *widget) {
+ ltk_widget *act = window->active_widget;
+ ltk_widget *pre = window->pressed_widget;
+ if (pre) {
+ if (act) {
+ act->state = LTK_NORMAL;
+ if (act->needs_redraw)
+ ltk_window_invalidate_rect(window, act->rect);
+ if (act->change_state)
+ act->change_state(act);
+ }
+ pre->state = LTK_ACTIVE;
+ window->active_widget = pre;
+ if (pre->needs_redraw)
+ ltk_window_invalidate_rect(window, pre->rect);
+ if (pre->change_state)
+ pre->change_state(pre);
+ }
+ window->pressed_widget = widget;
+ if (widget) {
widget->state = LTK_PRESSED;
- if (widget->change_state)
- widget->change_state(widget);
if (widget->needs_redraw)
ltk_window_invalidate_rect(widget->window, widget->rect);
+ if (widget->change_state)
+ widget->change_state(widget);
}
- if (widget->mouse_press) {
+}
+
+void
+ltk_widget_mouse_press_event(ltk_widget *widget, XEvent event) {
+ if (!widget || widget->state == LTK_DISABLED)
+ return;
+ if (event.xbutton.button == 1)
+ ltk_widget_set_pressed(widget->window, widget);
+ if (widget->mouse_press)
widget->mouse_press(widget, event);
- }
}
void
ltk_widget_mouse_release_event(ltk_widget *widget, XEvent event) {
- if (!widget || widget->state == LTK_DISABLED)
+ if (!widget)
return;
- /* FIXME: Why does it check for LTK_PRESSED? Is this left over from
- old ltkx, where there was a difference between hover and active? */
- if (widget->state == LTK_PRESSED) {
- widget->state = LTK_ACTIVE;
- if (widget->change_state)
- widget->change_state(widget);
- if (widget->needs_redraw)
- ltk_window_invalidate_rect(widget->window, widget->rect);
- }
- if (widget->mouse_release) {
+ /* FIXME: MAKE THIS WORK MORE CONSISTENTLY FOR OTHER MOUSE BUTTONS */
+ ltk_widget_set_pressed(widget->window, NULL);
+ if (widget->state == LTK_DISABLED)
+ return;
+ if (widget->mouse_release)
widget->mouse_release(widget, event);
- }
}
+/* FIXME: ONLY SET ACTIVE WIDGET AT BOTTOM OF HIERARCHY
+ -> Don't first set parent as active widget and then child */
void
ltk_widget_motion_notify_event(ltk_widget *widget, XEvent event) {
if (!widget) return;
- /* FIXME: THIS WHOLE STATE HANDLING IS BROKEN */
- int pressed = (event.xmotion.state & Button1Mask) == Button1Mask;
- if ((widget->state == LTK_NORMAL) && !pressed) {
+ /* FIXME: THIS WHOLE STATE HANDLING IS STILL PARTIALLY BROKEN */
+ if (((widget->state == LTK_NORMAL) ||
+ (widget->state == LTK_ACTIVE && widget->window->active_widget != widget)) &&
+ !widget->window->pressed_widget) {
widget->state = LTK_ACTIVE;
if (widget->change_state)
widget->change_state(widget);
if (widget->mouse_enter)
widget->mouse_enter(widget, event);
/* FIXME: do this properly */
- if (widget->window->active_widget != widget && !widget->motion_notify) {
- ltk_window_remove_active_widget(widget->window);
- ltk_window_set_active_widget(widget);
- }
- if (widget->needs_redraw)
- ltk_window_invalidate_rect(widget->window, widget->rect);
+ ltk_window_remove_active_widget(widget->window);
+ ltk_window_set_active_widget(widget);
}
- if (widget->motion_notify)
+ if (widget->window->pressed_widget && widget->window->pressed_widget->motion_notify)
+ widget->window->pressed_widget->motion_notify(widget->window->pressed_widget, event);
+ else if (widget->motion_notify)
widget->motion_notify(widget, event);
}
diff --git a/scrollbar.c b/scrollbar.c
@@ -160,18 +160,20 @@ ltk_scrollbar_draw(ltk_scrollbar *scrollbar, ltk_rect clip) {
static void
ltk_scrollbar_mouse_press(ltk_scrollbar *scrollbar, XEvent event) {
- scrollbar->last_mouse_x = event.xbutton.x;
- scrollbar->last_mouse_y = event.xbutton.y;
+ if (event.xbutton.button != 1)
+ return;
+ scrollbar->last_mouse_x = scrollbar->widget.rect.x;
+ scrollbar->last_mouse_y = scrollbar->widget.rect.y;
+ scrollbar->cur_pos = 0;
+ ltk_scrollbar_motion_notify(scrollbar, event);
}
static void
ltk_scrollbar_motion_notify(ltk_scrollbar *sc, XEvent event) {
double scale;
int delta, max_pos;
- /* FIXME: Make this work properly with LTK_PRESSED */
- if ((event.xmotion.state & Button1Mask) != Button1Mask)
+ if (sc->widget.state != LTK_PRESSED)
return;
- ltk_warn("adasd\n");
if (sc->orient == LTK_HORIZONTAL) {
delta = event.xbutton.x - sc->last_mouse_x;
max_pos = sc->virtual_size > sc->widget.rect.w ? sc->virtual_size - sc->widget.rect.w : 0;
@@ -181,6 +183,7 @@ ltk_scrollbar_motion_notify(ltk_scrollbar *sc, XEvent event) {
max_pos = sc->virtual_size > sc->widget.rect.h ? sc->virtual_size - sc->widget.rect.h : 0;
scale = sc->virtual_size / (double)sc->widget.rect.h;
}
+ /* FIXME: This doesn't work because delta is always only one pixel or so */
sc->cur_pos += (int)(scale * delta);
if (sc->cur_pos < 0)
sc->cur_pos = 0;