[upstream_utils] Update imgui and implot (#8762)

Not updating GLFW yet due to a likely future move to SDL.
This commit is contained in:
Peter Johnson
2026-04-12 12:19:32 -07:00
committed by GitHub
parent d76486d885
commit 476b9641c1
47 changed files with 27710 additions and 12792 deletions

View File

@@ -1,6 +1,7 @@
// MIT License
// Copyright (c) 2023 Evan Pezent
// Copyright (c) 2020-2024 Evan Pezent
// Copyright (c) 2025-2026 Breno Cunha Queiroz
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -20,7 +21,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ImPlot v0.16
// ImPlot v1.0
// You may use this file to debug, understand or extend ImPlot features but we
// don't provide any guarantee of forward compatibility!
@@ -31,18 +32,19 @@
#pragma once
#include <time.h>
#include "imgui_internal.h"
#ifndef IMPLOT_VERSION
#error Must include implot.h before implot_internal.h
#endif
#ifndef IMGUI_DISABLE
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#include <time.h>
#include "imgui_internal.h"
// Support for pre-1.84 versions. ImPool's GetSize() -> GetBufSize()
#if (IMGUI_VERSION_NUM < 18303)
#define GetBufSize GetSize
@@ -55,22 +57,25 @@
// Constants can be changed unless stated otherwise. We may move some of these
// to ImPlotStyleVar_ over time.
// Mimimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
#define IMPLOT_MIN_TIME 0
// Minimum allowable timestamp value 01/01/1970 @ 12:00am (UTC) (DO NOT DECREASE THIS)
constexpr double IMPLOT_MIN_TIME = 0;
// Maximum allowable timestamp value 01/01/3000 @ 12:00am (UTC) (DO NOT INCREASE THIS)
#define IMPLOT_MAX_TIME 32503680000
constexpr double IMPLOT_MAX_TIME = 32503680000;
// Default label format for axis labels
#define IMPLOT_LABEL_FORMAT "%g"
constexpr const char* IMPLOT_LABEL_FORMAT = "%g";
// Max character size for tick labels
#define IMPLOT_LABEL_MAX_SIZE 32
constexpr int IMPLOT_LABEL_MAX_SIZE = 32;
// Number of X axes
constexpr int IMPLOT_NUM_X_AXES = ImAxis_Y1;
// Number of Y axes
constexpr int IMPLOT_NUM_Y_AXES = ImAxis_COUNT - IMPLOT_NUM_X_AXES;
//-----------------------------------------------------------------------------
// [SECTION] Macros
//-----------------------------------------------------------------------------
#define IMPLOT_NUM_X_AXES ImAxis_Y1
#define IMPLOT_NUM_Y_AXES (ImAxis_COUNT - IMPLOT_NUM_X_AXES)
// Split ImU32 color into RGB components [0 255]
#define IM_COL32_SPLIT_RGB(col,r,g,b) \
ImU32 r = ((col >> IM_COL32_R_SHIFT) & 0xFF); \
@@ -118,7 +123,7 @@ static inline void ImFlipFlag(TSet& set, TFlag flag) { ImHasFlag(set, flag) ? se
// Linearly remaps x from [x0 x1] to [y0 y1].
template <typename T>
static inline T ImRemap(T x, T x0, T x1, T y0, T y1) { return y0 + (x - x0) * (y1 - y0) / (x1 - x0); }
// Linear rempas x from [x0 x1] to [0 1]
// Linearly remaps x from [x0 x1] to [0 1]
template <typename T>
static inline T ImRemap01(T x, T x0, T x1) { return (x - x0) / (x1 - x0); }
// Returns always positive modulo (assumes r != 0)
@@ -137,6 +142,7 @@ static inline double ImConstrainLog(double val) { return val <= 0 ? 0.001f : val
static inline double ImConstrainTime(double val) { return val < IMPLOT_MIN_TIME ? IMPLOT_MIN_TIME : (val > IMPLOT_MAX_TIME ? IMPLOT_MAX_TIME : val); }
// True if two numbers are approximately equal using units in the last place.
static inline bool ImAlmostEqual(double v1, double v2, int ulp = 2) { return ImAbs(v1-v2) < DBL_EPSILON * ImAbs(v1+v2) * ulp || ImAbs(v1-v2) < DBL_MIN; }
// Finds min value in an unsorted array
template <typename T>
static inline T ImMinArray(const T* values, int count) { T m = values[0]; for (int i = 1; i < count; ++i) { if (values[i] < m) { m = values[i]; } } return m; }
@@ -180,6 +186,7 @@ static inline double ImStdDev(const T* values, int count) {
x += ((double)values[i] - mu) * ((double)values[i] - mu) * den;
return sqrt(x);
}
// Mix color a and b by factor s in [0 256]
static inline ImU32 ImMixU32(ImU32 a, ImU32 b, ImU32 s) {
#ifdef IMPLOT_MIX64
@@ -202,7 +209,7 @@ static inline ImU32 ImMixU32(ImU32 a, ImU32 b, ImU32 s) {
#endif
}
// Lerp across an array of 32-bit collors given t in [0.0 1.0]
// Lerp across an array of 32-bit colors given t in [0.0 1.0]
static inline ImU32 ImLerpU32(const ImU32* colors, int size, float t) {
int i1 = (int)((size - 1 ) * t);
int i2 = i1 + 1;
@@ -230,9 +237,10 @@ static inline bool ImOverlaps(T min_a, T max_a, T min_b, T max_b) {
// [SECTION] ImPlot Enums
//-----------------------------------------------------------------------------
typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
typedef int ImPlotTimeUnit; // -> enum ImPlotTimeUnit_
typedef int ImPlotDateFmt; // -> enum ImPlotDateFmt_
typedef int ImPlotTimeFmt; // -> enum ImPlotTimeFmt_
typedef int ImPlotMarkerInternal; // -> enum ImPlotMarkerInternal_
enum ImPlotTimeUnit_ {
ImPlotTimeUnit_Us, // microsecond
@@ -268,6 +276,10 @@ enum ImPlotTimeFmt_ { // default [ 24 Hour Clock ]
ImPlotTimeFmt_Hr // 7pm [ 19:00 ]
};
enum ImPlotMarkerInternal_ {
ImPlotMarker_Invalid = -3
};
//-----------------------------------------------------------------------------
// [SECTION] Callbacks
//-----------------------------------------------------------------------------
@@ -424,6 +436,7 @@ struct ImPlotColormapData {
// ImPlotPoint with positive/negative error values
struct ImPlotPointError {
double X, Y, Neg, Pos;
ImPlotPointError() { X = 0; Y = 0; Neg = 0; Pos = 0; }
ImPlotPointError(double x, double y, double neg, double pos) {
X = x; Y = y; Neg = neg; Pos = pos;
}
@@ -490,6 +503,14 @@ struct ImPlotTag {
ImU32 ColorBg;
ImU32 ColorFg;
int TextOffset;
ImPlotTag() {
Axis = 0;
Value = 0;
ColorBg = 0;
ColorFg = 0;
TextOffset = 0;
}
};
struct ImPlotTagCollection {
@@ -544,6 +565,17 @@ struct ImPlotTick
int Level;
int Idx;
ImPlotTick() {
PlotPos = 0;
PixelPos = 0;
LabelSize = ImVec2(0,0);
TextOffset = -1;
Major = false;
ShowLabel = false;
Level = 0;
Idx = -1;
}
ImPlotTick(double value, bool major, int level, bool show_label) {
PixelPos = 0;
PlotPos = value;
@@ -735,7 +767,7 @@ struct ImPlotAxis
PickerTimeMin = ImPlotTime::FromDouble(Range.Min);
UpdateTransformCache();
return true;
};
}
inline bool SetMax(double _max, bool force=false) {
if (!force && IsLockedMax())
@@ -754,7 +786,7 @@ struct ImPlotAxis
PickerTimeMax = ImPlotTime::FromDouble(Range.Max);
UpdateTransformCache();
return true;
};
}
inline void SetRange(double v1, double v2) {
Range.Min = ImMin(v1,v2);
@@ -945,6 +977,7 @@ struct ImPlotItem
{
ImGuiID ID;
ImU32 Color;
ImPlotMarker Marker;
ImRect LegendHoverRect;
int NameOffset;
bool Show;
@@ -954,6 +987,7 @@ struct ImPlotItem
ImPlotItem() {
ID = 0;
Color = IM_COL32_WHITE;
Marker = ImPlotMarker_None;
NameOffset = -1;
Show = true;
SeenThisFrame = false;
@@ -970,9 +1004,11 @@ struct ImPlotLegend
ImPlotLegendFlags PreviousFlags;
ImPlotLocation Location;
ImPlotLocation PreviousLocation;
ImVec2 Scroll;
ImVector<int> Indices;
ImGuiTextBuffer Labels;
ImRect Rect;
ImRect RectClamped;
bool Hovered;
bool Held;
bool CanGoInside;
@@ -982,6 +1018,7 @@ struct ImPlotLegend
CanGoInside = true;
Hovered = Held = false;
Location = PreviousLocation = ImPlotLocation_NorthWest;
Scroll = ImVec2(0,0);
}
void Reset() { Indices.shrink(0); Labels.Buf.shrink(0); }
@@ -994,8 +1031,9 @@ struct ImPlotItemGroup
ImPlotLegend Legend;
ImPool<ImPlotItem> ItemPool;
int ColormapIdx;
ImPlotMarker MarkerIdx;
ImPlotItemGroup() { ID = 0; ColormapIdx = 0; }
ImPlotItemGroup() { ID = 0; ColormapIdx = 0; MarkerIdx = 0; }
int GetItemCount() const { return ItemPool.GetBufSize(); }
ImGuiID GetItemID(const char* label_id) { return ImGui::GetID(label_id); /* GetIDWithSeed */ }
@@ -1174,30 +1212,20 @@ struct ImPlotNextPlotData
// Temporary data storage for upcoming item
struct ImPlotNextItemData {
ImVec4 Colors[5]; // ImPlotCol_Line, ImPlotCol_Fill, ImPlotCol_MarkerOutline, ImPlotCol_MarkerFill, ImPlotCol_ErrorBar
float LineWeight;
ImPlotMarker Marker;
float MarkerSize;
float MarkerWeight;
float FillAlpha;
float ErrorBarSize;
float ErrorBarWeight;
float DigitalBitHeight;
float DigitalBitGap;
ImPlotSpec Spec;
bool RenderLine;
bool RenderFill;
bool RenderMarkerLine;
bool RenderMarkerFill;
bool RenderMarkers;
bool HasHidden;
bool Hidden;
ImPlotCond HiddenCond;
ImPlotNextItemData() { Reset(); }
void Reset() {
for (int i = 0; i < 5; ++i)
Colors[i] = IMPLOT_AUTO_COL;
LineWeight = MarkerSize = MarkerWeight = FillAlpha = ErrorBarSize = ErrorBarWeight = DigitalBitHeight = DigitalBitGap = IMPLOT_AUTO;
Marker = IMPLOT_AUTO;
HasHidden = Hidden = false;
Spec = ImPlotSpec();
HasHidden = Hidden = false;
HiddenCond = ImPlotCond_None;
}
};
@@ -1219,9 +1247,6 @@ struct ImPlotContext {
ImPlotAnnotationCollection Annotations;
ImPlotTagCollection Tags;
// Flags
bool ChildWindowMade;
// Style and Colormaps
ImPlotStyle Style;
ImVector<ImGuiColorMod> ColorModifiers;
@@ -1313,14 +1338,14 @@ IMPLOT_API void ShowSubplotsContextMenu(ImPlotSubplot& subplot);
//-----------------------------------------------------------------------------
// Begins a new item. Returns false if the item should not be plotted. Pushes PlotClipRect.
IMPLOT_API bool BeginItem(const char* label_id, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO);
IMPLOT_API bool BeginItem(const char* label_id, const ImPlotSpec& spec = ImPlotSpec(), const ImVec4& item_col = IMPLOT_AUTO_COL, ImPlotMarker item_mkr = ImPlotMarker_Invalid);
// Same as above but with fitting functionality.
template <typename _Fitter>
bool BeginItemEx(const char* label_id, const _Fitter& fitter, ImPlotItemFlags flags=0, ImPlotCol recolor_from=IMPLOT_AUTO) {
if (BeginItem(label_id, flags, recolor_from)) {
bool BeginItemEx(const char* label_id, const _Fitter& fitter, const ImPlotSpec& spec, const ImVec4& item_col = IMPLOT_AUTO_COL, ImPlotMarker item_mkr = ImPlotMarker_Invalid) {
if (BeginItem(label_id, spec, item_col, item_mkr)) {
ImPlotPlot& plot = *GetCurrentPlot();
if (plot.FitThisFrame && !ImHasFlag(flags, ImPlotItemFlags_NoFit))
if (plot.FitThisFrame && !ImHasFlag(spec.Flags, ImPlotItemFlags_NoFit))
fitter.Fit(plot.Axes[plot.CurrentX], plot.Axes[plot.CurrentY]);
return true;
}
@@ -1418,13 +1443,15 @@ IMPLOT_API void ShowAxisContextMenu(ImPlotAxis& axis, ImPlotAxis* equal_axis, bo
// Gets the position of an inner rect that is located inside of an outer rect according to an ImPlotLocation and padding amount.
IMPLOT_API ImVec2 GetLocationPos(const ImRect& outer_rect, const ImVec2& inner_size, ImPlotLocation location, const ImVec2& pad = ImVec2(0,0));
// Calculates the bounding box size of a legend
// Calculates the bounding box size of a legend _before_ clipping.
IMPLOT_API ImVec2 CalcLegendSize(ImPlotItemGroup& items, const ImVec2& pad, const ImVec2& spacing, bool vertical);
// Clips calculated legend size
IMPLOT_API bool ClampLegendRect(ImRect& legend_rect, const ImRect& outer_rect, const ImVec2& pad);
// Renders legend entries into a bounding box
IMPLOT_API bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool interactable, const ImVec2& pad, const ImVec2& spacing, bool vertical, ImDrawList& DrawList);
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window!).
// Shows an alternate legend for the plot identified by #title_id, outside of the plot frame (can be called before or after of Begin/EndPlot but must occur in the same ImGui window! This is not thoroughly tested nor scrollable!).
IMPLOT_API void ShowAltLegend(const char* title_id, bool vertical = true, const ImVec2 size = ImVec2(0,0), bool interactable = true);
// Shows an legends's context menu.
// Shows a legend's context menu.
IMPLOT_API bool ShowLegendContextMenu(ImPlotLegend& legend, bool visible);
//-----------------------------------------------------------------------------
@@ -1519,8 +1546,8 @@ void FillRange(ImVector<T>& buffer, int n, T vmin, T vmax) {
}
// Calculate histogram bin counts and widths
template <typename T>
static inline void CalculateBins(const T* values, int count, ImPlotBin meth, const ImPlotRange& range, int& bins_out, double& width_out) {
template <typename TContainer>
static inline void CalculateBins(const TContainer& values, int count, ImPlotBin meth, const ImPlotRange& range, int& bins_out, double& width_out) {
switch (meth) {
case ImPlotBin_Sqrt:
bins_out = (int)ceil(sqrt(count));
@@ -1549,7 +1576,7 @@ static inline bool IsLeapYear(int year) {
}
// Returns the number of days in a month, accounting for Feb. leap years. #month is zero indexed.
static inline int GetDaysInMonth(int year, int month) {
static const int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
constexpr int days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
return days[month] + (int)(month == 1 && IsLeapYear(year));
}
@@ -1566,11 +1593,24 @@ IMPLOT_API tm* GetLocTime(const ImPlotTime& t, tm* ptm);
// NB: The following functions only work if there is a current ImPlotContext because the
// internal tm struct is owned by the context! They are aware of ImPlotStyle.UseLocalTime.
// // Make a UNIX timestamp from a tm struct according to the current ImPlotStyle.UseLocalTime setting.
static inline ImPlotTime MkTime(struct tm *ptm) {
if (GetStyle().UseLocalTime) return MkLocTime(ptm);
else return MkGmtTime(ptm);
}
// Get a tm struct from a UNIX timestamp according to the current ImPlotStyle.UseLocalTime setting.
static inline tm* GetTime(const ImPlotTime& t, tm* ptm) {
if (GetStyle().UseLocalTime) return GetLocTime(t,ptm);
else return GetGmtTime(t,ptm);
}
// Make a timestamp from time components.
// year[1970-3000], month[0-11], day[1-31], hour[0-23], min[0-59], sec[0-59], us[0,999999]
IMPLOT_API ImPlotTime MakeTime(int year, int month = 0, int day = 1, int hour = 0, int min = 0, int sec = 0, int us = 0);
// Get year component from timestamp [1970-3000]
IMPLOT_API int GetYear(const ImPlotTime& t);
// Get month component from timestamp [0-11]
IMPLOT_API int GetMonth(const ImPlotTime& t);
// Adds or subtracts time from a timestamp. #count > 0 to add, < 0 to subtract.
IMPLOT_API ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count);
@@ -1583,6 +1623,11 @@ IMPLOT_API ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit);
// Combines the date of one timestamp with the time-of-day of another timestamp.
IMPLOT_API ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& time_part);
// Get the current time as a timestamp.
static inline ImPlotTime Now() { return ImPlotTime::FromDouble((double)time(nullptr)); }
// Get the current date as a timestamp.
static inline ImPlotTime Today() { return ImPlot::FloorTime(Now(), ImPlotTimeUnit_Day); }
// Formats the time part of timestamp t into a buffer according to #fmt
IMPLOT_API int FormatTime(const ImPlotTime& t, char* buffer, int size, ImPlotTimeFmt fmt, bool use_24_hr_clk);
// Formats the date part of timestamp t into a buffer according to #fmt
@@ -1663,13 +1708,15 @@ static inline int Formatter_Time(double, char* buff, int size, void* data) {
// [SECTION] Locator
//------------------------------------------------------------------------------
void Locator_Default(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
void Locator_Log10(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
void Locator_SymLog(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
IMPLOT_API void Locator_Default(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
IMPLOT_API void Locator_Time(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
IMPLOT_API void Locator_Log10(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
IMPLOT_API void Locator_SymLog(ImPlotTicker& ticker, const ImPlotRange& range, float pixels, bool vertical, ImPlotFormatter formatter, void* formatter_data);
} // namespace ImPlot
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif // #ifndef IMGUI_DISABLE