raygui icon indicating copy to clipboard operation
raygui copied to clipboard

`GuiButton()` not considering mouse state as exclusive mode

Open itsYakub opened this issue 1 year ago • 2 comments

The basic behaviour of the GuiButton works as follow:

  • Firstly we check if the element is interactable (enabled, player isn't currently using sliders);
  • Then we get the current mouse position and check if it's on the button's body;
  • Lastly we wait until the key is released on the button's body.

There is a problem with the last point though. It seems that the button only check if the mouse key is released on the button's body. What happen is that if we press the mouse button before we position it on the widget, then we move to the button, and at the end we release the mouse input, the button gets selected.

https://github.com/raysan5/raygui/assets/80039680/7ebcce52-0c45-4835-af9b-c92a3e36bc36

Worth mentioning is that the behaviour that prevents the inputing while the slider is held: if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging) ...work fine.

https://github.com/raysan5/raygui/assets/80039680/6050116f-5ea5-48ad-90ba-8e90834e598d

Code from the example:

// gcc -g main.c -Lraylib/src -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 -Iraylib/src -Iraygui/src

#include "raylib.h"

#define RAYGUI_IMPLEMENTATION
#include "raygui.h"

int main(int, char**) {
    InitWindow(600, 400, TextFormat("Raylib %s - Raygui %s - Raylib & Raygui Issue", RAYLIB_VERSION, RAYGUI_VERSION));

    SetTargetFPS(60);

    Rectangle label_rect = { 0, 0, 296, 48 };
    Rectangle button_rect = { 144, 176, 312, 56 };
    Rectangle slider_rect = { 144, 288, 312, 56 };

    float f = 0.0f;

    while(!WindowShouldClose()) {
        BeginDrawing();

        ClearBackground(RAYWHITE);

        GuiSetStyle(DEFAULT, TEXT_SIZE, 20);

        if(GuiButton(button_rect, "Click me!")) {
            TraceLog(LOG_INFO, "Button pressed!");
        }

        GuiSlider(slider_rect, NULL, NULL, &f, 0.0f, 1.0f);

        GuiLabel(label_rect, IsMouseButtonDown(MOUSE_BUTTON_LEFT) ? "Input state: PRESSED" : "Input state: RELEASED");

        GuiSetStyle(DEFAULT, TEXT_SIZE, DEFAULT);

        EndDrawing();
    }

    CloseWindow();
    
    return(0);
}

It can be quite problematic, for example: in my game I use state machine for the current state of the game. When we move further in it (or pause) the state is switched, and if the mouse was pressed at that moment and it was positioned when the button will be rendered, when we release the mouse the button gets selected by accident, causing some problems (resuming the game, quitting etc.)

The problem occurs in the latest raylib's and raygui's branch versions. Tested on the Linux platform. If needed, I can provide more info about the situation on Windows.

itsYakub avatar Feb 08 '24 19:02 itsYakub

Two new globals have been added to raygui that could be used to address this kind of issues:

static bool guiControlExclusiveMode = false;    // Gui control exclusive mode (no inputs processed except current control)
static Rectangle guiControlExclusiveRec = { 0 }; // Gui control exclusive bounds rectangle, used as an unique identifier

This issue is probably also related to https://github.com/raysan5/raygui/issues/339

raysan5 avatar Feb 15 '24 15:02 raysan5

Yes, indeed they're related Didn't notice it at first I'll test it soon!

itsYakub avatar Feb 15 '24 18:02 itsYakub