mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-11-04 01:34:32 +00:00 
			
		
		
		
	Merge branch 'master' into docking
# Conflicts: # imgui.cpp # imgui_demo.cpp
This commit is contained in:
		@@ -77,6 +77,57 @@ Other changes:
 | 
			
		||||
    Disabling this was previously possible for Selectable() via a direct flag but not for MenuItem().
 | 
			
		||||
    (#1379, #1468, #2200, #4936, #5216, #7302, #7573)
 | 
			
		||||
  - This was mostly all previously in imgui_internal.h.
 | 
			
		||||
- Multi-Select: added multi-select API and demos. (#1861)
 | 
			
		||||
   - This system implements standard multi-selection idioms (CTRL+mouse click, CTRL+keyboard moves,
 | 
			
		||||
     SHIFT+mouse click, SHIFT+keyboard moves, etc.) with support for clipper (not submitting non-visible
 | 
			
		||||
     items), box-selection with scrolling, and many other details.
 | 
			
		||||
   - In the spirit of Dear ImGui design, your code owns both items and actual selection data.
 | 
			
		||||
     This is designed to allow all kinds of selection storage you may use in your application
 | 
			
		||||
     (e.g. set/map/hash, intrusive selection, interval trees, up to you).
 | 
			
		||||
   - The supported widgets are Selectable(), Checkbox(). TreeNode() is also technically supported but...
 | 
			
		||||
     using this correctly is more complicated (you need some sort of linear/random access to your tree,
 | 
			
		||||
     which is suited to advanced trees setups already implementing filters and clipper.
 | 
			
		||||
     We will work toward simplifying and demoing this later.
 | 
			
		||||
   - A helper ImGuiSelectionBasicStorage is provided to facilitate getting started in a typical app.
 | 
			
		||||
   - Documentation:
 | 
			
		||||
     - Wiki page https://github.com/ocornut/imgui/wiki/Multi-Select for API overview.
 | 
			
		||||
     - Demo code.
 | 
			
		||||
     - Headers are well commented.
 | 
			
		||||
  - Added BeginMultiSelect(), EndMultiSelect(), SetNextItemSelectionUserData().
 | 
			
		||||
  - Added IsItemToggledSelection() for use if you need latest selection update during currnet iteration.
 | 
			
		||||
  - Added ImGuiMultiSelectIO and ImGuiSelectionRequest structures:
 | 
			
		||||
    - BeginMultiSelect() and EndMultiSelect() return a ImGuiMultiSelectIO structure, which
 | 
			
		||||
      is mostly an array of ImGuiSelectionRequest actions (clear, select all, set range, etc.)
 | 
			
		||||
    - Other fields are helpful when using a clipper, or wanting to handle deletion nicely.
 | 
			
		||||
  - Added ImGuiSelectionBasicStorage helper to store and maintain a selection (optional):
 | 
			
		||||
    - This is similar to if you used e.g. a std::set<ID> to store a selection, with all the right
 | 
			
		||||
      glue to honor ImGuiMultiSelectIO requests. Most applications can use that.
 | 
			
		||||
  - Added ImGuiSelectionExternalStorage helper to maintain an externally stored selection (optional):
 | 
			
		||||
    - Helpful to easily bind multi-selection to e.g. an array of checkboxes.
 | 
			
		||||
  - Added ImGuiMultiSelectFlags options:
 | 
			
		||||
    - ImGuiMultiSelectFlags_SingleSelect
 | 
			
		||||
    - ImGuiMultiSelectFlags_NoSelectAll
 | 
			
		||||
    - ImGuiMultiSelectFlags_NoRangeSelect
 | 
			
		||||
    - ImGuiMultiSelectFlags_NoAutoSelect
 | 
			
		||||
    - ImGuiMultiSelectFlags_NoAutoClear
 | 
			
		||||
    - ImGuiMultiSelectFlags_NoAutoClearOnReselect (#7424)
 | 
			
		||||
    - ImGuiMultiSelectFlags_BoxSelect1d
 | 
			
		||||
    - ImGuiMultiSelectFlags_BoxSelect2d
 | 
			
		||||
    - ImGuiMultiSelectFlags_BoxSelectNoScroll
 | 
			
		||||
    - ImGuiMultiSelectFlags_ClearOnEscape
 | 
			
		||||
    - ImGuiMultiSelectFlags_ClearOnClickVoid
 | 
			
		||||
    - ImGuiMultiSelectFlags_ScopeWindow (default), ImGuiMultiSelectFlags_ScopeRect
 | 
			
		||||
    - ImGuiMultiSelectFlags_SelectOnClick (default), ImGuiMultiSelectFlags_SelectOnClickRelease
 | 
			
		||||
    - ImGuiMultiSelectFlags_NavWrapX
 | 
			
		||||
  - Demo: Added "Examples->Assets Browser" demo.
 | 
			
		||||
  - Demo: Added "Widgets->Selection State & Multi-Select" section, with:
 | 
			
		||||
    - Multi-Select
 | 
			
		||||
    - Multi-Select (with clipper)
 | 
			
		||||
    - Multi-Select (with deletion)
 | 
			
		||||
    - Multi-Select (dual list box) (#6648)
 | 
			
		||||
    - Multi-Select (checkboxes)
 | 
			
		||||
    - Multi-Select (multiple scopes)
 | 
			
		||||
    - Multi-Select (advanced)
 | 
			
		||||
- Clipper: added SeekCursorForItem() function. When using ImGuiListClipper::Begin(INT_MAX) you can
 | 
			
		||||
  can use the clipper without knowing the amount of items beforehand. (#1311)
 | 
			
		||||
  In this situation, call ImGuiListClipper::SeekCursorForItem(items_count) as the end of your iteration
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -2619,6 +2619,7 @@ ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_
 | 
			
		||||
    return in_p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IM_MSVC_RUNTIME_CHECKS_OFF
 | 
			
		||||
static int IMGUI_CDECL PairComparerByID(const void* lhs, const void* rhs)
 | 
			
		||||
{
 | 
			
		||||
    // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that.
 | 
			
		||||
@@ -2632,6 +2633,7 @@ void ImGuiStorage::BuildSortByKey()
 | 
			
		||||
{
 | 
			
		||||
    ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), PairComparerByID);
 | 
			
		||||
}
 | 
			
		||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
 | 
			
		||||
 | 
			
		||||
int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
 | 
			
		||||
{
 | 
			
		||||
@@ -3140,9 +3142,27 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
 | 
			
		||||
                data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0));
 | 
			
		||||
 | 
			
		||||
            // Add visible range
 | 
			
		||||
            float min_y = window->ClipRect.Min.y;
 | 
			
		||||
            float max_y = window->ClipRect.Max.y;
 | 
			
		||||
 | 
			
		||||
            // Add box selection range
 | 
			
		||||
            ImGuiBoxSelectState* bs = &g.BoxSelectState;
 | 
			
		||||
            if (bs->IsActive && bs->Window == window)
 | 
			
		||||
            {
 | 
			
		||||
                // FIXME: Selectable() use of half-ItemSpacing isn't consistent in matter of layout, as ItemAdd(bb) stray above ItemSize()'s CursorPos.
 | 
			
		||||
                // RangeSelect's BoxSelect relies on comparing overlap of previous and current rectangle and is sensitive to that.
 | 
			
		||||
                // As a workaround we currently half ItemSpacing worth on each side.
 | 
			
		||||
                min_y -= g.Style.ItemSpacing.y;
 | 
			
		||||
                max_y += g.Style.ItemSpacing.y;
 | 
			
		||||
 | 
			
		||||
                // Box-select on 2D area requires different clipping.
 | 
			
		||||
                if (bs->UnclipMode)
 | 
			
		||||
                    data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y, bs->UnclipRect.Max.y, 0, 0));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
 | 
			
		||||
            const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
 | 
			
		||||
            data->Ranges.push_back(ImGuiListClipperRange::FromPositions(window->ClipRect.Min.y, window->ClipRect.Max.y, off_min, off_max));
 | 
			
		||||
            data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Convert position ranges to item index ranges
 | 
			
		||||
@@ -3904,6 +3924,9 @@ void ImGui::Shutdown()
 | 
			
		||||
    g.TablesTempData.clear_destruct();
 | 
			
		||||
    g.DrawChannelsTempMergeBuffer.clear();
 | 
			
		||||
 | 
			
		||||
    g.MultiSelectStorage.Clear();
 | 
			
		||||
    g.MultiSelectTempData.clear_destruct();
 | 
			
		||||
 | 
			
		||||
    g.ClipboardHandlerData.clear();
 | 
			
		||||
    g.MenusIdSubmittedThisFrame.clear();
 | 
			
		||||
    g.InputTextState.ClearFreeMemory();
 | 
			
		||||
@@ -4019,6 +4042,8 @@ void ImGui::GcCompactTransientMiscBuffers()
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    g.ItemFlagsStack.clear();
 | 
			
		||||
    g.GroupStack.clear();
 | 
			
		||||
    g.MultiSelectTempDataStacked = 0;
 | 
			
		||||
    g.MultiSelectTempData.clear_destruct();
 | 
			
		||||
    TableGcCompactSettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -4143,7 +4168,7 @@ void ImGui::MarkItemEdited(ImGuiID id)
 | 
			
		||||
 | 
			
		||||
    // We accept a MarkItemEdited() on drag and drop targets (see https://github.com/ocornut/imgui/issues/1875#issuecomment-978243343)
 | 
			
		||||
    // We accept 'ActiveIdPreviousFrame == id' for InputText() returning an edit after it has been taken ActiveId away (#4714)
 | 
			
		||||
    IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id);
 | 
			
		||||
    IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id || (g.CurrentMultiSelect != NULL && g.BoxSelectState.IsActive));
 | 
			
		||||
 | 
			
		||||
    //IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
 | 
			
		||||
    g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
 | 
			
		||||
@@ -5713,9 +5738,15 @@ bool ImGui::IsItemToggledOpen()
 | 
			
		||||
    return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Call after a Selectable() or TreeNode() involved in multi-selection.
 | 
			
		||||
// Useful if you need the per-item information before reaching EndMultiSelect(), e.g. for rendering purpose.
 | 
			
		||||
// This is only meant to be called inside a BeginMultiSelect()/EndMultiSelect() block.
 | 
			
		||||
// (Outside of multi-select, it would be misleading/ambiguous to report this signal, as widgets
 | 
			
		||||
// return e.g. a pressed event and user code is in charge of altering selection in ways we cannot predict.)
 | 
			
		||||
bool ImGui::IsItemToggledSelection()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
    IM_ASSERT(g.CurrentMultiSelect != NULL); // Can only be used inside a BeginMultiSelect()/EndMultiSelect()
 | 
			
		||||
    return (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -5775,7 +5806,8 @@ void ImGui::SetItemAllowOverlap()
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version for the two users of this function.
 | 
			
		||||
// This is a shortcut for not taking ownership of 100+ keys, frequently used by drag operations.
 | 
			
		||||
// FIXME: It might be undesirable that this will likely disable KeyOwner-aware shortcuts systems. Consider a more fine-tuned version if needed?
 | 
			
		||||
void ImGui::SetActiveIdUsingAllKeyboardKeys()
 | 
			
		||||
{
 | 
			
		||||
    ImGuiContext& g = *GImGui;
 | 
			
		||||
@@ -10736,6 +10768,11 @@ void    ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo
 | 
			
		||||
        if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name);
 | 
			
		||||
        EndTabBar();
 | 
			
		||||
    }
 | 
			
		||||
    while (g.CurrentMultiSelect != NULL && g.CurrentMultiSelect->Storage->Window == window)
 | 
			
		||||
    {
 | 
			
		||||
        if (log_callback) log_callback(user_data, "Recovered from missing EndMultiSelect() in '%s'", window->Name);
 | 
			
		||||
        EndMultiSelect();
 | 
			
		||||
    }
 | 
			
		||||
    while (window->DC.TreeDepth > 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name);
 | 
			
		||||
@@ -12942,6 +12979,7 @@ static void ImGui::NavUpdate()
 | 
			
		||||
 | 
			
		||||
    // Process navigation init request (select first/default focus)
 | 
			
		||||
    g.NavJustMovedToId = 0;
 | 
			
		||||
    g.NavJustMovedToFocusScopeId = g.NavJustMovedFromFocusScopeId = 0;
 | 
			
		||||
    if (g.NavInitResult.ID != 0)
 | 
			
		||||
        NavInitRequestApplyResult();
 | 
			
		||||
    g.NavInitRequest = false;
 | 
			
		||||
@@ -13094,6 +13132,7 @@ void ImGui::NavInitRequestApplyResult()
 | 
			
		||||
    ImGuiNavItemData* result = &g.NavInitResult;
 | 
			
		||||
    if (g.NavId != result->ID)
 | 
			
		||||
    {
 | 
			
		||||
        g.NavJustMovedFromFocusScopeId = g.NavFocusScopeId;
 | 
			
		||||
        g.NavJustMovedToId = result->ID;
 | 
			
		||||
        g.NavJustMovedToFocusScopeId = result->FocusScopeId;
 | 
			
		||||
        g.NavJustMovedToKeyMods = 0;
 | 
			
		||||
@@ -13352,6 +13391,7 @@ void ImGui::NavMoveRequestApplyResult()
 | 
			
		||||
    // PageUp/PageDown however sets always set NavJustMovedTo (vs Home/End which doesn't) mimicking Windows behavior.
 | 
			
		||||
    if ((g.NavId != result->ID || (g.NavMoveFlags & ImGuiNavMoveFlags_IsPageMove)) && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSelect) == 0)
 | 
			
		||||
    {
 | 
			
		||||
        g.NavJustMovedFromFocusScopeId = g.NavFocusScopeId;
 | 
			
		||||
        g.NavJustMovedToId = result->ID;
 | 
			
		||||
        g.NavJustMovedToFocusScopeId = result->FocusScopeId;
 | 
			
		||||
        g.NavJustMovedToKeyMods = g.NavMoveKeyMods;
 | 
			
		||||
@@ -14120,7 +14160,7 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
 | 
			
		||||
 | 
			
		||||
    IM_ASSERT(g.DragDropWithinTarget == false && g.DragDropWithinSource == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget()
 | 
			
		||||
    g.DragDropTargetRect = bb;
 | 
			
		||||
    g.DragDropTargetClipRect = window->ClipRect; // May want to be overriden by user depending on use case?
 | 
			
		||||
    g.DragDropTargetClipRect = window->ClipRect; // May want to be overridden by user depending on use case?
 | 
			
		||||
    g.DragDropTargetId = id;
 | 
			
		||||
    g.DragDropWithinTarget = true;
 | 
			
		||||
    return true;
 | 
			
		||||
@@ -20647,6 +20687,17 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
			
		||||
        TreePop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Details for MultiSelect
 | 
			
		||||
    if (TreeNode("MultiSelect", "MultiSelect (%d)", g.MultiSelectStorage.GetAliveCount()))
 | 
			
		||||
    {
 | 
			
		||||
        ImGuiBoxSelectState* bs = &g.BoxSelectState;
 | 
			
		||||
        BulletText("BoxSelect ID=0x%08X, Starting = %d, Active %d", bs->ID, bs->IsStarting, bs->IsActive);
 | 
			
		||||
        for (int n = 0; n < g.MultiSelectStorage.GetMapSize(); n++)
 | 
			
		||||
            if (ImGuiMultiSelectState* state = g.MultiSelectStorage.TryGetMapData(n))
 | 
			
		||||
                DebugNodeMultiSelectState(state);
 | 
			
		||||
        TreePop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Details for Docking
 | 
			
		||||
#ifdef IMGUI_HAS_DOCK
 | 
			
		||||
    if (TreeNode("Docking"))
 | 
			
		||||
@@ -21648,7 +21699,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open)
 | 
			
		||||
    ShowDebugLogFlag("IO", ImGuiDebugLogFlags_EventIO);
 | 
			
		||||
    ShowDebugLogFlag("Nav", ImGuiDebugLogFlags_EventNav);
 | 
			
		||||
    ShowDebugLogFlag("Popup", ImGuiDebugLogFlags_EventPopup);
 | 
			
		||||
    //ShowDebugLogFlag("Selection", ImGuiDebugLogFlags_EventSelection);
 | 
			
		||||
    ShowDebugLogFlag("Selection", ImGuiDebugLogFlags_EventSelection);
 | 
			
		||||
    ShowDebugLogFlag("Viewport", ImGuiDebugLogFlags_EventViewport);
 | 
			
		||||
    ShowDebugLogFlag("InputRouting", ImGuiDebugLogFlags_EventInputRouting);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										171
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										171
									
								
								imgui.h
									
									
									
									
									
								
							@@ -28,7 +28,7 @@
 | 
			
		||||
// Library Version
 | 
			
		||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
 | 
			
		||||
#define IMGUI_VERSION       "1.91.0 WIP"
 | 
			
		||||
#define IMGUI_VERSION_NUM   19095
 | 
			
		||||
#define IMGUI_VERSION_NUM   19096
 | 
			
		||||
#define IMGUI_HAS_TABLE
 | 
			
		||||
#define IMGUI_HAS_VIEWPORT          // Viewport WIP branch
 | 
			
		||||
#define IMGUI_HAS_DOCK              // Docking WIP branch
 | 
			
		||||
@@ -46,6 +46,7 @@ Index of this file:
 | 
			
		||||
// [SECTION] ImGuiIO
 | 
			
		||||
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiWindowClass, ImGuiPayload)
 | 
			
		||||
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor)
 | 
			
		||||
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage)
 | 
			
		||||
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
 | 
			
		||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
 | 
			
		||||
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
 | 
			
		||||
