Daandelange / ofxImGui

Please refer to the develop branch in https://github.com/jvcleave/ofxImGui. I'll keep this fork in sync until it's merged in master.
12 stars 1 forks source link

IsMouseOverGui() #17

Open moebiussurfing opened 1 year ago

moebiussurfing commented 1 year ago

Hey @Daandelange , Hope all fine on there.

... I continue here what we were talking about on Discord...

I am having some annoying behavior when trying to "bypass" OF mouse interacting when we are over/using the UI.

One fast way to debug/check it could be to modify the example-helpers, by drawing the bg white when the bMouseOverGui:

void ofApp::draw()
{
    // We have to use ofParameter::get() since this we are using an ofFloatColor.
    if (!mouseOverGui) ofClear(this->background.get());
    else ofClear(255);//bg white if overGui

Then you can see that the bMouseOver goes false when interacting/clicking widgets.

So you will see that when mouse is over the window, bg goes white (mouseOver = true), but when clicking a widget bg goes to black (mouseOver = false). (I say black but in reality it's the parameter ofColor Background)

That's not what we are expecting, as when clicking widgets we are overGui too...

--

BTW, that's how is checked internally:

bool ofxImGui::IsMouseOverGui()
{
    return ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
}

I was using other flags, not sure if something changed on ImGui or if it's the new OF backend. Maybe we need to check another new flag...

bMouseOverGui = false;
bMouseOverGui |= ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
bMouseOverGui |= ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
bMouseOverGui |= ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);

Regards

moebiussurfing commented 1 year ago

I think that I found a workaround that works:

//--------------------------------------------------------------
bool ofApp::isMouseOverGui() const {
    bool b = false;

    b |= ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow);
    b |= ImGui::IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
    b |= ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem);

    b |= ImGui::IsAnyItemHovered(); // -> Fix widgets interact

    return b;
}
moebiussurfing commented 1 year ago

That works too:

bool ofApp::isMouseOverGui() const {
  bool b = ImGui::GetIO().WantCaptureMouse;
  return b;
}
moebiussurfing commented 1 year ago

... just a small trouble: double click is passed to an ofEasyCam even when overGui=true

Maybe that's more related to what you said about the topic:

- ofAddListener(window.onMouseDown(), xxx, yyy); (then you do if(mouseOverGui)...).
- ofAddListener(gui.onMouseDownPassTrough(), xxx, yyy); (then you don't need to if(mouseOverGui) )
both the guiEventState (onMouseHoverPasstrough) and isEventStateGui (isMouseOverGui...) are linked anyways. 
I think registering to ofximgui events is easier then binding to OF events+calling isOverGui, 
but exposing both is a good option too. 
And then there's the same combination (event+eventMissedState for mouseDown, keydown, up, etc.
Plus I need to find a good "imgui_event_flags" combination for each of them. 
moebiussurfing commented 1 year ago

I think that you can directly replace with that:

bool ofxImGui::IsMouseOverGui()
{
    return ImGui::GetIO().WantCaptureMouse;
}
Daandelange commented 1 year ago

Thanks for your investigations and opening the issue :) .

I think there could also be a IsMouseInteracting() or bool ofxImGui::IsMouseOverGui(bool onlyInteractions=false). (and maybe some other utilities ?)

Ideally I'd like to combine these "state getters" with "custom event notifiers" that one can listen to, as the code you pasted above.