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

Dynamically remove window padding after Begin() call #3756

Closed
Vine1 opened this issue Jan 24, 2021 · 3 comments
Closed

Dynamically remove window padding after Begin() call #3756

Vine1 opened this issue Jan 24, 2021 · 3 comments

Comments

@Vine1
Copy link

Vine1 commented Jan 24, 2021

Hello! I'm developing my custom menu bar. It should look like a rectangle at top of the window, without paddings at the top, left, and right sides. My style has window padding for child windows, but ImGui uses this option for the simple windows too. So, my menu bar draws indented My application architecture draws UI element by element, after Begin call, so I can't give access to an element to call PushStyleVar(ImGuiStyleVar_WindowPadding) before Begin(). Also, the menu bar may be dynamically removed and added back, so, I can't just statically push the window padding variable before Begin() call. Also, change the style.WindowPadding I can't too because I need padding for child windows, and maybe in the future, I will need window padding for simple windows without a custom menu bar.
So, Is it possible to remove the current window padding after Begin() (or maybe just draw one frame bypassing padding)?
What I have tried already:

  • Set DC.CursorPos to window->Pos
  • Set DC.CursorStartPos to window->Pos
  • Set DC.CursorPosPrevLine to window->Pos
  • Set DC.Indent to 0
  • Set window->ContentRegionRect to (0, 0)
  • Set window->InnerRect to (0, 0)
  • Set window->ClipRect to (0, 0)
  • Set window->InnerClipRect to (0, 0)
  • Set window->WorkRect to (0, 0)
  • Set window->WindowPadding to (0, 0)

Nothing worked. If it's not possible, I'll find a way to call PushStyleVar before Begin(), but it'll hurt the architecture.
I hope for your help! Thanks in advance!

EDIT:
Example:

       ImGui::Begin("Window");
       
       const ImVec2 pos = ImGui::GetWindowPos();
       const ImVec2 size = ImGui::GetWindowSize();
       const ImU32 col = ImGui::GetColorU32(ImVec4(0, 1, 0, 1));

       ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + 200), col);
       
       ImGui::End();

Screenshot with padding 20:
image
And with padding 0:
image

Why even drawing through ImDrawList depends on padding? How to bypass it?

@ocornut
Copy link
Owner

ocornut commented Jan 25, 2021

Why even drawing through ImDrawList depends on padding? How to bypass it?

You can't change the WindowPadding of a window after Begin(), otherwise it seems what's blocking you is the active clipping rectangle. Try using ImGui::PushClipRect(). You shouldn't write to random fields in the window-> structure.

That single line is due to WindowBorderSize=1. If you push both WindowPadding to 0,0 and WindowBorderSize to 0 before Begin(), there will be zero-padding and the clipping rectangle will be equal to windows boundaries. But you can manipulate the clipping rectangle with PushClipRect/PopClipRect anytime, regardless of WindowPadding value.

Use Demo>Tools>Metrics/Debugger to visualize the clipping rectangle of each ImDrawCmd.

@ocornut ocornut closed this as completed Jan 25, 2021
@ocornut
Copy link
Owner

ocornut commented Jun 17, 2021

Linking to #3312

@CordeliaMist
Copy link

CordeliaMist commented Mar 13, 2025

@Vine1 Not sure if you ever figured this out, I came across it while trying to figure it out myself, as I was actually trying to do the same thing you were with a custom header without wanting to push the window padding to 0,0.

I was trying to work with what ocornut mentioned, that being:
ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
for quite a while, but nothing seemed to work. The issue was that I was setting intersect_with_current_clip_rect to true in every test.

Turns out, that was the problem. When set to true, it limits rendering to the area inside the padding since it's intersecting with the current InnerClipRect. If false, you can draw the pushed ClipRect onto the WindowPadding area (or anywhere on the screen, for that matter). —which makes sense in hindsight, but it’s easy to overlook when you’re deep in testing.

Hopefully, this helps anyone else who runs into the same issue down the line!
(See below, the window here has window padding <4,4>, and the pink is drawing into the padded region.) 👍
Image

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