Update ImGui to 1.92.2b

This commit is contained in:
TryTwo
2025-08-12 01:23:54 -07:00
parent 8a8d15799c
commit 7315acb981
10 changed files with 8125 additions and 4125 deletions

View File

@@ -1,139 +1,216 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DEAR IMGUI COMPILE-TIME OPTIONS // DEAR IMGUI COMPILE-TIME OPTIONS
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure. // Runtime options (clipboard callbacks, enabling various features, etc.) can
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions. // generally be set via the ImGuiIO structure. You can use
// ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to
// rewire memory allocation functions.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it) // A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template. // maintain a patch/rebased branch with your modifications to it) B) or '#define
// IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add
// directives in your own file without touching this template.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp // You need to make sure that configuration settings are defined consistently
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures. // _everywhere_ Dear ImGui is used, which include the imgui*.cpp files but also
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. // _any_ of your code that uses Dear ImGui. This is because some compile-time
// Call IMGUI_CHECKVERSION() from your .cpp file to verify that the data structures your files are using are matching the ones imgui.cpp is using. // options have an affect on data structures. Defining those options in
// imconfig.h will ensure every compilation unit gets to see the same data
// structure layouts. Call IMGUI_CHECKVERSION() from your .cpp file to verify
// that the data structures your files are using are matching the ones imgui.cpp
// is using.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#pragma once #pragma once
#include "Common/Assert.h"
//---- Define assertion handler. Defaults to calling assert(). //---- Define assertion handler. Defaults to calling assert().
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement. // If your macro uses multiple statements, make sure is enclosed in a 'do { .. }
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR) // while (0)' block so it can be used as a single statement.
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts #define IM_ASSERT(_EXPR) ASSERT(_EXPR)
// #define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows //---- Define attributes of all API symbols declarations, e.g. for DLL under
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. // Windows
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions() // Using Dear ImGui via a shared library is not recommended, because of function
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details. // call overhead and because we don't guarantee backward nor forward ABI
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export // compatibility.
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import // - Windows DLL users: heaps and globals are not shared across DLL boundaries!
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden // You will need to call SetCurrentContext() + SetAllocatorFunctions()
// for each static/DLL boundary you are calling from. Read "Context and Memory
// Allocators" section of imgui.cpp for more details.
// #define IMGUI_API __declspec(dllexport) // MSVC Windows:
// DLL export #define IMGUI_API __declspec(dllimport) // MSVC
// Windows: DLL import #define IMGUI_API __attribute__((visibility("default")))
// // GCC/Clang: override visibility when set is hidden
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names. //---- Don't define obsolete functions/enums/behaviors. Consider enabling from
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS // time to time after updating to clean your code of obsolete function/names.
// #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
//---- Disable all of Dear ImGui or don't implement standard windows/tools. //---- Disable all of Dear ImGui or don't implement standard windows/tools.
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows and debug
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty. // tool during development. They are extremely useful in day to day work. Please
#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. // read comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty. // #define IMGUI_DISABLE // Disable
// everything: all headers and source files will be empty.
#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows:
// ShowDemoWindow()/ShowStyleEditor() will be
// empty.
// #define IMGUI_DISABLE_DEBUG_TOOLS // Disable
// metrics/debugger and other debug tools: ShowMetricsWindow(),
// ShowDebugLogWindow() and ShowIDStackToolWindow() will be empty.
//---- Don't implement some functions to reduce linkage requirements. //---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a) // #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW) // implement default clipboard handler. Won't use and link with
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a) // OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a,
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME). // kernel32.lib/.a) #define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS //
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default). // [Win32] [Default with Visual Studio] Implement default IME handler (require
//#define IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")). // imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf) // #define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself. // with non-Visual Studio compilers] Don't implement default IME handler (won't
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies) // require imm32.lib/.a) #define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function. // use and link with any Win32 function (clipboard, IME). #define
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). // IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault() will assert. // OSX clipboard handler (need to link with '-framework ApplicationServices',
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available // this is why this is not the default). #define
// IMGUI_DISABLE_DEFAULT_SHELL_FUNCTIONS // Don't implement default
// platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require
// shell32.lib/.a, Mac/Linux: use system("")). #define
// IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement
// ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if
// you don't want to link with vsnprintf) #define
// IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement
// ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement
// them yourself. #define IMGUI_DISABLE_FILE_FUNCTIONS //
// Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and
// ImFileHandle at all (replace them with dummies) #define
// IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement
// ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can
// implement them yourself if you don't want to link with
// fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
// #define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement
// default allocators calling malloc()/free() to avoid linking with them. You
// will need to call ImGui::SetAllocatorFunctions(). #define
// IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded
// font (ProggyClean.ttf), remove ~9.5 KB from output binary. AddFontDefault()
// will assert. #define IMGUI_DISABLE_SSE //
// Disable use of SSE intrinsics even if available
//---- Enable Test Engine / Automation features. //---- Enable Test Engine / Automation features.
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details. // #define IMGUI_ENABLE_TEST_ENGINE // Enable
// imgui_test_engine hooks. Generally set automatically by include
// "imgui_te_config.h", see Test Engine for details.
//---- Include imgui_user.h at the end of imgui.h as a convenience //---- Include imgui_user.h at the end of imgui.h as a convenience
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included. // May be convenient for some users to only explicitly include vanilla imgui.h
//#define IMGUI_INCLUDE_IMGUI_USER_H // and have extra stuff included.
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h" // #define IMGUI_INCLUDE_IMGUI_USER_H
// #define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support. //---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from
//#define IMGUI_USE_BGRA_PACKED_COLOR // one to another). Need dedicated backend support. #define
// IMGUI_USE_BGRA_PACKED_COLOR
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate. //---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve
//#define IMGUI_USE_LEGACY_CRC32_ADLER // old .ini data that you cannot afford to invalidate. #define
// IMGUI_USE_LEGACY_CRC32_ADLER
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...) //---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes
//#define IMGUI_USE_WCHAR32 // 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes,
// ancient languages, etc...) #define IMGUI_USE_WCHAR32
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version //---- Avoid multiple STB libraries implementations, or redefine path/filenames
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files. // to prioritize another version
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" // By default the embedded implementations are declared static and not available
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" // outside of Dear ImGui sources files.
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined. // #define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION // #define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION // #define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined. // used if IMGUI_USE_STB_SPRINTF is defined. #define
// IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION #define
// IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #define
// IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled
// if IMGUI_USE_STB_SPRINTF is defined.
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined) //---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h. // one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
//#define IMGUI_USE_STB_SPRINTF // Compatibility checks of arguments and formats done by clang and GCC will be
// disabled in order to support the extra formats provided by stb_sprintf.h.
// #define IMGUI_USE_STB_SPRINTF
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) //---- Use FreeType to build and rasterize the font atlas (instead of
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). // stb_truetype which is embedded by default in Dear ImGui)
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. // Requires FreeType headers to be available in the include path. Requires
//#define IMGUI_ENABLE_FREETYPE // program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this
// repository) + the FreeType library (not provided). On Windows you may use
// vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate
// install'.
// #define IMGUI_ENABLE_FREETYPE
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT) //---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
// Only works in combination with IMGUI_ENABLE_FREETYPE. // Only works in combination with IMGUI_ENABLE_FREETYPE.
// - lunasvg is currently easier to acquire/install, as e.g. it is part of vcpkg. // - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It
// - plutosvg will support more fonts and may load them faster. It currently requires to be built manually but it is fairly easy. See misc/freetype/README for instructions. // will support more fonts and may load them faster. See misc/freetype/README
// - Both require headers to be available in the include path + program to be linked with the library code (not provided). // for instructions.
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement) // - Both require headers to be available in the include path + program to be
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG // linked with the library code (not provided).
//#define IMGUI_ENABLE_FREETYPE_LUNASVG // - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is
// licensed under CeCILL-C Free Software License Agreement)
// #define IMGUI_ENABLE_FREETYPE_PLUTOSVG
// #define IMGUI_ENABLE_FREETYPE_LUNASVG
//---- Use stb_truetype to build and rasterize the font atlas (default) //---- Use stb_truetype to build and rasterize the font atlas (default)
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. // The only purpose of this define is if you want force compilation of the
//#define IMGUI_ENABLE_STB_TRUETYPE // stb_truetype backend ALONG with the FreeType backend.
// #define IMGUI_ENABLE_STB_TRUETYPE
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. //---- Define constructor and implicit cast operators to convert back<>forth
// between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations. // This will be inlined as part of ImVec2 and ImVec4 class declarations.
/* /*
#define IM_VEC2_CLASS_EXTRA \ #define IM_VEC2_CLASS_EXTRA \
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \ operator
operator MyVec2() const { return MyVec2(x,y); } MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \ #define IM_VEC4_CLASS_EXTRA \
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \ constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
operator MyVec4() const { return MyVec4(x,y,z,w); } operator MyVec4() const { return MyVec4(x,y,z,w); }
*/ */
//---- ...Or use Dear ImGui's own very basic math operators. //---- ...Or use Dear ImGui's own very basic math operators.
//#define IMGUI_DEFINE_MATH_OPERATORS // #define IMGUI_DEFINE_MATH_OPERATORS
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices. //---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices). // meshes with more than 64K vertices.
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer. // Your renderer backend will need to support it (most example renderer backends
// support both 16/32-bit indices). Another way to allow large meshes while
// keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details. // Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
//#define ImDrawIdx unsigned int // #define ImDrawIdx unsigned int
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly) //---- Override ImDrawCallback signature (will need to modify renderer backends
//struct ImDrawList; // accordingly) struct ImDrawList; struct ImDrawCmd; typedef void
//struct ImDrawCmd; // (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void*
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); // my_renderer_user_data); #define ImDrawCallback MyImDrawCallback
//#define ImDrawCallback MyImDrawCallback
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase) //---- Debug Tools: Macro to break in Debugger (we provide a default
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.) // implementation of this in the codebase)
//#define IM_DEBUG_BREAK IM_ASSERT(0) // (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break
//#define IM_DEBUG_BREAK __debugbreak() // into them for easy debugging.)
// #define IM_DEBUG_BREAK IM_ASSERT(0)
// #define IM_DEBUG_BREAK __debugbreak()
//---- Debug Tools: Enable highlight ID conflicts _before_ hovering items. When
// io.ConfigDebugHighlightIdConflicts is set.
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
// #define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
//---- Debug Tools: Enable slower asserts //---- Debug Tools: Enable slower asserts
//#define IMGUI_DEBUG_PARANOID // #define IMGUI_DEBUG_PARANOID
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files) //---- Tip: You can add extra functions within the ImGui:: namespace from
// anywhere (e.g. your own sources/header files)
/* /*
namespace ImGui namespace ImGui
{ {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
// dear imgui, v1.91.7 // dear imgui, v1.92.2b
// (tables and columns code) // (tables and columns code)
/* /*
@@ -221,6 +221,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
#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 "-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" // warning: format specifies type 'int' but the argument has type 'unsigned int'
#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 "-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 #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
@@ -230,6 +231,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type #pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe #pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
@@ -340,6 +342,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
{ {
ItemSize(outer_rect); ItemSize(outer_rect);
ItemAdd(outer_rect, id); ItemAdd(outer_rect, id);
g.NextWindowData.ClearFlags();
return false; return false;
} }
@@ -374,6 +377,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->ColumnsCount = columns_count; table->ColumnsCount = columns_count;
table->IsLayoutLocked = false; table->IsLayoutLocked = false;
table->InnerWidth = inner_width; table->InnerWidth = inner_width;
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
temp_data->UserOuterSize = outer_size; temp_data->UserOuterSize = outer_size;
// Instance data (for instance 0, TableID == TableInstanceID) // Instance data (for instance 0, TableID == TableInstanceID)
@@ -414,12 +418,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Reset scroll if we are reactivating it // Reset scroll if we are reactivating it
if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0) if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasScroll) == 0) if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasScroll) == 0)
SetNextWindowScroll(ImVec2(0.0f, 0.0f)); SetNextWindowScroll(ImVec2(0.0f, 0.0f));
// Create scrolling region (without border and zero window padding) // Create scrolling region (without border and zero window padding)
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None; ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags); ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None;
if (flags & ImGuiTableFlags_ScrollX)
child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar;
BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags);
table->InnerWindow = g.CurrentWindow; table->InnerWindow = g.CurrentWindow;
table->WorkRect = table->InnerWindow->WorkRect; table->WorkRect = table->InnerWindow->WorkRect;
table->OuterRect = table->InnerWindow->Rect(); table->OuterRect = table->InnerWindow->Rect();
@@ -444,6 +451,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable(). // But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect; table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false; table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
table->InnerWindow->DC.TreeDepth++; // This is designed to always linking ImGuiTreeNodeFlags_DrawLines linking accross a table
} }
// Push a standardized ID for both child-using and not-child-using tables // Push a standardized ID for both child-using and not-child-using tables
@@ -534,7 +542,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Make table current // Make table current
g.CurrentTable = table; g.CurrentTable = table;
outer_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX(); inner_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
outer_window->DC.CurrentTableIdx = table_idx; outer_window->DC.CurrentTableIdx = table_idx;
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
inner_window->DC.CurrentTableIdx = table_idx; inner_window->DC.CurrentTableIdx = table_idx;
@@ -572,6 +580,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Initialize // Initialize
table->SettingsOffset = -1; table->SettingsOffset = -1;
table->IsSortSpecsDirty = true; table->IsSortSpecsDirty = true;
table->IsSettingsDirty = true; // Records itself into .ini file even when in default state (#7934)
table->InstanceInteracted = -1; table->InstanceInteracted = -1;
table->ContextPopupColumn = -1; table->ContextPopupColumn = -1;
table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1; table->ReorderColumn = table->ResizedColumn = table->LastResizedColumn = -1;
@@ -971,7 +980,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 4] Apply final widths based on requested widths // [Part 4] Apply final widths based on requested widths
const ImRect work_rect = table->WorkRect; const ImRect work_rect = table->WorkRect;
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920) const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synced tables with mismatching scrollbar state (#5920)
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed); const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
@@ -1050,7 +1059,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen // Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
if (offset_x_frozen && table->FreezeColumnsCount == visible_n) if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
{ {
@@ -1241,7 +1251,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 11] Default context menu // [Part 11] Default context menu
// - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup(). // - To append to this menu: you can call TableBeginContextMenuPopup()/.../EndPopup().
// - To modify or replace this: set table->IsContextPopupNoDefaultContents = true, then call TableBeginContextMenuPopup()/.../EndPopup(). // - To modify or replace this: set table->DisableDefaultContextMenu = true, then call TableBeginContextMenuPopup()/.../EndPopup().
// - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu, // - You may call TableDrawDefaultContextMenu() with selected flags to display specific sections of the default menu,
// e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options. // e.g. TableDrawDefaultContextMenu(table, table->Flags & ~ImGuiTableFlags_Hideable) will display everything EXCEPT columns visibility options.
if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table)) if (table->DisableDefaultContextMenu == false && TableBeginContextMenuPopup(table))
@@ -1383,7 +1393,7 @@ void ImGui::EndTable()
// Setup inner scrolling range // Setup inner scrolling range
// FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y, // FIXME: This ideally should be done earlier, in BeginTable() SetNextWindowContentSize call, just like writing to inner_window->DC.CursorMaxPos.y,
// but since the later is likely to be impossible to do we'd rather update both axises together. // but since the later is likely to be impossible to do we'd rather update both axes together.
if (table->Flags & ImGuiTableFlags_ScrollX) if (table->Flags & ImGuiTableFlags_ScrollX)
{ {
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f; const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
@@ -1493,7 +1503,7 @@ void ImGui::EndTable()
if (inner_window != outer_window) if (inner_window != outer_window)
{ {
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask; short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently. inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
g.CurrentTable = NULL; // To avoid error recovery recursing g.CurrentTable = NULL; // To avoid error recovery recursing
EndChild(); EndChild();
g.CurrentTable = table; g.CurrentTable = table;
@@ -1501,6 +1511,7 @@ void ImGui::EndTable()
} }
else else
{ {
table->InnerWindow->DC.TreeDepth--;
ItemSize(table->OuterRect.GetSize()); ItemSize(table->OuterRect.GetSize());
ItemAdd(table->OuterRect, 0); ItemAdd(table->OuterRect, 0);
} }
@@ -1558,6 +1569,31 @@ void ImGui::EndTable()
NavUpdateCurrentWindowIsScrollPushableX(); NavUpdateCurrentWindowIsScrollPushableX();
} }
// Called in TableSetupColumn() when initializing and in TableLoadSettings() for defaults before applying stored settings.
// 'init_mask' specify which fields to initialize.
static void TableInitColumnDefaults(ImGuiTable* table, ImGuiTableColumn* column, ImGuiTableColumnFlags init_mask)
{
ImGuiTableColumnFlags flags = column->Flags;
if (init_mask & ImGuiTableFlags_Resizable)
{
float init_width_or_weight = column->InitStretchWeightOrWidth;
column->WidthRequest = ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
column->StretchWeight = (init_width_or_weight > 0.0f && (flags & ImGuiTableColumnFlags_WidthStretch)) ? init_width_or_weight : -1.0f;
if (init_width_or_weight > 0.0f) // Disable auto-fit if an explicit width/weight has been specified
column->AutoFitQueue = 0x00;
}
if (init_mask & ImGuiTableFlags_Reorderable)
column->DisplayOrder = (ImGuiTableColumnIdx)table->Columns.index_from_ptr(column);
if (init_mask & ImGuiTableFlags_Hideable)
column->IsUserEnabled = column->IsUserEnabledNextFrame = (flags & ImGuiTableColumnFlags_DefaultHide) ? 0 : 1;
if (init_mask & ImGuiTableFlags_Sortable)
{
// Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
column->SortOrder = (flags & ImGuiTableColumnFlags_DefaultSort) ? 0 : -1;
column->SortDirection = (flags & ImGuiTableColumnFlags_DefaultSort) ? ((flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending)) : (ImS8)ImGuiSortDirection_None;
}
}
// See "COLUMNS SIZING POLICIES" comments at the top of this file // See "COLUMNS SIZING POLICIES" comments at the top of this file
// If (init_width_or_weight <= 0.0f) it is ignored // If (init_width_or_weight <= 0.0f) it is ignored
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
@@ -1586,7 +1622,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column."); IM_ASSERT(init_width_or_weight <= 0.0f && "Can only specify width/weight if sizing policy is set explicitly in either Table or Column.");
// When passing a width automatically enforce WidthFixed policy // When passing a width automatically enforce WidthFixed policy
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable) // (whereas TableSetupColumnFlags would default to WidthAuto if table is not resizable)
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f) if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame) if ((table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (table->Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
flags |= ImGuiTableColumnFlags_WidthFixed; flags |= ImGuiTableColumnFlags_WidthFixed;
@@ -1604,27 +1640,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
column->InitStretchWeightOrWidth = init_width_or_weight; column->InitStretchWeightOrWidth = init_width_or_weight;
if (table->IsInitializing) if (table->IsInitializing)
{ {
// Init width or weight ImGuiTableFlags init_flags = ~table->SettingsLoadedFlags;
if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f) if (column->WidthRequest < 0.0f && column->StretchWeight < 0.0f)
{ init_flags |= ImGuiTableFlags_Resizable;
if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f) TableInitColumnDefaults(table, column, init_flags);
column->WidthRequest = init_width_or_weight;
if (flags & ImGuiTableColumnFlags_WidthStretch)
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
// Disable auto-fit if an explicit width/weight has been specified
if (init_width_or_weight > 0.0f)
column->AutoFitQueue = 0x00;
}
// Init default visibility/sort state
if ((flags & ImGuiTableColumnFlags_DefaultHide) && (table->SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
column->IsUserEnabled = column->IsUserEnabledNextFrame = false;
if (flags & ImGuiTableColumnFlags_DefaultSort && (table->SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0)
{
column->SortOrder = 0; // Multiple columns using _DefaultSort will be reassigned unique SortOrder values when building the sort specs.
column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending);
}
} }
// Store name (append with zero-terminator in contiguous buffer) // Store name (append with zero-terminator in contiguous buffer)
@@ -1633,7 +1652,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
if (label != NULL && label[0] != 0) if (label != NULL && label[0] != 0)
{ {
column->NameOffset = (ImS16)table->ColumnsNames.size(); column->NameOffset = (ImS16)table->ColumnsNames.size();
table->ColumnsNames.append(label, label + strlen(label) + 1); table->ColumnsNames.append(label, label + ImStrlen(label) + 1);
} }
} }
@@ -1806,6 +1825,11 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable; ImGuiTable* table = g.CurrentTable;
IM_ASSERT(target != ImGuiTableBgTarget_None); IM_ASSERT(target != ImGuiTableBgTarget_None);
if (table == NULL)
{
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
return;
}
if (color == IM_COL32_DISABLE) if (color == IM_COL32_DISABLE)
color = 0; color = 0;
@@ -1934,7 +1958,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
IM_ASSERT(table->IsInsideRow); IM_ASSERT(table->IsInsideRow);
if (table->CurrentColumn != -1) if (table->CurrentColumn != -1)
{
TableEndCell(table); TableEndCell(table);
table->CurrentColumn = -1;
}
// Logging // Logging
if (g.LogEnabled) if (g.LogEnabled)
@@ -2032,7 +2059,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (unfreeze_rows_request) if (unfreeze_rows_request)
{ {
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main; table->Columns[column_n].NavLayerCurrent = table->NavLayer;
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y); const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y; table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
@@ -2099,7 +2126,11 @@ bool ImGui::TableSetColumnIndex(int column_n)
{ {
if (table->CurrentColumn != -1) if (table->CurrentColumn != -1)
TableEndCell(table); TableEndCell(table);
IM_ASSERT(column_n >= 0 && table->ColumnsCount); if ((column_n >= 0 && column_n < table->ColumnsCount) == false)
{
IM_ASSERT_USER_ERROR(column_n >= 0 && column_n < table->ColumnsCount, "TableSetColumnIndex() invalid column index!");
return false;
}
TableBeginCell(table, column_n); TableBeginCell(table, column_n);
} }
@@ -2170,6 +2201,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
g.LastItemData.StatusFlags = 0; g.LastItemData.StatusFlags = 0;
} }
// Also see TablePushColumnChannel()
if (table->Flags & ImGuiTableFlags_NoClip) if (table->Flags & ImGuiTableFlags_NoClip)
{ {
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed. // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
@@ -2443,10 +2475,38 @@ void ImGui::TablePopBackgroundChannel()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
ImGuiTable* table = g.CurrentTable; ImGuiTable* table = g.CurrentTable;
ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
// Optimization: avoid PopClipRect() + SetCurrentChannel() // Optimization: avoid PopClipRect() + SetCurrentChannel()
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect); SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[table->CurrentColumn].DrawChannelCurrent);
}
// Also see TableBeginCell()
void ImGui::TablePushColumnChannel(int column_n)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
// Optimization: avoid SetCurrentChannel() + PushClipRect()
if (table->Flags & ImGuiTableFlags_NoClip)
return;
ImGuiWindow* window = g.CurrentWindow;
const ImGuiTableColumn* column = &table->Columns[column_n];
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
}
void ImGui::TablePopColumnChannel()
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
// Optimization: avoid PopClipRect() + SetCurrentChannel()
if ((table->Flags & ImGuiTableFlags_NoClip) || (table->CurrentColumn == -1)) // Calling TreePop() after TableNextRow() is supported.
return;
ImGuiWindow* window = g.CurrentWindow;
const ImGuiTableColumn* column = &table->Columns[table->CurrentColumn];
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
} }
@@ -2821,9 +2881,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable; ImGuiTable* table = g.CurrentTable;
IM_ASSERT(table != NULL); if (table == NULL || !(table->Flags & ImGuiTableFlags_Sortable))
if (!(table->Flags & ImGuiTableFlags_Sortable))
return NULL; return NULL;
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths. // Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
@@ -3223,7 +3281,7 @@ void ImGui::TableHeader(const char* label)
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will // Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
// be merged into a single draw call. // be merged into a single draw call.
//window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE); //window->DrawList->AddCircleFilled(ImVec2(ellipsis_max, label_pos.y), 40, IM_COL32_WHITE);
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label, label_end, &label_size); RenderTextEllipsis(window->DrawList, label_pos, ImVec2(ellipsis_max, bb.Max.y), ellipsis_max, label, label_end, &label_size);
const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x); const bool text_clipped = label_size.x > (ellipsis_max - label_pos.x);
if (text_clipped && hovered && g.ActiveId == 0) if (text_clipped && hovered && g.ActiveId == 0)
@@ -3320,7 +3378,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
ButtonBehavior(row_r, row_id, NULL, NULL); ButtonBehavior(row_r, row_id, NULL, NULL);
KeepAliveID(row_id); KeepAliveID(row_id);
const float ascent_scaled = g.Font->Ascent * g.FontScale; // FIXME: Standardize those scaling factors better const float ascent_scaled = g.FontBaked->Ascent * g.FontBakedScale; // FIXME: Standardize those scaling factors better
const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f); const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f);
const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component
const ImVec2 align = g.Style.TableAngledHeadersTextAlign; const ImVec2 align = g.Style.TableAngledHeadersTextAlign;
@@ -3375,7 +3433,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height)); ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height));
int vtx_idx_begin = draw_list->_VtxCurrentIdx; int vtx_idx_begin = draw_list->_VtxCurrentIdx;
PushStyleColor(ImGuiCol_Text, request->TextColor); PushStyleColor(ImGuiCol_Text, request->TextColor);
RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size); RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, label_name, label_name_eol, &label_size);
PopStyleColor(); PopStyleColor();
int vtx_idx_end = draw_list->_VtxCurrentIdx; int vtx_idx_end = draw_list->_VtxCurrentIdx;
@@ -3712,6 +3770,14 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
table->SettingsLoadedFlags = settings->SaveFlags; table->SettingsLoadedFlags = settings->SaveFlags;
table->RefScale = settings->RefScale; table->RefScale = settings->RefScale;
// Initialize default columns settings
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{
ImGuiTableColumn* column = &table->Columns[column_n];
TableInitColumnDefaults(table, column, ~0);
column->AutoFitQueue = 0x00;
}
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
ImU64 display_order_mask = 0; ImU64 display_order_mask = 0;
@@ -3728,14 +3794,12 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
column->StretchWeight = column_settings->WidthOrWeight; column->StretchWeight = column_settings->WidthOrWeight;
else else
column->WidthRequest = column_settings->WidthOrWeight; column->WidthRequest = column_settings->WidthOrWeight;
column->AutoFitQueue = 0x00;
} }
if (settings->SaveFlags & ImGuiTableFlags_Reorderable) if (settings->SaveFlags & ImGuiTableFlags_Reorderable)
column->DisplayOrder = column_settings->DisplayOrder; column->DisplayOrder = column_settings->DisplayOrder;
else
column->DisplayOrder = (ImGuiTableColumnIdx)column_n;
display_order_mask |= (ImU64)1 << column->DisplayOrder; display_order_mask |= (ImU64)1 << column->DisplayOrder;
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled; if ((settings->SaveFlags & ImGuiTableFlags_Hideable) && column_settings->IsEnabled != -1)
column->IsUserEnabled = column->IsUserEnabledNextFrame = column_settings->IsEnabled == 1;
column->SortOrder = column_settings->SortOrder; column->SortOrder = column_settings->SortOrder;
column->SortDirection = column_settings->SortDirection; column->SortDirection = column_settings->SortDirection;
} }
@@ -3831,8 +3895,7 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0; const bool save_visible = (settings->SaveFlags & ImGuiTableFlags_Hideable) != 0;
const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0; const bool save_order = (settings->SaveFlags & ImGuiTableFlags_Reorderable) != 0;
const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0; const bool save_sort = (settings->SaveFlags & ImGuiTableFlags_Sortable) != 0;
if (!save_size && !save_visible && !save_order && !save_sort) // We need to save the [Table] entry even if all the bools are false, since this records a table with "default settings".
continue;
buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve buf->reserve(buf->size() + 30 + settings->ColumnsCount * 50); // ballpark reserve
buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount); buf->appendf("[%s][0x%08X,%d]\n", handler->TypeName, settings->ID, settings->ColumnsCount);

File diff suppressed because it is too large Load Diff

View File

@@ -141,6 +141,7 @@
// with previous char) // with previous char)
// STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character // STB_TEXTEDIT_KEYTOTEXT(k) maps a keyboard input to an insertable character
// (return type is int, -1 means not valid to insert) // (return type is int, -1 means not valid to insert)
// (not supported if you want to use UTF-8, see below)
// STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based // STB_TEXTEDIT_GETCHAR(obj,i) returns the i'th character of obj, 0-based
// STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize // STB_TEXTEDIT_NEWLINE the character returned by _GETCHAR() we recognize
// as manually wordwrapping for end-of-line positioning // as manually wordwrapping for end-of-line positioning
@@ -178,6 +179,13 @@
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text // STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text // STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
// //
// To support UTF-8:
//
// STB_TEXTEDIT_GETPREVCHARINDEX returns index of previous character
// STB_TEXTEDIT_GETNEXTCHARINDEX returns index of next character
// Do NOT define STB_TEXTEDIT_KEYTOTEXT.
// Instead, call stb_textedit_text() directly for text contents.
//
// Keyboard input must be encoded as a single integer value; e.g. a character code // Keyboard input must be encoded as a single integer value; e.g. a character code
// and some bitflags that represent shift states. to simplify the interface, SHIFT must // and some bitflags that represent shift states. to simplify the interface, SHIFT must
// be a bitflag, so we can test the shifted state of cursor movements to allow selection, // be a bitflag, so we can test the shifted state of cursor movements to allow selection,
@@ -250,8 +258,10 @@
// if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are // if the STB_TEXTEDIT_KEYTOTEXT function is defined, selected keys are
// transformed into text and stb_textedit_text() is automatically called. // transformed into text and stb_textedit_text() is automatically called.
// //
// text: [DEAR IMGUI] added 2024-09 // text: (added 2025)
// call this to text inputs sent to the textfield. // call this to directly send text input the textfield, which is required
// for UTF-8 support, because stb_textedit_key() + STB_TEXTEDIT_KEYTOTEXT()
// cannot infer text length.
// //
// //
// When rendering, you can read the cursor position and selection state from // When rendering, you can read the cursor position and selection state from
@@ -400,6 +410,16 @@ typedef struct
#define IMSTB_TEXTEDIT_memmove memmove #define IMSTB_TEXTEDIT_memmove memmove
#endif #endif
// [DEAR IMGUI]
// Functions must be implemented for UTF8 support
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(OBJ, IDX) ((IDX) - 1)
#endif
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(OBJ, IDX) ((IDX) + 1)
#endif
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
@@ -648,17 +668,6 @@ static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditSt
} }
} }
// [DEAR IMGUI]
// Functions must be implemented for UTF8 support
// Code in this file that uses those functions is modified for [DEAR IMGUI] and deviates from the original stb_textedit.
// There is not necessarily a '[DEAR IMGUI]' at the usage sites.
#ifndef IMSTB_TEXTEDIT_GETPREVCHARINDEX
#define IMSTB_TEXTEDIT_GETPREVCHARINDEX(obj, idx) (idx - 1)
#endif
#ifndef IMSTB_TEXTEDIT_GETNEXTCHARINDEX
#define IMSTB_TEXTEDIT_GETNEXTCHARINDEX(obj, idx) (idx + 1)
#endif
#ifdef STB_TEXTEDIT_IS_SPACE #ifdef STB_TEXTEDIT_IS_SPACE
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx ) static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
{ {
@@ -668,9 +677,9 @@ static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
#ifndef STB_TEXTEDIT_MOVEWORDLEFT #ifndef STB_TEXTEDIT_MOVEWORDLEFT
static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c ) static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c )
{ {
--c; // always move at least one character c = IMSTB_TEXTEDIT_GETPREVCHARINDEX( str, c ); // always move at least one character
while( c >= 0 && !is_word_boundary( str, c ) ) while (c >= 0 && !is_word_boundary(str, c))
--c; c = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, c);
if( c < 0 ) if( c < 0 )
c = 0; c = 0;
@@ -684,9 +693,9 @@ static int stb_textedit_move_to_word_previous( IMSTB_TEXTEDIT_STRING *str, int c
static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c ) static int stb_textedit_move_to_word_next( IMSTB_TEXTEDIT_STRING *str, int c )
{ {
const int len = STB_TEXTEDIT_STRINGLEN(str); const int len = STB_TEXTEDIT_STRINGLEN(str);
++c; // always move at least one character c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c); // always move at least one character
while( c < len && !is_word_boundary( str, c ) ) while( c < len && !is_word_boundary( str, c ) )
++c; c = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, c);
if( c > len ) if( c > len )
c = len; c = len;
@@ -739,6 +748,7 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
#define STB_TEXTEDIT_KEYTYPE int #define STB_TEXTEDIT_KEYTYPE int
#endif #endif
// API key: process text input
// [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility. // [DEAR IMGUI] Added stb_textedit_text(), extracted out and called by stb_textedit_key() for backward compatibility.
static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len) static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* state, const IMSTB_TEXTEDIT_CHARTYPE* text, int text_len)
{ {
@@ -753,8 +763,7 @@ static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* sta
state->cursor += text_len; state->cursor += text_len;
state->has_preferred_x = 0; state->has_preferred_x = 0;
} }
} } else {
else {
stb_textedit_delete_selection(str, state); // implicitly clamps stb_textedit_delete_selection(str, state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) { if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
stb_text_makeundo_insert(state, state->cursor, text_len); stb_text_makeundo_insert(state, state->cursor, text_len);
@@ -771,6 +780,7 @@ retry:
switch (key) { switch (key) {
default: { default: {
#ifdef STB_TEXTEDIT_KEYTOTEXT #ifdef STB_TEXTEDIT_KEYTOTEXT
// This is not suitable for UTF-8 support.
int c = STB_TEXTEDIT_KEYTOTEXT(key); int c = STB_TEXTEDIT_KEYTOTEXT(key);
if (c > 0) { if (c > 0) {
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c; IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE)c;
@@ -918,8 +928,9 @@ retry:
state->cursor = start; state->cursor = start;
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
x = row.x0; x = row.x0;
for (i=0; i < row.num_chars; ++i) { for (i=0; i < row.num_chars; ) {
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE #ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE) if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
break; break;
@@ -927,7 +938,8 @@ retry:
x += dx; x += dx;
if (x > goal_x) if (x > goal_x)
break; break;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor); i += next - state->cursor;
state->cursor = next;
} }
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
@@ -980,8 +992,9 @@ retry:
state->cursor = find.prev_first; state->cursor = find.prev_first;
STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
x = row.x0; x = row.x0;
for (i=0; i < row.num_chars; ++i) { for (i=0; i < row.num_chars; ) {
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
int next = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE #ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE) if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
break; break;
@@ -989,7 +1002,8 @@ retry:
x += dx; x += dx;
if (x > goal_x) if (x > goal_x)
break; break;
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor); i += next - state->cursor;
state->cursor = next;
} }
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
@@ -1002,8 +1016,13 @@ retry:
// go to previous line // go to previous line
// (we need to scan previous line the hard way. maybe we could expose this as a new API function?) // (we need to scan previous line the hard way. maybe we could expose this as a new API function?)
prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0; prev_scan = find.prev_first > 0 ? find.prev_first - 1 : 0;
while (prev_scan > 0 && STB_TEXTEDIT_GETCHAR(str, prev_scan - 1) != STB_TEXTEDIT_NEWLINE) while (prev_scan > 0)
--prev_scan; {
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, prev_scan);
if (STB_TEXTEDIT_GETCHAR(str, prev) == STB_TEXTEDIT_NEWLINE)
break;
prev_scan = prev;
}
find.first_char = find.prev_first; find.first_char = find.prev_first;
find.prev_first = prev_scan; find.prev_first = prev_scan;
} }
@@ -1082,7 +1101,7 @@ retry:
if (state->single_line) if (state->single_line)
state->cursor = 0; state->cursor = 0;
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
--state->cursor; state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
@@ -1094,9 +1113,9 @@ retry:
stb_textedit_clamp(str, state); stb_textedit_clamp(str, state);
stb_textedit_move_to_first(state); stb_textedit_move_to_first(state);
if (state->single_line) if (state->single_line)
state->cursor = n; state->cursor = n;
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
++state->cursor; state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
} }
@@ -1110,7 +1129,7 @@ retry:
if (state->single_line) if (state->single_line)
state->cursor = 0; state->cursor = 0;
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
--state->cursor; state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
state->select_end = state->cursor; state->select_end = state->cursor;
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;
@@ -1125,7 +1144,7 @@ retry:
if (state->single_line) if (state->single_line)
state->cursor = n; state->cursor = n;
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
++state->cursor; state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
state->select_end = state->cursor; state->select_end = state->cursor;
state->has_preferred_x = 0; state->has_preferred_x = 0;
break; break;

View File

@@ -4516,8 +4516,8 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
q2[0] = (float)x2; q2[0] = (float)x2;
q2[1] = (float)y2; q2[1] = (float)y2;
if (equal(q0,q1) || equal(q1,q2)) { if (equal(q0,q1) || equal(q1,q2)) {
x0 = (int)verts[i-1].x; x0 = (int)verts[i-1].x; //-V1048
y0 = (int)verts[i-1].y; y0 = (int)verts[i-1].y; //-V1048
x1 = (int)verts[i ].x; x1 = (int)verts[i ].x;
y1 = (int)verts[i ].y; y1 = (int)verts[i ].y;
if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) {