From bf60cac302345f84aa6f12563677b85e0d879959 Mon Sep 17 00:00:00 2001 From: Mid <> Date: Thu, 28 Aug 2025 19:14:02 +0300 Subject: [PATCH] Menu mouse capturing --- src/k3menu.c | 99 +++++++++++++++++++++++++++++++++------------------- src/k3menu.h | 2 ++ 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/k3menu.c b/src/k3menu.c index 3ba59bb..aff35f1 100644 --- a/src/k3menu.c +++ b/src/k3menu.c @@ -296,31 +296,36 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) { struct k3MScreen *this = (void*) ev->target; if(ev->code == k3M_EVENT_MOUSE_PRESS || ev->code == k3M_EVENT_MOUSE_RELEASE || ev->code == k3M_EVENT_MOUSE_MOTION) { - struct k3MObj *innermost = (void*) this; + struct k3MObj *innermost; - while(innermost->childCount != 0) { - - bool foundInner = false; - - for(intmax_t i = innermost->childCount - 1; i >= 0; i--) { + if(this->mouseCapture) { + innermost = this->mouseCapture; + } else { + innermost = (struct k3MObj*) this; + while(innermost->childCount != 0) { - struct k3MObj *child = innermost->children[i]; + bool foundInner = false; - if(!child->invisible && ev->mouse.x >= child->x && ev->mouse.x < child->x + child->w && ev->mouse.y >= child->y && ev->mouse.y < child->y + child->h) { + for(intmax_t i = innermost->childCount - 1; i >= 0; i--) { - innermost = child; - foundInner = true; + struct k3MObj *child = innermost->children[i]; - break; + if(!child->invisible && ev->mouse.x >= child->x && ev->mouse.x < child->x + child->w && ev->mouse.y >= child->y && ev->mouse.y < child->y + child->h) { + + innermost = child; + foundInner = true; + + break; + + } } + if(!foundInner) { + break; + } + } - - if(!foundInner) { - break; - } - } if(innermost != this->lastHover) { @@ -455,6 +460,18 @@ struct k3MScreen *k3MScreen() { return ret; } +bool k3MCaptureMouse(struct k3MScreen *screen, struct k3MObj *capt) { + if(screen->mouseCapture) { + return false; + } + + screen->mouseCapture = capt; + + return true; +} +void k3MReleaseMouse(struct k3MScreen *screen) { + screen->mouseCapture = NULL; +} static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) { struct k3MTextButton *this = (void*) ev->target; @@ -647,27 +664,37 @@ static bool scrollbox_mouseshit(struct k3MEvent *ev, uint8_t *ud) { struct k3MScrollbox *this = (void*) ev->target; if(ev->code == k3M_EVENT_MOUSE_PRESS) { - struct k3MProperty *prop = k3MFindProperty(ev->target, k3M_PROP_SCROLL_ANYWHERE, false); - bool scrollAnywhere = prop ? prop->si[0] : false; - - int scrollbarWidth = SCROLLBAR_WIDTH_DEFAULT; - prop = k3MFindProperty(ev->target, k3M_PROP_SCROLLBAR_SIZE, false); - if(prop) { - scrollbarWidth = prop->si[0]; + if(k3MCaptureMouse((struct k3MScreen*) ev->original, this)) { + + struct k3MProperty *prop = k3MFindProperty(ev->target, k3M_PROP_SCROLL_ANYWHERE, false); + bool scrollAnywhere = prop ? prop->si[0] : false; + + int scrollbarWidth = SCROLLBAR_WIDTH_DEFAULT; + prop = k3MFindProperty(ev->target, k3M_PROP_SCROLLBAR_SIZE, false); + if(prop) { + scrollbarWidth = prop->si[0]; + } + + if(ev->mouse.x >= this->x + this->w - scrollbarWidth) { + this->mouseHeld = 1; + } else if(scrollAnywhere) { + this->mouseHeld = 2; + } else { + this->mouseHeld = 0; + } + + this->mouseX = ev->mouse.x; + this->mouseY = ev->mouse.y; + + return !!this->mouseHeld; } - - if(ev->mouse.x >= this->x + this->w - scrollbarWidth) { - this->mouseHeld = 1; - } else if(scrollAnywhere) { - this->mouseHeld = 2; - } else { - this->mouseHeld = 0; - } - - this->mouseX = ev->mouse.x; - this->mouseY = ev->mouse.y; } else if(ev->code == k3M_EVENT_MOUSE_RELEASE) { - this->mouseHeld = false; + if(this->mouseHeld) { + this->mouseHeld = false; + k3MReleaseMouse((struct k3MScreen*) ev->original); + + return true; + } } else if(ev->code == k3M_EVENT_MOUSE_MOTION) { if(this->mouseHeld) { @@ -694,6 +721,8 @@ static bool scrollbox_mouseshit(struct k3MEvent *ev, uint8_t *ud) { k3MArrange(contentBox); + return true; + } } diff --git a/src/k3menu.h b/src/k3menu.h index 3f33586..183a2cc 100644 --- a/src/k3menu.h +++ b/src/k3menu.h @@ -179,6 +179,8 @@ struct k3MScreen { struct k3MObj *mouseCapture; }; struct k3MScreen *k3MScreen(); +bool k3MCaptureMouse(struct k3MScreen*, struct k3MObj*); +void k3MReleaseMouse(struct k3MScreen*); struct k3MTextButton { struct k3MObj;