Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsItemHovered(), IsWindowHovered() improvements #1382

Closed
ocornut opened this issue Oct 20, 2017 · 8 comments
Closed

IsItemHovered(), IsWindowHovered() improvements #1382

ocornut opened this issue Oct 20, 2017 · 8 comments

Comments

@ocornut
Copy link
Owner

ocornut commented Oct 20, 2017

(This is a news/info post. Will close in a few days)

I have pushed a bunch of changes related to the IsItemHovered() and IsWindowHovered() functions, in the form of new flags.

This is interesting to know:

  • If you are using mouse-triggered popups (~context menus) this is also interesting.
  • If you are using Drag'n Drop related idioms (Drag'n drop support #143) in your code this will likely interest you, and might affect you.
  • If you are using any other idioms related to hovering, most commonly when creating tooltip or displaying status based on hovered items.

Previously it was frequent to use IsItemRectHovered/IsItemHoveredRect (same function, was renamed on August 22) to do a basic rectangle-only test.

The existing normal functions now have flags to allow this and more, with better defined options:

bool IsItemHovered(ImGuiHoveredFlags flags = 0);
bool IsWindowHovered(ImGuiHoveredFlags flags = 0);

The flags are:

enum ImGuiHoveredFlags_
{
    ImGuiHoveredFlags_Default                       = 0,        // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them.
    ImGuiHoveredFlags_AllowWhenBlockedByPopup       = 1 << 0,   // Return true even if a popup window is normally blocking access to this item/window
    //ImGuiHoveredFlags_AllowWhenBlockedByModal     = 1 << 1,   // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
    ImGuiHoveredFlags_AllowWhenBlockedByActiveItem  = 1 << 2,   // Return true even if an active item is blocking access to this item/window
    ImGuiHoveredFlags_AllowWhenOverlapped           = 1 << 3,   // Return true even if the position is overlapped by another window
    ImGuiHoveredFlags_RectOnly                      = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped
};
  • This is particularly useful for contextual menu triggered from an item. The high-level BeginPopupContextItem() helper now uses the ImGuiHoveredFlags_AllowWhenBlockedByPopup flag meaning that you can right-click again on a different spot to reopen a context menu. (Popup menu right click behavior #439). Note that I also have committed another change that allows closing popups by right-clicking anywhere, making popups generally more usable.

  • Those new options will make it easier/clearer to have finer controls on drag and drop related behaviour.

  • If you use e.g. tooltip you can also have finer controls as to how when they should appear.

In the demo window you can visualize the output of those functions will different flags:

hovered
Above: normal hovering.

hovered_allow_when_overlapped
Above: Here the button is hidden by another window, but IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped)/RectOnly call returns true as expected:

hovered_allow_when_blocked_by_popup
Above: Here there is an open popup (the color picker) which prevents from clicking the button "ITEM" (so it doesn't appear as hovered). The IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) and IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) calls both returns true.

hovered_allow_when_blocked_by_active
Above: Here I have clicked on the DRAG ME button and click-dragged the mouse over the ITEM button. The IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) returns true.

Hope it is clear, and useful!
I haven't worked out in details how those features may relate to parent-child window relationship, and I imagine we could introduce new flags there.

BREAKING CHANGES

  • IsItemHoveredRect/IsItemRectHovered has been obsoleted, it is equivalent to calling: IsItemHovered(ImGuiHoveredFlags_RectOnly) aka all the flags enabled. I have kept an inline function doing that.

  • On August 22 I renamed IsItemHoveredRect to IsItemRectHovered for consistency with other functions. Instead of keeping 2 legacy names, I have now completely removed the name introduced on August 22, since few people will have renamed it their code, and if they did they are likely to find their way through the new changes. So only the oldest legacy name persist and it will be obsoleted in a few months/years.

  • Similarly, IsWindowRectHovered() has been obsoleted, the exact behavior that it had is equivalent to calling IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem).

  • Similarly, on August 22 I renamed IsMouseHoveringWindow to IsWindowRectHovered and I have removed the most recently introduced name. So the oldest legacy name IsMouseHoveringWindow will persist for a few more months/years.

  • IsWindowHovered() default behavior has been changed to return false if an item of another window is active. It makes the function more consistent and symmetrical with IsItemHovered() and I believe it is a better default and won't affect many people. You can call IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) to get the old behavior.
    This will probably affect you if you were doing drag and drop across windows and using IsWindowHovered.

@benajaero
Copy link

benajaero commented Oct 21, 2017

I now get these errors in the demo file:

src/imgui_demo.cpp:1776:40: error: use of undeclared identifier 'ImGuiHoveredFlags_AllowWhenBlockedByPopup'
                ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
                                       ^
src/imgui_demo.cpp:1777:40: error: use of undeclared identifier 'ImGuiHoveredFlags_AllowWhenBlockedByActiveItem'
                ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem));
                                       ^
src/imgui_demo.cpp:1788:38: error: use of undeclared identifier 'ImGuiHoveredFlags_AllowWhenBlockedByPopup'
                ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
                                     ^
src/imgui_demo.cpp:1789:38: error: use of undeclared identifier 'ImGuiHoveredFlags_AllowWhenBlockedByActiveItem'
                ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
                                     ^
src/imgui_demo.cpp:1790:38: error: use of undeclared identifier 'ImGuiHoveredFlags_AllowWhenOverlapped'
                ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
                                     ^
src/imgui_demo.cpp:1791:38: error: use of undeclared identifier 'ImGuiHoveredFlags_RectOnly'
                ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly));

Edit: I managed to fix this by updating the other files however IMGUI's windows don't scale in ratio to the size of my window. How do I fix this?

@benajaero
Copy link

I mean the widgets

@ocornut
Copy link
Owner Author

ocornut commented Oct 21, 2017 via email

@benajaero
Copy link

What happened was that I downloaded the demo file but forgot to update the other files.

ocornut added a commit that referenced this issue Oct 25, 2017
… isn't owned by imgui (will affect some future hovered test and drag'n drop patterns) (#143, #1382, #1392)
@ocornut
Copy link
Owner Author

ocornut commented Nov 2, 2017

Everyone who is using IsWindowHovered() : could you share your use cases of using the function? (code, pseudo-code, purpose, etc.)

The change described here introduced a bug that affects the console demo (see #1404, unable to open the right-click context menu while hovering the child window, because another widget is active). The fix for that one thing is easy but it led me to question exactly how IsWindowHovered() should behave when other items are active, and in particular in respect with where the active item is (within the window, outside, a child or a descendant?).

So seeing your usage patterns would be useful.
I already have those for references: https://github.com/nem0/LumixEngine/search?utf8=%E2%9C%93&q=IsWindowHovered&type=

ocornut added a commit that referenced this issue Nov 2, 2017
ocornut added a commit that referenced this issue Nov 2, 2017
…sRootWindowOrAnyChildHovered() obsolete in favor of IsWindowHovered( ImGuiHoveredFlags_FlattenChilds) (#1382, #1404)
ocornut added a commit that referenced this issue Dec 8, 2017
ocornut added a commit that referenced this issue Dec 12, 2017
… ChildWindows and RootWindow flags. Allowing more combination and a better symetry with IsWindowFocused() flags. (#1382)
ocornut added a commit that referenced this issue Dec 12, 2017
Marked IsRootWindowFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow).
Marked IsRootWindowOrAnyChildFocused() as obsolete in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows).
@ocornut
Copy link
Owner Author

ocornut commented Dec 12, 2017

I have made the same transition for IsWindowFocused, which now has flags and can handle more cases:

bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags = 0);

So essentially:
IsRootWindowFocused()
becomes:
IsWindowFocused(ImGuiFocusedFlags_RootWindow)

IsRootWindowOrAnyChildFocused()
becomes:
IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)

In addition it's now possible to do:
IsWindowFocused(ImGuiFocusedFlags_ChildWindows)
Which wasn't possible before.

// Flags for ImGui::IsWindowFocused()
enum ImGuiFocusedFlags_
{
    ImGuiFocusedFlags_ChildWindows          = 1 << 0,   // IsWindowFocused(): Return true if any children of the window is focused
    ImGuiFocusedFlags_RootWindow            = 1 << 1,   // IsWindowFocused(): Test from root window (top most parent of the current hierarchy)
    ImGuiFocusedFlags_RootAndChildWindows   = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows,
};

Demo code:
image

ocornut added a commit that referenced this issue Dec 13, 2017
@ocornut
Copy link
Owner Author

ocornut commented Jan 7, 2018

Closing this as solved.

@ocornut ocornut closed this as completed Jan 7, 2018
ocornut added a commit that referenced this issue Jan 11, 2018
…eted IsAnyWindowHovered()/IsAnyWindowFocused() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow)/IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Added to demo. (#1382)
ocornut added a commit that referenced this issue Jan 11, 2018
Vultraz added a commit to anura-engine/imgui that referenced this issue Mar 7, 2022
ImGuiHoveredFlags_Default isn't a valid identifier. It seems it perhaps was at some point, but the
flag that's in the api is ImGuiHoveredFlags_None. I see the former mentioned in ocornut#1382,
and its description is the same as what is now given to None.
@csp-admin
Copy link

csp-admin commented Mar 19, 2024

Since I didn't find a way to change a text color on hover with my hand-made icon font, I did it myself

bool IconButton(ImFont* font, const char* iconChar, ImVec4 iconColor, ImVec4 iconhoverColor, ImVec2 position, float size)
{
	ImGui::SetCursorPos(position);	
	ImVec2 mousePos = ImGui::GetMousePos() - ImGui::GetCurrentWindow()->Pos;


	ImGui::PushFont(font);
	if (mousePos.x >= position.x && mousePos.x <= position.x + size &&
		mousePos.y >= position.y && mousePos.y <= position.y + size)
	{
		ImGui::TextColored(iconhoverColor, iconChar);
		ImGui::PopFont();
		if (ImGui::IsMouseClicked(ImGuiMouseButton_Left) /*&& ImGui::IsWindowHovered()*/)
		return true;
	}
	else
	{
		ImGui::TextColored(iconColor, iconChar);
		ImGui::PopFont();
		return false;
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants