Open emilk opened 9 years ago
Yes!
The reason I haven't added the simple version yet (like your suggested API) is that I wanted to spend more time considering the layout problem holistically.
We'd probably want
Notes
Thanks for the suggestion!
But you are right, a simple helper would be welcome asap.
Could also skip on the Layout word. ?
Horizontal() / BeginHorizontal() / EndHorizontal() Vertical() / BeginVertical() / EndVertical()
And add ImGui::NextLine() as well.
Yeah, for now I've created my own NextLine based on Separator - that kind of works =)
I feel push/pop is more descriptive iff nesting is supported. I'm all for skipping the "Layout" part, i.e. PushHorizontal/PopHorizontal.
PushHorizontal(); Text("a"); Text("b"); PushVertical(); Text("c"); Text("d"); PopVertical(); PopHorizontal();
->
a b c
d
Something like that?
But:
Text("a"); SameLine(); Text("b"); Text("c"); Text("d");
Currently becomes:
a b
c
d
So starting a vertical layout should "lock" the X current coordinate? Which is what happens with your example. In which case how to do achieve the layout above with the Push/Pop system?
PushHorizontal(); Text("a"); Text("b"); PopHorizontal();
NextLine(); // Could be implicit ?
Text("c");
Text("d");
If locking is done on "pushing" the vertical layout and not "popping" then we can't have Horizontal() / Vertical().
Horizontal(); Text("a"); Text("b"); Vertical(); Text("c"); Text("d");
Does that become the layout in your example or in mine? Gets a bit confusing.
So my proposal is that all those gives the same output:
PushHorizontal(); Text("a"); Text("b"); PushVertical(); Text("c"); Text("d"); PopVertical(); PopHorizontal();
PushHorizontal(); Text("a"); Text("b"); PopHorizontal(); Text("c"); Text("d");
Horizontal(); Text("a"); Text("b"); Vertical(); Text("c"); Text("d");
That is:
a b
c
d
So there's less stored state.
Now if we want to implement your layout example (which is more of a rare case) we can have a way to set the value internally called "ColumnsStartX" (those variables can be cleaned up/renamed before being publicly exposed).
ImGui::SetColumnStartX(float x)
// this
ImGui::PushVertical(bool use_pos_x_as_column_start = false);
ImGui::Vertical(bool use_pos_x_as_column_start = false);
// or that
ImGui::PushVertical(float column_x = 0.0f); // default left side. passing -1 uses current cursor x
ImGui::Vertical(float column_x = 0.0f); // default left side. passing -1 uses current cursor x
Passing a float is more flexible but the difference between 0.0f (left side) and -1.0f (current cursor x) may be a bit arbitrary ? I guess you can always do ImGui::Vertical(ImGui::GetCursorPosX()); as well.
Does it makes sense?
Also - the devil is in the details - we would probably want to add WindowPadding.x to the provided offset_x. Which becomes a problem because:
ImGui::Vertical(0.0f); // >> 0.0f + WIndowPadding.x
ImGui::Vertical(GetCursorPosX()); // >> GetCursorPosX() + WindowPadding.x // Undesireable, cursor pos already include the padding.
We could treat 0.0f as a special case but that would be dodgy.
So a more consistent solution would be:
column_x < 0.0f (default value to all calls) gets turned into WindowPadding.x
column_x > 0.0f untouched
But then to implement your example you would need to call GetCursorPosX() and we lose the "lock current x position" shortcut.
I think Horizontal()/Vertical() plus PushCurrentLayout() can simplify things: wanna change layout? -- change, wanna save? -- push/pop.
Awesome library but I really hope this gets worked on soon as the current solution to use ImGui::CalcTextSize
is non-ideal for performance since this gets then get called twice (since it is also used the control like the text box itself). This is my code just to display a centered text on the screen which is twice as big as the default size. Btw any way to SetNextWindowFontScale
since we are supposed to use SetNextWindowSize
and the like which doesn't work properly if you change the font scale?
const ImGuiIO& guiIO = ImGui::GetIO();
const static char* titleWindowTitle = "title";
ImGui::Begin(titleWindowTitle, nullptr, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove);
const static char* title = "Centered Title";
ImVec2 textSize = ImGui::CalcTextSize(title);
ImVec2 windowSize = ImVec2(textSize.x + Constants::UiPadding * 2.f, textSize.y + Constants::UiPadding * 2.f);
ImGui::SetWindowPos(ImVec2((guiIO.DisplaySize.x - windowSize.x) * 0.5f, (guiIO.DisplaySize.y - windowSize.y) * 0.5f));
ImGui::SetWindowSize(windowSize);
ImGui::SetWindowFontScale(2.f);
ImGui::TextUnformatted(title);
ImGui::End();
There is something for me. Basic implementation of layouts in form of BeginHorizontal/EndHorizontal.
ImGui::BeginHorizontal("example_h1", spanToWindow ? bounds : ImVec2(0, 0));
ImGui::TextUnformatted("Left");
ImGui::Spring(middleWeight);
ImGui::TextUnformatted("Middle");
ImGui::Spring(1.0f - middleWeight);
ImGui::TextUnformatted("Right");
ImGui::EndHorizontal();
It is rough around the edges so please give me a feedback how it can be improved.
It's been 7 years already, any updates on builtin layouts? Or maybe any well-maintained addon?
What's wrong with Stack Layout? #846?
@thedmd the only thing wrong with StackLayout is that it is not merged :D
In some time I think a change can be proposed to allow other layout engines too. Truth is Stack Layouts are one of the possible solutions. Grids, forms (labels on the left anyone?), overflow layouts are examples of alternatives better suited for their respective use cases.
As for today few small modifications in ImGui are necessary to make custom layout code possible. (https://github.com/ocornut/imgui/pull/846#issuecomment-986006070).
There is a branch where Stack Layout code is moved to eventually became a plugin/extension to ImGui feature/layout-external.
What's wrong with Stack Layout? #846?
It's exactly what I want but It's still not merged( Any ETA?
In some time I think a change can be proposed to allow other layout engines too.
Yes importing yoga/flexbox would be a great addition too
Any updates on this?
It's taking ages 😂
One day...
This works for me
int maxColumns = 10;
ImGui::Columns(maxColumns, "MyLayout", false);
ImGui::SetColumnWidth(0, 80);
for (int i = 1; i < maxColumns - 1; i++)
{
ImGui::SetColumnWidth(i, 80);
ImGui::Text("item");
ImGui::NextColumn();
}
ImGui::EndColumns();
I'm just in the process of studying, and I'm unlikely to be useful in terms of project development right now. But, if someone decides to improve it, then I suggest considering the implementation https://developer.android.com/reference/android/widget/LinearLayout
I don't mean the code itself, but the capabilities of this Layout, which has been built into the Android OS since the first version. What would be cool to see: weightSum, orientation and gravity setup
The only way I've found to do horizontal layout in ImGui is to call SameLine() in between widgets that should go on the same line. This is problematic when the widgets are painted by some other code. In particular, I want to lay out an unknown number of Text:s horizontally on the same line.
May I suggest adding something like: