|
@@ -53,6 +53,7 @@ CODE
|
|
- ImGuiTextFilter
|
|
- ImGuiTextFilter
|
|
- ImGuiTextBuffer
|
|
- ImGuiTextBuffer
|
|
- ImGuiListClipper
|
|
- ImGuiListClipper
|
|
|
|
+- Render Helpers
|
|
- Main Code (most of the code! lots of stuff, needs tidying up)
|
|
- Main Code (most of the code! lots of stuff, needs tidying up)
|
|
- Tooltips
|
|
- Tooltips
|
|
- Popups
|
|
- Popups
|
|
@@ -2075,6 +2076,226 @@ bool ImGuiListClipper::Step()
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+// RENDER HELPERS
|
|
|
|
+// Those [Internal] functions are a terrible mess - their signature and behavior will change.
|
|
|
|
+// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state.
|
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
|
+
|
|
|
|
+const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
|
|
|
+{
|
|
|
|
+ const char* text_display_end = text;
|
|
|
|
+ if (!text_end)
|
|
|
|
+ text_end = (const char*)-1;
|
|
|
|
+
|
|
|
|
+ while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
|
|
|
+ text_display_end++;
|
|
|
|
+ return text_display_end;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Internal ImGui functions to render text
|
|
|
|
+// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
|
|
|
|
+void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+
|
|
|
|
+ // Hide anything after a '##' string
|
|
|
|
+ const char* text_display_end;
|
|
|
|
+ if (hide_text_after_hash)
|
|
|
|
+ {
|
|
|
|
+ text_display_end = FindRenderedTextEnd(text, text_end);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (!text_end)
|
|
|
|
+ text_end = text + strlen(text); // FIXME-OPT
|
|
|
|
+ text_display_end = text_end;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (text != text_display_end)
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
|
|
|
|
+ if (g.LogEnabled)
|
|
|
|
+ LogRenderedText(&pos, text, text_display_end);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+
|
|
|
|
+ if (!text_end)
|
|
|
|
+ text_end = text + strlen(text); // FIXME-OPT
|
|
|
|
+
|
|
|
|
+ if (text != text_end)
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
|
|
|
|
+ if (g.LogEnabled)
|
|
|
|
+ LogRenderedText(&pos, text, text_end);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Default clip_rect uses (pos_min,pos_max)
|
|
|
|
+// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
|
|
|
+void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
|
|
|
+{
|
|
|
|
+ // Hide anything after a '##' string
|
|
|
|
+ const char* text_display_end = FindRenderedTextEnd(text, text_end);
|
|
|
|
+ const int text_len = (int)(text_display_end - text);
|
|
|
|
+ if (text_len == 0)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+
|
|
|
|
+ // Perform CPU side clipping for single clipped element to avoid using scissor state
|
|
|
|
+ ImVec2 pos = pos_min;
|
|
|
|
+ const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
|
|
|
|
+
|
|
|
|
+ const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
|
|
|
+ const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
|
|
|
+ bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
|
|
|
|
+ if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min
|
|
|
|
+ need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
|
|
|
|
+
|
|
|
|
+ // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment.
|
|
|
|
+ if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
|
|
|
|
+ if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
|
|
|
|
+
|
|
|
|
+ // Render
|
|
|
|
+ if (need_clipping)
|
|
|
|
+ {
|
|
|
|
+ ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
|
|
|
+ window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
|
|
|
|
+ }
|
|
|
|
+ if (g.LogEnabled)
|
|
|
|
+ LogRenderedText(&pos, text, text_display_end);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Render a rectangle shaped with optional rounding and borders
|
|
|
|
+void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+ window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
|
|
|
|
+ const float border_size = g.Style.FrameBorderSize;
|
|
|
|
+ if (border && border_size > 0.0f)
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
+ window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+ const float border_size = g.Style.FrameBorderSize;
|
|
|
|
+ if (border_size > 0.0f)
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
+ window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state
|
|
|
|
+void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+
|
|
|
|
+ const float h = g.FontSize * 1.00f;
|
|
|
|
+ float r = h * 0.40f * scale;
|
|
|
|
+ ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale);
|
|
|
|
+
|
|
|
|
+ ImVec2 a, b, c;
|
|
|
|
+ switch (dir)
|
|
|
|
+ {
|
|
|
|
+ case ImGuiDir_Up:
|
|
|
|
+ case ImGuiDir_Down:
|
|
|
|
+ if (dir == ImGuiDir_Up) r = -r;
|
|
|
|
+ a = ImVec2(+0.000f,+0.750f) * r;
|
|
|
|
+ b = ImVec2(-0.866f,-0.750f) * r;
|
|
|
|
+ c = ImVec2(+0.866f,-0.750f) * r;
|
|
|
|
+ break;
|
|
|
|
+ case ImGuiDir_Left:
|
|
|
|
+ case ImGuiDir_Right:
|
|
|
|
+ if (dir == ImGuiDir_Left) r = -r;
|
|
|
|
+ a = ImVec2(+0.750f,+0.000f) * r;
|
|
|
|
+ b = ImVec2(-0.750f,+0.866f) * r;
|
|
|
|
+ c = ImVec2(-0.750f,-0.866f) * r;
|
|
|
|
+ break;
|
|
|
|
+ case ImGuiDir_None:
|
|
|
|
+ case ImGuiDir_COUNT:
|
|
|
|
+ IM_ASSERT(0);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ g.CurrentWindow->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ImGui::RenderBullet(ImVec2 pos)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+ window->DrawList->AddCircleFilled(pos, g.FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
+
|
|
|
|
+ float thickness = ImMax(sz / 5.0f, 1.0f);
|
|
|
|
+ sz -= thickness*0.5f;
|
|
|
|
+ pos += ImVec2(thickness*0.25f, thickness*0.25f);
|
|
|
|
+
|
|
|
|
+ float third = sz / 3.0f;
|
|
|
|
+ float bx = pos.x + third;
|
|
|
|
+ float by = pos.y + sz - third*0.5f;
|
|
|
|
+ window->DrawList->PathLineTo(ImVec2(bx - third, by - third));
|
|
|
|
+ window->DrawList->PathLineTo(ImVec2(bx, by));
|
|
|
|
+ window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2));
|
|
|
|
+ window->DrawList->PathStroke(col, false, thickness);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags)
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ if (id != g.NavId)
|
|
|
|
+ return;
|
|
|
|
+ if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw))
|
|
|
|
+ return;
|
|
|
|
+ ImGuiWindow* window = ImGui::GetCurrentWindow();
|
|
|
|
+ if (window->DC.NavHideHighlightOneFrame)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding;
|
|
|
|
+ ImRect display_rect = bb;
|
|
|
|
+ display_rect.ClipWith(window->ClipRect);
|
|
|
|
+ if (flags & ImGuiNavHighlightFlags_TypeDefault)
|
|
|
|
+ {
|
|
|
|
+ const float THICKNESS = 2.0f;
|
|
|
|
+ const float DISTANCE = 3.0f + THICKNESS * 0.5f;
|
|
|
|
+ display_rect.Expand(ImVec2(DISTANCE,DISTANCE));
|
|
|
|
+ bool fully_visible = window->ClipRect.Contains(display_rect);
|
|
|
|
+ if (!fully_visible)
|
|
|
|
+ window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
|
|
|
|
+ window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS);
|
|
|
|
+ if (!fully_visible)
|
|
|
|
+ window->DrawList->PopClipRect();
|
|
|
|
+ }
|
|
|
|
+ if (flags & ImGuiNavHighlightFlags_TypeThin)
|
|
|
|
+ {
|
|
|
|
+ window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
//-----------------------------------------------------------------------------
|
|
//-----------------------------------------------------------------------------
|
|
// MAIN CODE
|
|
// MAIN CODE
|
|
// (this category is still too large and badly ordered, needs some tidying up)
|
|
// (this category is still too large and badly ordered, needs some tidying up)
|
|
@@ -3463,326 +3684,112 @@ void ImGui::EndFrame()
|
|
// This is where we can trim the popup stack.
|
|
// This is where we can trim the popup stack.
|
|
ImGuiWindow* modal = GetFrontMostPopupModal();
|
|
ImGuiWindow* modal = GetFrontMostPopupModal();
|
|
bool hovered_window_above_modal = false;
|
|
bool hovered_window_above_modal = false;
|
|
- if (modal == NULL)
|
|
|
|
- hovered_window_above_modal = true;
|
|
|
|
- for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window = g.Windows[i];
|
|
|
|
- if (window == modal)
|
|
|
|
- break;
|
|
|
|
- if (window == g.HoveredWindow)
|
|
|
|
- hovered_window_above_modal = true;
|
|
|
|
- }
|
|
|
|
- ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Update user-facing viewport list
|
|
|
|
- g.PlatformIO.MainViewport = g.Viewports[0];
|
|
|
|
- g.PlatformIO.Viewports.resize(0);
|
|
|
|
- for (int i = 0; i < g.Viewports.Size; i++)
|
|
|
|
- {
|
|
|
|
- ImGuiViewportP* viewport = g.Viewports[i];
|
|
|
|
- if (viewport->LastFrameActive < g.FrameCount || viewport->Size.x <= 0.0f || viewport->Size.y <= 0.0f)
|
|
|
|
- continue;
|
|
|
|
- if (viewport->Window && !IsWindowActiveAndVisible(viewport->Window))
|
|
|
|
- continue;
|
|
|
|
- if (i > 0)
|
|
|
|
- IM_ASSERT(viewport->Window != NULL);
|
|
|
|
- g.PlatformIO.Viewports.push_back(viewport);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Sort the window list so that all child windows are after their parent
|
|
|
|
- // We cannot do that on FocusWindow() because childs may not exist yet
|
|
|
|
- g.WindowsSortBuffer.resize(0);
|
|
|
|
- g.WindowsSortBuffer.reserve(g.Windows.Size);
|
|
|
|
- for (int i = 0; i != g.Windows.Size; i++)
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window = g.Windows[i];
|
|
|
|
- if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it
|
|
|
|
- continue;
|
|
|
|
- AddWindowToSortedBuffer(&g.WindowsSortBuffer, window);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
|
|
|
|
- g.Windows.swap(g.WindowsSortBuffer);
|
|
|
|
- g.IO.MetricsActiveWindows = g.WindowsActiveCount;
|
|
|
|
-
|
|
|
|
- // Unlock font atlas
|
|
|
|
- g.IO.Fonts->Locked = false;
|
|
|
|
-
|
|
|
|
- // Clear Input data for next frame
|
|
|
|
- g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
|
|
|
|
- memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
|
|
|
|
- memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
|
|
|
|
-
|
|
|
|
- g.FrameScopeActive = false;
|
|
|
|
- g.FrameCountEnded = g.FrameCount;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::Render()
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- IM_ASSERT(g.Initialized);
|
|
|
|
-
|
|
|
|
- if (g.FrameCountEnded != g.FrameCount)
|
|
|
|
- ImGui::EndFrame();
|
|
|
|
- g.FrameCountRendered = g.FrameCount;
|
|
|
|
-
|
|
|
|
- // Gather ImDrawList to render (for each active window)
|
|
|
|
- g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
|
|
|
|
- for (int n = 0; n != g.Viewports.Size; n++)
|
|
|
|
- g.Viewports[n]->DrawDataBuilder.Clear();
|
|
|
|
- ImGuiWindow* windows_to_render_front_most[2];
|
|
|
|
- windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL;
|
|
|
|
- windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL;
|
|
|
|
- for (int n = 0; n != g.Windows.Size; n++)
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window = g.Windows[n];
|
|
|
|
- if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_front_most[0] && window != windows_to_render_front_most[1])
|
|
|
|
- AddRootWindowToDrawData(window);
|
|
|
|
- }
|
|
|
|
- for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_front_most); n++)
|
|
|
|
- if (windows_to_render_front_most[n] && IsWindowActiveAndVisible(windows_to_render_front_most[n])) // NavWindowingTarget is always temporarily displayed as the front-most window
|
|
|
|
- AddRootWindowToDrawData(windows_to_render_front_most[n]);
|
|
|
|
-
|
|
|
|
- // Draw software mouse cursor if requested
|
|
|
|
- if (g.IO.MouseDrawCursor)
|
|
|
|
- RenderMouseCursor(g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor);
|
|
|
|
-
|
|
|
|
- // Setup ImDrawData structures for end-user
|
|
|
|
- g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0;
|
|
|
|
- for (int n = 0; n < g.Viewports.Size; n++)
|
|
|
|
- {
|
|
|
|
- ImGuiViewportP* viewport = g.Viewports[n];
|
|
|
|
- viewport->DrawDataBuilder.FlattenIntoSingleLayer();
|
|
|
|
- if (viewport->OverlayDrawList != NULL)
|
|
|
|
- AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetOverlayDrawList(viewport));
|
|
|
|
- SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]);
|
|
|
|
- g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount;
|
|
|
|
- g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData()
|
|
|
|
-#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
|
|
- if (g.Viewports[0]->DrawData->CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL)
|
|
|
|
- g.IO.RenderDrawListsFn(g.Viewports[0]->DrawData);
|
|
|
|
-#endif
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
|
|
|
-{
|
|
|
|
- const char* text_display_end = text;
|
|
|
|
- if (!text_end)
|
|
|
|
- text_end = (const char*)-1;
|
|
|
|
-
|
|
|
|
- while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
|
|
|
|
- text_display_end++;
|
|
|
|
- return text_display_end;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Internal ImGui functions to render text
|
|
|
|
-// RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
|
|
|
|
-void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
-
|
|
|
|
- // Hide anything after a '##' string
|
|
|
|
- const char* text_display_end;
|
|
|
|
- if (hide_text_after_hash)
|
|
|
|
- {
|
|
|
|
- text_display_end = FindRenderedTextEnd(text, text_end);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- if (!text_end)
|
|
|
|
- text_end = text + strlen(text); // FIXME-OPT
|
|
|
|
- text_display_end = text_end;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (text != text_display_end)
|
|
|
|
- {
|
|
|
|
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
|
|
|
|
- if (g.LogEnabled)
|
|
|
|
- LogRenderedText(&pos, text, text_display_end);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
-
|
|
|
|
- if (!text_end)
|
|
|
|
- text_end = text + strlen(text); // FIXME-OPT
|
|
|
|
-
|
|
|
|
- if (text != text_end)
|
|
|
|
- {
|
|
|
|
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
|
|
|
|
- if (g.LogEnabled)
|
|
|
|
- LogRenderedText(&pos, text, text_end);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Default clip_rect uses (pos_min,pos_max)
|
|
|
|
-// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
|
|
|
-void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
|
|
|
-{
|
|
|
|
- // Hide anything after a '##' string
|
|
|
|
- const char* text_display_end = FindRenderedTextEnd(text, text_end);
|
|
|
|
- const int text_len = (int)(text_display_end - text);
|
|
|
|
- if (text_len == 0)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
-
|
|
|
|
- // Perform CPU side clipping for single clipped element to avoid using scissor state
|
|
|
|
- ImVec2 pos = pos_min;
|
|
|
|
- const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
|
|
|
|
-
|
|
|
|
- const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
|
|
|
|
- const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
|
|
|
|
- bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
|
|
|
|
- if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min
|
|
|
|
- need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
|
|
|
|
-
|
|
|
|
- // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment.
|
|
|
|
- if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
|
|
|
|
- if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
|
|
|
|
-
|
|
|
|
- // Render
|
|
|
|
- if (need_clipping)
|
|
|
|
- {
|
|
|
|
- ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
|
|
|
|
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
|
|
|
|
- }
|
|
|
|
- if (g.LogEnabled)
|
|
|
|
- LogRenderedText(&pos, text, text_display_end);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Render a rectangle shaped with optional rounding and borders
|
|
|
|
-void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
- window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
|
|
|
|
- const float border_size = g.Style.FrameBorderSize;
|
|
|
|
- if (border && border_size > 0.0f)
|
|
|
|
- {
|
|
|
|
- window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
- window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
|
|
+ if (modal == NULL)
|
|
|
|
+ hovered_window_above_modal = true;
|
|
|
|
+ for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
|
|
|
+ {
|
|
|
|
+ ImGuiWindow* window = g.Windows[i];
|
|
|
|
+ if (window == modal)
|
|
|
|
+ break;
|
|
|
|
+ if (window == g.HoveredWindow)
|
|
|
|
+ hovered_window_above_modal = true;
|
|
|
|
+ }
|
|
|
|
+ ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
- const float border_size = g.Style.FrameBorderSize;
|
|
|
|
- if (border_size > 0.0f)
|
|
|
|
|
|
+ // Update user-facing viewport list
|
|
|
|
+ g.PlatformIO.MainViewport = g.Viewports[0];
|
|
|
|
+ g.PlatformIO.Viewports.resize(0);
|
|
|
|
+ for (int i = 0; i < g.Viewports.Size; i++)
|
|
{
|
|
{
|
|
- window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
- window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
|
|
|
|
|
|
+ ImGuiViewportP* viewport = g.Viewports[i];
|
|
|
|
+ if (viewport->LastFrameActive < g.FrameCount || viewport->Size.x <= 0.0f || viewport->Size.y <= 0.0f)
|
|
|
|
+ continue;
|
|
|
|
+ if (viewport->Window && !IsWindowActiveAndVisible(viewport->Window))
|
|
|
|
+ continue;
|
|
|
|
+ if (i > 0)
|
|
|
|
+ IM_ASSERT(viewport->Window != NULL);
|
|
|
|
+ g.PlatformIO.Viewports.push_back(viewport);
|
|
}
|
|
}
|
|
-}
|
|
|
|
-
|
|
|
|
-// Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state
|
|
|
|
-void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
|
|
|
|
- const float h = g.FontSize * 1.00f;
|
|
|
|
- float r = h * 0.40f * scale;
|
|
|
|
- ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale);
|
|
|
|
-
|
|
|
|
- ImVec2 a, b, c;
|
|
|
|
- switch (dir)
|
|
|
|
|
|
+ // Sort the window list so that all child windows are after their parent
|
|
|
|
+ // We cannot do that on FocusWindow() because childs may not exist yet
|
|
|
|
+ g.WindowsSortBuffer.resize(0);
|
|
|
|
+ g.WindowsSortBuffer.reserve(g.Windows.Size);
|
|
|
|
+ for (int i = 0; i != g.Windows.Size; i++)
|
|
{
|
|
{
|
|
- case ImGuiDir_Up:
|
|
|
|
- case ImGuiDir_Down:
|
|
|
|
- if (dir == ImGuiDir_Up) r = -r;
|
|
|
|
- a = ImVec2(+0.000f,+0.750f) * r;
|
|
|
|
- b = ImVec2(-0.866f,-0.750f) * r;
|
|
|
|
- c = ImVec2(+0.866f,-0.750f) * r;
|
|
|
|
- break;
|
|
|
|
- case ImGuiDir_Left:
|
|
|
|
- case ImGuiDir_Right:
|
|
|
|
- if (dir == ImGuiDir_Left) r = -r;
|
|
|
|
- a = ImVec2(+0.750f,+0.000f) * r;
|
|
|
|
- b = ImVec2(-0.750f,+0.866f) * r;
|
|
|
|
- c = ImVec2(-0.750f,-0.866f) * r;
|
|
|
|
- break;
|
|
|
|
- case ImGuiDir_None:
|
|
|
|
- case ImGuiDir_COUNT:
|
|
|
|
- IM_ASSERT(0);
|
|
|
|
- break;
|
|
|
|
|
|
+ ImGuiWindow* window = g.Windows[i];
|
|
|
|
+ if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it
|
|
|
|
+ continue;
|
|
|
|
+ AddWindowToSortedBuffer(&g.WindowsSortBuffer, window);
|
|
}
|
|
}
|
|
|
|
|
|
- g.CurrentWindow->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::RenderBullet(ImVec2 pos)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
- window->DrawList->AddCircleFilled(pos, g.FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8);
|
|
|
|
-}
|
|
|
|
|
|
+ IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong
|
|
|
|
+ g.Windows.swap(g.WindowsSortBuffer);
|
|
|
|
+ g.IO.MetricsActiveWindows = g.WindowsActiveCount;
|
|
|
|
|
|
-void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
|
|
+ // Unlock font atlas
|
|
|
|
+ g.IO.Fonts->Locked = false;
|
|
|
|
|
|
- float thickness = ImMax(sz / 5.0f, 1.0f);
|
|
|
|
- sz -= thickness*0.5f;
|
|
|
|
- pos += ImVec2(thickness*0.25f, thickness*0.25f);
|
|
|
|
|
|
+ // Clear Input data for next frame
|
|
|
|
+ g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
|
|
|
|
+ memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters));
|
|
|
|
+ memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
|
|
|
|
|
|
- float third = sz / 3.0f;
|
|
|
|
- float bx = pos.x + third;
|
|
|
|
- float by = pos.y + sz - third*0.5f;
|
|
|
|
- window->DrawList->PathLineTo(ImVec2(bx - third, by - third));
|
|
|
|
- window->DrawList->PathLineTo(ImVec2(bx, by));
|
|
|
|
- window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2));
|
|
|
|
- window->DrawList->PathStroke(col, false, thickness);
|
|
|
|
|
|
+ g.FrameScopeActive = false;
|
|
|
|
+ g.FrameCountEnded = g.FrameCount;
|
|
}
|
|
}
|
|
|
|
|
|
-void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags)
|
|
|
|
|
|
+void ImGui::Render()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
- if (id != g.NavId)
|
|
|
|
- return;
|
|
|
|
- if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw))
|
|
|
|
- return;
|
|
|
|
- ImGuiWindow* window = ImGui::GetCurrentWindow();
|
|
|
|
- if (window->DC.NavHideHighlightOneFrame)
|
|
|
|
- return;
|
|
|
|
|
|
+ IM_ASSERT(g.Initialized);
|
|
|
|
|
|
- float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding;
|
|
|
|
- ImRect display_rect = bb;
|
|
|
|
- display_rect.ClipWith(window->ClipRect);
|
|
|
|
- if (flags & ImGuiNavHighlightFlags_TypeDefault)
|
|
|
|
|
|
+ if (g.FrameCountEnded != g.FrameCount)
|
|
|
|
+ ImGui::EndFrame();
|
|
|
|
+ g.FrameCountRendered = g.FrameCount;
|
|
|
|
+
|
|
|
|
+ // Gather ImDrawList to render (for each active window)
|
|
|
|
+ g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
|
|
|
|
+ for (int n = 0; n != g.Viewports.Size; n++)
|
|
|
|
+ g.Viewports[n]->DrawDataBuilder.Clear();
|
|
|
|
+ ImGuiWindow* windows_to_render_front_most[2];
|
|
|
|
+ windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL;
|
|
|
|
+ windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL;
|
|
|
|
+ for (int n = 0; n != g.Windows.Size; n++)
|
|
{
|
|
{
|
|
- const float THICKNESS = 2.0f;
|
|
|
|
- const float DISTANCE = 3.0f + THICKNESS * 0.5f;
|
|
|
|
- display_rect.Expand(ImVec2(DISTANCE,DISTANCE));
|
|
|
|
- bool fully_visible = window->ClipRect.Contains(display_rect);
|
|
|
|
- if (!fully_visible)
|
|
|
|
- window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
|
|
|
|
- window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS);
|
|
|
|
- if (!fully_visible)
|
|
|
|
- window->DrawList->PopClipRect();
|
|
|
|
|
|
+ ImGuiWindow* window = g.Windows[n];
|
|
|
|
+ if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_front_most[0] && window != windows_to_render_front_most[1])
|
|
|
|
+ AddRootWindowToDrawData(window);
|
|
}
|
|
}
|
|
- if (flags & ImGuiNavHighlightFlags_TypeThin)
|
|
|
|
|
|
+ for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_front_most); n++)
|
|
|
|
+ if (windows_to_render_front_most[n] && IsWindowActiveAndVisible(windows_to_render_front_most[n])) // NavWindowingTarget is always temporarily displayed as the front-most window
|
|
|
|
+ AddRootWindowToDrawData(windows_to_render_front_most[n]);
|
|
|
|
+
|
|
|
|
+ // Draw software mouse cursor if requested
|
|
|
|
+ if (g.IO.MouseDrawCursor)
|
|
|
|
+ RenderMouseCursor(g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor);
|
|
|
|
+
|
|
|
|
+ // Setup ImDrawData structures for end-user
|
|
|
|
+ g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0;
|
|
|
|
+ for (int n = 0; n < g.Viewports.Size; n++)
|
|
{
|
|
{
|
|
- window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f);
|
|
|
|
|
|
+ ImGuiViewportP* viewport = g.Viewports[n];
|
|
|
|
+ viewport->DrawDataBuilder.FlattenIntoSingleLayer();
|
|
|
|
+ if (viewport->OverlayDrawList != NULL)
|
|
|
|
+ AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetOverlayDrawList(viewport));
|
|
|
|
+ SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]);
|
|
|
|
+ g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount;
|
|
|
|
+ g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData()
|
|
|
|
+#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
|
|
+ if (g.Viewports[0]->DrawData->CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL)
|
|
|
|
+ g.IO.RenderDrawListsFn(g.Viewports[0]->DrawData);
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
|
|
// Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
|
|
@@ -4558,7 +4565,7 @@ const ImGuiResizeGripDef resize_grip_def[4] =
|
|
{ ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right
|
|
{ ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right
|
|
};
|
|
};
|
|
|
|
|
|
-static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness)
|
|
|
|
|
|
+static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness)
|
|
{
|
|
{
|
|
ImRect rect = window->Rect();
|
|
ImRect rect = window->Rect();
|
|
if (thickness == 0.0f) rect.Max -= ImVec2(1,1);
|
|
if (thickness == 0.0f) rect.Max -= ImVec2(1,1);
|
|
@@ -4622,7 +4629,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
|
|
const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check.
|
|
const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check.
|
|
const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
|
|
const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise
|
|
bool hovered, held;
|
|
bool hovered, held;
|
|
- ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
|
|
|
|
|
|
+ ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_size, BORDER_SIZE);
|
|
ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
|
|
ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
|
|
if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
|
|
if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held)
|
|
{
|
|
{
|
|
@@ -5187,7 +5194,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size);
|
|
window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size);
|
|
if (border_held != -1)
|
|
if (border_held != -1)
|
|
{
|
|
{
|
|
- ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f);
|
|
|
|
|
|
+ ImRect border = GetResizeBorderRect(window, border_held, grip_draw_size, 0.0f);
|
|
window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size));
|
|
window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size));
|
|
}
|
|
}
|
|
if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar))
|
|
if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar))
|
|
@@ -6383,17 +6390,6 @@ ImGuiStorage* ImGui::GetStateStorage()
|
|
return window->DC.StateStorage;
|
|
return window->DC.StateStorage;
|
|
}
|
|
}
|
|
|
|
|
|
-void ImGui::AlignTextToFramePadding()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2);
|
|
|
|
- window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void ImGui::PushID(const char* str_id)
|
|
void ImGui::PushID(const char* str_id)
|
|
{
|
|
{
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
@@ -6440,149 +6436,6 @@ ImGuiID ImGui::GetID(const void* ptr_id)
|
|
return GImGui->CurrentWindow->GetID(ptr_id);
|
|
return GImGui->CurrentWindow->GetID(ptr_id);
|
|
}
|
|
}
|
|
|
|
|
|
-// Horizontal/vertical separating line
|
|
|
|
-void ImGui::Separator()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
-
|
|
|
|
- // Those flags should eventually be overridable by the user
|
|
|
|
- ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
|
|
|
|
- IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected
|
|
|
|
- if (flags & ImGuiSeparatorFlags_Vertical)
|
|
|
|
- {
|
|
|
|
- VerticalSeparator();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Horizontal Separator
|
|
|
|
- if (window->DC.ColumnsSet)
|
|
|
|
- PopClipRect();
|
|
|
|
-
|
|
|
|
- float x1 = window->Pos.x;
|
|
|
|
- float x2 = window->Pos.x + window->Size.x;
|
|
|
|
- if (!window->DC.GroupStack.empty())
|
|
|
|
- x1 += window->DC.Indent.x;
|
|
|
|
-
|
|
|
|
- const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f));
|
|
|
|
- ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
|
|
|
|
- if (!ItemAdd(bb, 0))
|
|
|
|
- {
|
|
|
|
- if (window->DC.ColumnsSet)
|
|
|
|
- PushColumnClipRect();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator));
|
|
|
|
-
|
|
|
|
- if (g.LogEnabled)
|
|
|
|
- LogRenderedText(NULL, IM_NEWLINE "--------------------------------");
|
|
|
|
-
|
|
|
|
- if (window->DC.ColumnsSet)
|
|
|
|
- {
|
|
|
|
- PushColumnClipRect();
|
|
|
|
- window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::VerticalSeparator()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
-
|
|
|
|
- float y1 = window->DC.CursorPos.y;
|
|
|
|
- float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y;
|
|
|
|
- const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2));
|
|
|
|
- ItemSize(ImVec2(bb.GetWidth(), 0.0f));
|
|
|
|
- if (!ItemAdd(bb, 0))
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator));
|
|
|
|
- if (g.LogEnabled)
|
|
|
|
- LogText(" |");
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise.
|
|
|
|
-bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay)
|
|
|
|
-{
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
-
|
|
|
|
- const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
|
|
|
- window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
|
|
|
|
- bool item_add = ItemAdd(bb, id);
|
|
|
|
- window->DC.ItemFlags = item_flags_backup;
|
|
|
|
- if (!item_add)
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- bool hovered, held;
|
|
|
|
- ImRect bb_interact = bb;
|
|
|
|
- bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
|
|
|
|
- ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
|
|
|
|
- if (g.ActiveId != id)
|
|
|
|
- SetItemAllowOverlap();
|
|
|
|
-
|
|
|
|
- if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
|
|
|
|
- SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
|
|
|
|
-
|
|
|
|
- ImRect bb_render = bb;
|
|
|
|
- if (held)
|
|
|
|
- {
|
|
|
|
- ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min;
|
|
|
|
- float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x;
|
|
|
|
-
|
|
|
|
- // Minimum pane size
|
|
|
|
- float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1);
|
|
|
|
- float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2);
|
|
|
|
- if (mouse_delta < -size_1_maximum_delta)
|
|
|
|
- mouse_delta = -size_1_maximum_delta;
|
|
|
|
- if (mouse_delta > size_2_maximum_delta)
|
|
|
|
- mouse_delta = size_2_maximum_delta;
|
|
|
|
-
|
|
|
|
- // Apply resize
|
|
|
|
- if (mouse_delta != 0.0f)
|
|
|
|
- {
|
|
|
|
- if (mouse_delta < 0.0f)
|
|
|
|
- IM_ASSERT(*size1 + mouse_delta >= min_size1);
|
|
|
|
- if (mouse_delta > 0.0f)
|
|
|
|
- IM_ASSERT(*size2 - mouse_delta >= min_size2);
|
|
|
|
- *size1 += mouse_delta;
|
|
|
|
- *size2 -= mouse_delta;
|
|
|
|
- bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta));
|
|
|
|
- MarkItemEdited(id);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Render
|
|
|
|
- const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
|
|
|
|
- window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding);
|
|
|
|
-
|
|
|
|
- return held;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::Spacing()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
- ItemSize(ImVec2(0,0));
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-void ImGui::Dummy(const ImVec2& size)
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
|
|
|
|
- ItemSize(bb);
|
|
|
|
- ItemAdd(bb, 0);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
bool ImGui::IsRectVisible(const ImVec2& size)
|
|
bool ImGui::IsRectVisible(const ImVec2& size)
|
|
{
|
|
{
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
ImGuiWindow* window = GetCurrentWindowRead();
|
|
@@ -6689,22 +6542,6 @@ void ImGui::SameLine(float pos_x, float spacing_w)
|
|
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
|
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
|
}
|
|
}
|
|
|
|
|
|
-void ImGui::NewLine()
|
|
|
|
-{
|
|
|
|
- ImGuiWindow* window = GetCurrentWindow();
|
|
|
|
- if (window->SkipItems)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- ImGuiContext& g = *GImGui;
|
|
|
|
- const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
|
|
|
|
- window->DC.LayoutType = ImGuiLayoutType_Vertical;
|
|
|
|
- if (window->DC.CurrentLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
|
|
|
|
- ItemSize(ImVec2(0,0));
|
|
|
|
- else
|
|
|
|
- ItemSize(ImVec2(0.0f, g.FontSize));
|
|
|
|
- window->DC.LayoutType = backup_layout_type;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
void ImGui::Indent(float indent_w)
|
|
void ImGui::Indent(float indent_w)
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|