@@ -176,11 +177,15 @@ struct ImGuiIO;                     // Main configuration and I/O between your a
 | 
			
		||||
struct ImGuiInputTextCallbackData;  // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use)
 | 
			
		||||
struct ImGuiKeyData;                // Storage for ImGuiIO and IsKeyDown(), IsKeyPressed() etc functions.
 | 
			
		||||
struct ImGuiListClipper;            // Helper to manually clip large list of items
 | 
			
		||||
struct ImGuiMultiSelectIO;          // Structure to interact with a BeginMultiSelect()/EndMultiSelect() block
 | 
			
		||||
struct ImGuiOnceUponAFrame;         // Helper for running a block of code not more than once a frame
 | 
			
		||||
struct ImGuiPayload;                // User data payload for drag and drop operations
 | 
			
		||||
struct ImGuiPlatformIO;             // Multi-viewport support: interface for Platform/Renderer backends + viewports to render
 | 
			
		||||
struct ImGuiPlatformMonitor;        // Multi-viewport support: user-provided bounds for each connected monitor/display. Used when positioning popups and tooltips to avoid them straddling monitors
 | 
			
		||||
struct ImGuiPlatformImeData;        // Platform IME data for io.PlatformSetImeDataFn() function.
 | 
			
		||||
struct ImGuiSelectionBasicStorage;  // Optional helper to store multi-selection state + apply multi-selection requests.
 | 
			
		||||
struct ImGuiSelectionExternalStorage;//Optional helper to apply multi-selection requests to existing randomly accessible storage.
 | 
			
		||||
struct ImGuiSelectionRequest;       // A selection request (stored in ImGuiMultiSelectIO)
 | 
			
		||||
struct ImGuiSizeCallbackData;       // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use)
 | 
			
		||||
struct ImGuiStorage;                // Helper for key->value storage (container sorted by key)
 | 
			
		||||
struct ImGuiStoragePair;            // Helper for key->value storage (pair)
 | 
			
		||||
@@ -233,6 +238,7 @@ typedef int ImGuiInputTextFlags;    // -> enum ImGuiInputTextFlags_  // Flags: f
 | 
			
		||||
typedef int ImGuiItemFlags;         // -> enum ImGuiItemFlags_       // Flags: for PushItemFlag(), shared by all items
 | 
			
		||||
typedef int ImGuiKeyChord;          // -> ImGuiKey | ImGuiMod_XXX    // Flags: for IsKeyChordPressed(), Shortcut() etc. an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values.
 | 
			
		||||
typedef int ImGuiPopupFlags;        // -> enum ImGuiPopupFlags_      // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen()
 | 
			
		||||
typedef int ImGuiMultiSelectFlags;  // -> enum ImGuiMultiSelectFlags_// Flags: for BeginMultiSelect()
 | 
			
		||||
typedef int ImGuiSelectableFlags;   // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
 | 
			
		||||
typedef int ImGuiSliderFlags;       // -> enum ImGuiSliderFlags_     // Flags: for DragFloat(), DragInt(), SliderFloat(), SliderInt() etc.
 | 
			
		||||
typedef int ImGuiTabBarFlags;       // -> enum ImGuiTabBarFlags_     // Flags: for BeginTabBar()
 | 
			
		||||
@@ -268,6 +274,11 @@ typedef ImWchar32 ImWchar;
 | 
			
		||||
typedef ImWchar16 ImWchar;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Multi-Selection item index or identifier when using BeginMultiSelect()
 | 
			
		||||
// - Used by SetNextItemSelectionUserData() + and inside ImGuiMultiSelectIO structure.
 | 
			
		||||
// - Most users are likely to use this store an item INDEX but this may be used to store a POINTER/ID as well. Read comments near ImGuiMultiSelectIO for details.
 | 
			
		||||
typedef ImS64 ImGuiSelectionUserData;
 | 
			
		||||
 | 
			
		||||
// Callback and functions types
 | 
			
		||||
typedef int     (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data);    // Callback function for ImGui::InputText()
 | 
			
		||||
typedef void    (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);              // Callback function for ImGui::SetNextWindowSizeConstraints()
 | 
			
		||||
