Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui.h
#	imgui_internal.h
docking
omar 6 years ago
commit 8414c0bb09

@ -102,9 +102,12 @@ Breaking Changes:
- Renamed ColorEdit/ColorPicker's ImGuiColorEditFlags_RGB/_HSV/_HEX flags to respectively - Renamed ColorEdit/ColorPicker's ImGuiColorEditFlags_RGB/_HSV/_HEX flags to respectively
ImGuiColorEditFlags_DisplayRGB/_DisplayHSV/_DisplayHex. This is anticipation of adding new ImGuiColorEditFlags_DisplayRGB/_DisplayHSV/_DisplayHex. This is anticipation of adding new
flags to ColorEdit/ColorPicker functions which would make those ambiguous. (#2384) [@haldean] flags to ColorEdit/ColorPicker functions which would make those ambiguous. (#2384) [@haldean]
- Renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete). (#2391)
Other Changes: Other Changes:
- Added GetBackgroundDrawList() helper to quickly get access to a ImDrawList that will be rendered
behind every other windows. (#2391)
- Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer. - Nav: Fixed a tap on AltGR (e.g. German keyboard) from navigating to the menu layer.
- DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types. - DragScalar, InputScalar, SliderScalar: Added support for u8/s8/u16/s16 data types.
We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011) We are reusing function instances for larger types to reduce code size. (#643, #320, #708, #1011)
@ -130,6 +133,7 @@ Other Changes:
tree depth instead of a relative one. tree depth instead of a relative one.
- Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##". - Log/Capture: Fixed CollapsingHeader trailing ascii representation being "#" instead of "##".
- Misc: Asserting in NewFrame() if style.WindowMinSize is zero or smaller than (1.0f,1.0f). - Misc: Asserting in NewFrame() if style.WindowMinSize is zero or smaller than (1.0f,1.0f).
- Demo: Using GetBackgroundDrawList() and GetForegroundDrawList() in "Custom Rendering" demo.
- Examples: OpenGL: Fix to be able to run on ES 2.0 / WebGL 1.0. [@rmitton, @gabrielcuvillier] - Examples: OpenGL: Fix to be able to run on ES 2.0 / WebGL 1.0. [@rmitton, @gabrielcuvillier]
- Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN - Examples: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN
even if the OpenGL headers/loader happens to define the value. (#2366, #2186) even if the OpenGL headers/loader happens to define the value. (#2366, #2186)

@ -375,6 +375,7 @@ CODE
- 2018/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api. - 2018/XX/XX (1.XX) - Moved IME support functions from io.ImeSetInputScreenPosFn, io.ImeWindowHandle to the PlatformIO api.
- 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
- 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete). - 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value! - 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
- 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). - 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
@ -885,7 +886,8 @@ CODE
A: - You can create a dummy window. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags. A: - You can create a dummy window. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags.
(The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse) (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
- You can call ImGui::GetOverlayDrawList() and use this draw list to display contents over every other imgui windows (1 overlay per viewport). - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
contents behind or over every other imgui windows. (1 bg/fg drawlist per viewport)
- You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data. your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
@ -3133,33 +3135,51 @@ int ImGui::GetFrameCount()
return GImGui->FrameCount; return GImGui->FrameCount;
} }
ImDrawList* ImGui::GetOverlayDrawList(ImGuiViewport* viewport_public) static ImDrawList* GetViewportDrawList(ImGuiViewportP* viewport, size_t drawlist_no, const char* drawlist_name)
{ {
// Create the draw list on demand, because it is not frequently used for all viewports // Create the draw list on demand, because they are not frequently used for all viewports
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiViewportP* viewport = (ImGuiViewportP*)viewport_public; IM_ASSERT(drawlist_no >= 0 && drawlist_no < IM_ARRAYSIZE(viewport->DrawLists));
if (viewport->OverlayDrawList == NULL) ImDrawList* draw_list = viewport->DrawLists[drawlist_no];
if (draw_list == NULL)
{ {
viewport->OverlayDrawList = IM_NEW(ImDrawList)(&g.DrawListSharedData); draw_list = IM_NEW(ImDrawList)(&g.DrawListSharedData);
viewport->OverlayDrawList->_OwnerName = "##Overlay"; draw_list->_OwnerName = drawlist_name;
viewport->DrawLists[drawlist_no] = draw_list;
} }
// Our ImDrawList system requires that there is always a command // Our ImDrawList system requires that there is always a command
if (viewport->LastFrameOverlayDrawList != g.FrameCount) if (viewport->LastFrameDrawLists[drawlist_no] != g.FrameCount)
{ {
viewport->OverlayDrawList->Clear(); draw_list->Clear();
viewport->OverlayDrawList->PushTextureID(g.IO.Fonts->TexID); draw_list->PushTextureID(g.IO.Fonts->TexID);
viewport->OverlayDrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false); draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
viewport->OverlayDrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); draw_list->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
viewport->LastFrameOverlayDrawList = g.FrameCount; viewport->LastFrameDrawLists[drawlist_no] = g.FrameCount;
} }
return viewport->OverlayDrawList; return draw_list;
} }
ImDrawList* ImGui::GetOverlayDrawList() ImDrawList* ImGui::GetBackgroundDrawList(ImGuiViewport* viewport)
{
return GetViewportDrawList((ImGuiViewportP*)viewport, 0, "##Background");
}
ImDrawList* ImGui::GetBackgroundDrawList()
{
ImGuiWindow* window = GImGui->CurrentWindow;
return GetBackgroundDrawList(window->Viewport);
}
ImDrawList* ImGui::GetForegroundDrawList(ImGuiViewport* viewport)
{
return GetViewportDrawList((ImGuiViewportP*)viewport, 1, "##Foreground");
}
ImDrawList* ImGui::GetForegroundDrawList()
{ {
ImGuiWindow* window = GImGui->CurrentWindow; ImGuiWindow* window = GImGui->CurrentWindow;
return GetOverlayDrawList(window->Viewport); return GetForegroundDrawList(window->Viewport);
} }
ImDrawListSharedData* ImGui::GetDrawListSharedData() ImDrawListSharedData* ImGui::GetDrawListSharedData()
@ -3589,7 +3609,6 @@ void ImGui::NewFrame()
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, virtual_space_max.x, virtual_space_max.y); g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, virtual_space_max.x, virtual_space_max.y);
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
// Setup Overlay draw list for the viewport.
// Mark rendering data as invalid to prevent user who may have a handle on it to use it. // Mark rendering data as invalid to prevent user who may have a handle on it to use it.
for (int n = 0; n < g.Viewports.Size; n++) for (int n = 0; n < g.Viewports.Size; n++)
{ {
@ -3985,7 +4004,7 @@ static void ImGui::EndFrameDrawDimmedBackgrounds()
continue; continue;
if (g.NavWindowingTargetAnim && viewport == g.NavWindowingTargetAnim->Viewport) if (g.NavWindowingTargetAnim && viewport == g.NavWindowingTargetAnim->Viewport)
continue; continue;
ImDrawList* draw_list = GetOverlayDrawList(viewport); ImDrawList* draw_list = GetForegroundDrawList(viewport);
const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio); const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio);
draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col); draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col);
} }
@ -4131,7 +4150,13 @@ void ImGui::Render()
// Gather ImDrawList to render (for each active window) // Gather ImDrawList to render (for each active window)
g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0; g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
for (int n = 0; n != g.Viewports.Size; n++) for (int n = 0; n != g.Viewports.Size; n++)
g.Viewports[n]->DrawDataBuilder.Clear(); {
ImGuiViewportP* viewport = g.Viewports[n];
viewport->DrawDataBuilder.Clear();
if (viewport->DrawLists[0] != NULL)
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport));
}
ImGuiWindow* windows_to_render_front_most[2]; 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[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL;
windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL; windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL;
@ -4155,8 +4180,8 @@ void ImGui::Render()
{ {
ImGuiViewportP* viewport = g.Viewports[n]; ImGuiViewportP* viewport = g.Viewports[n];
viewport->DrawDataBuilder.FlattenIntoSingleLayer(); viewport->DrawDataBuilder.FlattenIntoSingleLayer();
if (viewport->OverlayDrawList != NULL) if (viewport->DrawLists[1] != NULL)
AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetOverlayDrawList(viewport)); AddDrawListToDrawData(&viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport));
SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]); SetupViewportDrawData(viewport, &viewport->DrawDataBuilder.Layers[0]);
g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount; g.IO.MetricsRenderVertices += viewport->DrawData->TotalVtxCount;
g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount; g.IO.MetricsRenderIndices += viewport->DrawData->TotalIdxCount;
@ -5055,7 +5080,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
bool hovered, held; bool hovered, held;
ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
//GetOverlayDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
if (hovered || held) if (hovered || held)
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
@ -5080,7 +5105,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
bool hovered, held; bool hovered, held;
ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS);
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);
//GetOverlayDrawList(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
{ {
g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
@ -7620,8 +7645,8 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button)
ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy) ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy)
{ {
ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size);
//GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
//GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); //GetForegroundDrawList()->AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
// Combo Box policy (we want a connecting edge) // Combo Box policy (we want a connecting edge)
if (policy == ImGuiPopupPositionPolicy_ComboBox) if (policy == ImGuiPopupPositionPolicy_ComboBox)
@ -8544,7 +8569,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max)) if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max))
{ {
ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
ImDrawList* draw_list = ImGui::GetOverlayDrawList(window); ImDrawList* draw_list = ImGui::GetForegroundDrawList(window);
draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100)); draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
draw_list->AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150)); draw_list->AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150));
@ -8556,7 +8581,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
if (quadrant == g.NavMoveDir) if (quadrant == g.NavMoveDir)
{ {
ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
ImDrawList* draw_list = ImGui::GetOverlayDrawList(window); ImDrawList* draw_list = ImGui::GetForegroundDrawList(window);
draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf);
} }
@ -8862,7 +8887,7 @@ ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInput
static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect) static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect)
{ {
ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1)); ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1));
//GetOverlayDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG] //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG]
if (window_rect.Contains(item_rect)) if (window_rect.Contains(item_rect))
return; return;
@ -9152,11 +9177,15 @@ static void ImGui::NavUpdate()
g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
//g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
g.NavScoringCount = 0; g.NavScoringCount = 0;
#if IMGUI_DEBUG_NAV_RECTS #if IMGUI_DEBUG_NAV_RECTS
if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) GetOverlayDrawList(g.NavWindow)->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] if (g.NavWindow)
if (g.NavWindow) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); GetOverlayDrawList(g.NavWindow)->AddCircleFilled(p, 3.0f, col); GetOverlayDrawList(g.NavWindow)->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } {
ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG]
if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255, 0, 255, 255) : IM_COL32(255, 0, 0, 255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8, -4), col, buf); }
}
#endif #endif
} }
@ -12309,9 +12338,9 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
// In case the two windows involved are on different viewports, we will draw the overlay on each of them. // In case the two windows involved are on different viewports, we will draw the overlay on each of them.
int overlay_draw_lists_count = 0; int overlay_draw_lists_count = 0;
ImDrawList* overlay_draw_lists[2]; ImDrawList* overlay_draw_lists[2];
overlay_draw_lists[overlay_draw_lists_count++] = GetOverlayDrawList(host_window->Viewport); overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(host_window->Viewport);
if (host_window->Viewport != root_payload->Viewport && !is_transparent_payload) if (host_window->Viewport != root_payload->Viewport && !is_transparent_payload)
overlay_draw_lists[overlay_draw_lists_count++] = GetOverlayDrawList(root_payload->Viewport); overlay_draw_lists[overlay_draw_lists_count++] = GetForegroundDrawList(root_payload->Viewport);
// Draw main preview rectangle // Draw main preview rectangle
const ImU32 overlay_col_tabs = GetColorU32(ImGuiCol_TabActive); const ImU32 overlay_col_tabs = GetColorU32(ImGuiCol_TabActive);
@ -12586,7 +12615,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node)
bb.Max = child_1->Pos; bb.Max = child_1->Pos;
bb.Min[axis] += child_0->Size[axis]; bb.Min[axis] += child_0->Size[axis];
bb.Max[axis ^ 1] += child_1->Size[axis ^ 1]; bb.Max[axis ^ 1] += child_1->Size[axis ^ 1];
//if (g.IO.KeyCtrl) GetOverlayDrawList(g.CurrentWindow->Viewport)->AddRect(bb.Min, bb.Max, IM_COL32(255,0,255,255)); //if (g.IO.KeyCtrl) GetForegroundDrawList(g.CurrentWindow->Viewport)->AddRect(bb.Min, bb.Max, IM_COL32(255,0,255,255));
if (node->Flags & ImGuiDockNodeFlags_NoResize) if (node->Flags & ImGuiDockNodeFlags_NoResize)
{ {
@ -13830,9 +13859,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return; return;
} }
ImDrawList* overlay_draw_list = viewport ? GetOverlayDrawList(viewport) : NULL; // Render additional visuals into the top-most draw list ImDrawList* fg_draw_list = viewport ? GetForegroundDrawList(viewport) : NULL; // Render additional visuals into the top-most draw list
if (window && overlay_draw_list && ImGui::IsItemHovered()) if (window && fg_draw_list && ImGui::IsItemHovered())
overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255));
if (!node_open) if (!node_open)
return; return;
@ -13848,14 +13877,14 @@ void ImGui::ShowMetricsWindow(bool* p_open)
} }
ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
if (show_draw_cmd_clip_rects && overlay_draw_list && ImGui::IsItemHovered()) if (show_draw_cmd_clip_rects && fg_draw_list && ImGui::IsItemHovered())
{ {
ImRect clip_rect = pcmd->ClipRect; ImRect clip_rect = pcmd->ClipRect;
ImRect vtxs_rect; ImRect vtxs_rect;
for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255)); clip_rect.Floor(); fg_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255));
vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255)); vtxs_rect.Floor(); fg_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255));
} }
if (!pcmd_node_open) if (!pcmd_node_open)
continue; continue;
@ -13877,12 +13906,12 @@ void ImGui::ShowMetricsWindow(bool* p_open)
(n == 0) ? "idx" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); (n == 0) ? "idx" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
} }
ImGui::Selectable(buf, false); ImGui::Selectable(buf, false);
if (overlay_draw_list && ImGui::IsItemHovered()) if (fg_draw_list && ImGui::IsItemHovered())
{ {
ImDrawListFlags backup_flags = overlay_draw_list->Flags; ImDrawListFlags backup_flags = fg_draw_list->Flags;
overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. fg_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); fg_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f);
overlay_draw_list->Flags = backup_flags; fg_draw_list->Flags = backup_flags;
} }
} }
ImGui::TreePop(); ImGui::TreePop();
@ -14033,11 +14062,10 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGuiWindow* window = g.Windows[n]; ImGuiWindow* window = g.Windows[n];
if (!window->WasActive || ((window->Flags & ImGuiWindowFlags_ChildWindow) && window->DockNode == NULL)) if (!window->WasActive || ((window->Flags & ImGuiWindowFlags_ChildWindow) && window->DockNode == NULL))
continue; continue;
char buf[64] = ""; char buf[64] = "";
char* p = buf; char* p = buf;
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Order: %d\n", window->BeginOrderWithinContext);
ImDrawList* overlay_draw_list = GetOverlayDrawList(window->Viewport); ImDrawList* overlay_draw_list = GetForegroundDrawList(window->Viewport);
overlay_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255)); overlay_draw_list->AddRectFilled(window->Pos - ImVec2(1, 1), window->Pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
overlay_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf); overlay_draw_list->AddText(NULL, 0.0f, window->Pos, IM_COL32(255, 255, 255, 255), buf);
} }
@ -14177,7 +14205,7 @@ void ImGui::ShowDockingDebug()
continue; continue;
char buf[64] = ""; char buf[64] = "";
char* p = buf; char* p = buf;
ImDrawList* overlay_draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport()); ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode ? " *CentralNode*" : ""); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode ? " *CentralNode*" : "");
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y);
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y);

