ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
61.14k stars 10.3k forks source link

Show window only when mouse is over? #1647

Closed sonoro1234 closed 6 years ago

sonoro1234 commented 6 years ago

Hi,

How could I show a window (used as transport control) only when mouse is over it?

Thanks, victor bombi

ocornut commented 6 years ago

I don't understand the question. Please clarify and explain the context.

sonoro1234 commented 6 years ago

Having a transparent window that gets drawed only when mouse is over it I have tried

ig.PushStyleVar(imgui.ImGuiStyleVar_Alpha,0)
if ig.Begin("Transport",nil,imgui.ImGuiWindowFlags_NoTitleBar + imgui.ImGuiWindowFlags_NoResize) then
        if ig.IsWindowHovered(imgui.ImGuiHoveredFlags_RectOnly) then
            ig.PushStyleVar(imgui.ImGuiStyleVar_Alpha,1)
        end

But window mouse over is not detected with alpha==0

sonoro1234 commented 6 years ago

alpha == 0.0001 works!! and it is almost invisible. Still I would like the window to be visible and not only the items inside when style alpha changes.

ocornut commented 6 years ago

As you just found out, Alpha==0.0 clips elements at a higher-level. So Alpha = 0.0001 will work for what you aim to do.

Still I would like the window to be visible and not only the items inside when style alpha changes.

Sorry I don't understand this sentence either.

sonoro1234 commented 6 years ago

In the solution I tryed when alpha changes to 1 ( on mouse over ) it is applied only to the items that follow, but the window background remains transparent.

Beasides, when opening a popup window from transport window, IsWindowHovered returns false and window dissappears. I even disappears when doing mouse click on any item of this window.

ocornut commented 6 years ago

the window background remains transparent.

The window background is drawn by Begin(). Here you are querying IsWindowHovered() after Begin. You'll probably need to track state in your application to remember which window is hovered and apply that Alpha before Begin.

(This is because there's no way to use IsWindowHovered() on a different window than the current at the moment)

I have no idea what "transport window" mean. Please provide code and screenshots (as explained here). It's hard to understand your use case right now, and I can't be spending time to guess what you want in order to help you.

Popups inhibit inputs behind them. Check the flags for IsWindowHovered().

sonoro1234 commented 6 years ago

transporte when doing click on any item of this window IsWindowHovered returns false and window dissappears.

function transport:draw()

        local height = ig.GetItemsLineHeightWithSpacing() + ig.GetStyle().WindowPadding.y*2
        ig.SetNextWindowPos(ig.ImVec2(0, ig.GetIO().DisplaySize.y - height),0);
        ig.SetNextWindowSize(ig.ImVec2(ig.GetIO().DisplaySize.x,height),0);

        local numpops = 1
        ig.PushStyleVar(imgui.ImGuiStyleVar_Alpha,0.0001)

        if ig.Begin("Transport",nil,imgui.ImGuiWindowFlags_NoTitleBar + imgui.ImGuiWindowFlags_NoResize) then
            if ig.IsWindowHovered(imgui.ImGuiHoveredFlags_RectOnly) then
                ig.PushStyleVar(imgui.ImGuiStyleVar_Alpha,1)
                numpops=2
            end

            if ig.Button(play_but_text) then 
                transport.play()
            end

            ig.SameLine()
            ig.Text("(%05.1f FPS)", ig.GetIO().Framerate)

            ig.SameLine()
            if ig.Button("next") then 
                GL.timeprovider:set_time(GL.globaltime[0] + 1/GL.fps)
            end
            ig.SameLine()
            if ig.Button("prev") then 
                GL.timeprovider:set_time(GL.globaltime[0] - 1/GL.fps)
            end
            ig.SameLine()

            if ig.Button("save") then  save_image_browser.open() end
            save_image_browser.draw()
            ig.SameLine()

            if ig.Button("tools") then imgui.igOpenPopup("toolbox") end
            ToolBox(GL):draw()
            ig.SameLine()

            ig.PushItemWidth(-1)
            if ig.SliderFloat("", GL.globaltime, 0, GL.timeprovider.totdur, "%.3f", 1.0) then
                GL.timeprovider:set_time(GL.globaltime[0])
            end
            ig.PopItemWidth()
        end

        ig.End()
        ig.PopStyleVar(numpops)
    end

Thanks for your patience victor

ocornut commented 6 years ago

According to this section of the Demo window, it should work with RectOnly: image

(you can try the demo)

RectOnly is a shortcut: ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,

Make sure your value for ImGuiHoveredFlags_RectOnly is the correct value that C++ imgui expects. Those define values change from time to time, if you have a language wrapper it should be using values from imgui.h.

(This is == 104 in current imgui.. maybe your back-end copied from values instead of reading them from imgui.h?)

sonoro1234 commented 6 years ago

I am using cimgui.h for imgui 1.53 and the value is 52. (4 + 16 + 32)

ocornut commented 6 years ago

It is == 52 with in imgui 1.53 you are right. Does that area of the Demo works correctly with your version? Click "Item" and check the value next to "AllowWhenBlockedByActiveItem".

PS: ( Actually, the ImGuiHoveredFlags_AllowWhenOverlapped flag is not supported by IsWindowHovered() and therefore ImGuiHoveredFlags_RectOnly isn't either:

bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
{
    IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0);   // Flags not supported by this function
    ImGuiContext& g = *GImGui;

This shouldn't concern you here, but you should maybe only use ImGuiHoveredFlags_AllowWhenBlockedByActiveItem, depending on how you want this to work. )

sonoro1234 commented 6 years ago

Demo works ok. I found error in cimgui implementation!! Thanks

ocornut commented 6 years ago

Nice. Please report issue or a PR to the cimgui repo ideally :)