diff --git a/imgui.cpp b/imgui.cpp index eecff101..a43fc5ed 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1091,8 +1091,8 @@ ImGuiIO::ImGuiIO() memset(this, 0, sizeof(*this)); // Settings - ConfigFlags = 0x00; - BackendFlags = 0x00; + ConfigFlags = ImGuiConfigFlags_None; + BackendFlags = ImGuiBackendFlags_None; DisplaySize = ImVec2(-1.0f, -1.0f); DeltaTime = 1.0f/60.0f; IniSavingRate = 5.0f; @@ -3026,7 +3026,7 @@ void ImGui::UpdateMouseMovingWindow() { // Try to merge the window back into the main viewport. // This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports) - if (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + if (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable) UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport); // Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button. @@ -3329,6 +3329,7 @@ void ImGui::NewFrame() g.FrameCount += 1; g.TooltipOverrideCount = 0; g.WindowsActiveCount = 0; + g.ConfigFlagsForFrame = g.IO.ConfigFlags; UpdateViewports(); @@ -3856,6 +3857,7 @@ void ImGui::EndFrame() for (int i = 0; i < g.Viewports.Size; i++) { ImGuiViewportP* viewport = g.Viewports[i]; + viewport->LastPos = viewport->Pos; if (viewport->LastFrameActive < g.FrameCount || viewport->Size.x <= 0.0f || viewport->Size.y <= 0.0f) continue; if (viewport->Window && !IsWindowActiveAndVisible(viewport->Window)) @@ -7410,7 +7412,7 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) { // Tooltips and menus are not automatically forced into their own viewport when the NoMerge flag is set, however the multiplication of viewports makes them more likely to protude and create their own. ImGuiContext& g = *GImGui; - if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsNoMerge) && (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsNoMerge) && (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) if (!window->DockIsActive) if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip)) == 0) return true; @@ -7493,7 +7495,7 @@ static void ImGui::UpdateViewports() IM_ASSERT(main_viewport->ID == IMGUI_VIEWPORT_DEFAULT_ID); IM_ASSERT(main_viewport->Window == NULL); ImVec2 main_viewport_platform_pos = ImVec2(0.0f, 0.0f); - if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) main_viewport_platform_pos = g.PlatformIO.Platform_GetWindowPos(main_viewport); AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, g.IO.DisplaySize, ImGuiViewportFlags_CanHostOtherWindows); @@ -7527,7 +7529,7 @@ static void ImGui::UpdateViewports() continue; } - if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) { if (g.PlatformIO.Platform_GetWindowMinimized && (n == 0 || viewport->CreatedPlatformWindow)) viewport->PlatformIsMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); @@ -7542,17 +7544,18 @@ static void ImGui::UpdateViewports() viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); } - // Translate imgui windows when a Host Viewport has been moved - ImVec2 delta = viewport->Pos - viewport->LastPos; - if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && (delta.x != 0.0f || delta.y != 0.0f)) - for (int window_n = 0; window_n < g.Windows.Size; window_n++) - if (g.Windows[window_n]->Viewport == viewport) - TranslateWindow(g.Windows[window_n], delta); - // Update monitor (we'll use this info to clamp windows and save windows lost in a removed monitor) viewport->PlatformMonitor = FindPlatformMonitorForRect(viewport->GetRect()); } + // Translate imgui windows when a Host Viewport has been moved + // (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!) + ImVec2 viewport_delta = viewport->Pos - viewport->LastPos; + if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && (viewport_delta.x != 0.0f || viewport_delta.y != 0.0f)) + for (int window_n = 0; window_n < g.Windows.Size; window_n++) + if (g.Windows[window_n]->Viewport == viewport || (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable) == 0) + TranslateWindow(g.Windows[window_n], viewport_delta); + // Update DPI scale float new_dpi_scale; if (g.PlatformIO.Platform_GetWindowDpiScale) @@ -7576,7 +7579,7 @@ static void ImGui::UpdateViewports() viewport->DpiScale = new_dpi_scale; } - if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) { g.MouseViewport = main_viewport; return; @@ -7693,7 +7696,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) // Restore main viewport if multi-viewport is not supported by the back-end ImGuiViewportP* main_viewport = g.Viewports[0]; - if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) { SetWindowViewport(window, main_viewport); return; @@ -7815,8 +7818,7 @@ void ImGui::UpdatePlatformWindows() IM_ASSERT(g.FrameCountEnded == g.FrameCount && "Forgot to call Render() or EndFrame() before UpdatePlatformWindows()?"); IM_ASSERT(g.FrameCountPlatformEnded < g.FrameCount); g.FrameCountPlatformEnded = g.FrameCount; - g.Viewports[0]->LastPos = g.Viewports[0]->Pos; - if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) + if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)) return; // Create/resize/destroy platform windows to match each active viewport. @@ -7824,7 +7826,6 @@ void ImGui::UpdatePlatformWindows() for (int i = 1; i < g.Viewports.Size; i++) { ImGuiViewportP* viewport = g.Viewports[i]; - viewport->LastPos = viewport->Pos; // Destroy platform window if the viewport hasn't been submitted or if it is hosting a hidden window (the implicit Debug window will be registered its viewport then be disabled) bool destroy_platform_window = false; diff --git a/imgui.h b/imgui.h index 0096bfc0..50ffa88f 100644 --- a/imgui.h +++ b/imgui.h @@ -6,9 +6,27 @@ // Read 'Programmer guide' in imgui.cpp for notes on how to setup ImGui in your codebase. // Get latest version at https://github.com/ocornut/imgui +/* + +Index of this file: +// Header mess +// Forward declarations and basic types +// ImGui API (Dear ImGui end-user API) +// Flags & Enumerations +// ImGuiStyle +// ImGuiIO +// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiDockFamily) +// Obsolete functions +// Helpers (ImVector, ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) +// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData) +// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFont) +// Platform interface for multi-viewport support (ImGuiPlatformMonitor, ImGuiPlatformIO, ImGuiViewport) + +*/ + #pragma once -// Configuration file (edit imconfig.h or define IMGUI_USER_CONFIG to set your own filename) +// Configuration file (edit imconfig.h or define IMGUI_USER_CONFIG to your own filename) #ifdef IMGUI_USER_CONFIG #include IMGUI_USER_CONFIG #endif @@ -16,6 +34,10 @@ #include "imconfig.h" #endif +//----------------------------------------------------------------------------- +// Header mess +//----------------------------------------------------------------------------- + #include // FLT_MAX #include // va_list #include // ptrdiff_t, NULL @@ -39,7 +61,7 @@ #define IMGUI_IMPL_API IMGUI_API #endif -// Helpers +// Helper Macros #ifndef IM_ASSERT #include #define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h @@ -54,6 +76,7 @@ #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) // Size of a static C-style array. Don't use on pointers! #define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in modern C++. +// Warnings #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" @@ -62,7 +85,10 @@ #pragma GCC diagnostic ignored "-Wclass-memaccess" #endif -// Forward declarations +//----------------------------------------------------------------------------- +// Forward declarations and basic types +//----------------------------------------------------------------------------- + struct ImDrawChannel; // Temporary storage for outputting drawing commands out of order, used by ImDrawList::ChannelsSplit() struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) struct ImDrawData; // All draw command lists required to render the frame @@ -165,8 +191,11 @@ struct ImVec4 #endif }; -// Dear ImGui end-user API -// (In a namespace so you can add extra functions in your own separate file. Please don't modify imgui.cpp/.h!) +//----------------------------------------------------------------------------- +// ImGui: Dear ImGui end-user API +// (Inside a namespace so you can add extra functions in your own separate file. Please don't modify imgui.cpp/.h!) +//----------------------------------------------------------------------------- + namespace ImGui { // Context creation and access @@ -654,6 +683,10 @@ namespace ImGui } // namespace ImGui +//----------------------------------------------------------------------------- +// Flags & Enumerations +//----------------------------------------------------------------------------- + // Flags for ImGui::Begin() enum ImGuiWindowFlags_ { @@ -951,6 +984,7 @@ enum ImGuiNavInput_ // Configuration flags stored in io.ConfigFlags. Set by user/application. enum ImGuiConfigFlags_ { + ImGuiConfigFlags_None = 0, ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeysDown[]. ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. Back-end also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. @@ -979,6 +1013,7 @@ enum ImGuiConfigFlags_ // Back-end capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom back-end. enum ImGuiBackendFlags_ { + ImGuiBackendFlags_None = 0, ImGuiBackendFlags_HasGamepad = 1 << 0, // Back-end supports gamepad and currently has one connected. ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Back-end supports honoring GetMouseCursor() value to change the OS cursor shape. ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Back-end supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). @@ -1089,7 +1124,7 @@ enum ImGuiStyleVar_ #endif }; -// Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() +// Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() enum ImGuiColorEditFlags_ { ImGuiColorEditFlags_None = 0, @@ -1144,7 +1179,8 @@ enum ImGuiMouseCursor_ #endif }; -// Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// Enumateration for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions +// Represent a condition. // Important: Treat as a regular enum! Do NOT combine multiple values using binary operators! All the functions above treat 0 as a shortcut to ImGuiCond_Always. enum ImGuiCond_ { @@ -1159,8 +1195,13 @@ enum ImGuiCond_ #endif }; +//----------------------------------------------------------------------------- +// ImGuiStyle // You may modify the ImGui::GetStyle() main instance during initialization and before NewFrame(). -// During the frame, use ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values, and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors. +// During the frame, use ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values, +// and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors. +//----------------------------------------------------------------------------- + struct ImGuiStyle { float Alpha; // Global alpha applies to everything in ImGui. @@ -1200,8 +1241,12 @@ struct ImGuiStyle IMGUI_API void ScaleAllSizes(float scale_factor); }; -// This is where your app communicate with Dear ImGui. Access via ImGui::GetIO(). -// Read 'Programmer guide' section in .cpp file for general usage. +//----------------------------------------------------------------------------- +// ImGuiIO +// Communicate most settings and inputs/outputs to Dear ImGui using this structure. +// Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage. +//----------------------------------------------------------------------------- + struct ImGuiIO { //------------------------------------------------------------------ @@ -1319,6 +1364,87 @@ struct ImGuiIO IMGUI_API ImGuiIO(); }; +//----------------------------------------------------------------------------- +// Misc data structures +//----------------------------------------------------------------------------- + +// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used. +// The callback function should return 0 by default. +// Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details) +// - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB +// - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows +// - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration +// - ImGuiInputTextFlags_CallbackCharFilter: Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. +// - ImGuiInputTextFlags_CallbackResize: Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. +struct ImGuiInputTextCallbackData +{ + ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + void* UserData; // What user passed to InputText() // Read-only + + // Arguments for the different callback events + // - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary. + // - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state. + ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0; + ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History] + char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer! + int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length() + int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1 + bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always] + int CursorPos; // // Read-write // [Completion,History,Always] + int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection) + int SelectionEnd; // // Read-write // [Completion,History,Always] + + // Helper functions for text manipulation. + // Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection. + IMGUI_API ImGuiInputTextCallbackData(); + IMGUI_API void DeleteChars(int pos, int bytes_count); + IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); + bool HasSelection() const { return SelectionStart != SelectionEnd; } +}; + +// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). +// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. +struct ImGuiSizeCallbackData +{ + void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. +}; + +// Data payload for Drag and Drop operations: AcceptDragDropPayload(), GetDragDropPayload() +struct ImGuiPayload +{ + // Members + void* Data; // Data (copied and owned by dear imgui) + int DataSize; // Data size + + // [Internal] + ImGuiID SourceId; // Source item id + ImGuiID SourceParentId; // Source parent id (if available) + int DataFrameCount; // Data timestamp + char DataType[32+1]; // Data type tag (short user-supplied string, 32 characters max) + bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) + bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. + + ImGuiPayload() { Clear(); } + void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; } + bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsPreview() const { return Preview; } + bool IsDelivery() const { return Delivery; } +}; + +// [BETA] For SetNextWindowDockFamily() and DockSpace() function +struct ImGuiDockFamily +{ + ImGuiID ID; // 0 = unaffiliated + bool CompatibleWithFamilyZero; // true = can be docked/merged with an unaffiliated window + + ImGuiDockFamily() { ID = 0; CompatibleWithFamilyZero = true; } + ImGuiDockFamily(ImGuiID id, bool compatible_with_family_zero = true) { ID = id; CompatibleWithFamilyZero = compatible_with_family_zero; } +}; + //----------------------------------------------------------------------------- // Obsolete functions (Will be removed! Read 'API BREAKING CHANGES' section in imgui.cpp for details) //----------------------------------------------------------------------------- @@ -1356,6 +1482,8 @@ namespace ImGui static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } } +typedef ImGuiInputTextCallback ImGuiTextEditCallback; // [OBSOLETE 1.63+] Made the names consistent +typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; #endif //----------------------------------------------------------------------------- @@ -1548,86 +1676,34 @@ struct ImGuiStorage IMGUI_API void BuildSortByKey(); }; -// Shared state of InputText(), passed as an argument to your callback when a ImGuiInputTextFlags_Callback* flag is used. -// The callback function should return 0 by default. -// Callbacks (follow a flag name and see comments in ImGuiInputTextFlags_ declarations for more details) -// - ImGuiInputTextFlags_CallbackCompletion: Callback on pressing TAB -// - ImGuiInputTextFlags_CallbackHistory: Callback on pressing Up/Down arrows -// - ImGuiInputTextFlags_CallbackAlways: Callback on each iteration -// - ImGuiInputTextFlags_CallbackCharFilter: Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. -// - ImGuiInputTextFlags_CallbackResize: Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. -struct ImGuiInputTextCallbackData +// Helper: Manually clip large list of items. +// If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all. +// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. +// ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null. +// Usage: +// ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced. +// while (clipper.Step()) +// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) +// ImGui::Text("line number %d", i); +// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor). +// - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. +// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.) +// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. +struct ImGuiListClipper { - ImGuiInputTextFlags EventFlag; // One ImGuiInputTextFlags_Callback* // Read-only - ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only - void* UserData; // What user passed to InputText() // Read-only + float StartPosY; + float ItemsHeight; + int ItemsCount, StepNo, DisplayStart, DisplayEnd; - // Arguments for the different callback events - // - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary. - // - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state. - ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0; - ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History] - char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer! - int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length() - int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1 - bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always] - int CursorPos; // // Read-write // [Completion,History,Always] - int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection) - int SelectionEnd; // // Read-write // [Completion,History,Always] + // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). + // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). + // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). + ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). + ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. - // Helper functions for text manipulation. - // Use those function to benefit from the CallbackResize behaviors. Calling those function reset the selection. - IMGUI_API ImGuiInputTextCallbackData(); - IMGUI_API void DeleteChars(int pos, int bytes_count); - IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); - bool HasSelection() const { return SelectionStart != SelectionEnd; } -}; - -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -typedef ImGuiInputTextCallback ImGuiTextEditCallback; // [OBSOLETE 1.63+] Made the names consistent -typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; -#endif - -// Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). -// NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. -struct ImGuiSizeCallbackData -{ - void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() - ImVec2 Pos; // Read-only. Window position, for reference. - ImVec2 CurrentSize; // Read-only. Current window size. - ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. -}; - -// [BETA] For SetNextWindowDockFamily() and DockSpace() function -struct ImGuiDockFamily -{ - ImGuiID ID; // 0 = unaffiliated - bool CompatibleWithFamilyZero; // true = can be docked/merged with an unaffiliated window - - ImGuiDockFamily() { ID = 0; CompatibleWithFamilyZero = true; } - ImGuiDockFamily(ImGuiID id, bool compatible_with_family_zero = true) { ID = id; CompatibleWithFamilyZero = compatible_with_family_zero; } -}; - -// Data payload for Drag and Drop operations -struct ImGuiPayload -{ - // Members - void* Data; // Data (copied and owned by dear imgui) - int DataSize; // Data size - - // [Internal] - ImGuiID SourceId; // Source item id - ImGuiID SourceParentId; // Source parent id (if available) - int DataFrameCount; // Data timestamp - char DataType[32+1]; // Data type tag (short user-supplied string, 32 characters max) - bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) - bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. - - ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; } - bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } - bool IsPreview() const { return Preview; } - bool IsDelivery() const { return Delivery; } + IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. + IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. }; // Helpers macros to generate 32-bits encoded colors @@ -1670,38 +1746,8 @@ 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); } }; -// Helper: Manually clip large list of items. -// If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all. -// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. -// ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null. -// Usage: -// ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced. -// while (clipper.Step()) -// for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) -// ImGui::Text("line number %d", i); -// - Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height (step skipped if we passed a known height as second arg to constructor). -// - Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. -// - (Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user call Step(). Does nothing and switch to Step 3.) -// - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. -struct ImGuiListClipper -{ - float StartPosY; - float ItemsHeight; - int ItemsCount, StepNo, DisplayStart, DisplayEnd; - - // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). - // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). - // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). - ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). - ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. - - IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. - IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. - IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. -}; - //----------------------------------------------------------------------------- -// Draw List +// Draw List API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListFlags, ImDrawList, ImDrawData) // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. //----------------------------------------------------------------------------- @@ -1887,6 +1933,10 @@ struct ImDrawData IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. }; +//----------------------------------------------------------------------------- +// Font API (ImFontConfig, ImFontGlyph, ImFontAtlasFlags, ImFontAtlas, ImFont) +//----------------------------------------------------------------------------- + struct ImFontConfig { void* FontData; // // TTF/OTF data @@ -2110,7 +2160,7 @@ struct ImFont //----------------------------------------------------------------------------- // (Optional) Represent the bounds of each connected monitor/display -// Dear ImGui only uses this to clamp the position of popups and tooltips so they don't straddle multiple monitors +// Dear ImGui only uses this to clamp the position of popups and tooltips so they don't straddle multiple monitors. struct ImGuiPlatformMonitor { ImVec2 MainPos, MainSize; // Coordinates of the area displayed on this monitor (Min = upper left, Max = bottom right) @@ -2119,12 +2169,16 @@ struct ImGuiPlatformMonitor ImGuiPlatformMonitor() { MainPos = MainSize = WorkPos = WorkSize = ImVec2(0,0); DpiScale = 1.0f; } }; -// (Optional) Setup required only if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) is enabled. Access via ImGui::GetPlatformIO(). -// This is designed so we can mix and match two imgui_impl_xxxx files, one for the Platform (~window handling), one for Renderer. -// Custom engine back-ends will often provide both Platform and Renderer interfaces and thus may not need to use all functions. -// Platform functions are typically called before their Renderer counterpart, apart from Destroy which are called the other way. -// RenderPlatformWindowsDefault() basically iterate secondary viewports and call Platform+Renderer's RenderWindow then Platform+Renderer's SwapBuffers, -// You may skip using RenderPlatformWindowsDefault() and call your draw/swap functions yourself if you need specific behavior for your multi-window rendering. +// (Optional) Setup required only if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) is enabled. +// Access via ImGui::GetPlatformIO(). This is designed so we can mix and match two imgui_impl_xxxx files, one for +// the Platform (~window handling), one for Renderer. Custom engine back-ends will often provide both Platform +// and Renderer interfaces and thus may not need to use all functions. +// Platform functions are typically called before their Renderer counterpart, +// apart from Destroy which are called the other way. +// RenderPlatformWindowsDefault() is that helper that iterate secondary viewports and call, in this order: +// Platform_RenderWindow(), Renderer_RenderWindow(), Platform_SwapBuffers(), Renderer_SwapBuffers() +// You may skip using RenderPlatformWindowsDefault() and call your draw/swap functions yourself if you need +// specific behavior for your multi-window rendering. struct ImGuiPlatformIO { //------------------------------------------------------------------ @@ -2168,11 +2222,10 @@ struct ImGuiPlatformIO // List of viewports (the list is updated by calling ImGui::EndFrame or ImGui::Render) ImGuiViewport* MainViewport; // Guaranteed to be == Viewports[0] ImVector Viewports; // Main viewports, followed by all secondary viewports. - ImGuiPlatformIO() { memset(this, 0, sizeof(*this)); } // Zero clear }; -// Flags stored in ImGuiViewport::Flags, giving indications to the platform back-ends +// Flags stored in ImGuiViewport::Flags, giving indications to the platform back-ends. enum ImGuiViewportFlags_ { ImGuiViewportFlags_None = 0, @@ -2194,7 +2247,7 @@ struct ImGuiViewport float DpiScale; // 1.0f = 96 DPI = No extra scale ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame(). - void* PlatformUserData; // void* to hold custom data structure for the platform (e.g. windowing info, render context) + void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context) void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GlfwWindow*, SDL_Window*) bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4) bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a9f5cd80..13e92e04 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -351,7 +351,6 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::SameLine(); ShowHelpMarker("Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable); - ImGui::SameLine(); ShowHelpMarker("Toggling this at runtime is normally unsupported (it will offset your windows)."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsNoTaskBarIcon", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsNoTaskBarIcon); ImGui::SameLine(); ShowHelpMarker("Toggling this at runtime is normally unsupported (most platform back-ends won't refresh the task bar icon state right away)."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsDecoration", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsDecoration); diff --git a/imgui_internal.h b/imgui_internal.h index d2c3a2a0..5f746f5e 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -812,6 +812,7 @@ struct ImGuiContext ImGuiIO IO; ImGuiPlatformIO PlatformIO; ImGuiStyle Style; + ImGuiConfigFlags ConfigFlagsForFrame; // = g.IO.ConfigFlags at the time of NewFrame() ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. @@ -986,6 +987,7 @@ struct ImGuiContext { Initialized = false; FrameScopeActive = false; + ConfigFlagsForFrame = ImGuiConfigFlags_None; Font = NULL; FontSize = FontBaseSize = 0.0f; FontAtlasOwnedByContext = shared_font_atlas ? false : true;