@ -652,9 +652,11 @@ namespace ImGui
IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame. IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame.
IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame. IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame.
IMGUI_API ImDrawList* GetOverlayDrawList(); // get overlay draw list for the viewport associated to the current window. this draw list will be the last rendered. useful to quickly draw overlays shapes/text. IMGUI_API ImDrawList* GetBackgroundDrawList(); // get background draw list for the viewport associated to the current window. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
IMGUI_API ImDrawList* GetOverlayDrawList(ImGuiViewport* viewport); // get overlay draw list for the given viewport. IMGUI_API ImDrawList* GetForegroundDrawList(); // get foreground draw list for the viewport associated to the current window. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances IMGUI_API ImDrawList* GetBackgroundDrawList(ImGuiViewport* viewport); // get background draw list for the given viewport. this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
IMGUI_API ImDrawList* GetForegroundDrawList(ImGuiViewport* viewport); // get foreground draw list for the given viewport. this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances.
IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.). IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.).
IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
IMGUI_API ImGuiStorage* GetStateStorage(); IMGUI_API ImGuiStorage* GetStateStorage();
@ -1589,6 +1591,8 @@ struct ImGuiWindowClass
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.69 (from Mar 2019)
static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); }
// OBSOLETED in 1.66 (from Sep 2018) // OBSOLETED in 1.66 (from Sep 2018)
static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); } static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); }
// OBSOLETED in 1.63 (between Aug 2018 and Sept 2018) // OBSOLETED in 1.63 (between Aug 2018 and Sept 2018)

