Open
Conversation
… labeled-border. - Add `ImGuiChildFlags_TopLabel` flag. - `ImGuiWindow`: add `float BorderDecoOffset` and `int LabelOffset, LabelLen` - Add `bool WindowUsesLabeledBorder()` (might be extended in the future) - Add helpers `GetWindowBorderRect()` and `RenderLabeledFrame()` - Reworked some code in window rendering to work with labeled borders (use the border rect for background, menu bar, resize borders).
Owner
|
Hello, May I ask if some of the PR description was written aided by an AI? |
Contributor
Author
No, I don't use these tools (neither for coding). |
Owner
|
Thank you. I’ll try to look at this when I have time. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I am proposing to add labeled border to child windows.
Motivation
Child windows rendered with a border (using
ImGuiChildFlags_Borders) often need to be labeled.This can be done using a
SeparatorText(label)at the begining, but this is not the most elegant solution.GUI APIs generaly provide a way to render a labeled border (fieldset in HTML, TitledBorder in java.swing or QGroupBox in Qt to name a few), but I haven't found a way to do it with imgui.
It is possible to construct a labled border with a custom wrapper arround
Begin/EndChild()(as mentioned in the comments of #9181, not sure how it interacts with other window decorations), but I think it makes sense for imgui to support this feature "natively".Solution
I propose to add a new child flag to decorate the child with a labled border:
ImGuiChildFlags_TopLabel(must be used withImGuiChildFlags_Borders).This does not introduce any breaking change.
This is then handled by the backend code for rendering window's border / decoration.
The labeled border depends on several parameters:
BeginChild(const char* name), not the constructed child name) for the label.window->Rect())ImGuiCol_Borderlike with the classic border.RenderTextEllipsis()(likeSeparatorText()) (so indirectly colored withImGuiCol_Text).window->WindowBorderSize(set bystyle.ChildBorderSize).window->WindowBorderSize(set bystyle.ChildBorderSize).Style.SeparatorTextAlign. I think it makes sense to re-use separator control variables here.Style.SeparatorTextPadding.x, same argument as above.Style.FramePadding.y, because this is not a separatorn but a frame.Style.ItemSpacing(same asSeparatorText())I had to add three members to
ImGuiWindow:BorderDecoOffsetis the vertical offset (in pixel) at which the top border starts.LabelOffsetandLabelLento store the label of the child window (Since the window name of the child is some combination of the parent name, name and the id). As noted in the code, there is a little issue where this label is not available at the first frame of the window creation.I added a helper
RenderLabeledFrame()which is essentialy a mashup betweenDrawList::AddRect()andSeparatorText().Currently it is only declared in
imgui.cpp, but it could be worth declaring it in a header as part of the imgui API.There are some interaction with other child rendering features:
API discussion:
One could argue that it is not necessary to add a new flag
ImGuiChildFlags_TopLabelto use a bordered label:If the
BeginChildis called withImGuiChildFlags_Bordersand a name with a non empty rendering name (according toFindRenderedTextEnd()), then a labeled border should be used.The main issue is that this would be a breaking change.
Background rendering tweak
I did some tweaks (in de7e90c) to improve the visuals when the child window has a background (or a menu bar).
The issue is best explained visually:
The background rect is the same as the border rect. But with labled border, there is hole in the border arround the label.
When the border is one pixel thick, the background is in the continuation of the border in the label region, which is less pleasantly looking than when the background is "contained" one pixel below with the tweak.
The solution is to manually crop by one pixel the edges of the background rectange.
A similar tweak is also aplied for the menu bar:
Possible extensions
Here are some ideas for potential improvements I did not include in this PR:
Collapsing child window:
Windows can be collapsed, but that requires a title bar (which is currently explicitely disabled for child windows). I think it would make sense to allow child window collapsing, and it would fit well with labled border. When collapsed, only the top border with the label would be shown (essentialy aSeparatorText()with a symbol indicating that it can be opened like aTreeNode()).Tootips:
Tooltips already have a border. It would be possible to decorate the top border with a label (with a vertical alignment forced to zero).Header and Footer labels:
We could add an option to label the top border or (inclusive) the bottom border (with a mirror alignment).Using the space in the top border
SeparatorText()provides anextra_wparameter to reserve some space in the separator bar (and sets the cursor there). Maybe a similar mechanism could be done with labeled border, given that its similarity withSeparatorText().