mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 07:35:41 +00:00
dep/imgui: Update to v1.90.1
This commit is contained in:
parent
352114dc91
commit
f369724b7c
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
// 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 generally be set via the ImGuiIO structure.
|
||||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
// 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 _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time 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.
|
// 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 files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
// 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
|
||||||
|
@ -26,21 +26,21 @@
|
||||||
//#define IMGUI_API __declspec( dllexport )
|
//#define IMGUI_API __declspec( dllexport )
|
||||||
//#define IMGUI_API __declspec( dllimport )
|
//#define IMGUI_API __declspec( dllimport )
|
||||||
|
|
||||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87: disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This will be folded into IMGUI_DISABLE_OBSOLETE_FUNCTIONS in a few versions.
|
//#define IMGUI_DISABLE_OBSOLETE_KEYIO // 1.87+ disable legacy io.KeyMap[]+io.KeysDown[] in favor io.AddKeyEvent(). This is automatically done by 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 tool during development. They are extremely useful in day to day work. Please read comments in imgui_demo.cpp.
|
||||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files 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_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 ShowStackToolWindow() will be empty (this was called IMGUI_DISABLE_METRICS_WINDOW before 1.88).
|
//#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 implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||||
//#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)
|
//#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)
|
||||||
//#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)
|
//#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)
|
||||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, IME).
|
||||||
//#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).
|
//#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).
|
||||||
//#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_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_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||||
|
@ -50,21 +50,24 @@
|
||||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
//---- 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.
|
||||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||||
|
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||||
|
|
||||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
|
||||||
//---- 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 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||||
//#define IMGUI_USE_WCHAR32
|
//#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 to prioritize another version
|
||||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||||
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if enabled
|
//#define IMGUI_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||||
//#define IMGUI_DISABLE_STB_RECT_PACK_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 one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||||
// 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.
|
// 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.
|
||||||
|
@ -75,6 +78,12 @@
|
||||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||||
//#define IMGUI_ENABLE_FREETYPE
|
//#define IMGUI_ENABLE_FREETYPE
|
||||||
|
|
||||||
|
//---- Use FreeType+lunasvg library to render OpenType SVG fonts (SVGinOT)
|
||||||
|
// Requires lunasvg headers to be available in the include path + program to be linked with the lunasvg library (not provided).
|
||||||
|
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||||
|
// (implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||||
|
//#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 stb_truetype backend ALONG with the FreeType backend.
|
||||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||||
|
@ -90,6 +99,8 @@
|
||||||
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.
|
||||||
|
//#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 meshes with more than 64K vertices.
|
||||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||||
|
@ -103,23 +114,18 @@
|
||||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||||
//#define ImDrawCallback MyImDrawCallback
|
//#define ImDrawCallback MyImDrawCallback
|
||||||
|
|
||||||
//---- Debug Tools: Macro to break in Debugger
|
//---- Debug Tools: Macro to break in Debugger (we provide a default implementation of this in the codebase)
|
||||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||||
//#define IM_DEBUG_BREAK __debugbreak()
|
//#define IM_DEBUG_BREAK __debugbreak()
|
||||||
|
|
||||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
|
||||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
|
||||||
// This adds a small runtime cost which is why it is not enabled by default.
|
|
||||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
|
||||||
|
|
||||||
//---- 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, here or in your own headers files.
|
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||||
/*
|
/*
|
||||||
namespace ImGui
|
namespace ImGui
|
||||||
{
|
{
|
||||||
void MyFunction(const char* name, const MyMatrix44& v);
|
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,9 @@
|
||||||
// Changelog:
|
// Changelog:
|
||||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||||
|
|
||||||
|
// See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
|
||||||
|
// https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -12,7 +15,7 @@ namespace ImGui
|
||||||
{
|
{
|
||||||
// ImGui::InputText() with std::string
|
// ImGui::InputText() with std::string
|
||||||
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
|
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
|
||||||
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||||
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||||
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = nullptr, void* user_data = nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
// This is a slightly modified version of stb_textedit.h 1.14.
|
// This is a slightly modified version of stb_textedit.h 1.14.
|
||||||
// Those changes would need to be pushed into nothings/stb:
|
// Those changes would need to be pushed into nothings/stb:
|
||||||
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
|
||||||
|
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
|
||||||
// Grep for [DEAR IMGUI] to find the changes.
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
|
||||||
|
|
||||||
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
// stb_textedit.h - v1.14 - public domain - Sean Barrett
|
||||||
// Development of this library was sponsored by RAD Game Tools
|
// Development of this library was sponsored by RAD Game Tools
|
||||||
|
@ -29,7 +31,7 @@
|
||||||
// DEPENDENCIES
|
// DEPENDENCIES
|
||||||
//
|
//
|
||||||
// Uses the C runtime function 'memmove', which you can override
|
// Uses the C runtime function 'memmove', which you can override
|
||||||
// by defining STB_TEXTEDIT_memmove before the implementation.
|
// by defining IMSTB_TEXTEDIT_memmove before the implementation.
|
||||||
// Uses no other functions. Performs no runtime allocations.
|
// Uses no other functions. Performs no runtime allocations.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -273,8 +275,8 @@
|
||||||
////
|
////
|
||||||
////
|
////
|
||||||
|
|
||||||
#ifndef INCLUDE_STB_TEXTEDIT_H
|
#ifndef INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
#define INCLUDE_STB_TEXTEDIT_H
|
#define INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -285,33 +287,33 @@
|
||||||
// and undo state.
|
// and undo state.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_UNDOSTATECOUNT
|
#ifndef IMSTB_TEXTEDIT_UNDOSTATECOUNT
|
||||||
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
|
#define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_UNDOCHARCOUNT
|
#ifndef IMSTB_TEXTEDIT_UNDOCHARCOUNT
|
||||||
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
|
#define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_CHARTYPE
|
#ifndef IMSTB_TEXTEDIT_CHARTYPE
|
||||||
#define STB_TEXTEDIT_CHARTYPE int
|
#define IMSTB_TEXTEDIT_CHARTYPE int
|
||||||
#endif
|
#endif
|
||||||
#ifndef STB_TEXTEDIT_POSITIONTYPE
|
#ifndef IMSTB_TEXTEDIT_POSITIONTYPE
|
||||||
#define STB_TEXTEDIT_POSITIONTYPE int
|
#define IMSTB_TEXTEDIT_POSITIONTYPE int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// private data
|
// private data
|
||||||
STB_TEXTEDIT_POSITIONTYPE where;
|
IMSTB_TEXTEDIT_POSITIONTYPE where;
|
||||||
STB_TEXTEDIT_POSITIONTYPE insert_length;
|
IMSTB_TEXTEDIT_POSITIONTYPE insert_length;
|
||||||
STB_TEXTEDIT_POSITIONTYPE delete_length;
|
IMSTB_TEXTEDIT_POSITIONTYPE delete_length;
|
||||||
int char_storage;
|
int char_storage;
|
||||||
} StbUndoRecord;
|
} StbUndoRecord;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// private data
|
// private data
|
||||||
StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT];
|
StbUndoRecord undo_rec [IMSTB_TEXTEDIT_UNDOSTATECOUNT];
|
||||||
STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT];
|
IMSTB_TEXTEDIT_CHARTYPE undo_char[IMSTB_TEXTEDIT_UNDOCHARCOUNT];
|
||||||
short undo_point, redo_point;
|
short undo_point, redo_point;
|
||||||
int undo_char_point, redo_char_point;
|
int undo_char_point, redo_char_point;
|
||||||
} StbUndoState;
|
} StbUndoState;
|
||||||
|
@ -370,7 +372,7 @@ typedef struct
|
||||||
float ymin,ymax; // height of row above and below baseline
|
float ymin,ymax; // height of row above and below baseline
|
||||||
int num_chars;
|
int num_chars;
|
||||||
} StbTexteditRow;
|
} StbTexteditRow;
|
||||||
#endif //INCLUDE_STB_TEXTEDIT_H
|
#endif //INCLUDE_IMSTB_TEXTEDIT_H
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -383,11 +385,11 @@ typedef struct
|
||||||
|
|
||||||
// implementation isn't include-guarded, since it might have indirectly
|
// implementation isn't include-guarded, since it might have indirectly
|
||||||
// included just the "header" portion
|
// included just the "header" portion
|
||||||
#ifdef STB_TEXTEDIT_IMPLEMENTATION
|
#ifdef IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_memmove
|
#ifndef IMSTB_TEXTEDIT_memmove
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#define STB_TEXTEDIT_memmove memmove
|
#define IMSTB_TEXTEDIT_memmove memmove
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,7 +399,7 @@ typedef struct
|
||||||
//
|
//
|
||||||
|
|
||||||
// traverse the layout to locate the nearest character to a display position
|
// traverse the layout to locate the nearest character to a display position
|
||||||
static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||||
{
|
{
|
||||||
StbTexteditRow r;
|
StbTexteditRow r;
|
||||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
|
@ -457,7 +459,7 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
// API click: on mouse down, move the cursor to the clicked location, and reset the selection
|
||||||
static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||||
{
|
{
|
||||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||||
// goes off the top or bottom of the text
|
// goes off the top or bottom of the text
|
||||||
|
@ -475,7 +477,7 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||||
}
|
}
|
||||||
|
|
||||||
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
||||||
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||||
{
|
{
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
|
||||||
|
@ -501,11 +503,11 @@ static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state
|
||||||
//
|
//
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state);
|
||||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length);
|
||||||
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length);
|
||||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -517,36 +519,21 @@ typedef struct
|
||||||
|
|
||||||
// find the x/y location of a character, and remember info about the previous row in
|
// find the x/y location of a character, and remember info about the previous row in
|
||||||
// case we get a move-up event (for page up, we'll have to rescan)
|
// case we get a move-up event (for page up, we'll have to rescan)
|
||||||
static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line)
|
static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING *str, int n, int single_line)
|
||||||
{
|
{
|
||||||
StbTexteditRow r;
|
StbTexteditRow r;
|
||||||
int prev_start = 0;
|
int prev_start = 0;
|
||||||
int z = STB_TEXTEDIT_STRINGLEN(str);
|
int z = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
int i=0, first;
|
int i=0, first;
|
||||||
|
|
||||||
if (n == z) {
|
if (n == z && single_line) {
|
||||||
// if it's at the end, then find the last line -- simpler than trying to
|
// special case if it's at the end (may not be needed?)
|
||||||
// explicitly handle this case in the regular code
|
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
||||||
if (single_line) {
|
find->y = 0;
|
||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
|
find->first_char = 0;
|
||||||
find->y = 0;
|
find->length = z;
|
||||||
find->first_char = 0;
|
find->height = r.ymax - r.ymin;
|
||||||
find->length = z;
|
find->x = r.x1;
|
||||||
find->height = r.ymax - r.ymin;
|
|
||||||
find->x = r.x1;
|
|
||||||
} else {
|
|
||||||
find->y = 0;
|
|
||||||
find->x = 0;
|
|
||||||
find->height = 1;
|
|
||||||
while (i < z) {
|
|
||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
|
||||||
prev_start = i;
|
|
||||||
i += r.num_chars;
|
|
||||||
}
|
|
||||||
find->first_char = i;
|
|
||||||
find->length = 0;
|
|
||||||
find->prev_first = prev_start;
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,9 +544,16 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||||
if (n < i + r.num_chars)
|
if (n < i + r.num_chars)
|
||||||
break;
|
break;
|
||||||
|
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
|
||||||
|
break; // [DEAR IMGUI]
|
||||||
prev_start = i;
|
prev_start = i;
|
||||||
i += r.num_chars;
|
i += r.num_chars;
|
||||||
find->y += r.baseline_y_delta;
|
find->y += r.baseline_y_delta;
|
||||||
|
if (i == z) // [DEAR IMGUI]
|
||||||
|
{
|
||||||
|
r.num_chars = 0; // [DEAR IMGUI]
|
||||||
|
break; // [DEAR IMGUI]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
find->first_char = first = i;
|
find->first_char = first = i;
|
||||||
|
@ -576,7 +570,7 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
|
||||||
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end)
|
||||||
|
|
||||||
// make the selection/cursor state valid if client altered the string
|
// make the selection/cursor state valid if client altered the string
|
||||||
static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_clamp(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
|
@ -590,7 +584,7 @@ static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete characters while updating undo
|
// delete characters while updating undo
|
||||||
static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
static void stb_textedit_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len)
|
||||||
{
|
{
|
||||||
stb_text_makeundo_delete(str, state, where, len);
|
stb_text_makeundo_delete(str, state, where, len);
|
||||||
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
STB_TEXTEDIT_DELETECHARS(str, where, len);
|
||||||
|
@ -598,7 +592,7 @@ static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the section
|
// delete the section
|
||||||
static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_delete_selection(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
|
@ -635,7 +629,7 @@ static void stb_textedit_move_to_first(STB_TexteditState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// move cursor to last character of selection
|
// move cursor to last character of selection
|
||||||
static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
stb_textedit_sortselection(state);
|
stb_textedit_sortselection(state);
|
||||||
|
@ -647,13 +641,13 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||||
static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
|
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||||
{
|
{
|
||||||
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
#ifndef STB_TEXTEDIT_MOVEWORDLEFT
|
||||||
static int stb_textedit_move_to_word_previous( STB_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; // always move at least one character
|
||||||
while( c >= 0 && !is_word_boundary( str, c ) )
|
while( c >= 0 && !is_word_boundary( str, c ) )
|
||||||
|
@ -668,7 +662,7 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
#ifndef STB_TEXTEDIT_MOVEWORDRIGHT
|
||||||
static int stb_textedit_move_to_word_next( STB_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; // always move at least one character
|
||||||
|
@ -695,7 +689,7 @@ static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// API cut: delete selection
|
// API cut: delete selection
|
||||||
static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static int stb_textedit_cut(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
if (STB_TEXT_HAS_SELECTION(state)) {
|
if (STB_TEXT_HAS_SELECTION(state)) {
|
||||||
stb_textedit_delete_selection(str,state); // implicitly clamps
|
stb_textedit_delete_selection(str,state); // implicitly clamps
|
||||||
|
@ -706,7 +700,7 @@ static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
// API paste: replace existing selection with passed-in text
|
// API paste: replace existing selection with passed-in text
|
||||||
static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE *text, int len)
|
static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE *text, int len)
|
||||||
{
|
{
|
||||||
// if there's a selection, the paste should delete it
|
// if there's a selection, the paste should delete it
|
||||||
stb_textedit_clamp(str, state);
|
stb_textedit_clamp(str, state);
|
||||||
|
@ -727,14 +721,14 @@ static int stb_textedit_paste_internal(STB_TEXTEDIT_STRING *str, STB_TexteditSta
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// API key: process a keyboard input
|
// API key: process a keyboard input
|
||||||
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
static void stb_textedit_key(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_KEYTYPE key)
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
switch (key) {
|
switch (key) {
|
||||||
default: {
|
default: {
|
||||||
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
int c = STB_TEXTEDIT_KEYTOTEXT(key);
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;
|
IMSTB_TEXTEDIT_CHARTYPE ch = (IMSTB_TEXTEDIT_CHARTYPE) c;
|
||||||
|
|
||||||
// can't add newline in single-line mode
|
// can't add newline in single-line mode
|
||||||
if (c == '\n' && state->single_line)
|
if (c == '\n' && state->single_line)
|
||||||
|
@ -899,8 +893,8 @@ retry:
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ++i) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
|
||||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
x += dx;
|
x += dx;
|
||||||
|
@ -961,8 +955,8 @@ retry:
|
||||||
x = row.x0;
|
x = row.x0;
|
||||||
for (i=0; i < row.num_chars; ++i) {
|
for (i=0; i < row.num_chars; ++i) {
|
||||||
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
|
||||||
#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
|
#ifdef IMSTB_TEXTEDIT_GETWIDTH_NEWLINE
|
||||||
if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
|
if (dx == IMSTB_TEXTEDIT_GETWIDTH_NEWLINE)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
x += dx;
|
x += dx;
|
||||||
|
@ -1119,8 +1113,8 @@ retry:
|
||||||
|
|
||||||
static void stb_textedit_flush_redo(StbUndoState *state)
|
static void stb_textedit_flush_redo(StbUndoState *state)
|
||||||
{
|
{
|
||||||
state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
state->redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||||
state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
state->redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// discard the oldest entry in the undo list
|
// discard the oldest entry in the undo list
|
||||||
|
@ -1132,13 +1126,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||||
int n = state->undo_rec[0].insert_length, i;
|
int n = state->undo_rec[0].insert_length, i;
|
||||||
// delete n characters from all other records
|
// delete n characters from all other records
|
||||||
state->undo_char_point -= n;
|
state->undo_char_point -= n;
|
||||||
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
IMSTB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||||
for (i=0; i < state->undo_point; ++i)
|
for (i=0; i < state->undo_point; ++i)
|
||||||
if (state->undo_rec[i].char_storage >= 0)
|
if (state->undo_rec[i].char_storage >= 0)
|
||||||
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
state->undo_rec[i].char_storage -= n; // @OPTIMIZE: get rid of char_storage and infer it
|
||||||
}
|
}
|
||||||
--state->undo_point;
|
--state->undo_point;
|
||||||
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
IMSTB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,7 +1142,7 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||||
// fill up even though the undo buffer didn't
|
// fill up even though the undo buffer didn't
|
||||||
static void stb_textedit_discard_redo(StbUndoState *state)
|
static void stb_textedit_discard_redo(StbUndoState *state)
|
||||||
{
|
{
|
||||||
int k = STB_TEXTEDIT_UNDOSTATECOUNT-1;
|
int k = IMSTB_TEXTEDIT_UNDOSTATECOUNT-1;
|
||||||
|
|
||||||
if (state->redo_point <= k) {
|
if (state->redo_point <= k) {
|
||||||
// if the k'th undo state has characters, clean those up
|
// if the k'th undo state has characters, clean those up
|
||||||
|
@ -1156,7 +1150,7 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||||
int n = state->undo_rec[k].insert_length, i;
|
int n = state->undo_rec[k].insert_length, i;
|
||||||
// move the remaining redo character data to the end of the buffer
|
// move the remaining redo character data to the end of the buffer
|
||||||
state->redo_char_point += n;
|
state->redo_char_point += n;
|
||||||
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
IMSTB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((IMSTB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(IMSTB_TEXTEDIT_CHARTYPE)));
|
||||||
// adjust the position of all the other records to account for above memmove
|
// adjust the position of all the other records to account for above memmove
|
||||||
for (i=state->redo_point; i < k; ++i)
|
for (i=state->redo_point; i < k; ++i)
|
||||||
if (state->undo_rec[i].char_storage >= 0)
|
if (state->undo_rec[i].char_storage >= 0)
|
||||||
|
@ -1164,12 +1158,12 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||||
}
|
}
|
||||||
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
// now move all the redo records towards the end of the buffer; the first one is at 'redo_point'
|
||||||
// [DEAR IMGUI]
|
// [DEAR IMGUI]
|
||||||
size_t move_size = (size_t)((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point - 1) * sizeof(state->undo_rec[0]));
|
size_t move_size = (size_t)((IMSTB_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_begin = (char*)state->undo_rec; (void)buf_begin;
|
||||||
const char* buf_end = (char*)state->undo_rec + sizeof(state->undo_rec); (void)buf_end;
|
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)) >= buf_begin);
|
||||||
IM_ASSERT(((char*)(state->undo_rec + state->redo_point + 1) + move_size) <= buf_end);
|
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);
|
IMSTB_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
|
// now move redo_point to point to the new one
|
||||||
++state->redo_point;
|
++state->redo_point;
|
||||||
|
@ -1183,32 +1177,32 @@ static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numch
|
||||||
|
|
||||||
// if we have no free records, we have to make room, by sliding the
|
// if we have no free records, we have to make room, by sliding the
|
||||||
// existing records down
|
// existing records down
|
||||||
if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (state->undo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
stb_textedit_discard_undo(state);
|
stb_textedit_discard_undo(state);
|
||||||
|
|
||||||
// if the characters to store won't possibly fit in the buffer, we can't undo
|
// if the characters to store won't possibly fit in the buffer, we can't undo
|
||||||
if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) {
|
if (numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||||
state->undo_point = 0;
|
state->undo_point = 0;
|
||||||
state->undo_char_point = 0;
|
state->undo_char_point = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't have enough free characters in the buffer, we have to make room
|
// if we don't have enough free characters in the buffer, we have to make room
|
||||||
while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT)
|
while (state->undo_char_point + numchars > IMSTB_TEXTEDIT_UNDOCHARCOUNT)
|
||||||
stb_textedit_discard_undo(state);
|
stb_textedit_discard_undo(state);
|
||||||
|
|
||||||
return &state->undo_rec[state->undo_point++];
|
return &state->undo_rec[state->undo_point++];
|
||||||
}
|
}
|
||||||
|
|
||||||
static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
static IMSTB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len)
|
||||||
{
|
{
|
||||||
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
StbUndoRecord *r = stb_text_create_undo_record(state, insert_len);
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
r->where = pos;
|
r->where = pos;
|
||||||
r->insert_length = (STB_TEXTEDIT_POSITIONTYPE) insert_len;
|
r->insert_length = (IMSTB_TEXTEDIT_POSITIONTYPE) insert_len;
|
||||||
r->delete_length = (STB_TEXTEDIT_POSITIONTYPE) delete_len;
|
r->delete_length = (IMSTB_TEXTEDIT_POSITIONTYPE) delete_len;
|
||||||
|
|
||||||
if (insert_len == 0) {
|
if (insert_len == 0) {
|
||||||
r->char_storage = -1;
|
r->char_storage = -1;
|
||||||
|
@ -1220,7 +1214,7 @@ static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
StbUndoState *s = &state->undostate;
|
StbUndoState *s = &state->undostate;
|
||||||
StbUndoRecord u, *r;
|
StbUndoRecord u, *r;
|
||||||
|
@ -1247,7 +1241,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
// characters stored for *undoing* don't leave room for redo
|
// characters stored for *undoing* don't leave room for redo
|
||||||
// if the last is true, we have to bail
|
// if the last is true, we have to bail
|
||||||
|
|
||||||
if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) {
|
if (s->undo_char_point + u.delete_length >= IMSTB_TEXTEDIT_UNDOCHARCOUNT) {
|
||||||
// the undo records take up too much character space; there's no space to store the redo characters
|
// the undo records take up too much character space; there's no space to store the redo characters
|
||||||
r->insert_length = 0;
|
r->insert_length = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1256,7 +1250,7 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
// there's definitely room to store the characters eventually
|
// there's definitely room to store the characters eventually
|
||||||
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
while (s->undo_char_point + u.delete_length > s->redo_char_point) {
|
||||||
// should never happen:
|
// should never happen:
|
||||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
return;
|
return;
|
||||||
// there's currently not enough room, so discard a redo record
|
// there's currently not enough room, so discard a redo record
|
||||||
stb_textedit_discard_redo(s);
|
stb_textedit_discard_redo(s);
|
||||||
|
@ -1288,11 +1282,11 @@ static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
s->redo_point--;
|
s->redo_point--;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
|
||||||
{
|
{
|
||||||
StbUndoState *s = &state->undostate;
|
StbUndoState *s = &state->undostate;
|
||||||
StbUndoRecord *u, r;
|
StbUndoRecord *u, r;
|
||||||
if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT)
|
if (s->redo_point == IMSTB_TEXTEDIT_UNDOSTATECOUNT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we need to do two things: apply the redo record, and create an undo record
|
// we need to do two things: apply the redo record, and create an undo record
|
||||||
|
@ -1344,20 +1338,20 @@ static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int le
|
||||||
stb_text_createundo(&state->undostate, where, 0, length);
|
stb_text_createundo(&state->undostate, where, 0, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
static void stb_text_makeundo_delete(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0);
|
||||||
if (p) {
|
if (p) {
|
||||||
for (i=0; i < length; ++i)
|
for (i=0; i < length; ++i)
|
||||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
static void stb_text_makeundo_replace(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
IMSTB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length);
|
||||||
if (p) {
|
if (p) {
|
||||||
for (i=0; i < old_length; ++i)
|
for (i=0; i < old_length; ++i)
|
||||||
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
p[i] = STB_TEXTEDIT_GETCHAR(str, where+i);
|
||||||
|
@ -1369,8 +1363,8 @@ static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_lin
|
||||||
{
|
{
|
||||||
state->undostate.undo_point = 0;
|
state->undostate.undo_point = 0;
|
||||||
state->undostate.undo_char_point = 0;
|
state->undostate.undo_char_point = 0;
|
||||||
state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT;
|
state->undostate.redo_point = IMSTB_TEXTEDIT_UNDOSTATECOUNT;
|
||||||
state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT;
|
state->undostate.redo_char_point = IMSTB_TEXTEDIT_UNDOCHARCOUNT;
|
||||||
state->select_end = state->select_start = 0;
|
state->select_end = state->select_start = 0;
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
state->has_preferred_x = 0;
|
state->has_preferred_x = 0;
|
||||||
|
@ -1393,16 +1387,16 @@ static void stb_textedit_initialize_state(STB_TexteditState *state, int is_singl
|
||||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
static int stb_textedit_paste(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, IMSTB_TEXTEDIT_CHARTYPE const *ctext, int len)
|
||||||
{
|
{
|
||||||
return stb_textedit_paste_internal(str, state, (STB_TEXTEDIT_CHARTYPE *) ctext, len);
|
return stb_textedit_paste_internal(str, state, (IMSTB_TEXTEDIT_CHARTYPE *) ctext, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif//STB_TEXTEDIT_IMPLEMENTATION
|
#endif//IMSTB_TEXTEDIT_IMPLEMENTATION
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
||||||
// dear imgui, v1.88
|
// dear imgui, v1.90.1
|
||||||
// (drawing and font code)
|
// (drawing and font code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,38 +26,24 @@ Index of this file:
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "imgui.h"
|
|
||||||
#ifndef IMGUI_DISABLE
|
|
||||||
|
|
||||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
#ifdef IMGUI_ENABLE_FREETYPE
|
#ifdef IMGUI_ENABLE_FREETYPE
|
||||||
#include "misc/freetype/imgui_freetype.h"
|
#include "misc/freetype/imgui_freetype.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h> // vsnprintf, sscanf, printf
|
#include <stdio.h> // vsnprintf, sscanf, printf
|
||||||
#if !defined(alloca)
|
|
||||||
#if defined(__GLIBC__) || defined(__sun) || defined(__APPLE__) || defined(__NEWLIB__)
|
|
||||||
#include <alloca.h> // alloca (glibc uses <alloca.h>. Note that Cygwin may have _WIN32 defined, so the order matters here)
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
#include <malloc.h> // alloca
|
|
||||||
#if !defined(alloca)
|
|
||||||
#define alloca _alloca // for clang with MS Codegen
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <stdlib.h> // alloca
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Visual Studio warnings
|
// Visual Studio warnings
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning (disable: 4127) // condition expression is constant
|
#pragma warning (disable: 4127) // condition expression is constant
|
||||||
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
||||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||||
#pragma warning (disable: 6255) // [Static Analyzer] _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead.
|
|
||||||
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
|
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
|
||||||
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
|
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
|
||||||
#endif
|
#endif
|
||||||
|
@ -67,9 +53,6 @@ Index of this file:
|
||||||
#if __has_warning("-Wunknown-warning-option")
|
#if __has_warning("-Wunknown-warning-option")
|
||||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' // not all warnings are known by all Clang versions and they tend to be rename-happy.. so ignoring warnings triggers new warnings on some configuration. Great!
|
||||||
#endif
|
#endif
|
||||||
#if __has_warning("-Walloca")
|
|
||||||
#pragma clang diagnostic ignored "-Walloca" // warning: use of function '__builtin_alloca' is discouraged
|
|
||||||
#endif
|
|
||||||
#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 ok.
|
#pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
|
||||||
|
@ -80,6 +63,7 @@ Index of this file:
|
||||||
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier
|
||||||
#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.
|
#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.
|
||||||
#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 "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter
|
||||||
#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 "-Wunused-function" // warning: 'xxxx' defined but not used
|
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||||||
|
@ -151,7 +135,7 @@ namespace IMGUI_STB_NAMESPACE
|
||||||
#define STBTT_sqrt(x) ImSqrt(x)
|
#define STBTT_sqrt(x) ImSqrt(x)
|
||||||
#define STBTT_pow(x,y) ImPow(x,y)
|
#define STBTT_pow(x,y) ImPow(x,y)
|
||||||
#define STBTT_fabs(x) ImFabs(x)
|
#define STBTT_fabs(x) ImFabs(x)
|
||||||
#define STBTT_ifloor(x) ((int)ImFloorSigned(x))
|
#define STBTT_ifloor(x) ((int)ImFloor(x))
|
||||||
#define STBTT_iceil(x) ((int)ImCeil(x))
|
#define STBTT_iceil(x) ((int)ImCeil(x))
|
||||||
#define STBTT_STATIC
|
#define STBTT_STATIC
|
||||||
#define STB_TRUETYPE_IMPLEMENTATION
|
#define STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
@ -402,9 +386,11 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error)
|
||||||
void ImDrawList::_ResetForNewFrame()
|
void ImDrawList::_ResetForNewFrame()
|
||||||
{
|
{
|
||||||
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
// Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory.
|
||||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, ClipRect) == 0);
|
IM_STATIC_ASSERT(offsetof(ImDrawCmd, ClipRect) == 0);
|
||||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, TextureId) == sizeof(ImVec4));
|
IM_STATIC_ASSERT(offsetof(ImDrawCmd, TextureId) == sizeof(ImVec4));
|
||||||
IM_STATIC_ASSERT(IM_OFFSETOF(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
|
IM_STATIC_ASSERT(offsetof(ImDrawCmd, VtxOffset) == sizeof(ImVec4) + sizeof(ImTextureID));
|
||||||
|
if (_Splitter._Count > 1)
|
||||||
|
_Splitter.Merge(this);
|
||||||
|
|
||||||
CmdBuffer.resize(0);
|
CmdBuffer.resize(0);
|
||||||
IdxBuffer.resize(0);
|
IdxBuffer.resize(0);
|
||||||
|
@ -463,11 +449,13 @@ void ImDrawList::AddDrawCmd()
|
||||||
// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL
|
// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL
|
||||||
void ImDrawList::_PopUnusedDrawCmd()
|
void ImDrawList::_PopUnusedDrawCmd()
|
||||||
{
|
{
|
||||||
if (CmdBuffer.Size == 0)
|
while (CmdBuffer.Size > 0)
|
||||||
return;
|
{
|
||||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||||
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL)
|
if (curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL)
|
||||||
|
return;// break;
|
||||||
CmdBuffer.pop_back();
|
CmdBuffer.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||||
|
@ -487,7 +475,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare ClipRect, TextureId and VtxOffset with a single memcmp()
|
// Compare ClipRect, TextureId and VtxOffset with a single memcmp()
|
||||||
#define ImDrawCmd_HeaderSize (IM_OFFSETOF(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
|
#define ImDrawCmd_HeaderSize (offsetof(ImDrawCmd, VtxOffset) + sizeof(unsigned int))
|
||||||
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
|
#define ImDrawCmd_HeaderCompare(CMD_LHS, CMD_RHS) (memcmp(CMD_LHS, CMD_RHS, ImDrawCmd_HeaderSize)) // Compare ClipRect, TextureId, VtxOffset
|
||||||
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
|
#define ImDrawCmd_HeaderCopy(CMD_DST, CMD_SRC) (memcpy(CMD_DST, CMD_SRC, ImDrawCmd_HeaderSize)) // Copy ClipRect, TextureId, VtxOffset
|
||||||
#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset)
|
#define ImDrawCmd_AreSequentialIdxOffset(CMD_0, CMD_1) (CMD_0->IdxOffset + CMD_0->ElemCount == CMD_1->IdxOffset)
|
||||||
|
@ -573,7 +561,7 @@ int ImDrawList::_CalcCircleAutoSegmentCount(float radius) const
|
||||||
{
|
{
|
||||||
// Automatic segment count
|
// Automatic segment count
|
||||||
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
|
const int radius_idx = (int)(radius + 0.999999f); // ceil to never reduce accuracy
|
||||||
if (radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
if (radius_idx >= 0 && radius_idx < IM_ARRAYSIZE(_Data->CircleSegmentCounts))
|
||||||
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
return _Data->CircleSegmentCounts[radius_idx]; // Use cached value
|
||||||
else
|
else
|
||||||
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
return IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(radius, _Data->CircleSegmentMaxError);
|
||||||
|
@ -720,7 +708,7 @@ void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, c
|
||||||
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
|
// We avoid using the ImVec2 math operators here to reduce cost to a minimum for debug/non-inlined builds.
|
||||||
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness)
|
void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, ImDrawFlags flags, float thickness)
|
||||||
{
|
{
|
||||||
if (points_count < 2)
|
if (points_count < 2 || (col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool closed = (flags & ImDrawFlags_Closed) != 0;
|
const bool closed = (flags & ImDrawFlags_Closed) != 0;
|
||||||
|
@ -753,7 +741,8 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||||
|
|
||||||
// Temporary buffer
|
// Temporary buffer
|
||||||
// The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point
|
// The first <points_count> items are normals at each line point, then after that there are either 2 or 4 temp points for each line point
|
||||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * ((use_texture || !thick_line) ? 3 : 5) * sizeof(ImVec2)); //-V630
|
_Data->TempBuffer.reserve_discard(points_count * ((use_texture || !thick_line) ? 3 : 5));
|
||||||
|
ImVec2* temp_normals = _Data->TempBuffer.Data;
|
||||||
ImVec2* temp_points = temp_normals + points_count;
|
ImVec2* temp_points = temp_normals + points_count;
|
||||||
|
|
||||||
// Calculate normals (tangents) for each line segment
|
// Calculate normals (tangents) for each line segment
|
||||||
|
@ -977,7 +966,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
|
||||||
// - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
// - Filled shapes must always use clockwise winding order. The anti-aliasing fringe depends on it. Counter-clockwise shapes will have "inward" anti-aliasing.
|
||||||
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
|
void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col)
|
||||||
{
|
{
|
||||||
if (points_count < 3)
|
if (points_count < 3 || (col & IM_COL32_A_MASK) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const ImVec2 uv = _Data->TexUvWhitePixel;
|
const ImVec2 uv = _Data->TexUvWhitePixel;
|
||||||
|
@ -1001,7 +990,8 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute normals
|
// Compute normals
|
||||||
ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); //-V630
|
_Data->TempBuffer.reserve_discard(points_count);
|
||||||
|
ImVec2* temp_normals = _Data->TempBuffer.Data;
|
||||||
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
|
for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++)
|
||||||
{
|
{
|
||||||
const ImVec2& p0 = points[i0];
|
const ImVec2& p0 = points[i0];
|
||||||
|
@ -1201,8 +1191,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
|
||||||
const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f);
|
const float a_min_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_min / (IM_PI * 2.0f);
|
||||||
const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f);
|
const float a_max_sample_f = IM_DRAWLIST_ARCFAST_SAMPLE_MAX * a_max / (IM_PI * 2.0f);
|
||||||
|
|
||||||
const int a_min_sample = a_is_reverse ? (int)ImFloorSigned(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
|
const int a_min_sample = a_is_reverse ? (int)ImFloor(a_min_sample_f) : (int)ImCeil(a_min_sample_f);
|
||||||
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloorSigned(a_max_sample_f);
|
const int a_max_sample = a_is_reverse ? (int)ImCeil(a_max_sample_f) : (int)ImFloor(a_max_sample_f);
|
||||||
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
|
const int a_mid_samples = a_is_reverse ? ImMax(a_min_sample - a_max_sample, 0) : ImMax(a_max_sample - a_min_sample, 0);
|
||||||
|
|
||||||
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
|
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
|
||||||
|
@ -1227,6 +1217,27 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments)
|
||||||
|
{
|
||||||
|
if (num_segments <= 0)
|
||||||
|
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||||
|
|
||||||
|
_Path.reserve(_Path.Size + (num_segments + 1));
|
||||||
|
|
||||||
|
const float cos_rot = ImCos(rot);
|
||||||
|
const float sin_rot = ImSin(rot);
|
||||||
|
for (int i = 0; i <= num_segments; i++)
|
||||||
|
{
|
||||||
|
const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min);
|
||||||
|
ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y);
|
||||||
|
const float rel_x = (point.x * cos_rot) - (point.y * sin_rot);
|
||||||
|
const float rel_y = (point.x * sin_rot) + (point.y * cos_rot);
|
||||||
|
point.x = rel_x + center.x;
|
||||||
|
point.y = rel_y + center.y;
|
||||||
|
_Path.push_back(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
|
ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t)
|
||||||
{
|
{
|
||||||
float u = 1.0f - t;
|
float u = 1.0f - t;
|
||||||
|
@ -1295,6 +1306,7 @@ void ImDrawList::PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, cons
|
||||||
ImVec2 p1 = _Path.back();
|
ImVec2 p1 = _Path.back();
|
||||||
if (num_segments == 0)
|
if (num_segments == 0)
|
||||||
{
|
{
|
||||||
|
IM_ASSERT(_Data->CurveTessellationTol > 0.0f);
|
||||||
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
|
PathBezierCubicCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1310,6 +1322,7 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3,
|
||||||
ImVec2 p1 = _Path.back();
|
ImVec2 p1 = _Path.back();
|
||||||
if (num_segments == 0)
|
if (num_segments == 0)
|
||||||
{
|
{
|
||||||
|
IM_ASSERT(_Data->CurveTessellationTol > 0.0f);
|
||||||
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated
|
PathBezierQuadraticCurveToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, _Data->CurveTessellationTol, 0);// Auto-tessellated
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1320,32 +1333,22 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4));
|
|
||||||
static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
|
static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4));
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
// Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All)
|
// Obsoleted in 1.82 (from February 2021). This code was stripped/simplified and mostly commented in 1.90 (from September 2023)
|
||||||
// ~0 --> ImDrawFlags_RoundCornersAll or 0
|
// - Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All)
|
||||||
if (flags == ~0)
|
if (flags == ~0) { return ImDrawFlags_RoundCornersAll; }
|
||||||
return ImDrawFlags_RoundCornersAll;
|
// - Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations). Read details in older version of this code.
|
||||||
|
if (flags >= 0x01 && flags <= 0x0F) { return (flags << 4); }
|
||||||
// Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations)
|
|
||||||
// 0x01 --> ImDrawFlags_RoundCornersTopLeft (VALUE 0x01 OVERLAPS ImDrawFlags_Closed but ImDrawFlags_Closed is never valid in this path!)
|
|
||||||
// 0x02 --> ImDrawFlags_RoundCornersTopRight
|
|
||||||
// 0x03 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight
|
|
||||||
// 0x04 --> ImDrawFlags_RoundCornersBotLeft
|
|
||||||
// 0x05 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBotLeft
|
|
||||||
// ...
|
|
||||||
// 0x0F --> ImDrawFlags_RoundCornersAll or 0
|
|
||||||
// (See all values in ImDrawCornerFlags_)
|
|
||||||
if (flags >= 0x01 && flags <= 0x0F)
|
|
||||||
return (flags << 4);
|
|
||||||
|
|
||||||
// We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'
|
// We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f'
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
// If this triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values.
|
// If this assert triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values.
|
||||||
// Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc...
|
// Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc. anyway.
|
||||||
|
// See details in 1.82 Changelog as well as 2021/03/12 and 2023/09/08 entries in "API BREAKING CHANGES" section.
|
||||||
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
|
IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!");
|
||||||
|
|
||||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||||
|
@ -1356,10 +1359,12 @@ static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags)
|
||||||
|
|
||||||
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags)
|
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags)
|
||||||
{
|
{
|
||||||
flags = FixRectCornerFlags(flags);
|
if (rounding >= 0.5f)
|
||||||
rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f ) - 1.0f);
|
{
|
||||||
rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f ) - 1.0f);
|
flags = FixRectCornerFlags(flags);
|
||||||
|
rounding = ImMin(rounding, ImFabs(b.x - a.x) * (((flags & ImDrawFlags_RoundCornersTop) == ImDrawFlags_RoundCornersTop) || ((flags & ImDrawFlags_RoundCornersBottom) == ImDrawFlags_RoundCornersBottom) ? 0.5f : 1.0f) - 1.0f);
|
||||||
|
rounding = ImMin(rounding, ImFabs(b.y - a.y) * (((flags & ImDrawFlags_RoundCornersLeft) == ImDrawFlags_RoundCornersLeft) || ((flags & ImDrawFlags_RoundCornersRight) == ImDrawFlags_RoundCornersRight) ? 0.5f : 1.0f) - 1.0f);
|
||||||
|
}
|
||||||
if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
if (rounding < 0.5f || (flags & ImDrawFlags_RoundCornersMask_) == ImDrawFlags_RoundCornersNone)
|
||||||
{
|
{
|
||||||
PathLineTo(a);
|
PathLineTo(a);
|
||||||
|
@ -1552,6 +1557,35 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in
|
||||||
PathFillConvex(col);
|
PathFillConvex(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ellipse
|
||||||
|
void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness)
|
||||||
|
{
|
||||||
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (num_segments <= 0)
|
||||||
|
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
|
||||||
|
PathStroke(col, true, thickness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments)
|
||||||
|
{
|
||||||
|
if ((col & IM_COL32_A_MASK) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (num_segments <= 0)
|
||||||
|
num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here.
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1);
|
||||||
|
PathFillConvex(col);
|
||||||
|
}
|
||||||
|
|
||||||
// Cubic Bezier takes 4 controls points
|
// Cubic Bezier takes 4 controls points
|
||||||
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
|
void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments)
|
||||||
{
|
{
|
||||||
|
@ -1816,6 +1850,63 @@ void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
|
||||||
// [SECTION] ImDrawData
|
// [SECTION] ImDrawData
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ImDrawData::Clear()
|
||||||
|
{
|
||||||
|
Valid = false;
|
||||||
|
CmdListsCount = TotalIdxCount = TotalVtxCount = 0;
|
||||||
|
CmdLists.resize(0); // The ImDrawList are NOT owned by ImDrawData but e.g. by ImGuiContext, so we don't clear them.
|
||||||
|
DisplayPos = DisplaySize = FramebufferScale = ImVec2(0.0f, 0.0f);
|
||||||
|
OwnerViewport = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Important: 'out_list' is generally going to be draw_data->CmdLists, but may be another temporary list
|
||||||
|
// as long at it is expected that the result will be later merged into draw_data->CmdLists[].
|
||||||
|
void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
|
||||||
|
{
|
||||||
|
if (draw_list->CmdBuffer.Size == 0)
|
||||||
|
return;
|
||||||
|
if (draw_list->CmdBuffer.Size == 1 && draw_list->CmdBuffer[0].ElemCount == 0 && draw_list->CmdBuffer[0].UserCallback == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
|
||||||
|
// May trigger for you if you are using PrimXXX functions incorrectly.
|
||||||
|
IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
|
||||||
|
IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size);
|
||||||
|
if (!(draw_list->Flags & ImDrawListFlags_AllowVtxOffset))
|
||||||
|
IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size);
|
||||||
|
|
||||||
|
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
|
||||||
|
// If this assert triggers because you are drawing lots of stuff manually:
|
||||||
|
// - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
|
||||||
|
// Be mindful that the lower-level ImDrawList API doesn't filter vertices. Use the Metrics/Debugger window to inspect draw list contents.
|
||||||
|
// - If you want large meshes with more than 64K vertices, you can either:
|
||||||
|
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer backend, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
|
||||||
|
// Most example backends already support this from 1.71. Pre-1.71 backends won't.
|
||||||
|
// Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
|
||||||
|
// (B) Or handle 32-bit indices in your renderer backend, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
|
||||||
|
// Most example backends already support this. For example, the OpenGL example code detect index size at compile-time:
|
||||||
|
// glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
|
||||||
|
// Your own engine or render API may use different parameters or function calls to specify index sizes.
|
||||||
|
// 2 and 4 bytes indices are generally supported by most graphics API.
|
||||||
|
// - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
|
||||||
|
// the 64K limit to split your draw commands in multiple draw lists.
|
||||||
|
if (sizeof(ImDrawIdx) == 2)
|
||||||
|
IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
|
||||||
|
|
||||||
|
// Add to output list + records state in ImDrawData
|
||||||
|
out_list->push_back(draw_list);
|
||||||
|
draw_data->CmdListsCount++;
|
||||||
|
draw_data->TotalVtxCount += draw_list->VtxBuffer.Size;
|
||||||
|
draw_data->TotalIdxCount += draw_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImDrawData::AddDrawList(ImDrawList* draw_list)
|
||||||
|
{
|
||||||
|
IM_ASSERT(CmdLists.Size == CmdListsCount);
|
||||||
|
draw_list->_PopUnusedDrawCmd();
|
||||||
|
ImGui::AddDrawListToDrawDataEx(this, &CmdLists, draw_list);
|
||||||
|
}
|
||||||
|
|
||||||
// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
|
// For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering!
|
||||||
void ImDrawData::DeIndexAllBuffers()
|
void ImDrawData::DeIndexAllBuffers()
|
||||||
{
|
{
|
||||||
|
@ -1840,15 +1931,9 @@ void ImDrawData::DeIndexAllBuffers()
|
||||||
// or if there is a difference between your window resolution and framebuffer resolution.
|
// or if there is a difference between your window resolution and framebuffer resolution.
|
||||||
void ImDrawData::ScaleClipRects(const ImVec2& fb_scale)
|
void ImDrawData::ScaleClipRects(const ImVec2& fb_scale)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < CmdListsCount; i++)
|
for (ImDrawList* draw_list : CmdLists)
|
||||||
{
|
for (ImDrawCmd& cmd : draw_list->CmdBuffer)
|
||||||
ImDrawList* cmd_list = CmdLists[i];
|
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);
|
||||||
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 * fb_scale.x, cmd->ClipRect.y * fb_scale.y, cmd->ClipRect.z * fb_scale.x, cmd->ClipRect.w * fb_scale.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1904,6 +1989,14 @@ void ImGui::ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int ve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::ShadeVertsTransformPos(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& pivot_in, float cos_a, float sin_a, const ImVec2& pivot_out)
|
||||||
|
{
|
||||||
|
ImDrawVert* vert_start = draw_list->VtxBuffer.Data + vert_start_idx;
|
||||||
|
ImDrawVert* vert_end = draw_list->VtxBuffer.Data + vert_end_idx;
|
||||||
|
for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex)
|
||||||
|
vertex->pos = ImRotate(vertex->pos- pivot_in, cos_a, sin_a) + pivot_out;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ImFontConfig
|
// [SECTION] ImFontConfig
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1912,10 +2005,11 @@ ImFontConfig::ImFontConfig()
|
||||||
{
|
{
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
FontDataOwnedByAtlas = true;
|
FontDataOwnedByAtlas = true;
|
||||||
OversampleH = 3; // FIXME: 2 may be a better default?
|
OversampleH = 2;
|
||||||
OversampleV = 1;
|
OversampleV = 1;
|
||||||
GlyphMaxAdvanceX = FLT_MAX;
|
GlyphMaxAdvanceX = FLT_MAX;
|
||||||
RasterizerMultiply = 1.0f;
|
RasterizerMultiply = 1.0f;
|
||||||
|
RasterizerDensity = 1.0f;
|
||||||
EllipsisChar = (ImWchar)-1;
|
EllipsisChar = (ImWchar)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,19 +2083,19 @@ ImFontAtlas::~ImFontAtlas()
|
||||||
void ImFontAtlas::ClearInputData()
|
void ImFontAtlas::ClearInputData()
|
||||||
{
|
{
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||||
for (int i = 0; i < ConfigData.Size; i++)
|
for (ImFontConfig& font_cfg : ConfigData)
|
||||||
if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas)
|
if (font_cfg.FontData && font_cfg.FontDataOwnedByAtlas)
|
||||||
{
|
{
|
||||||
IM_FREE(ConfigData[i].FontData);
|
IM_FREE(font_cfg.FontData);
|
||||||
ConfigData[i].FontData = NULL;
|
font_cfg.FontData = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When clearing this we lose access to the font name and other information used to build the font.
|
// When clearing this we lose access to the font name and other information used to build the font.
|
||||||
for (int i = 0; i < Fonts.Size; i++)
|
for (ImFont* font : Fonts)
|
||||||
if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size)
|
if (font->ConfigData >= ConfigData.Data && font->ConfigData < ConfigData.Data + ConfigData.Size)
|
||||||
{
|
{
|
||||||
Fonts[i]->ConfigData = NULL;
|
font->ConfigData = NULL;
|
||||||
Fonts[i]->ConfigDataCount = 0;
|
font->ConfigDataCount = 0;
|
||||||
}
|
}
|
||||||
ConfigData.clear();
|
ConfigData.clear();
|
||||||
CustomRects.clear();
|
CustomRects.clear();
|
||||||
|
@ -2098,6 +2192,8 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
||||||
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
|
if (new_font_cfg.DstFont->EllipsisChar == (ImWchar)-1)
|
||||||
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
|
new_font_cfg.DstFont->EllipsisChar = font_cfg->EllipsisChar;
|
||||||
|
|
||||||
|
ImFontAtlasUpdateConfigDataPointers(this);
|
||||||
|
|
||||||
// Invalidate texture
|
// Invalidate texture
|
||||||
TexReady = false;
|
TexReady = false;
|
||||||
ClearTexData();
|
ClearTexData();
|
||||||
|
@ -2134,7 +2230,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||||
if (font_cfg.Name[0] == '\0')
|
if (font_cfg.Name[0] == '\0')
|
||||||
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
|
ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "ProggyClean.ttf, %dpx", (int)font_cfg.SizePixels);
|
||||||
font_cfg.EllipsisChar = (ImWchar)0x0085;
|
font_cfg.EllipsisChar = (ImWchar)0x0085;
|
||||||
font_cfg.GlyphOffset.y = 1.0f * IM_FLOOR(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
font_cfg.GlyphOffset.y = 1.0f * IM_TRUNC(font_cfg.SizePixels / 13.0f); // Add +1 offset per 13 units
|
||||||
|
|
||||||
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
|
const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85();
|
||||||
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
|
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
|
||||||
|
@ -2164,13 +2260,14 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
|
// NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build().
|
||||||
ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
|
ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* font_data, int font_data_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges)
|
||||||
{
|
{
|
||||||
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!");
|
||||||
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig();
|
||||||
IM_ASSERT(font_cfg.FontData == NULL);
|
IM_ASSERT(font_cfg.FontData == NULL);
|
||||||
font_cfg.FontData = ttf_data;
|
IM_ASSERT(font_data_size > 100 && "Incorrect value for font_data_size!"); // Heuristic to prevent accidentally passing a wrong value to font_data_size.
|
||||||
font_cfg.FontDataSize = ttf_size;
|
font_cfg.FontData = font_data;
|
||||||
|
font_cfg.FontDataSize = font_data_size;
|
||||||
font_cfg.SizePixels = size_pixels > 0.0f ? size_pixels : font_cfg.SizePixels;
|
font_cfg.SizePixels = size_pixels > 0.0f ? size_pixels : font_cfg.SizePixels;
|
||||||
if (glyph_ranges)
|
if (glyph_ranges)
|
||||||
font_cfg.GlyphRanges = glyph_ranges;
|
font_cfg.GlyphRanges = glyph_ranges;
|
||||||
|
@ -2298,10 +2395,11 @@ void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], fl
|
||||||
|
|
||||||
void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride)
|
void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride)
|
||||||
{
|
{
|
||||||
|
IM_ASSERT_PARANOID(w <= stride);
|
||||||
unsigned char* data = pixels + x + y * stride;
|
unsigned char* data = pixels + x + y * stride;
|
||||||
for (int j = h; j > 0; j--, data += stride)
|
for (int j = h; j > 0; j--, data += stride - w)
|
||||||
for (int i = 0; i < w; i++)
|
for (int i = w; i > 0; i--, data++)
|
||||||
data[i] = table[data[i]];
|
*data = table[*data];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||||
|
@ -2318,7 +2416,7 @@ struct ImFontBuildSrcData
|
||||||
int GlyphsHighest; // Highest requested codepoint
|
int GlyphsHighest; // Highest requested codepoint
|
||||||
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
|
int GlyphsCount; // Glyph count (excluding missing glyphs and glyphs already set by an earlier source font)
|
||||||
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
|
ImBitVector GlyphsSet; // Glyph bit map (random access, 1-bit per codepoint. This will be a maximum of 8KB)
|
||||||
ImVector<int> GlyphsList; // Glyph codepoints list (flattened version of GlyphsMap)
|
ImVector<int> GlyphsList; // Glyph codepoints list (flattened version of GlyphsSet)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
|
// Temporary data for one destination ImFont* (multiple source fonts can be merged into one destination ImFont)
|
||||||
|
@ -2384,13 +2482,21 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
|
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
|
||||||
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
|
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");
|
||||||
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
|
if (!stbtt_InitFont(&src_tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset))
|
||||||
|
{
|
||||||
|
IM_ASSERT(0 && "stbtt_InitFont(): failed to parse FontData. It is correct and complete? Check FontDataSize.");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Measure highest codepoints
|
// Measure highest codepoints
|
||||||
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
ImFontBuildDstData& dst_tmp = dst_tmp_array[src_tmp.DstIndex];
|
||||||
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
src_tmp.SrcRanges = cfg.GlyphRanges ? cfg.GlyphRanges : atlas->GetGlyphRangesDefault();
|
||||||
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
for (const ImWchar* src_range = src_tmp.SrcRanges; src_range[0] && src_range[1]; src_range += 2)
|
||||||
|
{
|
||||||
|
// Check for valid range. This may also help detect *some* dangling pointers, because a common
|
||||||
|
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent.
|
||||||
|
IM_ASSERT(src_range[0] <= src_range[1]);
|
||||||
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
|
src_tmp.GlyphsHighest = ImMax(src_tmp.GlyphsHighest, (int)src_range[1]);
|
||||||
|
}
|
||||||
dst_tmp.SrcCount++;
|
dst_tmp.SrcCount++;
|
||||||
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
|
dst_tmp.GlyphsHighest = ImMax(dst_tmp.GlyphsHighest, src_tmp.GlyphsHighest);
|
||||||
}
|
}
|
||||||
|
@ -2461,7 +2567,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
|
|
||||||
// Convert our ranges in the format stb_truetype wants
|
// Convert our ranges in the format stb_truetype wants
|
||||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||||
src_tmp.PackRange.font_size = cfg.SizePixels;
|
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
|
||||||
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
|
src_tmp.PackRange.first_unicode_codepoint_in_range = 0;
|
||||||
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
|
src_tmp.PackRange.array_of_unicode_codepoints = src_tmp.GlyphsList.Data;
|
||||||
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
|
src_tmp.PackRange.num_chars = src_tmp.GlyphsList.Size;
|
||||||
|
@ -2470,7 +2576,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
|
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
|
||||||
|
|
||||||
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
|
// Gather the sizes of all rectangles we will need to pack (this loop is based on stbtt_PackFontRangesGatherRects)
|
||||||
const float scale = (cfg.SizePixels > 0) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels);
|
const float scale = (cfg.SizePixels > 0.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
|
||||||
const int padding = atlas->TexGlyphPadding;
|
const int padding = atlas->TexGlyphPadding;
|
||||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsList.Size; glyph_i++)
|
||||||
{
|
{
|
||||||
|
@ -2555,13 +2661,10 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
// 9. Setup ImFont and glyphs for runtime
|
// 9. Setup ImFont and glyphs for runtime
|
||||||
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
for (int src_i = 0; src_i < src_tmp_array.Size; src_i++)
|
||||||
{
|
{
|
||||||
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
|
||||||
if (src_tmp.GlyphsCount == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// When merging fonts with MergeMode=true:
|
// When merging fonts with MergeMode=true:
|
||||||
// - We can have multiple input fonts writing into a same destination font.
|
// - We can have multiple input fonts writing into a same destination font.
|
||||||
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
// - dst_font->ConfigData is != from cfg which is our source configuration.
|
||||||
|
ImFontBuildSrcData& src_tmp = src_tmp_array[src_i];
|
||||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||||
ImFont* dst_font = cfg.DstFont;
|
ImFont* dst_font = cfg.DstFont;
|
||||||
|
|
||||||
|
@ -2569,12 +2672,14 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
int unscaled_ascent, unscaled_descent, unscaled_line_gap;
|
||||||
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
|
stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap);
|
||||||
|
|
||||||
const float ascent = ImFloor(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
|
const float ascent = ImTrunc(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1));
|
||||||
const float descent = ImFloor(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
|
const float descent = ImTrunc(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1));
|
||||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||||
const float font_off_x = cfg.GlyphOffset.x;
|
const float font_off_x = cfg.GlyphOffset.x;
|
||||||
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent);
|
||||||
|
|
||||||
|
const float inv_rasterization_scale = 1.0f / cfg.RasterizerDensity;
|
||||||
|
|
||||||
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
for (int glyph_i = 0; glyph_i < src_tmp.GlyphsCount; glyph_i++)
|
||||||
{
|
{
|
||||||
// Register glyph
|
// Register glyph
|
||||||
|
@ -2583,7 +2688,11 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
||||||
stbtt_aligned_quad q;
|
stbtt_aligned_quad q;
|
||||||
float unused_x = 0.0f, unused_y = 0.0f;
|
float unused_x = 0.0f, unused_y = 0.0f;
|
||||||
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
|
stbtt_GetPackedQuad(src_tmp.PackedChars, atlas->TexWidth, atlas->TexHeight, glyph_i, &unused_x, &unused_y, &q, 0);
|
||||||
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, q.x0 + font_off_x, q.y0 + font_off_y, q.x1 + font_off_x, q.y1 + font_off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance);
|
float x0 = q.x0 * inv_rasterization_scale + font_off_x;
|
||||||
|
float y0 = q.y0 * inv_rasterization_scale + font_off_y;
|
||||||
|
float x1 = q.x1 * inv_rasterization_scale + font_off_x;
|
||||||
|
float y1 = q.y1 * inv_rasterization_scale + font_off_y;
|
||||||
|
dst_font->AddGlyph(&cfg, (ImWchar)codepoint, x0, y0, x1, y1, q.s0, q.t0, q.s1, q.t1, pc.xadvance * inv_rasterization_scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2603,19 +2712,31 @@ const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype()
|
||||||
|
|
||||||
#endif // IMGUI_ENABLE_STB_TRUETYPE
|
#endif // IMGUI_ENABLE_STB_TRUETYPE
|
||||||
|
|
||||||
|
void ImFontAtlasUpdateConfigDataPointers(ImFontAtlas* atlas)
|
||||||
|
{
|
||||||
|
for (ImFontConfig& font_cfg : atlas->ConfigData)
|
||||||
|
{
|
||||||
|
ImFont* font = font_cfg.DstFont;
|
||||||
|
if (!font_cfg.MergeMode)
|
||||||
|
{
|
||||||
|
font->ConfigData = &font_cfg;
|
||||||
|
font->ConfigDataCount = 0;
|
||||||
|
}
|
||||||
|
font->ConfigDataCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
|
void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent)
|
||||||
{
|
{
|
||||||
if (!font_config->MergeMode)
|
if (!font_config->MergeMode)
|
||||||
{
|
{
|
||||||
font->ClearOutputData();
|
font->ClearOutputData();
|
||||||
font->FontSize = font_config->SizePixels;
|
font->FontSize = font_config->SizePixels;
|
||||||
font->ConfigData = font_config;
|
IM_ASSERT(font->ConfigData == font_config);
|
||||||
font->ConfigDataCount = 0;
|
|
||||||
font->ContainerAtlas = atlas;
|
font->ContainerAtlas = atlas;
|
||||||
font->Ascent = ascent;
|
font->Ascent = ascent;
|
||||||
font->Descent = descent;
|
font->Descent = descent;
|
||||||
}
|
}
|
||||||
font->ConfigDataCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
|
void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque)
|
||||||
|
@ -2625,6 +2746,9 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
|
||||||
|
|
||||||
ImVector<ImFontAtlasCustomRect>& user_rects = atlas->CustomRects;
|
ImVector<ImFontAtlasCustomRect>& 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.
|
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
|
||||||
|
#ifdef __GNUC__
|
||||||
|
if (user_rects.Size < 1) { __builtin_unreachable(); } // Workaround for GCC bug if IM_ASSERT() is defined to conditionally throw (see #5343)
|
||||||
|
#endif
|
||||||
|
|
||||||
ImVector<stbrp_rect> pack_rects;
|
ImVector<stbrp_rect> pack_rects;
|
||||||
pack_rects.resize(user_rects.Size);
|
pack_rects.resize(user_rects.Size);
|
||||||
|
@ -2759,6 +2883,13 @@ static void ImFontAtlasBuildRenderLinesTexData(ImFontAtlas* atlas)
|
||||||
// Note: this is called / shared by both the stb_truetype and the FreeType builder
|
// Note: this is called / shared by both the stb_truetype and the FreeType builder
|
||||||
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
void ImFontAtlasBuildInit(ImFontAtlas* atlas)
|
||||||
{
|
{
|
||||||
|
// Round font size
|
||||||
|
// - We started rounding in 1.90 WIP (18991) as our layout system currently doesn't support non-rounded font size well yet.
|
||||||
|
// - Note that using io.FontGlobalScale or SetWindowFontScale(), with are legacy-ish, partially supported features, can still lead to unrounded sizes.
|
||||||
|
// - We may support it better later and remove this rounding.
|
||||||
|
for (ImFontConfig& cfg : atlas->ConfigData)
|
||||||
|
cfg.SizePixels = ImTrunc(cfg.SizePixels);
|
||||||
|
|
||||||
// Register texture region for mouse cursors or standard white pixels
|
// Register texture region for mouse cursors or standard white pixels
|
||||||
if (atlas->PackIdMouseCursors < 0)
|
if (atlas->PackIdMouseCursors < 0)
|
||||||
{
|
{
|
||||||
|
@ -2800,9 +2931,9 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build all fonts lookup tables
|
// Build all fonts lookup tables
|
||||||
for (int i = 0; i < atlas->Fonts.Size; i++)
|
for (ImFont* font : atlas->Fonts)
|
||||||
if (atlas->Fonts[i]->DirtyLookupTables)
|
if (font->DirtyLookupTables)
|
||||||
atlas->Fonts[i]->BuildLookupTable();
|
font->BuildLookupTable();
|
||||||
|
|
||||||
atlas->TexReady = true;
|
atlas->TexReady = true;
|
||||||
}
|
}
|
||||||
|
@ -2818,6 +2949,17 @@ const ImWchar* ImFontAtlas::GetGlyphRangesDefault()
|
||||||
return &ranges[0];
|
return &ranges[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ImWchar* ImFontAtlas::GetGlyphRangesGreek()
|
||||||
|
{
|
||||||
|
static const ImWchar ranges[] =
|
||||||
|
{
|
||||||
|
0x0020, 0x00FF, // Basic Latin + Latin Supplement
|
||||||
|
0x0370, 0x03FF, // Greek and Coptic
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
return &ranges[0];
|
||||||
|
}
|
||||||
|
|
||||||
const ImWchar* ImFontAtlas::GetGlyphRangesKorean()
|
const ImWchar* ImFontAtlas::GetGlyphRangesKorean()
|
||||||
{
|
{
|
||||||
static const ImWchar ranges[] =
|
static const ImWchar ranges[] =
|
||||||
|
@ -2934,19 +3076,19 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese()
|
||||||
// 2999 ideograms code points for Japanese
|
// 2999 ideograms code points for Japanese
|
||||||
// - 2136 Joyo (meaning "for regular use" or "for common use") Kanji code points
|
// - 2136 Joyo (meaning "for regular use" or "for common use") Kanji code points
|
||||||
// - 863 Jinmeiyo (meaning "for personal name") Kanji code points
|
// - 863 Jinmeiyo (meaning "for personal name") Kanji code points
|
||||||
// - Sourced from the character information database of the Information-technology Promotion Agency, Japan
|
// - Sourced from official information provided by the government agencies of Japan:
|
||||||
// - https://mojikiban.ipa.go.jp/mji/
|
// - List of Joyo Kanji by the Agency for Cultural Affairs
|
||||||
// - Available under the terms of the Creative Commons Attribution-ShareAlike 2.1 Japan (CC BY-SA 2.1 JP).
|
// - https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kijun/naikaku/kanji/
|
||||||
// - https://creativecommons.org/licenses/by-sa/2.1/jp/deed.en
|
// - List of Jinmeiyo Kanji by the Ministry of Justice
|
||||||
// - https://creativecommons.org/licenses/by-sa/2.1/jp/legalcode
|
// - http://www.moj.go.jp/MINJI/minji86.html
|
||||||
// - You can generate this code by the script at:
|
// - Available under the terms of the Creative Commons Attribution 4.0 International (CC BY 4.0).
|
||||||
// - https://github.com/vaiorabbit/everyday_use_kanji
|
// - https://creativecommons.org/licenses/by/4.0/legalcode
|
||||||
|
// - You can generate this code by the script at:
|
||||||
|
// - https://github.com/vaiorabbit/everyday_use_kanji
|
||||||
// - References:
|
// - References:
|
||||||
// - List of Joyo Kanji
|
// - List of Joyo Kanji
|
||||||
// - (Official list by the Agency for Cultural Affairs) https://www.bunka.go.jp/kokugo_nihongo/sisaku/joho/joho/kakuki/14/tosin02/index.html
|
|
||||||
// - (Wikipedia) https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji
|
// - (Wikipedia) https://en.wikipedia.org/wiki/List_of_j%C5%8Dy%C5%8D_kanji
|
||||||
// - List of Jinmeiyo Kanji
|
// - List of Jinmeiyo Kanji
|
||||||
// - (Official list by the Ministry of Justice) http://www.moj.go.jp/MINJI/minji86.html
|
|
||||||
// - (Wikipedia) https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji
|
// - (Wikipedia) https://en.wikipedia.org/wiki/Jinmeiy%C5%8D_kanji
|
||||||
// - Missing 1 Joyo Kanji: U+20B9F (Kun'yomi: Shikaru, On'yomi: Shitsu,shichi), see https://github.com/ocornut/imgui/pull/3627 for details.
|
// - Missing 1 Joyo Kanji: U+20B9F (Kun'yomi: Shikaru, On'yomi: Shitsu,shichi), see https://github.com/ocornut/imgui/pull/3627 for details.
|
||||||
// You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
|
// You can use ImFontGlyphRangesBuilder to create your own ranges derived from this, by merging existing ranges or adding new characters.
|
||||||
|
@ -3109,7 +3251,8 @@ ImFont::ImFont()
|
||||||
FallbackAdvanceX = 0.0f;
|
FallbackAdvanceX = 0.0f;
|
||||||
FallbackChar = (ImWchar)-1;
|
FallbackChar = (ImWchar)-1;
|
||||||
EllipsisChar = (ImWchar)-1;
|
EllipsisChar = (ImWchar)-1;
|
||||||
DotChar = (ImWchar)-1;
|
EllipsisWidth = EllipsisCharStep = 0.0f;
|
||||||
|
EllipsisCharCount = 0;
|
||||||
FallbackGlyph = NULL;
|
FallbackGlyph = NULL;
|
||||||
ContainerAtlas = NULL;
|
ContainerAtlas = NULL;
|
||||||
ConfigData = NULL;
|
ConfigData = NULL;
|
||||||
|
@ -3155,6 +3298,7 @@ void ImFont::BuildLookupTable()
|
||||||
max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
|
max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
|
||||||
|
|
||||||
// Build lookup table
|
// Build lookup table
|
||||||
|
IM_ASSERT(Glyphs.Size > 0 && "Font has not loaded glyph!");
|
||||||
IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
|
IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
|
||||||
IndexAdvanceX.clear();
|
IndexAdvanceX.clear();
|
||||||
IndexLookup.clear();
|
IndexLookup.clear();
|
||||||
|
@ -3190,17 +3334,7 @@ void ImFont::BuildLookupTable()
|
||||||
SetGlyphVisible((ImWchar)' ', false);
|
SetGlyphVisible((ImWchar)' ', false);
|
||||||
SetGlyphVisible((ImWchar)'\t', false);
|
SetGlyphVisible((ImWchar)'\t', false);
|
||||||
|
|
||||||
// Ellipsis character is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
|
// Setup Fallback character
|
||||||
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
|
|
||||||
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
|
|
||||||
const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 };
|
|
||||||
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
|
|
||||||
if (EllipsisChar == (ImWchar)-1)
|
|
||||||
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
|
|
||||||
if (DotChar == (ImWchar)-1)
|
|
||||||
DotChar = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars));
|
|
||||||
|
|
||||||
// Setup fallback character
|
|
||||||
const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' };
|
const ImWchar fallback_chars[] = { (ImWchar)IM_UNICODE_CODEPOINT_INVALID, (ImWchar)'?', (ImWchar)' ' };
|
||||||
FallbackGlyph = FindGlyphNoFallback(FallbackChar);
|
FallbackGlyph = FindGlyphNoFallback(FallbackChar);
|
||||||
if (FallbackGlyph == NULL)
|
if (FallbackGlyph == NULL)
|
||||||
|
@ -3213,11 +3347,32 @@ void ImFont::BuildLookupTable()
|
||||||
FallbackChar = (ImWchar)FallbackGlyph->Codepoint;
|
FallbackChar = (ImWchar)FallbackGlyph->Codepoint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FallbackAdvanceX = FallbackGlyph->AdvanceX;
|
FallbackAdvanceX = FallbackGlyph->AdvanceX;
|
||||||
for (int i = 0; i < max_codepoint + 1; i++)
|
for (int i = 0; i < max_codepoint + 1; i++)
|
||||||
if (IndexAdvanceX[i] < 0.0f)
|
if (IndexAdvanceX[i] < 0.0f)
|
||||||
IndexAdvanceX[i] = FallbackAdvanceX;
|
IndexAdvanceX[i] = FallbackAdvanceX;
|
||||||
|
|
||||||
|
// Setup Ellipsis character. It is required for rendering elided text. We prefer using U+2026 (horizontal ellipsis).
|
||||||
|
// However some old fonts may contain ellipsis at U+0085. Here we auto-detect most suitable ellipsis character.
|
||||||
|
// FIXME: Note that 0x2026 is rarely included in our font ranges. Because of this we are more likely to use three individual dots.
|
||||||
|
const ImWchar ellipsis_chars[] = { (ImWchar)0x2026, (ImWchar)0x0085 };
|
||||||
|
const ImWchar dots_chars[] = { (ImWchar)'.', (ImWchar)0xFF0E };
|
||||||
|
if (EllipsisChar == (ImWchar)-1)
|
||||||
|
EllipsisChar = FindFirstExistingGlyph(this, ellipsis_chars, IM_ARRAYSIZE(ellipsis_chars));
|
||||||
|
const ImWchar dot_char = FindFirstExistingGlyph(this, dots_chars, IM_ARRAYSIZE(dots_chars));
|
||||||
|
if (EllipsisChar != (ImWchar)-1)
|
||||||
|
{
|
||||||
|
EllipsisCharCount = 1;
|
||||||
|
EllipsisWidth = EllipsisCharStep = FindGlyph(EllipsisChar)->X1;
|
||||||
|
}
|
||||||
|
else if (dot_char != (ImWchar)-1)
|
||||||
|
{
|
||||||
|
const ImFontGlyph* glyph = FindGlyph(dot_char);
|
||||||
|
EllipsisChar = dot_char;
|
||||||
|
EllipsisCharCount = 3;
|
||||||
|
EllipsisCharStep = (glyph->X1 - glyph->X0) + 1.0f;
|
||||||
|
EllipsisWidth = EllipsisCharStep * 3.0f - 1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// API is designed this way to avoid exposing the 4K page size
|
// API is designed this way to avoid exposing the 4K page size
|
||||||
|
@ -3260,7 +3415,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
|
||||||
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
|
advance_x = ImClamp(advance_x, cfg->GlyphMinAdvanceX, cfg->GlyphMaxAdvanceX);
|
||||||
if (advance_x != advance_x_original)
|
if (advance_x != advance_x_original)
|
||||||
{
|
{
|
||||||
float char_off_x = cfg->PixelSnapH ? ImFloor((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
float char_off_x = cfg->PixelSnapH ? ImTrunc((advance_x - advance_x_original) * 0.5f) : (advance_x - advance_x_original) * 0.5f;
|
||||||
x0 += char_off_x;
|
x0 += char_off_x;
|
||||||
x1 += char_off_x;
|
x1 += char_off_x;
|
||||||
}
|
}
|
||||||
|
@ -3330,11 +3485,21 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c) const
|
||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrapping skips upcoming blanks
|
||||||
|
static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end)
|
||||||
|
{
|
||||||
|
while (text < text_end && ImCharIsBlankA(*text))
|
||||||
|
text++;
|
||||||
|
if (*text == '\n')
|
||||||
|
text++;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||||
|
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||||
|
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||||
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const
|
const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const
|
||||||
{
|
{
|
||||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
|
||||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
|
||||||
|
|
||||||
// For references, possible wrap point marked with ^
|
// For references, possible wrap point marked with ^
|
||||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||||
// ^ ^ ^ ^ ^__ ^ ^
|
// ^ ^ ^ ^ ^__ ^ ^
|
||||||
|
@ -3346,7 +3511,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||||
|
|
||||||
// Cut words that cannot possibly fit within one line.
|
// Cut words that cannot possibly fit within one line.
|
||||||
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
|
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
|
||||||
|
|
||||||
float line_width = 0.0f;
|
float line_width = 0.0f;
|
||||||
float word_width = 0.0f;
|
float word_width = 0.0f;
|
||||||
float blank_width = 0.0f;
|
float blank_width = 0.0f;
|
||||||
|
@ -3357,6 +3521,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||||
bool inside_word = true;
|
bool inside_word = true;
|
||||||
|
|
||||||
const char* s = text;
|
const char* s = text;
|
||||||
|
IM_ASSERT(text_end != NULL);
|
||||||
while (s < text_end)
|
while (s < text_end)
|
||||||
{
|
{
|
||||||
unsigned int c = (unsigned int)*s;
|
unsigned int c = (unsigned int)*s;
|
||||||
|
@ -3365,8 +3530,6 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||||
next_s = s + 1;
|
next_s = s + 1;
|
||||||
else
|
else
|
||||||
next_s = s + ImTextCharFromUtf8(&c, s, text_end);
|
next_s = s + ImTextCharFromUtf8(&c, s, text_end);
|
||||||
if (c == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (c < 32)
|
if (c < 32)
|
||||||
{
|
{
|
||||||
|
@ -3426,6 +3589,10 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
|
||||||
s = next_s;
|
s = next_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
||||||
|
// +1 may not be a character start point in UTF-8 but it's ok because caller loops use (text >= word_wrap_eol).
|
||||||
|
if (s == text && text < text_end)
|
||||||
|
return s + 1;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3450,11 +3617,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||||
{
|
{
|
||||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||||
if (!word_wrap_eol)
|
if (!word_wrap_eol)
|
||||||
{
|
|
||||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width);
|
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width);
|
||||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
|
||||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s >= word_wrap_eol)
|
if (s >= word_wrap_eol)
|
||||||
{
|
{
|
||||||
|
@ -3463,13 +3626,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||||
text_size.y += line_height;
|
text_size.y += line_height;
|
||||||
line_width = 0.0f;
|
line_width = 0.0f;
|
||||||
word_wrap_eol = NULL;
|
word_wrap_eol = NULL;
|
||||||
|
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
|
||||||
// Wrapping skips upcoming blanks
|
|
||||||
while (s < text_end)
|
|
||||||
{
|
|
||||||
const char c = *s;
|
|
||||||
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3478,15 +3635,9 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||||
const char* prev_s = s;
|
const char* prev_s = s;
|
||||||
unsigned int c = (unsigned int)*s;
|
unsigned int c = (unsigned int)*s;
|
||||||
if (c < 0x80)
|
if (c < 0x80)
|
||||||
{
|
|
||||||
s += 1;
|
s += 1;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
s += ImTextCharFromUtf8(&c, s, text_end);
|
s += ImTextCharFromUtf8(&c, s, text_end);
|
||||||
if (c == 0) // Malformed UTF-8?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c < 32)
|
if (c < 32)
|
||||||
{
|
{
|
||||||
|
@ -3532,8 +3683,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
if (glyph->Colored)
|
if (glyph->Colored)
|
||||||
col |= ~IM_COL32_A_MASK;
|
col |= ~IM_COL32_A_MASK;
|
||||||
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
|
float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f;
|
||||||
float x = IM_FLOOR(pos.x);
|
float x = IM_TRUNC(pos.x);
|
||||||
float y = IM_FLOOR(pos.y);
|
float y = IM_TRUNC(pos.y);
|
||||||
draw_list->PrimReserve(6, 4);
|
draw_list->PrimReserve(6, 4);
|
||||||
draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
|
draw_list->PrimRectUV(ImVec2(x + glyph->X0 * scale, y + glyph->Y0 * scale), ImVec2(x + glyph->X1 * scale, y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col);
|
||||||
}
|
}
|
||||||
|
@ -3545,8 +3696,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||||
|
|
||||||
// Align to be pixel perfect
|
// Align to be pixel perfect
|
||||||
float x = IM_FLOOR(pos.x);
|
float x = IM_TRUNC(pos.x);
|
||||||
float y = IM_FLOOR(pos.y);
|
float y = IM_TRUNC(pos.y);
|
||||||
if (y > clip_rect.w)
|
if (y > clip_rect.w)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3554,15 +3705,25 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
const float scale = size / FontSize;
|
const float scale = size / FontSize;
|
||||||
const float line_height = FontSize * scale;
|
const float line_height = FontSize * scale;
|
||||||
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
const bool word_wrap_enabled = (wrap_width > 0.0f);
|
||||||
const char* word_wrap_eol = NULL;
|
|
||||||
|
|
||||||
// Fast-forward to first visible line
|
// Fast-forward to first visible line
|
||||||
const char* s = text_begin;
|
const char* s = text_begin;
|
||||||
if (y + line_height < clip_rect.y && !word_wrap_enabled)
|
if (y + line_height < clip_rect.y)
|
||||||
while (y + line_height < clip_rect.y && s < text_end)
|
while (y + line_height < clip_rect.y && s < text_end)
|
||||||
{
|
{
|
||||||
s = (const char*)memchr(s, '\n', text_end - s);
|
const char* line_end = (const char*)memchr(s, '\n', text_end - s);
|
||||||
s = s ? s + 1 : text_end;
|
if (word_wrap_enabled)
|
||||||
|
{
|
||||||
|
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
|
||||||
|
// If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both.
|
||||||
|
// However it is still better than nothing performing the fast-forward!
|
||||||
|
s = CalcWordWrapPositionA(scale, s, line_end ? line_end : text_end, wrap_width);
|
||||||
|
s = CalcWordWrapNextLineStartA(s, text_end);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = line_end ? line_end + 1 : text_end;
|
||||||
|
}
|
||||||
y += line_height;
|
y += line_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3588,12 +3749,12 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
const int idx_count_max = (int)(text_end - s) * 6;
|
const int idx_count_max = (int)(text_end - s) * 6;
|
||||||
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
|
const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max;
|
||||||
draw_list->PrimReserve(idx_count_max, vtx_count_max);
|
draw_list->PrimReserve(idx_count_max, vtx_count_max);
|
||||||
|
ImDrawVert* vtx_write = draw_list->_VtxWritePtr;
|
||||||
ImDrawVert* vtx_write = draw_list->_VtxWritePtr;
|
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
|
||||||
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
|
unsigned int vtx_index = draw_list->_VtxCurrentIdx;
|
||||||
unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx;
|
|
||||||
|
|
||||||
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
||||||
|
const char* word_wrap_eol = NULL;
|
||||||
|
|
||||||
while (s < text_end)
|
while (s < text_end)
|
||||||
{
|
{
|
||||||
|
@ -3601,24 +3762,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
{
|
{
|
||||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||||
if (!word_wrap_eol)
|
if (!word_wrap_eol)
|
||||||
{
|
|
||||||
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x));
|
word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - start_x));
|
||||||
if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity.
|
|
||||||
word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s >= word_wrap_eol)
|
if (s >= word_wrap_eol)
|
||||||
{
|
{
|
||||||
x = start_x;
|
x = start_x;
|
||||||
y += line_height;
|
y += line_height;
|
||||||
word_wrap_eol = NULL;
|
word_wrap_eol = NULL;
|
||||||
|
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
|
||||||
// Wrapping skips upcoming blanks
|
|
||||||
while (s < text_end)
|
|
||||||
{
|
|
||||||
const char c = *s;
|
|
||||||
if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; }
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3626,15 +3777,9 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
// Decode and advance source
|
// Decode and advance source
|
||||||
unsigned int c = (unsigned int)*s;
|
unsigned int c = (unsigned int)*s;
|
||||||
if (c < 0x80)
|
if (c < 0x80)
|
||||||
{
|
|
||||||
s += 1;
|
s += 1;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
s += ImTextCharFromUtf8(&c, s, text_end);
|
s += ImTextCharFromUtf8(&c, s, text_end);
|
||||||
if (c == 0) // Malformed UTF-8?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c < 32)
|
if (c < 32)
|
||||||
{
|
{
|
||||||
|
@ -3705,14 +3850,14 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
|
|
||||||
// We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here:
|
// We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here:
|
||||||
{
|
{
|
||||||
idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2);
|
|
||||||
idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3);
|
|
||||||
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
|
vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = glyph_col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1;
|
||||||
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
|
vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = glyph_col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1;
|
||||||
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
|
vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = glyph_col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2;
|
||||||
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
|
vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = glyph_col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2;
|
||||||
|
idx_write[0] = (ImDrawIdx)(vtx_index); idx_write[1] = (ImDrawIdx)(vtx_index + 1); idx_write[2] = (ImDrawIdx)(vtx_index + 2);
|
||||||
|
idx_write[3] = (ImDrawIdx)(vtx_index); idx_write[4] = (ImDrawIdx)(vtx_index + 2); idx_write[5] = (ImDrawIdx)(vtx_index + 3);
|
||||||
vtx_write += 4;
|
vtx_write += 4;
|
||||||
vtx_current_idx += 4;
|
vtx_index += 4;
|
||||||
idx_write += 6;
|
idx_write += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3726,7 +3871,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||||
draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size);
|
draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size);
|
||||||
draw_list->_VtxWritePtr = vtx_write;
|
draw_list->_VtxWritePtr = vtx_write;
|
||||||
draw_list->_IdxWritePtr = idx_write;
|
draw_list->_IdxWritePtr = idx_write;
|
||||||
draw_list->_VtxCurrentIdx = vtx_current_idx;
|
draw_list->_VtxCurrentIdx = vtx_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -3778,6 +3923,7 @@ void ImGui::RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir d
|
||||||
|
|
||||||
void ImGui::RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col)
|
void ImGui::RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col)
|
||||||
{
|
{
|
||||||
|
// FIXME-OPT: This should be baked in font.
|
||||||
draw_list->AddCircleFilled(pos, draw_list->_Data->FontSize * 0.20f, col, 8);
|
draw_list->AddCircleFilled(pos, draw_list->_Data->FontSize * 0.20f, col, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4059,8 +4205,8 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// ProggyClean.ttf
|
// ProggyClean.ttf
|
||||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||||
// MIT license (see License.txt in http://www.upperbounds.net/download/ProggyClean.ttf.zip)
|
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
|
||||||
// Download and more information at http://upperbounds.net
|
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// File: 'ProggyClean.ttf' (41208 bytes)
|
// File: 'ProggyClean.ttf' (41208 bytes)
|
||||||
// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).
|
// Exported using misc/fonts/binary_to_compressed_c.cpp (with compression + base85 string encoding).
|
||||||
|
|
|
@ -4,9 +4,18 @@
|
||||||
// Changelog:
|
// Changelog:
|
||||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||||
|
|
||||||
|
// See more C++ related extension (fmt, RAII, syntaxis sugar) on Wiki:
|
||||||
|
// https://github.com/ocornut/imgui/wiki/Useful-Extensions#cness
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_stdlib.h"
|
#include "imgui_stdlib.h"
|
||||||
|
|
||||||
|
// Clang warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
struct InputTextCallback_UserData
|
struct InputTextCallback_UserData
|
||||||
{
|
{
|
||||||
std::string* Str;
|
std::string* Str;
|
||||||
|
@ -70,3 +79,7 @@ bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string*
|
||||||
cb_user_data.ChainCallbackUserData = user_data;
|
cb_user_data.ChainCallbackUserData = user_data;
|
||||||
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
|
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -2008,7 +2008,7 @@ static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int gly
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fdselector == -1) stbtt__new_buf(NULL, 0);
|
if (fdselector == -1) return stbtt__new_buf(NULL, 0); // [DEAR IMGUI] fixed, see #6007 and nothings/stb#1422
|
||||||
return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
|
return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2628,8 +2628,8 @@ void Achievements::DrawLeaderboardsWindow()
|
||||||
const float tab_width = (ImGui::GetWindowWidth() / ImGuiFullscreen::g_layout_scale) * 0.5f;
|
const float tab_width = (ImGui::GetWindowWidth() / ImGuiFullscreen::g_layout_scale) * 0.5f;
|
||||||
ImGui::SetCursorPos(ImVec2(0.0f, top + spacing_small));
|
ImGui::SetCursorPos(ImVec2(0.0f, top + spacing_small));
|
||||||
|
|
||||||
if (ImGui::IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiNavReadMode_Pressed) ||
|
if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakSlow, false) ||
|
||||||
ImGui::IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiNavReadMode_Pressed))
|
ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakFast, false))
|
||||||
{
|
{
|
||||||
s_is_showing_all_leaderboard_entries = !s_is_showing_all_leaderboard_entries;
|
s_is_showing_all_leaderboard_entries = !s_is_showing_all_leaderboard_entries;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1454,7 +1454,7 @@ void FullscreenUI::DrawInputBindingButton(SettingsInterface* bsi, InputBindingIn
|
||||||
BeginInputBinding(bsi, type, section, name, display_name);
|
BeginInputBinding(bsi, type, section, name, display_name);
|
||||||
}
|
}
|
||||||
else if (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
else if (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
||||||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed))
|
ImGui::IsKeyPressed(ImGuiKey_NavGamepadInput, false))
|
||||||
{
|
{
|
||||||
bsi->DeleteValue(section, name);
|
bsi->DeleteValue(section, name);
|
||||||
SetSettingsChanged(bsi);
|
SetSettingsChanged(bsi);
|
||||||
|
@ -2596,12 +2596,12 @@ void FullscreenUI::DrawSettingsWindow()
|
||||||
|
|
||||||
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup))
|
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup))
|
||||||
{
|
{
|
||||||
if (ImGui::IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiNavReadMode_Pressed))
|
if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakSlow, false))
|
||||||
{
|
{
|
||||||
index = (index == 0) ? (count - 1) : (index - 1);
|
index = (index == 0) ? (count - 1) : (index - 1);
|
||||||
s_settings_page = pages[index];
|
s_settings_page = pages[index];
|
||||||
}
|
}
|
||||||
else if (ImGui::IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiNavReadMode_Pressed))
|
else if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakFast, false))
|
||||||
{
|
{
|
||||||
index = (index + 1) % count;
|
index = (index + 1) % count;
|
||||||
s_settings_page = pages[index];
|
s_settings_page = pages[index];
|
||||||
|
@ -5486,7 +5486,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
||||||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed)))
|
ImGui::IsKeyPressed(ImGuiKey_NavGamepadInput, false)))
|
||||||
{
|
{
|
||||||
s_save_state_selector_submenu_index = static_cast<s32>(i);
|
s_save_state_selector_submenu_index = static_cast<s32>(i);
|
||||||
}
|
}
|
||||||
|
@ -5770,12 +5770,12 @@ void FullscreenUI::DrawGameListWindow()
|
||||||
|
|
||||||
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup))
|
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup))
|
||||||
{
|
{
|
||||||
if (ImGui::IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiNavReadMode_Pressed))
|
if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakSlow, false))
|
||||||
{
|
{
|
||||||
s_game_list_page = static_cast<GameListPage>(
|
s_game_list_page = static_cast<GameListPage>(
|
||||||
(s_game_list_page == static_cast<GameListPage>(0)) ? (count - 1) : (static_cast<u32>(s_game_list_page) - 1));
|
(s_game_list_page == static_cast<GameListPage>(0)) ? (count - 1) : (static_cast<u32>(s_game_list_page) - 1));
|
||||||
}
|
}
|
||||||
else if (ImGui::IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiNavReadMode_Pressed))
|
else if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadTweakFast, false))
|
||||||
{
|
{
|
||||||
s_game_list_page = static_cast<GameListPage>((static_cast<u32>(s_game_list_page) + 1) % count);
|
s_game_list_page = static_cast<GameListPage>((static_cast<u32>(s_game_list_page) + 1) % count);
|
||||||
}
|
}
|
||||||
|
@ -5889,7 +5889,7 @@ void FullscreenUI::DrawGameList(const ImVec2& heading_size)
|
||||||
selected_entry = entry;
|
selected_entry = entry;
|
||||||
|
|
||||||
if (selected_entry && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
if (selected_entry && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
||||||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed)))
|
ImGui::IsKeyPressed(ImGuiKey_NavGamepadInput, false)))
|
||||||
{
|
{
|
||||||
HandleGameListOptions(selected_entry);
|
HandleGameListOptions(selected_entry);
|
||||||
}
|
}
|
||||||
|
@ -6107,7 +6107,7 @@ void FullscreenUI::DrawGameGrid(const ImVec2& heading_size)
|
||||||
HandleGameListActivate(entry);
|
HandleGameListActivate(entry);
|
||||||
|
|
||||||
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
|
||||||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed)))
|
ImGui::IsKeyPressed(ImGuiKey_NavGamepadInput, false)))
|
||||||
{
|
{
|
||||||
HandleGameListOptions(entry);
|
HandleGameListOptions(entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -555,15 +555,15 @@ bool ImGuiFullscreen::WantsToCloseMenu()
|
||||||
// Wait for the Close button to be released, THEN pressed
|
// Wait for the Close button to be released, THEN pressed
|
||||||
if (s_close_button_state == 0)
|
if (s_close_button_state == 0)
|
||||||
{
|
{
|
||||||
if (ImGui::IsNavInputTest(ImGuiNavInput_Cancel, ImGuiNavReadMode_Pressed))
|
if (ImGui::IsKeyPressed(ImGuiKey_Escape, false))
|
||||||
s_close_button_state = 1;
|
s_close_button_state = 1;
|
||||||
}
|
else if (ImGui::IsKeyPressed(ImGuiKey_NavGamepadCancel, false))
|
||||||
else if (s_close_button_state == 1)
|
|
||||||
{
|
|
||||||
if (ImGui::IsNavInputTest(ImGuiNavInput_Cancel, ImGuiNavReadMode_Released))
|
|
||||||
{
|
|
||||||
s_close_button_state = 2;
|
s_close_button_state = 2;
|
||||||
}
|
}
|
||||||
|
else if ((s_close_button_state == 1 && ImGui::IsKeyReleased(ImGuiKey_Escape)) ||
|
||||||
|
(s_close_button_state == 2 && ImGui::IsKeyReleased(ImGuiKey_NavGamepadCancel)))
|
||||||
|
{
|
||||||
|
s_close_button_state = 3;
|
||||||
}
|
}
|
||||||
return s_close_button_state > 1;
|
return s_close_button_state > 1;
|
||||||
}
|
}
|
||||||
|
@ -2631,9 +2631,10 @@ void ImGuiFullscreen::DrawNotifications(ImVec2& position, float spacing)
|
||||||
ImDrawList* dl = ImGui::GetForegroundDrawList();
|
ImDrawList* dl = ImGui::GetForegroundDrawList();
|
||||||
dl->AddRectFilled(ImVec2(box_min.x + shadow_size, box_min.y + shadow_size),
|
dl->AddRectFilled(ImVec2(box_min.x + shadow_size, box_min.y + shadow_size),
|
||||||
ImVec2(box_max.x + shadow_size, box_max.y + shadow_size),
|
ImVec2(box_max.x + shadow_size, box_max.y + shadow_size),
|
||||||
IM_COL32(20, 20, 20, (180 * opacity) / 255u), rounding, ImDrawCornerFlags_All);
|
IM_COL32(20, 20, 20, (180 * opacity) / 255u), rounding, ImDrawFlags_RoundCornersAll);
|
||||||
dl->AddRectFilled(box_min, box_max, background_color, rounding, ImDrawCornerFlags_All);
|
dl->AddRectFilled(box_min, box_max, background_color, rounding, ImDrawFlags_RoundCornersAll);
|
||||||
dl->AddRect(box_min, box_max, border_color, rounding, ImDrawCornerFlags_All, ImGuiFullscreen::LayoutScale(1.0f));
|
dl->AddRect(box_min, box_max, border_color, rounding, ImDrawFlags_RoundCornersAll,
|
||||||
|
ImGuiFullscreen::LayoutScale(1.0f));
|
||||||
|
|
||||||
const ImVec2 badge_min(box_min.x + horizontal_padding, box_min.y + vertical_padding);
|
const ImVec2 badge_min(box_min.x + horizontal_padding, box_min.y + vertical_padding);
|
||||||
const ImVec2 badge_max(badge_min.x + badge_size, badge_min.y + badge_size);
|
const ImVec2 badge_max(badge_min.x + badge_size, badge_min.y + badge_size);
|
||||||
|
|
|
@ -170,7 +170,7 @@ bool ImGuiManager::Initialize(float global_scale, bool show_osd_messages)
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.IniFilename = nullptr;
|
io.IniFilename = nullptr;
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
io.BackendFlags |= ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_RendererHasVtxOffset;
|
||||||
io.BackendUsingLegacyKeyArrays = 0;
|
io.BackendUsingLegacyKeyArrays = 0;
|
||||||
io.BackendUsingLegacyNavInputArray = 0;
|
io.BackendUsingLegacyNavInputArray = 0;
|
||||||
#ifndef __ANDROID__
|
#ifndef __ANDROID__
|
||||||
|
@ -351,7 +351,7 @@ void ImGuiManager::SetKeyMap()
|
||||||
{
|
{
|
||||||
struct KeyMapping
|
struct KeyMapping
|
||||||
{
|
{
|
||||||
int index;
|
ImGuiKey index;
|
||||||
const char* name;
|
const char* name;
|
||||||
const char* alt_name;
|
const char* alt_name;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue