Reputation: 101
I have a basic test window in a renderer I'm working on in C using nuklear and SDL2:
void renderUI(){
static struct nk_colorf color = {1.0f, 0.0f, 0.0f, 1.0f};
if (nk_begin(ctx, "Debug Window", nk_rect(0, 0, 410, 500), NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_MINIMIZABLE)) {
// Define row layout with two columns: label + value
nk_layout_row_dynamic(ctx, 130, 2);
// Display "Camera Position: "
nk_label(ctx, "Camera Position:", NK_TEXT_LEFT);
get_camera_position(&p);
nk_labelf(ctx, NK_TEXT_LEFT, "(%.2f, %.2f, %.2f)", p[0], p[1], p[2]);
nk_layout_row_dynamic(ctx, 130, 2);
nk_label(ctx, "Light Colour:", NK_TEXT_LEFT);
color = nk_color_picker(ctx, color, NK_RGBA); // RGB mode (or NK_RGBA for alpha)
nk_layout_row_dynamic(ctx, 130, 2);
nk_label(ctx,"Frame Rate: ",NK_TEXT_ALIGN_LEFT);
nk_labelf(ctx, NK_TEXT_LEFT, "(%.2f)", fps);
lightColor[0] = color.r;
lightColor[1] = color.g;
lightColor[2] = color.b;
}
nk_end(ctx);
}
As you can see I have the NK_WINDOW_MINIMIZABLE flag set so there is a minimize button on the top right hand corner of the window, my problem is when I press the mouse button, it causes many SDL_Events to fire, this causes the window to jitter constantly as it is minimized and maximized every frame.
void process_input(void) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
nk_sdl_handle_event(&event);
switch (event.type) {
case SDL_QUIT:
is_running = false;
break;
case SDL_KEYDOWN:
keyStates[event.key.keysym.scancode] = true;
break;
case SDL_KEYUP:
keyStates[event.key.keysym.scancode] = false;
break;
case SDL_MOUSEBUTTONDOWN:
if(event.button.button == SDL_BUTTON_RIGHT)mouse_button_down = true;
break;
case SDL_MOUSEBUTTONUP:
if(event.button.button == SDL_BUTTON_RIGHT)mouse_button_down = false;
break;
case SDL_MOUSEMOTION:
if(mouse_button_down){
process_mouse_move((float)event.motion.xrel,(float)event.motion.yrel,1);
}
break;
case SDL_MOUSEWHEEL:
fov -= (float) event.wheel.y;
if (fov < 1.0f)
fov = 1.0f;
if (fov > 45.0f)
fov = 45.0f;
}
}
}
As I'm creating the minimize button from a flag being set, I have no real control over the button, and I'm not sure how to handle this case as SDL will pass events to nuklear every frame. Ideally I just want it to register on click not on mouse press.
Upvotes: 0
Views: 23
Reputation: 101
SDL_Event event;
nk_input_begin(ctx);
while (SDL_PollEvent(&event)) {
nk_sdl_handle_event(&event);
switch (event.type) {
case SDL_QUIT:
is_running = false;
break;
case SDL_KEYDOWN:
keyStates[event.key.keysym.scancode] = true;
break;
case SDL_KEYUP:
keyStates[event.key.keysym.scancode] = false;
break;
case SDL_MOUSEBUTTONDOWN:
if(event.button.button == SDL_BUTTON_RIGHT)mouse_button_down = true;
break;
case SDL_MOUSEBUTTONUP:
if(event.button.button == SDL_BUTTON_RIGHT)mouse_button_down = false;
break;
case SDL_MOUSEMOTION:
if(mouse_button_down){
process_mouse_move((float)event.motion.xrel,(float)event.motion.yrel,1);
}
break;
case SDL_MOUSEWHEEL:
fov -= (float) event.wheel.y;
if (fov < 1.0f)
fov = 1.0f;
if (fov > 45.0f)
fov = 45.0f;
}
}
nk_input_end(ctx);
Turns out my issue was the lack of nk_input_begin(ctx)
and nk_input_end(ctx)
As stated from nuklears docs:
input state needs to be provided to nuklear by first calling nk_input_begin which resets internal state like delta mouse position and button transitions. After nk_input_begin all current input state needs to be provided. This includes mouse motion, button and key pressed and released, text input and scrolling. Both event- or state-based input handling are supported by this API and should work without problems. Finally after all input state has been mirrored nk_input_end needs to be called to finish input process.
I wasn't resetting my internal state each frame causing unintended behaviour!
Upvotes: 0