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

How do I detect mouse held over title bar? #823

Closed
heretique opened this issue Sep 9, 2016 · 19 comments
Closed

How do I detect mouse held over title bar? #823

heretique opened this issue Sep 9, 2016 · 19 comments

Comments

@heretique
Copy link

Hi,
I was wondering if there is a way of dragging a borderless native window by grabbing from imgui window title bar. I want this because I want to keep a uniform style for all platforms and don't want to rely on platform's own window style. Basically I want the same functionality as Unity3D editor windows. Looking at the code I couldn't find a solution using the public API of imgui.

@ocornut
Copy link
Owner

ocornut commented Sep 9, 2016

Hi; that subject line and description are not the same thing you requested on twitter.
ImGui doesn't care about native window. If I understand correctly you wanted to be able to tell if
a) an imgui window is being dragged (from title bar or any empty spot in the window)
b) an imgui window is being dragged from the title bar
?

@heretique
Copy link
Author

Sorry I think the title is not properly picked, especially mentioning native window in there (I know imgui is native window agnostic). I'll try to be more specific. I think I need b) , how can i detect if i grabbed a window by it's title bar. If I can get that information I will do the rest myself, meaning when the mouse moves, I will move the native window myself accordingly. My imgui window is actually created with ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse flags to fill the whole native window and resizes along with it.
I need this for an editor docking system similar with ImWindow that has multiple native window support. It uses a single native window when all imgui windows are docked and an additional native window for each undocked imgui window so that I can use multiple monitors.
I hope this makes everything more clear.

@ocornut ocornut changed the title Dragging a borderless native window by grabbing from imgui window title bar How do I detect mouse held over title bar? Sep 9, 2016
@Nukem9
Copy link

Nukem9 commented Sep 11, 2016

https://gist.github.com/Nukem9/7f85beec2b22eed03b4de6684d4a6512

This is a partial example ripped from my own code - I moved everything to main() from the DirectX 11 sample project. It draws as if it was native and can be moved by holding the "Another Window" bar:
http://i.imgur.com/W2obGJE.png

This line shows why ImGui::GetWindowTitlebarSize().y would be needed.

@heretique
Copy link
Author

Thanks Nukem9, I've tried your approach and works really good. I agree that a method like ImGui::GetWindowTitlebarSize() would be needed in order to get rid of the hard-coded value.

@Flix01
Copy link

Flix01 commented Sep 13, 2016

About ImGui::GetWindowTitleBarSize():

In <imgui_internal.h>:

// Windows data
struct IMGUI_API ImGuiWindow
{
// [...]
float       TitleBarHeight() const                  { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; }
ImRect      TitleBarRect() const                    { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
// [...]
 };

So basically, everyone can create a method that exposes it, although I agree that the height of the titlebars (and of the main menus) could be exposed by <imgui.h> too.

[Edit:] I have to test it, but I guess that (currently) the title bar height is equal to:

const float titleBarHeight = ImGui::GetTextLineHeight() + ImGui::GetStyle().FramePadding.y * 2.0f;

This way we can avoid including imgui_internal.h.

@edin-purkovic
Copy link

you can simply use button as tittle bar and window without tittle for content as i did here.. It was quite easy to implement.. https://cloud.githubusercontent.com/assets/12642134/18140511/288541a8-6fb6-11e6-8423-72b4c808016d.gif

@heretique
Copy link
Author

Interesting approach...

@xsjqqq123
Copy link

xsjqqq123 commented Oct 30, 2016

@edin-p Hello, I want to realize the splitter as yours, the following simple code seems slow and some freeze the ui, What can I do?

ImGui::InvisibleButton("##splitter1", ImVec2(10, ImGui::GetContentRegionAvail().y));
if (ImGui::IsItemHovered())
{
    ImGui::SetMouseCursor(4);
    ImGui::GetIO().MouseDrawCursor = true;
}
else
{
    ImGui::GetIO().MouseDrawCursor = false;

}

@edin-purkovic
Copy link

I just used the splitter code #319 by ocornut and modified it to my needs..

@ocornut
Copy link
Owner

ocornut commented Oct 30, 2016

ImGui::SetMouseCursor(4);

@xsjqqq123 : Don't use constants when there's a define available (e.g. ImGuiMouseCursor_ResizeEW) if you don't want your sources to break on upcoming updates.

@xsjqqq123
Copy link

@edin-p your spliter with "ImGuiMouseCursor_ResizeEW" work smooth, but my spliter seems cost a lot CPU time when this mouse style show.Is there any tips?
ocornut,thank you for your advice ,I will rewrite it future

@edin-purkovic
Copy link

Well don't update it every frame, call SetCursor only when the button is active or check for changes by checking if ImGui::GetMouseCursor() changed.. That's out of the scope of imgui.. More general and easy to solve c++ problem

@ocornut
Copy link
Owner

ocornut commented Nov 15, 2017

Hello @heretique,

Better late than ever, I needed this feature as part of another feature I am working on.
I have now made a change to guarantee that after calling Begin(), the last Item data will represent the title bar. So you can call IsItemHovered() right after Begin() and it'll check the title bar for you.

I believe this issue can finally be closed today, phew! :)

-Omar

@ocornut ocornut closed this as completed Nov 15, 2017
@heretique
Copy link
Author

Wow, thanks!

ocornut added a commit that referenced this issue Nov 18, 2017
…t are clipped due to window collapsing logic. Fix 27fd1b9. (#823)
@rhard
Copy link

rhard commented Nov 12, 2018

Hi @ocornut , I need the same functionality as you mentioned in point a) from your reply. What would be the easiest way to determine if current mouse coordinates will drag the window?

ImGui doesn't care about native window. If I understand correctly you wanted to be able to tell if
a) an imgui window is being dragged (from title bar or any empty spot in the window)
b) an imgui window is being dragged from the title bar
?

@ocornut
Copy link
Owner

ocornut commented Nov 13, 2018

Hi @ocornut , I need the same functionality as you mentioned in point a) from your reply. What would be the easiest way to determine if current mouse coordinates will drag the window?

Why do you need it for? Clarifying the use case and context often help providing a better answer.

@rhard
Copy link

rhard commented Nov 13, 2018

@ocornut
Sorry, I was thinking it is clear from the original discussion. So I will put it again:

I have many native windows each of them has own ImGui context. Every window has one ImGui window with NoMove/NoResize flags to follow native window coordinates. Now I want a possibility to move the windows not only by dragging native window header, but also by pressing on any empty space inside the window. Like ImGui originally does. For that I need to know if my mouse position are interacting with some of widgets inside, or not. If there is no interaction, I will transfer dragging event to the native window and move it.

For now I use IsAnyItemHovered function and it works, but I'm not sure if it is right approach here. I was looking for something like IsWindowCouldBeDragged.

@ocornut
Copy link
Owner

ocornut commented Nov 13, 2018

@rhard See the implementation for StartMouseMovingWindow() and UpdateMouseMovingWindow().
You should be able to test for g.ActiveID == window->MoveId, that will be set even if the window has the NoMove flag. Note however than it will use the MoveId of the inner-most child window.

It seems like what you are doing is replicating what the Viewport branch is doing in a more generic manner and with a single shared imgui context. Any reason not using the Viewport? Perhaps consider using that instead.

@rhard
Copy link

rhard commented Nov 13, 2018

@ocornut Thank you! I will try your suggestion.
I know about the viewport branch and about the progress you did there in the last time. I just was not sure if the feature is ready to use. I think I will try it soon.

ocornut added a commit that referenced this issue Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants