mirror of
https://github.com/wolfpld/tracy.git
synced 2024-11-22 22:44:34 +00:00
Update imgui to 1.68.
This commit is contained in:
parent
938d8ce69e
commit
b33c61cead
528
imgui/imgui.cpp
528
imgui/imgui.cpp
File diff suppressed because it is too large
Load Diff
103
imgui/imgui.h
103
imgui/imgui.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.67
|
||||
// dear imgui, v1.68
|
||||
// (headers)
|
||||
|
||||
// See imgui.cpp file for documentation.
|
||||
@ -45,8 +45,8 @@ Index of this file:
|
||||
|
||||
// Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY00 then bounced up to XYY01 when release tagging happens)
|
||||
#define IMGUI_VERSION "1.67"
|
||||
#define IMGUI_VERSION_NUM 16603
|
||||
#define IMGUI_VERSION "1.68"
|
||||
#define IMGUI_VERSION_NUM 16801
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert))
|
||||
|
||||
// Define attributes of all API symbols declarations (e.g. for DLL under Windows)
|
||||
@ -72,12 +72,15 @@ Index of this file:
|
||||
#endif
|
||||
#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++.
|
||||
#define IM_UNUSED(_VAR) ((void)_VAR) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
|
||||
|
||||
// Warnings
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 8
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||
@ -167,7 +170,8 @@ struct ImVec2
|
||||
float x, y;
|
||||
ImVec2() { x = y = 0.0f; }
|
||||
ImVec2(float _x, float _y) { x = _x; y = _y; }
|
||||
float operator[] (size_t i) const { IM_ASSERT(i <= 1); return (&x)[i]; } // We very rarely use this [] operator, the assert overhead is fine.
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
|
||||
float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
|
||||
#ifdef IM_VEC2_CLASS_EXTRA
|
||||
IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2.
|
||||
#endif
|
||||
@ -251,7 +255,8 @@ namespace ImGui
|
||||
IMGUI_API bool IsWindowCollapsed();
|
||||
IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags=0); // is current window focused? or its root/child, depending on flags. see flags for options.
|
||||
IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ!
|
||||
IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the window, to append your own drawing primitives
|
||||
IMGUI_API ImDrawList* GetWindowDrawList(); // get draw list associated to the current window, to append your own drawing primitives
|
||||
|
||||
IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList API)
|
||||
IMGUI_API ImVec2 GetWindowSize(); // get current window size
|
||||
IMGUI_API float GetWindowWidth(); // get current window width (shortcut for GetWindowSize().x)
|
||||
@ -348,13 +353,14 @@ namespace ImGui
|
||||
// ID stack/scopes
|
||||
// - Read the FAQ for more details about how ID are handled in dear imgui. If you are creating widgets in a loop you most
|
||||
// likely want to push a unique identifier (e.g. object pointer, loop index) to uniquely differentiate them.
|
||||
// - The resulting ID are hashes of the entire stack.
|
||||
// - You can also use the "Label##foobar" syntax within widget label to distinguish them from each others.
|
||||
// - In this header file we use the "label"/"name" terminology to denote a string that will be displayed and used as an ID,
|
||||
// whereas "str_id" denote a string that is only used as an ID and not normally displayed.
|
||||
IMGUI_API void PushID(const char* str_id); // push string identifier into the ID stack. IDs == hash of the entire stack!
|
||||
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end);
|
||||
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack.
|
||||
IMGUI_API void PushID(int int_id); // push integer into the ID stack.
|
||||
IMGUI_API void PushID(const char* str_id); // push string into the ID stack (will hash string).
|
||||
IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); // push string into the ID stack (will hash string).
|
||||
IMGUI_API void PushID(const void* ptr_id); // push pointer into the ID stack (will hash pointer).
|
||||
IMGUI_API void PushID(int int_id); // push integer into the ID stack (will hash integer).
|
||||
IMGUI_API void PopID(); // pop from the ID stack.
|
||||
IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself
|
||||
IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end);
|
||||
@ -601,6 +607,7 @@ namespace ImGui
|
||||
IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) == IsMouseClicked(mouse_button) && IsItemHovered()
|
||||
IMGUI_API bool IsItemVisible(); // is the last item visible? (items may be out of sight because of clipping/scrolling)
|
||||
IMGUI_API bool IsItemEdited(); // did the last item modify its underlying value this frame? or was pressed? This is generally the same as the "bool" return value of many widgets.
|
||||
IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).
|
||||
IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing.
|
||||
IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).
|
||||
IMGUI_API bool IsAnyItemHovered();
|
||||
@ -670,7 +677,7 @@ namespace ImGui
|
||||
// Memory Utilities
|
||||
// - All those functions are not reliant on the current context.
|
||||
// - If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again.
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data = NULL);
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
|
||||
IMGUI_API void* MemAlloc(size_t size);
|
||||
IMGUI_API void MemFree(void* ptr);
|
||||
|
||||
@ -804,8 +811,8 @@ enum ImGuiTabBarFlags_
|
||||
ImGuiTabBarFlags_None = 0,
|
||||
ImGuiTabBarFlags_Reorderable = 1 << 0, // Allow manually dragging tabs to re-order them + New tabs are appended at the end of list
|
||||
ImGuiTabBarFlags_AutoSelectNewTabs = 1 << 1, // Automatically select new tabs when they appear
|
||||
ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
|
||||
ImGuiTabBarFlags_NoTabListPopupButton = 1 << 3,
|
||||
ImGuiTabBarFlags_TabListPopupButton = 1 << 2,
|
||||
ImGuiTabBarFlags_NoCloseWithMiddleMouseButton = 1 << 3, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
|
||||
ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4,
|
||||
ImGuiTabBarFlags_NoTooltip = 1 << 5, // Disable tooltips when hovering a tab
|
||||
ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 6, // Resize tabs when they don't fit
|
||||
@ -1075,6 +1082,7 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
|
||||
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
|
||||
ImGuiStyleVar_COUNT
|
||||
|
||||
// Obsolete names (will be removed)
|
||||
@ -1249,7 +1257,8 @@ struct ImGuiStyle
|
||||
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
float TabBorderSize; // Thickness of border around tabs.
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered.
|
||||
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
|
||||
ImVec2 SelectableTextAlign; // Alignment of selectable text when selectable is larger than text. Defaults to (0.0f, 0.0f) (top-left aligned).
|
||||
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows.
|
||||
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
@ -1276,7 +1285,7 @@ struct ImGuiIO
|
||||
|
||||
ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.
|
||||
ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by back-end (imgui_impl_xxx files or custom back-end) to communicate features supported by the back-end.
|
||||
ImVec2 DisplaySize; // <unset> // Main display size, in pixels. For clamping windows positions.
|
||||
ImVec2 DisplaySize; // <unset> // Main display size, in pixels.
|
||||
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
|
||||
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
|
||||
const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory.
|
||||
@ -1293,16 +1302,14 @@ struct ImGuiIO
|
||||
float FontGlobalScale; // = 1.0f // Global scale all fonts
|
||||
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.
|
||||
ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].
|
||||
ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui.
|
||||
ImVec2 DisplayVisibleMin; // <unset> // [OBSOLETE] If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area.
|
||||
ImVec2 DisplayVisibleMax; // <unset> // [OBSOLETE] Just use io.DisplaySize! If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize
|
||||
ImVec2 DisplayFramebufferScale; // = (1, 1) // For retina display or other situations where window coordinates are different from framebuffer coordinates. This generally ends up in ImDrawData::FramebufferScale.
|
||||
|
||||
// Miscellaneous configuration options
|
||||
// Miscellaneous options
|
||||
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by back-end implementations.
|
||||
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63)
|
||||
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
|
||||
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be the a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
|
||||
bool ConfigWindowsMoveFromTitleBarOnly;// = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
|
||||
bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Platform Functions
|
||||
@ -1490,7 +1497,7 @@ namespace ImGui
|
||||
// OBSOLETED in 1.60 (between Dec 2017 and Apr 2018)
|
||||
static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); }
|
||||
static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
|
||||
static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { (void)on_edge; (void)outward; IM_ASSERT(0); return pos; }
|
||||
static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { IM_UNUSED(on_edge); IM_UNUSED(outward); IM_ASSERT(0); return pos; }
|
||||
// OBSOLETED in 1.53 (between Oct 2017 and Dec 2017)
|
||||
static inline void ShowTestWindow() { return ShowDemoWindow(); }
|
||||
static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); }
|
||||
@ -1579,11 +1586,12 @@ struct ImGuiTextBuffer
|
||||
inline char operator[](int i) { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; }
|
||||
const char* begin() const { return Buf.Data ? &Buf.front() : EmptyString; }
|
||||
const char* end() const { return Buf.Data ? &Buf.back() : EmptyString; } // Buf is zero-terminated, so end() will point on the zero-terminator
|
||||
int size() const { return Buf.Data ? Buf.Size - 1 : 0; }
|
||||
int size() const { return Buf.Size ? Buf.Size - 1 : 0; }
|
||||
bool empty() { return Buf.Size <= 1; }
|
||||
void clear() { Buf.clear(); }
|
||||
void reserve(int capacity) { Buf.reserve(capacity); }
|
||||
const char* c_str() const { return Buf.Data ? Buf.Data : EmptyString; }
|
||||
IMGUI_API void append(const char* str, const char* str_end = NULL);
|
||||
IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2);
|
||||
IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2);
|
||||
};
|
||||
@ -1887,13 +1895,14 @@ struct ImDrawData
|
||||
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
|
||||
ImVec2 DisplayPos; // Upper-left position of the viewport to render (== upper-left of the orthogonal projection matrix to use)
|
||||
ImVec2 DisplaySize; // Size of the viewport to render (== io.DisplaySize for the main viewport) (DisplayPos + DisplaySize == lower-right of the orthogonal projection matrix to use)
|
||||
ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Based on io.DisplayFramebufferScale. Generally (1,1) on normal display, (2,2) on OSX with Retina display.
|
||||
|
||||
// Functions
|
||||
ImDrawData() { Valid = false; Clear(); }
|
||||
~ImDrawData() { Clear(); }
|
||||
void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = ImVec2(0.f, 0.f); } // The ImDrawList are owned by ImGuiContext!
|
||||
void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.f, 0.f); } // The ImDrawList are owned by ImGuiContext!
|
||||
IMGUI_API void DeIndexAllBuffers(); // Helper to convert all buffers from indexed to non-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
|
||||
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.
|
||||
IMGUI_API void ScaleClipRects(const ImVec2& fb_scale); // 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.
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1907,7 +1916,7 @@ struct ImFontConfig
|
||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
|
||||
int FontNo; // 0 // Index of font within TTF/OTF file
|
||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
|
||||
int OversampleH; // 3 // Rasterize at higher quality for sub-pixel positioning. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
||||
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
|
||||
bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
||||
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now.
|
||||
@ -1940,7 +1949,7 @@ struct ImFontGlyphRangesBuilder
|
||||
{
|
||||
ImVector<int> UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used)
|
||||
|
||||
ImFontGlyphRangesBuilder() { UsedChars.resize(0x10000 / 32); memset(UsedChars.Data, 0, 0x10000 / 32); }
|
||||
ImFontGlyphRangesBuilder() { UsedChars.resize(0x10000 / sizeof(int)); memset(UsedChars.Data, 0, 0x10000 / sizeof(int)); }
|
||||
bool GetBit(int n) const { int off = (n >> 5); int mask = 1 << (n & 31); return (UsedChars[off] & mask) != 0; } // Get bit n in the array
|
||||
void SetBit(int n) { int off = (n >> 5); int mask = 1 << (n & 31); UsedChars[off] |= mask; } // Set bit n in the array
|
||||
void AddChar(ImWchar c) { SetBit(c); } // Add character
|
||||
@ -2072,33 +2081,32 @@ struct ImFontAtlas
|
||||
// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32().
|
||||
struct ImFont
|
||||
{
|
||||
// Members: Hot ~62/78 bytes
|
||||
float FontSize; // <user set> // Height of characters, set during loading (don't change after loading)
|
||||
float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
|
||||
ImVec2 DisplayOffset; // = (0.f,0.f) // Offset font rendering by xx pixels
|
||||
ImVector<ImFontGlyph> Glyphs; // // All glyphs.
|
||||
ImVector<float> IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI).
|
||||
ImVector<ImWchar> IndexLookup; // // Sparse. Index glyphs by Unicode code-point.
|
||||
const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
|
||||
float FallbackAdvanceX; // == FallbackGlyph->AdvanceX
|
||||
ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
|
||||
// Members: Hot ~20/24 bytes (for CalcTextSize)
|
||||
ImVector<float> IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this this info, and are often bottleneck in large UI).
|
||||
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
|
||||
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
|
||||
|
||||
// Members: Cold ~18/26 bytes
|
||||
short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
|
||||
ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData
|
||||
ImFontAtlas* ContainerAtlas; // // What we has been loaded into
|
||||
float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
|
||||
bool DirtyLookupTables;
|
||||
int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
// Members: Hot ~36/48 bytes (for CalcTextSize + render loop)
|
||||
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
|
||||
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
|
||||
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
||||
ImVec2 DisplayOffset; // 8 // in // = (0,0) // Offset font rendering by xx pixels
|
||||
|
||||
// Members: Cold ~32/40 bytes
|
||||
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
|
||||
const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData
|
||||
short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
|
||||
ImWchar FallbackChar; // 2 // in // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar()
|
||||
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize]
|
||||
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
bool DirtyLookupTables; // 1 // out //
|
||||
|
||||
// Methods
|
||||
IMGUI_API ImFont();
|
||||
IMGUI_API ~ImFont();
|
||||
IMGUI_API void ClearOutputData();
|
||||
IMGUI_API void BuildLookupTable();
|
||||
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const;
|
||||
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const;
|
||||
IMGUI_API void SetFallbackChar(ImWchar c);
|
||||
float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
|
||||
bool IsLoaded() const { return ContainerAtlas != NULL; }
|
||||
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
|
||||
@ -2110,10 +2118,13 @@ struct ImFont
|
||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const;
|
||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const;
|
||||
|
||||
// [Internal]
|
||||
// [Internal] Don't use!
|
||||
IMGUI_API void BuildLookupTable();
|
||||
IMGUI_API void ClearOutputData();
|
||||
IMGUI_API void GrowIndex(int new_size);
|
||||
IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x);
|
||||
IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built.
|
||||
IMGUI_API void SetFallbackChar(ImWchar c);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
typedef ImFontGlyph Glyph; // OBSOLETE 1.52+
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.67
|
||||
// dear imgui, v1.68
|
||||
// (demo code)
|
||||
|
||||
// Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
|
||||
@ -62,7 +62,6 @@ Index of this file:
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
|
||||
@ -70,7 +69,10 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
|
||||
#pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal
|
||||
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning : warning: macro is not used // we define snprintf/vsnprintf on Windows so they are available, but not always used.
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
#endif
|
||||
#if __has_warning("-Wdouble-promotion")
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||
#endif
|
||||
@ -90,6 +92,8 @@ Index of this file:
|
||||
// Play it nice with Windows users. Notepad in 2017 still doesn't display text data with Unix-style \n.
|
||||
#ifdef _WIN32
|
||||
#define IM_NEWLINE "\r\n"
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#else
|
||||
#define IM_NEWLINE "\n"
|
||||
#endif
|
||||
@ -336,6 +340,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
|
||||
if (ImGui::TreeNode("Backend Flags"))
|
||||
{
|
||||
ShowHelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities.");
|
||||
ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying the back-end flags.
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
|
||||
@ -871,23 +876,44 @@ static void ShowDemoWindowWidgets()
|
||||
}
|
||||
if (ImGui::TreeNode("Grid"))
|
||||
{
|
||||
static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true };
|
||||
for (int i = 0; i < 16; i++)
|
||||
static bool selected[4*4] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true };
|
||||
for (int i = 0; i < 4*4; i++)
|
||||
{
|
||||
ImGui::PushID(i);
|
||||
if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50)))
|
||||
{
|
||||
int x = i % 4, y = i / 4;
|
||||
if (x > 0) selected[i - 1] ^= 1;
|
||||
if (x < 3) selected[i + 1] ^= 1;
|
||||
if (y > 0) selected[i - 4] ^= 1;
|
||||
if (y < 3) selected[i + 4] ^= 1;
|
||||
// Note: We _unnecessarily_ test for both x/y and i here only to silence some static analyzer. The second part of each test is unnecessary.
|
||||
int x = i % 4;
|
||||
int y = i / 4;
|
||||
if (x > 0) { selected[i - 1] ^= 1; }
|
||||
if (x < 3 && i < 15) { selected[i + 1] ^= 1; }
|
||||
if (y > 0 && i > 3) { selected[i - 4] ^= 1; }
|
||||
if (y < 3 && i < 12) { selected[i + 4] ^= 1; }
|
||||
}
|
||||
if ((i % 4) < 3) ImGui::SameLine();
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
if (ImGui::TreeNode("Alignment"))
|
||||
{
|
||||
ShowHelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar().");
|
||||
static bool selected[3*3] = { true, false, true, false, true, false, true, false, true };
|
||||
for (int y = 0; y < 3; y++)
|
||||
{
|
||||
for (int x = 0; x < 3; x++)
|
||||
{
|
||||
ImVec2 alignment = ImVec2((float)x / 2.0f, (float)y / 2.0f);
|
||||
char name[32];
|
||||
sprintf(name, "(%.1f,%.1f)", alignment.x, alignment.y);
|
||||
if (x > 0) ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, alignment);
|
||||
ImGui::Selectable(name, &selected[3*y+x], ImGuiSelectableFlags_None, ImVec2(80,80));
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
@ -947,7 +973,7 @@ static void ShowDemoWindowWidgets()
|
||||
static float values[90] = { 0 };
|
||||
static int values_offset = 0;
|
||||
static double refresh_time = 0.0;
|
||||
if (!animate || refresh_time == 0.0f)
|
||||
if (!animate || refresh_time == 0.0)
|
||||
refresh_time = ImGui::GetTime();
|
||||
while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo
|
||||
{
|
||||
@ -1000,7 +1026,7 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
if (ImGui::TreeNode("Color/Picker Widgets"))
|
||||
{
|
||||
static ImVec4 color = ImColor(114, 144, 154, 200);
|
||||
static ImVec4 color = ImVec4(114.0f/255.0f, 144.0f/255.0f, 154.0f/255.0f, 200.0f/255.0f);
|
||||
|
||||
static bool alpha_preview = true;
|
||||
static bool alpha_half_preview = false;
|
||||
@ -1030,16 +1056,18 @@ static void ShowDemoWindowWidgets()
|
||||
|
||||
ImGui::Text("Color button with Custom Picker Popup:");
|
||||
|
||||
// Generate a dummy palette
|
||||
static bool saved_palette_inited = false;
|
||||
static ImVec4 saved_palette[32];
|
||||
if (!saved_palette_inited)
|
||||
// Generate a dummy default palette. The palette will persist and can be edited.
|
||||
static bool saved_palette_init = true;
|
||||
static ImVec4 saved_palette[32] = { };
|
||||
if (saved_palette_init)
|
||||
{
|
||||
for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++)
|
||||
{
|
||||
ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z);
|
||||
saved_palette[n].w = 1.0f; // Alpha
|
||||
}
|
||||
saved_palette_inited = true;
|
||||
saved_palette_init = false;
|
||||
}
|
||||
|
||||
static ImVec4 backup_color;
|
||||
bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags);
|
||||
@ -1052,12 +1080,12 @@ static void ShowDemoWindowWidgets()
|
||||
}
|
||||
if (ImGui::BeginPopup("mypicker"))
|
||||
{
|
||||
// FIXME: Adding a drag and drop example here would be perfect!
|
||||
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
|
||||
ImGui::Separator();
|
||||
ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
ImGui::Text("Current");
|
||||
ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40));
|
||||
ImGui::Text("Previous");
|
||||
@ -1073,6 +1101,8 @@ static void ShowDemoWindowWidgets()
|
||||
if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20)))
|
||||
color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha!
|
||||
|
||||
// Allow user to drop colors into each palette entry
|
||||
// (Note that ColorButton is already a drag source by default, unless using ImGuiColorEditFlags_NoDragDrop)
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
@ -1411,7 +1441,7 @@ static void ShowDemoWindowWidgets()
|
||||
static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
|
||||
ImGui::RadioButton("Text", &item_type, 0);
|
||||
ImGui::RadioButton("Button", &item_type, 1);
|
||||
ImGui::RadioButton("CheckBox", &item_type, 2);
|
||||
ImGui::RadioButton("Checkbox", &item_type, 2);
|
||||
ImGui::RadioButton("SliderFloat", &item_type, 3);
|
||||
ImGui::RadioButton("ColorEdit4", &item_type, 4);
|
||||
ImGui::RadioButton("ListBox", &item_type, 5);
|
||||
@ -1419,7 +1449,7 @@ static void ShowDemoWindowWidgets()
|
||||
bool ret = false;
|
||||
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
|
||||
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
|
||||
if (item_type == 2) { ret = ImGui::Checkbox("ITEM: CheckBox", &b); } // Testing checkbox
|
||||
if (item_type == 2) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox
|
||||
if (item_type == 3) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item
|
||||
if (item_type == 4) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged)
|
||||
if (item_type == 5) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", ¤t, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
|
||||
@ -1433,6 +1463,7 @@ static void ShowDemoWindowWidgets()
|
||||
"IsItemHovered(_RectOnly) = %d\n"
|
||||
"IsItemActive() = %d\n"
|
||||
"IsItemEdited() = %d\n"
|
||||
"IsItemActivated() = %d\n"
|
||||
"IsItemDeactivated() = %d\n"
|
||||
"IsItemDeactivatedEdit() = %d\n"
|
||||
"IsItemVisible() = %d\n"
|
||||
@ -1448,6 +1479,7 @@ static void ShowDemoWindowWidgets()
|
||||
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
|
||||
ImGui::IsItemActive(),
|
||||
ImGui::IsItemEdited(),
|
||||
ImGui::IsItemActivated(),
|
||||
ImGui::IsItemDeactivated(),
|
||||
ImGui::IsItemDeactivatedAfterEdit(),
|
||||
ImGui::IsItemVisible(),
|
||||
@ -1765,6 +1797,7 @@ static void ShowDemoWindowLayout()
|
||||
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable;
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_Reorderable", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_Reorderable);
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_AutoSelectNewTabs", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_AutoSelectNewTabs);
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", (unsigned int*)&tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
|
||||
if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
|
||||
tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
|
||||
@ -1975,9 +2008,9 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleVar(2);
|
||||
float scroll_x_delta = 0.0f;
|
||||
ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine();
|
||||
ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) { scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; } ImGui::SameLine();
|
||||
ImGui::Text("Scroll from code"); ImGui::SameLine();
|
||||
ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine();
|
||||
ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) { scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; } ImGui::SameLine();
|
||||
ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x);
|
||||
if (scroll_x_delta != 0.0f)
|
||||
{
|
||||
@ -2167,13 +2200,24 @@ static void ShowDemoWindowPopups()
|
||||
|
||||
if (ImGui::Button("Stacked modals.."))
|
||||
ImGui::OpenPopup("Stacked 1");
|
||||
if (ImGui::BeginPopupModal("Stacked 1"))
|
||||
if (ImGui::BeginPopupModal("Stacked 1", NULL, ImGuiWindowFlags_MenuBar))
|
||||
{
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
{
|
||||
if (ImGui::MenuItem("Dummy menu item")) {}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDimBg] behind it.");
|
||||
|
||||
// Testing behavior of widgets stacking their own regular popups over the modal.
|
||||
static int item = 1;
|
||||
ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
|
||||
static float color[4] = { 0.4f,0.7f,0.0f,0.5f };
|
||||
ImGui::ColorEdit4("color", color); // This is to test behavior of stacked regular popups over a modal
|
||||
ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0");
|
||||
ImGui::ColorEdit4("color", color);
|
||||
|
||||
if (ImGui::Button("Add another modal.."))
|
||||
ImGui::OpenPopup("Stacked 2");
|
||||
@ -2505,9 +2549,9 @@ static void ShowDemoWindowMisc()
|
||||
// Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item
|
||||
static float f3[3] = { 0.0f, 0.0f, 0.0f };
|
||||
int focus_ahead = -1;
|
||||
if (ImGui::Button("Focus on X")) focus_ahead = 0; ImGui::SameLine();
|
||||
if (ImGui::Button("Focus on Y")) focus_ahead = 1; ImGui::SameLine();
|
||||
if (ImGui::Button("Focus on Z")) focus_ahead = 2;
|
||||
if (ImGui::Button("Focus on X")) { focus_ahead = 0; } ImGui::SameLine();
|
||||
if (ImGui::Button("Focus on Y")) { focus_ahead = 1; } ImGui::SameLine();
|
||||
if (ImGui::Button("Focus on Z")) { focus_ahead = 2; }
|
||||
if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead);
|
||||
ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f);
|
||||
|
||||
@ -2667,6 +2711,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::Separator();
|
||||
ImGui::Text("io.Fonts: %d fonts, Flags: 0x%08X, TexSize: %d,%d", io.Fonts->Fonts.Size, io.Fonts->Flags, io.Fonts->TexWidth, io.Fonts->TexHeight);
|
||||
ImGui::Text("io.DisplaySize: %.2f,%.2f", io.DisplaySize.x, io.DisplaySize.y);
|
||||
ImGui::Text("io.DisplayFramebufferScale: %.2f,%.2f", io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("style.WindowPadding: %.2f,%.2f", style.WindowPadding.x, style.WindowPadding.y);
|
||||
ImGui::Text("style.WindowBorderSize: %.2f", style.WindowBorderSize);
|
||||
@ -2714,8 +2759,13 @@ void ImGui::ShowFontSelector(const char* label)
|
||||
if (ImGui::BeginCombo(label, font_current->GetDebugName()))
|
||||
{
|
||||
for (int n = 0; n < io.Fonts->Fonts.Size; n++)
|
||||
if (ImGui::Selectable(io.Fonts->Fonts[n]->GetDebugName(), io.Fonts->Fonts[n] == font_current))
|
||||
io.FontDefault = io.Fonts->Fonts[n];
|
||||
{
|
||||
ImFont* font = io.Fonts->Fonts[n];
|
||||
ImGui::PushID((void*)font);
|
||||
if (ImGui::Selectable(font->GetDebugName(), font == font_current))
|
||||
io.FontDefault = font;
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
@ -2772,7 +2822,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
{
|
||||
ImGui::Text("Main");
|
||||
ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
|
||||
ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f");
|
||||
ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
|
||||
ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f");
|
||||
ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
|
||||
@ -2787,15 +2836,17 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
ImGui::Text("Rounding");
|
||||
ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 14.0f, "%.0f");
|
||||
ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f");
|
||||
ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
|
||||
ImGui::Text("Alignment");
|
||||
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
|
||||
ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content.");
|
||||
ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a selectable is larger than its text content.");
|
||||
ImGui::Text("Safe Area Padding"); ImGui::SameLine(); ShowHelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
|
||||
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
|
||||
ImGui::EndTabItem();
|
||||
@ -2861,7 +2912,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
|
||||
if (ImGui::BeginTabItem("Fonts"))
|
||||
{
|
||||
ImFontAtlas* atlas = ImGui::GetIO().Fonts;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImFontAtlas* atlas = io.Fonts;
|
||||
ShowHelpMarker("Read FAQ and misc/fonts/README.txt for details on font loading.");
|
||||
ImGui::PushItemWidth(120);
|
||||
for (int i = 0; i < atlas->Fonts.Size; i++)
|
||||
@ -2869,7 +2921,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImFont* font = atlas->Fonts[i];
|
||||
ImGui::PushID(font);
|
||||
bool font_details_opened = ImGui::TreeNode(font, "Font %d: \"%s\"\n%.2f px, %d glyphs, %d file(s)", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
|
||||
ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font;
|
||||
ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) { io.FontDefault = font; }
|
||||
if (font_details_opened)
|
||||
{
|
||||
ImGui::PushFont(font);
|
||||
@ -2880,9 +2932,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f");
|
||||
ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
|
||||
ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar);
|
||||
ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((float)font->MetricsTotalSurface), (int)sqrtf((float)font->MetricsTotalSurface));
|
||||
const float surface_sqrt = sqrtf((float)font->MetricsTotalSurface);
|
||||
ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)surface_sqrt, (int)surface_sqrt);
|
||||
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
|
||||
if (ImFontConfig* cfg = &font->ConfigData[config_i])
|
||||
if (const ImFontConfig* cfg = &font->ConfigData[config_i])
|
||||
ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
|
||||
if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
|
||||
{
|
||||
@ -2934,9 +2987,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
}
|
||||
|
||||
static float window_scale = 1.0f;
|
||||
if (ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f")) // scale only this window
|
||||
if (ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.2f")) // scale only this window
|
||||
ImGui::SetWindowFontScale(window_scale);
|
||||
ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything
|
||||
ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.2f"); // scale everything
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::EndTabItem();
|
||||
@ -3064,10 +3117,12 @@ struct ExampleAppConsole
|
||||
{
|
||||
char InputBuf[256];
|
||||
ImVector<char*> Items;
|
||||
bool ScrollToBottom;
|
||||
ImVector<const char*> Commands;
|
||||
ImVector<char*> History;
|
||||
int HistoryPos; // -1: new line, 0..History.Size-1 browsing history.
|
||||
ImVector<const char*> Commands;
|
||||
ImGuiTextFilter Filter;
|
||||
bool AutoScroll;
|
||||
bool ScrollToBottom;
|
||||
|
||||
ExampleAppConsole()
|
||||
{
|
||||
@ -3078,6 +3133,8 @@ struct ExampleAppConsole
|
||||
Commands.push_back("HISTORY");
|
||||
Commands.push_back("CLEAR");
|
||||
Commands.push_back("CLASSIFY"); // "classify" is only here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
|
||||
AutoScroll = true;
|
||||
ScrollToBottom = true;
|
||||
AddLog("Welcome to Dear ImGui!");
|
||||
}
|
||||
~ExampleAppConsole()
|
||||
@ -3090,7 +3147,7 @@ struct ExampleAppConsole
|
||||
// Portable helpers
|
||||
static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; }
|
||||
static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; }
|
||||
static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); }
|
||||
static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)str, len); }
|
||||
static void Strtrim(char* str) { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; }
|
||||
|
||||
void ClearLog()
|
||||
@ -3111,6 +3168,7 @@ struct ExampleAppConsole
|
||||
buf[IM_ARRAYSIZE(buf)-1] = 0;
|
||||
va_end(args);
|
||||
Items.push_back(Strdup(buf));
|
||||
if (AutoScroll)
|
||||
ScrollToBottom = true;
|
||||
}
|
||||
|
||||
@ -3146,10 +3204,20 @@ struct ExampleAppConsole
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
|
||||
static ImGuiTextFilter filter;
|
||||
filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
|
||||
ImGui::PopStyleVar();
|
||||
// Options menu
|
||||
if (ImGui::BeginPopup("Options"))
|
||||
{
|
||||
if (ImGui::Checkbox("Auto-scroll", &AutoScroll))
|
||||
if (AutoScroll)
|
||||
ScrollToBottom = true;
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Options, Filter
|
||||
if (ImGui::Button("Options"))
|
||||
ImGui::OpenPopup("Options");
|
||||
ImGui::SameLine();
|
||||
Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
|
||||
ImGui::Separator();
|
||||
|
||||
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); // 1 separator, 1 input text
|
||||
@ -3174,17 +3242,18 @@ struct ExampleAppConsole
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing
|
||||
if (copy_to_clipboard)
|
||||
ImGui::LogToClipboard();
|
||||
ImVec4 col_default_text = ImGui::GetStyleColorVec4(ImGuiCol_Text);
|
||||
for (int i = 0; i < Items.Size; i++)
|
||||
{
|
||||
const char* item = Items[i];
|
||||
if (!filter.PassFilter(item))
|
||||
if (!Filter.PassFilter(item))
|
||||
continue;
|
||||
ImVec4 col = col_default_text;
|
||||
if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f);
|
||||
else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, col);
|
||||
|
||||
// Normally you would store more information in your item (e.g. make Items[] an array of structure, store color/type etc.)
|
||||
bool pop_color = false;
|
||||
if (strstr(item, "[error]")) { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.4f, 0.4f, 1.0f)); pop_color = true; }
|
||||
else if (strncmp(item, "# ", 2) == 0) { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.8f, 0.6f, 1.0f)); pop_color = true; }
|
||||
ImGui::TextUnformatted(item);
|
||||
if (pop_color)
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (copy_to_clipboard)
|
||||
@ -3252,6 +3321,9 @@ struct ExampleAppConsole
|
||||
{
|
||||
AddLog("Unknown command: '%s'\n", command_line);
|
||||
}
|
||||
|
||||
// On commad input, we scroll to bottom even if AutoScroll==false
|
||||
ScrollToBottom = true;
|
||||
}
|
||||
|
||||
static int TextEditCallbackStub(ImGuiInputTextCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks
|
||||
@ -3380,8 +3452,16 @@ struct ExampleAppLog
|
||||
ImGuiTextBuffer Buf;
|
||||
ImGuiTextFilter Filter;
|
||||
ImVector<int> LineOffsets; // Index to lines offset. We maintain this with AddLog() calls, allowing us to have a random access on lines
|
||||
bool AutoScroll;
|
||||
bool ScrollToBottom;
|
||||
|
||||
ExampleAppLog()
|
||||
{
|
||||
AutoScroll = true;
|
||||
ScrollToBottom = false;
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
Buf.clear();
|
||||
@ -3399,6 +3479,7 @@ struct ExampleAppLog
|
||||
for (int new_size = Buf.size(); old_size < new_size; old_size++)
|
||||
if (Buf[old_size] == '\n')
|
||||
LineOffsets.push_back(old_size + 1);
|
||||
if (AutoScroll)
|
||||
ScrollToBottom = true;
|
||||
}
|
||||
|
||||
@ -3409,13 +3490,31 @@ struct ExampleAppLog
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
if (ImGui::Button("Clear")) Clear();
|
||||
|
||||
// Options menu
|
||||
if (ImGui::BeginPopup("Options"))
|
||||
{
|
||||
if (ImGui::Checkbox("Auto-scroll", &AutoScroll))
|
||||
if (AutoScroll)
|
||||
ScrollToBottom = true;
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Main window
|
||||
if (ImGui::Button("Options"))
|
||||
ImGui::OpenPopup("Options");
|
||||
ImGui::SameLine();
|
||||
bool clear = ImGui::Button("Clear");
|
||||
ImGui::SameLine();
|
||||
bool copy = ImGui::Button("Copy");
|
||||
ImGui::SameLine();
|
||||
Filter.Draw("Filter", -100.0f);
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::BeginChild("scrolling", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
if (clear)
|
||||
Clear();
|
||||
if (copy)
|
||||
ImGui::LogToClipboard();
|
||||
|
||||
@ -3424,6 +3523,10 @@ struct ExampleAppLog
|
||||
const char* buf_end = Buf.end();
|
||||
if (Filter.IsActive())
|
||||
{
|
||||
// In this example we don't use the clipper when Filter is enabled.
|
||||
// This is because we don't have a random access on the result on our filter.
|
||||
// A real application processing logs with ten of thousands of entries may want to store the result of search/filter.
|
||||
// especially if the filtering function is not trivial (e.g. reg-exp).
|
||||
for (int line_no = 0; line_no < LineOffsets.Size; line_no++)
|
||||
{
|
||||
const char* line_start = buf + LineOffsets[line_no];
|
||||
@ -3471,11 +3574,12 @@ static void ShowExampleAppLog(bool* p_open)
|
||||
{
|
||||
static ExampleAppLog log;
|
||||
|
||||
// For the demo: add a debug button before the normal log window contents
|
||||
// For the demo: add a debug button _BEFORE_ the normal log window contents
|
||||
// We take advantage of the fact that multiple calls to Begin()/End() are appending to the same window.
|
||||
// Most of the contents of the window will be added by the log.Draw() call.
|
||||
ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver);
|
||||
ImGui::Begin("Example: Log", p_open);
|
||||
if (ImGui::SmallButton("Add 5 entries"))
|
||||
if (ImGui::SmallButton("[Debug] Add 5 entries"))
|
||||
{
|
||||
static int counter = 0;
|
||||
for (int n = 0; n < 5; n++)
|
||||
@ -3727,7 +3831,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
|
||||
if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500
|
||||
if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500
|
||||
if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square
|
||||
if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step
|
||||
if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)(intptr_t)100); // Fixed Step
|
||||
|
||||
ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0;
|
||||
if (ImGui::Begin("Example: Constrained Resize", p_open, flags))
|
||||
@ -3765,17 +3869,20 @@ static void ShowExampleAppSimpleOverlay(bool* p_open)
|
||||
{
|
||||
const float DISTANCE = 10.0f;
|
||||
static int corner = 0;
|
||||
ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE);
|
||||
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (corner != -1)
|
||||
{
|
||||
ImVec2 window_pos = ImVec2((corner & 1) ? io.DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? io.DisplaySize.y - DISTANCE : DISTANCE);
|
||||
ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f);
|
||||
ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot);
|
||||
}
|
||||
ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background
|
||||
if (ImGui::Begin("Example: Simple overlay", p_open, (corner != -1 ? ImGuiWindowFlags_NoMove : 0) | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
|
||||
{
|
||||
ImGui::Text("Simple overlay\n" "in the corner of the screen.\n" "(right-click to change position)");
|
||||
ImGui::Separator();
|
||||
if (ImGui::IsMousePosValid())
|
||||
ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y);
|
||||
ImGui::Text("Mouse Position: (%.1f,%.1f)", io.MousePos.x, io.MousePos.y);
|
||||
else
|
||||
ImGui::Text("Mouse Position: <invalid>");
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
@ -3850,27 +3957,30 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
|
||||
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
|
||||
ImGui::ColorEdit3("Color", &col.x);
|
||||
ImGui::ColorEdit4("Color", &col.x);
|
||||
{
|
||||
const ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
const ImU32 col32 = ImColor(col);
|
||||
float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
|
||||
for (int n = 0; n < 2; n++)
|
||||
{
|
||||
float curr_thickness = (n == 0) ? 1.0f : thickness;
|
||||
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, curr_thickness); x += sz+spacing;
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, curr_thickness); x += sz+spacing;
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, curr_thickness); x += sz+spacing;
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, curr_thickness); x += sz+spacing;
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, curr_thickness); x += sz+spacing;
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, curr_thickness); x += sz+spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, curr_thickness); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, curr_thickness); x += sz+spacing; // Diagonal line
|
||||
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, curr_thickness);
|
||||
// First line uses a thickness of 1.0, second line uses the configurable thickness
|
||||
float th = (n == 0) ? 1.0f : thickness;
|
||||
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6, th); x += sz+spacing; // Hexagon
|
||||
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, th); x += sz+spacing; // Circle
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, th); x += sz+spacing;
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, th); x += sz+spacing;
|
||||
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, th); x += sz+spacing;
|
||||
draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, th); x += sz+spacing;
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, th); x += sz+spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
|
||||
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, th); x += sz+spacing; // Diagonal line
|
||||
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, th);
|
||||
x = p.x + 4;
|
||||
y += sz+spacing;
|
||||
}
|
||||
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing;
|
||||
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6); x += sz+spacing; // Hexagon
|
||||
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; // Circle
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing;
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing;
|
||||
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.67
|
||||
// dear imgui, v1.68
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@ -57,7 +57,9 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
|
||||
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
#endif
|
||||
#if __has_warning("-Wcomma")
|
||||
#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here //
|
||||
#endif
|
||||
@ -687,7 +689,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||
PrimReserve(idx_count, vtx_count);
|
||||
|
||||
// Temporary buffer
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2));
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); //-V630
|
||||
ImVec2* temp_points = temp_normals + points_count;
|
||||
|
||||
for (int i1 = 0; i1 < count; i1++)
|
||||
@ -878,7 +880,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
||||
}
|
||||
|
||||
// Compute normals
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2));
|
||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630
|
||||
for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++)
|
||||
{
|
||||
const ImVec2& p0 = points[i0];
|
||||
@ -955,6 +957,9 @@ void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float a_min, floa
|
||||
_Path.push_back(centre);
|
||||
return;
|
||||
}
|
||||
|
||||
// Note that we are adding a point at both a_min and a_max.
|
||||
// If you are trying to draw a full closed circle you don't want the overlapping points!
|
||||
_Path.reserve(_Path.Size + (num_segments + 1));
|
||||
for (int i = 0; i <= num_segments; i++)
|
||||
{
|
||||
@ -1138,21 +1143,23 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec
|
||||
|
||||
void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2)
|
||||
return;
|
||||
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments);
|
||||
PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments - 1);
|
||||
PathStroke(col, true, thickness);
|
||||
}
|
||||
|
||||
void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments)
|
||||
{
|
||||
if ((col & IM_COL32_A_MASK) == 0)
|
||||
if ((col & IM_COL32_A_MASK) == 0 || num_segments <= 2)
|
||||
return;
|
||||
|
||||
// Because we are filling a closed shape we remove 1 from the count of segments/points
|
||||
const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
|
||||
PathArcTo(centre, radius, 0.0f, a_max, num_segments);
|
||||
PathArcTo(centre, radius, 0.0f, a_max, num_segments - 1);
|
||||
PathFillConvex(col);
|
||||
}
|
||||
|
||||
@ -1280,8 +1287,10 @@ void ImDrawData::DeIndexAllBuffers()
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
void ImDrawData::ScaleClipRects(const ImVec2& scale)
|
||||
// Helper to scale the ClipRect field of each ImDrawCmd.
|
||||
// Use if your final output buffer is at a different scale than draw_data->DisplaySize,
|
||||
// or if there is a difference between your window resolution and framebuffer resolution.
|
||||
void ImDrawData::ScaleClipRects(const ImVec2& fb_scale)
|
||||
{
|
||||
for (int i = 0; i < CmdListsCount; i++)
|
||||
{
|
||||
@ -1289,7 +1298,7 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale)
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
cmd->ClipRect = ImVec4(cmd->ClipRect.x * scale.x, cmd->ClipRect.y * scale.y, cmd->ClipRect.z * scale.x, cmd->ClipRect.w * scale.y);
|
||||
cmd->ClipRect = ImVec4(cmd->ClipRect.x * fb_scale.x, cmd->ClipRect.y * fb_scale.y, cmd->ClipRect.z * fb_scale.x, cmd->ClipRect.w * fb_scale.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1352,7 +1361,7 @@ ImFontConfig::ImFontConfig()
|
||||
FontDataOwnedByAtlas = true;
|
||||
FontNo = 0;
|
||||
SizePixels = 0.0f;
|
||||
OversampleH = 3;
|
||||
OversampleH = 3; // FIXME: 2 may be a better default?
|
||||
OversampleV = 1;
|
||||
PixelSnapH = false;
|
||||
GlyphExtraSpacing = ImVec2(0.0f, 0.0f);
|
||||
@ -1518,7 +1527,7 @@ void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid
|
||||
GetTexDataAsAlpha8(&pixels, NULL, NULL);
|
||||
if (pixels)
|
||||
{
|
||||
TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4));
|
||||
TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)TexWidth * (size_t)TexHeight * 4);
|
||||
const unsigned char* src = pixels;
|
||||
unsigned int* dst = TexPixelsRGBA32;
|
||||
for (int n = TexWidth * TexHeight; n > 0; n--)
|
||||
@ -1585,8 +1594,10 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
font_cfg.OversampleH = font_cfg.OversampleV = 1;
|
||||
font_cfg.PixelSnapH = true;
|
||||
}
|
||||
if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px");
|
||||
if (font_cfg.SizePixels <= 0.0f) font_cfg.SizePixels = 13.0f;
|
||||
if (font_cfg.SizePixels <= 0.0f)
|
||||
font_cfg.SizePixels = 13.0f * 1.0f;
|
||||
if (font_cfg.Name[0] == '\0')
|
||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
|
||||
|
||||
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
|
||||
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
|
||||
@ -1829,15 +1840,14 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
{
|
||||
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
||||
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
|
||||
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty())
|
||||
if (dst_tmp.GlyphsSet.Storage.empty())
|
||||
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
|
||||
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
|
||||
{
|
||||
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option for MergeMode (e.g. MergeOverwrite==true)
|
||||
continue;
|
||||
if (!stbtt_FindGlyphIndex(&src_tmp.FontInfo, codepoint)) // It is actually in the font?
|
||||
continue;
|
||||
@ -1846,7 +1856,6 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||
src_tmp.GlyphsCount++;
|
||||
dst_tmp.GlyphsCount++;
|
||||
src_tmp.GlyphsSet.SetBit(codepoint, true);
|
||||
if (dst_tmp.SrcCount > 1)
|
||||
dst_tmp.GlyphsSet.SetBit(codepoint, true);
|
||||
total_glyphs_count++;
|
||||
}
|
||||
@ -2056,6 +2065,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
|
||||
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
|
||||
{
|
||||
stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque;
|
||||
IM_ASSERT(pack_context != NULL);
|
||||
|
||||
ImVector<ImFontAtlas::CustomRect>& user_rects = atlas->CustomRects;
|
||||
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
|
||||
@ -2162,7 +2172,8 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseFull()
|
||||
static const ImWchar ranges[] =
|
||||
{
|
||||
0x0020, 0x00FF, // Basic Latin + Latin Supplement
|
||||
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana
|
||||
0x2000, 0x206F, // General Punctuation
|
||||
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
|
||||
0x31F0, 0x31FF, // Katakana Phonetic Extensions
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0x4e00, 0x9FAF, // CJK Ideograms
|
||||
@ -2238,9 +2249,10 @@ const ImWchar* ImFontAtlas::GetGlyphRangesChineseSimplifiedCommon()
|
||||
static ImWchar base_ranges[] = // not zero-terminated
|
||||
{
|
||||
0x0020, 0x00FF, // Basic Latin + Latin Supplement
|
||||
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana
|
||||
0x2000, 0x206F, // General Punctuation
|
||||
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
|
||||
0x31F0, 0x31FF, // Katakana Phonetic Extensions
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFF00, 0xFFEF // Half-width characters
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00) * 2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
@ -2296,9 +2308,9 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
|
||||
static ImWchar base_ranges[] = // not zero-terminated
|
||||
{
|
||||
0x0020, 0x00FF, // Basic Latin + Latin Supplement
|
||||
0x3000, 0x30FF, // Punctuations, Hiragana, Katakana
|
||||
0x3000, 0x30FF, // CJK Symbols and Punctuations, Hiragana, Katakana
|
||||
0x31F0, 0x31FF, // Katakana Phonetic Extensions
|
||||
0xFF00, 0xFFEF, // Half-width characters
|
||||
0xFF00, 0xFFEF // Half-width characters
|
||||
};
|
||||
static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(accumulative_offsets_from_0x4E00)*2 + 1] = { 0 };
|
||||
if (!full_ranges[0])
|
||||
@ -2378,38 +2390,36 @@ void ImFontGlyphRangesBuilder::BuildRanges(ImVector<ImWchar>* out_ranges)
|
||||
|
||||
ImFont::ImFont()
|
||||
{
|
||||
Scale = 1.0f;
|
||||
FontSize = 0.0f;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
FallbackChar = (ImWchar)'?';
|
||||
DisplayOffset = ImVec2(0.0f, 0.0f);
|
||||
ClearOutputData();
|
||||
FallbackGlyph = NULL;
|
||||
ContainerAtlas = NULL;
|
||||
ConfigData = NULL;
|
||||
ConfigDataCount = 0;
|
||||
DirtyLookupTables = false;
|
||||
Scale = 1.0f;
|
||||
Ascent = Descent = 0.0f;
|
||||
MetricsTotalSurface = 0;
|
||||
}
|
||||
|
||||
ImFont::~ImFont()
|
||||
{
|
||||
// Invalidate active font so that the user gets a clear crash instead of a dangling pointer.
|
||||
// If you want to delete fonts you need to do it between Render() and NewFrame().
|
||||
// FIXME-CLEANUP
|
||||
/*
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.Font == this)
|
||||
g.Font = NULL;
|
||||
*/
|
||||
ClearOutputData();
|
||||
}
|
||||
|
||||
void ImFont::ClearOutputData()
|
||||
{
|
||||
FontSize = 0.0f;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
Glyphs.clear();
|
||||
IndexAdvanceX.clear();
|
||||
IndexLookup.clear();
|
||||
FallbackGlyph = NULL;
|
||||
FallbackAdvanceX = 0.0f;
|
||||
ConfigDataCount = 0;
|
||||
ConfigData = NULL;
|
||||
ContainerAtlas = NULL;
|
||||
Ascent = Descent = 0.0f;
|
||||
DirtyLookupTables = true;
|
||||
Ascent = Descent = 0.0f;
|
||||
MetricsTotalSurface = 0;
|
||||
}
|
||||
|
||||
@ -2999,13 +3009,14 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
const float inv_rounding = 1.0f / rounding;
|
||||
const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding);
|
||||
const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding);
|
||||
const float half_pi = IM_PI * 0.5f; // We will == compare to this because we know this is the exact value ImAcos01 can return.
|
||||
const float x0 = ImMax(p0.x, rect.Min.x + rounding);
|
||||
if (arc0_b == arc0_e)
|
||||
{
|
||||
draw_list->PathLineTo(ImVec2(x0, p1.y));
|
||||
draw_list->PathLineTo(ImVec2(x0, p0.y));
|
||||
}
|
||||
else if (arc0_b == 0.0f && arc0_e == IM_PI*0.5f)
|
||||
else if (arc0_b == 0.0f && arc0_e == half_pi)
|
||||
{
|
||||
draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL
|
||||
draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR
|
||||
@ -3025,7 +3036,7 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
draw_list->PathLineTo(ImVec2(x1, p0.y));
|
||||
draw_list->PathLineTo(ImVec2(x1, p1.y));
|
||||
}
|
||||
else if (arc1_b == 0.0f && arc1_e == IM_PI*0.5f)
|
||||
else if (arc1_b == 0.0f && arc1_e == half_pi)
|
||||
{
|
||||
draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR
|
||||
draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR
|
||||
@ -3045,7 +3056,8 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im
|
||||
void ImGui::RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col)
|
||||
{
|
||||
ImFont* font = draw_list->_Data->Font;
|
||||
pos.y += (float)(int)(font->DisplayOffset.y + font->Ascent + 0.5f - 1.0f);
|
||||
const float font_scale = draw_list->_Data->FontSize / font->FontSize;
|
||||
pos.y += (float)(int)(font->DisplayOffset.y + font->Ascent * font_scale + 0.5f - 1.0f);
|
||||
for (int dot_n = 0; dot_n < count; dot_n++)
|
||||
draw_list->AddRectFilled(ImVec2(pos.x + dot_n * 2.0f, pos.y), ImVec2(pos.x + dot_n * 2.0f + 1.0f, pos.y + 1.0f), col);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.67
|
||||
// dear imgui, v1.68
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
|
||||
@ -46,7 +46,9 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast"
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
#if __has_warning("-Wdouble-promotion")
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion"
|
||||
#endif
|
||||
@ -124,6 +126,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
|
||||
#else
|
||||
#define IM_NEWLINE "\n"
|
||||
#endif
|
||||
|
||||
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
|
||||
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
|
||||
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
||||
@ -145,7 +148,8 @@ IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const
|
||||
IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8
|
||||
|
||||
// Helpers: Misc
|
||||
IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings
|
||||
IMGUI_API ImU32 ImHashData(const void* data, size_t data_size, ImU32 seed = 0);
|
||||
IMGUI_API ImU32 ImHashStr(const char* data, size_t data_size, ImU32 seed = 0);
|
||||
IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size = NULL, int padding_bytes = 0);
|
||||
IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode);
|
||||
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
@ -153,6 +157,9 @@ static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c =
|
||||
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
#define ImQsort qsort
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
static inline ImU32 ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68]
|
||||
#endif
|
||||
|
||||
// Helpers: Geometry
|
||||
IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p);
|
||||
@ -177,7 +184,7 @@ IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* f
|
||||
IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
|
||||
IMGUI_API const char* ImParseFormatFindStart(const char* format);
|
||||
IMGUI_API const char* ImParseFormatFindEnd(const char* format);
|
||||
IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, int buf_size);
|
||||
IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size);
|
||||
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
|
||||
|
||||
// Helpers: ImVec2/ImVec4 operators
|
||||
@ -280,14 +287,6 @@ struct IMGUI_API ImPool
|
||||
// Misc data structures
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
|
||||
struct ImVec1
|
||||
{
|
||||
float x;
|
||||
ImVec1() { x = 0.0f; }
|
||||
ImVec1(float _x) { x = _x; }
|
||||
};
|
||||
|
||||
enum ImGuiButtonFlags_
|
||||
{
|
||||
ImGuiButtonFlags_None = 0,
|
||||
@ -346,6 +345,19 @@ enum ImGuiSeparatorFlags_
|
||||
ImGuiSeparatorFlags_Vertical = 1 << 1
|
||||
};
|
||||
|
||||
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
|
||||
// This is going to be exposed in imgui.h when stabilized enough.
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_NoTabStop = 1 << 0, // false
|
||||
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
|
||||
ImGuiItemFlags_Disabled = 1 << 2, // false // [BETA] Disable interactions but doesn't affect visuals yet. See github.com/ocornut/imgui/issues/211
|
||||
ImGuiItemFlags_NoNav = 1 << 3, // false
|
||||
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
|
||||
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
|
||||
ImGuiItemFlags_Default_ = 0
|
||||
};
|
||||
|
||||
// Storage for LastItem data
|
||||
enum ImGuiItemStatusFlags_
|
||||
{
|
||||
@ -411,7 +423,7 @@ enum ImGuiNavHighlightFlags_
|
||||
ImGuiNavHighlightFlags_None = 0,
|
||||
ImGuiNavHighlightFlags_TypeDefault = 1 << 0,
|
||||
ImGuiNavHighlightFlags_TypeThin = 1 << 1,
|
||||
ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2,
|
||||
ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse.
|
||||
ImGuiNavHighlightFlags_NoRounding = 1 << 3
|
||||
};
|
||||
|
||||
@ -454,6 +466,15 @@ enum ImGuiPopupPositionPolicy
|
||||
ImGuiPopupPositionPolicy_ComboBox
|
||||
};
|
||||
|
||||
// 1D vector (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
|
||||
struct ImVec1
|
||||
{
|
||||
float x;
|
||||
ImVec1() { x = 0.0f; }
|
||||
ImVec1(float _x) { x = _x; }
|
||||
};
|
||||
|
||||
|
||||
// 2D axis aligned bounding-box
|
||||
// NB: we can't rely on ImVec2 math operators being available here
|
||||
struct IMGUI_API ImRect
|
||||
@ -561,7 +582,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); }
|
||||
bool HasSelection() const { return StbState.select_start != StbState.select_end; }
|
||||
void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; }
|
||||
void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = false; }
|
||||
void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = 0; }
|
||||
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
|
||||
};
|
||||
|
||||
@ -580,7 +601,7 @@ struct ImGuiWindowSettings
|
||||
struct ImGuiSettingsHandler
|
||||
{
|
||||
const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']'
|
||||
ImGuiID TypeHash; // == ImHash(TypeName, 0, 0)
|
||||
ImGuiID TypeHash; // == ImHashStr(TypeName, 0, 0)
|
||||
void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); // Read: Called when entering into a new ini entry e.g. "[Window][Name]"
|
||||
void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry
|
||||
void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf'
|
||||
@ -670,6 +691,7 @@ struct ImDrawDataBuilder
|
||||
struct ImGuiNavMoveResult
|
||||
{
|
||||
ImGuiID ID; // Best candidate
|
||||
ImGuiID SelectScopeId;// Best candidate window current selectable group ID
|
||||
ImGuiWindow* Window; // Best candidate window
|
||||
float DistBox; // Best candidate box distance to current NavId
|
||||
float DistCenter; // Best candidate center distance to current NavId
|
||||
@ -677,7 +699,7 @@ struct ImGuiNavMoveResult
|
||||
ImRect RectRel; // Best candidate bounding box in window relative space
|
||||
|
||||
ImGuiNavMoveResult() { Clear(); }
|
||||
void Clear() { ID = 0; Window = NULL; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); }
|
||||
void Clear() { ID = SelectScopeId = 0; Window = NULL; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); }
|
||||
};
|
||||
|
||||
// Storage for SetNexWindow** functions
|
||||
@ -720,6 +742,10 @@ struct ImGuiNextWindowData
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Tabs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiTabBarSortItem
|
||||
{
|
||||
int Index;
|
||||
@ -767,10 +793,12 @@ struct ImGuiContext
|
||||
float ActiveIdTimer;
|
||||
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
|
||||
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
|
||||
bool ActiveIdHasBeenPressed; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
|
||||
bool ActiveIdHasBeenEdited; // Was the value associated to the widget Edited over the course of the Active state.
|
||||
bool ActiveIdPreviousFrameIsAlive;
|
||||
bool ActiveIdPreviousFrameHasBeenEdited;
|
||||
int ActiveIdAllowNavDirFlags; // Active widget allows using directional navigation (e.g. can activate a button and move away from it)
|
||||
int ActiveIdBlockNavInputFlags;
|
||||
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
|
||||
ImGuiWindow* ActiveIdWindow;
|
||||
ImGuiWindow* ActiveIdPreviousFrameWindow;
|
||||
@ -796,8 +824,9 @@ struct ImGuiContext
|
||||
ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0
|
||||
ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0
|
||||
ImGuiID NavJustTabbedId; // Just tabbed to this id.
|
||||
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest)
|
||||
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame
|
||||
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
|
||||
ImGuiID NavJustMovedToSelectScopeId; // Just navigated to this select scope id (result of a successfully MoveRequest).
|
||||
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
|
||||
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
|
||||
ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring.
|
||||
int NavScoringCount; // Metrics for debugging
|
||||
@ -870,8 +899,13 @@ struct ImGuiContext
|
||||
int TooltipOverrideCount;
|
||||
ImVector<char> PrivateClipboard; // If no custom clipboard handler is defined
|
||||
|
||||
// Range-Select/Multi-Select
|
||||
// [This is unused in this branch, but left here to facilitate merging/syncing multiple branches]
|
||||
ImGuiID MultiSelectScopeId;
|
||||
|
||||
// Platform support
|
||||
ImVec2 PlatformImePos, PlatformImeLastPos; // Cursor position request & last passed to the OS Input Method Editor
|
||||
ImVec2 PlatformImePos; // Cursor position request & last passed to the OS Input Method Editor
|
||||
ImVec2 PlatformImeLastPos;
|
||||
|
||||
// Settings
|
||||
bool SettingsLoaded;
|
||||
@ -922,10 +956,12 @@ struct ImGuiContext
|
||||
ActiveIdTimer = 0.0f;
|
||||
ActiveIdIsJustActivated = false;
|
||||
ActiveIdAllowOverlap = false;
|
||||
ActiveIdHasBeenPressed = false;
|
||||
ActiveIdHasBeenEdited = false;
|
||||
ActiveIdPreviousFrameIsAlive = false;
|
||||
ActiveIdPreviousFrameHasBeenEdited = false;
|
||||
ActiveIdAllowNavDirFlags = 0;
|
||||
ActiveIdAllowNavDirFlags = 0x00;
|
||||
ActiveIdBlockNavInputFlags = 0x00;
|
||||
ActiveIdClickOffset = ImVec2(-1,-1);
|
||||
ActiveIdWindow = ActiveIdPreviousFrameWindow = NULL;
|
||||
ActiveIdSource = ImGuiInputSource_None;
|
||||
@ -938,7 +974,7 @@ struct ImGuiContext
|
||||
|
||||
NavWindow = NULL;
|
||||
NavId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0;
|
||||
NavJustTabbedId = NavJustMovedToId = NavNextActivateId = 0;
|
||||
NavJustTabbedId = NavJustMovedToId = NavJustMovedToSelectScopeId = NavNextActivateId = 0;
|
||||
NavInputSource = ImGuiInputSource_None;
|
||||
NavScoringRectScreen = ImRect();
|
||||
NavScoringCount = 0;
|
||||
@ -984,6 +1020,9 @@ struct ImGuiContext
|
||||
DragSpeedDefaultRatio = 1.0f / 100.0f;
|
||||
ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f);
|
||||
TooltipOverrideCount = 0;
|
||||
|
||||
MultiSelectScopeId = 0;
|
||||
|
||||
PlatformImePos = PlatformImeLastPos = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
SettingsLoaded = false;
|
||||
@ -1002,18 +1041,9 @@ struct ImGuiContext
|
||||
}
|
||||
};
|
||||
|
||||
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
|
||||
// This is going to be exposed in imgui.h when stabilized enough.
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_NoTabStop = 1 << 0, // false
|
||||
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
|
||||
ImGuiItemFlags_Disabled = 1 << 2, // false // [BETA] Disable interactions but doesn't affect visuals yet. See github.com/ocornut/imgui/issues/211
|
||||
ImGuiItemFlags_NoNav = 1 << 3, // false
|
||||
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
|
||||
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
|
||||
ImGuiItemFlags_Default_ = 0
|
||||
};
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGuiWindow
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC variable name in ImGuiWindow.
|
||||
// FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiWindowTempData is quite tenuous and could be reconsidered.
|
||||
@ -1126,6 +1156,7 @@ struct IMGUI_API ImGuiWindow
|
||||
bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
|
||||
bool Hidden; // Do not display (== (HiddenFramesForResize > 0) ||
|
||||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
||||
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
||||
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
|
||||
short BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
|
||||
short BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
|
||||
@ -1214,10 +1245,14 @@ struct ImGuiItemHoveredDataBackup
|
||||
|
||||
enum ImGuiTabBarFlagsPrivate_
|
||||
{
|
||||
ImGuiTabBarFlags_DockNode = 1 << 20, // [Docking: Unused in Master Branch] Part of a dock node
|
||||
ImGuiTabBarFlags_DockNodeIsDockSpace = 1 << 21, // [Docking: Unused in Master Branch] Part of an explicit dockspace node node
|
||||
ImGuiTabBarFlags_IsFocused = 1 << 22,
|
||||
ImGuiTabBarFlags_SaveSettings = 1 << 23 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs
|
||||
ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node
|
||||
ImGuiTabBarFlags_IsFocused = 1 << 21,
|
||||
ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs
|
||||
};
|
||||
|
||||
enum ImGuiTabItemFlagsPrivate_
|
||||
{
|
||||
ImGuiTabItemFlags_NoCloseButton = 1 << 20 // Store whether p_open is set or not, which we need to recompute WidthContents during layout.
|
||||
};
|
||||
|
||||
// Storage for one active tab item (sizeof() 26~32 bytes)
|
||||
@ -1227,11 +1262,12 @@ struct ImGuiTabItem
|
||||
ImGuiTabItemFlags Flags;
|
||||
int LastFrameVisible;
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
int NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
|
||||
float Offset; // Position relative to beginning of tab
|
||||
float Width; // Width currently displayed
|
||||
float WidthContents; // Width of actual contents, stored during BeginTabItem() call
|
||||
|
||||
ImGuiTabItem() { ID = Flags = 0; LastFrameVisible = LastFrameSelected = -1; Offset = Width = WidthContents = 0.0f; }
|
||||
ImGuiTabItem() { ID = Flags = 0; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = WidthContents = 0.0f; }
|
||||
};
|
||||
|
||||
// Storage for a tab bar (sizeof() 92~96 bytes)
|
||||
@ -1256,9 +1292,16 @@ struct ImGuiTabBar
|
||||
bool WantLayout;
|
||||
bool VisibleTabWasSubmitted;
|
||||
short LastTabItemIdx; // For BeginTabItem()/EndTabItem()
|
||||
ImVec2 FramePadding; // style.FramePadding locked at the time of BeginTabBar()
|
||||
ImGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer.
|
||||
|
||||
ImGuiTabBar();
|
||||
int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); }
|
||||
const char* GetTabName(const ImGuiTabItem* tab) const
|
||||
{
|
||||
IM_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size);
|
||||
return TabsNames.Buf.Data + tab->NameOffset;
|
||||
}
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1290,6 +1333,9 @@ namespace ImGui
|
||||
IMGUI_API float GetWindowScrollMaxX(ImGuiWindow* window);
|
||||
IMGUI_API float GetWindowScrollMaxY(ImGuiWindow* window);
|
||||
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window);
|
||||
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond);
|
||||
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond);
|
||||
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond);
|
||||
|
||||
IMGUI_API void SetCurrentFont(ImFont* font);
|
||||
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
|
||||
@ -1309,6 +1355,7 @@ namespace ImGui
|
||||
IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window);
|
||||
IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
|
||||
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
|
||||
IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name);
|
||||
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
|
||||
|
||||
// Basic Accessors
|
||||
@ -1386,7 +1433,7 @@ namespace ImGui
|
||||
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags);
|
||||
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button);
|
||||
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
|
||||
IMGUI_API bool TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, const char* label, ImGuiID tab_id, ImGuiID close_button_id);
|
||||
IMGUI_API bool TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id);
|
||||
|
||||
// Render helpers
|
||||
// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT.
|
||||
@ -1417,6 +1464,7 @@ namespace ImGui
|
||||
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
|
||||
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
|
||||
IMGUI_API void Scrollbar(ImGuiLayoutType direction);
|
||||
IMGUI_API ImGuiID GetScrollbarID(ImGuiLayoutType direction);
|
||||
IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
|
||||
|
||||
// Widgets low-level behaviors
|
||||
@ -1446,7 +1494,7 @@ namespace ImGui
|
||||
IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags);
|
||||
|
||||
// Plot
|
||||
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
|
||||
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size);
|
||||
|
||||
// Shade functions (write over already created vertices)
|
||||
IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1);
|
||||
@ -1469,7 +1517,7 @@ IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned ch
|
||||
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);
|
||||
extern void ImGuiTestEngineHook_PostNewFrame(ImGuiContext* ctx);
|
||||
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
|
||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, int flags);
|
||||
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags);
|
||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register status flags
|
||||
#else
|
||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) do { } while (0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.67
|
||||
// dear imgui, v1.68
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -56,7 +56,9 @@ Index of this file:
|
||||
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
|
||||
#endif
|
||||
#if __has_warning("-Wdouble-promotion")
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||
#endif
|
||||
@ -505,6 +507,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
bool held = false;
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
if (pressed)
|
||||
g.ActiveIdHasBeenPressed = true;
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse)
|
||||
{
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
@ -575,6 +579,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
|
||||
//if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup))
|
||||
// CloseCurrentPopup();
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags);
|
||||
return pressed;
|
||||
}
|
||||
|
||||
@ -672,7 +677,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius)
|
||||
// Render
|
||||
ImVec2 center = bb.GetCenter();
|
||||
if (hovered)
|
||||
window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered), 9);
|
||||
window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered), 9);
|
||||
|
||||
float cross_extent = (radius * 0.7071f) - 1.0f;
|
||||
ImU32 cross_col = GetColorU32(ImGuiCol_Text);
|
||||
@ -705,6 +710,13 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
||||
return pressed;
|
||||
}
|
||||
|
||||
ImGuiID ImGui::GetScrollbarID(ImGuiLayoutType direction)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
return window->GetID((direction == ImGuiLayoutType_Horizontal) ? "#SCROLLX" : "#SCROLLY");
|
||||
}
|
||||
|
||||
// Vertical/Horizontal scrollbar
|
||||
// The entire piece of code below is rather confusing because:
|
||||
// - We handle absolute seeking (when first clicking outside the grab) and relative manipulation (afterward or when clicking inside the grab)
|
||||
@ -717,7 +729,7 @@ void ImGui::Scrollbar(ImGuiLayoutType direction)
|
||||
|
||||
const bool horizontal = (direction == ImGuiLayoutType_Horizontal);
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY");
|
||||
const ImGuiID id = GetScrollbarID(direction);
|
||||
|
||||
// Render background
|
||||
bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX);
|
||||
@ -729,9 +741,21 @@ void ImGui::Scrollbar(ImGuiLayoutType direction)
|
||||
: ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size);
|
||||
if (!horizontal)
|
||||
bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f);
|
||||
if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f)
|
||||
|
||||
const float bb_height = bb.GetHeight();
|
||||
if (bb.GetWidth() <= 0.0f || bb_height <= 0.0f)
|
||||
return;
|
||||
|
||||
// When we are too small, start hiding and disabling the grab (this reduce visual noise on very small window and facilitate using the resize grab)
|
||||
float alpha = 1.0f;
|
||||
if ((direction == ImGuiLayoutType_Vertical) && bb_height < g.FontSize + g.Style.FramePadding.y * 2.0f)
|
||||
{
|
||||
alpha = ImSaturate((bb_height - g.FontSize) / (g.Style.FramePadding.y * 2.0f));
|
||||
if (alpha <= 0.0f)
|
||||
return;
|
||||
}
|
||||
const bool allow_interaction = (alpha >= 1.0f);
|
||||
|
||||
int window_rounding_corners;
|
||||
if (horizontal)
|
||||
window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight);
|
||||
@ -762,7 +786,7 @@ void ImGui::Scrollbar(ImGuiLayoutType direction)
|
||||
float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v);
|
||||
float scroll_ratio = ImSaturate(scroll_v / scroll_max);
|
||||
float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v;
|
||||
if (held && grab_h_norm < 1.0f)
|
||||
if (held && allow_interaction && grab_h_norm < 1.0f)
|
||||
{
|
||||
float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y;
|
||||
float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y;
|
||||
@ -805,8 +829,8 @@ void ImGui::Scrollbar(ImGuiLayoutType direction)
|
||||
*click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f;
|
||||
}
|
||||
|
||||
// Render
|
||||
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab);
|
||||
// Render grab
|
||||
const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab, alpha);
|
||||
ImRect grab_rect;
|
||||
if (horizontal)
|
||||
grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y);
|
||||
@ -890,19 +914,10 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); // We want a square shape to we use Y twice
|
||||
ItemSize(check_bb, style.FramePadding.y);
|
||||
|
||||
ImRect total_bb = check_bb;
|
||||
if (label_size.x > 0)
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size);
|
||||
if (label_size.x > 0)
|
||||
{
|
||||
ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y);
|
||||
total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max));
|
||||
}
|
||||
|
||||
const float square_sz = GetFrameHeight();
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id))
|
||||
return false;
|
||||
|
||||
@ -914,19 +929,19 @@ bool ImGui::Checkbox(const char* label, bool* v)
|
||||
MarkItemEdited(id);
|
||||
}
|
||||
|
||||
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
|
||||
RenderNavHighlight(total_bb, id);
|
||||
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
|
||||
if (*v)
|
||||
{
|
||||
const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight());
|
||||
const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f));
|
||||
RenderCheckMark(check_bb.Min + ImVec2(pad,pad), GetColorU32(ImGuiCol_CheckMark), check_bb.GetWidth() - pad*2.0f);
|
||||
const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f));
|
||||
RenderCheckMark(check_bb.Min + ImVec2(pad, pad), GetColorU32(ImGuiCol_CheckMark), square_sz - pad*2.0f);
|
||||
}
|
||||
|
||||
if (g.LogEnabled)
|
||||
LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]");
|
||||
LogRenderedText(&total_bb.Min, *v ? "[x]" : "[ ]");
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(text_bb.Min, label);
|
||||
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
|
||||
return pressed;
|
||||
@ -958,26 +973,18 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
const ImGuiID id = window->GetID(label);
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1));
|
||||
ItemSize(check_bb, style.FramePadding.y);
|
||||
|
||||
ImRect total_bb = check_bb;
|
||||
if (label_size.x > 0)
|
||||
SameLine(0, style.ItemInnerSpacing.x);
|
||||
const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size);
|
||||
if (label_size.x > 0)
|
||||
{
|
||||
ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y);
|
||||
total_bb.Add(text_bb);
|
||||
}
|
||||
|
||||
const float square_sz = GetFrameHeight();
|
||||
const ImVec2 pos = window->DC.CursorPos;
|
||||
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
|
||||
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id))
|
||||
return false;
|
||||
|
||||
ImVec2 center = check_bb.GetCenter();
|
||||
center.x = (float)(int)center.x + 0.5f;
|
||||
center.y = (float)(int)center.y + 0.5f;
|
||||
const float radius = check_bb.GetHeight() * 0.5f;
|
||||
const float radius = (square_sz - 1.0f) * 0.5f;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
|
||||
@ -988,21 +995,20 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16);
|
||||
if (active)
|
||||
{
|
||||
const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight());
|
||||
const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f));
|
||||
window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16);
|
||||
const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f));
|
||||
window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark), 16);
|
||||
}
|
||||
|
||||
if (style.FrameBorderSize > 0.0f)
|
||||
{
|
||||
window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize);
|
||||
window->DrawList->AddCircle(center + ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize);
|
||||
window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize);
|
||||
}
|
||||
|
||||
if (g.LogEnabled)
|
||||
LogRenderedText(&text_bb.Min, active ? "(x)" : "( )");
|
||||
LogRenderedText(&total_bb.Min, active ? "(x)" : "( )");
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(text_bb.Min, label);
|
||||
RenderText(ImVec2(check_bb.Max.x + style.ItemInnerSpacing.x, check_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@ -1666,7 +1672,7 @@ static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
||||
static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f };
|
||||
if (decimal_precision < 0)
|
||||
return FLT_MIN;
|
||||
return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
return (decimal_precision < IM_ARRAYSIZE(min_steps)) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision);
|
||||
}
|
||||
|
||||
template<typename TYPE>
|
||||
@ -1868,15 +1874,12 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
||||
const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
{
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
|
||||
// Default format string when passing NULL
|
||||
@ -1904,12 +1907,12 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
}
|
||||
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
|
||||
{
|
||||
window->DC.CursorPos = frame_bb.Min;
|
||||
FocusableItemUnregister(window);
|
||||
return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format);
|
||||
}
|
||||
|
||||
// Actual drag behavior
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
const bool value_changed = DragBehavior(id, data_type, v, v_speed, v_min, v_max, format, power, ImGuiDragFlags_None);
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
@ -1925,8 +1928,9 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label);
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -1945,7 +1949,7 @@ bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* v, int
|
||||
for (int i = 0; i < components; i++)
|
||||
{
|
||||
PushID(i);
|
||||
value_changed |= DragScalar("##v", data_type, v, v_speed, v_min, v_max, format, power);
|
||||
value_changed |= DragScalar("", data_type, v, v_speed, v_min, v_max, format, power);
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@ -2305,12 +2309,9 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f));
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
|
||||
// NB- we don't call ItemSize() yet because we may turn into a text edit box below
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
{
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default format string when passing NULL
|
||||
// Patch old "%.0f" format string to use "%d", read function comments for more details.
|
||||
@ -2338,12 +2339,11 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
}
|
||||
if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id))
|
||||
{
|
||||
window->DC.CursorPos = frame_bb.Min;
|
||||
FocusableItemUnregister(window);
|
||||
return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format);
|
||||
}
|
||||
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
RenderNavHighlight(frame_bb, id);
|
||||
@ -2366,6 +2366,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -2385,7 +2386,7 @@ bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, i
|
||||
for (int i = 0; i < components; i++)
|
||||
{
|
||||
PushID(i);
|
||||
value_changed |= SliderScalar("##v", data_type, v, v_min, v_max, format, power);
|
||||
value_changed |= SliderScalar("", data_type, v, v_min, v_max, format, power);
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@ -2575,7 +2576,7 @@ const char* ImParseFormatFindEnd(const char* fmt)
|
||||
// fmt = "%.3f" -> return fmt
|
||||
// fmt = "hello %.3f" -> return fmt + 6
|
||||
// fmt = "%.3f hello" -> return buf written with "%.3f"
|
||||
const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, int buf_size)
|
||||
const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, size_t buf_size)
|
||||
{
|
||||
const char* fmt_start = ImParseFormatFindStart(fmt);
|
||||
if (fmt_start[0] != '%')
|
||||
@ -2583,7 +2584,7 @@ const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, int buf_siz
|
||||
const char* fmt_end = ImParseFormatFindEnd(fmt_start);
|
||||
if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data.
|
||||
return fmt_start;
|
||||
ImStrncpy(buf, fmt_start, ImMin((int)(fmt_end + 1 - fmt_start), buf_size));
|
||||
ImStrncpy(buf, fmt_start, ImMin((size_t)(fmt_end - fmt_start) + 1, buf_size));
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -2612,17 +2613,15 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
|
||||
}
|
||||
|
||||
// Create text input in place of an active drag/slider (used when doing a CTRL+Click on drag/slider widgets)
|
||||
// FIXME: Logic is awkward and confusing. This should be reworked to facilitate using in other situations.
|
||||
// FIXME: Facilitate using this in variety of other situations.
|
||||
bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
|
||||
// Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen)
|
||||
// On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id
|
||||
SetActiveID(g.ScalarAsInputTextId, window);
|
||||
SetHoveredID(0);
|
||||
g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
|
||||
// On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id.
|
||||
// We clear ActiveID on the first frame to allow the InputText() taking it back.
|
||||
if (g.ScalarAsInputTextId == 0)
|
||||
ClearActiveID();
|
||||
|
||||
char fmt_buf[32];
|
||||
char data_buf[32];
|
||||
@ -2631,11 +2630,11 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const c
|
||||
ImStrTrimBlanks(data_buf);
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
|
||||
bool value_changed = InputTextEx(label, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags);
|
||||
if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget
|
||||
if (g.ScalarAsInputTextId == 0)
|
||||
{
|
||||
IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID
|
||||
// First frame we started displaying the InputText widget, we expect it to take the active id.
|
||||
IM_ASSERT(g.ActiveId == id);
|
||||
g.ScalarAsInputTextId = g.ActiveId;
|
||||
SetHoveredID(id);
|
||||
}
|
||||
if (value_changed)
|
||||
return DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialText.Data, data_type, data_ptr, NULL);
|
||||
@ -2720,7 +2719,7 @@ bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* v, in
|
||||
for (int i = 0; i < components; i++)
|
||||
{
|
||||
PushID(i);
|
||||
value_changed |= InputScalar("##v", data_type, v, step, step_fast, format, flags);
|
||||
value_changed |= InputScalar("", data_type, v, step, step_fast, format, flags);
|
||||
SameLine(0, g.Style.ItemInnerSpacing.x);
|
||||
PopID();
|
||||
PopItemWidth();
|
||||
@ -2852,8 +2851,9 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
|
||||
|
||||
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line)
|
||||
{
|
||||
ImFont* font = GImGui->Font;
|
||||
const float line_height = GImGui->FontSize;
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImFont* font = g.Font;
|
||||
const float line_height = g.FontSize;
|
||||
const float scale = line_height / font->FontSize;
|
||||
|
||||
ImVec2 text_size = ImVec2(0,0);
|
||||
@ -3158,7 +3158,12 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
ImGuiWindow* draw_window = window;
|
||||
if (is_multiline)
|
||||
{
|
||||
ItemAdd(total_bb, id, &frame_bb);
|
||||
if (!ItemAdd(total_bb, id, &frame_bb))
|
||||
{
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
EndGroup();
|
||||
return false;
|
||||
}
|
||||
if (!BeginChildFrame(id, frame_bb.GetSize()))
|
||||
{
|
||||
EndChildFrame();
|
||||
@ -3245,15 +3250,16 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
select_all = true;
|
||||
}
|
||||
if (flags & ImGuiInputTextFlags_AlwaysInsertMode)
|
||||
edit_state.StbState.insert_mode = true;
|
||||
edit_state.StbState.insert_mode = 1;
|
||||
if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl)))
|
||||
select_all = true;
|
||||
}
|
||||
SetActiveID(id, window);
|
||||
SetFocusID(id, window);
|
||||
FocusWindow(window);
|
||||
g.ActiveIdBlockNavInputFlags = (1 << ImGuiNavInput_Cancel);
|
||||
if (!is_multiline && !(flags & ImGuiInputTextFlags_CallbackHistory))
|
||||
g.ActiveIdAllowNavDirFlags |= ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down));
|
||||
g.ActiveIdAllowNavDirFlags = ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down));
|
||||
}
|
||||
else if (io.MouseClicked[0])
|
||||
{
|
||||
@ -3583,7 +3589,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
}
|
||||
|
||||
// If the underlying buffer resize was denied or not carried to the next frame, apply_new_text_length+1 may be >= buf_size.
|
||||
ImStrncpy(buf, edit_state.TempBuffer.Data, ImMin(apply_new_text_length + 1, buf_size));
|
||||
ImStrncpy(buf, apply_new_text, ImMin(apply_new_text_length + 1, buf_size));
|
||||
value_changed = true;
|
||||
}
|
||||
|
||||
@ -3789,6 +3795,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags);
|
||||
if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0)
|
||||
return enter_pressed;
|
||||
else
|
||||
@ -3895,9 +3902,14 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
if (n + 1 == components)
|
||||
PushItemWidth(w_item_last);
|
||||
if (flags & ImGuiColorEditFlags_Float)
|
||||
value_changed = value_changed_as_float = value_changed | DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
{
|
||||
value_changed |= DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]);
|
||||
value_changed_as_float |= value_changed;
|
||||
}
|
||||
else
|
||||
{
|
||||
value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]);
|
||||
}
|
||||
if (!(flags & ImGuiColorEditFlags_NoOptions))
|
||||
OpenPopupOnItemClick("context");
|
||||
}
|
||||
@ -4000,7 +4012,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
{
|
||||
if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
{
|
||||
memcpy((float*)col, payload->Data, sizeof(float) * 3);
|
||||
memcpy((float*)col, payload->Data, sizeof(float) * 3); // Preserve alpha if any //-V512
|
||||
value_changed = true;
|
||||
}
|
||||
if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
|
||||
@ -4582,7 +4594,7 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
|
||||
g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask);
|
||||
SetCursorScreenPos(backup_pos);
|
||||
ImVec4 dummy_ref_col;
|
||||
memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (picker_flags & ImGuiColorEditFlags_NoAlpha ? 3 : 4));
|
||||
memcpy(&dummy_ref_col, ref_col, sizeof(float) * ((picker_flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4));
|
||||
ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags);
|
||||
PopID();
|
||||
}
|
||||
@ -4799,20 +4811,24 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
}
|
||||
|
||||
// Flags that affects opening behavior:
|
||||
// - 0(default) ..................... single-click anywhere to open
|
||||
// - 0 (default) .................... single-click anywhere to open
|
||||
// - OpenOnDoubleClick .............. double-click anywhere to open
|
||||
// - OpenOnArrow .................... single-click on arrow to open
|
||||
// - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open
|
||||
ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0);
|
||||
if (!is_leaf)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers;
|
||||
if (flags & ImGuiTreeNodeFlags_AllowItemOverlap)
|
||||
button_flags |= ImGuiButtonFlags_AllowItemOverlap;
|
||||
if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0);
|
||||
if (!is_leaf)
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
|
||||
bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags);
|
||||
bool selected = (flags & ImGuiTreeNodeFlags_Selected) != 0;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags);
|
||||
bool toggled = false;
|
||||
if (!is_leaf)
|
||||
{
|
||||
bool toggled = false;
|
||||
if (pressed)
|
||||
{
|
||||
toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) || (g.NavActivateId == id);
|
||||
@ -4847,11 +4863,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y);
|
||||
ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_TypeThin;
|
||||
if (display_frame)
|
||||
{
|
||||
// Framed type
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding);
|
||||
RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
RenderNavHighlight(frame_bb, id, nav_highlight_flags);
|
||||
RenderArrow(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
||||
if (g.LogEnabled)
|
||||
{
|
||||
@ -4870,10 +4887,10 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
else
|
||||
{
|
||||
// Unframed typed for tree nodes
|
||||
if (hovered || (flags & ImGuiTreeNodeFlags_Selected))
|
||||
if (hovered || selected)
|
||||
{
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, col, false);
|
||||
RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
RenderNavHighlight(frame_bb, id, nav_highlight_flags);
|
||||
}
|
||||
|
||||
if (flags & ImGuiTreeNodeFlags_Bullet)
|
||||
@ -4985,7 +5002,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
|
||||
ImGuiItemHoveredDataBackup last_item_backup;
|
||||
float button_radius = g.FontSize * 0.5f;
|
||||
ImVec2 button_center = ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_radius, window->DC.LastItemRect.GetCenter().y);
|
||||
if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), button_center, button_radius))
|
||||
if (CloseButton(window->GetID((void*)((intptr_t)id+1)), button_center, button_radius))
|
||||
*p_open = false;
|
||||
last_item_backup.Restore();
|
||||
}
|
||||
@ -5024,7 +5041,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
// Fill horizontal space.
|
||||
ImVec2 window_padding = window->WindowPadding;
|
||||
float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x;
|
||||
float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x);
|
||||
float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - pos.x);
|
||||
ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y);
|
||||
ImRect bb(pos, pos + size_draw);
|
||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth))
|
||||
@ -5053,11 +5070,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
if (flags & ImGuiSelectableFlags_PressedOnRelease) button_flags |= ImGuiButtonFlags_PressedOnRelease;
|
||||
if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled;
|
||||
if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
if (flags & ImGuiSelectableFlags_Disabled)
|
||||
selected = false;
|
||||
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
// Hovering selectable with mouse updates NavId accordingly so navigation can be resumed with gamepad/keyboard (this doesn't happen on most widgets)
|
||||
if (pressed || hovered)
|
||||
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
|
||||
@ -5083,7 +5100,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
}
|
||||
|
||||
if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
||||
RenderTextClipped(bb_inner.Min, bb.Max, label, NULL, &label_size, ImVec2(0.0f,0.0f));
|
||||
RenderTextClipped(bb_inner.Min, bb_inner.Max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||
if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor();
|
||||
|
||||
// Automatically close popups
|
||||
@ -5130,6 +5147,13 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
|
||||
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
|
||||
|
||||
if (!IsRectVisible(bb.Min, bb.Max))
|
||||
{
|
||||
ItemSize(bb.GetSize(), style.FramePadding.y);
|
||||
ItemAdd(bb, 0, &frame_bb);
|
||||
return false;
|
||||
}
|
||||
|
||||
BeginGroup();
|
||||
if (label_size.x > 0)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label);
|
||||
@ -5222,7 +5246,7 @@ bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(v
|
||||
// - PlotHistogram()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size)
|
||||
void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
if (window->SkipItems)
|
||||
@ -5230,20 +5254,21 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge
|
||||
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
|
||||
const ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
if (graph_size.x == 0.0f)
|
||||
graph_size.x = CalcItemWidth();
|
||||
if (graph_size.y == 0.0f)
|
||||
graph_size.y = label_size.y + (style.FramePadding.y * 2);
|
||||
if (frame_size.x == 0.0f)
|
||||
frame_size.x = CalcItemWidth();
|
||||
if (frame_size.y == 0.0f)
|
||||
frame_size.y = label_size.y + (style.FramePadding.y * 2);
|
||||
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y));
|
||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
||||
const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding);
|
||||
const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0));
|
||||
ItemSize(total_bb, style.FramePadding.y);
|
||||
if (!ItemAdd(total_bb, 0, &frame_bb))
|
||||
return;
|
||||
const bool hovered = ItemHoverable(inner_bb, 0);
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
|
||||
// Determine scale from values if not specified
|
||||
if (scale_min == FLT_MAX || scale_max == FLT_MAX)
|
||||
@ -5266,12 +5291,12 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge
|
||||
|
||||
if (values_count > 0)
|
||||
{
|
||||
int res_w = ImMin((int)graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0);
|
||||
int res_w = ImMin((int)frame_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0);
|
||||
int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0);
|
||||
|
||||
// Tooltip on hover
|
||||
int v_hovered = -1;
|
||||
if (hovered)
|
||||
if (hovered && inner_bb.Contains(g.IO.MousePos))
|
||||
{
|
||||
const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f);
|
||||
const int v_idx = (int)(t * item_count);
|
||||
@ -5478,7 +5503,7 @@ bool ImGui::BeginMainMenuBar()
|
||||
End();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return true; //-V1020
|
||||
}
|
||||
|
||||
void ImGui::EndMainMenuBar()
|
||||
@ -5580,7 +5605,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
if (menuset_is_open)
|
||||
g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent)
|
||||
|
||||
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestWindowPosForPopup).
|
||||
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu,
|
||||
// However the final position is going to be different! It is choosen by FindBestWindowPosForPopup().
|
||||
// e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
|
||||
ImVec2 popup_pos, pos = window->DC.CursorPos;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
@ -5620,6 +5647,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
{
|
||||
if (ImGuiWindow* next_window = g.OpenPopupStack[g.BeginPopupStack.Size].Window)
|
||||
{
|
||||
// FIXME-DPI: Values should be derived from a master "scale" factor.
|
||||
ImRect next_window_rect = next_window->Rect();
|
||||
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
|
||||
ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
|
||||
@ -5787,6 +5815,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected,
|
||||
// - TabBarScrollToTab() [Internal]
|
||||
// - TabBarQueueChangeTabOrder() [Internal]
|
||||
// - TabBarScrollingButtons() [Internal]
|
||||
// - TabBarTabListPopupButton() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
namespace ImGui
|
||||
@ -5797,6 +5826,7 @@ namespace ImGui
|
||||
static float TabBarScrollClamp(ImGuiTabBar* tab_bar, float scrolling);
|
||||
static void TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
static ImGuiTabItem* TabBarScrollingButtons(ImGuiTabBar* tab_bar);
|
||||
static ImGuiTabItem* TabBarTabListPopupButton(ImGuiTabBar* tab_bar);
|
||||
}
|
||||
|
||||
ImGuiTabBar::ImGuiTabBar()
|
||||
@ -5804,6 +5834,7 @@ ImGuiTabBar::ImGuiTabBar()
|
||||
ID = 0;
|
||||
SelectedTabId = NextSelectedTabId = VisibleTabId = 0;
|
||||
CurrFrameVisible = PrevFrameVisible = -1;
|
||||
ContentsHeight = 0.0f;
|
||||
OffsetMax = OffsetNextTab = 0.0f;
|
||||
ScrollingAnim = ScrollingTarget = 0.0f;
|
||||
Flags = ImGuiTabBarFlags_None;
|
||||
@ -5875,6 +5906,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||
tab_bar->WantLayout = true; // Layout will be done on the first call to ItemTab()
|
||||
tab_bar->PrevFrameVisible = tab_bar->CurrFrameVisible;
|
||||
tab_bar->CurrFrameVisible = g.FrameCount;
|
||||
tab_bar->FramePadding = g.Style.FramePadding;
|
||||
|
||||
// Layout
|
||||
ItemSize(ImVec2(tab_bar->OffsetMax, tab_bar->BarRect.GetHeight()));
|
||||
@ -5884,8 +5916,8 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||
const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_Tab);
|
||||
const float y = tab_bar->BarRect.Max.y - 1.0f;
|
||||
{
|
||||
const float separator_min_x = tab_bar->BarRect.Min.x - ((flags & ImGuiTabBarFlags_DockNodeIsDockSpace) ? 0.0f : window->WindowPadding.x);
|
||||
const float separator_max_x = tab_bar->BarRect.Max.x + ((flags & ImGuiTabBarFlags_DockNodeIsDockSpace) ? 0.0f : window->WindowPadding.x);
|
||||
const float separator_min_x = tab_bar->BarRect.Min.x - window->WindowPadding.x;
|
||||
const float separator_max_x = tab_bar->BarRect.Max.x + window->WindowPadding.x;
|
||||
window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f);
|
||||
}
|
||||
return true;
|
||||
@ -5972,6 +6004,12 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
tab_bar->ReorderRequestTabId = 0;
|
||||
}
|
||||
|
||||
// Tab List Popup (will alter tab_bar->BarRect and therefore the available width!)
|
||||
const bool tab_list_popup_button = (tab_bar->Flags & ImGuiTabBarFlags_TabListPopupButton) != 0;
|
||||
if (tab_list_popup_button)
|
||||
if (ImGuiTabItem* tab_to_select = TabBarTabListPopupButton(tab_bar)) // NB: Will alter BarRect.Max.x!
|
||||
scroll_track_selected_tab_id = tab_bar->SelectedTabId = tab_to_select->ID;
|
||||
|
||||
ImVector<ImGuiTabBarSortItem>& width_sort_buffer = g.TabSortByWidthBuffer;
|
||||
width_sort_buffer.resize(tab_bar->Tabs.Size);
|
||||
|
||||
@ -5989,9 +6027,12 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
if (tab->ID == tab_bar->SelectedTabId)
|
||||
found_selected_tab_id = true;
|
||||
|
||||
// Refresh tab width immediately if we can (for manual tab bar, WidthContent will lag by one frame which is mostly noticeable when changing style.FramePadding.x)
|
||||
// Refresh tab width immediately, otherwise changes of style e.g. style.FramePadding.x would noticeably lag in the tab bar.
|
||||
// Additionally, when using TabBarAddTab() to manipulate tab bar order we occasionally insert new tabs that don't have a width yet,
|
||||
// and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window.
|
||||
const char* tab_name = tab_bar->GetTabName(tab);
|
||||
tab->WidthContents = TabItemCalcSize(tab_name, (tab->Flags & ImGuiTabItemFlags_NoCloseButton) ? false : true).x;
|
||||
|
||||
width_total_contents += (tab_n > 0 ? g.Style.ItemInnerSpacing.x : 0.0f) + tab->WidthContents;
|
||||
|
||||
// Store data so we can build an array sorted by width if we need to shrink tabs down
|
||||
@ -6069,6 +6110,10 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
const float scrolling_speed = (tab_bar->PrevFrameVisible + 1 < g.FrameCount) ? FLT_MAX : (g.IO.DeltaTime * g.FontSize * 70.0f);
|
||||
if (tab_bar->ScrollingAnim != tab_bar->ScrollingTarget)
|
||||
tab_bar->ScrollingAnim = ImLinearSweep(tab_bar->ScrollingAnim, tab_bar->ScrollingTarget, scrolling_speed);
|
||||
|
||||
// Clear name buffers
|
||||
if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0)
|
||||
tab_bar->TabsNames.Buf.resize(0);
|
||||
}
|
||||
|
||||
// Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack.
|
||||
@ -6076,7 +6121,7 @@ static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label)
|
||||
{
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_DockNode)
|
||||
{
|
||||
ImGuiID id = ImHash(label, 0);
|
||||
ImGuiID id = ImHashStr(label, 0);
|
||||
KeepAliveID(id);
|
||||
return id;
|
||||
}
|
||||
@ -6210,6 +6255,41 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
|
||||
return tab_to_select;
|
||||
}
|
||||
|
||||
static ImGuiTabItem* ImGui::TabBarTabListPopupButton(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
|
||||
// We use g.Style.FramePadding.y to match the square ArrowButton size
|
||||
const float tab_list_popup_button_width = g.FontSize + g.Style.FramePadding.y;
|
||||
const ImVec2 backup_cursor_pos = window->DC.CursorPos;
|
||||
window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x - g.Style.FramePadding.y, tab_bar->BarRect.Min.y);
|
||||
tab_bar->BarRect.Min.x += tab_list_popup_button_width;
|
||||
|
||||
ImVec4 arrow_col = g.Style.Colors[ImGuiCol_Text];
|
||||
arrow_col.w *= 0.5f;
|
||||
PushStyleColor(ImGuiCol_Text, arrow_col);
|
||||
PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
||||
bool open = BeginCombo("##v", NULL, ImGuiComboFlags_NoPreview);
|
||||
PopStyleColor(2);
|
||||
|
||||
ImGuiTabItem* tab_to_select = NULL;
|
||||
if (open)
|
||||
{
|
||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
{
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
|
||||
const char* tab_name = tab_bar->GetTabName(tab);
|
||||
if (Selectable(tab_name, tab_bar->SelectedTabId == tab->ID))
|
||||
tab_to_select = tab;
|
||||
}
|
||||
EndCombo();
|
||||
}
|
||||
|
||||
window->DC.CursorPos = backup_cursor_pos;
|
||||
return tab_to_select;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: BeginTabItem, EndTabItem, etc.
|
||||
//-------------------------------------------------------------------------
|
||||
@ -6221,7 +6301,7 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
|
||||
// - TabItemEx() [Internal]
|
||||
// - SetTabItemClosed()
|
||||
// - TabItemCalcSize() [Internal]
|
||||
// - TabItemRenderBackground() [Internal]
|
||||
// - TabItemBackground() [Internal]
|
||||
// - TabItemLabelAndCloseButton() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@ -6296,12 +6376,19 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
tab_bar->LastTabItemIdx = (short)tab_bar->Tabs.index_from_ptr(tab);
|
||||
tab->WidthContents = size.x;
|
||||
|
||||
if (p_open == NULL)
|
||||
flags |= ImGuiTabItemFlags_NoCloseButton;
|
||||
|
||||
const bool tab_bar_appearing = (tab_bar->PrevFrameVisible + 1 < g.FrameCount);
|
||||
const bool tab_bar_focused = (tab_bar->Flags & ImGuiTabBarFlags_IsFocused) != 0;
|
||||
const bool tab_appearing = (tab->LastFrameVisible + 1 < g.FrameCount);
|
||||
tab->LastFrameVisible = g.FrameCount;
|
||||
tab->Flags = flags;
|
||||
|
||||
// Append name with zero-terminator
|
||||
tab->NameOffset = tab_bar->TabsNames.size();
|
||||
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
|
||||
|
||||
// If we are not reorderable, always reset offset based on submission order.
|
||||
// (We already handled layout and sizing using the previous known order, but sizing is not affected by order!)
|
||||
if (!tab_appearing && !(tab_bar->Flags & ImGuiTabBarFlags_Reorderable))
|
||||
@ -6398,7 +6485,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
// Enlarge tab display when hovering
|
||||
bb.Max.x = bb.Min.x + (float)(int)ImLerp(bb.GetWidth(), tab->WidthContents, ImSaturate((g.HoveredIdNotActiveTimer - 0.40f) * 6.0f));
|
||||
display_draw_list = GetOverlayDrawList(window);
|
||||
TabItemRenderBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
|
||||
TabItemBackground(display_draw_list, bb, flags, GetColorU32(ImGuiCol_TitleBgActive));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -6417,9 +6504,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
||||
|
||||
// Render tab label, process close button
|
||||
const ImGuiID close_button_id = p_open ? window->GetID((void*)(intptr_t)(id + 1)) : 0;
|
||||
bool just_closed = TabItemLabelAndCloseButton(display_draw_list, bb, flags, label, id, close_button_id);
|
||||
if (just_closed)
|
||||
const ImGuiID close_button_id = p_open ? window->GetID((void*)((intptr_t)id + 1)) : 0;
|
||||
bool just_closed = TabItemLabelAndCloseButton(display_draw_list, bb, flags, tab_bar->FramePadding, label, id, close_button_id);
|
||||
if (just_closed && p_open != NULL)
|
||||
{
|
||||
*p_open = false;
|
||||
TabBarCloseTab(tab_bar, tab);
|
||||
@ -6468,40 +6555,45 @@ ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button)
|
||||
void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col)
|
||||
{
|
||||
// While rendering tabs, we trim 1 pixel off the top of our bounding box so they can fit within a regular frame height while looking "detached" from it.
|
||||
(void)flags;
|
||||
ImGuiContext& g = *GImGui;
|
||||
const float width = bb.GetWidth();
|
||||
IM_UNUSED(flags);
|
||||
IM_ASSERT(width > 0.0f);
|
||||
const float rounding = ImMax(0.0f, ImMin(g.Style.TabRounding, width * 0.5f - 1.0f));
|
||||
float y1 = bb.Min.y + 1.0f;
|
||||
float y2 = bb.Max.y - 1.0f;
|
||||
const float y1 = bb.Min.y + 1.0f;
|
||||
const float y2 = bb.Max.y - 1.0f;
|
||||
draw_list->PathLineTo(ImVec2(bb.Min.x, y2));
|
||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9);
|
||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12);
|
||||
draw_list->PathLineTo(ImVec2(bb.Max.x, y2));
|
||||
draw_list->AddConvexPolyFilled(draw_list->_Path.Data, draw_list->_Path.Size, col);
|
||||
draw_list->PathFillConvex(col);
|
||||
if (g.Style.TabBorderSize > 0.0f)
|
||||
draw_list->AddPolyline(draw_list->_Path.Data, draw_list->_Path.Size, GetColorU32(ImGuiCol_Border), false, g.Style.TabBorderSize);
|
||||
draw_list->PathClear();
|
||||
{
|
||||
draw_list->PathLineTo(ImVec2(bb.Min.x + 0.5f, y2));
|
||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding + 0.5f, y1 + rounding + 0.5f), rounding, 6, 9);
|
||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding - 0.5f, y1 + rounding + 0.5f), rounding, 9, 12);
|
||||
draw_list->PathLineTo(ImVec2(bb.Max.x - 0.5f, y2));
|
||||
draw_list->PathStroke(GetColorU32(ImGuiCol_Border), false, g.Style.TabBorderSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Render text label (with custom clipping) + Unsaved Document marker + Close Button logic
|
||||
bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, const char* label, ImGuiID tab_id, ImGuiID close_button_id)
|
||||
// We tend to lock style.FramePadding for a given tab-bar, hence the 'frame_padding' parameter.
|
||||
bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiStyle& style = g.Style;
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
if (bb.GetWidth() <= 1.0f)
|
||||
return false;
|
||||
|
||||
// Render text label (with clipping + alpha gradient) + unsaved marker
|
||||
const char* TAB_UNSAVED_MARKER = "*";
|
||||
ImRect text_pixel_clip_bb(bb.Min.x + style.FramePadding.x, bb.Min.y + style.FramePadding.y, bb.Max.x - style.FramePadding.x, bb.Max.y);
|
||||
ImRect text_pixel_clip_bb(bb.Min.x + frame_padding.x, bb.Min.y + frame_padding.y, bb.Max.x - frame_padding.x, bb.Max.y);
|
||||
if (flags & ImGuiTabItemFlags_UnsavedDocument)
|
||||
{
|
||||
text_pixel_clip_bb.Max.x -= CalcTextSize(TAB_UNSAVED_MARKER, NULL, false).x;
|
||||
ImVec2 unsaved_marker_pos(ImMin(bb.Min.x + style.FramePadding.x + label_size.x + 2, text_pixel_clip_bb.Max.x), bb.Min.y + style.FramePadding.y + (float)(int)(-g.FontSize * 0.25f));
|
||||
RenderTextClippedEx(draw_list, unsaved_marker_pos, bb.Max - style.FramePadding, TAB_UNSAVED_MARKER, NULL, NULL);
|
||||
ImVec2 unsaved_marker_pos(ImMin(bb.Min.x + frame_padding.x + label_size.x + 2, text_pixel_clip_bb.Max.x), bb.Min.y + frame_padding.y + (float)(int)(-g.FontSize * 0.25f));
|
||||
RenderTextClippedEx(draw_list, unsaved_marker_pos, bb.Max - frame_padding, TAB_UNSAVED_MARKER, NULL, NULL);
|
||||
}
|
||||
ImRect text_ellipsis_clip_bb = text_pixel_clip_bb;
|
||||
|
||||
@ -6519,7 +6611,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
{
|
||||
ImGuiItemHoveredDataBackup last_item_backup;
|
||||
const float close_button_sz = g.FontSize * 0.5f;
|
||||
if (CloseButton(close_button_id, ImVec2(bb.Max.x - style.FramePadding.x - close_button_sz, bb.Min.y + style.FramePadding.y + close_button_sz), close_button_sz))
|
||||
if (CloseButton(close_button_id, ImVec2(bb.Max.x - frame_padding.x - close_button_sz, bb.Min.y + frame_padding.y + close_button_sz), close_button_sz))
|
||||
close_button_pressed = true;
|
||||
last_item_backup.Restore();
|
||||
|
||||
|
@ -1,4 +1,10 @@
|
||||
// stb_rect_pack.h - v0.11 - public domain - rectangle packing
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 0.99.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Added STBRP__CDECL
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_rect_pack.h - v0.99 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
@ -34,6 +40,7 @@
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
@ -204,6 +211,7 @@ struct stbrp_context
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
@ -512,6 +520,7 @@ static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, i
|
||||
return res;
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
@ -523,6 +532,7 @@ static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
@ -543,9 +553,6 @@ STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int nu
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
|
@ -1,9 +1,10 @@
|
||||
// [ImGui] this is a slightly modified version of stb_textedit.h 1.12. Those changes would need to be pushed into nothings/stb
|
||||
// [ImGui] - 2018-06: fixed undo/redo after pasting large amount of text (over 32 kb). Redo will still fail when undo buffers are exhausted, but text won't be corrupted (see nothings/stb issue #620)
|
||||
// [ImGui] - 2018-06: fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// [ImGui] - fixed some minor warnings
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_textedit.h 1.13.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_textedit.h - v1.12 - public domain - Sean Barrett
|
||||
// stb_textedit.h - v1.13 - public domain - Sean Barrett
|
||||
// Development of this library was sponsored by RAD Game Tools
|
||||
//
|
||||
// This C header file implements the guts of a multi-line text-editing
|
||||
@ -34,6 +35,7 @@
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.13 (2019-02-07) fix bug in undo size management
|
||||
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
|
||||
// 1.11 (2017-03-03) fix HOME on last line, dragging off single-line textfield
|
||||
// 1.10 (2016-10-25) supress warnings about casting away const with -Wcast-qual
|
||||
@ -563,7 +565,6 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||
|
||||
// now scan to find xpos
|
||||
find->x = r.x0;
|
||||
i = 0;
|
||||
for (i=0; first+i < n; ++i)
|
||||
find->x += STB_TEXTEDIT_GETWIDTH(str, first, i);
|
||||
}
|
||||
@ -693,7 +694,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||
{
|
||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||
stb_textedit_delete_selection(str,state); // implicity clamps
|
||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||
state->has_preferred_x = 0;
|
||||
return 1;
|
||||
}
|
||||
@ -745,7 +746,7 @@ retry:
|
||||
state->has_preferred_x = 0;
|
||||
}
|
||||
} else {
|
||||
stb_textedit_delete_selection(str,state); // implicity clamps
|
||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
|
||||
stb_text_makeundo_insert(state, state->cursor, 1);
|
||||
++state->cursor;
|
||||
@ -1133,7 +1134,14 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
state->undo_rec[i].char_storage += n;
|
||||
}
|
||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
// {DEAR IMGUI]
|
||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
||||
const char* buf_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point)) >= buf_begin);
|
||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
||||
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point+1, state->undo_rec + state->redo_point, move_size);
|
||||
|
||||
// now move redo_point to point to the new one
|
||||
++state->redo_point;
|
||||
}
|
||||
|
@ -1,4 +1,9 @@
|
||||
// stb_truetype.h - v1.19 - public domain
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_truetype.h 1.20.
|
||||
// Mostly fixing for compiler and static analyzer warnings.
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_truetype.h - v1.20 - public domain
|
||||
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
|
||||
//
|
||||
// This library processes TrueType files:
|
||||
@ -49,6 +54,7 @@
|
||||
//
|
||||
// VERSION HISTORY
|
||||
//
|
||||
// 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
|
||||
// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
|
||||
// 1.18 (2018-01-29) add missing function
|
||||
// 1.17 (2017-07-23) make more arguments const; doc fix
|
||||
@ -75,7 +81,7 @@
|
||||
//
|
||||
// USAGE
|
||||
//
|
||||
// Include this file in whatever places neeed to refer to it. In ONE C/C++
|
||||
// Include this file in whatever places need to refer to it. In ONE C/C++
|
||||
// file, write:
|
||||
// #define STB_TRUETYPE_IMPLEMENTATION
|
||||
// before the #include of this file. This expands out the actual
|
||||
@ -247,8 +253,8 @@
|
||||
// Documentation & header file 520 LOC \___ 660 LOC documentation
|
||||
// Sample code 140 LOC /
|
||||
// Truetype parsing 620 LOC ---- 620 LOC TrueType
|
||||
// Software rasterization 240 LOC \ .
|
||||
// Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
|
||||
// Software rasterization 240 LOC \.
|
||||
// Curve tessellation 120 LOC \__ 550 LOC Bitmap creation
|
||||
// Bitmap management 100 LOC /
|
||||
// Baked bitmap interface 70 LOC /
|
||||
// Font name matching & access 150 LOC ---- 150
|
||||
@ -556,6 +562,8 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
|
||||
//
|
||||
// It's inefficient; you might want to c&p it and optimize it.
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
|
||||
// Query the font vertical metrics without having to create a font first.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -641,6 +649,12 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
||||
// To use with PackFontRangesGather etc., you must set it before calls
|
||||
// call to PackFontRangesGatherRects.
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
|
||||
// If skip != 0, this tells stb_truetype to skip any codepoints for which
|
||||
// there is no corresponding glyph. If skip=0, which is the default, then
|
||||
// codepoints without a glyph recived the font's "missing character" glyph,
|
||||
// typically an empty box by convention.
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
|
||||
int char_index, // character to display
|
||||
float *xpos, float *ypos, // pointers to current position in screen pixel space
|
||||
@ -669,6 +683,7 @@ struct stbtt_pack_context {
|
||||
int height;
|
||||
int stride_in_bytes;
|
||||
int padding;
|
||||
int skip_missing;
|
||||
unsigned int h_oversample, v_oversample;
|
||||
unsigned char *pixels;
|
||||
void *nodes;
|
||||
@ -694,7 +709,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
|
||||
// file will only define one font and it always be at offset 0, so it will
|
||||
// return '0' for index 0, and -1 for all other indices.
|
||||
|
||||
// The following structure is defined publically so you can declare one on
|
||||
// The following structure is defined publicly so you can declare one on
|
||||
// the stack or as a global or etc, but you should treat it as opaque.
|
||||
struct stbtt_fontinfo
|
||||
{
|
||||
@ -733,6 +748,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
|
||||
// and you want a speed-up, call this function with the character you're
|
||||
// going to process, then use glyph-based functions instead of the
|
||||
// codepoint-based functions.
|
||||
// Returns 0 if the character codepoint is not defined in the font.
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -820,7 +836,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
|
||||
// returns # of vertices and fills *vertices with the pointer to them
|
||||
// these are expressed in "unscaled" coordinates
|
||||
//
|
||||
// The shape is a series of countours. Each one starts with
|
||||
// The shape is a series of contours. Each one starts with
|
||||
// a STBTT_moveto, then consists of a series of mixed
|
||||
// STBTT_lineto and STBTT_curveto segments. A lineto
|
||||
// draws a line from previous endpoint to its x,y; a curveto
|
||||
@ -916,7 +932,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
|
||||
STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
|
||||
// These functions compute a discretized SDF field for a single character, suitable for storing
|
||||
// in a single-channel texture, sampling with bilinear filtering, and testing against
|
||||
// larger than some threshhold to produce scalable fonts.
|
||||
// larger than some threshold to produce scalable fonts.
|
||||
// info -- the font
|
||||
// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
|
||||
// glyph/codepoint -- the character to generate the SDF for
|
||||
@ -1825,7 +1841,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s
|
||||
if (comp_verts) STBTT_free(comp_verts, info->userdata);
|
||||
return 0;
|
||||
}
|
||||
if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex));
|
||||
if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); //-V595
|
||||
STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex));
|
||||
if (vertices) STBTT_free(vertices, info->userdata);
|
||||
vertices = tmp;
|
||||
@ -2196,7 +2212,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st
|
||||
} break;
|
||||
|
||||
default:
|
||||
if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254))
|
||||
if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) //-V560
|
||||
return STBTT__CSERR("reserved operator");
|
||||
|
||||
// push immediate
|
||||
@ -2368,7 +2384,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
||||
if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
|
||||
return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
|
||||
|
||||
classDefTable = classDef1ValueArray + 2 * glyphCount;
|
||||
// [DEAR IMGUI] Commented to fix static analyzer warning
|
||||
//classDefTable = classDef1ValueArray + 2 * glyphCount;
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
@ -2392,7 +2409,8 @@ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
|
||||
return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
|
||||
}
|
||||
|
||||
classDefTable = classRangeRecords + 6 * classRangeCount;
|
||||
// [DEAR IMGUI] Commented to fix static analyzer warning
|
||||
//classDefTable = classRangeRecords + 6 * classRangeCount;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
@ -3024,6 +3042,8 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
|
||||
dx = -dx;
|
||||
dy = -dy;
|
||||
t = x0, x0 = xb, xb = t;
|
||||
// [DEAR IMGUI] Fix static analyzer warning
|
||||
(void)dx; // [ImGui: fix static analyzer warning]
|
||||
}
|
||||
|
||||
x1 = (int) x_top;
|
||||
@ -3161,7 +3181,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
|
||||
if (e->y0 != e->y1) {
|
||||
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
|
||||
if (z != NULL) {
|
||||
STBTT_assert(z->ey >= scan_y_top);
|
||||
if (j == 0 && off_y != 0) {
|
||||
if (z->ey < scan_y_top) {
|
||||
// this can happen due to subpixel positioning and some kind of fp rounding error i think
|
||||
z->ey = scan_y_top;
|
||||
}
|
||||
}
|
||||
STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
|
||||
// insert at front
|
||||
z->next = active;
|
||||
active = z;
|
||||
@ -3230,7 +3256,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
|
||||
|
||||
static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
|
||||
{
|
||||
/* threshhold for transitioning to insertion sort */
|
||||
/* threshold for transitioning to insertion sort */
|
||||
while (n > 12) {
|
||||
stbtt__edge t;
|
||||
int c01,c12,c,m,i,j;
|
||||
@ -3365,7 +3391,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
|
||||
points[n].y = y;
|
||||
}
|
||||
|
||||
// tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
// tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
|
||||
static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
|
||||
{
|
||||
// midpoint
|
||||
@ -3790,6 +3816,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
|
||||
spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
|
||||
spc->h_oversample = 1;
|
||||
spc->v_oversample = 1;
|
||||
spc->skip_missing = 0;
|
||||
|
||||
stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
|
||||
|
||||
@ -3815,6 +3842,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
|
||||
spc->v_oversample = v_oversample;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
|
||||
{
|
||||
spc->skip_missing = skip;
|
||||
}
|
||||
|
||||
#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
|
||||
|
||||
static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
|
||||
@ -3968,6 +4000,9 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
||||
int x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
int glyph = stbtt_FindGlyphIndex(info, codepoint);
|
||||
if (glyph == 0 && spc->skip_missing) {
|
||||
rects[k].w = rects[k].h = 0;
|
||||
} else {
|
||||
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
|
||||
scale * spc->h_oversample,
|
||||
scale * spc->v_oversample,
|
||||
@ -3975,6 +4010,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
|
||||
&x0,&y0,&x1,&y1);
|
||||
rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
|
||||
rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
|
||||
}
|
||||
++k;
|
||||
}
|
||||
}
|
||||
@ -4027,7 +4063,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
|
||||
sub_y = stbtt__oversample_shift(spc->v_oversample);
|
||||
for (j=0; j < ranges[i].num_chars; ++j) {
|
||||
stbrp_rect *r = &rects[k];
|
||||
if (r->was_packed) {
|
||||
if (r->was_packed && r->w != 0 && r->h != 0) {
|
||||
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
|
||||
int advance, lsb, x0,y0,x1,y1;
|
||||
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
|
||||
@ -4141,6 +4177,19 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *
|
||||
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
|
||||
{
|
||||
int i_ascent, i_descent, i_lineGap;
|
||||
float scale;
|
||||
stbtt_fontinfo info;
|
||||
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
|
||||
scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
|
||||
stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
|
||||
*ascent = (float) i_ascent * scale;
|
||||
*descent = (float) i_descent * scale;
|
||||
*lineGap = (float) i_lineGap * scale;
|
||||
}
|
||||
|
||||
STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
|
||||
{
|
||||
float ipw = 1.0f / pw, iph = 1.0f / ph;
|
||||
@ -4253,7 +4302,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
|
||||
int winding = 0;
|
||||
|
||||
orig[0] = x;
|
||||
orig[1] = y;
|
||||
//orig[1] = y; // [DEAR IMGUI] commmented double assignment
|
||||
|
||||
// make sure y never passes through a vertex of the shape
|
||||
y_frac = (float) STBTT_fmod(y, 1.0f);
|
||||
|
@ -5,12 +5,13 @@
|
||||
// Changelog:
|
||||
// - v0.50: (2017/08/16) imported from https://github.com/Vuhdo/imgui_freetype into http://www.github.com/ocornut/imgui_club, updated for latest changes in ImFontAtlas, minor tweaks.
|
||||
// - v0.51: (2017/08/26) cleanup, optimizations, support for ImFontConfig::RasterizerFlags, ImFontConfig::RasterizerMultiply.
|
||||
// - v0.52: (2017/09/26) fixes for imgui internal changes
|
||||
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement)
|
||||
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member
|
||||
// - v0.52: (2017/09/26) fixes for imgui internal changes.
|
||||
// - v0.53: (2017/10/22) minor inconsequential change to match change in master (removed an unnecessary statement).
|
||||
// - v0.54: (2018/01/22) fix for addition of ImFontAtlas::TexUvscale member.
|
||||
// - v0.55: (2018/02/04) moved to main imgui repository (away from http://www.github.com/ocornut/imgui_club)
|
||||
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX
|
||||
// - v0.56: (2018/06/08) added support for ImFontConfig::GlyphMinAdvanceX, GlyphMaxAdvanceX.
|
||||
// - v0.60: (2019/01/10) re-factored to match big update in STB builder. fixed texture height waste. fixed redundant glyphs when merging. support for glyph padding.
|
||||
// - v0.61: (2019/01/15) added support for imgui allocators + added FreeType only override function SetAllocatorFunctions().
|
||||
|
||||
// Gamma Correct Blending:
|
||||
// FreeType assumes blending in linear space rather than gamma space.
|
||||
@ -18,7 +19,6 @@
|
||||
// For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||
// The default imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||
|
||||
// FIXME: FreeType's memory allocator is not overridden.
|
||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
||||
|
||||
#include "imgui_freetype.h"
|
||||
@ -26,6 +26,7 @@
|
||||
#include <stdint.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H // <freetype/freetype.h>
|
||||
#include FT_MODULE_H // <freetype/ftmodapi.h>
|
||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||
|
||||
@ -115,7 +116,6 @@ namespace
|
||||
|
||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_user_flags)
|
||||
{
|
||||
// FIXME: substitute allocator
|
||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||
if (error != 0)
|
||||
return false;
|
||||
@ -244,10 +244,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds)
|
||||
#define STBRP_ASSERT(x) IM_ASSERT(x)
|
||||
#define STBRP_STATIC
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "imstb_rectpack.h"
|
||||
#endif
|
||||
|
||||
struct ImFontBuildSrcGlyphFT
|
||||
{
|
||||
@ -334,15 +336,14 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
{
|
||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||
ImFontBuildDstDataFT& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||
src_tmp.GlyphsSet.Resize(src_tmp.GlyphsHighest + 1);
|
||||
if (dst_tmp.SrcCount > 1 && dst_tmp.GlyphsSet.Storage.empty())
|
||||
if (dst_tmp.GlyphsSet.Storage.empty())
|
||||
dst_tmp.GlyphsSet.Resize(dst_tmp.GlyphsHighest + 1);
|
||||
|
||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||
for (int codepoint = src_range[0]; codepoint <= src_range[1]; codepoint++)
|
||||
{
|
||||
if (cfg.MergeMode && dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
if (dst_tmp.GlyphsSet.GetBit(codepoint)) // Don't overwrite existing glyphs. We could make this an option (e.g. MergeOverwrite)
|
||||
continue;
|
||||
uint32_t glyph_index = FT_Get_Char_Index(src_tmp.Font.Face, codepoint); // It is actually in the font? (FIXME-OPT: We are not storing the glyph_index..)
|
||||
if (glyph_index == 0)
|
||||
@ -352,7 +353,6 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
src_tmp.GlyphsCount++;
|
||||
dst_tmp.GlyphsCount++;
|
||||
src_tmp.GlyphsSet.SetBit(codepoint, true);
|
||||
if (dst_tmp.SrcCount > 1)
|
||||
dst_tmp.GlyphsSet.SetBit(codepoint, true);
|
||||
total_glyphs_count++;
|
||||
}
|
||||
@ -566,15 +566,75 @@ bool ImFontAtlasBuildWithFreeType(FT_Library ft_library, ImFontAtlas* atlas, uns
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default memory allocators
|
||||
static void* ImFreeTypeDefaultAllocFunc(size_t size, void* user_data) { IM_UNUSED(user_data); return ImGui::MemAlloc(size); }
|
||||
static void ImFreeTypeDefaultFreeFunc(void* ptr, void* user_data) { IM_UNUSED(user_data); ImGui::MemFree(ptr); }
|
||||
|
||||
// Current memory allocators
|
||||
static void* (*GImFreeTypeAllocFunc)(size_t size, void* user_data) = ImFreeTypeDefaultAllocFunc;
|
||||
static void (*GImFreeTypeFreeFunc)(void* ptr, void* user_data) = ImFreeTypeDefaultFreeFunc;
|
||||
static void* GImFreeTypeAllocatorUserData = NULL;
|
||||
|
||||
// FreeType memory allocation callbacks
|
||||
static void* FreeType_Alloc(FT_Memory /*memory*/, long size)
|
||||
{
|
||||
return GImFreeTypeAllocFunc((size_t)size, GImFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void FreeType_Free(FT_Memory /*memory*/, void* block)
|
||||
{
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
}
|
||||
|
||||
static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size, void* block)
|
||||
{
|
||||
// Implement realloc() as we don't ask user to provide it.
|
||||
if (block == NULL)
|
||||
return GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
|
||||
|
||||
if (new_size == 0)
|
||||
{
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (new_size > cur_size)
|
||||
{
|
||||
void* new_block = GImFreeTypeAllocFunc((size_t)new_size, GImFreeTypeAllocatorUserData);
|
||||
memcpy(new_block, block, (size_t)cur_size);
|
||||
GImFreeTypeFreeFunc(block, GImFreeTypeAllocatorUserData);
|
||||
return new_block;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
|
||||
{
|
||||
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
|
||||
FT_MemoryRec_ memory_rec = { 0 };
|
||||
memory_rec.alloc = &FreeType_Alloc;
|
||||
memory_rec.free = &FreeType_Free;
|
||||
memory_rec.realloc = &FreeType_Realloc;
|
||||
|
||||
// https://www.freetype.org/freetype2/docs/reference/ft2-module_management.html#FT_New_Library
|
||||
FT_Library ft_library;
|
||||
FT_Error error = FT_Init_FreeType(&ft_library);
|
||||
FT_Error error = FT_New_Library(&memory_rec, &ft_library);
|
||||
if (error != 0)
|
||||
return false;
|
||||
|
||||
// If you don't call FT_Add_Default_Modules() the rest of code may work, but FreeType won't use our custom allocator.
|
||||
FT_Add_Default_Modules(ft_library);
|
||||
|
||||
bool ret = ImFontAtlasBuildWithFreeType(ft_library, atlas, extra_flags);
|
||||
FT_Done_FreeType(ft_library);
|
||||
FT_Done_Library(ft_library);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ImGuiFreeType::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
|
||||
{
|
||||
GImFreeTypeAllocFunc = alloc_func;
|
||||
GImFreeTypeFreeFunc = free_func;
|
||||
GImFreeTypeAllocatorUserData = user_data;
|
||||
}
|
||||
|
@ -28,4 +28,8 @@ namespace ImGuiFreeType
|
||||
};
|
||||
|
||||
IMGUI_API bool BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags = 0);
|
||||
|
||||
// By default ImGuiFreeType will use ImGui::MemAlloc()/MemFree().
|
||||
// However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired:
|
||||
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
|
||||
}
|
||||
|
@ -265,31 +265,13 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_NewFrame()
|
||||
static void ImGui_ImplGlfw_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
glfwGetWindowSize(g_Window, &w, &h);
|
||||
glfwGetFramebufferSize(g_Window, &display_w, &display_h);
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
|
||||
|
||||
// Setup time step
|
||||
double current_time = glfwGetTime();
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
ImGui_ImplGlfw_UpdateMousePosAndButtons();
|
||||
ImGui_ImplGlfw_UpdateMouseCursor();
|
||||
|
||||
// Gamepad navigation mapping [BETA]
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad)
|
||||
{
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Update gamepad inputs
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, AXIS_NO, V0, V1) { float v = (axes_count > AXIS_NO) ? axes[AXIS_NO] : V0; v = (v - V0) / (V1 - V0); if (v > 1.0f) v = 1.0f; if (io.NavInputs[NAV_NO] < v) io.NavInputs[NAV_NO] = v; }
|
||||
@ -318,5 +300,29 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
else
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
glfwGetWindowSize(g_Window, &w, &h);
|
||||
glfwGetFramebufferSize(g_Window, &display_w, &display_h);
|
||||
io.DisplaySize = ImVec2((float)w, (float)h);
|
||||
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0);
|
||||
|
||||
// Setup time step
|
||||
double current_time = glfwGetTime();
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f);
|
||||
g_Time = current_time;
|
||||
|
||||
ImGui_ImplGlfw_UpdateMousePosAndButtons();
|
||||
ImGui_ImplGlfw_UpdateMouseCursor();
|
||||
|
||||
// Gamepad navigation mapping
|
||||
ImGui_ImplGlfw_UpdateGamepads();
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
||||
// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT).
|
||||
// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
|
||||
@ -136,12 +138,10 @@ void ImGui_ImplOpenGL3_NewFrame()
|
||||
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
||||
|
||||
// Backup GL state
|
||||
GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint*)&last_active_texture);
|
||||
@ -219,12 +219,15 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
|
||||
glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col));
|
||||
|
||||
// Draw
|
||||
ImVec2 pos = draw_data->DisplayPos;
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawIdx* idx_buffer_offset = 0;
|
||||
size_t idx_buffer_offset = 0;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
|
||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
|
||||
@ -242,7 +245,13 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
}
|
||||
else
|
||||
{
|
||||
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec4 clip_rect;
|
||||
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
||||
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||
{
|
||||
// Apply scissor/clipping rectangle
|
||||
@ -253,10 +262,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Bind texture, Draw
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)idx_buffer_offset);
|
||||
}
|
||||
}
|
||||
idx_buffer_offset += pcmd->ElemCount;
|
||||
idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
|
||||
}
|
||||
}
|
||||
glDeleteVertexArrays(1, &vao_handle);
|
||||
@ -477,7 +486,7 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
vertex_shader = vertex_shader_glsl_120;
|
||||
fragment_shader = fragment_shader_glsl_120;
|
||||
}
|
||||
else if (glsl_version == 410)
|
||||
else if (glsl_version >= 410)
|
||||
{
|
||||
vertex_shader = vertex_shader_glsl_410_core;
|
||||
fragment_shader = fragment_shader_glsl_410_core;
|
||||
|
Loading…
Reference in New Issue
Block a user