With 1.62 I would like to draw some buttons with SameLine between them until the window width is reached in order to begin a new line.
I can get window width with GetWindowWidth. How do I get where is current button position in order to do SameLine or not?
GetCursorPos()
for i,v in ipairs(self.imguimodals) do
if (ig.Button(v.name)) then curr_notmodal = i end
pos = ig.GetCursorPos()
ig.SameLine(0,1)
print(pos.x)
end
always outputs the same value
I see, sorry. You may need to use GetItemRectMin/GetItemRectMax + add style.ItemSpacing.x to compute the expected position.
(This pattern should be supported automatically but with the current signature of ItemAdd/ItemSize it isn鈥檛 possible for them to modify the current position. So it鈥檒l require breaking the most common internal.h api to support it. Will do it at some point)
local wwidth = ig.GetWindowWidth()
local pos = ig.GetCursorPos()
local posini = pos
for i,v in ipairs(self.imguimodals) do
if (ig.Button(v.name)) then curr_notmodal = i end
pos = pos + ig.GetItemRectSize()
if pos.x < wwidth then
ig.SameLine(0,1)
else
pos = posini
end
end
this is the pattern working for me
Althought last button in line is partially out!!!
This kind of task needs sample/documentation
this is the pattern working for me
Althought last button in line is partially out!!!
Well the code is wrong for two reasons:
style.ItemSpacing.xGetContentRegionAvailWidth() instead of GetWindowWidth() since your starting X position is WindowPadding.x and the end X position is Width-WindowPadding.x as well.May be that GetItemRectSize() with GetContentRegionAvailWidth() already takes in account for style.ItemSpacing?
The cause of "last button partially out" is that we are getting pos after the Button is already posted so that the first button which has pos > wwidth is posted after SameLine. Solution would be to know pos before Button.
Solution would be to know pos before Button.
GetCursorPos() ?
edit If you are in doubt about any value you should visualize it with the ImDrawList api.
I'm not sure I understand your message, but I have added an extra demo.
// Manually wrapping (we should eventually provide this as an automatic layout feature, but for now you can do it manually)
ImVec2 button_sz(40, 40);
ImGui::Text("Manually wrapping:");
ImGuiStyle& style = ImGui::GetStyle();
int buttons_count = 20;
float window_visible_x2 = ImGui::GetWindowPos().x + ImGui::GetWindowContentRegionMax().x;
for (int n = 0; n < buttons_count; n++)
{
ImGui::PushID(n);
ImGui::Button("Box", button_sz);
float last_button_x2 = ImGui::GetItemRectMax().x;
float next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_sz.x; // Expected position if next button was on same line
if (n + 1 < buttons_count && next_button_x2 < window_visible_x2)
ImGui::SameLine();
ImGui::PopID();
}

This is made a little confusing because GetWindowContentRegionMax() is in local window space.. someday will need to refactor all this and use absolute positions everywhere :/
The problem in my use case is that button size is not known before it is posted as it depends on its label
Then you can calculate its size in advance with CalcTextSize(label) + style.FramePadding * 2.
Could you please ensemble all the code for that?
local window_visible_x2 = ig.GetWindowPos().x + ig.GetWindowContentRegionMax().x
local last_button_x2 = 0
for i,v in ipairs(self.imguimodals) do
local button_szx = ig.CalcTextSize(v.name).x + 2*style.FramePadding.x
local next_button_x2 = last_button_x2 + style.ItemSpacing.x + button_szx;
if next_button_x2 < window_visible_x2 then ig.SameLine(0,1) end
if (ig.Button(v.name)) then curr_notmodal = i end
last_button_x2 = ig.GetItemRectMax().x;
end
this is working
Most helpful comment
this is working