mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Refactor: Moved Plot/Value functions from imgui.cpp to imgui_widgets.cpp (#2036)
This commit is contained in:
		
							
								
								
									
										176
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -9400,153 +9400,6 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_ | ||||
|     return value_changed; | ||||
| } | ||||
|  | ||||
| void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|         return; | ||||
|  | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     const ImGuiStyle& style = g.Style; | ||||
|  | ||||
|     const ImVec2 label_size = CalcTextSize(label, NULL, true); | ||||
|     if (graph_size.x == 0.0f) | ||||
|         graph_size.x = CalcItemWidth(); | ||||
|     if (graph_size.y == 0.0f) | ||||
|         graph_size.y = label_size.y + (style.FramePadding.y * 2); | ||||
|  | ||||
|     const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); | ||||
|     const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); | ||||
|     const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); | ||||
|     ItemSize(total_bb, style.FramePadding.y); | ||||
|     if (!ItemAdd(total_bb, 0, &frame_bb)) | ||||
|         return; | ||||
|     const bool hovered = ItemHoverable(inner_bb, 0); | ||||
|  | ||||
|     // Determine scale from values if not specified | ||||
|     if (scale_min == FLT_MAX || scale_max == FLT_MAX) | ||||
|     { | ||||
|         float v_min = FLT_MAX; | ||||
|         float v_max = -FLT_MAX; | ||||
|         for (int i = 0; i < values_count; i++) | ||||
|         { | ||||
|             const float v = values_getter(data, i); | ||||
|             v_min = ImMin(v_min, v); | ||||
|             v_max = ImMax(v_max, v); | ||||
|         } | ||||
|         if (scale_min == FLT_MAX) | ||||
|             scale_min = v_min; | ||||
|         if (scale_max == FLT_MAX) | ||||
|             scale_max = v_max; | ||||
|     } | ||||
|  | ||||
|     RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); | ||||
|  | ||||
|     if (values_count > 0) | ||||
|     { | ||||
|         int res_w = ImMin((int)graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); | ||||
|         int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); | ||||
|  | ||||
|         // Tooltip on hover | ||||
|         int v_hovered = -1; | ||||
|         if (hovered) | ||||
|         { | ||||
|             const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); | ||||
|             const int v_idx = (int)(t * item_count); | ||||
|             IM_ASSERT(v_idx >= 0 && v_idx < values_count); | ||||
|  | ||||
|             const float v0 = values_getter(data, (v_idx + values_offset) % values_count); | ||||
|             const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); | ||||
|             if (plot_type == ImGuiPlotType_Lines) | ||||
|                 SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1); | ||||
|             else if (plot_type == ImGuiPlotType_Histogram) | ||||
|                 SetTooltip("%d: %8.4g", v_idx, v0); | ||||
|             v_hovered = v_idx; | ||||
|         } | ||||
|  | ||||
|         const float t_step = 1.0f / (float)res_w; | ||||
|         const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); | ||||
|  | ||||
|         float v0 = values_getter(data, (0 + values_offset) % values_count); | ||||
|         float t0 = 0.0f; | ||||
|         ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) );                       // Point in the normalized space of our target rectangle | ||||
|         float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f);   // Where does the zero line stands | ||||
|  | ||||
|         const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); | ||||
|         const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); | ||||
|  | ||||
|         for (int n = 0; n < res_w; n++) | ||||
|         { | ||||
|             const float t1 = t0 + t_step; | ||||
|             const int v1_idx = (int)(t0 * item_count + 0.5f); | ||||
|             IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); | ||||
|             const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); | ||||
|             const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale) ); | ||||
|  | ||||
|             // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. | ||||
|             ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); | ||||
|             ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, histogram_zero_line_t)); | ||||
|             if (plot_type == ImGuiPlotType_Lines) | ||||
|             { | ||||
|                 window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); | ||||
|             } | ||||
|             else if (plot_type == ImGuiPlotType_Histogram) | ||||
|             { | ||||
|                 if (pos1.x >= pos0.x + 2.0f) | ||||
|                     pos1.x -= 1.0f; | ||||
|                 window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); | ||||
|             } | ||||
|  | ||||
|             t0 = t1; | ||||
|             tp0 = tp1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Text overlay | ||||
|     if (overlay_text) | ||||
|         RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f,0.0f)); | ||||
|  | ||||
|     if (label_size.x > 0.0f) | ||||
|         RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); | ||||
| } | ||||
|  | ||||
| struct ImGuiPlotArrayGetterData | ||||
| { | ||||
|     const float* Values; | ||||
|     int Stride; | ||||
|  | ||||
|     ImGuiPlotArrayGetterData(const float* values, int stride) { Values = values; Stride = stride; } | ||||
| }; | ||||
|  | ||||
| static float Plot_ArrayGetter(void* data, int idx) | ||||
| { | ||||
|     ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; | ||||
|     const float v = *(const float*)(const void*)((const unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); | ||||
|     return v; | ||||
| } | ||||
|  | ||||
| void ImGui::PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) | ||||
| { | ||||
|     ImGuiPlotArrayGetterData data(values, stride); | ||||
|     PlotEx(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); | ||||
| } | ||||
|  | ||||
| void ImGui::PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) | ||||
| { | ||||
|     PlotEx(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); | ||||
| } | ||||
|  | ||||
| void ImGui::PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) | ||||
| { | ||||
|     ImGuiPlotArrayGetterData data(values, stride); | ||||
|     PlotEx(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); | ||||
| } | ||||
|  | ||||
| void ImGui::PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) | ||||
| { | ||||
|     PlotEx(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); | ||||
| } | ||||
|  | ||||
| static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) | ||||
| { | ||||
|     int line_count = 0; | ||||
| @@ -12216,35 +12069,6 @@ void ImGui::TreePop() | ||||
|     PopID(); | ||||
| } | ||||
|  | ||||
| void ImGui::Value(const char* prefix, bool b) | ||||
| { | ||||
|     Text("%s: %s", prefix, (b ? "true" : "false")); | ||||
| } | ||||
|  | ||||
| void ImGui::Value(const char* prefix, int v) | ||||
| { | ||||
|     Text("%s: %d", prefix, v); | ||||
| } | ||||
|  | ||||
| void ImGui::Value(const char* prefix, unsigned int v) | ||||
| { | ||||
|     Text("%s: %d", prefix, v); | ||||
| } | ||||
|  | ||||
| void ImGui::Value(const char* prefix, float v, const char* float_format) | ||||
| { | ||||
|     if (float_format) | ||||
|     { | ||||
|         char fmt[64]; | ||||
|         ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); | ||||
|         Text(fmt, prefix, v); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Text("%s: %.3f", prefix, v); | ||||
|     } | ||||
| } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // DRAG AND DROP | ||||
| //----------------------------------------------------------------------------- | ||||
|   | ||||
		Reference in New Issue
	
	Block a user