mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Merge branch 'master' into navigation
# Conflicts: # imgui.cpp
This commit is contained in:
commit
287380261c
4
TODO.txt
4
TODO.txt
@ -30,12 +30,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
!- scrolling: allow immediately effective change of scroll after Begin() if we haven't appended items yet.
|
||||
- scrolling/clipping: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y). (2017-08-20: can't repro)
|
||||
|
||||
- drawlist: move Font, FontSize, FontTexUvWhitePixel inside ImDrawList and make it self-contained (apart from drawing settings?)
|
||||
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
||||
- drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
|
||||
- drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command).
|
||||
- drawlist: avoid passing null (-9999,+9999) rectangle to end-user, instead perhaps pass rectangle based on io.DisplaySize?
|
||||
- drawlist: primtiives/helpers to manipulate vertices post submission, so e.g. a quad/rect can be resized to fit later submitted content, _without_ using the ChannelSplit api
|
||||
- drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally
|
||||
- drawlist: non-AA strokes have gaps between points (#593, #288), especially RenderCheckmark().
|
||||
- drawlist: would be good to be able to deep copy a draw list (ImVector= op?).
|
||||
- drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation.
|
||||
|
80
imgui.cpp
80
imgui.cpp
@ -249,6 +249,8 @@
|
||||
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
|
||||
Also read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2017/12/21 (1.53) - renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags
|
||||
- 2017/12/21 (1.53) - removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags.
|
||||
- 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set.
|
||||
- 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete).
|
||||
- 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete).
|
||||
@ -775,8 +777,8 @@ ImGuiStyle::ImGuiStyle()
|
||||
DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows.
|
||||
DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
|
||||
AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU.
|
||||
AntiAliasedShapes = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
CurveTessellationTol = 1.25f; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
|
||||
ImGui::StyleColorsClassic(this);
|
||||
}
|
||||
@ -952,17 +954,17 @@ int ImStricmp(const char* str1, const char* str2)
|
||||
return d;
|
||||
}
|
||||
|
||||
int ImStrnicmp(const char* str1, const char* str2, int count)
|
||||
int ImStrnicmp(const char* str1, const char* str2, size_t count)
|
||||
{
|
||||
int d = 0;
|
||||
while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
|
||||
return d;
|
||||
}
|
||||
|
||||
void ImStrncpy(char* dst, const char* src, int count)
|
||||
void ImStrncpy(char* dst, const char* src, size_t count)
|
||||
{
|
||||
if (count < 1) return;
|
||||
strncpy(dst, src, (size_t)count);
|
||||
strncpy(dst, src, count);
|
||||
dst[count-1] = 0;
|
||||
}
|
||||
|
||||
@ -1033,7 +1035,7 @@ static const char* ImAtoi(const char* src, int* output)
|
||||
// Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm.
|
||||
// B) When buf==NULL vsnprintf() will return the output size.
|
||||
#ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS
|
||||
int ImFormatString(char* buf, int buf_size, const char* fmt, ...)
|
||||
int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@ -1041,19 +1043,19 @@ int ImFormatString(char* buf, int buf_size, const char* fmt, ...)
|
||||
va_end(args);
|
||||
if (buf == NULL)
|
||||
return w;
|
||||
if (w == -1 || w >= buf_size)
|
||||
w = buf_size - 1;
|
||||
if (w == -1 || w >= (int)buf_size)
|
||||
w = (int)buf_size - 1;
|
||||
buf[w] = 0;
|
||||
return w;
|
||||
}
|
||||
|
||||
int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args)
|
||||
int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
|
||||
{
|
||||
int w = vsnprintf(buf, buf_size, fmt, args);
|
||||
if (buf == NULL)
|
||||
return w;
|
||||
if (w == -1 || w >= buf_size)
|
||||
w = buf_size - 1;
|
||||
if (w == -1 || w >= (int)buf_size)
|
||||
w = (int)buf_size - 1;
|
||||
buf[w] = 0;
|
||||
return w;
|
||||
}
|
||||
@ -1861,7 +1863,7 @@ bool ImGuiListClipper::Step()
|
||||
// ImGuiWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiWindow::ImGuiWindow(const char* name)
|
||||
ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
{
|
||||
Name = ImStrdup(name);
|
||||
ID = ImHash(name, 0);
|
||||
@ -1907,7 +1909,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
|
||||
FontWindowScale = 1.0f;
|
||||
|
||||
DrawList = (ImDrawList*)ImGui::MemAlloc(sizeof(ImDrawList));
|
||||
IM_PLACEMENT_NEW(DrawList) ImDrawList();
|
||||
IM_PLACEMENT_NEW(DrawList) ImDrawList(&context->DrawListSharedData);
|
||||
DrawList->_OwnerName = Name;
|
||||
ParentWindow = NULL;
|
||||
RootWindow = NULL;
|
||||
@ -2575,6 +2577,11 @@ ImDrawList* ImGui::GetOverlayDrawList()
|
||||
return &GImGui->OverlayDrawList;
|
||||
}
|
||||
|
||||
ImDrawListSharedData* ImGui::GetDrawListSharedData()
|
||||
{
|
||||
return &GImGui->DrawListSharedData;
|
||||
}
|
||||
|
||||
// This needs to be called before we submit any widget (aka in or before Begin)
|
||||
void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
|
||||
{
|
||||
@ -3061,6 +3068,8 @@ void ImGui::NewFrame()
|
||||
|
||||
SetCurrentFont(GetDefaultFont());
|
||||
IM_ASSERT(g.Font->IsLoaded());
|
||||
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
|
||||
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
|
||||
|
||||
g.Time += g.IO.DeltaTime;
|
||||
g.FrameCount += 1;
|
||||
@ -3069,6 +3078,7 @@ void ImGui::NewFrame()
|
||||
g.OverlayDrawList.Clear();
|
||||
g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID);
|
||||
g.OverlayDrawList.PushClipRectFullScreen();
|
||||
g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
|
||||
|
||||
// Mark rendering data as invalid to prevent user who may have a handle on it to use it
|
||||
g.RenderDrawData.Valid = false;
|
||||
@ -5043,7 +5053,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
||||
|
||||
// Create window the first time
|
||||
ImGuiWindow* window = (ImGuiWindow*)ImGui::MemAlloc(sizeof(ImGuiWindow));
|
||||
IM_PLACEMENT_NEW(window) ImGuiWindow(name);
|
||||
IM_PLACEMENT_NEW(window) ImGuiWindow(&g, name);
|
||||
window->Flags = flags;
|
||||
g.WindowsById.SetVoidPtr(window->ID, window);
|
||||
|
||||
@ -5371,8 +5381,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->LastFrameActive = current_frame;
|
||||
window->IDStack.resize(1);
|
||||
|
||||
// Clear draw list, setup texture, outer clipping rectangle
|
||||
// Setup draw list and outer clipping rectangle
|
||||
window->DrawList->Clear();
|
||||
window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
|
||||
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
|
||||
ImRect fullscreen_rect(GetVisibleRect());
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
|
||||
@ -5558,11 +5569,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
// Modal window darkens what is behind them
|
||||
if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow())
|
||||
window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio));
|
||||
// Apply focus, new windows appears in front
|
||||
bool want_focus = false;
|
||||
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup))
|
||||
want_focus = true;
|
||||
|
||||
// Navigation windowing (via ImGuiKey_NavWindowing key) shows whole window selected
|
||||
// Draw navigation windowing rectangle (via ImGuiKey_NavWindowing key), shows whole window selected
|
||||
if (g.NavWindowingTarget == window)
|
||||
{
|
||||
ImRect bb = window->Rect();
|
||||
@ -5571,11 +5584,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_HeaderHovered, g.NavWindowingDisplayAlpha), g.Style.WindowRounding);
|
||||
}
|
||||
|
||||
// Apply focus, new windows appears in front
|
||||
bool want_focus = false;
|
||||
if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup))
|
||||
want_focus = true;
|
||||
// Draw modal window background (darkens what is behind them)
|
||||
if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow())
|
||||
window->DrawList->AddRectFilled(fullscreen_rect.Min, fullscreen_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio));
|
||||
|
||||
// Draw window + handle manual resize
|
||||
ImRect title_bar_rect = window->TitleBarRect();
|
||||
@ -6208,7 +6219,11 @@ static void SetCurrentFont(ImFont* font)
|
||||
g.Font = font;
|
||||
g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale;
|
||||
g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
|
||||
g.FontTexUvWhitePixel = g.Font->ContainerAtlas->TexUvWhitePixel;
|
||||
|
||||
ImFontAtlas* atlas = g.Font->ContainerAtlas;
|
||||
g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
|
||||
g.DrawListSharedData.Font = g.Font;
|
||||
g.DrawListSharedData.FontSize = g.FontSize;
|
||||
}
|
||||
|
||||
void ImGui::PushFont(ImFont* font)
|
||||
@ -6794,7 +6809,7 @@ float ImGui::GetFontSize()
|
||||
|
||||
ImVec2 ImGui::GetFontTexUvWhitePixel()
|
||||
{
|
||||
return GImGui->FontTexUvWhitePixel;
|
||||
return GImGui->DrawListSharedData.TexUvWhitePixel;
|
||||
}
|
||||
|
||||
void ImGui::SetWindowFontScale(float scale)
|
||||
@ -11661,7 +11676,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle);
|
||||
ImVec2 uv_white = g.FontTexUvWhitePixel;
|
||||
ImVec2 uv_white = GetFontTexUvWhitePixel();
|
||||
draw_list->PrimReserve(6, 6);
|
||||
draw_list->PrimVtx(tra, uv_white, hue_color32);
|
||||
draw_list->PrimVtx(trb, uv_white, hue_color32);
|
||||
@ -12782,7 +12797,6 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
return;
|
||||
|
||||
ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list
|
||||
overlay_draw_list->PushClipRectFullScreen();
|
||||
int elem_offset = 0;
|
||||
for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
|
||||
{
|
||||
@ -12806,6 +12820,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
}
|
||||
if (!pcmd_node_open)
|
||||
continue;
|
||||
|
||||
// Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
|
||||
ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
|
||||
while (clipper.Step())
|
||||
for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
|
||||
@ -12821,11 +12837,15 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
}
|
||||
ImGui::Selectable(buf, false);
|
||||
if (ImGui::IsItemHovered())
|
||||
overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f, false); // Add triangle without AA, more readable for large-thin triangle
|
||||
{
|
||||
ImDrawListFlags backup_flags = overlay_draw_list->Flags;
|
||||
overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.
|
||||
overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f);
|
||||
overlay_draw_list->Flags = backup_flags;
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
overlay_draw_list->PopClipRect();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
|
34
imgui.h
34
imgui.h
@ -51,6 +51,7 @@ struct ImDrawChannel; // Temporary storage for outputting drawing
|
||||
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call)
|
||||
struct ImDrawData; // All draw command lists required to render the frame
|
||||
struct ImDrawList; // A single draw command list (generally one per window)
|
||||
struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself)
|
||||
struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT)
|
||||
struct ImFont; // Runtime data for a single font within a parent ImFontAtlas
|
||||
struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader
|
||||
@ -80,6 +81,7 @@ typedef int ImGuiNavInput; // enum: an input identifier for navigation
|
||||
typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_
|
||||
typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_
|
||||
typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_
|
||||
typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_
|
||||
typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_
|
||||
typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_
|
||||
typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_
|
||||
@ -471,6 +473,7 @@ namespace ImGui
|
||||
IMGUI_API float GetTime();
|
||||
IMGUI_API int GetFrameCount();
|
||||
IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text
|
||||
IMGUI_API ImDrawListSharedData* GetDrawListSharedData();
|
||||
IMGUI_API const char* GetStyleColorName(ImGuiCol idx);
|
||||
IMGUI_API ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = +0.0f); // utility to find the closest point the last item bounding rectangle edge. useful to visually link items
|
||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
@ -890,8 +893,8 @@ struct ImGuiStyle
|
||||
ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows.
|
||||
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
|
||||
bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU.
|
||||
bool AntiAliasedShapes; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
float CurveTessellationTol; // Tessellation tolerance. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
|
||||
float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
|
||||
ImVec4 Colors[ImGuiCol_COUNT];
|
||||
|
||||
IMGUI_API ImGuiStyle();
|
||||
@ -1368,7 +1371,7 @@ struct ImDrawCmd
|
||||
ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally.
|
||||
void* UserCallbackData; // The draw callback code can access this.
|
||||
|
||||
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = -8192.0f; ClipRect.z = ClipRect.w = +8192.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }
|
||||
ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; }
|
||||
};
|
||||
|
||||
// Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h)
|
||||
@ -1413,21 +1416,28 @@ enum ImDrawCornerFlags_
|
||||
ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience
|
||||
};
|
||||
|
||||
enum ImDrawListFlags_
|
||||
{
|
||||
ImDrawListFlags_AntiAliasedLines = 1 << 0,
|
||||
ImDrawListFlags_AntiAliasedFill = 1 << 1
|
||||
};
|
||||
|
||||
// Draw command list
|
||||
// This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
|
||||
// At the moment, each ImGui window contains its own ImDrawList but they could potentially be merged in the future.
|
||||
// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives.
|
||||
// Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives.
|
||||
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
|
||||
// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well)
|
||||
// Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions).
|
||||
// Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects.
|
||||
struct ImDrawList
|
||||
{
|
||||
// This is what you have to render
|
||||
ImVector<ImDrawCmd> CmdBuffer; // Commands. Typically 1 command = 1 GPU draw call.
|
||||
ImVector<ImDrawCmd> CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback.
|
||||
ImVector<ImDrawIdx> IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those
|
||||
ImVector<ImDrawVert> VtxBuffer; // Vertex buffer.
|
||||
|
||||
// [Internal, used while building lists]
|
||||
ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive.
|
||||
const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context)
|
||||
const char* _OwnerName; // Pointer to owner window's name for debugging
|
||||
unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size
|
||||
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||
@ -1439,7 +1449,7 @@ struct ImDrawList
|
||||
int _ChannelsCount; // [Internal] number of active channels (1+)
|
||||
ImVector<ImDrawChannel> _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
|
||||
|
||||
ImDrawList() { _OwnerName = NULL; Clear(); }
|
||||
ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); }
|
||||
~ImDrawList() { ClearFreeMemory(); }
|
||||
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
|
||||
IMGUI_API void PushClipRectFullScreen();
|
||||
@ -1465,16 +1475,16 @@ struct ImDrawList
|
||||
IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF);
|
||||
IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF);
|
||||
IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All);
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness, bool anti_aliased);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col, bool anti_aliased);
|
||||
IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness);
|
||||
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col);
|
||||
IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
|
||||
|
||||
// Stateful path API, add points then finish with PathFill() or PathStroke()
|
||||
inline void PathClear() { _Path.resize(0); }
|
||||
inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); }
|
||||
inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); }
|
||||
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); }
|
||||
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); }
|
||||
inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); }
|
||||
inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); }
|
||||
IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
|
||||
IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
|
||||
IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
|
||||
|
@ -2021,7 +2021,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
if (ImGui::TreeNode("Rendering"))
|
||||
{
|
||||
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
|
||||
ImGui::Checkbox("Anti-aliased shapes", &style.AntiAliasedShapes);
|
||||
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
|
||||
ImGui::PushItemWidth(100);
|
||||
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f);
|
||||
if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f;
|
||||
|
@ -283,16 +283,34 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawList
|
||||
// ImDrawListData
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const ImVec4 GNullClipRect(-8192.0f, -8192.0f, +8192.0f, +8192.0f); // Large values that are easy to encode in a few bits+shift
|
||||
ImDrawListSharedData::ImDrawListSharedData()
|
||||
{
|
||||
Font = NULL;
|
||||
FontSize = 0.0f;
|
||||
CurveTessellationTol = 0.0f;
|
||||
ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f);
|
||||
|
||||
// Const data
|
||||
for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++)
|
||||
{
|
||||
const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12);
|
||||
CircleVtx12[i] = ImVec2(cosf(a), sinf(a));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImDrawList
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImDrawList::Clear()
|
||||
{
|
||||
CmdBuffer.resize(0);
|
||||
IdxBuffer.resize(0);
|
||||
VtxBuffer.resize(0);
|
||||
Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill;
|
||||
_VtxCurrentIdx = 0;
|
||||
_VtxWritePtr = NULL;
|
||||
_IdxWritePtr = NULL;
|
||||
@ -327,7 +345,7 @@ void ImDrawList::ClearFreeMemory()
|
||||
}
|
||||
|
||||
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
|
||||
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : GNullClipRect)
|
||||
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
|
||||
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL)
|
||||
|
||||
void ImDrawList::AddDrawCmd()
|
||||
@ -418,8 +436,7 @@ void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_
|
||||
|
||||
void ImDrawList::PushClipRectFullScreen()
|
||||
{
|
||||
PushClipRect(ImVec2(GNullClipRect.x, GNullClipRect.y), ImVec2(GNullClipRect.z, GNullClipRect.w));
|
||||
//PushClipRect(GetVisibleRect()); // FIXME-OPT: This would be more correct but we're not supposed to access ImGuiContext from here?
|
||||
PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w));
|
||||
}
|
||||
|
||||
void ImDrawList::PopClipRect()
|
||||
@ -539,7 +556,7 @@ void ImDrawList::PrimReserve(int idx_count, int vtx_count)
|
||||
// Fully unrolled with inline call to keep our debug builds decently fast.
|
||||
void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col)
|
||||
{
|
||||
ImVec2 b(c.x, a.y), d(a.x, c.y), uv(GImGui->FontTexUvWhitePixel);
|
||||
ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel);
|
||||
ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx;
|
||||
_IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2);
|
||||
_IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3);
|
||||
@ -582,21 +599,19 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
|
||||
}
|
||||
|
||||
// TODO: Thickness anti-aliased lines cap are missing their AA fringe.
|
||||
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness, bool anti_aliased)
|
||||
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness)
|
||||
{
|
||||
if (points_count < 2)
|
||||
return;
|
||||
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
anti_aliased &= GImGui->Style.AntiAliasedLines;
|
||||
//if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
|
||||
int count = points_count;
|
||||
if (!closed)
|
||||
count = points_count-1;
|
||||
|
||||
const bool thick_line = thickness > 1.0f;
|
||||
if (anti_aliased)
|
||||
if (Flags & ImDrawListFlags_AntiAliasedLines)
|
||||
{
|
||||
// Anti-aliased stroke
|
||||
const float AA_SIZE = 1.0f;
|
||||
@ -763,13 +778,11 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
}
|
||||
}
|
||||
|
||||
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col, bool anti_aliased)
|
||||
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
|
||||
{
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
anti_aliased &= GImGui->Style.AntiAliasedShapes;
|
||||
//if (ImGui::GetIO().KeyCtrl) anti_aliased = false; // Debug
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
|
||||
if (anti_aliased)
|
||||
if (Flags & ImDrawListFlags_AntiAliasedFill)
|
||||
{
|
||||
// Anti-aliased Fill
|
||||
const float AA_SIZE = 1.0f;
|
||||
@ -848,20 +861,6 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
||||
|
||||
void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12)
|
||||
{
|
||||
static ImVec2 circle_vtx[12];
|
||||
static bool circle_vtx_builds = false;
|
||||
const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx);
|
||||
if (!circle_vtx_builds)
|
||||
{
|
||||
for (int i = 0; i < circle_vtx_count; i++)
|
||||
{
|
||||
const float a = ((float)i / (float)circle_vtx_count) * 2*IM_PI;
|
||||
circle_vtx[i].x = cosf(a);
|
||||
circle_vtx[i].y = sinf(a);
|
||||
}
|
||||
circle_vtx_builds = true;
|
||||
}
|
||||
|
||||
if (radius == 0.0f || a_min_of_12 > a_max_of_12)
|
||||
{
|
||||
_Path.push_back(centre);
|
||||
@ -870,7 +869,7 @@ void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_
|
||||
_Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1));
|
||||
for (int a = a_min_of_12; a <= a_max_of_12; a++)
|
||||
{
|
||||
const ImVec2& c = circle_vtx[a % circle_vtx_count];
|
||||
const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)];
|
||||
_Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius));
|
||||
}
|
||||
}
|
||||
@ -922,7 +921,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV
|
||||
if (num_segments == 0)
|
||||
{
|
||||
// Auto-tessellated
|
||||
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, GImGui->Style.CurveTessellationTol, 0);
|
||||
PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1004,7 +1003,7 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32
|
||||
if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0)
|
||||
return;
|
||||
|
||||
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
|
||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||
PrimReserve(6, 4);
|
||||
PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2));
|
||||
PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3));
|
||||
@ -1100,12 +1099,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
|
||||
if (text_begin == text_end)
|
||||
return;
|
||||
|
||||
// IMPORTANT: This is one of the few instance of breaking the encapsulation of ImDrawList, as we pull this from ImGui state, but it is just SO useful.
|
||||
// Might just move Font/FontSize to ImDrawList?
|
||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||
if (font == NULL)
|
||||
font = GImGui->Font;
|
||||
font = _Data->Font;
|
||||
if (font_size == 0.0f)
|
||||
font_size = GImGui->FontSize;
|
||||
font_size = _Data->FontSize;
|
||||
|
||||
IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
|
||||
|
||||
|
@ -105,15 +105,15 @@ IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec
|
||||
|
||||
// Helpers: String
|
||||
IMGUI_API int ImStricmp(const char* str1, const char* str2);
|
||||
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count);
|
||||
IMGUI_API void ImStrncpy(char* dst, const char* src, int count);
|
||||
IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count);
|
||||
IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count);
|
||||
IMGUI_API char* ImStrdup(const char* str);
|
||||
IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c);
|
||||
IMGUI_API int ImStrlenW(const ImWchar* str);
|
||||
IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line
|
||||
IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
|
||||
IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
|
||||
IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
|
||||
// Helpers: Math
|
||||
// We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined)
|
||||
@ -472,6 +472,21 @@ struct ImGuiColumnsSet
|
||||
}
|
||||
};
|
||||
|
||||
struct ImDrawListSharedData
|
||||
{
|
||||
ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas
|
||||
ImFont* Font; // Current/default font (optional, for simplified AddText overload)
|
||||
float FontSize; // Current/default font size (optional, for simplified AddText overload)
|
||||
float CurveTessellationTol;
|
||||
ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
|
||||
|
||||
// Const data
|
||||
// FIXME: Bake rounded corners fill/borders in atlas
|
||||
ImVec2 CircleVtx12[12];
|
||||
|
||||
ImDrawListSharedData();
|
||||
};
|
||||
|
||||
// Main state for ImGui
|
||||
struct ImGuiContext
|
||||
{
|
||||
@ -481,7 +496,7 @@ struct ImGuiContext
|
||||
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
||||
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
||||
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
|
||||
ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel
|
||||
ImDrawListSharedData DrawListSharedData;
|
||||
|
||||
float Time;
|
||||
int FrameCount;
|
||||
@ -630,12 +645,11 @@ struct ImGuiContext
|
||||
int WantTextInputNextFrame;
|
||||
char TempBuffer[1024*3+1]; // temporary text buffer
|
||||
|
||||
ImGuiContext()
|
||||
ImGuiContext() : OverlayDrawList(NULL)
|
||||
{
|
||||
Initialized = false;
|
||||
Font = NULL;
|
||||
FontSize = FontBaseSize = 0.0f;
|
||||
FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
|
||||
|
||||
Time = 0.0f;
|
||||
FrameCount = 0;
|
||||
@ -721,6 +735,7 @@ struct ImGuiContext
|
||||
OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f);
|
||||
|
||||
ModalWindowDarkeningRatio = 0.0f;
|
||||
OverlayDrawList._Data = &DrawListSharedData;
|
||||
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
memset(MouseCursorData, 0, sizeof(MouseCursorData));
|
||||
@ -904,7 +919,7 @@ struct IMGUI_API ImGuiWindow
|
||||
int FocusIdxTabRequestNext; // "
|
||||
|
||||
public:
|
||||
ImGuiWindow(const char* name);
|
||||
ImGuiWindow(ImGuiContext* context, const char* name);
|
||||
~ImGuiWindow();
|
||||
|
||||
ImGuiID GetID(const char* str, const char* str_end = NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user