@ -4059,97 +4059,121 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// In this example we are not using the maths operators! // In this example we are not using the maths operators!
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Primitives if (ImGui::BeginTabBar("##TabBar"))
ImGui::Text("Primitives");
static float sz = 36.0f;
static float thickness = 4.0f;
static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
ImGui::ColorEdit4("Color", &col.x);
{ {
const ImVec2 p = ImGui::GetCursorScreenPos(); // Primitives
const ImU32 col32 = ImColor(col); if (ImGui::BeginTabItem("Primitives"))
float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
for (int n = 0; n < 2; n++)
{ {
// First line uses a thickness of 1.0, second line uses the configurable thickness static float sz = 36.0f;
float th = (n == 0) ? 1.0f : thickness; static float thickness = 4.0f;
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6, th); x += sz+spacing; // Hexagon static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, th); x += sz+spacing; // Circle ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, th); x += sz+spacing; ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, th); x += sz+spacing; ImGui::ColorEdit4("Color", &col.x);
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, th); x += sz+spacing; const ImVec2 p = ImGui::GetCursorScreenPos();
draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, th); x += sz+spacing; const ImU32 col32 = ImColor(col);
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, th); x += sz+spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) for (int n = 0; n < 2; n++)
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, th); x += sz+spacing; // Diagonal line {
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, th); // First line uses a thickness of 1.0, second line uses the configurable thickness
x = p.x + 4; float th = (n == 0) ? 1.0f : thickness;
y += sz+spacing; draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 6, th); x += sz + spacing; // Hexagon
} draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 20, th); x += sz + spacing; // Circle
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6); x += sz+spacing; // Hexagon draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 0.0f, ImDrawCornerFlags_All, th); x += sz + spacing;
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; // Circle draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_All, th); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight, th); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; draw_list->AddTriangle(ImVec2(x + sz*0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32, th); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing; draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col32, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col32, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+thickness), col32); x += sz+spacing; // Horizontal line (faster than AddLine, but only handle integer thickness) draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, th); x += sz + spacing; // Diagonal line
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+thickness, y+sz), col32); x += spacing+spacing; // Vertical line (faster than AddLine, but only handle integer thickness) draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz*1.3f, y + sz*0.3f), ImVec2(x + sz - sz*1.3f, y + sz - sz*0.3f), ImVec2(x + sz, y + sz), col32, th);
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+1, y+1), col32); x += sz; // Pixel (faster than AddLine) x = p.x + 4;
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), IM_COL32(0,0,0,255), IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255)); y += sz + spacing;
ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); }
} draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 6); x += sz + spacing; // Hexagon
ImGui::Separator(); draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 32); x += sz + spacing; // Circle
{ draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32); x += sz + spacing;
static ImVector<ImVec2> points; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f); x += sz + spacing;
static bool adding_line = false; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight); x += sz + spacing;
ImGui::Text("Canvas example"); draw_list->AddTriangleFilled(ImVec2(x + sz*0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32); x += sz + spacing;
if (ImGui::Button("Clear")) points.clear(); draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col32); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col32); x += spacing + spacing; // Vertical line (faster than AddLine, but only handle integer thickness)
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo"); draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col32); x += sz; // Pixel (faster than AddLine)
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() ImGui::Dummy(ImVec2((sz + spacing) * 8, (sz + spacing) * 3));
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). ImGui::EndTabItem();
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255));
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size);
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_in_canvas);
if (!ImGui::IsMouseDown(0))
adding_line = adding_preview = false;
} }
if (ImGui::IsItemHovered())
if (ImGui::BeginTabItem("Canvas"))
{ {
if (!adding_line && ImGui::IsMouseClicked(0)) static ImVector<ImVec2> points;
static bool adding_line = false;
if (ImGui::Button("Clear")) points.clear();
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255));
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size);
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (adding_line)
{ {
adding_preview = true;
points.push_back(mouse_pos_in_canvas); points.push_back(mouse_pos_in_canvas);
adding_line = true; if (!ImGui::IsMouseDown(0))
adding_line = adding_preview = false;
} }
if (ImGui::IsMouseClicked(1) && !points.empty()) if (ImGui::IsItemHovered())
{ {
adding_line = adding_preview = false; if (!adding_line && ImGui::IsMouseClicked(0))
points.pop_back(); {
points.pop_back(); points.push_back(mouse_pos_in_canvas);
adding_line = true;
}
if (ImGui::IsMouseClicked(1) && !points.empty())
{
adding_line = adding_preview = false;
points.pop_back();
points.pop_back();
}
} }
draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
draw_list->PopClipRect();
if (adding_preview)
points.pop_back();
ImGui::EndTabItem();
} }
draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2) if (ImGui::BeginTabItem("BG/FG draw lists"))
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); {
draw_list->PopClipRect(); static bool draw_bg = true;
if (adding_preview) static bool draw_fg = true;
points.pop_back(); ImGui::Checkbox("Draw in Background draw list", &draw_bg);
ImGui::Checkbox("Draw in Foreground draw list", &draw_fg);
ImVec2 window_pos = ImGui::GetWindowPos();
ImVec2 window_size = ImGui::GetWindowSize();
ImVec2 window_center = ImVec2(window_pos.x + window_size.x * 0.5f, window_pos.y + window_size.y * 0.5f);
if (draw_bg)
ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 32, 10);
if (draw_fg)
ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 32, 10);
ImGui::EndTabItem();
}
ImGui::EndTabBar();
} }
ImGui::End(); ImGui::End();
} }

