Internals: Extracted RenderMouseCursor() out of EndFrame(). Moved to imgui_draw.cpp along with RenderArrowPointingAt(). Comments. (#2013)
diff --git a/imgui.cpp b/imgui.cpp
index 1f29a71..3fc9495 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -4551,7 +4551,7 @@
ImGui::EndFrame();
g.FrameCountRendered = g.FrameCount;
- // Gather windows to render
+ // Gather ImDrawList to render (for each active window)
g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
g.DrawDataBuilder.Clear();
ImGuiWindow* windows_to_render_front_most[2];
@@ -4569,19 +4569,9 @@
g.DrawDataBuilder.FlattenIntoSingleLayer();
// Draw software mouse cursor if requested
- ImVec2 offset, size, uv[4];
- if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2]))
- {
- const ImVec2 pos = g.IO.MousePos - offset;
- const ImTextureID tex_id = g.IO.Fonts->TexID;
- const float sc = g.Style.MouseCursorScale;
- g.OverlayDrawList.PushTextureID(tex_id);
- g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow
- g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow
- g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border
- g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill
- g.OverlayDrawList.PopTextureID();
- }
+ if (g.IO.MouseDrawCursor)
+ RenderMouseCursor(&g.OverlayDrawList, g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor);
+
if (!g.OverlayDrawList.VtxBuffer.empty())
AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList);
@@ -4787,19 +4777,6 @@
}
}
-// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
-void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col)
-{
- switch (direction)
- {
- case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return;
- case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return;
- case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return;
- case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return;
- case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings
- }
-}
-
// 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)
{
diff --git a/imgui_draw.cpp b/imgui_draw.cpp
index 2f45c9d..073c1c8 100644
--- a/imgui_draw.cpp
+++ b/imgui_draw.cpp
@@ -6,6 +6,7 @@
// - ImDrawList
// - ImDrawData
// - ImFontAtlas
+// - Internal Render Helpers
// - ImFont
// - Default font data
@@ -2786,8 +2787,51 @@
}
//-----------------------------------------------------------------------------
-// Internals Drawing Helpers
+// Internals Render Helpers
+// (progressively moved from imgui.cpp to here when they are redesigned to stop accessing ImGui global state)
//-----------------------------------------------------------------------------
+// RenderMouseCursor()
+// RenderArrowPointingAt()
+// RenderRectFilledRangeH()
+//-----------------------------------------------------------------------------
+
+void ImGui::RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor)
+{
+ if (mouse_cursor == ImGuiMouseCursor_None)
+ return;
+ IM_ASSERT(mouse_cursor > ImGuiMouseCursor_None && mouse_cursor < ImGuiMouseCursor_COUNT);
+
+ const ImU32 col_shadow = IM_COL32(0, 0, 0, 48);
+ const ImU32 col_border = IM_COL32(0, 0, 0, 255); // Black
+ const ImU32 col_fill = IM_COL32(255, 255, 255, 255); // White
+
+ ImFontAtlas* font_atlas = draw_list->_Data->Font->ContainerAtlas;
+ ImVec2 offset, size, uv[4];
+ if (font_atlas->GetMouseCursorTexData(mouse_cursor, &offset, &size, &uv[0], &uv[2]))
+ {
+ pos -= offset;
+ const ImTextureID tex_id = font_atlas->TexID;
+ draw_list->PushTextureID(tex_id);
+ draw_list->AddImage(tex_id, pos + ImVec2(1,0)*scale, pos + ImVec2(1,0)*scale + size*scale, uv[2], uv[3], col_shadow);
+ draw_list->AddImage(tex_id, pos + ImVec2(2,0)*scale, pos + ImVec2(2,0)*scale + size*scale, uv[2], uv[3], col_shadow);
+ draw_list->AddImage(tex_id, pos, pos + size*scale, uv[2], uv[3], col_border);
+ draw_list->AddImage(tex_id, pos, pos + size*scale, uv[0], uv[1], col_fill);
+ draw_list->PopTextureID();
+ }
+}
+
+// Render an arrow. 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side.
+void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col)
+{
+ switch (direction)
+ {
+ case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return;
+ case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return;
+ case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return;
+ case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return;
+ case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings
+ }
+}
static inline float ImAcos01(float x)
{
diff --git a/imgui_internal.h b/imgui_internal.h
index adf45c3..d6dc79e 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -1166,7 +1166,7 @@
// Render helpers
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
- // NB: All position are in absolute pixels coordinates (never using window coordinates internally)
+ // NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void 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 = ImVec2(0,0), const ImRect* clip_rect = NULL);
@@ -1174,13 +1174,16 @@
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0);
IMGUI_API void RenderArrow(ImVec2 pos, ImGuiDir dir, float scale = 1.0f);
- IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
IMGUI_API void RenderBullet(ImVec2 pos);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz);
IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight
- IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
+ // Render helpers (those functions don't access any ImGui state!)
+ IMGUI_API void RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor = ImGuiMouseCursor_Arrow);
+ IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col);
+ IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding);
+
// Widgets
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);