@@ -670,6 +681,18 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API bool          Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height
 | 
			
		||||
    IMGUI_API bool          Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0));      // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
 | 
			
		||||
 | 
			
		||||
    // Multi-selection system for Selectable(), Checkbox() functions*
 | 
			
		||||
    // - This enables standard multi-selection/range-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
 | 
			
		||||
    // - ImGuiSelectionUserData is often used to store your item index within the current view (but may store something else).
 | 
			
		||||
    // - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State & Multi-Select' for demo.
 | 
			
		||||
    // - (*) TreeNode() is technically supported but... using this correctly is more complicate: you need some sort of linear/random access to your tree,
 | 
			
		||||
    //   which is suited to advanced trees setups already implementing filters and clipper. We will work toward simplifying and demoing this.
 | 
			
		||||
    // - 'selection_size' and 'items_count' parameters are optional and used by a few features. If they are costly for you to compute, you may avoid them.
 | 
			
		||||
    IMGUI_API ImGuiMultiSelectIO*   BeginMultiSelect(ImGuiMultiSelectFlags flags, int selection_size = -1, int items_count = -1);
 | 
			
		||||
    IMGUI_API ImGuiMultiSelectIO*   EndMultiSelect();
 | 
			
		||||
    IMGUI_API void                  SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
 | 
			
		||||
    IMGUI_API bool                  IsItemToggledSelection();                                   // Was the last item selection state toggled? Useful if you need the per-item information _before_ reaching EndMultiSelect(). We only returns toggle _event_ in order to handle clipping correctly.
 | 
			
		||||
 | 
			
		||||
    // Widgets: List Boxes
 | 
			
		||||
    // - This is essentially a thin wrapper to using BeginChild/EndChild with the ImGuiChildFlags_FrameStyle flag for stylistic changes + displaying a label.
 | 
			
		||||
    // - You can submit contents and manage your selection state however you want it, by creating e.g. Selectable() or any other items.
 | 
			
		||||
@@ -2819,6 +2842,152 @@ struct ImColor
 | 
			
		||||
    static ImColor HSV(float h, float s, float v, float a = 1.0f)   { float r, g, b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r, g, b, a); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiSelectionRequestType, ImGuiSelectionRequest, ImGuiMultiSelectIO, ImGuiSelectionBasicStorage)
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
// Multi-selection system
 | 
			
		||||
// Documentation at: https://github.com/ocornut/imgui/wiki/Multi-Select
 | 
			
		||||
// - Refer to 'Demo->Widgets->Selection State & Multi-Select' for demos using this.
 | 
			
		||||
// - This system implements standard multi-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc)
 | 
			
		||||
//   with support for clipper (skipping non-visible items), box-select and many other details.
 | 
			
		||||
// - Selectable(), Checkbox() are supported but custom widgets may use it as well.
 | 
			
		||||
// - TreeNode() is technically supported but... using this correctly is more complicated: you need some sort of linear/random access to your tree,
 | 
			
		||||
//   which is suited to advanced trees setups also implementing filters and clipper. We will work toward simplifying and demoing it.
 | 
			
		||||
// - In the spirit of Dear ImGui design, your code owns actual selection data.
 | 
			
		||||
//   This is designed to allow all kinds of selection storage you may use in your application e.g. set/map/hash.
 | 
			
		||||
// About ImGuiSelectionBasicStorage:
 | 
			
		||||
// - This is an optional helper to store a selection state and apply selection requests.
 | 
			
		||||
// - It is used by our demos and provided as a convenience to quickly implement multi-selection.
 | 
			
		||||
// Usage:
 | 
			
		||||
// - Identify submitted items with SetNextItemSelectionUserData(), most likely using an index into your current data-set.
 | 
			
		||||
// - Store and maintain actual selection data using persistent object identifiers.
 | 
			
		||||
// - Usage flow:
 | 
			
		||||
//     BEGIN - (1) Call BeginMultiSelect() and retrieve the ImGuiMultiSelectIO* result.
 | 
			
		||||
//           - (2) Honor request list (SetAll/SetRange requests) by updating your selection data. Same code as Step 6.
 | 
			
		||||
//           - (3) [If using clipper] You need to make sure RangeSrcItem is always submitted. Calculate its index and pass to clipper.IncludeItemByIndex(). If storing indices in ImGuiSelectionUserData, a simple clipper.IncludeItemByIndex(ms_io->RangeSrcItem) call will work.
 | 
			
		||||
//     LOOP  - (4) Submit your items with SetNextItemSelectionUserData() + Selectable()/TreeNode() calls.
 | 
			
		||||
//     END   - (5) Call EndMultiSelect() and retrieve the ImGuiMultiSelectIO* result.
 | 
			
		||||
//           - (6) Honor request list (SetAll/SetRange requests) by updating your selection data. Same code as Step 2.
 | 
			
		||||
//     If you submit all items (no clipper), Step 2 and 3 are optional and will be handled by each item themselves. It is fine to always honor those steps.
 | 
			
		||||
// About ImGuiSelectionUserData:
 | 
			
		||||
// - This can store an application-defined identifier (e.g. index or pointer) submitted via SetNextItemSelectionUserData().
 | 
			
		||||
// - In return we store them into RangeSrcItem/RangeFirstItem/RangeLastItem and other fields in ImGuiMultiSelectIO.
 | 
			
		||||
// - Most applications will store an object INDEX, hence the chosen name and type. Storing an index is natural, because
 | 
			
		||||
//   SetRange requests will give you two end-points and you will need to iterate/interpolate between them to update your selection.
 | 
			
		||||
// - However it is perfectly possible to store a POINTER or another IDENTIFIER inside ImGuiSelectionUserData.
 | 
			
		||||
//   Our system never assume that you identify items by indices, it never attempts to interpolate between two values.
 | 
			
		||||
// - As most users will want to store an index, for convenience and to reduce confusion we use ImS64 instead of void*,
 | 
			
		||||
//   being syntactically easier to downcast. Feel free to reinterpret_cast and store a pointer inside.
 | 
			
		||||
 | 
			
		||||
// Flags for BeginMultiSelect()
 | 
			
		||||