@ -2976,7 +2976,7 @@ void ImGui::RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cu
if (!viewport->GetRect().Overlaps(ImRect(pos, pos + ImVec2(size.x + 2, size.y + 2) * scale))) if (!viewport->GetRect().Overlaps(ImRect(pos, pos + ImVec2(size.x + 2, size.y + 2) * scale)))
continue; continue;
ImDrawList* draw_list = GetOverlayDrawList(viewport); ImDrawList* draw_list = GetForegroundDrawList(viewport);
draw_list->PushTextureID(tex_id); 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(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 + ImVec2(2,0)*scale, pos + ImVec2(2,0)*scale + size*scale, uv[2], uv[3], col_shadow);

@ -737,7 +737,7 @@ struct ImGuiViewportP : public ImGuiViewport
{ {
int Idx; int Idx;
int LastFrameActive; // Last frame number this viewport was activated by a window int LastFrameActive; // Last frame number this viewport was activated by a window
int LastFrameOverlayDrawList; int LastFrameDrawLists[2]; // Last frame number the background (0) and foreground (1) draw lists were used
int LastFrontMostStampCount; // Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order int LastFrontMostStampCount; // Last stamp number from when a window hosted by this viewport was made front-most (by comparing this value between two viewport we have an implicit viewport z-order
ImGuiID LastNameHash; ImGuiID LastNameHash;
ImVec2 LastPos; ImVec2 LastPos;
@ -747,15 +747,15 @@ struct ImGuiViewportP : public ImGuiViewport
bool PlatformWindowCreated; bool PlatformWindowCreated;
bool PlatformWindowMinimized; // When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport bool PlatformWindowMinimized; // When minimized we tend to avoid using the viewport pos/size for clipping window or testing if they are contained in the viewport
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set) ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
ImDrawList* OverlayDrawList; // For convenience, a draw list we can render to that's always rendered last (we use it to draw software mouse cursor when io.MouseDrawCursor is set) ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
ImDrawData DrawDataP; ImDrawData DrawDataP;
ImDrawDataBuilder DrawDataBuilder; ImDrawDataBuilder DrawDataBuilder;
ImVec2 LastPlatformPos; ImVec2 LastPlatformPos;
ImVec2 LastPlatformSize; ImVec2 LastPlatformSize;
ImVec2 LastRendererSize; ImVec2 LastRendererSize;
ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = PlatformWindowMinimized = false; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameDrawLists[0] = LastFrameDrawLists[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = PlatformWindowMinimized = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
~ImGuiViewportP() { if (OverlayDrawList) IM_DELETE(OverlayDrawList); } ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } ImVec2 GetCenter() const { return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); }
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
@ -1547,7 +1547,7 @@ namespace ImGui
IMGUI_API void SetCurrentFont(ImFont* font); IMGUI_API void SetCurrentFont(ImFont* font);
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
inline ImDrawList* GetOverlayDrawList(ImGuiWindow* window) { return GetOverlayDrawList(window->Viewport); } inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); }
// Init // Init
IMGUI_API void Initialize(ImGuiContext* context); IMGUI_API void Initialize(ImGuiContext* context);

@ -6755,7 +6755,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
{ {
// Enlarge tab display when hovering // Enlarge tab display when hovering
bb.Max.x = bb.Min.x + (float)(int)ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f)); bb.Max.x = bb.Min.x + (float)(int)ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f));
display_draw_list = GetOverlayDrawList(window); display_draw_list = GetForegroundDrawList(window);
TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive)); TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
} }
#endif #endif

Loading…
Cancel
Save