mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Merge branch 'master' into viewport
# Conflicts: # imgui.cpp
This commit is contained in:
		
							
								
								
									
										611
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										611
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -53,6 +53,7 @@ CODE | ||||
| - ImGuiTextFilter | ||||
| - ImGuiTextBuffer | ||||
| - ImGuiListClipper | ||||
| - Render Helpers | ||||
| - Main Code (most of the code! lots of stuff, needs tidying up) | ||||
| - Tooltips | ||||
| - Popups | ||||
| @@ -2075,6 +2076,226 @@ bool ImGuiListClipper::Step() | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // RENDER HELPERS | ||||
| // Those [Internal] functions are a terrible mess - their signature and behavior will change. | ||||
| // Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state. | ||||
| //----------------------------------------------------------------------------- | ||||
|  | ||||
| const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) | ||||
| { | ||||
|     const char* text_display_end = text; | ||||
|     if (!text_end) | ||||
|         text_end = (const char*)-1; | ||||
|  | ||||
|     while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) | ||||
|         text_display_end++; | ||||
|     return text_display_end; | ||||
| } | ||||
|  | ||||
| // Internal ImGui functions to render text | ||||
| // RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() | ||||
| void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end; | ||||
|     if (hide_text_after_hash) | ||||
|     { | ||||
|         text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!text_end) | ||||
|             text_end = text + strlen(text); // FIXME-OPT | ||||
|         text_display_end = text_end; | ||||
|     } | ||||
|  | ||||
|     if (text != text_display_end) | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); | ||||
|         if (g.LogEnabled) | ||||
|             LogRenderedText(&pos, text, text_display_end); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     if (!text_end) | ||||
|         text_end = text + strlen(text); // FIXME-OPT | ||||
|  | ||||
|     if (text != text_end) | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); | ||||
|         if (g.LogEnabled) | ||||
|             LogRenderedText(&pos, text, text_end); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Default clip_rect uses (pos_min,pos_max) | ||||
| // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) | ||||
| void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) | ||||
| { | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     const int text_len = (int)(text_display_end - text); | ||||
|     if (text_len == 0) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     // Perform CPU side clipping for single clipped element to avoid using scissor state | ||||
|     ImVec2 pos = pos_min; | ||||
|     const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); | ||||
|  | ||||
|     const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min; | ||||
|     const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max; | ||||
|     bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); | ||||
|     if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min | ||||
|         need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); | ||||
|  | ||||
|     // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. | ||||
|     if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); | ||||
|     if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); | ||||
|  | ||||
|     // Render | ||||
|     if (need_clipping) | ||||
|     { | ||||
|         ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); | ||||
|     } | ||||
|     if (g.LogEnabled) | ||||
|         LogRenderedText(&pos, text, text_display_end); | ||||
| } | ||||
|  | ||||
| // Render a rectangle shaped with optional rounding and borders | ||||
| void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); | ||||
|     const float border_size = g.Style.FrameBorderSize; | ||||
|     if (border && border_size > 0.0f) | ||||
|     { | ||||
|         window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); | ||||
|         window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     const float border_size = g.Style.FrameBorderSize; | ||||
|     if (border_size > 0.0f) | ||||
|     { | ||||
|         window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); | ||||
|         window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state | ||||
| void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     const float h = g.FontSize * 1.00f; | ||||
|     float r = h * 0.40f * scale; | ||||
|     ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale); | ||||
|  | ||||
|     ImVec2 a, b, c; | ||||
|     switch (dir) | ||||
|     { | ||||
|     case ImGuiDir_Up: | ||||
|     case ImGuiDir_Down: | ||||
|         if (dir == ImGuiDir_Up) r = -r; | ||||
|         a = ImVec2(+0.000f,+0.750f) * r; | ||||
|         b = ImVec2(-0.866f,-0.750f) * r; | ||||
|         c = ImVec2(+0.866f,-0.750f) * r; | ||||
|         break; | ||||
|     case ImGuiDir_Left: | ||||
|     case ImGuiDir_Right: | ||||
|         if (dir == ImGuiDir_Left) r = -r; | ||||
|         a = ImVec2(+0.750f,+0.000f) * r; | ||||
|         b = ImVec2(-0.750f,+0.866f) * r; | ||||
|         c = ImVec2(-0.750f,-0.866f) * r; | ||||
|         break; | ||||
|     case ImGuiDir_None: | ||||
|     case ImGuiDir_COUNT: | ||||
|         IM_ASSERT(0); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     g.CurrentWindow->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text)); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderBullet(ImVec2 pos) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     window->DrawList->AddCircleFilled(pos, g.FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     float thickness = ImMax(sz / 5.0f, 1.0f); | ||||
|     sz -= thickness*0.5f; | ||||
|     pos += ImVec2(thickness*0.25f, thickness*0.25f); | ||||
|  | ||||
|     float third = sz / 3.0f; | ||||
|     float bx = pos.x + third; | ||||
|     float by = pos.y + sz - third*0.5f; | ||||
|     window->DrawList->PathLineTo(ImVec2(bx - third, by - third)); | ||||
|     window->DrawList->PathLineTo(ImVec2(bx, by)); | ||||
|     window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2)); | ||||
|     window->DrawList->PathStroke(col, false, thickness); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     if (id != g.NavId) | ||||
|         return; | ||||
|     if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) | ||||
|         return; | ||||
|     ImGuiWindow* window = ImGui::GetCurrentWindow(); | ||||
|     if (window->DC.NavHideHighlightOneFrame) | ||||
|         return; | ||||
|  | ||||
|     float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding; | ||||
|     ImRect display_rect = bb; | ||||
|     display_rect.ClipWith(window->ClipRect); | ||||
|     if (flags & ImGuiNavHighlightFlags_TypeDefault) | ||||
|     { | ||||
|         const float THICKNESS = 2.0f; | ||||
|         const float DISTANCE = 3.0f + THICKNESS * 0.5f; | ||||
|         display_rect.Expand(ImVec2(DISTANCE,DISTANCE)); | ||||
|         bool fully_visible = window->ClipRect.Contains(display_rect); | ||||
|         if (!fully_visible) | ||||
|             window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); | ||||
|         window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS); | ||||
|         if (!fully_visible) | ||||
|             window->DrawList->PopClipRect(); | ||||
|     } | ||||
|     if (flags & ImGuiNavHighlightFlags_TypeThin) | ||||
|     { | ||||
|         window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f); | ||||
|     } | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // MAIN CODE | ||||
| // (this category is still too large and badly ordered, needs some tidying up) | ||||
| @@ -3571,220 +3792,6 @@ void ImGui::Render() | ||||
| #endif | ||||
| } | ||||
|  | ||||
| const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) | ||||
| { | ||||
|     const char* text_display_end = text; | ||||
|     if (!text_end) | ||||
|         text_end = (const char*)-1; | ||||
|  | ||||
|     while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) | ||||
|         text_display_end++; | ||||
|     return text_display_end; | ||||
| } | ||||
|  | ||||
| // Internal ImGui functions to render text | ||||
| // RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() | ||||
| void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end; | ||||
|     if (hide_text_after_hash) | ||||
|     { | ||||
|         text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!text_end) | ||||
|             text_end = text + strlen(text); // FIXME-OPT | ||||
|         text_display_end = text_end; | ||||
|     } | ||||
|  | ||||
|     if (text != text_display_end) | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); | ||||
|         if (g.LogEnabled) | ||||
|             LogRenderedText(&pos, text, text_display_end); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     if (!text_end) | ||||
|         text_end = text + strlen(text); // FIXME-OPT | ||||
|  | ||||
|     if (text != text_end) | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); | ||||
|         if (g.LogEnabled) | ||||
|             LogRenderedText(&pos, text, text_end); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Default clip_rect uses (pos_min,pos_max) | ||||
| // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) | ||||
| void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) | ||||
| { | ||||
|     // Hide anything after a '##' string | ||||
|     const char* text_display_end = FindRenderedTextEnd(text, text_end); | ||||
|     const int text_len = (int)(text_display_end - text); | ||||
|     if (text_len == 0) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     // Perform CPU side clipping for single clipped element to avoid using scissor state | ||||
|     ImVec2 pos = pos_min; | ||||
|     const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); | ||||
|  | ||||
|     const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min; | ||||
|     const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max; | ||||
|     bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); | ||||
|     if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min | ||||
|         need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); | ||||
|  | ||||
|     // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. | ||||
|     if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); | ||||
|     if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); | ||||
|  | ||||
|     // Render | ||||
|     if (need_clipping) | ||||
|     { | ||||
|         ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); | ||||
|     } | ||||
|     if (g.LogEnabled) | ||||
|         LogRenderedText(&pos, text, text_display_end); | ||||
| } | ||||
|  | ||||
| // Render a rectangle shaped with optional rounding and borders | ||||
| void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); | ||||
|     const float border_size = g.Style.FrameBorderSize; | ||||
|     if (border && border_size > 0.0f) | ||||
|     { | ||||
|         window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); | ||||
|         window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     const float border_size = g.Style.FrameBorderSize; | ||||
|     if (border_size > 0.0f) | ||||
|     { | ||||
|         window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); | ||||
|         window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Render an arrow aimed to be aligned with text (p_min is a position in the same space text would be positioned). To e.g. denote expanded/collapsed state | ||||
| void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     const float h = g.FontSize * 1.00f; | ||||
|     float r = h * 0.40f * scale; | ||||
|     ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale); | ||||
|  | ||||
|     ImVec2 a, b, c; | ||||
|     switch (dir) | ||||
|     { | ||||
|     case ImGuiDir_Up: | ||||
|     case ImGuiDir_Down: | ||||
|         if (dir == ImGuiDir_Up) r = -r; | ||||
|         a = ImVec2(+0.000f,+0.750f) * r; | ||||
|         b = ImVec2(-0.866f,-0.750f) * r; | ||||
|         c = ImVec2(+0.866f,-0.750f) * r; | ||||
|         break; | ||||
|     case ImGuiDir_Left: | ||||
|     case ImGuiDir_Right: | ||||
|         if (dir == ImGuiDir_Left) r = -r; | ||||
|         a = ImVec2(+0.750f,+0.000f) * r; | ||||
|         b = ImVec2(-0.750f,+0.866f) * r; | ||||
|         c = ImVec2(-0.750f,-0.866f) * r; | ||||
|         break; | ||||
|     case ImGuiDir_None: | ||||
|     case ImGuiDir_COUNT: | ||||
|         IM_ASSERT(0); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     g.CurrentWindow->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text)); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderBullet(ImVec2 pos) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|     window->DrawList->AddCircleFilled(pos, g.FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     float thickness = ImMax(sz / 5.0f, 1.0f); | ||||
|     sz -= thickness*0.5f; | ||||
|     pos += ImVec2(thickness*0.25f, thickness*0.25f); | ||||
|  | ||||
|     float third = sz / 3.0f; | ||||
|     float bx = pos.x + third; | ||||
|     float by = pos.y + sz - third*0.5f; | ||||
|     window->DrawList->PathLineTo(ImVec2(bx - third, by - third)); | ||||
|     window->DrawList->PathLineTo(ImVec2(bx, by)); | ||||
|     window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2)); | ||||
|     window->DrawList->PathStroke(col, false, thickness); | ||||
| } | ||||
|  | ||||
| void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     if (id != g.NavId) | ||||
|         return; | ||||
|     if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) | ||||
|         return; | ||||
|     ImGuiWindow* window = ImGui::GetCurrentWindow(); | ||||
|     if (window->DC.NavHideHighlightOneFrame) | ||||
|         return; | ||||
|  | ||||
|     float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding; | ||||
|     ImRect display_rect = bb; | ||||
|     display_rect.ClipWith(window->ClipRect); | ||||
|     if (flags & ImGuiNavHighlightFlags_TypeDefault) | ||||
|     { | ||||
|         const float THICKNESS = 2.0f; | ||||
|         const float DISTANCE = 3.0f + THICKNESS * 0.5f; | ||||
|         display_rect.Expand(ImVec2(DISTANCE,DISTANCE)); | ||||
|         bool fully_visible = window->ClipRect.Contains(display_rect); | ||||
|         if (!fully_visible) | ||||
|             window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); | ||||
|         window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS); | ||||
|         if (!fully_visible) | ||||
|             window->DrawList->PopClipRect(); | ||||
|     } | ||||
|     if (flags & ImGuiNavHighlightFlags_TypeThin) | ||||
|     { | ||||
|         window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. | ||||
| // CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) | ||||
| ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) | ||||
| @@ -4558,7 +4565,7 @@ const ImGuiResizeGripDef resize_grip_def[4] = | ||||
|     { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right | ||||
| }; | ||||
|  | ||||
| static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) | ||||
| static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) | ||||
| { | ||||
|     ImRect rect = window->Rect(); | ||||
|     if (thickness == 0.0f) rect.Max -= ImVec2(1,1); | ||||
| @@ -4622,7 +4629,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au | ||||
|         const float BORDER_SIZE = 5.0f;          // FIXME: Only works _inside_ window because of HoveredWindow check. | ||||
|         const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise | ||||
|         bool hovered, held; | ||||
|         ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); | ||||
|         ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); | ||||
|         ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); | ||||
|         if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) | ||||
|         { | ||||
| @@ -5187,7 +5194,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) | ||||
|                 window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); | ||||
|             if (border_held != -1) | ||||
|             { | ||||
|                 ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f); | ||||
|                 ImRect border = GetResizeBorderRect(window, border_held, grip_draw_size, 0.0f); | ||||
|                 window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); | ||||
|             } | ||||
|             if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) | ||||
| @@ -6383,17 +6390,6 @@ ImGuiStorage* ImGui::GetStateStorage() | ||||
|     return window->DC.StateStorage; | ||||
| } | ||||
|  | ||||
| void ImGui::AlignTextToFramePadding() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2); | ||||
|     window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); | ||||
| } | ||||
|  | ||||
| void ImGui::PushID(const char* str_id) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindowRead(); | ||||
| @@ -6440,149 +6436,6 @@ ImGuiID ImGui::GetID(const void* ptr_id) | ||||
|     return GImGui->CurrentWindow->GetID(ptr_id); | ||||
| } | ||||
|  | ||||
| // Horizontal/vertical separating line | ||||
| void ImGui::Separator() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     // Those flags should eventually be overridable by the user | ||||
|     ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; | ||||
|     IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))));   // Check that only 1 option is selected | ||||
|     if (flags & ImGuiSeparatorFlags_Vertical) | ||||
|     { | ||||
|         VerticalSeparator(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // Horizontal Separator | ||||
|     if (window->DC.ColumnsSet) | ||||
|         PopClipRect(); | ||||
|  | ||||
|     float x1 = window->Pos.x; | ||||
|     float x2 = window->Pos.x + window->Size.x; | ||||
|     if (!window->DC.GroupStack.empty()) | ||||
|         x1 += window->DC.Indent.x; | ||||
|  | ||||
|     const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); | ||||
|     ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. | ||||
|     if (!ItemAdd(bb, 0)) | ||||
|     { | ||||
|         if (window->DC.ColumnsSet) | ||||
|             PushColumnClipRect(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); | ||||
|  | ||||
|     if (g.LogEnabled) | ||||
|         LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); | ||||
|  | ||||
|     if (window->DC.ColumnsSet) | ||||
|     { | ||||
|         PushColumnClipRect(); | ||||
|         window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::VerticalSeparator() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     float y1 = window->DC.CursorPos.y; | ||||
|     float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y; | ||||
|     const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); | ||||
|     ItemSize(ImVec2(bb.GetWidth(), 0.0f)); | ||||
|     if (!ItemAdd(bb, 0)) | ||||
|         return; | ||||
|  | ||||
|     window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); | ||||
|     if (g.LogEnabled) | ||||
|         LogText(" |"); | ||||
| } | ||||
|  | ||||
| // Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise. | ||||
| bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; | ||||
|     window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; | ||||
|     bool item_add = ItemAdd(bb, id); | ||||
|     window->DC.ItemFlags = item_flags_backup; | ||||
|     if (!item_add) | ||||
|         return false; | ||||
|  | ||||
|     bool hovered, held; | ||||
|     ImRect bb_interact = bb; | ||||
|     bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); | ||||
|     ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); | ||||
|     if (g.ActiveId != id) | ||||
|         SetItemAllowOverlap(); | ||||
|  | ||||
|     if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay)) | ||||
|         SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); | ||||
|  | ||||
|     ImRect bb_render = bb; | ||||
|     if (held) | ||||
|     { | ||||
|         ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; | ||||
|         float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; | ||||
|  | ||||
|         // Minimum pane size | ||||
|         float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1); | ||||
|         float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2); | ||||
|         if (mouse_delta < -size_1_maximum_delta) | ||||
|             mouse_delta = -size_1_maximum_delta; | ||||
|         if (mouse_delta > size_2_maximum_delta) | ||||
|             mouse_delta = size_2_maximum_delta; | ||||
|  | ||||
|         // Apply resize | ||||
|         if (mouse_delta != 0.0f) | ||||
|         { | ||||
|             if (mouse_delta < 0.0f) | ||||
|                 IM_ASSERT(*size1 + mouse_delta >= min_size1); | ||||
|             if (mouse_delta > 0.0f) | ||||
|                IM_ASSERT(*size2 - mouse_delta >= min_size2); | ||||
|             *size1 += mouse_delta; | ||||
|             *size2 -= mouse_delta; | ||||
|             bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); | ||||
|             MarkItemEdited(id); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Render | ||||
|     const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); | ||||
|     window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding); | ||||
|  | ||||
|     return held; | ||||
| } | ||||
|  | ||||
| void ImGui::Spacing() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ItemSize(ImVec2(0,0)); | ||||
| } | ||||
|  | ||||
| void ImGui::Dummy(const ImVec2& size) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); | ||||
|     ItemSize(bb); | ||||
|     ItemAdd(bb, 0); | ||||
| } | ||||
|  | ||||
| bool ImGui::IsRectVisible(const ImVec2& size) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindowRead(); | ||||
| @@ -6689,22 +6542,6 @@ void ImGui::SameLine(float pos_x, float spacing_w) | ||||
|     window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; | ||||
| } | ||||
|  | ||||
| void ImGui::NewLine() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; | ||||
|     window->DC.LayoutType = ImGuiLayoutType_Vertical; | ||||
|     if (window->DC.CurrentLineSize.y > 0.0f)     // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. | ||||
|         ItemSize(ImVec2(0,0)); | ||||
|     else | ||||
|         ItemSize(ImVec2(0.0f, g.FontSize)); | ||||
|     window->DC.LayoutType = backup_layout_type; | ||||
| } | ||||
|  | ||||
| void ImGui::Indent(float indent_w) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| Index of this file: | ||||
| - Widgets: Text, etc. | ||||
| - Widgets: Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc. | ||||
| - Widgets: Low-level Layout helpers: Spacing, Dummy, NewLine, Separator, etc. | ||||
| - Widgets: ComboBox | ||||
| - Data Type and Data Formatting Helpers | ||||
| - Widgets: DragScalar, DragFloat, DragInt, etc. | ||||
| @@ -1051,6 +1052,187 @@ void ImGui::Bullet() | ||||
|     SameLine(0, style.FramePadding.x*2); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------- | ||||
| // WIDGETS: Low-level Layout helpers | ||||
| // - Spacing() | ||||
| // - Dummy() | ||||
| // - NewLine() | ||||
| // - AlignTextToFramePadding() | ||||
| // - Separator() | ||||
| // - VerticalSeparator() [Internal] | ||||
| // - SplitterBehavior() [Internal] | ||||
| //------------------------------------------------------------------------- | ||||
|  | ||||
| void ImGui::Spacing() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ItemSize(ImVec2(0,0)); | ||||
| } | ||||
|  | ||||
| void ImGui::Dummy(const ImVec2& size) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); | ||||
|     ItemSize(bb); | ||||
|     ItemAdd(bb, 0); | ||||
| } | ||||
|  | ||||
| void ImGui::NewLine() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; | ||||
|     window->DC.LayoutType = ImGuiLayoutType_Vertical; | ||||
|     if (window->DC.CurrentLineSize.y > 0.0f)     // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. | ||||
|         ItemSize(ImVec2(0,0)); | ||||
|     else | ||||
|         ItemSize(ImVec2(0.0f, g.FontSize)); | ||||
|     window->DC.LayoutType = backup_layout_type; | ||||
| } | ||||
|  | ||||
| void ImGui::AlignTextToFramePadding() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2); | ||||
|     window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); | ||||
| } | ||||
|  | ||||
| // Horizontal/vertical separating line | ||||
| void ImGui::Separator() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     // Those flags should eventually be overridable by the user | ||||
|     ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; | ||||
|     IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))));   // Check that only 1 option is selected | ||||
|     if (flags & ImGuiSeparatorFlags_Vertical) | ||||
|     { | ||||
|         VerticalSeparator(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     // Horizontal Separator | ||||
|     if (window->DC.ColumnsSet) | ||||
|         PopClipRect(); | ||||
|  | ||||
|     float x1 = window->Pos.x; | ||||
|     float x2 = window->Pos.x + window->Size.x; | ||||
|     if (!window->DC.GroupStack.empty()) | ||||
|         x1 += window->DC.Indent.x; | ||||
|  | ||||
|     const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); | ||||
|     ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. | ||||
|     if (!ItemAdd(bb, 0)) | ||||
|     { | ||||
|         if (window->DC.ColumnsSet) | ||||
|             PushColumnClipRect(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); | ||||
|  | ||||
|     if (g.LogEnabled) | ||||
|         LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); | ||||
|  | ||||
|     if (window->DC.ColumnsSet) | ||||
|     { | ||||
|         PushColumnClipRect(); | ||||
|         window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ImGui::VerticalSeparator() | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|     ImGuiContext& g = *GImGui; | ||||
|  | ||||
|     float y1 = window->DC.CursorPos.y; | ||||
|     float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y; | ||||
|     const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); | ||||
|     ItemSize(ImVec2(bb.GetWidth(), 0.0f)); | ||||
|     if (!ItemAdd(bb, 0)) | ||||
|         return; | ||||
|  | ||||
|     window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); | ||||
|     if (g.LogEnabled) | ||||
|         LogText(" |"); | ||||
| } | ||||
|  | ||||
| // Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise. | ||||
| bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImGuiWindow* window = g.CurrentWindow; | ||||
|  | ||||
|     const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; | ||||
|     window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; | ||||
|     bool item_add = ItemAdd(bb, id); | ||||
|     window->DC.ItemFlags = item_flags_backup; | ||||
|     if (!item_add) | ||||
|         return false; | ||||
|  | ||||
|     bool hovered, held; | ||||
|     ImRect bb_interact = bb; | ||||
|     bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); | ||||
|     ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); | ||||
|     if (g.ActiveId != id) | ||||
|         SetItemAllowOverlap(); | ||||
|  | ||||
|     if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay)) | ||||
|         SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); | ||||
|  | ||||
|     ImRect bb_render = bb; | ||||
|     if (held) | ||||
|     { | ||||
|         ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; | ||||
|         float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; | ||||
|  | ||||
|         // Minimum pane size | ||||
|         float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1); | ||||
|         float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2); | ||||
|         if (mouse_delta < -size_1_maximum_delta) | ||||
|             mouse_delta = -size_1_maximum_delta; | ||||
|         if (mouse_delta > size_2_maximum_delta) | ||||
|             mouse_delta = size_2_maximum_delta; | ||||
|  | ||||
|         // Apply resize | ||||
|         if (mouse_delta != 0.0f) | ||||
|         { | ||||
|             if (mouse_delta < 0.0f) | ||||
|                 IM_ASSERT(*size1 + mouse_delta >= min_size1); | ||||
|             if (mouse_delta > 0.0f) | ||||
|                 IM_ASSERT(*size2 - mouse_delta >= min_size2); | ||||
|             *size1 += mouse_delta; | ||||
|             *size2 -= mouse_delta; | ||||
|             bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); | ||||
|             MarkItemEdited(id); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Render | ||||
|     const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); | ||||
|     window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding); | ||||
|  | ||||
|     return held; | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------- | ||||
| // WIDGETS: Combo Box | ||||
| // - BeginCombo() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user