enum ImGuiMultiSelectFlags_
 | 
			
		||||
{
 | 
			
		||||
    ImGuiMultiSelectFlags_None                  = 0,
 | 
			
		||||
    ImGuiMultiSelectFlags_SingleSelect          = 1 << 0,   // Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho!
 | 
			
		||||
    ImGuiMultiSelectFlags_NoSelectAll           = 1 << 1,   // Disable CTRL+A shortcut to select all.
 | 
			
		||||
    ImGuiMultiSelectFlags_NoRangeSelect         = 1 << 2,   // Disable Shift+selection mouse/keyboard support (useful for unordered 2D selection).
 | 
			
		||||
    ImGuiMultiSelectFlags_NoAutoSelect          = 1 << 3,   // Disable selecting items when navigating (useful for e.g. supporting range-select in a list of checkboxes)
 | 
			
		||||
    ImGuiMultiSelectFlags_NoAutoClear           = 1 << 4,   // Disable clearing selection when navigating or selecting another one (generally used with ImGuiMultiSelectFlags_NoAutoSelect. useful for e.g. supporting range-select in a list of checkboxes)
 | 
			
		||||
    ImGuiMultiSelectFlags_NoAutoClearOnReselect = 1 << 5,   // Disable clearing selection when clicking/selecting an already selected item
 | 
			
		||||
    ImGuiMultiSelectFlags_BoxSelect1d           = 1 << 6,   // Enable box-selection with same width and same x pos items (e.g. only full row Selectable()). Box-selection works better with little bit of spacing between items hit-box in order to be able to aim at empty space.
 | 
			
		||||
    ImGuiMultiSelectFlags_BoxSelect2d           = 1 << 7,   // Enable box-selection with varying width or varying x pos items support (e.g. different width labels, or 2D layout/grid). This is slower: alters clipping logic so that e.g. horizontal movements will update selection of normally clipped items.
 | 
			
		||||
    ImGuiMultiSelectFlags_BoxSelectNoScroll     = 1 << 8,   // Disable scrolling when box-selecting near edges of scope.
 | 
			
		||||
    ImGuiMultiSelectFlags_ClearOnEscape         = 1 << 9,   // Clear selection when pressing Escape while scope is focused.
 | 
			
		||||
    ImGuiMultiSelectFlags_ClearOnClickVoid      = 1 << 10,  // Clear selection when clicking on empty location within scope.
 | 
			
		||||
    ImGuiMultiSelectFlags_ScopeWindow           = 1 << 11,  // Scope for _BoxSelect and _ClearOnClickVoid is whole window (Default). Use if BeginMultiSelect() covers a whole window or used a single time in same window.
 | 
			
		||||
    ImGuiMultiSelectFlags_ScopeRect             = 1 << 12,  // Scope for _BoxSelect and _ClearOnClickVoid is rectangle encompassing BeginMultiSelect()/EndMultiSelect(). Use if BeginMultiSelect() is called multiple times in same window.
 | 
			
		||||
    ImGuiMultiSelectFlags_SelectOnClick         = 1 << 13,  // Apply selection on mouse down when clicking on unselected item. (Default)
 | 
			
		||||
    ImGuiMultiSelectFlags_SelectOnClickRelease  = 1 << 14,  // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
 | 
			
		||||
    //ImGuiMultiSelectFlags_RangeSelect2d       = 1 << 15,  // Shift+Selection uses 2d geometry instead of linear sequence, so possible to use Shift+up/down to select vertically in grid. Analogous to what BoxSelect does.
 | 
			
		||||
    ImGuiMultiSelectFlags_NavWrapX              = 1 << 16,  // [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Main IO structure returned by BeginMultiSelect()/EndMultiSelect().
 | 
			
		||||
// This mainly contains a list of selection requests.
 | 
			
		||||
// - Use 'Demo->Tools->Debug Log->Selection' to see requests as they happen.
 | 
			
		||||
// - Some fields are only useful if your list is dynamic and allows deletion (getting post-deletion focus/state right is shown in the demo)
 | 
			
		||||
// - Below: who reads/writes each fields? 'r'=read, 'w'=write, 'ms'=multi-select code, 'app'=application/user code.
 | 
			
		||||
struct ImGuiMultiSelectIO
 | 
			
		||||
{
 | 
			
		||||
    //------------------------------------------// BeginMultiSelect / EndMultiSelect
 | 
			
		||||
    ImVector<ImGuiSelectionRequest> Requests;   //  ms:w, app:r     /  ms:w  app:r   // Requests to apply to your selection data.
 | 
			
		||||
    ImGuiSelectionUserData      RangeSrcItem;   //  ms:w  app:r     /                // (If using clipper) Begin: Source item (often the first selected item) must never be clipped: use clipper.IncludeItemByIndex() to ensure it is submitted.
 | 
			
		||||
    ImGuiSelectionUserData      NavIdItem;      //  ms:w, app:r     /                // (If using deletion) Last known SetNextItemSelectionUserData() value for NavId (if part of submitted items).
 | 
			
		||||
    bool                        NavIdSelected;  //  ms:w, app:r     /        app:r   // (If using deletion) Last known selection state for NavId (if part of submitted items).
 | 
			
		||||
    bool                        RangeSrcReset;  //        app:w     /  ms:r          // (If using deletion) Set before EndMultiSelect() to reset ResetSrcItem (e.g. if deleted selection).
 | 
			
		||||
    int                         ItemsCount;     //  ms:w, app:r     /        app:r   // 'int items_count' parameter to BeginMultiSelect() is copied here for convenience, allowing simpler calls to your ApplyRequests handler. Not used internally.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Selection request type
 | 
			
		||||
enum ImGuiSelectionRequestType
 | 
			
		||||
{
 | 
			
		||||
    ImGuiSelectionRequestType_None = 0,
 | 
			
		||||
    ImGuiSelectionRequestType_SetAll,           // Request app to clear selection (if Selected==false) or select all items (if Selected==true). We cannot set RangeFirstItem/RangeLastItem as its contents is entirely up to user (not necessarily an index)
 | 
			
		||||
    ImGuiSelectionRequestType_SetRange,         // Request app to select/unselect [RangeFirstItem..RangeLastItem] items (inclusive) based on value of Selected. Only EndMultiSelect() request this, app code can read after BeginMultiSelect() and it will always be false.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Selection request item
 | 
			
		||||
struct ImGuiSelectionRequest
 | 
			
		||||
{
 | 
			
		||||
    //------------------------------------------// BeginMultiSelect / EndMultiSelect
 | 
			
		||||
    ImGuiSelectionRequestType   Type;           //  ms:w, app:r     /  ms:w, app:r   // Request type. You'll most often receive 1 Clear + 1 SetRange with a single-item range.
 | 
			
		||||
    bool                        Selected;       //  ms:w, app:r     /  ms:w, app:r   // Parameter for SetAll/SetRange requests (true = select, false = unselect)
 | 
			
		||||
    ImS8                        RangeDirection; //                  /  ms:w  app:r   // Parameter for SetRange request: +1 when RangeFirstItem comes before RangeLastItem, -1 otherwise. Useful if you want to preserve selection order on a backward Shift+Click.
 | 
			
		||||
    ImGuiSelectionUserData      RangeFirstItem; //                  /  ms:w, app:r   // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from top to bottom).
 | 
			
		||||
    ImGuiSelectionUserData      RangeLastItem;  //                  /  ms:w, app:r   // Parameter for SetRange request (this is generally == RangeSrcItem when shift selecting from bottom to top). Inclusive!
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Optional helper to store multi-selection state + apply multi-selection requests.
 | 
			
		||||
// - Used by our demos and provided as a convenience to easily implement basic multi-selection.
 | 
			
		||||
// - Iterate selection with 'void* it = NULL; ImGuiID id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
 | 
			
		||||
//   Or you can check 'if (Contains(id)) { ... }' for each possible object if their number is not too high to iterate.
 | 
			
		||||
// - USING THIS IS NOT MANDATORY. This is only a helper and not a required API.
 | 
			
		||||
// To store a multi-selection, in your application you could:
 | 
			
		||||
// - Use this helper as a convenience. We use our simple key->value ImGuiStorage as a std::set<ImGuiID> replacement.
 | 
			
		||||
// - Use your own external storage: e.g. std::set<MyObjectId>, std::vector<MyObjectId>, interval trees, intrusively stored selection etc.
 | 
			
		||||
// In ImGuiSelectionBasicStorage we:
 | 
			
		||||
// - always use indices in the multi-selection API (passed to SetNextItemSelectionUserData(), retrieved in ImGuiMultiSelectIO)
 | 
			
		||||
// - use the AdapterIndexToStorageId() indirection layer to abstract how persistent selection data is derived from an index.
 | 
			
		||||
// - use decently optimized logic to allow queries and insertion of very large selection sets.
 | 
			
		||||
// - do not preserve selection order.
 | 
			
		||||
// Many combinations are possible depending on how you prefer to store your items and how you prefer to store your selection.
 | 
			
		||||
// Large applications are likely to eventually want to get rid of this indirection layer and do their own thing.
 | 
			
		||||
// See https://github.com/ocornut/imgui/wiki/Multi-Select for details and pseudo-code using this helper.
 | 
			
		||||
struct ImGuiSelectionBasicStorage
 | 
			
		||||
{
 | 
			
		||||
    // Members
 | 
			
		||||
    int             Size;           //          // Number of selected items, maintained by this helper.
 | 
			
		||||
    bool            PreserveOrder;  // = false  // GetNextSelectedItem() will return ordered selection (currently implemented by two additional sorts of selection. Could be improved)
 | 
			
		||||
    void*           UserData;       // = NULL   // User data for use by adapter function        // e.g. selection.UserData = (void*)my_items;
 | 
			
		||||
    ImGuiID         (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx);      // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->UserData)[idx]->ID; };
 | 
			
		||||
    int             _SelectionOrder;// [Internal] Increasing counter to store selection order
 | 
			
		||||
    ImGuiStorage    _Storage;       // [Internal] Selection set. Think of this as similar to e.g. std::set<ImGuiID>. Prefer not accessing directly: iterate with GetNextSelectedItem().
 | 
			
		||||
 | 
			
		||||
    // Methods
 | 
			
		||||
    ImGuiSelectionBasicStorage();
 | 
			
		||||
    IMGUI_API void  ApplyRequests(ImGuiMultiSelectIO* ms_io);   // Apply selection requests coming from BeginMultiSelect() and EndMultiSelect() functions. It uses 'items_count' passed to BeginMultiSelect()
 | 
			
		||||
    IMGUI_API bool  Contains(ImGuiID id) const;                 // Query if an item id is in selection.
 | 
			
		||||
    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)) { ... }'
 | 
			
		||||
    inline ImGuiID  GetStorageIdFromIndex(int idx)              { return AdapterIndexToStorageId(this, idx); }  // Convert index to item id based on provided adapter.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Optional helper to apply multi-selection requests to existing randomly accessible storage.
 | 
			
		||||
// Convenient if you want to quickly wire multi-select API on e.g. an array of bool or items storing their own selection state.
 | 
			
		||||
struct ImGuiSelectionExternalStorage
 | 
			
		||||
{
 | 
			
		||||
    // Members
 | 
			
		||||
    void*           UserData;       // User data for use by adapter function                                // e.g. selection.UserData = (void*)my_items;
 | 
			
		||||
    void            (*AdapterSetItemSelected)(ImGuiSelectionExternalStorage* self, int idx, bool selected); // e.g. AdapterSetItemSelected = [](ImGuiSelectionExternalStorage* self, int idx, bool selected) { ((MyItems**)self->UserData)[idx]->Selected = selected; }
 | 
			
		||||
 | 
			
		||||
    // Methods
 | 
			
		||||
    IMGUI_API ImGuiSelectionExternalStorage();
 | 
			
		||||
    IMGUI_API void  ApplyRequests(ImGuiMultiSelectIO* ms_io);   // Apply selection requests by using AdapterSetItemSelected() calls
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
 | 
			
		||||
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1200
									
								
								imgui_demo.cpp
									
									
									
									
									
								
							
							
						
						
									
										1200
									
								
								imgui_demo.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										107
									
								
								imgui_internal.h
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								imgui_internal.h
									
									
									
									
									
								
							@@ -22,6 +22,7 @@ Index of this file:
 | 
			
		||||
// [SECTION] Navigation support
 | 
			
		||||
// [SECTION] Typing-select support
 | 
			
		||||
// [SECTION] Columns support
 | 
			
		||||
// [SECTION] Box-select support
 | 
			
		||||
// [SECTION] Multi-select support
 | 
			
		||||
// [SECTION] Docking support
 | 
			
		||||
// [SECTION] Viewport support
 | 
			
		||||
@@ -124,6 +125,7 @@ struct ImBitVector;                 // Store 1-bit per value
 | 
			
		||||
struct ImRect;                      // An axis-aligned rectangle (2 points)
 | 
			
		||||
struct ImDrawDataBuilder;           // Helper to build a ImDrawData instance
 | 
			
		||||
struct ImDrawListSharedData;        // Data shared between all ImDrawList instances
 | 
			
		||||
struct ImGuiBoxSelectState;         // Box-selection state (currently used by multi-selection, could potentially be used by others)
 | 
			
		||||
struct ImGuiColorMod;               // Stacked color modifier, backup of modified data so we can restore it
 | 
			
		||||
struct ImGuiContext;                // Main Dear ImGui context
 | 
			
		||||
struct ImGuiContextHook;            // Hook for extensions like ImGuiTestEngine
 | 
			
		||||
@@ -139,6 +141,8 @@ struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a de
 | 
			
		||||
struct ImGuiLastItemData;           // Status storage for last submitted items
 | 
			
		||||
struct ImGuiLocEntry;               // A localization entry.
 | 
			
		||||
struct ImGuiMenuColumns;            // Simple column measurement, currently used for MenuItem() only
 | 
			
		||||
struct ImGuiMultiSelectState;       // Multi-selection persistent state (for focused selection).
 | 
			
		||||
struct ImGuiMultiSelectTempData;    // Multi-selection temporary state (while traversing).
 | 
			
		||||
struct ImGuiNavItemData;            // Result of a gamepad/keyboard directional navigation move query result
 | 
			
		||||
struct ImGuiMetricsConfig;          // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
 | 
			
		||||
struct ImGuiNextWindowData;         // Storage for SetNextWindow** functions
 | 
			
		||||
@@ -500,6 +504,7 @@ static inline int    ImModPositive(int a, int b)
 | 
			
		||||
static inline float  ImDot(const ImVec2& a, const ImVec2& b)                    { return a.x * b.x + a.y * b.y; }
 | 
			
		||||
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a)        { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
 | 
			
		||||
static inline float  ImLinearSweep(float current, float target, float speed)    { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
 | 
			
		||||
static inline float  ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
 | 
			
		||||
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs)                { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
 | 
			
		||||
static inline bool   ImIsFloatAboveGuaranteedIntegerPrecision(float f)          { return f <= -16777216 || f >= 16777216; }
 | 
			
		||||
static inline float  ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
 | 
			
		||||
@@ -866,6 +871,7 @@ enum ImGuiItemFlagsPrivate_
 | 
			
		||||
    // Controlled by widget code
 | 
			
		||||
    ImGuiItemFlags_Inputable                = 1 << 20, // false     // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
 | 
			
		||||
    ImGuiItemFlags_HasSelectionUserData     = 1 << 21, // false     // Set by SetNextItemSelectionUserData()
 | 
			
		||||
    ImGuiItemFlags_IsMultiSelect            = 1 << 22, // false     // Set by SetNextItemSelectionUserData()
 | 
			
		||||
 | 
			
		||||
    ImGuiItemFlags_Default_                 = ImGuiItemFlags_AutoClosePopups,    // Please don't change, use PushItemFlag() instead.
 | 
			
		||||
 | 
			
		||||
@@ -1221,10 +1227,6 @@ struct ImGuiNextWindowData
 | 
			
		||||
    inline void ClearFlags()    { Flags = ImGuiNextWindowDataFlags_None; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Multi-Selection item index or identifier when using SetNextItemSelectionUserData()/BeginMultiSelect()
 | 
			
		||||
// (Most users are likely to use this store an item INDEX but this may be used to store a POINTER as well.)
 | 
			
		||||
typedef ImS64 ImGuiSelectionUserData;
 | 
			
		||||
 | 
			
		||||
enum ImGuiNextItemDataFlags_
 | 
			
		||||
{
 | 
			
		||||
    ImGuiNextItemDataFlags_None         = 0,
 | 
			
		||||
@@ -1237,8 +1239,9 @@ enum ImGuiNextItemDataFlags_
 | 
			
		||||
struct ImGuiNextItemData
 | 
			
		||||
{
 | 
			
		||||
    ImGuiNextItemDataFlags      Flags;
 | 
			
		||||
    ImGuiItemFlags              ItemFlags;          // Currently only tested/used for ImGuiItemFlags_AllowOverlap.
 | 
			
		||||
    ImGuiItemFlags              ItemFlags;          // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData.
 | 
			
		||||
    // Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem()
 | 
			
		||||
    ImGuiID                     FocusScopeId;       // Set by SetNextItemSelectionUserData()
 | 
			
		||||
    ImGuiSelectionUserData      SelectionUserData;  // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values)
 | 
			
		||||
    float                       Width;              // Set by SetNextItemWidth()
 | 
			
		||||
    ImGuiKeyChord               Shortcut;           // Set by SetNextItemShortcut()
 | 
			
		||||
@@ -1727,6 +1730,33 @@ struct ImGuiOldColumns
 | 
			
		||||
    ImGuiOldColumns()   { memset(this, 0, sizeof(*this)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// [SECTION] Box-select support
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
struct ImGuiBoxSelectState
 | 
			
		||||
{
 | 
			
		||||
    // Active box-selection data (persistent, 1 active at a time)
 | 
			
		||||
    ImGuiID                 ID;
 | 
			
		||||
    bool                    IsActive;
 | 
			
		||||
    bool                    IsStarting;
 | 
			
		||||
    bool                    IsStartedFromVoid;  // Starting click was not from an item.
 | 
			
		||||
    bool                    RequestClear;
 | 
			
		||||
    ImGuiKeyChord           KeyMods : 16;       // Latched key-mods for box-select logic.
 | 
			
		||||
    ImVec2                  StartPosRel;        // Start position in window-contents relative space (to support scrolling)
 | 
			
		||||
    ImVec2                  EndPosRel;          // End position in window-contents relative space
 | 
			
		||||
    ImVec2                  ScrollAccum;        // Scrolling accumulator (to behave at high-frame spaces)
 | 
			
		||||
    ImGuiWindow*            Window;
 | 
			
		||||
 | 
			
		||||
    // Temporary/Transient data
 | 
			
		||||
    bool                    UnclipMode;         // (Temp/Transient, here in hot area). Set/cleared by the BeginMultiSelect()/EndMultiSelect() owning active box-select.
 | 
			
		||||
    ImRect                  UnclipRect;         // Rectangle where ItemAdd() clipping may be temporarily disabled. Need support by multi-select supporting widgets.
 | 
			
		||||
    ImRect                  BoxSelectRectPrev;  // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos)
 | 
			
		||||
    ImRect                  BoxSelectRectCurr;
 | 
			
		||||
 | 
			
		||||
    ImGuiBoxSelectState()   { memset(this, 0, sizeof(*this)); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// [SECTION] Multi-select support
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
@@ -1734,9 +1764,45 @@ struct ImGuiOldColumns
 | 
			
		||||
// We always assume that -1 is an invalid value (which works for indices and pointers)
 | 
			
		||||
#define ImGuiSelectionUserData_Invalid        ((ImGuiSelectionUserData)-1)
 | 
			
		||||
 | 
			
		||||
#ifdef IMGUI_HAS_MULTI_SELECT
 | 
			
		||||
// <this is filled in 'range_select' branch>
 | 
			
		||||
#endif // #ifdef IMGUI_HAS_MULTI_SELECT
 | 
			
		||||
// Temporary storage for multi-select
 | 
			
		||||
struct IMGUI_API ImGuiMultiSelectTempData
 | 
			
		||||
{
 | 
			
		||||
    ImGuiMultiSelectIO      IO;                 // MUST BE FIRST FIELD. Requests are set and returned by BeginMultiSelect()/EndMultiSelect() + written to by user during the loop.
 | 
			
		||||
    ImGuiMultiSelectState*  Storage;
 | 
			
		||||
    ImGuiID                 FocusScopeId;       // Copied from g.CurrentFocusScopeId (unless another selection scope was pushed manually)
 | 
			
		||||
    ImGuiMultiSelectFlags   Flags;
 | 
			
		||||
    ImVec2                  ScopeRectMin;
 | 
			
		||||
    ImVec2                  BackupCursorMaxPos;
 | 
			
		||||
    ImGuiID                 BoxSelectId;
 | 
			
		||||
    ImGuiKeyChord           KeyMods;
 | 
			
		||||
    ImS8                    LoopRequestSetAll;  // -1: no operation, 0: clear all, 1: select all.
 | 
			
		||||
    bool                    IsEndIO;            // Set when switching IO from BeginMultiSelect() to EndMultiSelect() state.
 | 
			
		||||
    bool                    IsFocused;          // Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection.
 | 
			
		||||
    bool                    IsKeyboardSetRange; // Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
 | 
			
		||||
    bool                    NavIdPassedBy;
 | 
			
		||||
    bool                    RangeSrcPassedBy;   // Set by the item that matches RangeSrcItem.
 | 
			
		||||
    bool                    RangeDstPassedBy;   // Set by the item that matches NavJustMovedToId when IsSetRange is set.
 | 
			
		||||
    ImGuiSelectionUserData  BoxSelectLastitem;  // Copy of last submitted item data, used to merge output ranges.
 | 
			
		||||
 | 
			
		||||
    ImGuiMultiSelectTempData()  { Clear(); }
 | 
			
		||||
    void Clear()            { size_t io_sz = sizeof(IO); ClearIO(); memset((void*)(&IO + 1), 0, sizeof(*this) - io_sz); } // Zero-clear except IO as we preserve IO.Requests[] buffer allocation.
 | 
			
		||||
    void ClearIO()          { IO.Requests.resize(0); IO.RangeSrcItem = IO.NavIdItem = ImGuiSelectionUserData_Invalid; IO.NavIdSelected = IO.RangeSrcReset = false; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Persistent storage for multi-select (as long as selection is alive)
 | 
			
		||||
struct IMGUI_API ImGuiMultiSelectState
 | 
			
		||||
{
 | 
			
		||||
    ImGuiWindow*            Window;
 | 
			
		||||
    ImGuiID                 ID;
 | 
			
		||||
    int                     LastFrameActive;    // Last used frame-count, for GC.
 | 
			
		||||
    int                     LastSelectionSize;  // Set by BeginMultiSelect() based on optional info provided by user. May be -1 if unknown.
 | 
			
		||||
    ImS8                    RangeSelected;      // -1 (don't have) or true/false
 | 
			
		||||
    ImS8                    NavIdSelected;      // -1 (don't have) or true/false
 | 
			
		||||
    ImGuiSelectionUserData  RangeSrcItem;       //
 | 
			
		||||
    ImGuiSelectionUserData  NavIdItem;          // SetNextItemSelectionUserData() value for NavId (if part of submitted items)
 | 
			
		||||
 | 
			
		||||
    ImGuiMultiSelectState() { Window = NULL; ID = 0; LastFrameActive = LastSelectionSize = 0; RangeSelected = NavIdSelected = -1; RangeSrcItem = NavIdItem = ImGuiSelectionUserData_Invalid; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//-----------------------------------------------------------------------------
 | 
			
		||||
// [SECTION] Docking support
 | 
			
		||||
@@ -2207,7 +2273,7 @@ struct ImGuiContext
 | 
			
		||||
    ImGuiKeyOwnerData       KeysOwnerData[ImGuiKey_NamedKey_COUNT];
 | 
			
		||||
    ImGuiKeyRoutingTable    KeysRoutingTable;
 | 
			
		||||
    ImU32                   ActiveIdUsingNavDirMask;            // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
 | 
			
		||||
    bool                    ActiveIdUsingAllKeyboardKeys;       // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency)
 | 
			
		||||
    bool                    ActiveIdUsingAllKeyboardKeys;       // Active widget will want to read all keyboard keys inputs. (this is a shortcut for not taking ownership of 100+ keys, frequently used by drag operations)
 | 
			
		||||
    ImGuiKeyChord           DebugBreakInShortcutRouting;        // Set to break in SetShortcutRouting()/Shortcut() calls.
 | 
			
		||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
 | 
			
		||||
    ImU32                   ActiveIdUsingNavInputMask;          // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);'
 | 
			
		||||
@@ -2354,6 +2420,13 @@ struct ImGuiContext
 | 
			
		||||
    ImVector<ImGuiPtrOrIndex>       CurrentTabBarStack;
 | 
			
		||||
    ImVector<ImGuiShrinkWidthItem>  ShrinkWidthBuffer;
 | 
			
		||||
 | 
			
		||||
    // Multi-Select state
 | 
			
		||||
    ImGuiBoxSelectState             BoxSelectState;
 | 
			
		||||
    ImGuiMultiSelectTempData*       CurrentMultiSelect;
 | 
			
		||||
    int                             MultiSelectTempDataStacked; // Temporary multi-select data size (because we leave previous instances undestructed, we generally don't use MultiSelectTempData.Size)
 | 
			
		||||
    ImVector<ImGuiMultiSelectTempData> MultiSelectTempData;
 | 
			
		||||
    ImPool<ImGuiMultiSelectState>   MultiSelectStorage;
 | 
			
		||||
 | 
			
		||||
    // Hover Delay system
 | 
			
		||||
    ImGuiID                 HoverItemDelayId;
 | 
			
		||||
    ImGuiID                 HoverItemDelayIdPreviousFrame;
 | 
			
		||||
@@ -2608,6 +2681,8 @@ struct ImGuiContext
 | 
			
		||||
        CurrentTable = NULL;
 | 
			
		||||
        TablesTempDataStacked = 0;
 | 
			
		||||
        CurrentTabBar = NULL;
 | 
			
		||||
        CurrentMultiSelect = NULL;
 | 
			
		||||
        MultiSelectTempDataStacked = 0;
 | 
			
		||||
 | 
			
		||||
        HoverItemDelayId = HoverItemDelayIdPreviousFrame = HoverItemUnlockedStationaryId = HoverWindowUnlockedStationaryId = 0;
 | 
			
		||||
        HoverItemDelayTimer = HoverItemDelayClearTimer = 0.0f;
 | 
			
		||||
@@ -3291,6 +3366,7 @@ namespace ImGui
 | 
			
		||||
    inline ImRect           WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
 | 
			
		||||
    inline ImRect           WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
 | 
			
		||||
    inline ImVec2           WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
 | 
			
		||||
    inline ImVec2           WindowPosAbsToRel(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x - off.x, p.y - off.y); }
 | 
			
		||||
 | 
			
		||||
    // Windows: Display Order and Focus Order
 | 
			
		||||
    IMGUI_API void          FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0);
 | 
			
		||||
@@ -3397,7 +3473,6 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API ImVec2        CalcItemSize(ImVec2 size, float default_w, float default_h);
 | 
			
		||||
    IMGUI_API float         CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
 | 
			
		||||
    IMGUI_API void          PushMultiItemsWidths(int components, float width_full);
 | 
			
		||||
    IMGUI_API bool          IsItemToggledSelection();                                   // Was the last item selection toggled? (after Selectable(), TreeNode() etc. We only returns toggle _event_ in order to handle clipping correctly)
 | 
			
		||||
    IMGUI_API ImVec2        GetContentRegionMaxAbs();
 | 
			
		||||
    IMGUI_API void          ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
 | 
			
		||||
 | 
			
		||||
@@ -3633,6 +3708,16 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API int           TypingSelectFindNextSingleCharMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data, int nav_item_idx);
 | 
			
		||||
    IMGUI_API int           TypingSelectFindBestLeadingMatch(ImGuiTypingSelectRequest* req, int items_count, const char* (*get_item_name_func)(void*, int), void* user_data);
 | 
			
		||||
 | 
			
		||||
    // Box-Select API
 | 
			
		||||
    IMGUI_API bool          BeginBoxSelect(ImGuiWindow* window, ImGuiID box_select_id, ImGuiMultiSelectFlags ms_flags);
 | 
			
		||||
    IMGUI_API void          EndBoxSelect(const ImRect& scope_rect, ImGuiMultiSelectFlags ms_flags);
 | 
			
		||||
 | 
			
		||||
    // Multi-Select API
 | 
			
		||||
    IMGUI_API void          MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags* p_button_flags);
 | 
			
		||||
    IMGUI_API void          MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed);
 | 
			
		||||
    inline ImGuiBoxSelectState*     GetBoxSelectState(ImGuiID id)   { ImGuiContext& g = *GImGui; return (id != 0 && g.BoxSelectState.ID == id && g.BoxSelectState.IsActive) ? &g.BoxSelectState : NULL; }
 | 
			
		||||
    inline ImGuiMultiSelectState*   GetMultiSelectState(ImGuiID id) { ImGuiContext& g = *GImGui; return g.MultiSelectStorage.GetByKey(id); }
 | 
			
		||||
 | 
			
		||||
    // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
 | 
			
		||||
    IMGUI_API void          SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect);
 | 
			
		||||
    IMGUI_API void          BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
 | 
			
		||||
@@ -3773,7 +3858,6 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API bool          DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags);
 | 
			
		||||
    IMGUI_API bool          SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb);
 | 
			
		||||
    IMGUI_API bool          SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, ImU32 bg_col = 0);
 | 
			
		||||
    IMGUI_API void          SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
 | 
			
		||||
 | 
			
		||||
    // Widgets: Tree Nodes
 | 
			
		||||
    IMGUI_API bool          TreeNodeBehavior(ImGuiID id, ImGuiID storage_id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
 | 
			
		||||
@@ -3856,6 +3940,7 @@ namespace ImGui
 | 
			
		||||
    IMGUI_API void          DebugNodeTableSettings(ImGuiTableSettings* settings);
 | 
			
		||||
    IMGUI_API void          DebugNodeInputTextState(ImGuiInputTextState* state);
 | 
			
		||||
    IMGUI_API void          DebugNodeTypingSelectState(ImGuiTypingSelectState* state);
 | 
			
		||||
    IMGUI_API void          DebugNodeMultiSelectState(ImGuiMultiSelectState* state);
 | 
			
		||||
    IMGUI_API void          DebugNodeWindow(ImGuiWindow* window, const char* label);
 | 
			
		||||
    IMGUI_API void          DebugNodeWindowSettings(ImGuiWindowSettings* settings);
 | 
			
		||||
    IMGUI_API void          DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1026
									
								
								imgui_widgets.cpp
									
									
									
									
									
								
							
							
						
						
									
										1026
									
								
								imgui_widgets.cpp
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user