Menu mouse capturing

This commit is contained in:
Mid 2025-08-28 19:14:02 +03:00
parent 6d5ba6037c
commit bf60cac302
2 changed files with 66 additions and 35 deletions

View File

@ -296,31 +296,36 @@ static bool screen_ev(struct k3MEvent *ev, uint8_t *ud) {
struct k3MScreen *this = (void*) ev->target; 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) { 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) { if(this->mouseCapture) {
innermost = this->mouseCapture;
} else {
innermost = (struct k3MObj*) this;
while(innermost->childCount != 0) {
bool foundInner = false; bool foundInner = false;
for(intmax_t i = innermost->childCount - 1; i >= 0; i--) { for(intmax_t i = innermost->childCount - 1; i >= 0; i--) {
struct k3MObj *child = innermost->children[i]; struct k3MObj *child = innermost->children[i];
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) { 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; innermost = child;
foundInner = true; foundInner = true;
break; break;
}
} }
} if(!foundInner) {
break;
}
if(!foundInner) {
break;
} }
} }
if(innermost != this->lastHover) { if(innermost != this->lastHover) {
@ -455,6 +460,18 @@ struct k3MScreen *k3MScreen() {
return ret; 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) { static bool textbutton_draw(struct k3MEvent *ev, uint8_t *ud) {
struct k3MTextButton *this = (void*) ev->target; 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; struct k3MScrollbox *this = (void*) ev->target;
if(ev->code == k3M_EVENT_MOUSE_PRESS) { if(ev->code == k3M_EVENT_MOUSE_PRESS) {
struct k3MProperty *prop = k3MFindProperty(ev->target, k3M_PROP_SCROLL_ANYWHERE, false); if(k3MCaptureMouse((struct k3MScreen*) ev->original, this)) {
bool scrollAnywhere = prop ? prop->si[0] : false;
int scrollbarWidth = SCROLLBAR_WIDTH_DEFAULT; struct k3MProperty *prop = k3MFindProperty(ev->target, k3M_PROP_SCROLL_ANYWHERE, false);
prop = k3MFindProperty(ev->target, k3M_PROP_SCROLLBAR_SIZE, false); bool scrollAnywhere = prop ? prop->si[0] : false;
if(prop) {
scrollbarWidth = prop->si[0]; 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) { } 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) { } else if(ev->code == k3M_EVENT_MOUSE_MOTION) {
if(this->mouseHeld) { if(this->mouseHeld) {
@ -694,6 +721,8 @@ static bool scrollbox_mouseshit(struct k3MEvent *ev, uint8_t *ud) {
k3MArrange(contentBox); k3MArrange(contentBox);
return true;
} }
} }

View File

@ -179,6 +179,8 @@ struct k3MScreen {
struct k3MObj *mouseCapture; struct k3MObj *mouseCapture;
}; };
struct k3MScreen *k3MScreen(); struct k3MScreen *k3MScreen();
bool k3MCaptureMouse(struct k3MScreen*, struct k3MObj*);
void k3MReleaseMouse(struct k3MScreen*);
struct k3MTextButton { struct k3MTextButton {
struct k3MObj; struct k3MObj;