Merge branch 'master' into docking
This commit is contained in:
commit
367b2c24f3
@ -4018,6 +4018,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
|
|||||||
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
|
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
|
||||||
// better advantage of the render function taking size into account for coarse clipping.
|
// better advantage of the render function taking size into account for coarse clipping.
|
||||||
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||||
|
// DOES NOT CALL LogRenderedText(), unlike RenderTextClipped!!!
|
||||||
{
|
{
|
||||||
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
||||||
ImVec2 pos = pos_min;
|
ImVec2 pos = pos_min;
|
||||||
|
|||||||
14
imgui.h
14
imgui.h
@ -30,7 +30,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.93.0 WIP"
|
#define IMGUI_VERSION "1.93.0 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19296
|
#define IMGUI_VERSION_NUM 19297
|
||||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||||
@ -1305,7 +1305,6 @@ enum ImGuiItemFlags_
|
|||||||
ImGuiItemFlags_AutoClosePopups = 1 << 4, // true // MenuItem()/Selectable() automatically close their parent popup window.
|
ImGuiItemFlags_AutoClosePopups = 1 << 4, // true // MenuItem()/Selectable() automatically close their parent popup window.
|
||||||
ImGuiItemFlags_AllowDuplicateId = 1 << 5, // false // Allow submitting an item with the same identifier as an item already submitted this frame without triggering a warning tooltip if io.ConfigDebugHighlightIdConflicts is set.
|
ImGuiItemFlags_AllowDuplicateId = 1 << 5, // false // Allow submitting an item with the same identifier as an item already submitted this frame without triggering a warning tooltip if io.ConfigDebugHighlightIdConflicts is set.
|
||||||
ImGuiItemFlags_Disabled = 1 << 6, // false // [Internal] Disable interactions. DOES NOT affect visuals. This is used by BeginDisabled()/EndDisabled() and only provided here so you can read back via GetItemFlags().
|
ImGuiItemFlags_Disabled = 1 << 6, // false // [Internal] Disable interactions. DOES NOT affect visuals. This is used by BeginDisabled()/EndDisabled() and only provided here so you can read back via GetItemFlags().
|
||||||
ImGuiItemFlags_MixedValue = 1 << 9, // false // [BETA] Represent a mixed/indeterminate value. Replace value label with "-" and apply edits on validation. Only supported by some widgets: Checkbox, RadioButton, Sliders and Drags.
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
// LiveEdit refers to applying edits to backing variables _while_ typing a value using the keyboard.
|
// LiveEdit refers to applying edits to backing variables _while_ typing a value using the keyboard.
|
||||||
@ -1319,6 +1318,17 @@ enum ImGuiItemFlags_
|
|||||||
ImGuiItemFlags_LiveEditOnInputText = 1 << 7, // true // InputText: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
ImGuiItemFlags_LiveEditOnInputText = 1 << 7, // true // InputText: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
||||||
ImGuiItemFlags_LiveEditOnInputScalar = 1 << 8, // false // DragXXX, SliderXXX, InputScalar: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
ImGuiItemFlags_LiveEditOnInputScalar = 1 << 8, // false // DragXXX, SliderXXX, InputScalar: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
||||||
ImGuiItemFlags_LiveEditOnInput = ImGuiItemFlags_LiveEditOnInputText | ImGuiItemFlags_LiveEditOnInputScalar,
|
ImGuiItemFlags_LiveEditOnInput = ImGuiItemFlags_LiveEditOnInputText | ImGuiItemFlags_LiveEditOnInputScalar,
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
// [BETA] MixedValue mode used to represent a mixed/indeterminate state, typically for multi-selection.
|
||||||
|
// - Replace value display with "-" or a custom label.
|
||||||
|
// - Enter key validation apply an edit and return true even if value hasn't changed (in order to apply to all).
|
||||||
|
// - Supported by selected widgets: Checkbox, RadioButton, Sliders, Drags, Inputs, Combo.
|
||||||
|
// - Note: InputText-side Undo cannot be reliably combined with MixedValue + LiveEdit On:
|
||||||
|
// - Both the initial edit and subsequent undo/revert will typically make your app code write to all backing objects.
|
||||||
|
// - If you use MixedMode and the simplest solution is to ensure LiveEdit is off but widgets where this applies.
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
|
ImGuiItemFlags_MixedValue = 1 << 9, // false // [BETA] Represent a mixed/indeterminate value. Replace value label with "-" and apply edits on validation.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Flags for ImGui::InputText()
|
// Flags for ImGui::InputText()
|
||||||
|
|||||||
@ -2133,13 +2133,16 @@ static void DemoWindowWidgetsMixedValues()
|
|||||||
// This is designed for advanced property editors which are generally reusable and data-driven.
|
// This is designed for advanced property editors which are generally reusable and data-driven.
|
||||||
HelpMarker("Using ImGuiItemFlags_MixedValue.");
|
HelpMarker("Using ImGuiItemFlags_MixedValue.");
|
||||||
|
|
||||||
|
static bool use_liveedit = false;
|
||||||
static float items[3] = { 12.0f, 0.0f, 0.0f };
|
static float items[3] = { 12.0f, 0.0f, 0.0f };
|
||||||
float* item_ref = &items[0];
|
float* item_ref = &items[0];
|
||||||
|
ImGui::Checkbox("ImGuiItemFlags_LiveEditOnInput", &use_liveedit);
|
||||||
|
|
||||||
ImGui::SeparatorText("Scalar/Text Widgets");
|
ImGui::SeparatorText("Scalar/Text Widgets");
|
||||||
const bool is_mixed = memcmp(&items[0], &items[1], sizeof(float)) != 0 || memcmp(&items[0], &items[2], sizeof(float)) != 0;
|
const bool is_mixed = memcmp(&items[0], &items[1], sizeof(float)) != 0 || memcmp(&items[0], &items[2], sizeof(float)) != 0;
|
||||||
|
|
||||||
// Demonstrate Drags, Sliders, Inputs
|
// Demonstrate Drags, Sliders, Inputs
|
||||||
|
ImGui::PushItemFlag(ImGuiItemFlags_LiveEditOnInput, use_liveedit);
|
||||||
ImGui::PushItemFlag(ImGuiItemFlags_MixedValue, is_mixed);
|
ImGui::PushItemFlag(ImGuiItemFlags_MixedValue, is_mixed);
|
||||||
bool edited = false;
|
bool edited = false;
|
||||||
edited |= ImGui::DragFloat("DragFloat", item_ref);
|
edited |= ImGui::DragFloat("DragFloat", item_ref);
|
||||||
@ -2155,6 +2158,7 @@ static void DemoWindowWidgetsMixedValues()
|
|||||||
ImGui::InputFloat("item 0 (ref)", &items[0]);
|
ImGui::InputFloat("item 0 (ref)", &items[0]);
|
||||||
ImGui::InputFloat("item 1", &items[1]);
|
ImGui::InputFloat("item 1", &items[1]);
|
||||||
ImGui::InputFloat("item 2", &items[2]);
|
ImGui::InputFloat("item 2", &items[2]);
|
||||||
|
ImGui::PopItemFlag();
|
||||||
|
|
||||||
// Demonstrate Checkbox(), RadioButton(), Combo(), ColorEdit4()
|
// Demonstrate Checkbox(), RadioButton(), Combo(), ColorEdit4()
|
||||||
ImGui::SeparatorText("Others Widgets");
|
ImGui::SeparatorText("Others Widgets");
|
||||||
|
|||||||
@ -194,6 +194,7 @@ struct ImGuiWindow; // Storage for one window
|
|||||||
struct ImGuiWindowDockStyle; // Storage for window-style data which needs to be stored for docking purpose
|
struct ImGuiWindowDockStyle; // Storage for window-style data which needs to be stored for docking purpose
|
||||||
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
|
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
|
||||||
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
||||||
|
struct ImGuiWindowStackData; // Storage for each window pushed into the stack
|
||||||
|
|
||||||
// Enumerations
|
// Enumerations
|
||||||
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
||||||
@ -943,6 +944,8 @@ struct ImFontStackData
|
|||||||
// [SECTION] Style support
|
// [SECTION] Style support
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define ImGuiCol_TextMixedValue ImGuiCol_TextDisabled
|
||||||
|
|
||||||
struct ImGuiStyleVarInfo
|
struct ImGuiStyleVarInfo
|
||||||
{
|
{
|
||||||
ImU32 Count : 8; // 1+
|
ImU32 Count : 8; // 1+
|
||||||
@ -1093,12 +1096,6 @@ enum ImGuiButtonFlagsPrivate_
|
|||||||
//ImGuiButtonFlags_NoKeyModifiers = ImGuiButtonFlags_NoKeyModsAllowed, // Renamed in 1.91.4
|
//ImGuiButtonFlags_NoKeyModifiers = ImGuiButtonFlags_NoKeyModsAllowed, // Renamed in 1.91.4
|
||||||
};
|
};
|
||||||
|
|
||||||
// Extend ImGuiComboFlags_
|
|
||||||
enum ImGuiComboFlagsPrivate_
|
|
||||||
{
|
|
||||||
ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview()
|
|
||||||
};
|
|
||||||
|
|
||||||
// Extend ImGuiSliderFlags_
|
// Extend ImGuiSliderFlags_
|
||||||
enum ImGuiSliderFlagsPrivate_
|
enum ImGuiSliderFlagsPrivate_
|
||||||
{
|
{
|
||||||
@ -1193,6 +1190,10 @@ enum ImGuiPlotType
|
|||||||
ImGuiPlotType_Histogram,
|
ImGuiPlotType_Histogram,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
//ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview() // [Obsoleted in 1.93.0] Unnecessary: can now use BeginComboPreview() without a flag.
|
||||||
|
#endif
|
||||||
|
|
||||||
// Storage data for BeginComboPreview()/EndComboPreview()
|
// Storage data for BeginComboPreview()/EndComboPreview()
|
||||||
struct IMGUI_API ImGuiComboPreviewData
|
struct IMGUI_API ImGuiComboPreviewData
|
||||||
{
|
{
|
||||||
@ -1201,7 +1202,10 @@ struct IMGUI_API ImGuiComboPreviewData
|
|||||||
ImVec2 BackupCursorMaxPos;
|
ImVec2 BackupCursorMaxPos;
|
||||||
ImVec2 BackupCursorPosPrevLine;
|
ImVec2 BackupCursorPosPrevLine;
|
||||||
float BackupPrevLineTextBaseOffset;
|
float BackupPrevLineTextBaseOffset;
|
||||||
ImGuiLayoutType BackupLayout;
|
float BackupWorkRectMaxX;
|
||||||
|
float BackupContentRectMaxX;
|
||||||
|
ImGuiLayoutType BackupLayout : 8;
|
||||||
|
int WithinPreview : 2;
|
||||||
|
|
||||||
ImGuiComboPreviewData() { memset((void*)this, 0, sizeof(*this)); }
|
ImGuiComboPreviewData() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@ -1290,6 +1294,7 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||||
bool EditedBefore; // edited since activated
|
bool EditedBefore; // edited since activated
|
||||||
bool EditedThisFrame; // edited this frame
|
bool EditedThisFrame; // edited this frame
|
||||||
|
bool ValidatedThisFrame;
|
||||||
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||||
ImS8 LastMoveDirectionLR; // ImGuiDir_Left or ImGuiDir_Right. track last movement direction so when cursor cross over a word-wrapping boundaries we can display it on either line depending on last move.s
|
ImS8 LastMoveDirectionLR; // ImGuiDir_Left or ImGuiDir_Right. track last movement direction so when cursor cross over a word-wrapping boundaries we can display it on either line depending on last move.s
|
||||||
int ReloadSelectionStart;
|
int ReloadSelectionStart;
|
||||||
@ -1475,7 +1480,7 @@ struct IMGUI_API ImGuiErrorRecoveryState
|
|||||||
ImGuiErrorRecoveryState() { memset((void*)this, 0, sizeof(*this)); }
|
ImGuiErrorRecoveryState() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Data saved for each window pushed into the stack
|
// Storage for each window pushed into the stack.
|
||||||
struct ImGuiWindowStackData
|
struct ImGuiWindowStackData
|
||||||
{
|
{
|
||||||
ImGuiWindow* Window;
|
ImGuiWindow* Window;
|
||||||
@ -1483,6 +1488,7 @@ struct ImGuiWindowStackData
|
|||||||
ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
|
ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
|
||||||
bool DisabledOverrideReenable; // Non-child window override disabled flag
|
bool DisabledOverrideReenable; // Non-child window override disabled flag
|
||||||
float DisabledOverrideReenableAlphaBackup;
|
float DisabledOverrideReenableAlphaBackup;
|
||||||
|
ImRect ParentLastComboPreviewRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImGuiShrinkWidthItem
|
struct ImGuiShrinkWidthItem
|
||||||
@ -2501,7 +2507,7 @@ struct ImGuiContext
|
|||||||
ImVec2 WheelingAxisAvg;
|
ImVec2 WheelingAxisAvg;
|
||||||
|
|
||||||
// Item/widgets state and tracking information
|
// Item/widgets state and tracking information
|
||||||
const char* MixedValueLabel; // Value replacement when displaying a mixed value. Default to "-" (Unreal uses "Multiple values", Unity uses "---"). May be interpreted as a format: must not contain single %.
|
const char* MixedValueLabel; // Value replacement when displaying a mixed value. Default to "-" (Unreal uses "Multiple values", Unity uses "---"). May be interpreted as a format: must not contain single %. Set to NULL to display original value.
|
||||||
ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier
|
ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier
|
||||||
ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
||||||
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
||||||
@ -3772,7 +3778,7 @@ namespace ImGui
|
|||||||
|
|
||||||
// Combos
|
// Combos
|
||||||
IMGUI_API bool BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags);
|
IMGUI_API bool BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags);
|
||||||
IMGUI_API bool BeginComboPreview();
|
IMGUI_API bool BeginComboPreview(); // Submit preview contents a combo. Call this after EndCombo() to display contents that's more than just a text label.
|
||||||
IMGUI_API void EndComboPreview();
|
IMGUI_API void EndComboPreview();
|
||||||
|
|
||||||
// Keyboard/Gamepad Navigation
|
// Keyboard/Gamepad Navigation
|
||||||
|
|||||||
@ -1958,7 +1958,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
||||||
if (flags & ImGuiComboFlags_WidthFitPreview)
|
if (flags & ImGuiComboFlags_WidthFitPreview)
|
||||||
IM_ASSERT((flags & (ImGuiComboFlags_NoPreview | (ImGuiComboFlags)ImGuiComboFlags_CustomPreview)) == 0);
|
IM_ASSERT((flags & ImGuiComboFlags_NoPreview) == 0);
|
||||||
|
|
||||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||||
const char* label_end = FindRenderedTextEnd(label);
|
const char* label_end = FindRenderedTextEnd(label);
|
||||||
@ -1998,13 +1998,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
|||||||
}
|
}
|
||||||
RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding);
|
RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding);
|
||||||
|
|
||||||
// Custom preview
|
// Store geometry for BeginComboPreview() - only necessary when visible.
|
||||||
if (flags & ImGuiComboFlags_CustomPreview)
|
g.ComboPreviewData.PreviewRect = (flags & ImGuiComboFlags_NoPreview) ? ImRect() : ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
||||||
{
|
|
||||||
g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
|
||||||
IM_ASSERT(preview_value == NULL || preview_value[0] == 0);
|
|
||||||
preview_value = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render preview and label
|
// Render preview and label
|
||||||
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
||||||
@ -2086,6 +2081,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
g.BeginComboDepth++;
|
g.BeginComboDepth++;
|
||||||
|
g.CurrentWindowStack.back().ParentLastComboPreviewRect = g.ComboPreviewData.PreviewRect;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2093,6 +2089,7 @@ void ImGui::EndCombo()
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
g.BeginComboDepth--;
|
g.BeginComboDepth--;
|
||||||
|
g.ComboPreviewData.PreviewRect = g.CurrentWindowStack.back().ParentLastComboPreviewRect;
|
||||||
char name[16];
|
char name[16];
|
||||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // FIXME: Move those to helpers?
|
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // FIXME: Move those to helpers?
|
||||||
if (strcmp(g.CurrentWindow->Name, name) != 0)
|
if (strcmp(g.CurrentWindow->Name, name) != 0)
|
||||||
@ -2100,19 +2097,26 @@ void ImGui::EndCombo()
|
|||||||
EndPopup();
|
EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements
|
// Submit preview contents for BeginCombo()/EndCombo(), to display contents that's more than just a text label.
|
||||||
// (Experimental, see GitHub issues: #1658, #4168)
|
// - [BETA] See GitHub issues: #1658, #4168.
|
||||||
|
// - Make sure you call this after EndCombo().
|
||||||
|
// - The preview is designed to only host non-interactive elements.
|
||||||
|
// - Not compatible with ImGuiComboFlags_WidthFitPreview.
|
||||||
|
// - 2026-09-08 (1.93.0): removed ImGuiComboFlags_CustomPreview. You can use BeginComboPreview()/EndComboPreview() without an extra flag.
|
||||||
bool ImGui::BeginComboPreview()
|
bool ImGui::BeginComboPreview()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
|
||||||
|
|
||||||
if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible))
|
if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible))
|
||||||
return false;
|
return false;
|
||||||
IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
|
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
||||||
if (!window->ClipRect.Overlaps(preview_data->PreviewRect)) // Narrower test (optional)
|
if (!window->ClipRect.Overlaps(preview_data->PreviewRect) || preview_data->PreviewRect.GetWidth() <= 0.0f) // Narrower test (optional) + handle _NoPreview
|
||||||
return false;
|
return false;
|
||||||
|
IM_ASSERT_USER_ERROR_RETV(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y, false,
|
||||||
|
"Call BeginComboPreview() after BeginCombo(), not after EndCombo()!"); // Calling after EndCombo() works only if you don't nest combos.
|
||||||
|
IM_ASSERT_USER_ERROR_RETV(preview_data->WithinPreview == false, false,
|
||||||
|
"Cannot recurse BeginComboPreview(): call EndComboPreview() before opening another combo.");
|
||||||
|
|
||||||
// FIXME: This could be contained in a PushWorkRect() api
|
// FIXME: This could be contained in a PushWorkRect() api
|
||||||
preview_data->BackupCursorPos = window->DC.CursorPos;
|
preview_data->BackupCursorPos = window->DC.CursorPos;
|
||||||
@ -2120,6 +2124,10 @@ bool ImGui::BeginComboPreview()
|
|||||||
preview_data->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine;
|
preview_data->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine;
|
||||||
preview_data->BackupPrevLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
preview_data->BackupPrevLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
||||||
preview_data->BackupLayout = window->DC.LayoutType;
|
preview_data->BackupLayout = window->DC.LayoutType;
|
||||||
|
preview_data->WithinPreview = true;
|
||||||
|
preview_data->BackupWorkRectMaxX = window->WorkRect.Max.x;
|
||||||
|
preview_data->BackupContentRectMaxX = window->ContentRegionRect.Max.x;
|
||||||
|
window->WorkRect.Max.x = window->ContentRegionRect.Max.x = preview_data->PreviewRect.Max.x - g.Style.FramePadding.x;
|
||||||
window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding;
|
window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding;
|
||||||
window->DC.CursorMaxPos = window->DC.CursorPos;
|
window->DC.CursorMaxPos = window->DC.CursorPos;
|
||||||
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
||||||
@ -2145,12 +2153,14 @@ void ImGui::EndComboPreview()
|
|||||||
}
|
}
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
window->DC.CursorPos = preview_data->BackupCursorPos;
|
window->DC.CursorPos = preview_data->BackupCursorPos;
|
||||||
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos);
|
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos); // No need to do the same with IdealMaxPos
|
||||||
window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine;
|
window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine;
|
||||||
window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset;
|
window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset;
|
||||||
|
window->WorkRect.Max.x = preview_data->BackupWorkRectMaxX;
|
||||||
|
window->ContentRegionRect.Max.x = preview_data->BackupContentRectMaxX;
|
||||||
window->DC.LayoutType = preview_data->BackupLayout;
|
window->DC.LayoutType = preview_data->BackupLayout;
|
||||||
window->DC.IsSameLine = false;
|
window->DC.IsSameLine = false;
|
||||||
preview_data->PreviewRect = ImRect();
|
preview_data->WithinPreview = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter for the old Combo() API: const char*[]
|
// Getter for the old Combo() API: const char*[]
|
||||||
@ -2824,12 +2834,16 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
|||||||
MarkItemEdited(id);
|
MarkItemEdited(id);
|
||||||
|
|
||||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||||
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format;
|
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||||
char value_buf[64];
|
char value_buf[64];
|
||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
|
if (is_mixed)
|
||||||
|
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||||
|
if (is_mixed)
|
||||||
|
PopStyleColor();
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||||
@ -3432,12 +3446,16 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
|||||||
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
||||||
|
|
||||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||||
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format;
|
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||||
char value_buf[64];
|
char value_buf[64];
|
||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||||
if (g.LogEnabled)
|
if (g.LogEnabled)
|
||||||
LogSetNextTextDecoration("{", "}");
|
LogSetNextTextDecoration("{", "}");
|
||||||
|
if (is_mixed)
|
||||||
|
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||||
|
if (is_mixed)
|
||||||
|
PopStyleColor();
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||||
@ -3587,10 +3605,15 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
|||||||
|
|
||||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||||
// For the vertical slider we allow centered text to overlap the frame padding
|
// For the vertical slider we allow centered text to overlap the frame padding
|
||||||
const char* format_for_display = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) ? g.MixedValueLabel : format;
|
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||||
char value_buf[64];
|
char value_buf[64];
|
||||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format_for_display);
|
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||||
|
if (is_mixed)
|
||||||
|
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||||
|
if (is_mixed)
|
||||||
|
PopStyleColor();
|
||||||
|
|
||||||
if (label_size.x > 0.0f)
|
if (label_size.x > 0.0f)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||||
|
|
||||||
@ -3827,7 +3850,11 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
|||||||
|
|
||||||
// Only mark as edited if new value is different
|
// Only mark as edited if new value is different
|
||||||
g.LastItemData.ItemFlags &= ~ImGuiItemFlags_NoMarkEdited;
|
g.LastItemData.ItemFlags &= ~ImGuiItemFlags_NoMarkEdited;
|
||||||
bool value_changed = memcmp(&data_backup, p_data, data_type_size) != 0 || (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue);
|
bool value_changed = memcmp(&data_backup, p_data, data_type_size) != 0;
|
||||||
|
if (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue)
|
||||||
|
if (ImGuiInputTextState* state = GetInputTextState(g.LastItemData.ID))
|
||||||
|
value_changed |= (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputScalar) ? (state->EditedThisFrame | state->ValidatedThisFrame) : state->ValidatedThisFrame;
|
||||||
|
|
||||||
if (value_changed)
|
if (value_changed)
|
||||||
MarkItemEdited(id);
|
MarkItemEdited(id);
|
||||||
return value_changed;
|
return value_changed;
|
||||||
@ -3905,7 +3932,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue)
|
if (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue)
|
||||||
value_changed |= ret;
|
if (ImGuiInputTextState* state = GetInputTextState(g.LastItemData.ID))
|
||||||
|
value_changed |= (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputScalar) ? (state->EditedThisFrame | state->ValidatedThisFrame) : state->ValidatedThisFrame;
|
||||||
|
|
||||||
// Step buttons
|
// Step buttons
|
||||||
if (has_step_buttons)
|
if (has_step_buttons)
|
||||||
@ -5045,6 +5073,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (state != NULL && state->ID == id)
|
if (state != NULL && state->ID == id)
|
||||||
{
|
{
|
||||||
state->Flags = flags;
|
state->Flags = flags;
|
||||||
|
state->EditedThisFrame = state->ValidatedThisFrame = false;
|
||||||
//state->LastFrameActive = g.FrameCount;
|
//state->LastFrameActive = g.FrameCount;
|
||||||
|
|
||||||
// Word-wrapping: attempt to keep cursor in view while resizing frame/parent (FIXME-WORDWRAP: would be better to preserve same relative offset)
|
// Word-wrapping: attempt to keep cursor in view while resizing frame/parent (FIXME-WORDWRAP: would be better to preserve same relative offset)
|
||||||
@ -5060,7 +5089,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (g.ActiveId == id)
|
if (g.ActiveId == id)
|
||||||
{
|
{
|
||||||
IM_ASSERT(state != NULL);
|
IM_ASSERT(state != NULL);
|
||||||
state->EditedThisFrame = false;
|
|
||||||
state->BufCapacity = buf_size;
|
state->BufCapacity = buf_size;
|
||||||
state->WrapWidth = wrap_width;
|
state->WrapWidth = wrap_width;
|
||||||
|
|
||||||
@ -5463,7 +5491,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputText)
|
if (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputText)
|
||||||
{
|
{
|
||||||
// Apply when modified
|
// Apply when modified
|
||||||
if (strcmp(state->TextSrc, buf) != 0 || (is_mixed && validated))
|
if (strcmp(state->TextSrc, buf) != 0 || (is_mixed && (state->EditedThisFrame || validated)))
|
||||||
{
|
{
|
||||||
apply_new_text = state->TextSrc;
|
apply_new_text = state->TextSrc;
|
||||||
apply_new_text_length = state->TextLen;
|
apply_new_text_length = state->TextLen;
|
||||||
@ -5567,7 +5595,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (is_password && !is_displaying_hint)
|
if (is_password && !is_displaying_hint)
|
||||||
PushPasswordFont();
|
PushPasswordFont();
|
||||||
}
|
}
|
||||||
if (is_mixed && g.ActiveId != id && apply_new_text == NULL)
|
const bool is_displaying_mixed = is_mixed && g.ActiveId != id && apply_new_text == NULL;
|
||||||
|
if (is_displaying_mixed && g.MixedValueLabel != NULL)
|
||||||
{
|
{
|
||||||
buf_display = g.MixedValueLabel;
|
buf_display = g.MixedValueLabel;
|
||||||
buf_display_end = buf_display + strlen(g.MixedValueLabel);
|
buf_display_end = buf_display + strlen(g.MixedValueLabel);
|
||||||
@ -5616,7 +5645,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
ImVec2 draw_scroll;
|
ImVec2 draw_scroll;
|
||||||
|
|
||||||
// Render text. We currently only render selection when the widget is active or while scrolling.
|
// Render text. We currently only render selection when the widget is active or while scrolling.
|
||||||
const ImU32 text_col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
const ImU32 text_col = GetColorU32(is_displaying_mixed ? ImGuiCol_TextMixedValue : is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||||
if (render_cursor || render_selection)
|
if (render_cursor || render_selection)
|
||||||
{
|
{
|
||||||
// Render text (with cursor and selection)
|
// Render text (with cursor and selection)
|
||||||
@ -5789,6 +5818,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
if (label_size.x > 0)
|
if (label_size.x > 0)
|
||||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||||
|
|
||||||
|
if (state && validated)
|
||||||
|
state->ValidatedThisFrame = true;
|
||||||
if (value_changed)
|
if (value_changed)
|
||||||
MarkItemEdited(id);
|
MarkItemEdited(id);
|
||||||
|
|
||||||
@ -6590,7 +6621,10 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||||||
if (is_mixed)
|
if (is_mixed)
|
||||||
{
|
{
|
||||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding);
|
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding);
|
||||||
RenderTextClipped(ImVec2(bb.Min.x, bb.Min.y + g.Style.FramePadding.y), bb.Max, g.MixedValueLabel, NULL, NULL, ImVec2(0.5f, 0.0f));
|
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||||
|
if (g.MixedValueLabel != NULL)
|
||||||
|
RenderTextClipped(ImVec2(bb.Min.x, bb.Min.y + g.Style.FramePadding.y), bb.Max, g.MixedValueLabel, NULL, NULL, ImVec2(0.5f, 0.0f));
|
||||||
|
PopStyleColor();
|
||||||
}
|
}
|
||||||
else if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
else if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user