-
-
Notifications
You must be signed in to change notification settings - Fork 10.6k
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
SeparatorText / TextSeparator / CenteredSeparator (which respects columns and SameLine) #1643
Comments
Hello @phed, Thanks for submitting that. I probably won't be able to look at it in depth or comment on it for a bit but it's good to have those references and ideas posted. And here's a GIF for reference of what your demo looks like: Here's the same code with minor tweak to make it compatible with imgui's latest internals (your version of imgui is a little old I guess). Also
|
Hello ocornut, Im very thankful for your excellent work. In the latest version (v1.89.1) I noted that there are some changes in the code above (in the 'CenteredSeparator' function): ColumnsSet -> CurrentColumns |
@hebohang yes indeed the code, as-is, does not compile with the latest ImGui release. @ocornut I wished this control was part of the standard ImGui as it is quite useful and seems basic, especially when it comes to creating section. I have been using pre-opened TreeNode to combine separation/header but this control replaces it hands-down. I am definitely 👍 on this control. |
Here is an example on how it significantly help with my popup menu. Before: The only thing I wished is that the line would be at least as long before and after the text (it looks a little too short after |
I'm going to focus on a |
I think we ought to have a simple function with only text parameters, and padding/centering are part of the Style structure. My issue is that it would make sense to make it use its own color but that means associating more semantic to the widget, at which point the semantic may be more generic than a separator, and we need to know more about that in order to name things. |
@ocornut I agree with you. It's better to follow the model already in place for other widgets |
I implemented this now: // FIXME: How to fit e.g. a (?) helpmarker
void ImGui::SeparatorTextV(const char* fmt, va_list args)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style;
const char* label, *label_end;
ImFormatStringToTempBufferV(&label, &label_end, fmt, args);
label_end = FindRenderedTextEnd(label, label_end);
static float Style_SeparatorPaddingY = style.FramePadding.y;
static float Style_SeparatorMinWidth = 10.0f;
static float Style_SeparatorAlign = 0.0f; // When set to >0.0f (most often 0.5f or 1.0f) generally MinLeadingWidth would be 0.0f
static float Style_SeparatorSize = 1.0f; // FIXME-STYLE: If intending a Separator (as per current name) abs thickness is good. If intending a larger fill may better be expressed as a % of total height.
#if 0 // [DEBUG] Until moved to style structure
static ImGuiOnceUponAFrame ouaf;
if (ouaf)
{
ImGui::Begin("WIP style");
ImGui::SliderFloat("Align", &Style_SeparatorAlign, 0.0f, 1.0f);
ImGui::DragFloat("MinWidth", &Style_SeparatorMinWidth, 1.0f, 0.0f, 100.0f);
ImGui::DragFloat("PaddingY", &Style_SeparatorPaddingY, 1.0f, 0.0f, 20.0f);
ImGui::DragFloat("Size", &Style_SeparatorSize, 0.2f, 0.0f, 40.0f, "%.0f");
ImGui::End();
}
#endif
const ImVec2 label_size = CalcTextSize(label, label_end, false);
const ImVec2 pos = window->DC.CursorPos;
const float sep1_min_w = Style_SeparatorMinWidth;
const float sep2_min_w = Style_SeparatorMinWidth;// 0.0f;
const float min_size_padding = (sep1_min_w > 0.0f ? sep1_min_w + style.ItemSpacing.x : 0.0f) + (sep2_min_w > 0.0f ? sep2_min_w + style.ItemSpacing.x : 0.0f);
const ImVec2 min_size(min_size_padding + label_size.x, label_size.y + Style_SeparatorPaddingY * 2.0f);
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
ItemSize(min_size);
if (!ItemAdd(bb, 0))
return;
const float seps_y = ImFloor((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f);
const float sep1_x1 = pos.x;
const float sep2_x2 = bb.Max.x;
const float sep1_spacing = (sep1_min_w > 0.0f || Style_SeparatorAlign > 0.0f) ? style.ItemSpacing.x : 0.0f;
const float sep2_spacing = (sep2_min_w > 0.0f || Style_SeparatorAlign < 1.0f) ? style.ItemSpacing.x : 0.0f;
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - sep1_spacing - sep1_min_w - sep2_spacing - sep2_min_w);
ImVec2 label_pos;
label_pos.x = pos.x + sep1_min_w + sep1_spacing + ImMax(0.0f, (label_avail_w - label_size.x) * Style_SeparatorAlign);
label_pos.y = pos.y + Style_SeparatorPaddingY;
const ImU32 col = GetColorU32(ImGuiCol_Separator);
if (label_size.x > 0.0f)
{
const float sep1_x2 = label_pos.x - sep1_spacing;
const float sep2_x1 = label_pos.x + label_size.x + sep2_spacing;
if (sep1_x2 > sep1_x1)
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), col, Style_SeparatorSize);
if (sep2_x2 > sep2_x1)
window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), col, Style_SeparatorSize);
if (g.LogEnabled)
LogSetNextTextDecoration("----", NULL);
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, bb.Max.x, label, label_end, &label_size);
}
else
{
if (g.LogEnabled)
LogText("----");
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), col, Style_SeparatorSize);
}
} With text ellipsis: Centering etc.
I probably didn't express myself clearly. My problem is that it's not easy to take the decision of how/what to present in Style and with which semantic, it has many ramifications and needs to be future-proof / forward-thinking. As with many of the style related issues that are still open, it may difficult to solve them without a more holistic approach of styling. Not being able to decide how to express those values in the style structure today means it is difficult for me to merge this widget in the code-base, but trivial for anyone to use the widget themselves. e.g. e.g. I believe
|
e.g.
As that point we may draw inspiration from css/web headings and consider the possibility we would later provide several level of heading, where H1 to H3 are expected to be larger than current font size. So need to pick a name that will be compatible with those future extensions.
|
I went back on forth several times to settle on something.. I have pushed a WIP branch: There are a few things I need to do
|
@ocornut Thank you for spending cycles on this. This is my view, but consider it just as brainstorming as I clearly do not know the internals of ImGui like you do... I actually really like the concept of header. And from you said here are some ideas: Idea 1: ImGui::BeginHeader();
ImGui::Text("my text");
if(!error.empty())
{
ImGui::PushStyleColor(ImGuiCol_Text, kErrorColorU32);
ImGui::TextUnformatted(ReGui::kErrorIcon);
ImGui::PopStyleColor();
if(ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal))
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(error.c_str());
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
ImGui::EndHeader(); Idea 2: Like you mentioned css/websettings, you could imagine having styles associated to each "level", like ImGuiCol_H1_Text, etc... and then you could use something like: ImGui::BeginHeader(1) // for using *_H1_* styles/colors
ImGui::BeginHeader(2) // for using *_H2_* styles/colors Idea 3: How about extending the ImGui::BeginHorizontalLayout(); // I don't know if it exists but to prevent having to write SameLine() between each item
ImGui::SeparatorExactSize(10); // a 10 pixels wide line
ImGui::Text("my header");
// more stuff...
ImGui::SeparatorMinSize(10); // a line which extends until the end of the window but is at least 10 pixels wide
ImGui::EndHorizontalLayout(); |
I have pushed a I believe the sizes/distances/alignment should be standardized and not provided by finer API calls, hence a simpler design than the finer-grained functions suggested by original post, and settings in style structure. I consider this solved and would encourage you to use this now :) |
I updated to 1.89.3 (docking) and confirm that it works great. Thank you @ocornut |
Hi. This is a great feature that allows separating the clutter in a nice way. I have a question though. Does the |
Yes. See style editor and commit 99c0bd6 for details. |
I wanted to write a decorative combined text and separator.
So, this TextSeparator can be used inside columns and respects SameLine().
There is a number of variations, and CenteredSeparator is the main function, which is obviously an edit of ImGui::Separator
The main difference between this and ImGui::Separator is that it is aligned centered vertically, and that it does not align to the edges of the window when used alone, since I haven't found a clean way to detect if it is the first element on a line.
Maybe someone will find it useful. I would love any feedback for how to make it cleaner.
Other issues discussing the topic is #759 #205 #697 - Probably more too
The text was updated successfully, but these errors were encountered: