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.
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
?
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.
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.
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.
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.
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
Interesting approach...
@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;
}
I just used the splitter code #319 by ocornut and modified it to my needs..
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.
@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
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
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
Wow, thanks!
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
?
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.
@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.
@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.
@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.
Most helpful comment
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 callIsItemHovered()right afterBegin()and it'll check the title bar for you.I believe this issue can finally be closed today, phew! :)
-Omar