-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Differentiating between events Nuklear want to consume, and events to sent to app #189
Comments
Hey and thanks for your issue. |
The change you pushed doesn't really address my problem. You're returning 1 if the type of event is something Nuklear might consume. However, even for any given type(say SDL_MOUSEBUTTONDOWN), Nuklear might not consume that event because the mouse click happened outside a Nuklear widget. (EDIT: Assuming you're taking about this commit: c4315ea) |
Actually, it turns out just checking |
Ah ok you meant that. Instead of |
Thank you, this was very helpful. But is there a way to exclude "simply hovered" from being counted as "active"? I have some hot keys (events) which I handle in my underlying event routine to toggle things in the Nuklear GUI. These are things like hiding the GUI, bringing up certain windows, or turning on different widgets. The problem is that the any mouse hover will block these. This means if the user just left the mouse cursor idle over any GUI widgets, the hot keys won't work. (E.g. Move the touchpad to click a button. When you are done, the cursor is just parked there because there was no reason to move it elsewhere.) I think I need something like nk_item_is_any_interacting, or a mask flag parameter for nk_item_is_any_active that can filter out mouse hover. (I don't usually think of mouse hover events doing any primary action that can't be ignored. Touch screens and mobile really necessitated that mouse hover not do anything primary that cannot be lived without.) Thanks P.S. NK_API int
nk_item_is_any_interacting(struct nk_context *ctx)
{
// int any_hovered = nk_window_is_any_hovered(ctx);
int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED);
// return any_hovered || any_active;
return any_active;
} But this didn't do the right thing. The combo box going outside the window problem in #212 came back, and edit_string fields no longer blocked other input. |
Here is another attempt. Seems to work better. What do you think? NK_API int
nk_item_is_any_interacting(struct nk_context *ctx)
{
struct nk_window *iter;
NK_ASSERT(ctx);
if (!ctx) return 0;
iter = ctx->begin;
while (iter) {
/* check if window is being hovered */
if (iter->flags & NK_WINDOW_MINIMIZED) {
struct nk_rect header = iter->bounds;
header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
if (nk_input_mouse_clicked(&ctx->input, NK_BUTTON_LEFT, header)
|| nk_input_mouse_clicked(&ctx->input, NK_BUTTON_MIDDLE, header)
|| nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, header)
)
{
return 1;
}
} else if ( (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVE)
|| nk_input_mouse_clicked(&ctx->input, NK_BUTTON_LEFT, iter->bounds)
|| nk_input_mouse_clicked(&ctx->input, NK_BUTTON_MIDDLE, iter->bounds)
|| nk_input_mouse_clicked(&ctx->input, NK_BUTTON_RIGHT, iter->bounds)
)
{
return 1;
}
/* check if window popup is being hovered */
// (Willing to accept hover blocking for popups for now)
if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
return 1;
/* check if window edit is being edited */
if (iter->edit.active & NK_EDIT_ACTIVE)
return 1;
iter = iter->next;
}
return 0;
} |
I made a mistake and discovered that while handling combo boxes, popups, and edit fields, it no longer worked with simple clicks on a window. However, I think I found a bug in Nuklear itself. The call in the following function to nk_input_has_mouse_click_down_in_rect passed nk_false as the 4th parameter, which always results in my click detection failing when using nk_input_any_mouse_click_in_rect(). I think it should be nk_true like so: NK_API int
nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id,
struct nk_rect b)
{
const struct nk_mouse_button *btn;
if (!i) return nk_false;
btn = &i->mouse.buttons[id];
return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_true) &&
btn->clicked) ? nk_true : nk_false;
} This seems to work and my function seems to be working (at least in the cases I've tested so far). Here is the newer, slightly simplified code. NK_API int
nk_item_is_any_interacting(struct nk_context *ctx)
{
struct nk_window *iter;
NK_ASSERT(ctx);
if (!ctx) return 0;
iter = ctx->begin;
while (iter) {
/* check if window is being hovered */
if (iter->flags & NK_WINDOW_MINIMIZED) {
struct nk_rect header = iter->bounds;
header.h = ctx->style.font->height + 2 * ctx->style.window.header.padding.y;
if (nk_input_any_mouse_click_in_rect(&ctx->input, header)) {
return 1;
}
}
else if ( (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVE)
|| nk_input_any_mouse_click_in_rect(&ctx->input, iter->bounds)
)
{
return 1;
}
/* check if window popup is being hovered */
// (Willing to accept hover blocking for popups for now)
if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds))
return 1;
/* check if window edit is being edited */
if (iter->edit.active & NK_EDIT_ACTIVE)
return 1;
iter = iter->next;
}
return 0;
} |
I found this trying to figure out how I figure out if Nuklear uses an input event. Is this or a smiliar feature now included in the current build? |
i don't think |
Using ewmailing's code as a starting point I came up with this soulution, using SDL2:
With these functions the input queue handling looks like this:
This solves the problem where the mouse click happens inside a nuklear window but leaves it after (dragging a scrollbar or resizing a window) while the mouse button is still pressed. |
Generally Nuklear itself (i.e. the backend-agnostic single-header library) doesn't handle this use case - it should be probably handled by backends e.g. like in your solution. Feel free to make a pull request and I'll be happy to review & merge it (but it might take some weeks/months - see #913 (comment) ). |
Currently my code to handle events looks like this:
The problem is that the events go to both Nuklear and to my app. What I want to do is first pass it to Nuklear, then check if it is something Nuklear uses, then if it is not, pass it to my own
handle_event
function. How do I do that?In "dear imgui" it seems it sets the
wantCaptureFlags
. Is there anything equivalent in Nuklear?The text was updated successfully, but these errors were encountered: