build: Updated ImGui to v1.91.7
This commit is contained in:
parent
a4af55cb66
commit
6a1de5fc4e
29
lib/third_party/imgui/imgui/include/imgui.h
vendored
29
lib/third_party/imgui/imgui/include/imgui.h
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -28,8 +28,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.91.6"
|
||||
#define IMGUI_VERSION_NUM 19160
|
||||
#define IMGUI_VERSION "1.91.7"
|
||||
#define IMGUI_VERSION_NUM 19170
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@ -141,6 +141,7 @@ Index of this file:
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
@ -700,6 +701,7 @@ namespace ImGui
|
||||
|
||||
// Widgets: List Boxes
|
||||
// - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// - If you don't need a label you can probably simply use BeginChild() with the ImGuiChildFlags_FrameStyle flag for the same result.
|
||||
// - You can submit contents and manage your selection state however you want it, by creating e.g. Selectable() or any other items.
|
||||
// - The simplified/old ListBox() api are helpers over BeginListBox()/EndListBox() which are kept available for convenience purpose. This is analoguous to how Combos are created.
|
||||
// - Choose frame width: size.x > 0.0f: custom / size.x < 0.0f or -FLT_MIN: right-align / size.x = 0.0f (default): use current ItemWidth
|
||||
@ -1136,8 +1138,8 @@ enum ImGuiWindowFlags_
|
||||
|
||||
// Obsolete names
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiWindowFlags_NavFlattened = 1 << 29, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call.
|
||||
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30, // Obsoleted in 1.90.0: Use ImGuiChildFlags_AlwaysUseWindowPadding in BeginChild() call.
|
||||
ImGuiWindowFlags_NavFlattened = 1 << 31, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call.
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1219,7 +1221,7 @@ enum ImGuiInputTextFlags_
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 << 20, // Callback on each iteration. User code may query cursor position, modify text buffer.
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 << 21, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard.
|
||||
ImGuiInputTextFlags_CallbackResize = 1 << 22, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 23, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 23, // Callback on any edit. Note that InputText() already returns true on edit + you can always use IsItemEdited(). The callback is useful to manipulate the underlying buffer while focus is active.
|
||||
|
||||
// Obsolete names
|
||||
//ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior
|
||||
@ -1242,14 +1244,16 @@ enum ImGuiTreeNodeFlags_
|
||||
ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node.
|
||||
ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode.
|
||||
ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area).
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text.
|
||||
ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (text will still fit in current column)
|
||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 15, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)
|
||||
ImGuiTreeNodeFlags_SpanLabelWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text.
|
||||
ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (label will still fit in current column)
|
||||
ImGuiTreeNodeFlags_LabelSpanAllColumns = 1 << 15, // Label will span all columns of its container table
|
||||
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 16, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible
|
||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 17, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop)
|
||||
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog,
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth,// Renamed in 1.90.7
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1457,6 +1461,7 @@ enum ImGuiDataType_
|
||||
ImGuiDataType_Float, // float
|
||||
ImGuiDataType_Double, // double
|
||||
ImGuiDataType_Bool, // bool (provided for user convenience, not supported by scalar widgets)
|
||||
ImGuiDataType_String, // char* (provided for user convenience, not supported by scalar widgets)
|
||||
ImGuiDataType_COUNT
|
||||
};
|
||||
|
||||
@ -1865,6 +1870,7 @@ enum ImGuiSliderFlags_
|
||||
ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max. Only supported by DragXXX() functions for now.
|
||||
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.
|
||||
ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
|
||||
ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.
|
||||
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
|
||||
ImGuiSliderFlags_InvalidMask_ = 0x7000000F, // [Internal] We treat using those bits as being potentially a 'float power' argument from the previous API that has got miscast to this enum, and will trigger an assert if needed.
|
||||
};
|
||||
@ -2535,7 +2541,7 @@ struct ImGuiIO
|
||||
// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used.
|
||||
// The callback function should return 0 by default.
|
||||
// Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details)
|
||||
// - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
|
||||
// - ImGuiInputTextFlags_CallbackEdit: Callback on buffer edit. Note that InputText() already returns true on edit + you can always use IsItemEdited(). The callback is useful to manipulate the underlying buffer while focus is active.
|
||||
// - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration
|
||||
// - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB
|
||||
// - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows
|
||||
@ -2810,6 +2816,7 @@ struct ImGuiListClipper
|
||||
// - It is important that we are keeping those disabled by default so they don't leak in user space.
|
||||
// - This is in order to allow user enabling implicit cast operators between ImVec2/ImVec4 and their own types (using IM_VEC2_CLASS_EXTRA in imconfig.h)
|
||||
// - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including this file (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4.
|
||||
// - We intentionally provide ImVec2*float but not float*ImVec2: this is rare enough and we want to reduce the surface for possible user mistake.
|
||||
#ifdef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
@ -3011,7 +3018,7 @@ struct ImGuiSelectionBasicStorage
|
||||
IMGUI_API void Clear(); // Clear selection
|
||||
IMGUI_API void Swap(ImGuiSelectionBasicStorage& r); // Swap two selections
|
||||
IMGUI_API void SetItemSelected(ImGuiID id, bool selected); // Add/remove an item from selection (generally done by ApplyRequests() function)
|
||||
IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiId id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||
IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiID id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||
inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter.
|
||||
};
|
||||
|
||||
@ -3399,7 +3406,7 @@ struct ImFontConfig
|
||||
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
||||
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
|
||||
ImWchar EllipsisChar; // -1 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||
|
||||
// [Internal]
|
||||
char Name[40]; // Name (strictly to ease debugging)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@ -101,6 +101,7 @@ Index of this file:
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#endif
|
||||
@ -139,6 +140,7 @@ struct ImGuiContext; // Main Dear ImGui context
|
||||
struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine
|
||||
struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum)
|
||||
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
|
||||
struct ImGuiDeactivatedItemData; // Data for IsItemDeactivated()/IsItemDeactivatedAfterEdit() function.
|
||||
struct ImGuiDockContext; // Docking system context
|
||||
struct ImGuiDockRequest; // Docking system dock/undock queued request
|
||||
struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
|
||||
@ -472,7 +474,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); }
|
||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
@ -842,8 +844,7 @@ struct ImGuiDataTypeInfo
|
||||
// Extend ImGuiDataType_
|
||||
enum ImGuiDataTypePrivate_
|
||||
{
|
||||
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_Pointer,
|
||||
ImGuiDataType_Pointer = ImGuiDataType_COUNT + 1,
|
||||
ImGuiDataType_ID,
|
||||
};
|
||||
|
||||
@ -929,7 +930,7 @@ enum ImGuiButtonFlagsPrivate_
|
||||
ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
|
||||
ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
|
||||
//ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
|
||||
//ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat -> use ImGuiItemFlags_ButtonRepeat instead.
|
||||
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
|
||||
ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable.
|
||||
//ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press
|
||||
@ -1086,7 +1087,7 @@ struct IMGUI_API ImGuiGroupData
|
||||
ImVec2 BackupCurrLineSize;
|
||||
float BackupCurrLineTextBaseOffset;
|
||||
ImGuiID BackupActiveIdIsAlive;
|
||||
bool BackupActiveIdPreviousFrameIsAlive;
|
||||
bool BackupDeactivatedIdIsAlive;
|
||||
bool BackupHoveredIdIsAlive;
|
||||
bool BackupIsSameLine;
|
||||
bool EmitItem;
|
||||
@ -1137,8 +1138,10 @@ struct IMGUI_API ImGuiInputTextState
|
||||
{
|
||||
ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent).
|
||||
ImStbTexteditState* Stb; // State for stb_textedit.h
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
ImGuiID ID; // widget id owning the text state
|
||||
int TextLen; // UTF-8 length of the string in TextA (in bytes)
|
||||
const char* TextSrc; // == TextA.Data unless read-only, in which case == buf passed to InputText(). Field only set and valid _inside_ the call InputText() call.
|
||||
ImVector<char> TextA; // main UTF8 buffer. TextA.Size is a buffer size! Should always be >= buf_size passed by user (and of course >= CurLenA + 1).
|
||||
ImVector<char> TextToRevertTo; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered)
|
||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||
@ -1148,9 +1151,8 @@ struct IMGUI_API ImGuiInputTextState
|
||||
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
|
||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||
bool Edited; // edited this frame
|
||||
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
|
||||
bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet.
|
||||
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
int ReloadSelectionStart;
|
||||
int ReloadSelectionEnd;
|
||||
|
||||
ImGuiInputTextState();
|
||||
@ -1270,11 +1272,11 @@ struct ImGuiNextItemData
|
||||
struct ImGuiLastItemData
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_
|
||||
ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_ (called 'InFlags' before v1.91.4).
|
||||
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
|
||||
ImRect Rect; // Full rectangle
|
||||
ImRect NavRect; // Navigation scoring rectangle (not displayed)
|
||||
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set.
|
||||
// Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags are set.
|
||||
ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set.
|
||||
ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set..
|
||||
ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set..
|
||||
@ -1337,6 +1339,15 @@ struct ImGuiPtrOrIndex
|
||||
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
|
||||
};
|
||||
|
||||
// Data used by IsItemDeactivated()/IsItemDeactivatedAfterEdit() functions
|
||||
struct ImGuiDeactivatedItemData
|
||||
{
|
||||
ImGuiID ID;
|
||||
int ElapseFrame;
|
||||
bool HasBeenEditedBefore;
|
||||
bool IsAlive;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Popup support
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2244,9 +2255,9 @@ struct ImGuiContext
|
||||
int FrameCountEnded;
|
||||
int FrameCountPlatformEnded;
|
||||
int FrameCountRendered;
|
||||
ImGuiID WithinEndChildID; // Set within EndChild()
|
||||
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
|
||||
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
|
||||
bool WithinEndChild; // Set within EndChild()
|
||||
bool GcCompactAll; // Request full GC
|
||||
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
|
||||
void* TestEngine; // Test engine user data
|
||||
@ -2306,9 +2317,8 @@ struct ImGuiContext
|
||||
ImGuiWindow* ActiveIdWindow;
|
||||
ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad
|
||||
ImGuiID ActiveIdPreviousFrame;
|
||||
bool ActiveIdPreviousFrameIsAlive;
|
||||
bool ActiveIdPreviousFrameHasBeenEditedBefore;
|
||||
ImGuiWindow* ActiveIdPreviousFrameWindow;
|
||||
ImGuiDeactivatedItemData DeactivatedItemData;
|
||||
ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX.
|
||||
ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
|
||||
float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
|
||||
|
||||
|
776
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
776
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@ -147,11 +147,15 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wformat-security" // warning: format string is not a string literal (potentially insecure)
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
// Play it nice with Windows users (Update: May 2018, Notepad now supports Unix-style carriage returns!)
|
||||
@ -303,6 +307,7 @@ struct ExampleMemberInfo
|
||||
// Metadata description of ExampleTreeNode struct.
|
||||
static const ExampleMemberInfo ExampleTreeNodeMemberInfos[]
|
||||
{
|
||||
{ "MyName", ImGuiDataType_String, 1, offsetof(ExampleTreeNode, Name) },
|
||||
{ "MyBool", ImGuiDataType_Bool, 1, offsetof(ExampleTreeNode, DataMyBool) },
|
||||
{ "MyInt", ImGuiDataType_S32, 1, offsetof(ExampleTreeNode, DataMyInt) },
|
||||
{ "MyVec2", ImGuiDataType_Float, 2, offsetof(ExampleTreeNode, DataMyVec2) },
|
||||
@ -799,18 +804,25 @@ static void ShowDemoWindowMenuBar(ImGuiDemoWindowData* demo_data)
|
||||
const bool has_debug_tools = false;
|
||||
#endif
|
||||
ImGui::MenuItem("Metrics/Debugger", NULL, &demo_data->ShowMetrics, has_debug_tools);
|
||||
if (ImGui::BeginMenu("Debug Options"))
|
||||
{
|
||||
ImGui::BeginDisabled(!has_debug_tools);
|
||||
ImGui::Checkbox("Highlight ID Conflicts", &io.ConfigDebugHighlightIdConflicts);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Checkbox("Assert on error recovery", &io.ConfigErrorRecoveryEnableAssert);
|
||||
ImGui::TextDisabled("(see Demo->Configuration for details & more)");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::MenuItem("Debug Log", NULL, &demo_data->ShowDebugLog, has_debug_tools);
|
||||
ImGui::MenuItem("ID Stack Tool", NULL, &demo_data->ShowIDStackTool, has_debug_tools);
|
||||
bool is_debugger_present = io.ConfigDebugIsDebuggerPresent;
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools && is_debugger_present))
|
||||
if (ImGui::MenuItem("Item Picker", NULL, false, has_debug_tools))// && is_debugger_present))
|
||||
ImGui::DebugStartItemPicker();
|
||||
if (!is_debugger_present)
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable the menu option to avoid casual users crashing the application.\n\nYou can however always access the Item Picker in Metrics->Tools.");
|
||||
ImGui::SetItemTooltip("Requires io.ConfigDebugIsDebuggerPresent=true to be set.\n\nWe otherwise disable some extra features to avoid casual users crashing the application.");
|
||||
ImGui::MenuItem("Style Editor", NULL, &demo_data->ShowStyleEditor);
|
||||
ImGui::MenuItem("About Dear ImGui", NULL, &demo_data->ShowAbout);
|
||||
|
||||
ImGui::SeparatorText("Debug Options");
|
||||
ImGui::MenuItem("Highlight ID Conflicts", NULL, &io.ConfigDebugHighlightIdConflicts, has_debug_tools);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
@ -1170,7 +1182,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &base_flags, ImGuiTreeNodeFlags_SpanLabelWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only.");
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)");
|
||||
@ -1207,9 +1219,9 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::Text("This is a drag and drop source");
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanTextWidth))
|
||||
if (i == 2 && (base_flags & ImGuiTreeNodeFlags_SpanLabelWidth))
|
||||
{
|
||||
// Item 2 has an additional inline button to help demonstrate SpanTextWidth.
|
||||
// Item 2 has an additional inline button to help demonstrate SpanLabelWidth.
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton("button")) {}
|
||||
}
|
||||
@ -2370,6 +2382,8 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
|
||||
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks);
|
||||
ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.");
|
||||
ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround);
|
||||
ImGui::SameLine(); HelpMarker("Enable wrapping around from max to min and from min to max (only supported by DragXXX() functions)");
|
||||
|
||||
@ -6418,15 +6432,17 @@ static void ShowDemoWindowTables()
|
||||
IMGUI_DEMO_MARKER("Tables/Tree view");
|
||||
if (ImGui::TreeNode("Tree view"))
|
||||
{
|
||||
static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
static ImGuiTableFlags table_flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||
|
||||
static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanTextWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
static ImGuiTreeNodeFlags tree_node_flags_base = ImGuiTreeNodeFlags_SpanAllColumns;
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanFullWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanLabelWidth", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanLabelWidth);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_SpanAllColumns);
|
||||
ImGui::CheckboxFlags("ImGuiTreeNodeFlags_LabelSpanAllColumns", &tree_node_flags_base, ImGuiTreeNodeFlags_LabelSpanAllColumns);
|
||||
ImGui::SameLine(); HelpMarker("Useful if you know that you aren't displaying contents in other columns");
|
||||
|
||||
HelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns.");
|
||||
if (ImGui::BeginTable("3ways", 3, flags))
|
||||
if (ImGui::BeginTable("3ways", 3, table_flags))
|
||||
{
|
||||
// The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On
|
||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoHide);
|
||||
@ -6447,13 +6463,21 @@ static void ShowDemoWindowTables()
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
const bool is_folder = (node->ChildCount > 0);
|
||||
|
||||
ImGuiTreeNodeFlags node_flags = tree_node_flags_base;
|
||||
if (node != &all_nodes[0])
|
||||
node_flags &= ~ImGuiTreeNodeFlags_LabelSpanAllColumns; // Only demonstrate this on the root node.
|
||||
|
||||
if (is_folder)
|
||||
{
|
||||
bool open = ImGui::TreeNodeEx(node->Name, tree_node_flags);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
bool open = ImGui::TreeNodeEx(node->Name, node_flags);
|
||||
if ((node_flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) == 0)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextDisabled("--");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(node->Type);
|
||||
}
|
||||
if (open)
|
||||
{
|
||||
for (int child_n = 0; child_n < node->ChildCount; child_n++)
|
||||
@ -6463,7 +6487,7 @@ static void ShowDemoWindowTables()
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui::TreeNodeEx(node->Name, tree_node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TreeNodeEx(node->Name, node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_Bullet | ImGuiTreeNodeFlags_NoTreePushOnOpen);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", node->Size);
|
||||
ImGui::TableNextColumn();
|
||||
@ -6473,7 +6497,7 @@ static void ShowDemoWindowTables()
|
||||
};
|
||||
static const MyTreeNode nodes[] =
|
||||
{
|
||||
{ "Root", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Root with Long Name", "Folder", -1, 1, 3 }, // 0
|
||||
{ "Music", "Folder", -1, 4, 2 }, // 1
|
||||
{ "Textures", "Folder", -1, 6, 3 }, // 2
|
||||
{ "desktop.ini", "System file", 1024, -1,-1 }, // 3
|
||||
@ -7761,7 +7785,8 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::TextLinkOpenURL("Funding", "https://github.com/ocornut/imgui/wiki/Funding");
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("By Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("(c) 2014-2025 Omar Cornut");
|
||||
ImGui::Text("Developed by Omar Cornut and all Dear ImGui contributors.");
|
||||
ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information.");
|
||||
ImGui::Text("If your company uses this, please consider funding the project.");
|
||||
|
||||
@ -7939,6 +7964,8 @@ void ImGui::ShowFontSelector(const char* label)
|
||||
ImGui::PushID((void*)font);
|
||||
if (ImGui::Selectable(font->GetDebugName(), font == font_current))
|
||||
io.FontDefault = font;
|
||||
if (font == font_current)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
@ -9065,6 +9092,8 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginTable("##properties", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY))
|
||||
{
|
||||
// Push object ID after we entered the table, so table is shared for all objects
|
||||
ImGui::PushID((int)node->UID);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 2.0f); // Default twice larger
|
||||
if (node->HasData)
|
||||
@ -9103,10 +9132,16 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::SliderScalarN("##Editor", field_desc.DataType, field_ptr, field_desc.DataCount, &v_min, &v_max);
|
||||
break;
|
||||
}
|
||||
case ImGuiDataType_String:
|
||||
{
|
||||
ImGui::InputText("##Editor", reinterpret_cast<char*>(field_ptr), 28);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@ -69,13 +69,17 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||||
#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -107,13 +111,12 @@ namespace IMGUI_STB_NAMESPACE
|
||||
#pragma clang diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#pragma clang diagnostic ignored "-Wcast-qual" // warning: cast from 'const xxxx *' to 'xxx *' drops const qualifier
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits]
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" // warning: this statement may fall through
|
||||
#endif
|
||||
|
||||
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
|
||||
@ -3130,12 +3133,44 @@ ImFontConfig::ImFontConfig()
|
||||
GlyphMaxAdvanceX = FLT_MAX;
|
||||
RasterizerMultiply = 1.0f;
|
||||
RasterizerDensity = 1.0f;
|
||||
EllipsisChar = (ImWchar)-1;
|
||||
EllipsisChar = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ImFontAtlas
|
||||
//-----------------------------------------------------------------------------
|
||||
// - Default texture data encoded in ASCII
|
||||
// - ImFontAtlas::ClearInputData()
|
||||
// - ImFontAtlas::ClearTexData()
|
||||
// - ImFontAtlas::ClearFonts()
|
||||
// - ImFontAtlas::Clear()
|
||||
// - ImFontAtlas::GetTexDataAsAlpha8()
|
||||
// - ImFontAtlas::GetTexDataAsRGBA32()
|
||||
// - ImFontAtlas::AddFont()
|
||||
// - ImFontAtlas::AddFontDefault()
|
||||
// - ImFontAtlas::AddFontFromFileTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedTTF()
|
||||
// - ImFontAtlas::AddFontFromMemoryCompressedBase85TTF()
|
||||
// - ImFontAtlas::AddCustomRectRegular()
|
||||
// - ImFontAtlas::AddCustomRectFontGlyph()
|
||||
// - ImFontAtlas::CalcCustomRectUV()
|
||||
// - ImFontAtlas::GetMouseCursorTexData()
|
||||
// - ImFontAtlas::Build()
|
||||
// - ImFontAtlasBuildMultiplyCalcLookupTable()
|
||||
// - ImFontAtlasBuildMultiplyRectAlpha8()
|
||||
// - ImFontAtlasBuildWithStbTruetype()
|
||||
// - ImFontAtlasGetBuilderForStbTruetype()
|
||||
// - ImFontAtlasUpdateConfigDataPointers()
|
||||
// - ImFontAtlasBuildSetupFont()
|
||||
// - ImFontAtlasBuildPackCustomRects()
|
||||
// - ImFontAtlasBuildRender8bppRectFromString()
|
||||
// - ImFontAtlasBuildRender32bppRectFromString()
|
||||
// - ImFontAtlasBuildRenderDefaultTexData()
|
||||
// - ImFontAtlasBuildRenderLinesTexData()
|
||||
// - ImFontAtlasBuildInit()
|
||||
// - ImFontAtlasBuildFinish()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// A work of art lies ahead! (. = white layer, X = black layer, others are blank)
|
||||
// The 2x2 white texels on the top left are the ones we'll use everywhere in Dear ImGui to render filled shapes.
|
||||
@ -3320,9 +3355,6 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||
// - We may support it better later and remove this rounding.
|
||||
new_font_cfg.SizePixels = ImTrunc(new_font_cfg.SizePixels);
|
||||
|
||||
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
|
||||
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
|
||||
|
||||
// Pointers to ConfigData and BuilderData are otherwise dangling
|
||||
ImFontAtlasUpdateConfigDataPointers(this);
|
||||
|
||||
@ -4304,6 +4336,16 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] ImFontAtlas: glyph ranges helpers
|
||||
//-------------------------------------------------------------------------
|
||||
// - GetGlyphRangesDefault()
|
||||
// - GetGlyphRangesGreek()
|
||||
// - GetGlyphRangesKorean()
|
||||
// - GetGlyphRangesChineseFull()
|
||||
// - GetGlyphRangesChineseSimplifiedCommon()
|
||||
// - GetGlyphRangesJapanese()
|
||||
// - GetGlyphRangesCyrillic()
|
||||
// - GetGlyphRangesThai()
|
||||
// - GetGlyphRangesVietnamese()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Retrieve list of range (2 int per range, values are inclusive)
|
||||
const ImWchar* ImFontAtlas::GetGlyphRangesDefault()
|
||||
@ -4612,8 +4654,8 @@ ImFont::ImFont()
|
||||
{
|
||||
FontSize = 0.0f;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
FallbackChar = (ImWchar)-1;
|
||||
EllipsisChar = (ImWchar)-1;
|
||||
FallbackChar = 0;
|
||||
EllipsisChar = 0;
|
||||
EllipsisWidth = EllipsisCharStep = 0.0f;
|
||||
EllipsisCharCount = 0;
|
||||
FallbackGlyph = NULL;
|
||||
@ -4652,7 +4694,7 @@ static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_cha
|
||||
for (int n = 0; n < candidate_chars_count; n++)
|
||||
if (font->FindGlyphNoFallback(candidate_chars[n]) != NULL)
|
||||
return candidate_chars[n];
|
||||
return (ImWchar)-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ImFont::BuildLookupTable()
|
||||
@ -4719,23 +4761,23 @@ void ImFont::BuildLookupTable()
|
||||
// Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
|
||||
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
|
||||
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
|
||||
const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar ellipsis_chars[] = { ConfigData->EllipsisChar, (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
|
||||
if (EllipsisChar == (ImWchar)-1)
|
||||
if (EllipsisChar == 0)
|
||||
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
|
||||
const ImWchar dot_char = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars));
|
||||
if (EllipsisChar != (ImWchar)-1)
|
||||
if (EllipsisChar != 0)
|
||||
{
|
||||
EllipsisCharCount = 1;
|
||||
EllipsisWidth = EllipsisCharStep = FindGlyph(EllipsisChar)->X1;
|
||||
}
|
||||
else if (dot_char != (ImWchar)-1)
|
||||
else if (dot_char != 0)
|
||||
{
|
||||
const ImFontGlyph* glyph = FindGlyph(dot_char);
|
||||
const ImFontGlyph* dot_glyph = FindGlyph(dot_char);
|
||||
EllipsisChar = dot_char;
|
||||
EllipsisCharCount = 3;
|
||||
EllipsisCharStep = (glyph->X1 - glyph->X0) + 1.0f;
|
||||
EllipsisWidth = EllipsisCharStep * 3.0f - 1.0f;
|
||||
EllipsisCharStep = (float)(int)(dot_glyph->X1 - dot_glyph->X0) + 1.0f;
|
||||
EllipsisWidth = ImMax(dot_glyph->AdvanceX, dot_glyph->X0 + EllipsisCharStep * 3.0f - 1.0f); // FIXME: Slightly odd for normally mono-space fonts but since this is used for trailing contents.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@ -232,7 +232,11 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow"
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#endif
|
||||
|
||||
@ -1333,7 +1337,11 @@ void ImGui::EndTable()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Only call EndTable() if BeginTable() returns true!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "EndTable() call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
// This assert would be very useful to catch a common error... unfortunately it would probably trigger in some
|
||||
// cases, and for consistency user may sometimes output empty tables (and still benefit from e.g. outer border)
|
||||
@ -1556,8 +1564,12 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call call TableSetupColumn() before first row!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 && "Illegal to pass StatusMask values to TableSetupColumn()");
|
||||
if (table->DeclColumnsCount >= table->ColumnsCount)
|
||||
{
|
||||
@ -1630,7 +1642,11 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
@ -1707,9 +1723,11 @@ void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL);
|
||||
if (!table)
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->Flags & ImGuiTableFlags_Hideable); // See comments above
|
||||
if (column_n < 0)
|
||||
column_n = table->CurrentColumn;
|
||||
@ -3030,7 +3048,11 @@ void ImGui::TableHeadersRow()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Call layout if not already done. This is automatically done by TableNextRow: we do it here _only_ to make
|
||||
// it easier to debug-step in TableUpdateLayout(). Your own version of this function doesn't need this.
|
||||
@ -3075,7 +3097,12 @@ void ImGui::TableHeader(const char* label)
|
||||
return;
|
||||
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
IM_ASSERT(table->CurrentColumn != -1);
|
||||
const int column_n = table->CurrentColumn;
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
@ -3250,7 +3277,11 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImDrawList* draw_list = window->DrawList;
|
||||
IM_ASSERT(table != NULL && "Need to call TableHeadersRow() after BeginTable()!");
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(table->CurrentRow == -1 && "Must be first row");
|
||||
|
||||
if (max_label_width == 0.0f)
|
||||
@ -3295,7 +3326,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
|
||||
const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
|
||||
|
||||
// Draw background and labels in first pass, then all borders.
|
||||
float max_x = 0.0f;
|
||||
float max_x = -FLT_MAX;
|
||||
for (int pass = 0; pass < 2; pass++)
|
||||
for (int order_n = 0; order_n < data_count; order_n++)
|
||||
{
|
||||
|
265
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
265
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.91.6
|
||||
// dear imgui, v1.91.7
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -82,9 +82,14 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||||
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@ -472,7 +477,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args)
|
||||
// - PressedOnDragDropHold can generally be associated with any flag.
|
||||
// - PressedOnDoubleClick can be associated by PressedOnClickRelease/PressedOnRelease, in which case the second release event won't be reported.
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// The behavior of the return-value changes when ImGuiButtonFlags_Repeat is set:
|
||||
// The behavior of the return-value changes when ImGuiItemFlags_ButtonRepeat is set:
|
||||
// Repeat+ Repeat+ Repeat+ Repeat+
|
||||
// PressedOnClickRelease PressedOnClick PressedOnRelease PressedOnDoubleClick
|
||||
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -2172,6 +2177,7 @@ static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{ sizeof(float), "float", "%.3f","%f" }, // ImGuiDataType_Float (float are promoted to double in va_arg)
|
||||
{ sizeof(double), "double","%f", "%lf" }, // ImGuiDataType_Double
|
||||
{ sizeof(bool), "bool", "%d", "%d" }, // ImGuiDataType_Bool
|
||||
{ 0, "char*","%s", "%s" }, // ImGuiDataType_String
|
||||
};
|
||||
IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT);
|
||||
|
||||
@ -2440,9 +2446,9 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
|
||||
{
|
||||
adjust_delta = g.IO.MouseDelta[axis];
|
||||
if (g.IO.KeyAlt)
|
||||
if (g.IO.KeyAlt && !(flags & ImGuiSliderFlags_NoSpeedTweaks))
|
||||
adjust_delta *= 1.0f / 100.0f;
|
||||
if (g.IO.KeyShift)
|
||||
if (g.IO.KeyShift && !(flags & ImGuiSliderFlags_NoSpeedTweaks))
|
||||
adjust_delta *= 10.0f;
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
@ -2450,7 +2456,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0;
|
||||
const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow);
|
||||
const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast);
|
||||
const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f;
|
||||
const float tweak_factor = (flags & ImGuiSliderFlags_NoSpeedTweaks) ? 1.0f : tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f;
|
||||
adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor;
|
||||
v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision));
|
||||
}
|
||||
@ -2638,6 +2644,10 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
temp_input_is_active = true;
|
||||
}
|
||||
|
||||
// Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert)
|
||||
if (make_active)
|
||||
memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size);
|
||||
|
||||
if (make_active && !temp_input_is_active)
|
||||
{
|
||||
SetActiveID(id, window);
|
||||
@ -3228,6 +3238,10 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
if ((clicked && g.IO.KeyCtrl) || (g.NavActivateId == id && (g.NavActivateFlags & ImGuiActivateFlags_PreferInput)))
|
||||
temp_input_is_active = true;
|
||||
|
||||
// Store initial value (not used by main lib but available as a convenience but some mods e.g. to revert)
|
||||
if (make_active)
|
||||
memcpy(&g.ActiveIdValueOnActivation, p_data, DataTypeGetInfo(data_type)->Size);
|
||||
|
||||
if (make_active && !temp_input_is_active)
|
||||
{
|
||||
SetActiveID(id, window);
|
||||
@ -3936,12 +3950,12 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c
|
||||
namespace ImStb
|
||||
{
|
||||
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->TextLen; }
|
||||
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextA[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextA.Data + line_start_idx + char_idx, obj->TextA.Data + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
||||
static char STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->TextLen); return obj->TextSrc[idx]; }
|
||||
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { unsigned int c; ImTextCharFromUtf8(&c, obj->TextSrc + line_start_idx + char_idx, obj->TextSrc + obj->TextLen); if ((ImWchar)c == '\n') return IMSTB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance((ImWchar)c) * g.FontScale; }
|
||||
static char STB_TEXTEDIT_NEWLINE = '\n';
|
||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
||||
{
|
||||
const char* text = obj->TextA.Data;
|
||||
const char* text = obj->TextSrc;
|
||||
const char* text_remaining = NULL;
|
||||
const ImVec2 size = InputTextCalcTextSize(obj->Ctx, text + line_start_idx, text + obj->TextLen, &text_remaining, NULL, true);
|
||||
r->x0 = 0.0f;
|
||||
@ -3960,15 +3974,15 @@ static int IMSTB_TEXTEDIT_GETNEXTCHARINDEX_IMPL(ImGuiInputTextState* obj, int id
|
||||
if (idx >= obj->TextLen)
|
||||
return obj->TextLen + 1;
|
||||
unsigned int c;
|
||||
return idx + ImTextCharFromUtf8(&c, obj->TextA.Data + idx, obj->TextA.Data + obj->TextLen);
|
||||
return idx + ImTextCharFromUtf8(&c, obj->TextSrc + idx, obj->TextSrc + obj->TextLen);
|
||||
}
|
||||
|
||||
static int IMSTB_TEXTEDIT_GETPREVCHARINDEX_IMPL(ImGuiInputTextState* obj, int idx)
|
||||
{
|
||||
if (idx <= 0)
|
||||
return -1;
|
||||
const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, obj->TextA.Data + idx);
|
||||
return (int)(p - obj->TextA.Data);
|
||||
const char* p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, obj->TextSrc + idx);
|
||||
return (int)(p - obj->TextSrc);
|
||||
}
|
||||
|
||||
static bool ImCharIsSeparatorW(unsigned int c)
|
||||
@ -3991,10 +4005,10 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
||||
if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0)
|
||||
return 0;
|
||||
|
||||
const char* curr_p = obj->TextA.Data + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||
const char* curr_p = obj->TextSrc + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, curr_p, obj->TextSrc + obj->TextLen);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, prev_p, obj->TextSrc + obj->TextLen);
|
||||
|
||||
bool prev_white = ImCharIsBlankW(prev_c);
|
||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||
@ -4007,10 +4021,10 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
|
||||
if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0)
|
||||
return 0;
|
||||
|
||||
const char* curr_p = obj->TextA.Data + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextA.Data, curr_p);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextA.Data + obj->TextLen);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextA.Data + obj->TextLen);
|
||||
const char* curr_p = obj->TextSrc + idx;
|
||||
const char* prev_p = ImTextFindPreviousUtf8Codepoint(obj->TextSrc, curr_p);
|
||||
unsigned int prev_c; ImTextCharFromUtf8(&prev_c, curr_p, obj->TextSrc + obj->TextLen);
|
||||
unsigned int curr_c; ImTextCharFromUtf8(&curr_c, prev_p, obj->TextSrc + obj->TextLen);
|
||||
|
||||
bool prev_white = ImCharIsBlankW(prev_c);
|
||||
bool prev_separ = ImCharIsSeparatorW(prev_c);
|
||||
@ -4047,16 +4061,13 @@ static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx)
|
||||
|
||||
static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
|
||||
{
|
||||
// Offset remaining text (+ copy zero terminator)
|
||||
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
||||
char* dst = obj->TextA.Data + pos;
|
||||
|
||||
char* src = obj->TextA.Data + pos + n;
|
||||
memmove(dst, src, obj->TextLen - n - pos + 1);
|
||||
obj->Edited = true;
|
||||
obj->TextLen -= n;
|
||||
|
||||
// Offset remaining text (FIXME-OPT: Use memmove)
|
||||
const char* src = obj->TextA.Data + pos + n;
|
||||
while (char c = *src++)
|
||||
*dst++ = c;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
|
||||
@ -4069,11 +4080,13 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
|
||||
return false;
|
||||
|
||||
// Grow internal buffer if needed
|
||||
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
|
||||
if (new_text_len + text_len + 1 > obj->TextA.Size)
|
||||
{
|
||||
if (!is_resizable)
|
||||
return false;
|
||||
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
|
||||
obj->TextSrc = obj->TextA.Data;
|
||||
}
|
||||
|
||||
char* text = obj->TextA.Data;
|
||||
@ -4171,26 +4184,25 @@ int ImGuiInputTextState::GetCursorPos() const { return Stb->cursor
|
||||
int ImGuiInputTextState::GetSelectionStart() const { return Stb->select_start; }
|
||||
int ImGuiInputTextState::GetSelectionEnd() const { return Stb->select_end; }
|
||||
void ImGuiInputTextState::SelectAll() { Stb->select_start = 0; Stb->cursor = Stb->select_end = TextLen; Stb->has_preferred_x = 0; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { ReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { ReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { ReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndSelectAll() { WantReloadUserBuf = true; ReloadSelectionStart = 0; ReloadSelectionEnd = INT_MAX; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndKeepSelection() { WantReloadUserBuf = true; ReloadSelectionStart = Stb->select_start; ReloadSelectionEnd = Stb->select_end; }
|
||||
void ImGuiInputTextState::ReloadUserBufAndMoveToEnd() { WantReloadUserBuf = true; ReloadSelectionStart = ReloadSelectionEnd = INT_MAX; }
|
||||
|
||||
ImGuiInputTextCallbackData::ImGuiInputTextCallbackData()
|
||||
{
|
||||
memset(this, 0, sizeof(*this));
|
||||
}
|
||||
|
||||
// Public API to manipulate UTF-8 text
|
||||
// We expose UTF-8 to the user (unlike the STB_TEXTEDIT_* functions which are manipulating wchar)
|
||||
// Public API to manipulate UTF-8 text from within a callback.
|
||||
// FIXME: The existence of this rarely exercised code path is a bit of a nuisance.
|
||||
// Historically they existed because STB_TEXTEDIT_INSERTCHARS() etc. worked on our ImWchar
|
||||
// buffer, but nowadays they both work on UTF-8 data. Should aim to merge both.
|
||||
void ImGuiInputTextCallbackData::DeleteChars(int pos, int bytes_count)
|
||||
{
|
||||
IM_ASSERT(pos + bytes_count <= BufTextLen);
|
||||
char* dst = Buf + pos;
|
||||
const char* src = Buf + pos + bytes_count;
|
||||
while (char c = *src++)
|
||||
*dst++ = c;
|
||||
*dst = '\0';
|
||||
memmove(dst, src, BufTextLen - bytes_count - pos + 1);
|
||||
|
||||
if (CursorPos >= pos + bytes_count)
|
||||
CursorPos -= bytes_count;
|
||||
@ -4215,13 +4227,13 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
||||
if (!is_resizable)
|
||||
return;
|
||||
|
||||
// Contrary to STB_TEXTEDIT_INSERTCHARS() this is working in the UTF8 buffer, hence the mildly similar code (until we remove the U16 buffer altogether!)
|
||||
ImGuiContext& g = *Ctx;
|
||||
ImGuiInputTextState* edit_state = &g.InputTextState;
|
||||
IM_ASSERT(edit_state->ID != 0 && g.ActiveId == edit_state->ID);
|
||||
IM_ASSERT(Buf == edit_state->TextA.Data);
|
||||
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
|
||||
edit_state->TextA.resize(new_buf_size + 1);
|
||||
edit_state->TextSrc = edit_state->TextA.Data;
|
||||
Buf = edit_state->TextA.Data;
|
||||
BufSize = edit_state->BufCapacity = new_buf_size;
|
||||
}
|
||||
@ -4339,26 +4351,23 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find the shortest single replacement we can make to get the new text from the old text.
|
||||
// Important: needs to be run before TextW is rewritten with the new characters because calling STB_TEXTEDIT_GETCHAR() at the end.
|
||||
// Find the shortest single replacement we can make to get from old_buf to new_buf
|
||||
// Note that this doesn't directly alter state->TextA, state->TextLen. They are expected to be made valid separately.
|
||||
// FIXME: Ideally we should transition toward (1) making InsertChars()/DeleteChars() update undo-stack (2) discourage (and keep reconcile) or obsolete (and remove reconcile) accessing buffer directly.
|
||||
static void InputTextReconcileUndoStateAfterUserCallback(ImGuiInputTextState* state, const char* new_buf_a, int new_length_a)
|
||||
static void InputTextReconcileUndoState(ImGuiInputTextState* state, const char* old_buf, int old_length, const char* new_buf, int new_length)
|
||||
{
|
||||
const char* old_buf = state->CallbackTextBackup.Data;
|
||||
const int old_length = state->CallbackTextBackup.Size - 1;
|
||||
|
||||
const int shorter_length = ImMin(old_length, new_length_a);
|
||||
const int shorter_length = ImMin(old_length, new_length);
|
||||
int first_diff;
|
||||
for (first_diff = 0; first_diff < shorter_length; first_diff++)
|
||||
if (old_buf[first_diff] != new_buf_a[first_diff])
|
||||
if (old_buf[first_diff] != new_buf[first_diff])
|
||||
break;
|
||||
if (first_diff == old_length && first_diff == new_length_a)
|
||||
if (first_diff == old_length && first_diff == new_length)
|
||||
return;
|
||||
|
||||
int old_last_diff = old_length - 1;
|
||||
int new_last_diff = new_length_a - 1;
|
||||
int new_last_diff = new_length - 1;
|
||||
for (; old_last_diff >= first_diff && new_last_diff >= first_diff; old_last_diff--, new_last_diff--)
|
||||
if (old_buf[old_last_diff] != new_buf_a[new_last_diff])
|
||||
if (old_buf[old_last_diff] != new_buf[new_last_diff])
|
||||
break;
|
||||
|
||||
const int insert_len = new_last_diff - first_diff + 1;
|
||||
@ -4387,6 +4396,7 @@ void ImGui::InputTextDeactivateHook(ImGuiID id)
|
||||
else
|
||||
{
|
||||
IM_ASSERT(state->TextA.Data != 0);
|
||||
IM_ASSERT(state->TextA[state->TextLen] == 0);
|
||||
g.InputTextDeactivatedState.TextA.resize(state->TextLen + 1);
|
||||
memcpy(g.InputTextDeactivatedState.TextA.Data, state->TextA.Data, state->TextLen + 1);
|
||||
}
|
||||
@ -4510,64 +4520,67 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
float scroll_y = is_multiline ? draw_window->Scroll.y : FLT_MAX;
|
||||
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->ReloadUserBuf);
|
||||
const bool init_reload_from_user_buf = (state != NULL && state->WantReloadUserBuf);
|
||||
const bool init_changed_specs = (state != NULL && state->Stb->single_line != !is_multiline); // state != NULL means its our state.
|
||||
const bool init_make_active = (user_clicked || user_scroll_finish || input_requested_by_nav);
|
||||
const bool init_state = (init_make_active || user_scroll_active);
|
||||
if ((init_state && g.ActiveId != id) || init_changed_specs || init_reload_from_user_buf)
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
int new_len = (int)strlen(buf);
|
||||
IM_ASSERT(new_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->WantReloadUserBuf = false;
|
||||
InputTextReconcileUndoState(state, state->TextA.Data, state->TextLen, buf, new_len);
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
state->TextLen = new_len;
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
state->Stb->select_start = state->ReloadSelectionStart;
|
||||
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
|
||||
state->CursorClamp();
|
||||
}
|
||||
else if ((init_state && g.ActiveId != id) || init_changed_specs)
|
||||
{
|
||||
// Access state even if we don't own it yet.
|
||||
state = &g.InputTextState;
|
||||
state->CursorAnimReset();
|
||||
state->ReloadUserBuf = false;
|
||||
|
||||
// Backup state of deactivating item so they'll have a chance to do a write to output buffer on the same frame they report IsItemDeactivatedAfterEdit (#4714)
|
||||
InputTextDeactivateHook(state->ID);
|
||||
|
||||
// Take a copy of the initial buffer value.
|
||||
// From the moment we focused we are normally ignoring the content of 'buf' (unless we are in read-only mode)
|
||||
const int buf_len = (int)strlen(buf);
|
||||
if (!init_reload_from_user_buf)
|
||||
{
|
||||
// Take a copy of the initial buffer value.
|
||||
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||
}
|
||||
IM_ASSERT(buf_len + 1 <= buf_size && "Is your input buffer properly zero-terminated?");
|
||||
state->TextToRevertTo.resize(buf_len + 1); // UTF-8. we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextToRevertTo.Data, buf, buf_len + 1);
|
||||
|
||||
// Preserve cursor position and undo/redo stack if we come back to same widget
|
||||
// FIXME: Since we reworked this on 2022/06, may want to differentiate recycle_cursor vs recycle_undostate?
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs && !init_reload_from_user_buf);
|
||||
if (recycle_state && (state->TextLen != buf_len || (strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
bool recycle_state = (state->ID == id && !init_changed_specs);
|
||||
if (recycle_state && (state->TextLen != buf_len || (state->TextA.Data == NULL || strncmp(state->TextA.Data, buf, buf_len) != 0)))
|
||||
recycle_state = false;
|
||||
|
||||
// Start edition
|
||||
state->ID = id;
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
state->TextLen = (int)strlen(buf);
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
state->TextLen = buf_len;
|
||||
if (!is_readonly)
|
||||
{
|
||||
state->TextA.resize(buf_size + 1); // we use +1 to make sure that .Data is always pointing to at least an empty string.
|
||||
memcpy(state->TextA.Data, buf, state->TextLen + 1);
|
||||
}
|
||||
|
||||
// Find initial scroll position for right alignment
|
||||
state->Scroll = ImVec2(0.0f, 0.0f);
|
||||
if (flags & ImGuiInputTextFlags_ElideLeft)
|
||||
state->Scroll.x += ImMax(0.0f, CalcTextSize(buf).x - frame_size.x + style.FramePadding.x * 2.0f);
|
||||
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
|
||||
if (recycle_state)
|
||||
{
|
||||
// Recycle existing cursor/selection/undo stack but clamp position
|
||||
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
|
||||
state->CursorClamp();
|
||||
}
|
||||
else
|
||||
{
|
||||
stb_textedit_initialize_state(state->Stb, !is_multiline);
|
||||
}
|
||||
|
||||
if (init_reload_from_user_buf)
|
||||
{
|
||||
state->Stb->select_start = state->ReloadSelectionStart;
|
||||
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
|
||||
state->CursorClamp();
|
||||
}
|
||||
else if (!is_multiline)
|
||||
if (!is_multiline)
|
||||
{
|
||||
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
||||
select_all = true;
|
||||
@ -4617,7 +4630,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Expose scroll in a manner that is agnostic to us using a child window
|
||||
if (is_multiline && state != NULL)
|
||||
state->Scroll.y = draw_window->Scroll.y;
|
||||
|
||||
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
|
||||
if (is_readonly && state != NULL)
|
||||
state->TextLen = (int)strlen(buf);
|
||||
//if (is_readonly && state != NULL)
|
||||
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
|
||||
}
|
||||
if (state != NULL)
|
||||
state->TextSrc = is_readonly ? buf : state->TextA.Data;
|
||||
|
||||
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function)
|
||||
if (g.ActiveId == id && state == NULL)
|
||||
@ -4882,13 +4903,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// Cut, Copy
|
||||
if (g.PlatformIO.Platform_SetClipboardTextFn != NULL)
|
||||
{
|
||||
// SetClipboardText() only takes null terminated strings + state->TextSrc may point to read-only user buffer, so we need to make a copy.
|
||||
const int ib = state->HasSelection() ? ImMin(state->Stb->select_start, state->Stb->select_end) : 0;
|
||||
const int ie = state->HasSelection() ? ImMax(state->Stb->select_start, state->Stb->select_end) : state->TextLen;
|
||||
|
||||
char backup = state->TextA.Data[ie];
|
||||
state->TextA.Data[ie] = 0; // A bit of a hack since SetClipboardText only takes null terminated strings
|
||||
SetClipboardText(state->TextA.Data + ib);
|
||||
state->TextA.Data[ie] = backup;
|
||||
g.TempBuffer.reserve(ie - ib + 1);
|
||||
memcpy(g.TempBuffer.Data, state->TextSrc + ib, ie - ib);
|
||||
g.TempBuffer.Data[ie - ib] = 0;
|
||||
SetClipboardText(g.TempBuffer.Data);
|
||||
}
|
||||
if (is_cut)
|
||||
{
|
||||
@ -4904,25 +4925,27 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Filter pasted buffer
|
||||
const int clipboard_len = (int)strlen(clipboard);
|
||||
char* clipboard_filtered = (char*)IM_ALLOC(clipboard_len + 1);
|
||||
int clipboard_filtered_len = 0;
|
||||
ImVector<char> clipboard_filtered;
|
||||
clipboard_filtered.reserve(clipboard_len + 1);
|
||||
for (const char* s = clipboard; *s != 0; )
|
||||
{
|
||||
unsigned int c;
|
||||
int len = ImTextCharFromUtf8(&c, s, NULL);
|
||||
s += len;
|
||||
int in_len = ImTextCharFromUtf8(&c, s, NULL);
|
||||
s += in_len;
|
||||
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
|
||||
continue;
|
||||
memcpy(clipboard_filtered + clipboard_filtered_len, s - len, len);
|
||||
clipboard_filtered_len += len;
|
||||
char c_utf8[5];
|
||||
ImTextCharToUtf8(c_utf8, c);
|
||||
int out_len = (int)strlen(c_utf8);
|
||||
clipboard_filtered.resize(clipboard_filtered.Size + out_len);
|
||||
memcpy(clipboard_filtered.Data + clipboard_filtered.Size - out_len, c_utf8, out_len);
|
||||
}
|
||||
clipboard_filtered[clipboard_filtered_len] = 0;
|
||||
if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation
|
||||
if (clipboard_filtered.Size > 0) // If everything was filtered, ignore the pasting operation
|
||||
{
|
||||
stb_textedit_paste(state, state->Stb, clipboard_filtered, clipboard_filtered_len);
|
||||
clipboard_filtered.push_back(0);
|
||||
stb_textedit_paste(state, state->Stb, clipboard_filtered.Data, clipboard_filtered.Size - 1);
|
||||
state->CursorFollow = true;
|
||||
}
|
||||
MemFree(clipboard_filtered);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4960,19 +4983,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
}
|
||||
|
||||
// When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer
|
||||
// before clearing ActiveId, even though strictly speaking it wasn't modified on this frame.
|
||||
// If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail.
|
||||
// This also allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage
|
||||
// FIXME-OPT: We always reapply the live buffer back to the input buffer before clearing ActiveId,
|
||||
// even though strictly speaking it wasn't modified on this frame. Should mark dirty state from the stb_textedit callbacks.
|
||||
// If we do that, need to ensure that as special case, 'validated == true' also writes back.
|
||||
// This also allows the user to use InputText() without maintaining any user-side storage.
|
||||
// (please note that if you use this property along ImGuiInputTextFlags_CallbackResize you can end up with your temporary string object
|
||||
// unnecessarily allocating once a frame, either store your string data, either if you don't then don't use ImGuiInputTextFlags_CallbackResize).
|
||||
const bool apply_edit_back_to_user_buffer = !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0);
|
||||
const bool apply_edit_back_to_user_buffer = true;// !revert_edit || (validated && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0);
|
||||
if (apply_edit_back_to_user_buffer)
|
||||
{
|
||||
// Apply new value immediately - copy modified buffer back
|
||||
// Apply current edited text immediately.
|
||||
// Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer
|
||||
// FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect.
|
||||
// FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks.
|
||||
|
||||
// User callback
|
||||
if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackEdit | ImGuiInputTextFlags_CallbackAlways)) != 0)
|
||||
@ -5015,10 +5036,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
callback_data.UserData = callback_user_data;
|
||||
|
||||
// FIXME-OPT: Undo stack reconcile needs a backup of the data until we rework API, see #7925
|
||||
state->CallbackTextBackup.resize(state->TextLen + 1);
|
||||
memcpy(state->CallbackTextBackup.Data, state->TextA.Data, state->TextLen + 1);
|
||||
|
||||
char* callback_buf = is_readonly ? buf : state->TextA.Data;
|
||||
IM_ASSERT(callback_buf == state->TextSrc);
|
||||
state->CallbackTextBackup.resize(state->TextLen + 1);
|
||||
memcpy(state->CallbackTextBackup.Data, callback_buf, state->TextLen + 1);
|
||||
|
||||
callback_data.EventKey = event_key;
|
||||
callback_data.Buf = callback_buf;
|
||||
callback_data.BufTextLen = state->TextLen;
|
||||
@ -5045,7 +5067,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
{
|
||||
// Callback may update buffer and thus set buf_dirty even in read-only mode.
|
||||
IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
|
||||
InputTextReconcileUndoStateAfterUserCallback(state, callback_data.Buf, callback_data.BufTextLen); // FIXME: Move the rest of this block inside function and rename to InputTextReconcileStateAfterUserCallback() ?
|
||||
InputTextReconcileUndoState(state, state->CallbackTextBackup.Data, state->CallbackTextBackup.Size - 1, callback_data.Buf, callback_data.BufTextLen);
|
||||
state->TextLen = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen()
|
||||
state->CursorAnimReset();
|
||||
}
|
||||
@ -5053,9 +5075,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
|
||||
// Will copy result string if modified
|
||||
if (!is_readonly && strcmp(state->TextA.Data, buf) != 0)
|
||||
if (!is_readonly && strcmp(state->TextSrc, buf) != 0)
|
||||
{
|
||||
apply_new_text = state->TextA.Data;
|
||||
apply_new_text = state->TextSrc;
|
||||
apply_new_text_length = state->TextLen;
|
||||
value_changed = true;
|
||||
}
|
||||
@ -5149,7 +5171,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
// - Measure text height (for scrollbar)
|
||||
// We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort)
|
||||
// FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8.
|
||||
const char* text_begin = state->TextA.Data;
|
||||
const char* text_begin = buf_display;
|
||||
const char* text_end = text_begin + state->TextLen;
|
||||
ImVec2 cursor_offset, select_start_offset;
|
||||
|
||||
@ -5330,6 +5352,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
g.LastItemData.StatusFlags = item_data_backup.StatusFlags;
|
||||
}
|
||||
}
|
||||
if (state)
|
||||
state->TextSrc = NULL;
|
||||
|
||||
// Log as text
|
||||
if (g.LogEnabled && (!is_password || is_displaying_hint))
|
||||
@ -6515,10 +6539,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2);
|
||||
const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL);
|
||||
ImRect frame_bb;
|
||||
frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x;
|
||||
frame_bb.Min.y = window->DC.CursorPos.y;
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanTextWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x;
|
||||
frame_bb.Max.y = window->DC.CursorPos.y + frame_height;
|
||||
if (display_frame)
|
||||
{
|
||||
@ -6532,7 +6557,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
|
||||
ImRect interact_bb = frame_bb;
|
||||
if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanTextWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0)
|
||||
if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanLabelWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0)
|
||||
interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f);
|
||||
|
||||
// Compute open and multi-select states before ItemAdd() as it clear NextItem data.
|
||||
@ -6540,7 +6565,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
bool is_open = TreeNodeUpdateNextOpen(storage_id, flags);
|
||||
|
||||
bool is_visible;
|
||||
if (span_all_columns)
|
||||
if (span_all_columns || span_all_columns_label)
|
||||
{
|
||||
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable..
|
||||
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
|
||||
@ -6581,7 +6606,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
return is_open;
|
||||
}
|
||||
|
||||
if (span_all_columns)
|
||||
if (span_all_columns || span_all_columns_label)
|
||||
{
|
||||
TablePushBackgroundChannel();
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasClipRect;
|
||||
@ -6734,7 +6759,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
LogSetNextTextDecoration(">", NULL);
|
||||
}
|
||||
|
||||
if (span_all_columns)
|
||||
if (span_all_columns && !span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
|
||||
// Label
|
||||
@ -6742,6 +6767,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
else
|
||||
RenderText(text_pos, label, label_end, false);
|
||||
|
||||
if (span_all_columns_label)
|
||||
TablePopBackgroundChannel();
|
||||
}
|
||||
|
||||
if (store_tree_node_stack_data && is_open)
|
||||
@ -7500,6 +7528,12 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel
|
||||
if (flags & ImGuiMultiSelectFlags_BoxSelect2d)
|
||||
flags &= ~ImGuiMultiSelectFlags_BoxSelect1d;
|
||||
|
||||
// FIXME: Workaround to the fact we override CursorMaxPos, meaning size measurement are lost. (#8250)
|
||||
// They should perhaps be stacked properly?
|
||||
if (ImGuiTable* table = g.CurrentTable)
|
||||
if (table->CurrentColumn != -1)
|
||||
TableEndCell(table); // This is currently safe to call multiple time. If that properly is lost we can extract the "save measurement" part of it.
|
||||
|
||||
// FIXME: BeginFocusScope()
|
||||
const ImGuiID id = window->IDStack.back();
|
||||
ms->Clear();
|
||||
@ -8213,15 +8247,10 @@ void ImGuiSelectionExternalStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
|
||||
// This handle some subtleties with capturing info from the label, but for 99% uses it could essentially be rewritten as:
|
||||
// if (ImGui::BeginChild("...", ImVec2(ImGui::CalcItemWidth(), ImGui::GetTextLineHeight() * 7.5f), ImGuiChildFlags_FrameStyle))
|
||||
// { .... }
|
||||
// ImGui::EndChild();
|
||||
// ImGui::SameLine();
|
||||
// ImGui::AlignTextToFramePadding();
|
||||
// ImGui::Text("Label");
|
||||
// This handle some subtleties with capturing info from the label.
|
||||
// If you don't need a label you can pretty much directly use ImGui::BeginChild() with ImGuiChildFlags_FrameStyle.
|
||||
// Tip: To have a list filling the entire window width, use size.x = -FLT_MIN and pass an non-visible label e.g. "##empty"
|
||||
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.25 * item_height).
|
||||
// Tip: If your vertical size is calculated from an item count (e.g. 10 * item_height) consider adding a fractional part to facilitate seeing scrolling boundaries (e.g. 10.5f * item_height).
|
||||
bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -8701,7 +8730,7 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
|
||||
viewport->BuildWorkInsetMax[axis] += axis_size;
|
||||
}
|
||||
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
|
||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||
|
||||
// Create window
|
||||
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
||||
|
Loading…
x
Reference in New Issue
Block a user