build: Updated dependencies
This commit is contained in:
parent
18669f3230
commit
948cbe0a9c
2
lib/third_party/fmt
vendored
2
lib/third_party/fmt
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 8303d140a1a11f19b982a9f664bbe59a1ccda3f4
|
Subproject commit 9cf9f38eded63e5e0fb95cd536ba51be601d7fa2
|
86
lib/third_party/imgui/imgui/include/imgui.h
vendored
86
lib/third_party/imgui/imgui/include/imgui.h
vendored
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (headers)
|
// (headers)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@ -28,8 +28,8 @@
|
|||||||
|
|
||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.91.7"
|
#define IMGUI_VERSION "1.91.8"
|
||||||
#define IMGUI_VERSION_NUM 19170
|
#define IMGUI_VERSION_NUM 19180
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||||
@ -160,7 +160,7 @@ typedef unsigned int ImU32; // 32-bit unsigned integer (often used to st
|
|||||||
typedef signed long long ImS64; // 64-bit signed integer
|
typedef signed long long ImS64; // 64-bit signed integer
|
||||||
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
typedef unsigned long long ImU64; // 64-bit unsigned integer
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations: ImDrawList, ImFontAtlas layer
|
||||||
struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
|
struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit()
|
||||||
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
|
struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback)
|
||||||
struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix.
|
struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix.
|
||||||
@ -175,6 +175,8 @@ struct ImFontConfig; // Configuration data when adding a font or
|
|||||||
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
|
struct ImFontGlyph; // A single font glyph (code point + coordinates within in ImFontAtlas + offset)
|
||||||
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
|
struct ImFontGlyphRangesBuilder; // Helper to build glyph ranges from text/string data
|
||||||
struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using)
|
struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*OBSOLETE* please avoid using)
|
||||||
|
|
||||||
|
// Forward declarations: ImGui layer
|
||||||
struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h)
|
struct ImGuiContext; // Dear ImGui context (opaque structure, unless including imgui_internal.h)
|
||||||
struct ImGuiIO; // Main configuration and I/O between your application and ImGui (also see: ImGuiPlatformIO)
|
struct ImGuiIO; // Main configuration and I/O between your application and ImGui (also see: ImGuiPlatformIO)
|
||||||
struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use)
|
struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use)
|
||||||
@ -1037,6 +1039,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
|
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat = false); // did mouse button clicked? (went from !Down to Down). Same as GetMouseClickedCount() == 1.
|
||||||
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
|
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button); // did mouse button released? (went from Down to !Down)
|
||||||
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true)
|
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button); // did mouse button double-clicked? Same as GetMouseClickedCount() == 2. (note that a double-click will also report IsMouseClicked() == true)
|
||||||
|
IMGUI_API bool IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay); // delayed mouse release (use very sparingly!). Generally used with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount==1' test. This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
|
||||||
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
|
IMGUI_API int GetMouseClickedCount(ImGuiMouseButton button); // return the number of successive mouse-clicks at the time where a click happen (otherwise 0).
|
||||||
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
|
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true);// is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
|
||||||
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
|
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse available
|
||||||
@ -1129,12 +1132,12 @@ enum ImGuiWindowFlags_
|
|||||||
ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
|
ImGuiWindowFlags_NoInputs = ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
|
||||||
|
|
||||||
// [Internal]
|
// [Internal]
|
||||||
|
ImGuiWindowFlags_DockNodeHost = 1 << 23, // Don't use! For internal use by Begin()/NewFrame()
|
||||||
ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild()
|
ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild()
|
||||||
ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip()
|
ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip()
|
||||||
ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup()
|
ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup()
|
||||||
ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal()
|
ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal()
|
||||||
ImGuiWindowFlags_ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu()
|
ImGuiWindowFlags_ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu()
|
||||||
ImGuiWindowFlags_DockNodeHost = 1 << 29, // Don't use! For internal use by Begin()/NewFrame()
|
|
||||||
|
|
||||||
// Obsolete names
|
// Obsolete names
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
@ -1829,10 +1832,16 @@ enum ImGuiColorEditFlags_
|
|||||||
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
|
||||||
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
ImGuiColorEditFlags_NoBorder = 1 << 10, // // ColorButton: disable border (which is enforced by default)
|
||||||
|
|
||||||
|
// Alpha preview
|
||||||
|
// - Prior to 1.91.8 (2025/01/21): alpha was made opaque in the preview by default using old name ImGuiColorEditFlags_AlphaPreview.
|
||||||
|
// - We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||||
|
// - The new flags may be combined better and allow finer controls.
|
||||||
|
ImGuiColorEditFlags_AlphaOpaque = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: disable alpha in the preview,. Contrary to _NoAlpha it may still be edited when calling ColorEdit4()/ColorPicker4(). For ColorButton() this does the same as _NoAlpha.
|
||||||
|
ImGuiColorEditFlags_AlphaNoBg = 1 << 12, // // ColorEdit, ColorPicker, ColorButton: disable rendering a checkerboard background behind transparent color.
|
||||||
|
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 13, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half transparent preview.
|
||||||
|
|
||||||
// User Options (right-click on widget to change some of them).
|
// User Options (right-click on widget to change some of them).
|
||||||
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
|
||||||
ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.
|
|
||||||
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.
|
|
||||||
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
|
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
|
||||||
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
|
ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
|
||||||
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
|
ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
|
||||||
@ -1849,12 +1858,16 @@ enum ImGuiColorEditFlags_
|
|||||||
ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar,
|
ImGuiColorEditFlags_DefaultOptions_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_PickerHueBar,
|
||||||
|
|
||||||
// [Internal] Masks
|
// [Internal] Masks
|
||||||
|
ImGuiColorEditFlags_AlphaMask_ = ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque | ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf,
|
||||||
ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex,
|
ImGuiColorEditFlags_DisplayMask_ = ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_DisplayHex,
|
||||||
ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float,
|
ImGuiColorEditFlags_DataTypeMask_ = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float,
|
||||||
ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar,
|
ImGuiColorEditFlags_PickerMask_ = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar,
|
||||||
ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV,
|
ImGuiColorEditFlags_InputMask_ = ImGuiColorEditFlags_InputRGB | ImGuiColorEditFlags_InputHSV,
|
||||||
|
|
||||||
// Obsolete names
|
// Obsolete names
|
||||||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
ImGuiColorEditFlags_AlphaPreview = 0, // [Removed in 1.91.8] This is the default now. Will display a checkerboard unless ImGuiColorEditFlags_AlphaNoBg is set.
|
||||||
|
#endif
|
||||||
//ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
|
//ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2499,6 +2512,7 @@ struct ImGuiIO
|
|||||||
ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down
|
ImU16 MouseClickedCount[5]; // == 0 (not clicked), == 1 (same as MouseClicked[]), == 2 (double-clicked), == 3 (triple-clicked) etc. when going from !Down to Down
|
||||||
ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done.
|
ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done.
|
||||||
bool MouseReleased[5]; // Mouse button went from Down to !Down
|
bool MouseReleased[5]; // Mouse button went from Down to !Down
|
||||||
|
double MouseReleasedTime[5]; // Time of last released (rarely used! but useful to handle delayed single-click when trying to disambiguate them from double-click).
|
||||||
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
|
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
|
||||||
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
|
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
|
||||||
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
|
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
|
||||||
@ -3042,7 +3056,7 @@ struct ImGuiSelectionExternalStorage
|
|||||||
|
|
||||||
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
|
// The maximum line width to bake anti-aliased textures for. Build atlas with ImFontAtlasFlags_NoBakedLines to disable baking.
|
||||||
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
#ifndef IM_DRAWLIST_TEX_LINES_WIDTH_MAX
|
||||||
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (63)
|
#define IM_DRAWLIST_TEX_LINES_WIDTH_MAX (32)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
|
// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h]
|
||||||
@ -3116,7 +3130,6 @@ struct ImDrawChannel
|
|||||||
ImVector<ImDrawIdx> _IdxBuffer;
|
ImVector<ImDrawIdx> _IdxBuffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
|
// Split/Merge functions are used to split the draw list into different layers which can be drawn into out of order.
|
||||||
// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call.
|
// This is used by the Columns/Tables API, so items of each column can be batched together in a same draw call.
|
||||||
struct ImDrawListSplitter
|
struct ImDrawListSplitter
|
||||||
@ -3387,26 +3400,27 @@ struct ImFontAtlasShadowTexConfig
|
|||||||
int CalcConvexTexHeight() const; // The height of the texture area required for the convex shape shadow texture.
|
int CalcConvexTexHeight() const; // The height of the texture area required for the convex shape shadow texture.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A font input/source (we may rename this to ImFontSource in the future)
|
||||||
struct ImFontConfig
|
struct ImFontConfig
|
||||||
{
|
{
|
||||||
void* FontData; // // TTF/OTF data
|
void* FontData; // // TTF/OTF data
|
||||||
int FontDataSize; // // TTF/OTF data size
|
int FontDataSize; // // TTF/OTF data size
|
||||||
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
|
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
|
||||||
int FontNo; // 0 // Index of font within TTF/OTF file
|
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
||||||
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
|
||||||
int OversampleH; // 2 // Rasterize at higher quality for sub-pixel positioning. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
|
||||||
int OversampleV; // 1 // Rasterize at higher quality for sub-pixel positioning. This is not really useful as we don't use sub-pixel positions on the Y axis.
|
|
||||||
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
bool PixelSnapH; // false // Align every glyph AdvanceX to pixel boundaries. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
|
||||||
|
int FontNo; // 0 // Index of font within TTF/OTF file
|
||||||
|
int OversampleH; // 0 (2) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1 or 2 depending on size. Note the difference between 2 and 3 is minimal. You can reduce this to 1 for large glyphs save memory. Read https://github.com/nothings/stb/blob/master/tests/oversample/README.md for details.
|
||||||
|
int OversampleV; // 0 (1) // Rasterize at higher quality for sub-pixel positioning. 0 == auto == 1. This is not really useful as we don't use sub-pixel positions on the Y axis.
|
||||||
|
float SizePixels; // // Size in pixels for rasterizer (more or less maps to the resulting font height).
|
||||||
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
|
ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs when rendered: essentially add to glyph->AdvanceX. Only X axis is supported for now.
|
||||||
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
|
ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input.
|
||||||
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
|
const ImWchar* GlyphRanges; // NULL // THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list).
|
||||||
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
|
float GlyphMinAdvanceX; // 0 // Minimum AdvanceX for glyphs, set Min to align font icons, set both Min/Max to enforce mono-space font
|
||||||
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
|
float GlyphMaxAdvanceX; // FLT_MAX // Maximum AdvanceX for glyphs
|
||||||
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
|
|
||||||
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
unsigned int FontBuilderFlags; // 0 // Settings for custom font builder. THIS IS BUILDER IMPLEMENTATION DEPENDENT. Leave as zero if unsure.
|
||||||
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
float RasterizerMultiply; // 1.0f // Linearly brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. This is a silly thing we may remove in the future.
|
||||||
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
|
float RasterizerDensity; // 1.0f // DPI scale for rasterization, not altering other font metrics: make it easy to swap between e.g. a 100% and a 400% fonts for a zooming display. IMPORTANT: If you increase this it is expected that you increase font scale accordingly, otherwise quality may look lowered.
|
||||||
ImWchar EllipsisChar; // 0 // Explicitly specify unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
ImWchar EllipsisChar; // 0 // Explicitly specify Unicode codepoint of ellipsis character. When fonts are being merged first specified ellipsis will be used.
|
||||||
|
|
||||||
// [Internal]
|
// [Internal]
|
||||||
char Name[40]; // Name (strictly to ease debugging)
|
char Name[40]; // Name (strictly to ease debugging)
|
||||||
@ -3496,8 +3510,8 @@ struct ImFontAtlas
|
|||||||
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
|
IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_data_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp.
|
||||||
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
|
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
|
||||||
IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
|
IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts.
|
||||||
|
IMGUI_API void ClearFonts(); // Clear input+output font data (same as ClearInputData() + glyphs storage, UV coordinates).
|
||||||
IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory.
|
IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory.
|
||||||
IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates).
|
|
||||||
IMGUI_API void Clear(); // Clear all input and output.
|
IMGUI_API void Clear(); // Clear all input and output.
|
||||||
|
|
||||||
// Build atlas, retrieve pixel data.
|
// Build atlas, retrieve pixel data.
|
||||||
@ -3530,7 +3544,7 @@ struct ImFontAtlas
|
|||||||
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters
|
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters
|
||||||
|
|
||||||
//-------------------------------------------
|
//-------------------------------------------
|
||||||
// [BETA] Custom Rectangles/Glyphs API
|
// [ALPHA] Custom Rectangles/Glyphs API
|
||||||
//-------------------------------------------
|
//-------------------------------------------
|
||||||
|
|
||||||
// You can request arbitrary rectangles to be packed into the atlas, for your own purposes.
|
// You can request arbitrary rectangles to be packed into the atlas, for your own purposes.
|
||||||
@ -3556,11 +3570,11 @@ struct ImFontAtlas
|
|||||||
ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
|
ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure.
|
||||||
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
|
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
|
||||||
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
|
int TexGlyphPadding; // FIXME: Should be called "TexPackPadding". Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
|
||||||
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
|
|
||||||
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
|
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
|
||||||
|
|
||||||
// [Internal]
|
// [Internal]
|
||||||
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
|
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
|
||||||
|
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
|
||||||
bool TexReady; // Set when texture was built matching current font input
|
bool TexReady; // Set when texture was built matching current font input
|
||||||
bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format.
|
bool TexPixelsUseColors; // Tell whether our texture data is known to use colors (rather than just alpha channel), in order to help backend select a format.
|
||||||
unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight
|
unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight
|
||||||
@ -3597,39 +3611,39 @@ struct ImFontAtlas
|
|||||||
struct ImFont
|
struct ImFont
|
||||||
{
|
{
|
||||||
// [Internal] Members: Hot ~20/24 bytes (for CalcTextSize)
|
// [Internal] Members: Hot ~20/24 bytes (for CalcTextSize)
|
||||||
ImVector<float> IndexAdvanceX; // 12-16 // out // // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
|
ImVector<float> IndexAdvanceX; // 12-16 // out // Sparse. Glyphs->AdvanceX in a directly indexable way (cache-friendly for CalcTextSize functions which only this info, and are often bottleneck in large UI).
|
||||||
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
|
float FallbackAdvanceX; // 4 // out // = FallbackGlyph->AdvanceX
|
||||||
float FontSize; // 4 // in // // Height of characters/line, set during loading (don't change after loading)
|
float FontSize; // 4 // in // Height of characters/line, set during loading (don't change after loading)
|
||||||
|
|
||||||
// [Internal] Members: Hot ~28/40 bytes (for RenderText loop)
|
// [Internal] Members: Hot ~28/40 bytes (for RenderText loop)
|
||||||
ImVector<ImWchar> IndexLookup; // 12-16 // out // // Sparse. Index glyphs by Unicode code-point.
|
ImVector<ImU16> IndexLookup; // 12-16 // out // Sparse. Index glyphs by Unicode code-point.
|
||||||
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // // All glyphs.
|
ImVector<ImFontGlyph> Glyphs; // 12-16 // out // All glyphs.
|
||||||
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
const ImFontGlyph* FallbackGlyph; // 4-8 // out // = FindGlyph(FontFallbackChar)
|
||||||
|
|
||||||
// [Internal] Members: Cold ~32/40 bytes
|
// [Internal] Members: Cold ~32/40 bytes
|
||||||
// Conceptually ConfigData[] is the list of font sources merged to create this font.
|
// Conceptually ConfigData[] is the list of font sources merged to create this font.
|
||||||
ImFontAtlas* ContainerAtlas; // 4-8 // out // // What we has been loaded into
|
ImFontAtlas* ContainerAtlas; // 4-8 // out // What we has been loaded into
|
||||||
const ImFontConfig* ConfigData; // 4-8 // in // // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
|
const ImFontConfig* ConfigData; // 4-8 // in // Pointer within ContainerAtlas->ConfigData to ConfigDataCount instances
|
||||||
short ConfigDataCount; // 2 // in // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont.
|
short ConfigDataCount; // 2 // in // Number of ImFontConfig involved in creating this font. Usually 1, or >1 when merging multiple font sources into one ImFont.
|
||||||
short EllipsisCharCount; // 1 // out // 1 or 3
|
short EllipsisCharCount; // 1 // out // 1 or 3
|
||||||
ImWchar EllipsisChar; // 2-4 // out // = '...'/'.'// Character used for ellipsis rendering.
|
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
|
||||||
ImWchar FallbackChar; // 2-4 // out // = FFFD/'?' // Character used if a glyph isn't found.
|
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
|
||||||
float EllipsisWidth; // 4 // out // Width
|
float EllipsisWidth; // 4 // out // Total ellipsis Width
|
||||||
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
|
float EllipsisCharStep; // 4 // out // Step between characters when EllipsisCount > 0
|
||||||
|
float Scale; // 4 // in // Base font scale (1.0f), multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
||||||
|
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
|
||||||
|
int MetricsTotalSurface;// 4 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||||
bool DirtyLookupTables; // 1 // out //
|
bool DirtyLookupTables; // 1 // out //
|
||||||
float Scale; // 4 // in // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetWindowFontScale()
|
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
||||||
float Ascent, Descent; // 4+4 // out // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
|
|
||||||
int MetricsTotalSurface;// 4 // out // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
|
||||||
ImU8 Used4kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/4096/8]; // 2 bytes if ImWchar=ImWchar16, 34 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
|
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
IMGUI_API ImFont();
|
IMGUI_API ImFont();
|
||||||
IMGUI_API ~ImFont();
|
IMGUI_API ~ImFont();
|
||||||
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
|
IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c);
|
||||||
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
|
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c);
|
||||||
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
|
float GetCharAdvance(ImWchar c) { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; }
|
||||||
bool IsLoaded() const { return ContainerAtlas != NULL; }
|
bool IsLoaded() const { return ContainerAtlas != NULL; }
|
||||||
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
|
const char* GetDebugName() const { return ConfigData ? ConfigData->Name : "<unknown>"; }
|
||||||
|
|
||||||
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
||||||
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (internal structures/api)
|
// (internal structures/api)
|
||||||
|
|
||||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||||
@ -130,10 +130,17 @@ Index of this file:
|
|||||||
// [SECTION] Forward declarations
|
// [SECTION] Forward declarations
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
// (other types which are not forwarded declared are: ImBitArray<>, ImSpan<>, ImSpanAllocator<>, ImPool<>, ImChunkStream<>)
|
||||||
struct ImBitVector; // Store 1-bit per value
|
struct ImBitVector; // Store 1-bit per value
|
||||||
struct ImRect; // An axis-aligned rectangle (2 points)
|
struct ImRect; // An axis-aligned rectangle (2 points)
|
||||||
|
struct ImGuiTextIndex; // Maintain a line index for a text buffer.
|
||||||
|
|
||||||
|
// ImDrawList/ImFontAtlas
|
||||||
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
|
struct ImDrawDataBuilder; // Helper to build a ImDrawData instance
|
||||||
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
|
struct ImDrawListSharedData; // Data shared between all ImDrawList instances
|
||||||
|
|
||||||
|
// ImGui
|
||||||
struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others)
|
struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others)
|
||||||
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
|
struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
|
||||||
struct ImGuiContext; // Main Dear ImGui context
|
struct ImGuiContext; // Main Dear ImGui context
|
||||||
@ -232,7 +239,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
|
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
|
||||||
#define IMGUI_DEBUG_LOG_ERROR(...) do { ImGuiContext& g2 = *GImGui; if (g2.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g2.DebugLogSkippedErrors++; } while (0)
|
#define IMGUI_DEBUG_LOG_ERROR(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g.DebugLogSkippedErrors++; } while (0)
|
||||||
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||||
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||||
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
|
||||||
@ -474,7 +481,7 @@ static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
|||||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * (T)t); }
|
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||||
@ -749,6 +756,7 @@ struct ImGuiTextIndex
|
|||||||
|
|
||||||
// Helper: ImGuiStorage
|
// Helper: ImGuiStorage
|
||||||
IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key);
|
IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ImDrawList support
|
// [SECTION] ImDrawList support
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2666,6 +2674,12 @@ struct IMGUI_API ImGuiWindowTempData
|
|||||||
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
|
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
|
||||||
ImU32 ModalDimBgColor;
|
ImU32 ModalDimBgColor;
|
||||||
|
|
||||||
|
// Status flags
|
||||||
|
ImGuiItemStatusFlags WindowItemStatusFlags;
|
||||||
|
ImGuiItemStatusFlags ChildItemStatusFlags;
|
||||||
|
ImGuiItemStatusFlags DockTabItemStatusFlags;
|
||||||
|
ImRect DockTabItemRect;
|
||||||
|
|
||||||
// Local parameters stacks
|
// Local parameters stacks
|
||||||
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
|
||||||
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
|
float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
|
||||||
@ -2768,7 +2782,9 @@ struct IMGUI_API ImGuiWindow
|
|||||||
ImGuiStorage StateStorage;
|
ImGuiStorage StateStorage;
|
||||||
ImVector<ImGuiOldColumns> ColumnsStorage;
|
ImVector<ImGuiOldColumns> ColumnsStorage;
|
||||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||||
|
float FontWindowScaleParents;
|
||||||
float FontDpiScale;
|
float FontDpiScale;
|
||||||
|
float FontRefSize; // This is a copy of window->CalcFontSize() at the time of Begin(), trying to phase out CalcFontSize() especially as it may be called on non-current window.
|
||||||
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
|
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
|
||||||
|
|
||||||
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
||||||
@ -2802,8 +2818,6 @@ struct IMGUI_API ImGuiWindow
|
|||||||
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
|
ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as this will still be set when the dock node is hidden.
|
||||||
ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
|
ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
|
||||||
ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
|
ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
|
||||||
ImGuiItemStatusFlags DockTabItemStatusFlags;
|
|
||||||
ImRect DockTabItemRect;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ImGuiWindow(ImGuiContext* context, const char* name);
|
ImGuiWindow(ImGuiContext* context, const char* name);
|
||||||
@ -2817,7 +2831,7 @@ public:
|
|||||||
|
|
||||||
// We don't use g.FontSize because the window may be != g.CurrentWindow.
|
// We don't use g.FontSize because the window may be != g.CurrentWindow.
|
||||||
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
|
||||||
float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale * FontDpiScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
|
float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontBaseSize * FontWindowScale * FontDpiScale * FontWindowScaleParents; }
|
||||||
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
|
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
|
||||||
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
|
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
|
||||||
};
|
};
|
||||||
@ -2840,7 +2854,8 @@ enum ImGuiTabItemFlagsPrivate_
|
|||||||
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
|
ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing,
|
||||||
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
|
ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next frame to recompute ContentWidth during layout)
|
||||||
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
|
ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
|
||||||
ImGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
|
ImGuiTabItemFlags_Invisible = 1 << 22, // To reserve space e.g. with ImGuiTabItemFlags_Leading
|
||||||
|
ImGuiTabItemFlags_Unsorted = 1 << 23, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Storage for one active tab item (sizeof() 48 bytes)
|
// Storage for one active tab item (sizeof() 48 bytes)
|
||||||
@ -3105,6 +3120,7 @@ struct IMGUI_API ImGuiTable
|
|||||||
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
|
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
|
||||||
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
|
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
|
||||||
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
|
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
|
||||||
|
ImS8 NavLayer; // ImGuiNavLayer at the time of BeginTable().
|
||||||
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
|
bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
|
||||||
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
|
bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
|
||||||
bool IsInitializing;
|
bool IsInitializing;
|
||||||
@ -3247,6 +3263,7 @@ namespace ImGui
|
|||||||
// Fonts, drawing
|
// Fonts, drawing
|
||||||
IMGUI_API void SetCurrentFont(ImFont* font);
|
IMGUI_API void SetCurrentFont(ImFont* font);
|
||||||
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
|
inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; }
|
||||||
|
IMGUI_API void PushPasswordFont();
|
||||||
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); }
|
inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); }
|
||||||
IMGUI_API void AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
|
IMGUI_API void AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
|
||||||
|
|
||||||
@ -3332,7 +3349,7 @@ namespace ImGui
|
|||||||
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
|
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flags);
|
||||||
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
|
IMGUI_API bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags = 0);
|
||||||
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
|
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
|
||||||
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags item_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
|
||||||
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
||||||
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
|
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
|
||||||
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
|
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
|
||||||
@ -3670,6 +3687,7 @@ namespace ImGui
|
|||||||
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
|
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImVec2 mouse_pos);
|
||||||
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
|
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
|
||||||
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window);
|
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window);
|
||||||
|
IMGUI_API void TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width);
|
||||||
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
|
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
|
||||||
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
|
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
|
||||||
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
|
IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col);
|
||||||
@ -3869,6 +3887,7 @@ IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas,
|
|||||||
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
|
IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
|
||||||
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
|
IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
|
||||||
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
|
IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
|
||||||
|
IMGUI_API void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Test Engine specific hooks (imgui_test_engine)
|
// [SECTION] Test Engine specific hooks (imgui_test_engine)
|
||||||
|
@ -5,6 +5,13 @@
|
|||||||
#include "imgui.h" // IMGUI_API
|
#include "imgui.h" // IMGUI_API
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
// Usage:
|
||||||
|
// - Add '#define IMGUI_ENABLE_FREETYPE' in your imconfig to enable support for imgui_freetype in imgui.
|
||||||
|
|
||||||
|
// Optional support for OpenType SVG fonts:
|
||||||
|
// - Add '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG' to use plutosvg (not provided). See #7927.
|
||||||
|
// - Add '#define IMGUI_ENABLE_FREETYPE_LUNASVG' to use lunasvg (not provided). See #6591.
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
struct ImFontAtlas;
|
struct ImFontAtlas;
|
||||||
struct ImFontBuilderIO;
|
struct ImFontBuilderIO;
|
||||||
|
223
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
223
lib/third_party/imgui/imgui/source/imgui.cpp
vendored
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (main code and documentation)
|
// (main code and documentation)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@ -438,6 +438,9 @@ CODE
|
|||||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||||
|
|
||||||
|
- 2025/01/22 (1.91.8) - removed ImGuiColorEditFlags_AlphaPreview (made value 0): it is now the default behavior.
|
||||||
|
prior to 1.91.8: alpha was made opaque in the preview by default _unless_ using ImGuiColorEditFlags_AlphaPreview. We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||||||
|
the new flags (ImGuiColorEditFlags_AlphaOpaque, ImGuiColorEditFlags_AlphaNoBg + existing ImGuiColorEditFlags_AlphaPreviewHalf) may be combined better and allow finer controls:
|
||||||
- 2025/01/14 (1.91.7) - renamed ImGuiTreeNodeFlags_SpanTextWidth to ImGuiTreeNodeFlags_SpanLabelWidth for consistency with other names. Kept redirection enum (will obsolete). (#6937)
|
- 2025/01/14 (1.91.7) - renamed ImGuiTreeNodeFlags_SpanTextWidth to ImGuiTreeNodeFlags_SpanLabelWidth for consistency with other names. Kept redirection enum (will obsolete). (#6937)
|
||||||
- 2024/11/27 (1.91.6) - changed CRC32 table from CRC32-adler to CRC32c polynomial in order to be compatible with the result of SSE 4.2 instructions.
|
- 2024/11/27 (1.91.6) - changed CRC32 table from CRC32-adler to CRC32c polynomial in order to be compatible with the result of SSE 4.2 instructions.
|
||||||
As a result, old .ini data may be partially lost (docking and tables information particularly).
|
As a result, old .ini data may be partially lost (docking and tables information particularly).
|
||||||
@ -1268,6 +1271,7 @@ static void RenderWindowTitleBarContents(ImGuiWindow* window, const
|
|||||||
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
||||||
static void RenderDimmedBackgrounds();
|
static void RenderDimmedBackgrounds();
|
||||||
static void SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect);
|
static void SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect);
|
||||||
|
static void SetLastItemDataForChildWindowItem(ImGuiWindow* window, const ImRect& rect);
|
||||||
|
|
||||||
// Viewports
|
// Viewports
|
||||||
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
|
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
|
||||||
@ -1360,11 +1364,11 @@ ImGuiStyle::ImGuiStyle()
|
|||||||
GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar
|
GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar
|
||||||
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||||
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||||
TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
TabRounding = 5.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||||
TabBorderSize = 0.0f; // Thickness of border around tabs.
|
TabBorderSize = 0.0f; // Thickness of border around tabs.
|
||||||
TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
||||||
TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
|
TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
|
||||||
TabBarOverlineSize = 2.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
|
TabBarOverlineSize = 1.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
|
||||||
TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees).
|
TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees).
|
||||||
TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell
|
TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell
|
||||||
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||||||
@ -4381,7 +4385,8 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* ctx, const char* name) : DrawListInst(NUL
|
|||||||
LastFrameActive = -1;
|
LastFrameActive = -1;
|
||||||
LastFrameJustFocused = -1;
|
LastFrameJustFocused = -1;
|
||||||
LastTimeActive = -1.0f;
|
LastTimeActive = -1.0f;
|
||||||
FontWindowScale = FontDpiScale = 1.0f;
|
FontRefSize = 0.0f;
|
||||||
|
FontWindowScale = FontWindowScaleParents = FontDpiScale = 1.0f;
|
||||||
SettingsOffset = -1;
|
SettingsOffset = -1;
|
||||||
DockOrder = -1;
|
DockOrder = -1;
|
||||||
DrawList = &DrawListInst;
|
DrawList = &DrawListInst;
|
||||||
@ -4803,15 +4808,30 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
|
|||||||
|
|
||||||
// This is also inlined in ItemAdd()
|
// This is also inlined in ItemAdd()
|
||||||
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set g.LastItemData.DisplayRect.
|
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set g.LastItemData.DisplayRect.
|
||||||
void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
|
void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags item_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
g.LastItemData.ID = item_id;
|
g.LastItemData.ID = item_id;
|
||||||
g.LastItemData.ItemFlags = in_flags;
|
g.LastItemData.ItemFlags = item_flags;
|
||||||
g.LastItemData.StatusFlags = item_flags;
|
g.LastItemData.StatusFlags = status_flags;
|
||||||
g.LastItemData.Rect = g.LastItemData.NavRect = item_rect;
|
g.LastItemData.Rect = g.LastItemData.NavRect = item_rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ImGui::SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (window->DockIsActive)
|
||||||
|
SetLastItemData(window->MoveId, g.CurrentItemFlags, window->DC.DockTabItemStatusFlags, window->DC.DockTabItemRect);
|
||||||
|
else
|
||||||
|
SetLastItemData(window->MoveId, g.CurrentItemFlags, window->DC.WindowItemStatusFlags, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui::SetLastItemDataForChildWindowItem(ImGuiWindow* window, const ImRect& rect)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
SetLastItemData(window->ChildId, g.CurrentItemFlags, window->DC.ChildItemStatusFlags, rect);
|
||||||
|
}
|
||||||
|
|
||||||
float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
|
float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
|
||||||
{
|
{
|
||||||
if (wrap_pos_x < 0.0f)
|
if (wrap_pos_x < 0.0f)
|
||||||
@ -5274,6 +5294,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
|
// Called once a frame. Followed by SetCurrentFont() which sets up the remaining data.
|
||||||
|
// FIXME-VIEWPORT: the concept of a single ClipRectFullscreen is not ideal!
|
||||||
static void SetupDrawListSharedData()
|
static void SetupDrawListSharedData()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -6434,7 +6455,14 @@ void ImGui::EndChild()
|
|||||||
}
|
}
|
||||||
if (g.HoveredWindow == child_window)
|
if (g.HoveredWindow == child_window)
|
||||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||||
|
child_window->DC.ChildItemStatusFlags = g.LastItemData.StatusFlags;
|
||||||
|
//SetLastItemDataForChildWindowItem(child_window, child_window->Rect()); // Not needed, effectively done by ItemAdd()
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastItemDataForChildWindowItem(child_window, child_window->Rect());
|
||||||
|
}
|
||||||
|
|
||||||
g.WithinEndChildID = backup_within_end_child_id;
|
g.WithinEndChildID = backup_within_end_child_id;
|
||||||
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
|
g.LogLinePosY = -FLT_MAX; // To enforce a carriage return
|
||||||
}
|
}
|
||||||
@ -7033,7 +7061,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window)
|
|||||||
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar) && !window->DockIsActive)
|
||||||
{
|
{
|
||||||
float y = window->Pos.y + window->TitleBarHeight - 1;
|
float y = window->Pos.y + window->TitleBarHeight - 1;
|
||||||
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), border_col, g.Style.FrameBorderSize);
|
window->DrawList->AddLine(ImVec2(window->Pos.x + border_size * 0.5f, y), ImVec2(window->Pos.x + window->Size.x - border_size * 0.5f, y), border_col, g.Style.FrameBorderSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7135,9 +7163,9 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
|||||||
{
|
{
|
||||||
ImRect menu_bar_rect = window->MenuBarRect();
|
ImRect menu_bar_rect = window->MenuBarRect();
|
||||||
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
|
menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
|
||||||
window->DrawList->AddRectFilled(menu_bar_rect.Min + ImVec2(window_border_size, 0), menu_bar_rect.Max - ImVec2(window_border_size, 0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
|
window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop);
|
||||||
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
|
if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
|
||||||
window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
window->DrawList->AddLine(menu_bar_rect.GetBL() + ImVec2(window_border_size * 0.5f, 0.0f), menu_bar_rect.GetBR() - ImVec2(window_border_size * 0.5f, 0.0f), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Docking: Unhide tab bar (small triangle in the corner), drag from small triangle to quickly undock
|
// Docking: Unhide tab bar (small triangle in the corner), drag from small triangle to quickly undock
|
||||||
@ -7177,9 +7205,10 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar
|
|||||||
continue;
|
continue;
|
||||||
const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
|
const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
|
||||||
const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
|
const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
|
||||||
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size)));
|
const float border_inner = IM_ROUND(window_border_size * 0.5f);
|
||||||
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size)));
|
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(border_inner, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, border_inner)));
|
||||||
window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12);
|
window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, border_inner) : ImVec2(border_inner, resize_grip_draw_size)));
|
||||||
|
window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + border_inner), corner.y + grip.InnerDir.y * (window_rounding + border_inner)), window_rounding, grip.AngleMin12, grip.AngleMax12);
|
||||||
window->DrawList->PathFillConvex(col);
|
window->DrawList->PathFillConvex(col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7487,6 +7516,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->ParentWindowForFocusRoute = FindWindowByID(window->WindowClass.FocusRouteParentWindowId);
|
window->ParentWindowForFocusRoute = FindWindowByID(window->WindowClass.FocusRouteParentWindowId);
|
||||||
IM_ASSERT(window->ParentWindowForFocusRoute != 0); // Invalid value for FocusRouteParentWindowId.
|
IM_ASSERT(window->ParentWindowForFocusRoute != 0); // Invalid value for FocusRouteParentWindowId.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inherit SetWindowFontScale() from parent until we fix this system...
|
||||||
|
window->FontWindowScaleParents = parent_window ? parent_window->FontWindowScaleParents * parent_window->FontWindowScale : 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to focus scope stack
|
// Add to focus scope stack
|
||||||
@ -7664,6 +7696,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
|
||||||
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f;
|
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f;
|
||||||
window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f;
|
window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f;
|
||||||
|
window->FontRefSize = g.FontSize; // Lock this to discourage calling window->CalcFontSize() outside of current window.
|
||||||
|
|
||||||
// Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible.
|
// Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible.
|
||||||
// Those flags will be altered further down in the function depending on more conditions.
|
// Those flags will be altered further down in the function depending on more conditions.
|
||||||
@ -8159,6 +8192,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
|
|
||||||
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
|
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
|
||||||
// This is useful to allow creating context menus on title bar only, etc.
|
// This is useful to allow creating context menus on title bar only, etc.
|
||||||
|
window->DC.WindowItemStatusFlags = ImGuiItemStatusFlags_None;
|
||||||
|
window->DC.WindowItemStatusFlags |= IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
|
||||||
SetLastItemDataForWindow(window, title_bar_rect);
|
SetLastItemDataForWindow(window, title_bar_rect);
|
||||||
|
|
||||||
// [DEBUG]
|
// [DEBUG]
|
||||||
@ -8287,15 +8322,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
return !window->SkipItems;
|
return !window->SkipItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui::SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
if (window->DockIsActive)
|
|
||||||
SetLastItemData(window->MoveId, g.CurrentItemFlags, window->DockTabItemStatusFlags, window->DockTabItemRect);
|
|
||||||
else
|
|
||||||
SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(rect.Min, rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::End()
|
void ImGui::End()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -9849,6 +9875,17 @@ bool ImGui::IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id)
|
|||||||
return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id)
|
return g.IO.MouseReleased[button] && TestKeyOwner(MouseButtonToKey(button), owner_id); // Should be same as IsKeyReleased(MouseButtonToKey(button), owner_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use if you absolutely need to distinguish single-click from double-click by introducing a delay.
|
||||||
|
// Generally use with 'delay >= io.MouseDoubleClickTime' + combined with a 'io.MouseClickedLastCount == 1' test.
|
||||||
|
// This is a very rarely used UI idiom, but some apps use this: e.g. MS Explorer single click on an icon to rename.
|
||||||
|
bool ImGui::IsMouseReleasedWithDelay(ImGuiMouseButton button, float delay)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
|
||||||
|
const float time_since_release = (float)(g.Time - g.IO.MouseReleasedTime[button]);
|
||||||
|
return !IsMouseDown(button) && (time_since_release - g.IO.DeltaTime < delay) && (time_since_release >= delay);
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
bool ImGui::IsMouseDoubleClicked(ImGuiMouseButton button)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -10124,6 +10161,8 @@ static void ImGui::UpdateMouseInputs()
|
|||||||
io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
|
io.MouseClicked[i] = io.MouseDown[i] && io.MouseDownDuration[i] < 0.0f;
|
||||||
io.MouseClickedCount[i] = 0; // Will be filled below
|
io.MouseClickedCount[i] = 0; // Will be filled below
|
||||||
io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f;
|
io.MouseReleased[i] = !io.MouseDown[i] && io.MouseDownDuration[i] >= 0.0f;
|
||||||
|
if (io.MouseReleased[i])
|
||||||
|
io.MouseReleasedTime[i] = g.Time;
|
||||||
io.MouseDownDurationPrev[i] = io.MouseDownDuration[i];
|
io.MouseDownDurationPrev[i] = io.MouseDownDuration[i];
|
||||||
io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f;
|
io.MouseDownDuration[i] = io.MouseDown[i] ? (io.MouseDownDuration[i] < 0.0f ? 0.0f : io.MouseDownDuration[i] + io.DeltaTime) : -1.0f;
|
||||||
if (io.MouseClicked[i])
|
if (io.MouseClicked[i])
|
||||||
@ -10295,7 +10334,7 @@ void ImGui::UpdateMouseWheel()
|
|||||||
{
|
{
|
||||||
LockWheelingWindow(window, wheel.x);
|
LockWheelingWindow(window, wheel.x);
|
||||||
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
||||||
float scroll_step = ImTrunc(ImMin(2 * window->CalcFontSize(), max_step));
|
float scroll_step = ImTrunc(ImMin(2 * window->FontRefSize, max_step));
|
||||||
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
||||||
g.WheelingWindowScrolledFrame = g.FrameCount;
|
g.WheelingWindowScrolledFrame = g.FrameCount;
|
||||||
}
|
}
|
||||||
@ -10303,7 +10342,7 @@ void ImGui::UpdateMouseWheel()
|
|||||||
{
|
{
|
||||||
LockWheelingWindow(window, wheel.y);
|
LockWheelingWindow(window, wheel.y);
|
||||||
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
||||||
float scroll_step = ImTrunc(ImMin(5 * window->CalcFontSize(), max_step));
|
float scroll_step = ImTrunc(ImMin(5 * window->FontRefSize, max_step));
|
||||||
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
||||||
g.WheelingWindowScrolledFrame = g.FrameCount;
|
g.WheelingWindowScrolledFrame = g.FrameCount;
|
||||||
}
|
}
|
||||||
@ -10956,6 +10995,11 @@ void ImGui::ErrorRecoveryTryToRecoverWindowState(const ImGuiErrorRecoveryStat
|
|||||||
IM_ASSERT_USER_ERROR(0, "Missing EndMultiSelect()");
|
IM_ASSERT_USER_ERROR(0, "Missing EndMultiSelect()");
|
||||||
EndMultiSelect();
|
EndMultiSelect();
|
||||||
}
|
}
|
||||||
|
if (window->DC.MenuBarAppending) //-V1044
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(0, "Missing EndMenuBar()");
|
||||||
|
EndMenuBar();
|
||||||
|
}
|
||||||
while (window->DC.TreeDepth > state_in->SizeOfTreeStack) //-V1044
|
while (window->DC.TreeDepth > state_in->SizeOfTreeStack) //-V1044
|
||||||
{
|
{
|
||||||
IM_ASSERT_USER_ERROR(0, "Missing TreePop()");
|
IM_ASSERT_USER_ERROR(0, "Missing TreePop()");
|
||||||
@ -13709,7 +13753,7 @@ static void ImGui::NavUpdate()
|
|||||||
{
|
{
|
||||||
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
|
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
|
||||||
ImGuiWindow* window = g.NavWindow;
|
ImGuiWindow* window = g.NavWindow;
|
||||||
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
|
const float scroll_speed = IM_ROUND(window->FontRefSize * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
|
||||||
const ImGuiDir move_dir = g.NavMoveDir;
|
const ImGuiDir move_dir = g.NavMoveDir;
|
||||||
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None)
|
if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY && move_dir != ImGuiDir_None)
|
||||||
{
|
{
|
||||||
@ -13899,8 +13943,8 @@ void ImGui::NavUpdateCreateMoveRequest()
|
|||||||
if ((clamp_x || clamp_y) && !inner_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
|
if ((clamp_x || clamp_y) && !inner_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
|
||||||
{
|
{
|
||||||
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n");
|
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel for gamepad move\n");
|
||||||
float pad_x = ImMin(inner_rect_rel.GetWidth(), window->CalcFontSize() * 0.5f);
|
float pad_x = ImMin(inner_rect_rel.GetWidth(), window->FontRefSize * 0.5f);
|
||||||
float pad_y = ImMin(inner_rect_rel.GetHeight(), window->CalcFontSize() * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item
|
float pad_y = ImMin(inner_rect_rel.GetHeight(), window->FontRefSize * 0.5f); // Terrible approximation for the intent of starting navigation from first fully visible item
|
||||||
inner_rect_rel.Min.x = clamp_x ? (inner_rect_rel.Min.x + pad_x) : -FLT_MAX;
|
inner_rect_rel.Min.x = clamp_x ? (inner_rect_rel.Min.x + pad_x) : -FLT_MAX;
|
||||||
inner_rect_rel.Max.x = clamp_x ? (inner_rect_rel.Max.x - pad_x) : +FLT_MAX;
|
inner_rect_rel.Max.x = clamp_x ? (inner_rect_rel.Max.x - pad_x) : +FLT_MAX;
|
||||||
inner_rect_rel.Min.y = clamp_y ? (inner_rect_rel.Min.y + pad_y) : -FLT_MAX;
|
inner_rect_rel.Min.y = clamp_y ? (inner_rect_rel.Min.y + pad_y) : -FLT_MAX;
|
||||||
@ -14158,7 +14202,7 @@ static float ImGui::NavUpdatePageUpPageDown()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
||||||
const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->FontRefSize * 1.0f + nav_rect_rel.GetHeight());
|
||||||
float nav_scoring_rect_offset_y = 0.0f;
|
float nav_scoring_rect_offset_y = 0.0f;
|
||||||
if (IsKeyPressed(ImGuiKey_PageUp, true))
|
if (IsKeyPressed(ImGuiKey_PageUp, true))
|
||||||
{
|
{
|
||||||
@ -14336,7 +14380,7 @@ static void ImGui::NavUpdateWindowing()
|
|||||||
|
|
||||||
// Start CTRL+Tab or Square+L/R window selection
|
// Start CTRL+Tab or Square+L/R window selection
|
||||||
// (g.ConfigNavWindowingKeyNext/g.ConfigNavWindowingKeyPrev defaults are ImGuiMod_Ctrl|ImGuiKey_Tab and ImGuiMod_Ctrl|ImGuiMod_Shift|ImGuiKey_Tab)
|
// (g.ConfigNavWindowingKeyNext/g.ConfigNavWindowingKeyPrev defaults are ImGuiMod_Ctrl|ImGuiKey_Tab and ImGuiMod_Ctrl|ImGuiMod_Shift|ImGuiKey_Tab)
|
||||||
const ImGuiID owner_id = ImHashStr("###NavUpdateWindowing");
|
const ImGuiID owner_id = ImHashStr("##NavUpdateWindowing");
|
||||||
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
||||||
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
||||||
const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
|
const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id);
|
||||||
@ -14546,12 +14590,12 @@ void ImGui::NavUpdateWindowingOverlay()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (g.NavWindowingListWindow == NULL)
|
if (g.NavWindowingListWindow == NULL)
|
||||||
g.NavWindowingListWindow = FindWindowByName("###NavWindowingList");
|
g.NavWindowingListWindow = FindWindowByName("##NavWindowingOverlay");
|
||||||
const ImGuiViewport* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ GetMainViewport();
|
const ImGuiViewport* viewport = /*g.NavWindow ? g.NavWindow->Viewport :*/ GetMainViewport();
|
||||||
SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
|
SetNextWindowSizeConstraints(ImVec2(viewport->Size.x * 0.20f, viewport->Size.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
|
||||||
SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
|
PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
|
||||||
Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
|
Begin("##NavWindowingOverlay", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
|
||||||
if (g.ContextName[0] != 0)
|
if (g.ContextName[0] != 0)
|
||||||
SeparatorText(g.ContextName);
|
SeparatorText(g.ContextName);
|
||||||
for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
|
for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
|
||||||
@ -18520,8 +18564,8 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
|
|||||||
node->VisibleWindow = window;
|
node->VisibleWindow = window;
|
||||||
|
|
||||||
// Store last item data so it can be queried with IsItemXXX functions after the user Begin() call
|
// Store last item data so it can be queried with IsItemXXX functions after the user Begin() call
|
||||||
window->DockTabItemStatusFlags = g.LastItemData.StatusFlags;
|
window->DC.DockTabItemStatusFlags = g.LastItemData.StatusFlags;
|
||||||
window->DockTabItemRect = g.LastItemData.Rect;
|
window->DC.DockTabItemRect = g.LastItemData.Rect;
|
||||||
|
|
||||||
// Update navigation ID on menu layer
|
// Update navigation ID on menu layer
|
||||||
if (g.NavWindow && g.NavWindow->RootWindow == window && (window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0)
|
if (g.NavWindow && g.NavWindow->RootWindow == window && (window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0)
|
||||||
@ -21986,18 +22030,24 @@ void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, co
|
|||||||
// [DEBUG] Display details for a single font, called by ShowStyleEditor().
|
// [DEBUG] Display details for a single font, called by ShowStyleEditor().
|
||||||
void ImGui::DebugNodeFont(ImFont* font)
|
void ImGui::DebugNodeFont(ImFont* font)
|
||||||
{
|
{
|
||||||
bool opened = TreeNode(font, "Font: \"%s\"\n%.2f px, %d glyphs, %d file(s)",
|
bool opened = TreeNode(font, "Font: \"%s\": %.2f px, %d glyphs, %d sources(s)",
|
||||||
font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
|
font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size, font->ConfigDataCount);
|
||||||
SameLine();
|
|
||||||
if (SmallButton("Set as default"))
|
|
||||||
GetIO().FontDefault = font;
|
|
||||||
if (!opened)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Display preview text
|
// Display preview text
|
||||||
|
if (!opened)
|
||||||
|
Indent();
|
||||||
|
Indent();
|
||||||
PushFont(font);
|
PushFont(font);
|
||||||
Text("The quick brown fox jumps over the lazy dog");
|
Text("The quick brown fox jumps over the lazy dog");
|
||||||
PopFont();
|
PopFont();
|
||||||
|
if (!opened)
|
||||||
|
{
|
||||||
|
Unindent();
|
||||||
|
Unindent();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (SmallButton("Set as default"))
|
||||||
|
GetIO().FontDefault = font;
|
||||||
|
|
||||||
// Display details
|
// Display details
|
||||||
SetNextItemWidth(GetFontSize() * 8);
|
SetNextItemWidth(GetFontSize() * 8);
|
||||||
@ -22016,62 +22066,69 @@ void ImGui::DebugNodeFont(ImFont* font)
|
|||||||
Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt);
|
Text("Texture Area: about %d px ~%dx%d px", font->MetricsTotalSurface, surface_sqrt, surface_sqrt);
|
||||||
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
|
for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
|
||||||
if (font->ConfigData)
|
if (font->ConfigData)
|
||||||
if (const ImFontConfig* cfg = &font->ConfigData[config_i])
|
{
|
||||||
BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
|
const ImFontConfig* cfg = &font->ConfigData[config_i];
|
||||||
config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
|
int oversample_h, oversample_v;
|
||||||
|
ImFontAtlasBuildGetOversampleFactors(cfg, &oversample_h, &oversample_v);
|
||||||
|
BulletText("Input %d: \'%s\', Oversample: (%d=>%d,%d=>%d), PixelSnapH: %d, Offset: (%.1f,%.1f)",
|
||||||
|
config_i, cfg->Name, cfg->OversampleH, oversample_h, cfg->OversampleV, oversample_v, cfg->PixelSnapH, cfg->GlyphOffset.x, cfg->GlyphOffset.y);
|
||||||
|
}
|
||||||
|
|
||||||
// Display all glyphs of the fonts in separate pages of 256 characters
|
// Display all glyphs of the fonts in separate pages of 256 characters
|
||||||
if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
|
|
||||||
{
|
{
|
||||||
ImDrawList* draw_list = GetWindowDrawList();
|
if (TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
|
||||||
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
|
|
||||||
const float cell_size = font->FontSize * 1;
|
|
||||||
const float cell_spacing = GetStyle().ItemSpacing.y;
|
|
||||||
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
|
|
||||||
{
|
{
|
||||||
// Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
|
ImDrawList* draw_list = GetWindowDrawList();
|
||||||
// This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
|
const ImU32 glyph_col = GetColorU32(ImGuiCol_Text);
|
||||||
// is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
|
const float cell_size = font->FontSize * 1;
|
||||||
if (!(base & 4095) && font->IsGlyphRangeUnused(base, base + 4095))
|
const float cell_spacing = GetStyle().ItemSpacing.y;
|
||||||
|
for (unsigned int base = 0; base <= IM_UNICODE_CODEPOINT_MAX; base += 256)
|
||||||
{
|
{
|
||||||
base += 4096 - 256;
|
// Skip ahead if a large bunch of glyphs are not present in the font (test in chunks of 4k)
|
||||||
continue;
|
// This is only a small optimization to reduce the number of iterations when IM_UNICODE_MAX_CODEPOINT
|
||||||
}
|
// is large // (if ImWchar==ImWchar32 we will do at least about 272 queries here)
|
||||||
|
if (!(base & 8191) && font->IsGlyphRangeUnused(base, base + 8191))
|
||||||
int count = 0;
|
|
||||||
for (unsigned int n = 0; n < 256; n++)
|
|
||||||
if (font->FindGlyphNoFallback((ImWchar)(base + n)))
|
|
||||||
count++;
|
|
||||||
if (count <= 0)
|
|
||||||
continue;
|
|
||||||
if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Draw a 16x16 grid of glyphs
|
|
||||||
ImVec2 base_pos = GetCursorScreenPos();
|
|
||||||
for (unsigned int n = 0; n < 256; n++)
|
|
||||||
{
|
|
||||||
// We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
|
|
||||||
// available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
|
|
||||||
ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
|
|
||||||
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
|
|
||||||
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
|
|
||||||
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
|
|
||||||
if (!glyph)
|
|
||||||
continue;
|
|
||||||
font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
|
|
||||||
if (IsMouseHoveringRect(cell_p1, cell_p2) && BeginTooltip())
|
|
||||||
{
|
{
|
||||||
DebugNodeFontGlyph(font, glyph);
|
base += 8192 - 256;
|
||||||
EndTooltip();
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
for (unsigned int n = 0; n < 256; n++)
|
||||||
|
if (font->FindGlyphNoFallback((ImWchar)(base + n)))
|
||||||
|
count++;
|
||||||
|
if (count <= 0)
|
||||||
|
continue;
|
||||||
|
if (!TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Draw a 16x16 grid of glyphs
|
||||||
|
ImVec2 base_pos = GetCursorScreenPos();
|
||||||
|
for (unsigned int n = 0; n < 256; n++)
|
||||||
|
{
|
||||||
|
// We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions
|
||||||
|
// available here and thus cannot easily generate a zero-terminated UTF-8 encoded string.
|
||||||
|
ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size + cell_spacing), base_pos.y + (n / 16) * (cell_size + cell_spacing));
|
||||||
|
ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size);
|
||||||
|
const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base + n));
|
||||||
|
draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50));
|
||||||
|
if (!glyph)
|
||||||
|
continue;
|
||||||
|
font->RenderChar(draw_list, cell_size, cell_p1, glyph_col, (ImWchar)(base + n));
|
||||||
|
if (IsMouseHoveringRect(cell_p1, cell_p2) && BeginTooltip())
|
||||||
|
{
|
||||||
|
DebugNodeFontGlyph(font, glyph);
|
||||||
|
EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
|
||||||
|
TreePop();
|
||||||
}
|
}
|
||||||
Dummy(ImVec2((cell_size + cell_spacing) * 16, (cell_size + cell_spacing) * 16));
|
|
||||||
TreePop();
|
TreePop();
|
||||||
}
|
}
|
||||||
TreePop();
|
|
||||||
}
|
}
|
||||||
TreePop();
|
TreePop();
|
||||||
|
Unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::DebugNodeFontGlyph(ImFont*, const ImFontGlyph* glyph)
|
void ImGui::DebugNodeFontGlyph(ImFont*, const ImFontGlyph* glyph)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (demo code)
|
// (demo code)
|
||||||
|
|
||||||
// Help:
|
// Help:
|
||||||
@ -2177,19 +2177,16 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
if (ImGui::TreeNode("Color/Picker Widgets"))
|
if (ImGui::TreeNode("Color/Picker Widgets"))
|
||||||
{
|
{
|
||||||
static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f);
|
static ImVec4 color = ImVec4(114.0f / 255.0f, 144.0f / 255.0f, 154.0f / 255.0f, 200.0f / 255.0f);
|
||||||
|
static ImGuiColorEditFlags base_flags = ImGuiColorEditFlags_None;
|
||||||
|
|
||||||
static bool alpha_preview = true;
|
|
||||||
static bool alpha_half_preview = false;
|
|
||||||
static bool drag_and_drop = true;
|
|
||||||
static bool options_menu = true;
|
|
||||||
static bool hdr = false;
|
|
||||||
ImGui::SeparatorText("Options");
|
ImGui::SeparatorText("Options");
|
||||||
ImGui::Checkbox("With Alpha Preview", &alpha_preview);
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &base_flags, ImGuiColorEditFlags_NoAlpha);
|
||||||
ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaOpaque", &base_flags, ImGuiColorEditFlags_AlphaOpaque);
|
||||||
ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaNoBg", &base_flags, ImGuiColorEditFlags_AlphaNoBg);
|
||||||
ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaPreviewHalf", &base_flags, ImGuiColorEditFlags_AlphaPreviewHalf);
|
||||||
ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoDragDrop", &base_flags, ImGuiColorEditFlags_NoDragDrop);
|
||||||
ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions);
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoOptions", &base_flags, ImGuiColorEditFlags_NoOptions); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
|
||||||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_HDR", &base_flags, ImGuiColorEditFlags_HDR); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
|
||||||
ImGui::SeparatorText("Inline color editor");
|
ImGui::SeparatorText("Inline color editor");
|
||||||
@ -2197,15 +2194,15 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
ImGui::SameLine(); HelpMarker(
|
ImGui::SameLine(); HelpMarker(
|
||||||
"Click on the color square to open a color picker.\n"
|
"Click on the color square to open a color picker.\n"
|
||||||
"CTRL+click on individual component to input value.\n");
|
"CTRL+click on individual component to input value.\n");
|
||||||
ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags);
|
ImGui::ColorEdit3("MyColor##1", (float*)&color, base_flags);
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
|
||||||
ImGui::Text("Color widget HSV with Alpha:");
|
ImGui::Text("Color widget HSV with Alpha:");
|
||||||
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags);
|
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | base_flags);
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (float display)");
|
||||||
ImGui::Text("Color widget with Float Display:");
|
ImGui::Text("Color widget with Float Display:");
|
||||||
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags);
|
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | base_flags);
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with Picker)");
|
||||||
ImGui::Text("Color button with Picker:");
|
ImGui::Text("Color button with Picker:");
|
||||||
@ -2213,7 +2210,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
"With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n"
|
"With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\n"
|
||||||
"With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only "
|
"With the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only "
|
||||||
"be used for the tooltip and picker popup.");
|
"be used for the tooltip and picker popup.");
|
||||||
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags);
|
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | base_flags);
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorButton (with custom Picker popup)");
|
||||||
ImGui::Text("Color button with Custom Picker Popup:");
|
ImGui::Text("Color button with Custom Picker Popup:");
|
||||||
@ -2233,7 +2230,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ImVec4 backup_color;
|
static ImVec4 backup_color;
|
||||||
bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags);
|
bool open_popup = ImGui::ColorButton("MyColor##3b", color, base_flags);
|
||||||
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
|
ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
open_popup |= ImGui::Button("Palette");
|
open_popup |= ImGui::Button("Palette");
|
||||||
if (open_popup)
|
if (open_popup)
|
||||||
@ -2245,7 +2242,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
{
|
{
|
||||||
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
|
ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
ImGui::ColorPicker4("##picker", (float*)&color, base_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview);
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
ImGui::BeginGroup(); // Lock X position
|
ImGui::BeginGroup(); // Lock X position
|
||||||
@ -2287,40 +2284,42 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
ImGui::Text("Color button only:");
|
ImGui::Text("Color button only:");
|
||||||
static bool no_border = false;
|
static bool no_border = false;
|
||||||
ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
|
ImGui::Checkbox("ImGuiColorEditFlags_NoBorder", &no_border);
|
||||||
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
|
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, base_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
|
||||||
|
|
||||||
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
|
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
|
||||||
ImGui::SeparatorText("Color picker");
|
ImGui::SeparatorText("Color picker");
|
||||||
static bool alpha = true;
|
|
||||||
static bool alpha_bar = true;
|
|
||||||
static bool side_preview = true;
|
|
||||||
static bool ref_color = false;
|
static bool ref_color = false;
|
||||||
static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f);
|
static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f);
|
||||||
static int display_mode = 0;
|
|
||||||
static int picker_mode = 0;
|
static int picker_mode = 0;
|
||||||
ImGui::Checkbox("With Alpha", &alpha);
|
static int display_mode = 0;
|
||||||
ImGui::Checkbox("With Alpha Bar", &alpha_bar);
|
static ImGuiColorEditFlags color_picker_flags = ImGuiColorEditFlags_AlphaBar;
|
||||||
ImGui::Checkbox("With Side Preview", &side_preview);
|
|
||||||
if (side_preview)
|
ImGui::PushID("Color picker");
|
||||||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoAlpha", &color_picker_flags, ImGuiColorEditFlags_NoAlpha);
|
||||||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_AlphaBar", &color_picker_flags, ImGuiColorEditFlags_AlphaBar);
|
||||||
|
ImGui::CheckboxFlags("ImGuiColorEditFlags_NoSidePreview", &color_picker_flags, ImGuiColorEditFlags_NoSidePreview);
|
||||||
|
if (color_picker_flags & ImGuiColorEditFlags_NoSidePreview)
|
||||||
{
|
{
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Checkbox("With Ref Color", &ref_color);
|
ImGui::Checkbox("With Ref Color", &ref_color);
|
||||||
if (ref_color)
|
if (ref_color)
|
||||||
{
|
{
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags);
|
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | base_flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
|
|
||||||
|
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0ImGuiColorEditFlags_PickerHueBar\0ImGuiColorEditFlags_PickerHueWheel\0");
|
||||||
|
ImGui::SameLine(); HelpMarker("When not specified explicitly, user can right-click the picker to change mode.");
|
||||||
|
|
||||||
|
ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0ImGuiColorEditFlags_NoInputs\0ImGuiColorEditFlags_DisplayRGB\0ImGuiColorEditFlags_DisplayHSV\0ImGuiColorEditFlags_DisplayHex\0");
|
||||||
ImGui::SameLine(); HelpMarker(
|
ImGui::SameLine(); HelpMarker(
|
||||||
"ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, "
|
"ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, "
|
||||||
"but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
|
"but the user can change it with a right-click on those inputs.\n\nColorPicker defaults to displaying RGB+HSV+Hex "
|
||||||
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
|
"if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
|
||||||
ImGui::SameLine(); HelpMarker("When not specified explicitly (Auto/Current mode), user can right-click the picker to change mode.");
|
|
||||||
ImGuiColorEditFlags flags = misc_flags;
|
ImGuiColorEditFlags flags = base_flags | color_picker_flags;
|
||||||
if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
|
|
||||||
if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar;
|
|
||||||
if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview;
|
|
||||||
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
|
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
|
||||||
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
|
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
|
||||||
if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
|
if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
|
||||||
@ -2349,6 +2348,7 @@ static void ShowDemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(w);
|
ImGui::SetNextItemWidth(w);
|
||||||
ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
|
ImGui::ColorPicker3("##MyColor##6", (float*)&color, ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha);
|
||||||
|
ImGui::PopID();
|
||||||
|
|
||||||
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
|
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
|
||||||
static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV!
|
static ImVec4 color_hsv(0.23f, 1.0f, 1.0f, 1.0f); // Stored as HSV!
|
||||||
@ -7483,6 +7483,8 @@ static void ShowDemoWindowInputs()
|
|||||||
ImGui::Text("Mouse down:");
|
ImGui::Text("Mouse down:");
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
|
||||||
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
|
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
|
||||||
|
ImGui::Text("Mouse clicked count:");
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseClickedCount[i] > 0) { ImGui::SameLine(); ImGui::Text("b%d: %d", i, io.MouseClickedCount[i]); }
|
||||||
|
|
||||||
// We iterate both legacy native range and named ImGuiKey ranges. This is a little unusual/odd but this allows
|
// We iterate both legacy native range and named ImGuiKey ranges. This is a little unusual/odd but this allows
|
||||||
// displaying the data for old/new backends.
|
// displaying the data for old/new backends.
|
||||||
@ -8062,7 +8064,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||||||
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
|
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
|
||||||
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
||||||
ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f");
|
ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f");
|
||||||
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 2.0f, "%.0f");
|
ImGui::SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f");
|
||||||
ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.");
|
ImGui::SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.");
|
||||||
|
|
||||||
ImGui::SeparatorText("Rounding");
|
ImGui::SeparatorText("Rounding");
|
||||||
@ -8145,9 +8147,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
|||||||
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
||||||
|
|
||||||
static ImGuiColorEditFlags alpha_flags = 0;
|
static ImGuiColorEditFlags alpha_flags = 0;
|
||||||
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) { alpha_flags = ImGuiColorEditFlags_AlphaOpaque; } ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
|
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
||||||
HelpMarker(
|
HelpMarker(
|
||||||
"In the color list:\n"
|
"In the color list:\n"
|
||||||
"Left-click on color square to open color picker,\n"
|
"Left-click on color square to open color picker,\n"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (drawing and font code)
|
// (drawing and font code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1704,8 +1704,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
|||||||
// Accept null ranges
|
// Accept null ranges
|
||||||
if (text_begin == text_end || text_begin[0] == 0)
|
if (text_begin == text_end || text_begin[0] == 0)
|
||||||
return;
|
return;
|
||||||
if (text_end == NULL)
|
// No need to strlen() here: font->RenderText() will do it and may early out.
|
||||||
text_end = text_begin + strlen(text_begin);
|
|
||||||
|
|
||||||
// Pull default font/size from the shared ImDrawListSharedData instance
|
// Pull default font/size from the shared ImDrawListSharedData instance
|
||||||
if (font == NULL)
|
if (font == NULL)
|
||||||
@ -1728,7 +1727,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
|||||||
|
|
||||||
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
||||||
{
|
{
|
||||||
AddText(NULL, 0.0f, pos, col, text_begin, text_end);
|
AddText(_Data->Font, _Data->FontSize, pos, col, text_begin, text_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& p_min, const ImVec2& p_max, const ImVec2& uv_min, const ImVec2& uv_max, ImU32 col)
|
||||||
@ -3128,8 +3127,8 @@ ImFontConfig::ImFontConfig()
|
|||||||
{
|
{
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
FontDataOwnedByAtlas = true;
|
FontDataOwnedByAtlas = true;
|
||||||
OversampleH = 2;
|
OversampleH = 0; // Auto == 1 or 2 depending on size
|
||||||
OversampleV = 1;
|
OversampleV = 0; // Auto == 1
|
||||||
GlyphMaxAdvanceX = FLT_MAX;
|
GlyphMaxAdvanceX = FLT_MAX;
|
||||||
RasterizerMultiply = 1.0f;
|
RasterizerMultiply = 1.0f;
|
||||||
RasterizerDensity = 1.0f;
|
RasterizerDensity = 1.0f;
|
||||||
@ -3277,6 +3276,7 @@ void ImFontAtlas::ClearTexData()
|
|||||||
void ImFontAtlas::ClearFonts()
|
void ImFontAtlas::ClearFonts()
|
||||||
{
|
{
|
||||||
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()!");
|
||||||
|
ClearInputData();
|
||||||
Fonts.clear_delete();
|
Fonts.clear_delete();
|
||||||
TexReady = false;
|
TexReady = false;
|
||||||
}
|
}
|
||||||
@ -3329,8 +3329,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg)
|
|||||||
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()!");
|
||||||
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
|
IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0);
|
||||||
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
IM_ASSERT(font_cfg->SizePixels > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||||
IM_ASSERT(font_cfg->OversampleH > 0 && font_cfg->OversampleV > 0 && "Is ImFontConfig struct correctly initialized?");
|
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f && "Is ImFontConfig struct correctly initialized?");
|
||||||
IM_ASSERT(font_cfg->RasterizerDensity > 0.0f);
|
|
||||||
|
|
||||||
// Create new font
|
// Create new font
|
||||||
if (!font_cfg->MergeMode)
|
if (!font_cfg->MergeMode)
|
||||||
@ -3576,6 +3575,13 @@ void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsig
|
|||||||
*data = table[*data];
|
*data = table[*data];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImFontAtlasBuildGetOversampleFactors(const ImFontConfig* cfg, int* out_oversample_h, int* out_oversample_v)
|
||||||
|
{
|
||||||
|
// Automatically disable horizontal oversampling over size 36
|
||||||
|
*out_oversample_h = (cfg->OversampleH != 0) ? cfg->OversampleH : (cfg->SizePixels * cfg->RasterizerDensity > 36.0f || cfg->PixelSnapH) ? 1 : 2;
|
||||||
|
*out_oversample_v = (cfg->OversampleV != 0) ? cfg->OversampleV : 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
#ifdef IMGUI_ENABLE_STB_TRUETYPE
|
||||||
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
|
// Temporary data for one source font (multiple source fonts can be merged into one destination ImFont)
|
||||||
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
|
// (C++03 doesn't allow instancing ImVector<> with function-local types so we declare the type here.)
|
||||||
@ -3741,15 +3747,19 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
|||||||
buf_rects_out_n += src_tmp.GlyphsCount;
|
buf_rects_out_n += src_tmp.GlyphsCount;
|
||||||
buf_packedchars_out_n += src_tmp.GlyphsCount;
|
buf_packedchars_out_n += src_tmp.GlyphsCount;
|
||||||
|
|
||||||
// Convert our ranges in the format stb_truetype wants
|
// Automatic selection of oversampling parameters
|
||||||
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
ImFontConfig& cfg = atlas->ConfigData[src_i];
|
||||||
|
int oversample_h, oversample_v;
|
||||||
|
ImFontAtlasBuildGetOversampleFactors(&cfg, &oversample_h, &oversample_v);
|
||||||
|
|
||||||
|
// Convert our ranges in the format stb_truetype wants
|
||||||
src_tmp.PackRange.font_size = cfg.SizePixels * cfg.RasterizerDensity;
|
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;
|
||||||
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
|
src_tmp.PackRange.chardata_for_range = src_tmp.PackedChars;
|
||||||
src_tmp.PackRange.h_oversample = (unsigned char)cfg.OversampleH;
|
src_tmp.PackRange.h_oversample = (unsigned char)oversample_h;
|
||||||
src_tmp.PackRange.v_oversample = (unsigned char)cfg.OversampleV;
|
src_tmp.PackRange.v_oversample = (unsigned char)oversample_v;
|
||||||
|
|
||||||
// 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.0f) ? stbtt_ScaleForPixelHeight(&src_tmp.FontInfo, cfg.SizePixels * cfg.RasterizerDensity) : stbtt_ScaleForMappingEmToPixels(&src_tmp.FontInfo, -cfg.SizePixels * cfg.RasterizerDensity);
|
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);
|
||||||
@ -3758,9 +3768,9 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
|
|||||||
int x0, y0, x1, y1;
|
int x0, y0, x1, y1;
|
||||||
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
|
const int glyph_index_in_font = stbtt_FindGlyphIndex(&src_tmp.FontInfo, src_tmp.GlyphsList[glyph_i]);
|
||||||
IM_ASSERT(glyph_index_in_font != 0);
|
IM_ASSERT(glyph_index_in_font != 0);
|
||||||
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * cfg.OversampleH, scale * cfg.OversampleV, 0, 0, &x0, &y0, &x1, &y1);
|
stbtt_GetGlyphBitmapBoxSubpixel(&src_tmp.FontInfo, glyph_index_in_font, scale * oversample_h, scale * oversample_v, 0, 0, &x0, &y0, &x1, &y1);
|
||||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + cfg.OversampleH - 1);
|
src_tmp.Rects[glyph_i].w = (stbrp_coord)(x1 - x0 + pack_padding + oversample_h - 1);
|
||||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + cfg.OversampleV - 1);
|
src_tmp.Rects[glyph_i].h = (stbrp_coord)(y1 - y0 + pack_padding + oversample_v - 1);
|
||||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4666,7 +4676,7 @@ ImFont::ImFont()
|
|||||||
Scale = 1.0f;
|
Scale = 1.0f;
|
||||||
Ascent = Descent = 0.0f;
|
Ascent = Descent = 0.0f;
|
||||||
MetricsTotalSurface = 0;
|
MetricsTotalSurface = 0;
|
||||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImFont::~ImFont()
|
ImFont::~ImFont()
|
||||||
@ -4686,7 +4696,7 @@ void ImFont::ClearOutputData()
|
|||||||
DirtyLookupTables = true;
|
DirtyLookupTables = true;
|
||||||
Ascent = Descent = 0.0f;
|
Ascent = Descent = 0.0f;
|
||||||
MetricsTotalSurface = 0;
|
MetricsTotalSurface = 0;
|
||||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
|
static ImWchar FindFirstExistingGlyph(ImFont* font, const ImWchar* candidate_chars, int candidate_chars_count)
|
||||||
@ -4709,17 +4719,17 @@ void ImFont::BuildLookupTable()
|
|||||||
IndexAdvanceX.clear();
|
IndexAdvanceX.clear();
|
||||||
IndexLookup.clear();
|
IndexLookup.clear();
|
||||||
DirtyLookupTables = false;
|
DirtyLookupTables = false;
|
||||||
memset(Used4kPagesMap, 0, sizeof(Used4kPagesMap));
|
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
|
||||||
GrowIndex(max_codepoint + 1);
|
GrowIndex(max_codepoint + 1);
|
||||||
for (int i = 0; i < Glyphs.Size; i++)
|
for (int i = 0; i < Glyphs.Size; i++)
|
||||||
{
|
{
|
||||||
int codepoint = (int)Glyphs[i].Codepoint;
|
int codepoint = (int)Glyphs[i].Codepoint;
|
||||||
IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX;
|
IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX;
|
||||||
IndexLookup[codepoint] = (ImWchar)i;
|
IndexLookup[codepoint] = (ImU16)i;
|
||||||
|
|
||||||
// Mark 4K page as used
|
// Mark 4K page as used
|
||||||
const int page_n = codepoint / 4096;
|
const int page_n = codepoint / 8192;
|
||||||
Used4kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
|
Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a glyph to handle TAB
|
// Create a glyph to handle TAB
|
||||||
@ -4733,7 +4743,7 @@ void ImFont::BuildLookupTable()
|
|||||||
tab_glyph.Codepoint = '\t';
|
tab_glyph.Codepoint = '\t';
|
||||||
tab_glyph.AdvanceX *= IM_TABSIZE;
|
tab_glyph.AdvanceX *= IM_TABSIZE;
|
||||||
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
|
IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX;
|
||||||
IndexLookup[(int)tab_glyph.Codepoint] = (ImWchar)(Glyphs.Size - 1);
|
IndexLookup[(int)tab_glyph.Codepoint] = (ImU16)(Glyphs.Size - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
|
// Mark special glyphs as not visible (note that AddGlyph already mark as non-visible glyphs with zero-size polygons)
|
||||||
@ -4781,15 +4791,15 @@ void ImFont::BuildLookupTable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// API is designed this way to avoid exposing the 4K page size
|
// API is designed this way to avoid exposing the 8K page size
|
||||||
// e.g. use with IsGlyphRangeUnused(0, 255)
|
// e.g. use with IsGlyphRangeUnused(0, 255)
|
||||||
bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
|
bool ImFont::IsGlyphRangeUnused(unsigned int c_begin, unsigned int c_last)
|
||||||
{
|
{
|
||||||
unsigned int page_begin = (c_begin / 4096);
|
unsigned int page_begin = (c_begin / 8192);
|
||||||
unsigned int page_last = (c_last / 4096);
|
unsigned int page_last = (c_last / 8192);
|
||||||
for (unsigned int page_n = page_begin; page_n <= page_last; page_n++)
|
for (unsigned int page_n = page_begin; page_n <= page_last; page_n++)
|
||||||
if ((page_n >> 3) < sizeof(Used4kPagesMap))
|
if ((page_n >> 3) < sizeof(Used8kPagesMap))
|
||||||
if (Used4kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
|
if (Used8kPagesMap[page_n >> 3] & (1 << (page_n & 7)))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4806,7 +4816,7 @@ void ImFont::GrowIndex(int new_size)
|
|||||||
if (new_size <= IndexLookup.Size)
|
if (new_size <= IndexLookup.Size)
|
||||||
return;
|
return;
|
||||||
IndexAdvanceX.resize(new_size, -1.0f);
|
IndexAdvanceX.resize(new_size, -1.0f);
|
||||||
IndexLookup.resize(new_size, (ImWchar)-1);
|
IndexLookup.resize(new_size, (ImU16)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
|
// x0/y0/x1/y1 are offset from the character upper-left layout position, in pixels. Therefore x0/y0 are often fairly close to zero.
|
||||||
@ -4849,6 +4859,7 @@ void ImFont::AddGlyph(const ImFontConfig* cfg, ImWchar codepoint, float x0, floa
|
|||||||
glyph.U1 = u1;
|
glyph.U1 = u1;
|
||||||
glyph.V1 = v1;
|
glyph.V1 = v1;
|
||||||
glyph.AdvanceX = advance_x;
|
glyph.AdvanceX = advance_x;
|
||||||
|
IM_ASSERT(Glyphs.Size < 0xFFFF); // IndexLookup[] hold 16-bit values and -1 is reserved.
|
||||||
|
|
||||||
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
|
// Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round)
|
||||||
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
|
// We use (U1-U0)*TexWidth instead of X1-X0 to account for oversampling.
|
||||||
@ -4862,13 +4873,13 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
|
|||||||
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
|
IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
|
||||||
unsigned int index_size = (unsigned int)IndexLookup.Size;
|
unsigned int index_size = (unsigned int)IndexLookup.Size;
|
||||||
|
|
||||||
if (dst < index_size && IndexLookup.Data[dst] == (ImWchar)-1 && !overwrite_dst) // 'dst' already exists
|
if (dst < index_size && IndexLookup.Data[dst] == (ImU16)-1 && !overwrite_dst) // 'dst' already exists
|
||||||
return;
|
return;
|
||||||
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
|
if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GrowIndex(dst + 1);
|
GrowIndex(dst + 1);
|
||||||
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImWchar)-1;
|
IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (ImU16)-1;
|
||||||
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
|
IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4877,8 +4888,8 @@ const ImFontGlyph* ImFont::FindGlyph(ImWchar c)
|
|||||||
{
|
{
|
||||||
if (c >= (size_t)IndexLookup.Size)
|
if (c >= (size_t)IndexLookup.Size)
|
||||||
return FallbackGlyph;
|
return FallbackGlyph;
|
||||||
const ImWchar i = IndexLookup.Data[c];
|
const ImU16 i = IndexLookup.Data[c];
|
||||||
if (i == (ImWchar)-1)
|
if (i == (ImU16)-1)
|
||||||
return FallbackGlyph;
|
return FallbackGlyph;
|
||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
}
|
}
|
||||||
@ -4887,8 +4898,8 @@ const ImFontGlyph* ImFont::FindGlyphNoFallback(ImWchar c)
|
|||||||
{
|
{
|
||||||
if (c >= (size_t)IndexLookup.Size)
|
if (c >= (size_t)IndexLookup.Size)
|
||||||
return NULL;
|
return NULL;
|
||||||
const ImWchar i = IndexLookup.Data[c];
|
const ImU16 i = IndexLookup.Data[c];
|
||||||
if (i == (ImWchar)-1)
|
if (i == (ImU16)-1)
|
||||||
return NULL;
|
return NULL;
|
||||||
return &Glyphs.Data[i];
|
return &Glyphs.Data[i];
|
||||||
}
|
}
|
||||||
@ -5102,15 +5113,15 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
|||||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
|
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
|
||||||
{
|
{
|
||||||
if (!text_end)
|
|
||||||
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_TRUNC(pos.x);
|
float x = IM_TRUNC(pos.x);
|
||||||
float y = IM_TRUNC(pos.y);
|
float y = IM_TRUNC(pos.y);
|
||||||
if (y > clip_rect.w)
|
if (y > clip_rect.w)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!text_end)
|
||||||
|
text_end = text_begin + strlen(text_begin); // ImGui:: functions generally already provides a valid text_end, so this is merely to handle direct calls.
|
||||||
|
|
||||||
const float scale = size / FontSize;
|
const float scale = size / FontSize;
|
||||||
const float line_height = FontSize * scale;
|
const float line_height = FontSize * scale;
|
||||||
const float origin_x = x;
|
const float origin_x = x;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (tables and columns code)
|
// (tables and columns code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -374,6 +374,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
table->ColumnsCount = columns_count;
|
table->ColumnsCount = columns_count;
|
||||||
table->IsLayoutLocked = false;
|
table->IsLayoutLocked = false;
|
||||||
table->InnerWidth = inner_width;
|
table->InnerWidth = inner_width;
|
||||||
|
table->NavLayer = (ImS8)outer_window->DC.NavLayerCurrent;
|
||||||
temp_data->UserOuterSize = outer_size;
|
temp_data->UserOuterSize = outer_size;
|
||||||
|
|
||||||
// Instance data (for instance 0, TableID == TableInstanceID)
|
// Instance data (for instance 0, TableID == TableInstanceID)
|
||||||
@ -1050,7 +1051,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
|
// Initial nav layer: using FreezeRowsCount, NOT FreezeRowsRequest, so Header line changes layer when frozen
|
||||||
|
column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : (ImGuiNavLayer)table->NavLayer);
|
||||||
|
|
||||||
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
|
||||||
{
|
{
|
||||||
@ -1493,7 +1495,7 @@ void ImGui::EndTable()
|
|||||||
if (inner_window != outer_window)
|
if (inner_window != outer_window)
|
||||||
{
|
{
|
||||||
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask;
|
||||||
inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently.
|
inner_window->DC.NavLayersActiveMask |= 1 << table->NavLayer; // So empty table don't appear to navigate differently.
|
||||||
g.CurrentTable = NULL; // To avoid error recovery recursing
|
g.CurrentTable = NULL; // To avoid error recovery recursing
|
||||||
EndChild();
|
EndChild();
|
||||||
g.CurrentTable = table;
|
g.CurrentTable = table;
|
||||||
@ -2032,7 +2034,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
|||||||
if (unfreeze_rows_request)
|
if (unfreeze_rows_request)
|
||||||
{
|
{
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
|
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
|
||||||
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
||||||
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
table_instance->LastFrozenHeight = y0 - table->OuterRect.Min.y;
|
||||||
|
|
||||||
|
236
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
236
lib/third_party/imgui/imgui/source/imgui_widgets.cpp
vendored
@ -1,4 +1,4 @@
|
|||||||
// dear imgui, v1.91.7
|
// dear imgui, v1.91.8
|
||||||
// (widgets code)
|
// (widgets code)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -915,15 +915,17 @@ ImGuiID ImGui::GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis)
|
|||||||
// Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set.
|
// Return scrollbar rectangle, must only be called for corresponding axis if window->ScrollbarX/Y is set.
|
||||||
ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
|
ImRect ImGui::GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis)
|
||||||
{
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
const ImRect outer_rect = window->Rect();
|
const ImRect outer_rect = window->Rect();
|
||||||
const ImRect inner_rect = window->InnerRect;
|
const ImRect inner_rect = window->InnerRect;
|
||||||
const float border_size = window->WindowBorderSize;
|
|
||||||
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
|
const float scrollbar_size = window->ScrollbarSizes[axis ^ 1]; // (ScrollbarSizes.x = width of Y scrollbar; ScrollbarSizes.y = height of X scrollbar)
|
||||||
IM_ASSERT(scrollbar_size > 0.0f);
|
IM_ASSERT(scrollbar_size > 0.0f);
|
||||||
|
const float border_size = IM_ROUND(window->WindowBorderSize * 0.5f);
|
||||||
|
const float border_top = (window->Flags & ImGuiWindowFlags_MenuBar) ? IM_ROUND(g.Style.FrameBorderSize * 0.5f) : 0.0f;
|
||||||
if (axis == ImGuiAxis_X)
|
if (axis == ImGuiAxis_X)
|
||||||
return ImRect(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
|
return ImRect(inner_rect.Min.x + border_size, ImMax(outer_rect.Min.y + border_size, outer_rect.Max.y - border_size - scrollbar_size), inner_rect.Max.x - border_size, outer_rect.Max.y - border_size);
|
||||||
else
|
else
|
||||||
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
|
return ImRect(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y + border_top, outer_rect.Max.x - border_size, inner_rect.Max.y - border_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::Scrollbar(ImGuiAxis axis)
|
void ImGui::Scrollbar(ImGuiAxis axis)
|
||||||
@ -4250,6 +4252,23 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
|
|||||||
BufTextLen += new_text_len;
|
BufTextLen += new_text_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::PushPasswordFont()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImFont* in_font = g.Font;
|
||||||
|
ImFont* out_font = &g.InputTextPasswordFont;
|
||||||
|
const ImFontGlyph* glyph = in_font->FindGlyph('*');
|
||||||
|
out_font->FontSize = in_font->FontSize;
|
||||||
|
out_font->Scale = in_font->Scale;
|
||||||
|
out_font->Ascent = in_font->Ascent;
|
||||||
|
out_font->Descent = in_font->Descent;
|
||||||
|
out_font->ContainerAtlas = in_font->ContainerAtlas;
|
||||||
|
out_font->FallbackGlyph = glyph;
|
||||||
|
out_font->FallbackAdvanceX = glyph->AdvanceX;
|
||||||
|
IM_ASSERT(out_font->Glyphs.Size == 0 && out_font->IndexAdvanceX.Size == 0 && out_font->IndexLookup.Size == 0);
|
||||||
|
PushFont(out_font);
|
||||||
|
}
|
||||||
|
|
||||||
// Return false to discard a character.
|
// Return false to discard a character.
|
||||||
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard)
|
||||||
{
|
{
|
||||||
@ -4660,19 +4679,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
|||||||
|
|
||||||
// Password pushes a temporary font with only a fallback glyph
|
// Password pushes a temporary font with only a fallback glyph
|
||||||
if (is_password && !is_displaying_hint)
|
if (is_password && !is_displaying_hint)
|
||||||
{
|
PushPasswordFont();
|
||||||
const ImFontGlyph* glyph = g.Font->FindGlyph('*');
|
|
||||||
ImFont* password_font = &g.InputTextPasswordFont;
|
|
||||||
password_font->FontSize = g.Font->FontSize;
|
|
||||||
password_font->Scale = g.Font->Scale;
|
|
||||||
password_font->Ascent = g.Font->Ascent;
|
|
||||||
password_font->Descent = g.Font->Descent;
|
|
||||||
password_font->ContainerAtlas = g.Font->ContainerAtlas;
|
|
||||||
password_font->FallbackGlyph = glyph;
|
|
||||||
password_font->FallbackAdvanceX = glyph->AdvanceX;
|
|
||||||
IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty());
|
|
||||||
PushFont(password_font);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process mouse inputs and character inputs
|
// Process mouse inputs and character inputs
|
||||||
if (g.ActiveId == id)
|
if (g.ActiveId == id)
|
||||||
@ -5909,7 +5916,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
|||||||
if ((flags & ImGuiColorEditFlags_NoLabel))
|
if ((flags & ImGuiColorEditFlags_NoLabel))
|
||||||
Text("Current");
|
Text("Current");
|
||||||
|
|
||||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip;
|
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoTooltip;
|
||||||
ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2));
|
ColorButton("##current", col_v4, (flags & sub_flags_to_forward), ImVec2(square_sz * 3, square_sz * 2));
|
||||||
if (ref_col != NULL)
|
if (ref_col != NULL)
|
||||||
{
|
{
|
||||||
@ -5949,7 +5956,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
|||||||
if ((flags & ImGuiColorEditFlags_NoInputs) == 0)
|
if ((flags & ImGuiColorEditFlags_NoInputs) == 0)
|
||||||
{
|
{
|
||||||
PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x);
|
PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x);
|
||||||
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf;
|
ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaMask_ | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoSmallPreview;
|
||||||
ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker;
|
ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker;
|
||||||
if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags_DisplayMask_) == 0)
|
if (flags & ImGuiColorEditFlags_DisplayRGB || (flags & ImGuiColorEditFlags_DisplayMask_) == 0)
|
||||||
if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB))
|
if (ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_DisplayRGB))
|
||||||
@ -6125,8 +6132,8 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||||||
bool hovered, held;
|
bool hovered, held;
|
||||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
|
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
|
||||||
|
|
||||||
if (flags & ImGuiColorEditFlags_NoAlpha)
|
if (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaOpaque))
|
||||||
flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf);
|
flags &= ~(ImGuiColorEditFlags_AlphaNoBg | ImGuiColorEditFlags_AlphaPreviewHalf);
|
||||||
|
|
||||||
ImVec4 col_rgb = col;
|
ImVec4 col_rgb = col;
|
||||||
if (flags & ImGuiColorEditFlags_InputHSV)
|
if (flags & ImGuiColorEditFlags_InputHSV)
|
||||||
@ -6145,14 +6152,17 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||||||
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||||
{
|
{
|
||||||
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
|
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
|
||||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
|
if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||||
|
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
|
||||||
|
else
|
||||||
|
window->DrawList->AddRectFilled(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
|
||||||
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha
|
// Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha
|
||||||
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col_rgb : col_rgb_without_alpha;
|
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaOpaque) ? col_rgb_without_alpha : col_rgb;
|
||||||
if (col_source.w < 1.0f)
|
if (col_source.w < 1.0f && (flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding);
|
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding);
|
||||||
else
|
else
|
||||||
window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding);
|
window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding);
|
||||||
@ -6182,7 +6192,7 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
|||||||
|
|
||||||
// Tooltip
|
// Tooltip
|
||||||
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered && IsItemHovered(ImGuiHoveredFlags_ForTooltip))
|
||||||
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
|
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_));
|
||||||
|
|
||||||
return pressed;
|
return pressed;
|
||||||
}
|
}
|
||||||
@ -6223,7 +6233,8 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
|
|||||||
ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2);
|
ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2);
|
||||||
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||||
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
||||||
ColorButton("##preview", cf, (flags & (ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz);
|
ImGuiColorEditFlags flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_;
|
||||||
|
ColorButton("##preview", cf, (flags & flags_to_forward) | ImGuiColorEditFlags_NoTooltip, sz);
|
||||||
SameLine();
|
SameLine();
|
||||||
if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_))
|
if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_))
|
||||||
{
|
{
|
||||||
@ -6944,13 +6955,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
|
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
|
||||||
size.x = ImMax(label_size.x, max_x - min_x);
|
size.x = ImMax(label_size.x, max_x - min_x);
|
||||||
|
|
||||||
// Text stays at the submission position, but bounding box may be extended on both sides
|
|
||||||
const ImVec2 text_min = pos;
|
|
||||||
const ImVec2 text_max(min_x + size.x, pos.y + size.y);
|
|
||||||
|
|
||||||
// Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable.
|
// Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable.
|
||||||
// FIXME: Not part of layout so not included in clipper calculation, but ItemSize currently doesn't allow offsetting CursorPos.
|
// FIXME: Not part of layout so not included in clipper calculation, but ItemSize currently doesn't allow offsetting CursorPos.
|
||||||
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
|
ImRect bb(min_x, pos.y, min_x + size.x, pos.y + size.y);
|
||||||
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
|
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
|
||||||
{
|
{
|
||||||
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
||||||
@ -7086,8 +7093,9 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
|||||||
PopColumnsBackground();
|
PopColumnsBackground();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Text stays at the submission position. Alignment/clipping extents ignore SpanAllColumns.
|
||||||
if (is_visible)
|
if (is_visible)
|
||||||
RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
RenderTextClipped(pos, ImVec2(window->WorkRect.Max.x, pos.y + size.y), label, NULL, &label_size, style.SelectableTextAlign, &bb);
|
||||||
|
|
||||||
// Automatically close popups
|
// Automatically close popups
|
||||||
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
|
if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_NoAutoClosePopups) && (g.LastItemData.ItemFlags & ImGuiItemFlags_AutoClosePopups))
|
||||||
@ -8629,12 +8637,14 @@ bool ImGui::BeginMenuBar()
|
|||||||
|
|
||||||
IM_ASSERT(!window->DC.MenuBarAppending);
|
IM_ASSERT(!window->DC.MenuBarAppending);
|
||||||
BeginGroup(); // Backup position on layer 0 // FIXME: Misleading to use a group for that backup/restore
|
BeginGroup(); // Backup position on layer 0 // FIXME: Misleading to use a group for that backup/restore
|
||||||
PushID("##menubar");
|
PushID("##MenuBar");
|
||||||
|
|
||||||
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
|
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
|
||||||
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
|
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
|
||||||
|
const float border_top = ImMax(IM_ROUND(window->WindowBorderSize * 0.5f - window->TitleBarHeight), 0.0f);
|
||||||
|
const float border_half = IM_ROUND(window->WindowBorderSize * 0.5f);
|
||||||
ImRect bar_rect = window->MenuBarRect();
|
ImRect bar_rect = window->MenuBarRect();
|
||||||
ImRect clip_rect(ImFloor(bar_rect.Min.x + window->WindowBorderSize), ImFloor(bar_rect.Min.y + window->WindowBorderSize), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize))), ImFloor(bar_rect.Max.y));
|
ImRect clip_rect(ImFloor(bar_rect.Min.x + border_half), ImFloor(bar_rect.Min.y + border_top), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, border_half))), ImFloor(bar_rect.Max.y));
|
||||||
clip_rect.ClipWith(window->OuterRectClipped);
|
clip_rect.ClipWith(window->OuterRectClipped);
|
||||||
PushClipRect(clip_rect.Min, clip_rect.Max, false);
|
PushClipRect(clip_rect.Min, clip_rect.Max, false);
|
||||||
|
|
||||||
@ -8655,6 +8665,10 @@ void ImGui::EndMenuBar()
|
|||||||
return;
|
return;
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
|
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
|
||||||
|
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
|
||||||
|
IM_ASSERT(window->DC.MenuBarAppending);
|
||||||
|
|
||||||
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
|
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
|
||||||
if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
|
||||||
{
|
{
|
||||||
@ -8681,9 +8695,6 @@ void ImGui::EndMenuBar()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IM_MSVC_WARNING_SUPPRESS(6011); // Static Analysis false positive "warning C6011: Dereferencing NULL pointer 'window'"
|
|
||||||
IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar);
|
|
||||||
IM_ASSERT(window->DC.MenuBarAppending);
|
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
PopID();
|
PopID();
|
||||||
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos.
|
||||||
@ -8730,7 +8741,7 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
|
|||||||
viewport->BuildWorkInsetMax[axis] += axis_size;
|
viewport->BuildWorkInsetMax[axis] += axis_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
|
||||||
|
|
||||||
// Create window
|
// Create window
|
||||||
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
||||||
@ -8760,22 +8771,33 @@ bool ImGui::BeginMainMenuBar()
|
|||||||
float height = GetFrameHeight();
|
float height = GetFrameHeight();
|
||||||
bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags);
|
bool is_open = BeginViewportSideBar("##MainMenuBar", viewport, ImGuiDir_Up, height, window_flags);
|
||||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
||||||
|
if (!is_open)
|
||||||
if (is_open)
|
{
|
||||||
BeginMenuBar();
|
|
||||||
else
|
|
||||||
End();
|
End();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temporarily disable _NoSavedSettings, in the off-chance that tables or child windows submitted within the menu-bar may want to use settings. (#8356)
|
||||||
|
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_NoSavedSettings;
|
||||||
|
BeginMenuBar();
|
||||||
return is_open;
|
return is_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::EndMainMenuBar()
|
void ImGui::EndMainMenuBar()
|
||||||
{
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (!g.CurrentWindow->DC.MenuBarAppending)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(0, "Calling EndMainMenuBar() not from a menu-bar!"); // Not technically testing that it is the main menu bar
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
EndMenuBar();
|
EndMenuBar();
|
||||||
|
g.CurrentWindow->Flags |= ImGuiWindowFlags_NoSavedSettings; // Restore _NoSavedSettings (#8356)
|
||||||
|
|
||||||
// When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window
|
// When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window
|
||||||
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
||||||
ImGuiContext& g = *GImGui;
|
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest && g.ActiveId == 0)
|
||||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == ImGuiNavLayer_Main && !g.NavAnyRequest)
|
|
||||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
|
FocusTopMostWindowUnderOne(g.NavWindow, NULL, NULL, ImGuiFocusRequestFlags_UnlessBelowModal | ImGuiFocusRequestFlags_RestoreFocusedChild);
|
||||||
|
|
||||||
End();
|
End();
|
||||||
@ -9980,7 +10002,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
|||||||
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
IM_ASSERT_USER_ERROR(tab_bar, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
IM_ASSERT((flags & ImGuiTabItemFlags_Button) == 0); // BeginTabItem() Can't be used with button flags, use TabItemButton() instead!
|
||||||
|
|
||||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||||
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
||||||
@ -10026,6 +10048,23 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
|
|||||||
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
return TabItemEx(tab_bar, label, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::TabItemSpacing(const char* str_id, ImGuiTabItemFlags flags, float width)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
if (window->SkipItems)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiTabBar* tab_bar = g.CurrentTabBar;
|
||||||
|
if (tab_bar == NULL)
|
||||||
|
{
|
||||||
|
IM_ASSERT_USER_ERROR(tab_bar != NULL, "Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetNextItemWidth(width);
|
||||||
|
TabItemEx(tab_bar, str_id, NULL, flags | ImGuiTabItemFlags_Button | ImGuiTabItemFlags_NoReorder | ImGuiTabItemFlags_Invisible, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
|
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
|
||||||
{
|
{
|
||||||
// Layout whole tab bar if not already done
|
// Layout whole tab bar if not already done
|
||||||
@ -10173,8 +10212,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
ImGuiButtonFlags button_flags = ((is_tab_button ? ImGuiButtonFlags_PressedOnClickRelease : ImGuiButtonFlags_PressedOnClick) | ImGuiButtonFlags_AllowOverlap);
|
||||||
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
|
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW)) // FIXME: May be an opt-in property of the payload to disable this
|
||||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||||
bool hovered, held;
|
bool hovered, held, pressed;
|
||||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
if (flags & ImGuiTabItemFlags_Invisible)
|
||||||
|
hovered = held = pressed = false;
|
||||||
|
else
|
||||||
|
pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||||
if (pressed && !is_tab_button)
|
if (pressed && !is_tab_button)
|
||||||
TabBarQueueFocus(tab_bar, tab);
|
TabBarQueueFocus(tab_bar, tab);
|
||||||
|
|
||||||
@ -10259,57 +10301,71 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Render tab shape
|
// Render tab shape
|
||||||
ImDrawList* display_draw_list = window->DrawList;
|
const bool is_visible = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible) && !(flags & ImGuiTabItemFlags_Invisible);
|
||||||
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
if (is_visible)
|
||||||
TabItemBackground(display_draw_list, bb, flags, tab_col);
|
|
||||||
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
|
||||||
{
|
{
|
||||||
float x_offset = IM_TRUNC(0.4f * style.TabRounding);
|
ImDrawList* display_draw_list = window->DrawList;
|
||||||
if (x_offset < 2.0f * g.CurrentDpiScale)
|
const ImU32 tab_col = GetColorU32((held || hovered) ? ImGuiCol_TabHovered : tab_contents_visible ? (tab_bar_focused ? ImGuiCol_TabSelected : ImGuiCol_TabDimmedSelected) : (tab_bar_focused ? ImGuiCol_Tab : ImGuiCol_TabDimmed));
|
||||||
x_offset = 0.0f;
|
TabItemBackground(display_draw_list, bb, flags, tab_col);
|
||||||
float y_offset = 1.0f * g.CurrentDpiScale;
|
if (tab_contents_visible && (tab_bar->Flags & ImGuiTabBarFlags_DrawSelectedOverline) && style.TabBarOverlineSize > 0.0f)
|
||||||
display_draw_list->AddLine(bb.GetTL() + ImVec2(x_offset, y_offset), bb.GetTR() + ImVec2(-x_offset, y_offset), GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline), style.TabBarOverlineSize);
|
{
|
||||||
|
// Might be moved to TabItemBackground() ?
|
||||||
|
ImVec2 tl = bb.GetTL() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||||
|
ImVec2 tr = bb.GetTR() + ImVec2(0, 1.0f * g.CurrentDpiScale);
|
||||||
|
ImU32 overline_col = GetColorU32(tab_bar_focused ? ImGuiCol_TabSelectedOverline : ImGuiCol_TabDimmedSelectedOverline);
|
||||||
|
if (style.TabRounding > 0.0f)
|
||||||
|
{
|
||||||
|
float rounding = style.TabRounding;
|
||||||
|
display_draw_list->PathArcToFast(tl + ImVec2(+rounding, +rounding), rounding, 7, 9);
|
||||||
|
display_draw_list->PathArcToFast(tr + ImVec2(-rounding, +rounding), rounding, 9, 11);
|
||||||
|
display_draw_list->PathStroke(overline_col, 0, style.TabBarOverlineSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
display_draw_list->AddLine(tl - ImVec2(0.5f, 0.5f), tr - ImVec2(0.5f, 0.5f), overline_col, style.TabBarOverlineSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RenderNavCursor(bb, id);
|
||||||
|
|
||||||
|
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
||||||
|
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
||||||
|
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
||||||
|
TabBarQueueFocus(tab_bar, tab);
|
||||||
|
|
||||||
|
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
||||||
|
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
||||||
|
|
||||||
|
// Render tab label, process close button
|
||||||
|
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0;
|
||||||
|
bool just_closed;
|
||||||
|
bool text_clipped;
|
||||||
|
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
||||||
|
if (just_closed && p_open != NULL)
|
||||||
|
{
|
||||||
|
*p_open = false;
|
||||||
|
TabBarCloseTab(tab_bar, tab);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent)
|
||||||
|
// That state is copied to window->DockTabItemStatusFlags by our caller.
|
||||||
|
if (docked_window && (hovered || g.HoveredId == close_button_id))
|
||||||
|
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
||||||
|
|
||||||
|
// Tooltip
|
||||||
|
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
|
||||||
|
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
|
||||||
|
// FIXME: This is a mess.
|
||||||
|
// FIXME: We may want disabled tab to still display the tooltip?
|
||||||
|
if (text_clipped && g.HoveredId == id && !held)
|
||||||
|
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
||||||
|
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
||||||
}
|
}
|
||||||
RenderNavCursor(bb, id);
|
|
||||||
|
|
||||||
// Select with right mouse button. This is so the common idiom for context menu automatically highlight the current widget.
|
|
||||||
const bool hovered_unblocked = IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
|
||||||
if (tab_bar->SelectedTabId != tab->ID && hovered_unblocked && (IsMouseClicked(1) || IsMouseReleased(1)) && !is_tab_button)
|
|
||||||
TabBarQueueFocus(tab_bar, tab);
|
|
||||||
|
|
||||||
if (tab_bar->Flags & ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)
|
|
||||||
flags |= ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
|
|
||||||
|
|
||||||
// Render tab label, process close button
|
|
||||||
const ImGuiID close_button_id = p_open ? GetIDWithSeed("#CLOSE", NULL, docked_window ? docked_window->ID : id) : 0;
|
|
||||||
bool just_closed;
|
|
||||||
bool text_clipped;
|
|
||||||
TabItemLabelAndCloseButton(display_draw_list, bb, tab_just_unsaved ? (flags & ~ImGuiTabItemFlags_UnsavedDocument) : flags, tab_bar->FramePadding, label, id, close_button_id, tab_contents_visible, &just_closed, &text_clipped);
|
|
||||||
if (just_closed && p_open != NULL)
|
|
||||||
{
|
|
||||||
*p_open = false;
|
|
||||||
TabBarCloseTab(tab_bar, tab);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward Hovered state so IsItemHovered() after Begin() can work (even though we are technically hovering our parent)
|
|
||||||
// That state is copied to window->DockTabItemStatusFlags by our caller.
|
|
||||||
if (docked_window && (hovered || g.HoveredId == close_button_id))
|
|
||||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
|
|
||||||
|
|
||||||
// Restore main window position so user can draw there
|
// Restore main window position so user can draw there
|
||||||
if (want_clip_rect)
|
if (want_clip_rect)
|
||||||
PopClipRect();
|
PopClipRect();
|
||||||
window->DC.CursorPos = backup_main_cursor_pos;
|
window->DC.CursorPos = backup_main_cursor_pos;
|
||||||
|
|
||||||
// Tooltip
|
|
||||||
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
|
|
||||||
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
|
|
||||||
// FIXME: This is a mess.
|
|
||||||
// FIXME: We may want disabled tab to still display the tooltip?
|
|
||||||
if (text_clipped && g.HoveredId == id && !held)
|
|
||||||
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
|
|
||||||
SetItemTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);
|
|
||||||
|
|
||||||
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
IM_ASSERT(!is_tab_button || !(tab_bar->SelectedTabId == tab->ID && is_tab_button)); // TabItemButton should not be selected
|
||||||
if (is_tab_button)
|
if (is_tab_button)
|
||||||
return pressed;
|
return pressed;
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2024/10/17: added plutosvg support for SVG Fonts (seems faster/better than lunasvg). Enable by using '#define IMGUI_ENABLE_FREETYPE_PLUTOSVG'. (#7927)
|
||||||
// 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
|
// 2023/11/13: added support for ImFontConfig::RasterizationDensity field for scaling render density without scaling metrics.
|
||||||
// 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG' (#6591)
|
// 2023/08/01: added support for SVG fonts, enable by using '#define IMGUI_ENABLE_FREETYPE_LUNASVG'. (#6591)
|
||||||
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
|
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
|
||||||
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
|
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns nullptr.
|
||||||
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
|
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
|
||||||
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a preferred texture format.
|
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a preferred texture format.
|
||||||
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
|
// 2021/01/28: added support for color-layered glyphs via ImGuiFreeTypeBuilderFlags_LoadColor (require Freetype 2.10+).
|
||||||
@ -32,7 +33,7 @@
|
|||||||
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
// - For correct results you need to be using sRGB and convert to linear space in the pixel shader output.
|
||||||
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
|
// - The default dear imgui styles will be impacted by this change (alpha values will need tweaking).
|
||||||
|
|
||||||
// FIXME: cfg.OversampleH, OversampleV are not supported (but perhaps not so necessary with this rasterizer).
|
// FIXME: cfg.OversampleH, OversampleV are not supported, but generally not necessary with this rasterizer because Hinting makes everything look better.
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
@ -45,12 +46,21 @@
|
|||||||
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
#include FT_GLYPH_H // <freetype/ftglyph.h>
|
||||||
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
#include FT_SYNTHESIS_H // <freetype/ftsynth.h>
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
// Handle LunaSVG and PlutoSVG
|
||||||
|
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) && defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||||
|
#error "Cannot enable both IMGUI_ENABLE_FREETYPE_LUNASVG and IMGUI_ENABLE_FREETYPE_PLUTOSVG"
|
||||||
|
#endif
|
||||||
|
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
#include FT_OTSVG_H // <freetype/otsvg.h>
|
#include FT_OTSVG_H // <freetype/otsvg.h>
|
||||||
#include FT_BBOX_H // <freetype/ftbbox.h>
|
#include FT_BBOX_H // <freetype/ftbbox.h>
|
||||||
#include <lunasvg.h>
|
#include <lunasvg.h>
|
||||||
|
#endif
|
||||||
|
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||||
|
#include <plutosvg.h>
|
||||||
|
#endif
|
||||||
|
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined (IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||||
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
#if !((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
||||||
#error IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
|
#error IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG requires FreeType version >= 2.12
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -94,6 +104,9 @@ static FT_Error ImGuiLunasvgPortPresetSlot(FT_GlyphSlot slot, FT_Bool cache, FT_
|
|||||||
// Code
|
// Code
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define FT_CEIL(X) (((X + 63) & -64) / 64) // From SDL_ttf: Handy routines for converting from fixed point
|
||||||
|
#define FT_SCALEFACTOR 64.0f
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// Glyph metrics:
|
// Glyph metrics:
|
||||||
@ -159,6 +172,7 @@ namespace
|
|||||||
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
const FT_Glyph_Metrics* LoadGlyph(uint32_t in_codepoint);
|
||||||
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
|
const FT_Bitmap* RenderGlyphAndGetInfo(GlyphInfo* out_glyph_info);
|
||||||
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = nullptr);
|
void BlitGlyph(const FT_Bitmap* ft_bitmap, uint32_t* dst, uint32_t dst_pitch, unsigned char* multiply_table = nullptr);
|
||||||
|
FreeTypeFont() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
~FreeTypeFont() { CloseFont(); }
|
~FreeTypeFont() { CloseFont(); }
|
||||||
|
|
||||||
// [Internals]
|
// [Internals]
|
||||||
@ -171,9 +185,6 @@ namespace
|
|||||||
float InvRasterizationDensity;
|
float InvRasterizationDensity;
|
||||||
};
|
};
|
||||||
|
|
||||||
// From SDL_ttf: Handy routines for converting from fixed point
|
|
||||||
#define FT_CEIL(X) (((X + 63) & -64) / 64)
|
|
||||||
|
|
||||||
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
|
bool FreeTypeFont::InitFont(FT_Library ft_library, const ImFontConfig& cfg, unsigned int extra_font_builder_flags)
|
||||||
{
|
{
|
||||||
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
FT_Error error = FT_New_Memory_Face(ft_library, (uint8_t*)cfg.FontData, (uint32_t)cfg.FontDataSize, (uint32_t)cfg.FontNo, &Face);
|
||||||
@ -269,11 +280,11 @@ namespace
|
|||||||
|
|
||||||
// Need an outline for this to work
|
// Need an outline for this to work
|
||||||
FT_GlyphSlot slot = Face->glyph;
|
FT_GlyphSlot slot = Face->glyph;
|
||||||
#ifdef IMGUI_ENABLE_FREETYPE_LUNASVG
|
#if defined(IMGUI_ENABLE_FREETYPE_LUNASVG) || defined(IMGUI_ENABLE_FREETYPE_PLUTOSVG)
|
||||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
|
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP || slot->format == FT_GLYPH_FORMAT_SVG);
|
||||||
#else
|
#else
|
||||||
#if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
#if ((FREETYPE_MAJOR >= 2) && (FREETYPE_MINOR >= 12))
|
||||||
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
|
IM_ASSERT(slot->format != FT_GLYPH_FORMAT_SVG && "The font contains SVG glyphs, you'll need to enable IMGUI_ENABLE_FREETYPE_PLUTOSVG or IMGUI_ENABLE_FREETYPE_LUNASVG in imconfig.h and install required libraries in order to use this font");
|
||||||
#endif
|
#endif
|
||||||
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
|
IM_ASSERT(slot->format == FT_GLYPH_FORMAT_OUTLINE || slot->format == FT_GLYPH_FORMAT_BITMAP);
|
||||||
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
@ -305,7 +316,7 @@ namespace
|
|||||||
out_glyph_info->Height = (int)ft_bitmap->rows;
|
out_glyph_info->Height = (int)ft_bitmap->rows;
|
||||||
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
out_glyph_info->OffsetX = Face->glyph->bitmap_left;
|
||||||
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
out_glyph_info->OffsetY = -Face->glyph->bitmap_top;
|
||||||
out_glyph_info->AdvanceX = (float)FT_CEIL(slot->advance.x);
|
out_glyph_info->AdvanceX = (float)slot->advance.x / FT_SCALEFACTOR;
|
||||||
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
|
out_glyph_info->IsColored = (ft_bitmap->pixel_mode == FT_PIXEL_MODE_BGRA);
|
||||||
|
|
||||||
return ft_bitmap;
|
return ft_bitmap;
|
||||||
@ -480,8 +491,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
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
|
// 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.
|
// user error is to setup ImFontConfig::GlyphRanges with a pointer to data that isn't persistent,
|
||||||
IM_ASSERT(src_range[0] <= src_range[1]);
|
// or to forget to zero-terminate the glyph range array.
|
||||||
|
IM_ASSERT(src_range[0] <= src_range[1] && "Invalid range: is your glyph range array persistent? it is zero-terminated?");
|
||||||
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++;
|
||||||
@ -561,6 +573,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
// 8. Render/rasterize font characters into the texture
|
// 8. Render/rasterize font characters into the texture
|
||||||
int total_surface = 0;
|
int total_surface = 0;
|
||||||
int buf_rects_out_n = 0;
|
int buf_rects_out_n = 0;
|
||||||
|
const int pack_padding = atlas->TexGlyphPadding;
|
||||||
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++)
|
||||||
{
|
{
|
||||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||||
@ -578,7 +591,6 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply);
|
||||||
|
|
||||||
// Gather the sizes of all rectangles we will need to pack
|
// Gather the sizes of all rectangles we will need to pack
|
||||||
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++)
|
||||||
{
|
{
|
||||||
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
ImFontBuildSrcGlyphFT& src_glyph = src_tmp.GlyphsList[glyph_i];
|
||||||
@ -606,11 +618,13 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
|
buf_bitmap_current_used_bytes += bitmap_size_in_bytes;
|
||||||
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : nullptr);
|
src_tmp.Font.BlitGlyph(ft_bitmap, src_glyph.BitmapData, src_glyph.Info.Width, multiply_enabled ? multiply_table : nullptr);
|
||||||
|
|
||||||
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + padding);
|
src_tmp.Rects[glyph_i].w = (stbrp_coord)(src_glyph.Info.Width + pack_padding);
|
||||||
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + padding);
|
src_tmp.Rects[glyph_i].h = (stbrp_coord)(src_glyph.Info.Height + pack_padding);
|
||||||
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
total_surface += src_tmp.Rects[glyph_i].w * src_tmp.Rects[glyph_i].h;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < atlas->CustomRects.Size; i++)
|
||||||
|
total_surface += (atlas->CustomRects[i].Width + pack_padding) * (atlas->CustomRects[i].Height + pack_padding);
|
||||||
|
|
||||||
// We need a width for the skyline algorithm, any width!
|
// We need a width for the skyline algorithm, any width!
|
||||||
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
// The exact width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height.
|
||||||
@ -636,8 +650,10 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
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++)
|
||||||
{
|
{
|
||||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||||
if (src_tmp.GlyphsCount == 0)
|
// IMHEX PATCH BEGIN
|
||||||
continue;
|
// if (src_tmp.GlyphsCount == 0)
|
||||||
|
// continue;
|
||||||
|
// IMHEX PATCH END
|
||||||
|
|
||||||
stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
|
stbrp_pack_rects(&pack_context, src_tmp.Rects, src_tmp.GlyphsCount);
|
||||||
|
|
||||||
@ -670,10 +686,6 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
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++)
|
||||||
{
|
{
|
||||||
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
ImFontBuildSrcDataFT& src_tmp = src_tmp_array[src_i];
|
||||||
// IMHEX PATCH BEGIN
|
|
||||||
// if (src_tmp.GlyphsCount == 0)
|
|
||||||
// continue;
|
|
||||||
// IMHEX PATCH END
|
|
||||||
|
|
||||||
// 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.
|
||||||
@ -684,6 +696,9 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
|
|||||||
const float ascent = src_tmp.Font.Info.Ascender;
|
const float ascent = src_tmp.Font.Info.Ascender;
|
||||||
const float descent = src_tmp.Font.Info.Descender;
|
const float descent = src_tmp.Font.Info.Descender;
|
||||||
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent);
|
||||||
|
|
||||||
|
if (src_tmp.GlyphsCount == 0)
|
||||||
|
continue;
|
||||||
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);
|
||||||
|
|
||||||
@ -811,6 +826,10 @@ static bool ImFontAtlasBuildWithFreeType(ImFontAtlas* atlas)
|
|||||||
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
|
SVG_RendererHooks hooks = { ImGuiLunasvgPortInit, ImGuiLunasvgPortFree, ImGuiLunasvgPortRender, ImGuiLunasvgPortPresetSlot };
|
||||||
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
|
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", &hooks);
|
||||||
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
#endif // IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
|
#ifdef IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||||
|
// With plutosvg, use provided hooks
|
||||||
|
FT_Property_Set(ft_library, "ot-svg", "svg-hooks", plutosvg_ft_svg_hooks());
|
||||||
|
#endif // IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||||
|
|
||||||
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
|
bool ret = ImFontAtlasBuildWithFreeTypeEx(ft_library, atlas, atlas->FontBuilderFlags);
|
||||||
FT_Done_Library(ft_library);
|
FT_Done_Library(ft_library);
|
||||||
|
@ -5010,9 +5010,15 @@ void ShowStyleEditor(ImPlotStyle* ref) {
|
|||||||
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
||||||
|
|
||||||
static ImGuiColorEditFlags alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
static ImGuiColorEditFlags alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||||
|
#if IMGUI_VERSION_NUM < 19173
|
||||||
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
|
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview)) { alpha_flags = ImGuiColorEditFlags_AlphaPreview; } ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
||||||
|
#else
|
||||||
|
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) { alpha_flags = ImGuiColorEditFlags_AlphaOpaque; } ImGui::SameLine();
|
||||||
|
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } ImGui::SameLine();
|
||||||
|
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf)) { alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf; } ImGui::SameLine();
|
||||||
|
#endif
|
||||||
HelpMarker(
|
HelpMarker(
|
||||||
"In the color list:\n"
|
"In the color list:\n"
|
||||||
"Left-click on colored square to open color picker,\n"
|
"Left-click on colored square to open color picker,\n"
|
||||||
|
114
lib/third_party/imgui/implot3d/include/implot3d.h
vendored
114
lib/third_party/imgui/implot3d/include/implot3d.h
vendored
@ -15,6 +15,7 @@
|
|||||||
// [SECTION] Macros and Defines
|
// [SECTION] Macros and Defines
|
||||||
// [SECTION] Forward declarations and basic types
|
// [SECTION] Forward declarations and basic types
|
||||||
// [SECTION] Flags & Enumerations
|
// [SECTION] Flags & Enumerations
|
||||||
|
// [SECTION] Callbacks
|
||||||
// [SECTION] Context
|
// [SECTION] Context
|
||||||
// [SECTION] Begin/End Plot
|
// [SECTION] Begin/End Plot
|
||||||
// [SECTION] Setup
|
// [SECTION] Setup
|
||||||
@ -30,7 +31,6 @@
|
|||||||
// [SECTION] ImPlot3DBox
|
// [SECTION] ImPlot3DBox
|
||||||
// [SECTION] ImPlot3DQuat
|
// [SECTION] ImPlot3DQuat
|
||||||
// [SECTION] ImPlot3DStyle
|
// [SECTION] ImPlot3DStyle
|
||||||
// [SECTION] Callbacks
|
|
||||||
// [SECTION] Meshes
|
// [SECTION] Meshes
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -97,6 +97,7 @@ enum ImPlot3DFlags_ {
|
|||||||
ImPlot3DFlags_NoLegend = 1 << 1, // Hide plot legend
|
ImPlot3DFlags_NoLegend = 1 << 1, // Hide plot legend
|
||||||
ImPlot3DFlags_NoMouseText = 1 << 2, // Hide mouse position in plot coordinates
|
ImPlot3DFlags_NoMouseText = 1 << 2, // Hide mouse position in plot coordinates
|
||||||
ImPlot3DFlags_NoClip = 1 << 3, // Disable 3D box clipping
|
ImPlot3DFlags_NoClip = 1 << 3, // Disable 3D box clipping
|
||||||
|
ImPlot3DFlags_NoMenus = 1 << 4, // The user will not be able to open context menus
|
||||||
ImPlot3DFlags_CanvasOnly = ImPlot3DFlags_NoTitle | ImPlot3DFlags_NoLegend | ImPlot3DFlags_NoMouseText,
|
ImPlot3DFlags_CanvasOnly = ImPlot3DFlags_NoTitle | ImPlot3DFlags_NoLegend | ImPlot3DFlags_NoMouseText,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,6 +249,7 @@ enum ImPlot3DAxisFlags_ {
|
|||||||
ImPlot3DAxisFlags_LockMin = 1 << 4, // The axis minimum value will be locked when panning/zooming
|
ImPlot3DAxisFlags_LockMin = 1 << 4, // The axis minimum value will be locked when panning/zooming
|
||||||
ImPlot3DAxisFlags_LockMax = 1 << 5, // The axis maximum value will be locked when panning/zooming
|
ImPlot3DAxisFlags_LockMax = 1 << 5, // The axis maximum value will be locked when panning/zooming
|
||||||
ImPlot3DAxisFlags_AutoFit = 1 << 6, // Axis will be auto-fitting to data extents
|
ImPlot3DAxisFlags_AutoFit = 1 << 6, // Axis will be auto-fitting to data extents
|
||||||
|
ImPlot3DAxisFlags_Invert = 1 << 7, // The axis will be inverted
|
||||||
ImPlot3DAxisFlags_Lock = ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax,
|
ImPlot3DAxisFlags_Lock = ImPlot3DAxisFlags_LockMin | ImPlot3DAxisFlags_LockMax,
|
||||||
ImPlot3DAxisFlags_NoDecorations = ImPlot3DAxisFlags_NoLabel | ImPlot3DAxisFlags_NoGridLines | ImPlot3DAxisFlags_NoTickLabels,
|
ImPlot3DAxisFlags_NoDecorations = ImPlot3DAxisFlags_NoLabel | ImPlot3DAxisFlags_NoGridLines | ImPlot3DAxisFlags_NoTickLabels,
|
||||||
};
|
};
|
||||||
@ -288,6 +290,13 @@ enum ImPlot3DColormap_ {
|
|||||||
ImPlot3DColormap_Greys = 15, // White/black
|
ImPlot3DColormap_Greys = 15, // White/black
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// [SECTION] Callbacks
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Callback signature for axis tick label formatter
|
||||||
|
typedef int (*ImPlot3DFormatter)(float value, char* buff, int size, void* user_data);
|
||||||
|
|
||||||
namespace ImPlot3D {
|
namespace ImPlot3D {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -353,12 +362,23 @@ IMPLOT3D_API void SetupAxis(ImAxis3D axis, const char* label = nullptr, ImPlot3D
|
|||||||
|
|
||||||
IMPLOT3D_API void SetupAxisLimits(ImAxis3D axis, double v_min, double v_max, ImPlot3DCond cond = ImPlot3DCond_Once);
|
IMPLOT3D_API void SetupAxisLimits(ImAxis3D axis, double v_min, double v_max, ImPlot3DCond cond = ImPlot3DCond_Once);
|
||||||
|
|
||||||
|
IMPLOT3D_API void SetupAxisFormat(ImAxis3D idx, ImPlot3DFormatter formatter, void* data = nullptr);
|
||||||
|
|
||||||
|
// Sets an axis' ticks and optionally the labels. To keep the default ticks, set #keep_default=true
|
||||||
|
IMPLOT3D_API void SetupAxisTicks(ImAxis3D axis, const double* values, int n_ticks, const char* const labels[] = nullptr, bool keep_default = false);
|
||||||
|
|
||||||
|
// Sets an axis' ticks and optionally the labels for the next plot. To keep the default ticks, set #keep_default=true
|
||||||
|
IMPLOT3D_API void SetupAxisTicks(ImAxis3D axis, double v_min, double v_max, int n_ticks, const char* const labels[] = nullptr, bool keep_default = false);
|
||||||
|
|
||||||
// Sets the label and/or flags for primary X/Y/Z axes (shorthand for three calls to SetupAxis)
|
// Sets the label and/or flags for primary X/Y/Z axes (shorthand for three calls to SetupAxis)
|
||||||
IMPLOT3D_API void SetupAxes(const char* x_label, const char* y_label, const char* z_label, ImPlot3DAxisFlags x_flags = 0, ImPlot3DAxisFlags y_flags = 0, ImPlot3DAxisFlags z_flags = 0);
|
IMPLOT3D_API void SetupAxes(const char* x_label, const char* y_label, const char* z_label, ImPlot3DAxisFlags x_flags = 0, ImPlot3DAxisFlags y_flags = 0, ImPlot3DAxisFlags z_flags = 0);
|
||||||
|
|
||||||
// Sets the X/Y/Z axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits)
|
// Sets the X/Y/Z axes range limits. If ImPlotCond_Always is used, the axes limits will be locked (shorthand for two calls to SetupAxisLimits)
|
||||||
IMPLOT3D_API void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, double z_min, double z_max, ImPlot3DCond cond = ImPlot3DCond_Once);
|
IMPLOT3D_API void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, double z_min, double z_max, ImPlot3DCond cond = ImPlot3DCond_Once);
|
||||||
|
|
||||||
|
// Sets the plot box X/Y/Z scale. A scale of 1.0 is the default. Values greater than 1.0 enlarge the plot, while values between 0.0 and 1.0 shrink it.
|
||||||
|
IMPLOT3D_API void SetupBoxScale(float x, float y, float z);
|
||||||
|
|
||||||
IMPLOT3D_API void SetupLegend(ImPlot3DLocation location, ImPlot3DLegendFlags flags = 0);
|
IMPLOT3D_API void SetupLegend(ImPlot3DLocation location, ImPlot3DLegendFlags flags = 0);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -373,7 +393,8 @@ IMPLOT3D_TMP void PlotTriangle(const char* label_id, const T* xs, const T* ys, c
|
|||||||
|
|
||||||
IMPLOT3D_TMP void PlotQuad(const char* label_id, const T* xs, const T* ys, const T* zs, int count, ImPlot3DQuadFlags flags = 0, int offset = 0, int stride = sizeof(T));
|
IMPLOT3D_TMP void PlotQuad(const char* label_id, const T* xs, const T* ys, const T* zs, int count, ImPlot3DQuadFlags flags = 0, int offset = 0, int stride = sizeof(T));
|
||||||
|
|
||||||
IMPLOT3D_TMP void PlotSurface(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, ImPlot3DSurfaceFlags flags = 0, int offset = 0, int stride = sizeof(T));
|
// Plot the surface defined by a grid of vertices. The grid is defined by the x and y arrays, and the z array contains the height of each vertex. A total of x_count * y_count vertices are expected for each array. Leave #scale_min and #scale_max both at 0 for automatic color scaling, or set them to a predefined range.
|
||||||
|
IMPLOT3D_TMP void PlotSurface(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, double scale_min = 0.0, double scale_max = 0.0, ImPlot3DSurfaceFlags flags = 0, int offset = 0, int stride = sizeof(T));
|
||||||
|
|
||||||
IMPLOT3D_API void PlotMesh(const char* label_id, const ImPlot3DPoint* vtx, const unsigned int* idx, int vtx_count, int idx_count, ImPlot3DMeshFlags flags = 0);
|
IMPLOT3D_API void PlotMesh(const char* label_id, const ImPlot3DPoint* vtx, const unsigned int* idx, int vtx_count, int idx_count, ImPlot3DMeshFlags flags = 0);
|
||||||
|
|
||||||
@ -523,51 +544,51 @@ struct ImPlot3DPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
ImPlot3DPoint operator*(float rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator*(float rhs) const;
|
||||||
ImPlot3DPoint operator/(float rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator/(float rhs) const;
|
||||||
ImPlot3DPoint operator+(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator+(const ImPlot3DPoint& rhs) const;
|
||||||
ImPlot3DPoint operator-(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator-(const ImPlot3DPoint& rhs) const;
|
||||||
ImPlot3DPoint operator*(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator*(const ImPlot3DPoint& rhs) const;
|
||||||
ImPlot3DPoint operator/(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API ImPlot3DPoint operator/(const ImPlot3DPoint& rhs) const;
|
||||||
|
|
||||||
// Unary operator
|
// Unary operator
|
||||||
ImPlot3DPoint operator-() const;
|
IMPLOT3D_API ImPlot3DPoint operator-() const;
|
||||||
|
|
||||||
// Compound assignment operators
|
// Compound assignment operators
|
||||||
ImPlot3DPoint& operator*=(float rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator*=(float rhs);
|
||||||
ImPlot3DPoint& operator/=(float rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator/=(float rhs);
|
||||||
ImPlot3DPoint& operator+=(const ImPlot3DPoint& rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator+=(const ImPlot3DPoint& rhs);
|
||||||
ImPlot3DPoint& operator-=(const ImPlot3DPoint& rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator-=(const ImPlot3DPoint& rhs);
|
||||||
ImPlot3DPoint& operator*=(const ImPlot3DPoint& rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator*=(const ImPlot3DPoint& rhs);
|
||||||
ImPlot3DPoint& operator/=(const ImPlot3DPoint& rhs);
|
IMPLOT3D_API ImPlot3DPoint& operator/=(const ImPlot3DPoint& rhs);
|
||||||
|
|
||||||
// Comparison operators
|
// Comparison operators
|
||||||
bool operator==(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API bool operator==(const ImPlot3DPoint& rhs) const;
|
||||||
bool operator!=(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API bool operator!=(const ImPlot3DPoint& rhs) const;
|
||||||
|
|
||||||
// Dot product
|
// Dot product
|
||||||
float Dot(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API float Dot(const ImPlot3DPoint& rhs) const;
|
||||||
|
|
||||||
// Cross product
|
// Cross product
|
||||||
ImPlot3DPoint Cross(const ImPlot3DPoint& rhs) const;
|
IMPLOT3D_API ImPlot3DPoint Cross(const ImPlot3DPoint& rhs) const;
|
||||||
|
|
||||||
// Get vector length
|
// Get vector length
|
||||||
float Length() const;
|
IMPLOT3D_API float Length() const;
|
||||||
|
|
||||||
// Get vector squared length
|
// Get vector squared length
|
||||||
float LengthSquared() const;
|
IMPLOT3D_API float LengthSquared() const;
|
||||||
|
|
||||||
// Normalize to unit length
|
// Normalize to unit length
|
||||||
void Normalize();
|
IMPLOT3D_API void Normalize();
|
||||||
|
|
||||||
// Return vector normalized to unit length
|
// Return vector normalized to unit length
|
||||||
ImPlot3DPoint Normalized() const;
|
IMPLOT3D_API ImPlot3DPoint Normalized() const;
|
||||||
|
|
||||||
// Friend binary operators to allow commutative behavior
|
// Friend binary operators to allow commutative behavior
|
||||||
friend ImPlot3DPoint operator*(float lhs, const ImPlot3DPoint& rhs);
|
IMPLOT3D_API friend ImPlot3DPoint operator*(float lhs, const ImPlot3DPoint& rhs);
|
||||||
|
|
||||||
// Check if the point is NaN
|
// Check if the point is NaN
|
||||||
bool IsNaN() const;
|
IMPLOT3D_API bool IsNaN() const;
|
||||||
|
|
||||||
#ifdef IMPLOT3D_POINT_CLASS_EXTRA
|
#ifdef IMPLOT3D_POINT_CLASS_EXTRA
|
||||||
IMPLOT3D_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImPlot3DPoint
|
IMPLOT3D_POINT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImPlot3DPoint
|
||||||
@ -607,13 +628,13 @@ struct ImPlot3DBox {
|
|||||||
constexpr ImPlot3DBox(const ImPlot3DPoint& min, const ImPlot3DPoint& max) : Min(min), Max(max) {}
|
constexpr ImPlot3DBox(const ImPlot3DPoint& min, const ImPlot3DPoint& max) : Min(min), Max(max) {}
|
||||||
|
|
||||||
// Method to expand the box to include a point
|
// Method to expand the box to include a point
|
||||||
void Expand(const ImPlot3DPoint& point);
|
IMPLOT3D_API void Expand(const ImPlot3DPoint& point);
|
||||||
|
|
||||||
// Method to check if a point is inside the box
|
// Method to check if a point is inside the box
|
||||||
bool Contains(const ImPlot3DPoint& point) const;
|
IMPLOT3D_API bool Contains(const ImPlot3DPoint& point) const;
|
||||||
|
|
||||||
// Method to clip a line segment against the box
|
// Method to clip a line segment against the box
|
||||||
bool ClipLineSegment(const ImPlot3DPoint& p0, const ImPlot3DPoint& p1, ImPlot3DPoint& p0_clipped, ImPlot3DPoint& p1_clipped) const;
|
IMPLOT3D_API bool ClipLineSegment(const ImPlot3DPoint& p0, const ImPlot3DPoint& p1, ImPlot3DPoint& p0_clipped, ImPlot3DPoint& p1_clipped) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -627,8 +648,8 @@ struct ImPlot3DRange {
|
|||||||
constexpr ImPlot3DRange() : Min(0.0f), Max(0.0f) {}
|
constexpr ImPlot3DRange() : Min(0.0f), Max(0.0f) {}
|
||||||
constexpr ImPlot3DRange(float min, float max) : Min(min), Max(max) {}
|
constexpr ImPlot3DRange(float min, float max) : Min(min), Max(max) {}
|
||||||
|
|
||||||
void Expand(float value);
|
IMPLOT3D_API void Expand(float value);
|
||||||
bool Contains(float value) const;
|
IMPLOT3D_API bool Contains(float value) const;
|
||||||
float Size() const { return Max - Min; }
|
float Size() const { return Max - Min; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -643,41 +664,41 @@ struct ImPlot3DQuat {
|
|||||||
constexpr ImPlot3DQuat() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {}
|
constexpr ImPlot3DQuat() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) {}
|
||||||
constexpr ImPlot3DQuat(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {}
|
constexpr ImPlot3DQuat(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {}
|
||||||
|
|
||||||
ImPlot3DQuat(float _angle, const ImPlot3DPoint& _axis);
|
IMPLOT3D_API ImPlot3DQuat(float _angle, const ImPlot3DPoint& _axis);
|
||||||
|
|
||||||
// Set quaternion from two vectors
|
// Set quaternion from two vectors
|
||||||
static ImPlot3DQuat FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3DPoint& v1);
|
IMPLOT3D_API static ImPlot3DQuat FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3DPoint& v1);
|
||||||
|
|
||||||
// Get quaternion length
|
// Get quaternion length
|
||||||
float Length() const;
|
IMPLOT3D_API float Length() const;
|
||||||
|
|
||||||
// Get normalized quaternion
|
// Get normalized quaternion
|
||||||
ImPlot3DQuat Normalized() const;
|
IMPLOT3D_API ImPlot3DQuat Normalized() const;
|
||||||
|
|
||||||
// Conjugate of the quaternion
|
// Conjugate of the quaternion
|
||||||
ImPlot3DQuat Conjugate() const;
|
IMPLOT3D_API ImPlot3DQuat Conjugate() const;
|
||||||
|
|
||||||
// Inverse of the quaternion
|
// Inverse of the quaternion
|
||||||
ImPlot3DQuat Inverse() const;
|
IMPLOT3D_API ImPlot3DQuat Inverse() const;
|
||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
ImPlot3DQuat operator*(const ImPlot3DQuat& rhs) const;
|
IMPLOT3D_API ImPlot3DQuat operator*(const ImPlot3DQuat& rhs) const;
|
||||||
|
|
||||||
// Normalize the quaternion in place
|
// Normalize the quaternion in place
|
||||||
ImPlot3DQuat& Normalize();
|
IMPLOT3D_API ImPlot3DQuat& Normalize();
|
||||||
|
|
||||||
// Rotate a 3D point using the quaternion
|
// Rotate a 3D point using the quaternion
|
||||||
ImPlot3DPoint operator*(const ImPlot3DPoint& point) const;
|
IMPLOT3D_API ImPlot3DPoint operator*(const ImPlot3DPoint& point) const;
|
||||||
|
|
||||||
// Comparison operators
|
// Comparison operators
|
||||||
bool operator==(const ImPlot3DQuat& rhs) const;
|
IMPLOT3D_API bool operator==(const ImPlot3DQuat& rhs) const;
|
||||||
bool operator!=(const ImPlot3DQuat& rhs) const;
|
IMPLOT3D_API bool operator!=(const ImPlot3DQuat& rhs) const;
|
||||||
|
|
||||||
// Interpolate between two quaternions
|
// Interpolate between two quaternions
|
||||||
static ImPlot3DQuat Slerp(const ImPlot3DQuat& q1, const ImPlot3DQuat& q2, float t);
|
IMPLOT3D_API static ImPlot3DQuat Slerp(const ImPlot3DQuat& q1, const ImPlot3DQuat& q2, float t);
|
||||||
|
|
||||||
// Get quaternion dot product
|
// Get quaternion dot product
|
||||||
float Dot(const ImPlot3DQuat& rhs) const;
|
IMPLOT3D_API float Dot(const ImPlot3DQuat& rhs) const;
|
||||||
|
|
||||||
#ifdef IMPLOT3D_QUAT_CLASS_EXTRA
|
#ifdef IMPLOT3D_QUAT_CLASS_EXTRA
|
||||||
IMPLOT3D_QUAT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImPlot3DQuat
|
IMPLOT3D_QUAT_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImPlot3DQuat
|
||||||
@ -712,13 +733,6 @@ struct ImPlot3DStyle {
|
|||||||
IMPLOT3D_API ImPlot3DStyle();
|
IMPLOT3D_API ImPlot3DStyle();
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// [SECTION] Callbacks
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Callback signature for axis tick label formatter
|
|
||||||
typedef int (*ImPlot3DFormatter)(float value, char* buff, int size, void* user_data);
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Meshes
|
// [SECTION] Meshes
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -97,6 +97,16 @@ static inline ImU32 ImMixU32(ImU32 a, ImU32 b, ImU32 s) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fills a buffer with n samples linear interpolated from vmin to vmax
|
||||||
|
template <typename T>
|
||||||
|
void FillRange(ImVector<T>& buffer, int n, T vmin, T vmax) {
|
||||||
|
buffer.resize(n);
|
||||||
|
T step = (vmax - vmin) / (n - 1);
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
buffer[i] = vmin + i * step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ImPlot3D
|
} // namespace ImPlot3D
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -109,24 +119,30 @@ struct ImPlot3DTicker;
|
|||||||
// [SECTION] Callbacks
|
// [SECTION] Callbacks
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef void (*ImPlot3DLocator)(ImPlot3DTicker& ticker, const ImPlot3DRange& range, ImPlot3DFormatter formatter, void* formatter_data);
|
typedef void (*ImPlot3DLocator)(ImPlot3DTicker& ticker, const ImPlot3DRange& range, float pixels, ImPlot3DFormatter formatter, void* formatter_data);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Structs
|
// [SECTION] Structs
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct ImDrawList3D {
|
struct ImDrawList3D {
|
||||||
ImVector<ImDrawIdx> IdxBuffer = {}; // Index buffer
|
ImVector<ImDrawIdx> IdxBuffer; // Index buffer
|
||||||
ImVector<ImDrawVert> VtxBuffer = {}; // Vertex buffer
|
ImVector<ImDrawVert> VtxBuffer; // Vertex buffer
|
||||||
ImVector<float> ZBuffer = {}; // Z buffer. Depth value for each triangle
|
ImVector<float> ZBuffer; // Z buffer. Depth value for each triangle
|
||||||
unsigned int _VtxCurrentIdx = 0; // [Internal] current vertex index
|
unsigned int _VtxCurrentIdx; // [Internal] current vertex index
|
||||||
ImDrawVert* _VtxWritePtr = nullptr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||||
ImDrawIdx* _IdxWritePtr = nullptr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||||
float* _ZWritePtr = nullptr; // [Internal] point within ZBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
float* _ZWritePtr; // [Internal] point within ZBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
|
||||||
ImDrawListFlags _Flags = ImDrawListFlags_None; // [Internal] draw list flags
|
ImDrawListFlags _Flags; // [Internal] draw list flags
|
||||||
ImDrawListSharedData* _SharedData = nullptr; // [Internal] shared draw list data
|
ImDrawListSharedData* _SharedData; // [Internal] shared draw list data
|
||||||
|
|
||||||
ImDrawList3D() {
|
ImDrawList3D() {
|
||||||
|
_VtxCurrentIdx = 0;
|
||||||
|
_VtxWritePtr = nullptr;
|
||||||
|
_IdxWritePtr = nullptr;
|
||||||
|
_ZWritePtr = nullptr;
|
||||||
|
_Flags = ImDrawListFlags_None;
|
||||||
|
_SharedData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrimReserve(int idx_count, int vtx_count);
|
void PrimReserve(int idx_count, int vtx_count);
|
||||||
@ -360,7 +376,7 @@ struct ImPlot3DTick {
|
|||||||
int Idx;
|
int Idx;
|
||||||
|
|
||||||
ImPlot3DTick(double value, bool major, bool show_label) {
|
ImPlot3DTick(double value, bool major, bool show_label) {
|
||||||
PlotPos = value;
|
PlotPos = (float)value;
|
||||||
Major = major;
|
Major = major;
|
||||||
ShowLabel = show_label;
|
ShowLabel = show_label;
|
||||||
TextOffset = -1;
|
TextOffset = -1;
|
||||||
@ -434,10 +450,12 @@ struct ImPlot3DAxis {
|
|||||||
ImPlot3DFormatter Formatter;
|
ImPlot3DFormatter Formatter;
|
||||||
void* FormatterData;
|
void* FormatterData;
|
||||||
ImPlot3DLocator Locator;
|
ImPlot3DLocator Locator;
|
||||||
|
bool ShowDefaultTicks;
|
||||||
// Fit data
|
// Fit data
|
||||||
bool FitThisFrame;
|
bool FitThisFrame;
|
||||||
ImPlot3DRange FitExtents;
|
ImPlot3DRange FitExtents;
|
||||||
// User input
|
// User input
|
||||||
|
bool Hovered;
|
||||||
bool Held;
|
bool Held;
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
@ -451,36 +469,48 @@ struct ImPlot3DAxis {
|
|||||||
Formatter = nullptr;
|
Formatter = nullptr;
|
||||||
FormatterData = nullptr;
|
FormatterData = nullptr;
|
||||||
Locator = nullptr;
|
Locator = nullptr;
|
||||||
|
ShowDefaultTicks = true;
|
||||||
// Fit data
|
// Fit data
|
||||||
FitThisFrame = true;
|
FitThisFrame = true;
|
||||||
FitExtents.Min = HUGE_VAL;
|
FitExtents.Min = HUGE_VAL;
|
||||||
FitExtents.Max = -HUGE_VAL;
|
FitExtents.Max = -HUGE_VAL;
|
||||||
// User input
|
// User input
|
||||||
|
Hovered = false;
|
||||||
Held = false;
|
Held = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Reset() {
|
||||||
|
Formatter = nullptr;
|
||||||
|
FormatterData = nullptr;
|
||||||
|
Locator = nullptr;
|
||||||
|
ShowDefaultTicks = true;
|
||||||
|
FitExtents.Min = HUGE_VAL;
|
||||||
|
FitExtents.Max = -HUGE_VAL;
|
||||||
|
Ticker.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
inline void SetRange(double v1, double v2) {
|
inline void SetRange(double v1, double v2) {
|
||||||
Range.Min = ImMin(v1, v2);
|
Range.Min = (float)ImMin(v1, v2);
|
||||||
Range.Max = ImMax(v1, v2);
|
Range.Max = (float)ImMax(v1, v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetMin(double _min, bool force = false) {
|
inline bool SetMin(double _min, bool force = false) {
|
||||||
if (!force && IsLockedMin())
|
if (!force && IsLockedMin())
|
||||||
return false;
|
return false;
|
||||||
_min = ImPlot3D::ImConstrainNan(ImPlot3D::ImConstrainInf(_min));
|
_min = ImPlot3D::ImConstrainNan((float)ImPlot3D::ImConstrainInf(_min));
|
||||||
if (_min >= Range.Max)
|
if (_min >= Range.Max)
|
||||||
return false;
|
return false;
|
||||||
Range.Min = _min;
|
Range.Min = (float)_min;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SetMax(double _max, bool force = false) {
|
inline bool SetMax(double _max, bool force = false) {
|
||||||
if (!force && IsLockedMax())
|
if (!force && IsLockedMax())
|
||||||
return false;
|
return false;
|
||||||
_max = ImPlot3D::ImConstrainNan(ImPlot3D::ImConstrainInf(_max));
|
_max = ImPlot3D::ImConstrainNan((float)ImPlot3D::ImConstrainInf(_max));
|
||||||
if (_max <= Range.Min)
|
if (_max <= Range.Min)
|
||||||
return false;
|
return false;
|
||||||
Range.Max = _max;
|
Range.Max = (float)_max;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,6 +518,9 @@ struct ImPlot3DAxis {
|
|||||||
inline bool IsLockedMin() const { return IsRangeLocked() || ImPlot3D::ImHasFlag(Flags, ImPlot3DAxisFlags_LockMin); }
|
inline bool IsLockedMin() const { return IsRangeLocked() || ImPlot3D::ImHasFlag(Flags, ImPlot3DAxisFlags_LockMin); }
|
||||||
inline bool IsLockedMax() const { return IsRangeLocked() || ImPlot3D::ImHasFlag(Flags, ImPlot3DAxisFlags_LockMax); }
|
inline bool IsLockedMax() const { return IsRangeLocked() || ImPlot3D::ImHasFlag(Flags, ImPlot3DAxisFlags_LockMax); }
|
||||||
inline bool IsLocked() const { return IsLockedMin() && IsLockedMax(); }
|
inline bool IsLocked() const { return IsLockedMin() && IsLockedMax(); }
|
||||||
|
inline bool IsInputLockedMin() const { return IsLockedMin() || IsAutoFitting(); }
|
||||||
|
inline bool IsInputLockedMax() const { return IsLockedMax() || IsAutoFitting(); }
|
||||||
|
inline bool IsInputLocked() const { return IsLocked() || IsAutoFitting(); }
|
||||||
|
|
||||||
inline void SetLabel(const char* label) {
|
inline void SetLabel(const char* label) {
|
||||||
Label.Buf.shrink(0);
|
Label.Buf.shrink(0);
|
||||||
@ -504,8 +537,6 @@ struct ImPlot3DAxis {
|
|||||||
bool IsAutoFitting() const;
|
bool IsAutoFitting() const;
|
||||||
void ExtendFit(float value);
|
void ExtendFit(float value);
|
||||||
void ApplyFit();
|
void ApplyFit();
|
||||||
float PlotToNDC(float value) const;
|
|
||||||
float NDCToPlot(float value) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Holds plot state information that must persist after EndPlot
|
// Holds plot state information that must persist after EndPlot
|
||||||
@ -520,9 +551,10 @@ struct ImPlot3DPlot {
|
|||||||
ImRect FrameRect; // Outermost bounding rectangle that encapsulates whole the plot/title/padding/etc
|
ImRect FrameRect; // Outermost bounding rectangle that encapsulates whole the plot/title/padding/etc
|
||||||
ImRect CanvasRect; // Frame rectangle reduced by padding
|
ImRect CanvasRect; // Frame rectangle reduced by padding
|
||||||
ImRect PlotRect; // Bounding rectangle for the actual plot area
|
ImRect PlotRect; // Bounding rectangle for the actual plot area
|
||||||
// Rotation & Axes
|
// Rotation & axes & box
|
||||||
ImPlot3DQuat Rotation;
|
ImPlot3DQuat Rotation; // Current rotation quaternion
|
||||||
ImPlot3DAxis Axes[3];
|
ImPlot3DAxis Axes[3]; // X, Y, Z axes
|
||||||
|
ImPlot3DPoint BoxScale; // Scale factor for plot box X, Y, Z axes
|
||||||
// Animation
|
// Animation
|
||||||
float AnimationTime; // Remaining animation time
|
float AnimationTime; // Remaining animation time
|
||||||
ImPlot3DQuat RotationAnimationEnd; // End rotation for animation
|
ImPlot3DQuat RotationAnimationEnd; // End rotation for animation
|
||||||
@ -550,6 +582,7 @@ struct ImPlot3DPlot {
|
|||||||
Rotation = ImPlot3DQuat(0.0f, 0.0f, 0.0f, 1.0f);
|
Rotation = ImPlot3DQuat(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
Axes[i] = ImPlot3DAxis();
|
Axes[i] = ImPlot3DAxis();
|
||||||
|
BoxScale = ImPlot3DPoint(1.0f, 1.0f, 1.0f);
|
||||||
AnimationTime = 0.0f;
|
AnimationTime = 0.0f;
|
||||||
RotationAnimationEnd = Rotation;
|
RotationAnimationEnd = Rotation;
|
||||||
SetupLocked = false;
|
SetupLocked = false;
|
||||||
@ -575,6 +608,7 @@ struct ImPlot3DPlot {
|
|||||||
ImPlot3DPoint RangeMax() const;
|
ImPlot3DPoint RangeMax() const;
|
||||||
ImPlot3DPoint RangeCenter() const;
|
ImPlot3DPoint RangeCenter() const;
|
||||||
void SetRange(const ImPlot3DPoint& min, const ImPlot3DPoint& max);
|
void SetRange(const ImPlot3DPoint& min, const ImPlot3DPoint& max);
|
||||||
|
float GetBoxZoom() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImPlot3DContext {
|
struct ImPlot3DContext {
|
||||||
@ -680,7 +714,7 @@ int Formatter_Default(float value, char* buff, int size, void* data);
|
|||||||
// [SECTION] Locator
|
// [SECTION] Locator
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, ImPlot3DFormatter formatter, void* formatter_data);
|
void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, float pixels, ImPlot3DFormatter formatter, void* formatter_data);
|
||||||
|
|
||||||
} // namespace ImPlot3D
|
} // namespace ImPlot3D
|
||||||
|
|
||||||
|
437
lib/third_party/imgui/implot3d/source/implot3d.cpp
vendored
437
lib/third_party/imgui/implot3d/source/implot3d.cpp
vendored
@ -48,11 +48,14 @@
|
|||||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// We define this to avoid accidentally using the deprecated API
|
||||||
|
#ifndef IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
#define IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "implot3d.h"
|
#include "implot3d.h"
|
||||||
#include "implot3d_internal.h"
|
#include "implot3d_internal.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -73,7 +76,7 @@ namespace ImPlot3D {
|
|||||||
ImPlot3DContext* GImPlot3D = nullptr;
|
ImPlot3DContext* GImPlot3D = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ImPlot3DQuat init_rotation = ImPlot3DQuat(-0.513269, -0.212596, -0.318184, 0.76819);
|
static ImPlot3DQuat init_rotation = ImPlot3DQuat(-0.513269f, -0.212596f, -0.318184f, 0.76819f);
|
||||||
|
|
||||||
ImPlot3DContext* CreateContext() {
|
ImPlot3DContext* CreateContext() {
|
||||||
ImPlot3DContext* ctx = IM_NEW(ImPlot3DContext)();
|
ImPlot3DContext* ctx = IM_NEW(ImPlot3DContext)();
|
||||||
@ -107,8 +110,7 @@ void AddTextRotated(ImDrawList* draw_list, ImVec2 pos, float angle, ImU32 col, c
|
|||||||
ImFont* font = g.Font;
|
ImFont* font = g.Font;
|
||||||
|
|
||||||
// Align to be pixel perfect
|
// Align to be pixel perfect
|
||||||
pos.x = IM_FLOOR(pos.x);
|
pos = ImFloor(pos);
|
||||||
pos.y = IM_FLOOR(pos.y);
|
|
||||||
|
|
||||||
const float scale = g.FontSize / font->FontSize;
|
const float scale = g.FontSize / font->FontSize;
|
||||||
|
|
||||||
@ -244,7 +246,6 @@ void ShowLegendEntries(ImPlot3DItemGroup& items, const ImRect& legend_bb, bool h
|
|||||||
const int num_items = items.GetLegendCount();
|
const int num_items = items.GetLegendCount();
|
||||||
if (num_items == 0)
|
if (num_items == 0)
|
||||||
return;
|
return;
|
||||||
ImPlot3DContext& gp = *GImPlot3D;
|
|
||||||
|
|
||||||
// Render legend items
|
// Render legend items
|
||||||
for (int i = 0; i < num_items; i++) {
|
for (int i = 0; i < num_items; i++) {
|
||||||
@ -508,7 +509,7 @@ int GetMouseOverAxis(const ImPlot3DPlot& plot, const bool* active_faces, const I
|
|||||||
|
|
||||||
void RenderPlotBackground(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImVec2* corners_pix, const bool* active_faces, const int plane_2d) {
|
void RenderPlotBackground(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImVec2* corners_pix, const bool* active_faces, const int plane_2d) {
|
||||||
const ImVec4 col_bg = GetStyleColorVec4(ImPlot3DCol_PlotBg);
|
const ImVec4 col_bg = GetStyleColorVec4(ImPlot3DCol_PlotBg);
|
||||||
const ImVec4 col_bg_hov = col_bg + ImVec4(0.03, 0.03, 0.03, 0.0);
|
const ImVec4 col_bg_hov = col_bg + ImVec4(0.03f, 0.03f, 0.03f, 0.0f);
|
||||||
|
|
||||||
int hovered_plane = -1;
|
int hovered_plane = -1;
|
||||||
if (!plot.Held) {
|
if (!plot.Held) {
|
||||||
@ -531,8 +532,6 @@ void RenderPlotBackground(ImDrawList* draw_list, const ImPlot3DPlot& plot, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderPlotBorder(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImVec2* corners_pix, const bool* active_faces, const int plane_2d) {
|
void RenderPlotBorder(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImVec2* corners_pix, const bool* active_faces, const int plane_2d) {
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
int hovered_edge = -1;
|
int hovered_edge = -1;
|
||||||
if (!plot.Held)
|
if (!plot.Held)
|
||||||
GetMouseOverAxis(plot, active_faces, corners_pix, plane_2d, &hovered_edge);
|
GetMouseOverAxis(plot, active_faces, corners_pix, plane_2d, &hovered_edge);
|
||||||
@ -575,13 +574,11 @@ void RenderGrid(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DP
|
|||||||
// Get the two axes (u and v) that define the face plane
|
// Get the two axes (u and v) that define the face plane
|
||||||
int idx0 = faces[face_idx][0];
|
int idx0 = faces[face_idx][0];
|
||||||
int idx1 = faces[face_idx][1];
|
int idx1 = faces[face_idx][1];
|
||||||
int idx2 = faces[face_idx][2];
|
|
||||||
int idx3 = faces[face_idx][3];
|
int idx3 = faces[face_idx][3];
|
||||||
|
|
||||||
// Corners of the face in plot space
|
// Corners of the face in plot space
|
||||||
ImPlot3DPoint p0 = corners[idx0];
|
ImPlot3DPoint p0 = corners[idx0];
|
||||||
ImPlot3DPoint p1 = corners[idx1];
|
ImPlot3DPoint p1 = corners[idx1];
|
||||||
ImPlot3DPoint p2 = corners[idx2];
|
|
||||||
ImPlot3DPoint p3 = corners[idx3];
|
ImPlot3DPoint p3 = corners[idx3];
|
||||||
|
|
||||||
// Vectors along the edges
|
// Vectors along the edges
|
||||||
@ -595,6 +592,11 @@ void RenderGrid(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DP
|
|||||||
|
|
||||||
// Compute position along u
|
// Compute position along u
|
||||||
float t_u = (tick.PlotPos - axis_u.Range.Min) / (axis_u.Range.Max - axis_u.Range.Min);
|
float t_u = (tick.PlotPos - axis_u.Range.Min) / (axis_u.Range.Max - axis_u.Range.Min);
|
||||||
|
|
||||||
|
// Skip ticks that are out of range
|
||||||
|
if (t_u < 0.0f || t_u > 1.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
ImPlot3DPoint p_start = p0 + u_vec * t_u;
|
ImPlot3DPoint p_start = p0 + u_vec * t_u;
|
||||||
ImPlot3DPoint p_end = p3 + u_vec * t_u;
|
ImPlot3DPoint p_end = p3 + u_vec * t_u;
|
||||||
|
|
||||||
@ -616,6 +618,11 @@ void RenderGrid(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DP
|
|||||||
|
|
||||||
// Compute position along v
|
// Compute position along v
|
||||||
float t_v = (tick.PlotPos - axis_v.Range.Min) / (axis_v.Range.Max - axis_v.Range.Min);
|
float t_v = (tick.PlotPos - axis_v.Range.Min) / (axis_v.Range.Max - axis_v.Range.Min);
|
||||||
|
|
||||||
|
// Skip ticks that are out of range
|
||||||
|
if (t_v < 0.0f || t_v > 1.0f)
|
||||||
|
continue;
|
||||||
|
|
||||||
ImPlot3DPoint p_start = p0 + v_vec * t_v;
|
ImPlot3DPoint p_start = p0 + v_vec * t_v;
|
||||||
ImPlot3DPoint p_end = p1 + v_vec * t_v;
|
ImPlot3DPoint p_end = p1 + v_vec * t_v;
|
||||||
|
|
||||||
@ -718,6 +725,9 @@ void RenderTickMarks(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPl
|
|||||||
const ImPlot3DTick& tick = axis.Ticker.Ticks[t];
|
const ImPlot3DTick& tick = axis.Ticker.Ticks[t];
|
||||||
float v = (tick.PlotPos - axis.Range.Min) / (axis.Range.Max - axis.Range.Min);
|
float v = (tick.PlotPos - axis.Range.Min) / (axis.Range.Max - axis.Range.Min);
|
||||||
|
|
||||||
|
// Skip ticks that are out of range
|
||||||
|
if (v < 0.0f || v > 1.0f)
|
||||||
|
continue;
|
||||||
ImPlot3DPoint tick_pos_ndc = PlotToNDC(axis_start + axis_dir * (v * axis_len));
|
ImPlot3DPoint tick_pos_ndc = PlotToNDC(axis_start + axis_dir * (v * axis_len));
|
||||||
|
|
||||||
// Half tick on each side of the axis line
|
// Half tick on each side of the axis line
|
||||||
@ -736,7 +746,6 @@ void RenderTickMarks(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderTickLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DPoint* corners, const ImVec2* corners_pix, const int axis_corners[3][2]) {
|
void RenderTickLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DPoint* corners, const ImVec2* corners_pix, const int axis_corners[3][2]) {
|
||||||
ImVec2 box_center_pix = PlotToPixels(plot.RangeCenter());
|
|
||||||
ImU32 col_tick_txt = GetStyleColorU32(ImPlot3DCol_AxisText);
|
ImU32 col_tick_txt = GetStyleColorU32(ImPlot3DCol_AxisText);
|
||||||
|
|
||||||
for (int a = 0; a < 3; a++) {
|
for (int a = 0; a < 3; a++) {
|
||||||
@ -809,6 +818,10 @@ void RenderTickLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImP
|
|||||||
|
|
||||||
// Compute position along the axis
|
// Compute position along the axis
|
||||||
float t_axis = (tick.PlotPos - axis.Range.Min) / (axis.Range.Max - axis.Range.Min);
|
float t_axis = (tick.PlotPos - axis.Range.Min) / (axis.Range.Max - axis.Range.Min);
|
||||||
|
|
||||||
|
// Skip ticks that are out of range
|
||||||
|
if (t_axis < 0.0f || t_axis > 1.0f)
|
||||||
|
continue;
|
||||||
ImPlot3DPoint tick_pos = axis_start + axis_dir * t_axis;
|
ImPlot3DPoint tick_pos = axis_start + axis_dir * t_axis;
|
||||||
|
|
||||||
// Convert to pixel coordinates
|
// Convert to pixel coordinates
|
||||||
@ -827,7 +840,6 @@ void RenderTickLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImP
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderAxisLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DPoint* corners, const ImVec2* corners_pix, const int axis_corners[3][2]) {
|
void RenderAxisLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImPlot3DPoint* corners, const ImVec2* corners_pix, const int axis_corners[3][2]) {
|
||||||
ImPlot3DPoint range_center = plot.RangeCenter();
|
|
||||||
for (int a = 0; a < 3; a++) {
|
for (int a = 0; a < 3; a++) {
|
||||||
const ImPlot3DAxis& axis = plot.Axes[a];
|
const ImPlot3DAxis& axis = plot.Axes[a];
|
||||||
if (!axis.HasLabel())
|
if (!axis.HasLabel())
|
||||||
@ -844,12 +856,13 @@ void RenderAxisLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImP
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Position at the end of the axis
|
// Position at the end of the axis
|
||||||
ImPlot3DPoint label_pos = (corners[idx0] + corners[idx1]) * 0.5f;
|
ImPlot3DPoint label_pos = (PlotToNDC(corners[idx0]) + PlotToNDC(corners[idx1])) * 0.5f;
|
||||||
|
ImPlot3DPoint center_dir = label_pos.Normalized();
|
||||||
// Add offset
|
// Add offset
|
||||||
label_pos += (label_pos - range_center) * 0.4f;
|
label_pos += center_dir * 0.3f;
|
||||||
|
|
||||||
// Convert to pixel coordinates
|
// Convert to pixel coordinates
|
||||||
ImVec2 label_pos_pix = PlotToPixels(label_pos);
|
ImVec2 label_pos_pix = NDCToPixels(label_pos);
|
||||||
|
|
||||||
// Adjust label position and angle
|
// Adjust label position and angle
|
||||||
ImU32 col_ax_txt = GetStyleColorU32(ImPlot3DCol_AxisText);
|
ImU32 col_ax_txt = GetStyleColorU32(ImPlot3DCol_AxisText);
|
||||||
@ -869,7 +882,7 @@ void RenderAxisLabels(ImDrawList* draw_list, const ImPlot3DPlot& plot, const ImP
|
|||||||
// Function to compute active faces based on the rotation
|
// Function to compute active faces based on the rotation
|
||||||
// If the plot is close to 2D, plane_2d is set to the plane index (0 -> YZ, 1 -> XZ, 2 -> XY)
|
// If the plot is close to 2D, plane_2d is set to the plane index (0 -> YZ, 1 -> XZ, 2 -> XY)
|
||||||
// plane_2d is set to -1 otherwise
|
// plane_2d is set to -1 otherwise
|
||||||
void ComputeActiveFaces(bool* active_faces, const ImPlot3DQuat& rotation, int* plane_2d = nullptr) {
|
void ComputeActiveFaces(bool* active_faces, const ImPlot3DQuat& rotation, const ImPlot3DAxis* axes, int* plane_2d = nullptr) {
|
||||||
if (plane_2d)
|
if (plane_2d)
|
||||||
*plane_2d = -1;
|
*plane_2d = -1;
|
||||||
|
|
||||||
@ -888,7 +901,8 @@ void ComputeActiveFaces(bool* active_faces, const ImPlot3DQuat& rotation, int* p
|
|||||||
num_deg++;
|
num_deg++;
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, determine based on the Z component
|
// Otherwise, determine based on the Z component
|
||||||
active_faces[i] = rot_face_n[i].z < 0.0f;
|
bool is_inverted = ImHasFlag(axes[i].Flags, ImPlot3DAxisFlags_Invert);
|
||||||
|
active_faces[i] = is_inverted ? (rot_face_n[i].z > 0.0f) : (rot_face_n[i].z < 0.0f);
|
||||||
// Set this plane as possible 2d plane
|
// Set this plane as possible 2d plane
|
||||||
if (plane_2d)
|
if (plane_2d)
|
||||||
*plane_2d = i;
|
*plane_2d = i;
|
||||||
@ -920,16 +934,14 @@ void ComputeBoxCornersPix(ImVec2* corners_pix, const ImPlot3DPoint* corners) {
|
|||||||
|
|
||||||
void RenderPlotBox(ImDrawList* draw_list, const ImPlot3DPlot& plot) {
|
void RenderPlotBox(ImDrawList* draw_list, const ImPlot3DPlot& plot) {
|
||||||
// Get plot parameters
|
// Get plot parameters
|
||||||
const ImRect& plot_area = plot.PlotRect;
|
|
||||||
const ImPlot3DQuat& rotation = plot.Rotation;
|
const ImPlot3DQuat& rotation = plot.Rotation;
|
||||||
ImPlot3DPoint range_min = plot.RangeMin();
|
ImPlot3DPoint range_min = plot.RangeMin();
|
||||||
ImPlot3DPoint range_max = plot.RangeMax();
|
ImPlot3DPoint range_max = plot.RangeMax();
|
||||||
ImPlot3DPoint range_center = plot.RangeCenter();
|
|
||||||
|
|
||||||
// Compute active faces
|
// Compute active faces
|
||||||
bool active_faces[3];
|
bool active_faces[3];
|
||||||
int plane_2d = -1;
|
int plane_2d = -1;
|
||||||
ComputeActiveFaces(active_faces, rotation, &plane_2d);
|
ComputeActiveFaces(active_faces, rotation, plot.Axes, &plane_2d);
|
||||||
bool is_2d = plane_2d != -1;
|
bool is_2d = plane_2d != -1;
|
||||||
|
|
||||||
// Compute box corners in plot space
|
// Compute box corners in plot space
|
||||||
@ -1016,7 +1028,7 @@ void RenderPlotBox(ImDrawList* draw_list, const ImPlot3DPlot& plot) {
|
|||||||
axis_corners[y_axis][1] = y_corner;
|
axis_corners[y_axis][1] = y_corner;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int index = (active_faces[0] << 2) | (active_faces[1] << 1) | (active_faces[2]);
|
int index = ((int)active_faces[0] << 2) | ((int)active_faces[1] << 1) | ((int)active_faces[2]);
|
||||||
for (int a = 0; a < 3; a++) {
|
for (int a = 0; a < 3; a++) {
|
||||||
axis_corners[a][0] = axis_corners_lookup_3d[index][a][0];
|
axis_corners[a][0] = axis_corners_lookup_3d[index][a][0];
|
||||||
axis_corners[a][1] = axis_corners_lookup_3d[index][a][1];
|
axis_corners[a][1] = axis_corners_lookup_3d[index][a][1];
|
||||||
@ -1048,7 +1060,7 @@ int Formatter_Default(float value, char* buff, int size, void* data) {
|
|||||||
double NiceNum(double x, bool round) {
|
double NiceNum(double x, bool round) {
|
||||||
double f;
|
double f;
|
||||||
double nf;
|
double nf;
|
||||||
int expv = (int)floor(ImLog10(x));
|
int expv = (int)floor(ImLog10((float)x));
|
||||||
f = x / ImPow(10.0, (double)expv);
|
f = x / ImPow(10.0, (double)expv);
|
||||||
if (round)
|
if (round)
|
||||||
if (f < 1.5)
|
if (f < 1.5)
|
||||||
@ -1070,11 +1082,11 @@ double NiceNum(double x, bool round) {
|
|||||||
return nf * ImPow(10.0, expv);
|
return nf * ImPow(10.0, expv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, ImPlot3DFormatter formatter, void* formatter_data) {
|
void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, float pixels, ImPlot3DFormatter formatter, void* formatter_data) {
|
||||||
if (range.Min == range.Max)
|
if (range.Min == range.Max)
|
||||||
return;
|
return;
|
||||||
const int nMinor = 5;
|
const int nMinor = ImMin(ImMax(1, (int)IM_ROUND(pixels / 30.0f)), 5);
|
||||||
const int nMajor = 3;
|
const int nMajor = ImMax(2, (int)IM_ROUND(pixels / 80.0f));
|
||||||
const int max_ticks_labels = 7;
|
const int max_ticks_labels = 7;
|
||||||
const double nice_range = NiceNum(range.Size() * 0.99, false);
|
const double nice_range = NiceNum(range.Size() * 0.99, false);
|
||||||
const double interval = NiceNum(nice_range / (nMajor - 1), true);
|
const double interval = NiceNum(nice_range / (nMajor - 1), true);
|
||||||
@ -1082,23 +1094,22 @@ void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, ImPlot3
|
|||||||
const double graphmax = ceil(range.Max / interval) * interval;
|
const double graphmax = ceil(range.Max / interval) * interval;
|
||||||
bool first_major_set = false;
|
bool first_major_set = false;
|
||||||
int first_major_idx = 0;
|
int first_major_idx = 0;
|
||||||
const int idx0 = ticker.TickCount(); // ticker may have user custom ticks
|
const int idx0 = ticker.TickCount(); // Ticker may have user custom ticks
|
||||||
ImVec2 total_size(0, 0);
|
|
||||||
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
for (double major = graphmin; major < graphmax + 0.5 * interval; major += interval) {
|
||||||
// is this zero? combat zero formatting issues
|
// Is this zero? combat zero formatting issues
|
||||||
if (major - interval < 0 && major + interval > 0)
|
if (major - interval < 0 && major + interval > 0)
|
||||||
major = 0;
|
major = 0;
|
||||||
if (range.Contains(major)) {
|
if (range.Contains((float)major)) {
|
||||||
if (!first_major_set) {
|
if (!first_major_set) {
|
||||||
first_major_idx = ticker.TickCount();
|
first_major_idx = ticker.TickCount();
|
||||||
first_major_set = true;
|
first_major_set = true;
|
||||||
}
|
}
|
||||||
total_size += ticker.AddTick(major, true, true, formatter, formatter_data).LabelSize;
|
ticker.AddTick(major, true, true, formatter, formatter_data);
|
||||||
}
|
}
|
||||||
for (int i = 1; i < nMinor; ++i) {
|
for (int i = 1; i < nMinor; ++i) {
|
||||||
double minor = major + i * interval / nMinor;
|
double minor = major + i * interval / nMinor;
|
||||||
if (range.Contains(minor)) {
|
if (range.Contains((float)minor)) {
|
||||||
total_size += ticker.AddTick(minor, false, true, formatter, formatter_data).LabelSize;
|
ticker.AddTick(minor, false, true, formatter, formatter_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1112,10 +1123,24 @@ void Locator_Default(ImPlot3DTicker& ticker, const ImPlot3DRange& range, ImPlot3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddTicksCustom(const double* values, const char* const labels[], int n, ImPlot3DTicker& ticker, ImPlot3DFormatter formatter, void* data) {
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
if (labels != nullptr)
|
||||||
|
ticker.AddTick(values[i], false, true, labels[i]);
|
||||||
|
else
|
||||||
|
ticker.AddTick(values[i], false, true, formatter, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// [SECTION] Context Menus
|
// [SECTION] Context Menus
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static const char* axis_contexts[3] = {"##XAxisContext", "##YAxisContext", "##ZAxisContext"};
|
||||||
|
static const char* axis_labels[3] = {"X-Axis", "Y-Axis", "Z-Axis"};
|
||||||
|
static const char* plane_contexts[3] = {"##YZPlaneContext", "##XZPlaneContext", "##XYPlaneContext"};
|
||||||
|
static const char* plane_labels[3] = {"YZ-Plane", "XZ-Plane", "XY-Plane"};
|
||||||
|
|
||||||
bool ShowLegendContextMenu(ImPlot3DLegend& legend, bool visible) {
|
bool ShowLegendContextMenu(ImPlot3DLegend& legend, bool visible) {
|
||||||
const float s = ImGui::GetFrameHeight();
|
const float s = ImGui::GetFrameHeight();
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@ -1180,6 +1205,12 @@ void ShowAxisContextMenu(ImPlot3DAxis& axis) {
|
|||||||
ImGui::CheckboxFlags("Auto-Fit", (unsigned int*)&axis.Flags, ImPlot3DAxisFlags_AutoFit);
|
ImGui::CheckboxFlags("Auto-Fit", (unsigned int*)&axis.Flags, ImPlot3DAxisFlags_AutoFit);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
bool inverted = ImPlot3D::ImHasFlag(axis.Flags, ImPlot3DAxisFlags_Invert);
|
||||||
|
if (ImGui::Checkbox("Invert", &inverted))
|
||||||
|
ImFlipFlag(axis.Flags, ImPlot3DAxisFlags_Invert);
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
ImGui::BeginDisabled(axis.Label.empty());
|
ImGui::BeginDisabled(axis.Label.empty());
|
||||||
if (ImGui::Checkbox("Label", &label))
|
if (ImGui::Checkbox("Label", &label))
|
||||||
ImFlipFlag(axis.Flags, ImPlot3DAxisFlags_NoLabel);
|
ImFlipFlag(axis.Flags, ImPlot3DAxisFlags_NoLabel);
|
||||||
@ -1193,13 +1224,22 @@ void ShowAxisContextMenu(ImPlot3DAxis& axis) {
|
|||||||
ImFlipFlag(axis.Flags, ImPlot3DAxisFlags_NoTickLabels);
|
ImFlipFlag(axis.Flags, ImPlot3DAxisFlags_NoTickLabels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowPlaneContextMenu(ImPlot3DPlot& plot, int plane_idx) {
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (i == plane_idx)
|
||||||
|
continue;
|
||||||
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
|
ImGui::PushID(i);
|
||||||
|
if (ImGui::BeginMenu(axis.HasLabel() ? axis.GetLabel() : axis_labels[i])) {
|
||||||
|
ShowAxisContextMenu(axis);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShowPlotContextMenu(ImPlot3DPlot& plot) {
|
void ShowPlotContextMenu(ImPlot3DPlot& plot) {
|
||||||
ImPlot3DContext& gp = *GImPlot3D;
|
|
||||||
const bool owns_legend = gp.CurrentItems == &plot.Items;
|
|
||||||
|
|
||||||
char buf[16] = {};
|
char buf[16] = {};
|
||||||
|
|
||||||
const char* axis_labels[3] = {"X-Axis", "Y-Axis", "Z-Axis"};
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
ImPlot3DAxis& axis = plot.Axes[i];
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
ImGui::PushID(i);
|
ImGui::PushID(i);
|
||||||
@ -1212,6 +1252,22 @@ void ShowPlotContextMenu(ImPlot3DPlot& plot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if ((ImGui::BeginMenu("Box"))) {
|
||||||
|
ImGui::PushItemWidth(75);
|
||||||
|
float temp_scale[3] = {plot.BoxScale[0], plot.BoxScale[1], plot.BoxScale[2]};
|
||||||
|
if (ImGui::DragFloat("Scale X", &temp_scale[0], 0.01f, 0.1f, 3.0f))
|
||||||
|
plot.BoxScale[0] = ImMax(temp_scale[0], 0.01f);
|
||||||
|
if (ImGui::DragFloat("Scale Y", &temp_scale[1], 0.01f, 0.1f, 3.0f))
|
||||||
|
plot.BoxScale[1] = ImMax(temp_scale[1], 0.01f);
|
||||||
|
if (ImGui::DragFloat("Scale Z", &temp_scale[2], 0.01f, 0.1f, 3.0f))
|
||||||
|
plot.BoxScale[2] = ImMax(temp_scale[2], 0.01f);
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
if ((ImGui::BeginMenu("Legend"))) {
|
if ((ImGui::BeginMenu("Legend"))) {
|
||||||
if (ShowLegendContextMenu(plot.Items.Legend, !ImPlot3D::ImHasFlag(plot.Flags, ImPlot3DFlags_NoLegend)))
|
if (ShowLegendContextMenu(plot.Items.Legend, !ImPlot3D::ImHasFlag(plot.Flags, ImPlot3DFlags_NoLegend)))
|
||||||
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoLegend);
|
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoLegend);
|
||||||
@ -1223,6 +1279,10 @@ void ShowPlotContextMenu(ImPlot3DPlot& plot) {
|
|||||||
if (ImGui::MenuItem("Title", nullptr, plot.HasTitle()))
|
if (ImGui::MenuItem("Title", nullptr, plot.HasTitle()))
|
||||||
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoTitle);
|
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoTitle);
|
||||||
ImGui::EndDisabled();
|
ImGui::EndDisabled();
|
||||||
|
if (ImGui::MenuItem("Clip", nullptr, !ImHasFlag(plot.Flags, ImPlot3DFlags_NoClip)))
|
||||||
|
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoClip);
|
||||||
|
if (ImGui::MenuItem("Mouse Position", nullptr, !ImHasFlag(plot.Flags, ImPlot3DFlags_NoMouseText)))
|
||||||
|
ImFlipFlag(plot.Flags, ImPlot3DFlags_NoMouseText);
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1295,6 +1355,11 @@ bool BeginPlot(const char* title_id, const ImVec2& size, ImPlot3DFlags flags) {
|
|||||||
// Reset legend
|
// Reset legend
|
||||||
plot.Items.Legend.Reset();
|
plot.Items.Legend.Reset();
|
||||||
|
|
||||||
|
// Reset axes
|
||||||
|
for (int i = 0; i < ImAxis3D_COUNT; ++i) {
|
||||||
|
plot.Axes[i].Reset();
|
||||||
|
}
|
||||||
|
|
||||||
// Push frame rect clipping
|
// Push frame rect clipping
|
||||||
ImGui::PushClipRect(plot.FrameRect.Min, plot.FrameRect.Max, true);
|
ImGui::PushClipRect(plot.FrameRect.Min, plot.FrameRect.Max, true);
|
||||||
plot.DrawList._Flags = window->DrawList->Flags;
|
plot.DrawList._Flags = window->DrawList->Flags;
|
||||||
@ -1345,7 +1410,6 @@ void EndPlot() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Axis context menus
|
// Axis context menus
|
||||||
static const char* axis_contexts[3] = {"##XAxisContext", "##YAxisContext", "##ZAxisContext"};
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
ImPlot3DAxis& axis = plot.Axes[i];
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
if (ImGui::BeginPopup(axis_contexts[i])) {
|
if (ImGui::BeginPopup(axis_contexts[i])) {
|
||||||
@ -1356,6 +1420,16 @@ void EndPlot() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Plane context menus
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (ImGui::BeginPopup(plane_contexts[i])) {
|
||||||
|
ImGui::Text("%s", plane_labels[i]);
|
||||||
|
ImGui::Separator();
|
||||||
|
ShowPlaneContextMenu(plot, i);
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Plot context menu
|
// Plot context menu
|
||||||
if (ImGui::BeginPopup("##PlotContext")) {
|
if (ImGui::BeginPopup("##PlotContext")) {
|
||||||
ShowPlotContextMenu(plot);
|
ShowPlotContextMenu(plot);
|
||||||
@ -1408,6 +1482,41 @@ void SetupAxisLimits(ImAxis3D idx, double min_lim, double max_lim, ImPlot3DCond
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupAxisFormat(ImAxis3D idx, ImPlot3DFormatter formatter, void* data) {
|
||||||
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||||
|
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
|
||||||
|
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
||||||
|
ImPlot3DAxis& axis = plot.Axes[idx];
|
||||||
|
axis.Formatter = formatter;
|
||||||
|
axis.FormatterData = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupAxisTicks(ImAxis3D idx, const double* values, int n_ticks, const char* const labels[], bool keep_default) {
|
||||||
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||||
|
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
|
||||||
|
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
||||||
|
ImPlot3DAxis& axis = plot.Axes[idx];
|
||||||
|
axis.ShowDefaultTicks = keep_default;
|
||||||
|
AddTicksCustom(values,
|
||||||
|
labels,
|
||||||
|
n_ticks,
|
||||||
|
axis.Ticker,
|
||||||
|
axis.Formatter ? axis.Formatter : Formatter_Default,
|
||||||
|
(axis.Formatter && axis.FormatterData) ? axis.FormatterData : (void*)IMPLOT3D_LABEL_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupAxisTicks(ImAxis3D idx, double v_min, double v_max, int n_ticks, const char* const labels[], bool keep_default) {
|
||||||
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||||
|
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
|
||||||
|
n_ticks = n_ticks < 2 ? 2 : n_ticks;
|
||||||
|
ImVector<double> temp;
|
||||||
|
FillRange(temp, n_ticks, v_min, v_max);
|
||||||
|
SetupAxisTicks(idx, temp.Data, n_ticks, labels, keep_default);
|
||||||
|
}
|
||||||
|
|
||||||
void SetupAxes(const char* x_label, const char* y_label, const char* z_label, ImPlot3DAxisFlags x_flags, ImPlot3DAxisFlags y_flags, ImPlot3DAxisFlags z_flags) {
|
void SetupAxes(const char* x_label, const char* y_label, const char* z_label, ImPlot3DAxisFlags x_flags, ImPlot3DAxisFlags y_flags, ImPlot3DAxisFlags z_flags) {
|
||||||
SetupAxis(ImAxis3D_X, x_label, x_flags);
|
SetupAxis(ImAxis3D_X, x_label, x_flags);
|
||||||
SetupAxis(ImAxis3D_Y, y_label, y_flags);
|
SetupAxis(ImAxis3D_Y, y_label, y_flags);
|
||||||
@ -1422,6 +1531,15 @@ void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, dou
|
|||||||
GImPlot3D->CurrentPlot->FitThisFrame = false;
|
GImPlot3D->CurrentPlot->FitThisFrame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupBoxScale(float x, float y, float z) {
|
||||||
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||||
|
"SetupBoxScale() needs to be called after BeginPlot() and before any setup locking functions (e.g. PlotX)!");
|
||||||
|
IM_ASSERT_USER_ERROR(x > 0.0f && y > 0.0f && z > 0.0f, "SetupBoxScale() requires all aspect ratios to be greater than 0!");
|
||||||
|
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
||||||
|
plot.BoxScale = ImPlot3DPoint(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
void SetupLegend(ImPlot3DLocation location, ImPlot3DLegendFlags flags) {
|
void SetupLegend(ImPlot3DLocation location, ImPlot3DLegendFlags flags) {
|
||||||
ImPlot3DContext& gp = *GImPlot3D;
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
|
||||||
@ -1457,7 +1575,7 @@ ImVec2 PlotToPixels(const ImPlot3DPoint& point) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 PlotToPixels(double x, double y, double z) {
|
ImVec2 PlotToPixels(double x, double y, double z) {
|
||||||
return PlotToPixels(ImPlot3DPoint(x, y, z));
|
return PlotToPixels(ImPlot3DPoint((float)x, (float)y, (float)z));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DRay PixelsToPlotRay(const ImVec2& pix) {
|
ImPlot3DRay PixelsToPlotRay(const ImVec2& pix) {
|
||||||
@ -1467,7 +1585,7 @@ ImPlot3DRay PixelsToPlotRay(const ImVec2& pix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DRay PixelsToPlotRay(double x, double y) {
|
ImPlot3DRay PixelsToPlotRay(double x, double y) {
|
||||||
return PixelsToPlotRay(ImVec2(x, y));
|
return PixelsToPlotRay(ImVec2((float)x, (float)y));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DPoint PixelsToPlotPlane(const ImVec2& pix, ImPlane3D plane, bool mask) {
|
ImPlot3DPoint PixelsToPlotPlane(const ImVec2& pix, ImPlane3D plane, bool mask) {
|
||||||
@ -1509,22 +1627,22 @@ ImPlot3DPoint PixelsToPlotPlane(const ImVec2& pix, ImPlane3D plane, bool mask) {
|
|||||||
return O + D * t;
|
return O + D * t;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper lambda to check if point P is within the plot box
|
|
||||||
auto InRange = [&](const ImPlot3DPoint& P) {
|
|
||||||
return P.x >= -0.5 && P.x <= 0.5 &&
|
|
||||||
P.y >= -0.5 && P.y <= 0.5 &&
|
|
||||||
P.z >= -0.5 && P.z <= 0.5;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute which plane to intersect with
|
// Compute which plane to intersect with
|
||||||
bool active_faces[3];
|
bool active_faces[3];
|
||||||
ComputeActiveFaces(active_faces, plot.Rotation);
|
ComputeActiveFaces(active_faces, plot.Rotation, plot.Axes);
|
||||||
|
|
||||||
// Calculate intersection point with the planes
|
// Calculate intersection point with the planes
|
||||||
ImPlot3DPoint P = IntersectPlane(active_faces[plane] ? 0.5 : -0.5);
|
ImPlot3DPoint P = IntersectPlane(active_faces[plane] ? 0.5f * plot.BoxScale[plane] : -0.5f * plot.BoxScale[plane]);
|
||||||
if (P.IsNaN())
|
if (P.IsNaN())
|
||||||
return P;
|
return P;
|
||||||
|
|
||||||
|
// Helper lambda to check if point P is within the plot box
|
||||||
|
auto InRange = [&](const ImPlot3DPoint& P) {
|
||||||
|
return P.x >= -0.5f * plot.BoxScale.x && P.x <= 0.5f * plot.BoxScale.x &&
|
||||||
|
P.y >= -0.5f * plot.BoxScale.y && P.y <= 0.5f * plot.BoxScale.y &&
|
||||||
|
P.z >= -0.5f * plot.BoxScale.z && P.z <= 0.5f * plot.BoxScale.z;
|
||||||
|
};
|
||||||
|
|
||||||
// Handle mask (if one of the intersections is out of range, set it to NAN)
|
// Handle mask (if one of the intersections is out of range, set it to NAN)
|
||||||
if (mask) {
|
if (mask) {
|
||||||
switch (plane) {
|
switch (plane) {
|
||||||
@ -1547,7 +1665,7 @@ ImPlot3DPoint PixelsToPlotPlane(const ImVec2& pix, ImPlane3D plane, bool mask) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DPoint PixelsToPlotPlane(double x, double y, ImPlane3D plane, bool mask) {
|
ImPlot3DPoint PixelsToPlotPlane(double x, double y, ImPlane3D plane, bool mask) {
|
||||||
return PixelsToPlotPlane(ImVec2(x, y), plane, mask);
|
return PixelsToPlotPlane(ImVec2((float)x, (float)y), plane, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 GetPlotPos() {
|
ImVec2 GetPlotPos() {
|
||||||
@ -1583,8 +1701,13 @@ ImPlot3DPoint PlotToNDC(const ImPlot3DPoint& point) {
|
|||||||
SetupLock();
|
SetupLock();
|
||||||
|
|
||||||
ImPlot3DPoint ndc_point;
|
ImPlot3DPoint ndc_point;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
ndc_point[i] = plot.Axes[i].PlotToNDC(point[i]);
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
|
float ndc_range = 0.5f * plot.BoxScale[i];
|
||||||
|
float t = (point[i] - axis.Range.Min) / (axis.Range.Max - axis.Range.Min);
|
||||||
|
t *= plot.BoxScale[i];
|
||||||
|
ndc_point[i] = ImPlot3D::ImHasFlag(axis.Flags, ImPlot3DAxisFlags_Invert) ? (ndc_range - t) : (t - ndc_range);
|
||||||
|
}
|
||||||
return ndc_point;
|
return ndc_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1595,8 +1718,13 @@ ImPlot3DPoint NDCToPlot(const ImPlot3DPoint& point) {
|
|||||||
SetupLock();
|
SetupLock();
|
||||||
|
|
||||||
ImPlot3DPoint plot_point;
|
ImPlot3DPoint plot_point;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++) {
|
||||||
plot_point[i] = plot.Axes[i].NDCToPlot(point[i]);
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
|
float ndc_range = 0.5f * plot.BoxScale[i];
|
||||||
|
float t = ImPlot3D::ImHasFlag(axis.Flags, ImPlot3DAxisFlags_Invert) ? (ndc_range - point[i]) : (point[i] + ndc_range);
|
||||||
|
t /= plot.BoxScale[i];
|
||||||
|
plot_point[i] = axis.Range.Min + t * (axis.Range.Max - axis.Range.Min);
|
||||||
|
}
|
||||||
return plot_point;
|
return plot_point;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1606,9 +1734,8 @@ ImVec2 NDCToPixels(const ImPlot3DPoint& point) {
|
|||||||
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
||||||
SetupLock();
|
SetupLock();
|
||||||
|
|
||||||
float zoom = ImMin(plot.PlotRect.GetWidth(), plot.PlotRect.GetHeight()) / 1.8f;
|
|
||||||
ImVec2 center = plot.PlotRect.GetCenter();
|
ImVec2 center = plot.PlotRect.GetCenter();
|
||||||
ImPlot3DPoint point_pix = zoom * (plot.Rotation * point);
|
ImPlot3DPoint point_pix = plot.GetBoxZoom() * (plot.Rotation * point);
|
||||||
point_pix.y *= -1.0f; // Invert y-axis
|
point_pix.y *= -1.0f; // Invert y-axis
|
||||||
point_pix.x += center.x;
|
point_pix.x += center.x;
|
||||||
point_pix.y += center.y;
|
point_pix.y += center.y;
|
||||||
@ -1623,7 +1750,7 @@ ImPlot3DRay PixelsToNDCRay(const ImVec2& pix) {
|
|||||||
SetupLock();
|
SetupLock();
|
||||||
|
|
||||||
// Calculate zoom factor and plot center
|
// Calculate zoom factor and plot center
|
||||||
float zoom = ImMin(plot.PlotRect.GetWidth(), plot.PlotRect.GetHeight()) / 1.8f;
|
float zoom = plot.GetBoxZoom();
|
||||||
ImVec2 center = plot.PlotRect.GetCenter();
|
ImVec2 center = plot.PlotRect.GetCenter();
|
||||||
|
|
||||||
// Undo screen transformations to get back to NDC space
|
// Undo screen transformations to get back to NDC space
|
||||||
@ -1645,7 +1772,6 @@ ImPlot3DRay PixelsToNDCRay(const ImVec2& pix) {
|
|||||||
ImPlot3DRay NDCRayToPlotRay(const ImPlot3DRay& ray) {
|
ImPlot3DRay NDCRayToPlotRay(const ImPlot3DRay& ray) {
|
||||||
ImPlot3DContext& gp = *GImPlot3D;
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "NDCRayToPlotRay() needs to be called between BeginPlot() and EndPlot()!");
|
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "NDCRayToPlotRay() needs to be called between BeginPlot() and EndPlot()!");
|
||||||
ImPlot3DPlot& plot = *gp.CurrentPlot;
|
|
||||||
SetupLock();
|
SetupLock();
|
||||||
|
|
||||||
// Convert NDC origin and a point along the ray to plot coordinates
|
// Convert NDC origin and a point along the ray to plot coordinates
|
||||||
@ -1697,7 +1823,7 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
ImPlot3DPoint range_max = plot.RangeMax();
|
ImPlot3DPoint range_max = plot.RangeMax();
|
||||||
bool active_faces[3];
|
bool active_faces[3];
|
||||||
int plane_2d = -1;
|
int plane_2d = -1;
|
||||||
ComputeActiveFaces(active_faces, rotation, &plane_2d);
|
ComputeActiveFaces(active_faces, rotation, plot.Axes, &plane_2d);
|
||||||
ImPlot3DPoint corners[8];
|
ImPlot3DPoint corners[8];
|
||||||
ComputeBoxCorners(corners, range_min, range_max);
|
ComputeBoxCorners(corners, range_min, range_max);
|
||||||
ImVec2 corners_pix[8];
|
ImVec2 corners_pix[8];
|
||||||
@ -1725,25 +1851,37 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
|
|
||||||
// Check which axes should be transformed (fit/zoom/translate)
|
// Check which axes should be transformed (fit/zoom/translate)
|
||||||
bool any_axis_held = plot.Axes[0].Held || plot.Axes[1].Held || plot.Axes[2].Held;
|
bool any_axis_held = plot.Axes[0].Held || plot.Axes[1].Held || plot.Axes[2].Held;
|
||||||
static bool transform_axis[3] = {false, false, false};
|
|
||||||
if (!any_axis_held) {
|
if (!any_axis_held) {
|
||||||
// Only update the transformation axes if the user is not already performing a transformation
|
// Only update the transformation axes if the user is not already performing a transformation
|
||||||
transform_axis[0] = transform_axis[1] = transform_axis[2] = false;
|
plot.Axes[0].Hovered = plot.Axes[1].Hovered = plot.Axes[2].Hovered = false;
|
||||||
if (hovered_axis != -1) {
|
if (hovered_axis != -1) {
|
||||||
transform_axis[hovered_axis] = true;
|
plot.Axes[hovered_axis].Hovered = true;
|
||||||
} else if (hovered_plane != -1) {
|
} else if (hovered_plane != -1) {
|
||||||
transform_axis[(hovered_plane + 1) % 3] = true;
|
plot.Axes[(hovered_plane + 1) % 3].Hovered = true;
|
||||||
transform_axis[(hovered_plane + 2) % 3] = true;
|
plot.Axes[(hovered_plane + 2) % 3].Hovered = true;
|
||||||
} else {
|
} else {
|
||||||
transform_axis[0] = transform_axis[1] = transform_axis[2] = true;
|
plot.Axes[0].Hovered = plot.Axes[1].Hovered = plot.Axes[2].Hovered = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute plane that is being hovered by mouse
|
||||||
|
ImPlane3D mouse_plane = ImPlane3D_XY;
|
||||||
|
if (plane_2d != -1)
|
||||||
|
mouse_plane = plane_2d;
|
||||||
|
else if (plot.Axes[1].Hovered && plot.Axes[2].Hovered)
|
||||||
|
mouse_plane = ImPlane3D_YZ;
|
||||||
|
else if (plot.Axes[0].Hovered && plot.Axes[2].Hovered)
|
||||||
|
mouse_plane = ImPlane3D_XZ;
|
||||||
|
else if (plot.Axes[2].Hovered)
|
||||||
|
mouse_plane = ImPlane3D_YZ;
|
||||||
|
ImVec2 mouse_pos = ImGui::GetMousePos();
|
||||||
|
ImPlot3DPoint mouse_pos_plot = PixelsToPlotPlane(mouse_pos, mouse_plane, false);
|
||||||
|
|
||||||
// Handle translation/zoom fit with double click
|
// Handle translation/zoom fit with double click
|
||||||
if (plot_clicked && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) || ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Middle)) {
|
if (plot_clicked && (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) || ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Middle))) {
|
||||||
plot.FitThisFrame = true;
|
plot.FitThisFrame = true;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
plot.Axes[i].FitThisFrame = transform_axis[i];
|
plot.Axes[i].FitThisFrame = plot.Axes[i].Hovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle auto fit
|
// Handle auto fit
|
||||||
@ -1757,23 +1895,32 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
if (plot.Held && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
if (plot.Held && ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||||
ImVec2 delta(IO.MouseDelta.x, IO.MouseDelta.y);
|
ImVec2 delta(IO.MouseDelta.x, IO.MouseDelta.y);
|
||||||
|
|
||||||
if (transform_axis[0] && transform_axis[1] && transform_axis[2]) {
|
if (plot.Axes[0].Hovered && plot.Axes[1].Hovered && plot.Axes[2].Hovered) {
|
||||||
// Perform unconstrained translation (translate on the viewer plane)
|
// Perform unconstrained translation (translate on the viewer plane)
|
||||||
|
|
||||||
// Compute delta_pixels in 3D (invert y-axis)
|
// Compute delta_pixels in 3D (invert y-axis)
|
||||||
ImPlot3DPoint delta_pixels(delta.x, -delta.y, 0.0f);
|
ImPlot3DPoint delta_pixels(delta.x, -delta.y, 0.0f);
|
||||||
|
|
||||||
// Convert delta to NDC space
|
// Convert delta to NDC space
|
||||||
float zoom = ImMin(plot.PlotRect.GetWidth(), plot.PlotRect.GetHeight()) / 1.8f;
|
float zoom = plot.GetBoxZoom();
|
||||||
ImPlot3DPoint delta_NDC = plot.Rotation.Inverse() * (delta_pixels / zoom);
|
ImPlot3DPoint delta_NDC = plot.Rotation.Inverse() * (delta_pixels / zoom);
|
||||||
|
|
||||||
// Convert delta to plot space
|
// Convert delta to plot space
|
||||||
ImPlot3DPoint delta_plot = delta_NDC * (plot.RangeMax() - plot.RangeMin());
|
ImPlot3DPoint delta_plot = delta_NDC * (plot.RangeMax() - plot.RangeMin()) / plot.BoxScale;
|
||||||
|
|
||||||
|
// Adjust delta for inverted axes
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
if (ImHasFlag(plot.Axes[i].Flags, ImPlot3DAxisFlags_Invert))
|
||||||
|
delta_plot[i] *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Adjust plot range to translate the plot
|
// Adjust plot range to translate the plot
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (transform_axis[i]) {
|
if (plot.Axes[i].Hovered) {
|
||||||
plot.Axes[i].SetRange(plot.Axes[i].Range.Min - delta_plot[i], plot.Axes[i].Range.Max - delta_plot[i]);
|
if (!plot.Axes[i].IsInputLocked()) {
|
||||||
|
plot.Axes[i].SetMin(plot.Axes[i].Range.Min - delta_plot[i]);
|
||||||
|
plot.Axes[i].SetMax(plot.Axes[i].Range.Max - delta_plot[i]);
|
||||||
|
}
|
||||||
plot.Axes[i].Held = true;
|
plot.Axes[i].Held = true;
|
||||||
}
|
}
|
||||||
// If no axis was held before (user started translating in this frame), set the held edge/plane indices
|
// If no axis was held before (user started translating in this frame), set the held edge/plane indices
|
||||||
@ -1782,32 +1929,22 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
plot.HeldPlaneIdx = hovered_plane_idx;
|
plot.HeldPlaneIdx = hovered_plane_idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (transform_axis[0] || transform_axis[1] || transform_axis[2]) {
|
} else if (plot.Axes[0].Hovered || plot.Axes[1].Hovered || plot.Axes[2].Hovered) {
|
||||||
// Translate along plane/axis
|
// Translate along plane/axis
|
||||||
|
|
||||||
// Mouse delta in pixels
|
// Mouse delta in pixels
|
||||||
ImVec2 mouse_pos = ImGui::GetMousePos();
|
|
||||||
ImVec2 mouse_delta(IO.MouseDelta.x, IO.MouseDelta.y);
|
ImVec2 mouse_delta(IO.MouseDelta.x, IO.MouseDelta.y);
|
||||||
|
|
||||||
// TODO Choose best plane given transform_axis and current view
|
ImPlot3DPoint mouse_delta_plot = PixelsToPlotPlane(mouse_pos + mouse_delta, mouse_plane, false);
|
||||||
// For now it crashes when transforming only one axis in the 2D view
|
ImPlot3DPoint delta_plot = mouse_delta_plot - mouse_pos_plot;
|
||||||
ImPlane3D plane = ImPlane3D_XY;
|
|
||||||
if (transform_axis[1] && transform_axis[2])
|
|
||||||
plane = ImPlane3D_YZ;
|
|
||||||
else if (transform_axis[0] && transform_axis[2])
|
|
||||||
plane = ImPlane3D_XZ;
|
|
||||||
else if (transform_axis[2])
|
|
||||||
plane = ImPlane3D_YZ;
|
|
||||||
|
|
||||||
ImPlot3DPoint mouse_plot = PixelsToPlotPlane(mouse_pos, plane, false);
|
|
||||||
ImPlot3DPoint mouse_delta_plot = PixelsToPlotPlane(mouse_pos + mouse_delta, plane, false);
|
|
||||||
ImPlot3DPoint delta_plot = mouse_delta_plot - mouse_plot;
|
|
||||||
|
|
||||||
// Apply translation to the selected axes
|
// Apply translation to the selected axes
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (transform_axis[i]) {
|
if (plot.Axes[i].Hovered) {
|
||||||
plot.Axes[i].SetRange(plot.Axes[i].Range.Min - delta_plot[i],
|
if (!plot.Axes[i].IsInputLocked()) {
|
||||||
plot.Axes[i].Range.Max - delta_plot[i]);
|
plot.Axes[i].SetMin(plot.Axes[i].Range.Min - delta_plot[i]);
|
||||||
|
plot.Axes[i].SetMax(plot.Axes[i].Range.Max - delta_plot[i]);
|
||||||
|
}
|
||||||
plot.Axes[i].Held = true;
|
plot.Axes[i].Held = true;
|
||||||
}
|
}
|
||||||
if (!any_axis_held) {
|
if (!any_axis_held) {
|
||||||
@ -1819,7 +1956,7 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle context click with right mouse button
|
// Handle context click with right mouse button
|
||||||
if (plot.Held && ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
if (plot.Held && ImGui::IsMouseClicked(ImGuiMouseButton_Right) && !ImPlot3D::ImHasFlag(plot.Flags, ImPlot3DFlags_NoMenus))
|
||||||
plot.ContextClick = true;
|
plot.ContextClick = true;
|
||||||
if (rotating || ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right))
|
if (rotating || ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right))
|
||||||
plot.ContextClick = false;
|
plot.ContextClick = false;
|
||||||
@ -1835,6 +1972,8 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
// Compute plane normal
|
// Compute plane normal
|
||||||
ImPlot3DPoint axis_normal = ImPlot3DPoint(0.0f, 0.0f, 0.0f);
|
ImPlot3DPoint axis_normal = ImPlot3DPoint(0.0f, 0.0f, 0.0f);
|
||||||
axis_normal[hovered_plane] = active_faces[hovered_plane] ? -1.0f : 1.0f;
|
axis_normal[hovered_plane] = active_faces[hovered_plane] ? -1.0f : 1.0f;
|
||||||
|
if (ImPlot3D::ImHasFlag(plot.Axes[hovered_plane].Flags, ImPlot3DAxisFlags_Invert))
|
||||||
|
axis_normal[hovered_plane] *= -1;
|
||||||
|
|
||||||
// Compute rotation to align the plane normal with the z-axis
|
// Compute rotation to align the plane normal with the z-axis
|
||||||
ImPlot3DQuat align_normal = ImPlot3DQuat::FromTwoVectors(plot.RotationAnimationEnd * axis_normal, ImPlot3DPoint(0.0f, 0.0f, 1.0f));
|
ImPlot3DQuat align_normal = ImPlot3DQuat::FromTwoVectors(plot.RotationAnimationEnd * axis_normal, ImPlot3DPoint(0.0f, 0.0f, 1.0f));
|
||||||
@ -1909,13 +2048,37 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
float zoom = 1.0f + delta;
|
float zoom = 1.0f + delta;
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
ImPlot3DAxis& axis = plot.Axes[i];
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
float center = (axis.Range.Min + axis.Range.Max) * 0.5f;
|
|
||||||
float size = axis.Range.Max - axis.Range.Min;
|
float size = axis.Range.Max - axis.Range.Min;
|
||||||
size *= zoom;
|
float new_min, new_max;
|
||||||
if (transform_axis[i]) {
|
if (hovered_axis != -1 || hovered_plane != -1) {
|
||||||
plot.Axes[i].SetRange(center - size * 0.5f, center + size * 0.5f);
|
// If mouse over the plot box, zoom around the mouse plot position
|
||||||
|
float new_size = size * zoom;
|
||||||
|
|
||||||
|
// Calculate offset ratio of the mouse position relative to the axis range
|
||||||
|
float offset = mouse_pos_plot[i] - axis.Range.Min;
|
||||||
|
float ratio = offset / size;
|
||||||
|
|
||||||
|
// Adjust the axis range to zoom around the mouse position
|
||||||
|
new_min = mouse_pos_plot[i] - new_size * ratio;
|
||||||
|
new_max = mouse_pos_plot[i] + new_size * (1.0f - ratio);
|
||||||
|
} else {
|
||||||
|
// If mouse is not over the plot box, zoom around the plot center
|
||||||
|
float center = (axis.Range.Min + axis.Range.Max) * 0.5f;
|
||||||
|
|
||||||
|
// Adjust the axis range to zoom around plot center
|
||||||
|
new_min = center - zoom * size * 0.5f;
|
||||||
|
new_max = center + zoom * size * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new range after zoom
|
||||||
|
if (plot.Axes[i].Hovered) {
|
||||||
|
if (!plot.Axes[i].IsInputLocked()) {
|
||||||
|
plot.Axes[i].SetMin(new_min);
|
||||||
|
plot.Axes[i].SetMax(new_max);
|
||||||
|
}
|
||||||
plot.Axes[i].Held = true;
|
plot.Axes[i].Held = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no axis was held before (user started zoom in this frame), set the held edge/plane indices
|
// If no axis was held before (user started zoom in this frame), set the held edge/plane indices
|
||||||
if (!any_axis_held) {
|
if (!any_axis_held) {
|
||||||
plot.HeldEdgeIdx = hovered_edge_idx;
|
plot.HeldEdgeIdx = hovered_edge_idx;
|
||||||
@ -1931,15 +2094,13 @@ void HandleInput(ImPlot3DPlot& plot) {
|
|||||||
plot.OpenContextThisFrame = true;
|
plot.OpenContextThisFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Only open context menu if the mouse is not in the middle of double click action
|
|
||||||
const char* axis_contexts[3] = {"##XAxisContext", "##YAxisContext", "##ZAxisContext"};
|
|
||||||
if (plot.OpenContextThisFrame) {
|
if (plot.OpenContextThisFrame) {
|
||||||
if (plot.Items.Legend.Hovered)
|
if (plot.Items.Legend.Hovered)
|
||||||
ImGui::OpenPopup("##LegendContext");
|
ImGui::OpenPopup("##LegendContext");
|
||||||
else if (hovered_axis != -1) {
|
else if (hovered_axis != -1) {
|
||||||
ImGui::OpenPopup(axis_contexts[hovered_axis]);
|
ImGui::OpenPopup(axis_contexts[hovered_axis]);
|
||||||
} else if (hovered_plane != -1) {
|
} else if (hovered_plane != -1) {
|
||||||
ImGui::OpenPopup(axis_contexts[hovered_plane]);
|
ImGui::OpenPopup(plane_contexts[hovered_plane]);
|
||||||
} else if (plot.Hovered) {
|
} else if (plot.Hovered) {
|
||||||
ImGui::OpenPopup("##PlotContext");
|
ImGui::OpenPopup("##PlotContext");
|
||||||
}
|
}
|
||||||
@ -1988,8 +2149,10 @@ void SetupLock() {
|
|||||||
// Compute ticks
|
// Compute ticks
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
ImPlot3DAxis& axis = plot.Axes[i];
|
ImPlot3DAxis& axis = plot.Axes[i];
|
||||||
axis.Ticker.Reset();
|
if (axis.ShowDefaultTicks) {
|
||||||
axis.Locator(axis.Ticker, axis.Range, axis.Formatter, axis.FormatterData);
|
float pixels = plot.GetBoxZoom() * plot.BoxScale[i];
|
||||||
|
axis.Locator(axis.Ticker, axis.Range, pixels, axis.Formatter, axis.FormatterData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render title
|
// Render title
|
||||||
@ -2043,22 +2206,22 @@ struct ImPlot3DStyleVarInfo {
|
|||||||
static const ImPlot3DStyleVarInfo GPlot3DStyleVarInfo[] =
|
static const ImPlot3DStyleVarInfo GPlot3DStyleVarInfo[] =
|
||||||
{
|
{
|
||||||
// Item style
|
// Item style
|
||||||
{ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlot3DStyle, LineWeight)}, // ImPlot3DStyleVar_LineWeight
|
{ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlot3DStyle, LineWeight)}, // ImPlot3DStyleVar_LineWeight
|
||||||
{ImGuiDataType_S32, 1, (ImU32)IM_OFFSETOF(ImPlot3DStyle, Marker)}, // ImPlot3DStyleVar_Marker
|
{ImGuiDataType_S32, 1, (ImU32)offsetof(ImPlot3DStyle, Marker)}, // ImPlot3DStyleVar_Marker
|
||||||
{ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlot3DStyle, MarkerSize)}, // ImPlot3DStyleVar_MarkerSize
|
{ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlot3DStyle, MarkerSize)}, // ImPlot3DStyleVar_MarkerSize
|
||||||
{ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlot3DStyle, MarkerWeight)}, // ImPlot3DStyleVar_MarkerWeight
|
{ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlot3DStyle, MarkerWeight)}, // ImPlot3DStyleVar_MarkerWeight
|
||||||
{ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImPlot3DStyle, FillAlpha)}, // ImPlot3DStyleVar_FillAlpha
|
{ImGuiDataType_Float, 1, (ImU32)offsetof(ImPlot3DStyle, FillAlpha)}, // ImPlot3DStyleVar_FillAlpha
|
||||||
|
|
||||||
// Plot style
|
// Plot style
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, PlotDefaultSize)}, // ImPlot3DStyleVar_Plot3DDefaultSize
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, PlotDefaultSize)}, // ImPlot3DStyleVar_Plot3DDefaultSize
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, PlotMinSize)}, // ImPlot3DStyleVar_Plot3DMinSize
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, PlotMinSize)}, // ImPlot3DStyleVar_Plot3DMinSize
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, PlotPadding)}, // ImPlot3DStyleVar_Plot3DPadding
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, PlotPadding)}, // ImPlot3DStyleVar_Plot3DPadding
|
||||||
|
|
||||||
// Label style
|
// Label style
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, LabelPadding)}, // ImPlot3DStyleVar_LabelPaddine
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, LabelPadding)}, // ImPlot3DStyleVar_LabelPaddine
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, LegendPadding)}, // ImPlot3DStyleVar_LegendPadding
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, LegendPadding)}, // ImPlot3DStyleVar_LegendPadding
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, LegendInnerPadding)}, // ImPlot3DStyleVar_LegendInnerPadding
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, LegendInnerPadding)}, // ImPlot3DStyleVar_LegendInnerPadding
|
||||||
{ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImPlot3DStyle, LegendSpacing)}, // ImPlot3DStyleVar_LegendSpacing
|
{ImGuiDataType_Float, 2, (ImU32)offsetof(ImPlot3DStyle, LegendSpacing)}, // ImPlot3DStyleVar_LegendSpacing
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ImPlot3DStyleVarInfo* GetPlotStyleVarInfo(ImPlot3DStyleVar idx) {
|
static const ImPlot3DStyleVarInfo* GetPlotStyleVarInfo(ImPlot3DStyleVar idx) {
|
||||||
@ -2624,8 +2787,8 @@ bool ImPlot3DBox::ClipLineSegment(const ImPlot3DPoint& p0, const ImPlot3DPoint&
|
|||||||
return false; // Far
|
return false; // Far
|
||||||
|
|
||||||
// Compute clipped points
|
// Compute clipped points
|
||||||
p0_clipped = p0 + d * t0;
|
p0_clipped = p0 + d * (float)t0;
|
||||||
p1_clipped = p0 + d * t1;
|
p1_clipped = p0 + d * (float)t1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2649,11 +2812,11 @@ bool ImPlot3DRange::Contains(float value) const {
|
|||||||
|
|
||||||
ImPlot3DQuat::ImPlot3DQuat(float _angle, const ImPlot3DPoint& _axis) {
|
ImPlot3DQuat::ImPlot3DQuat(float _angle, const ImPlot3DPoint& _axis) {
|
||||||
float half_angle = _angle * 0.5f;
|
float half_angle = _angle * 0.5f;
|
||||||
float s = std::sin(half_angle);
|
float s = ImSin(half_angle);
|
||||||
x = s * _axis.x;
|
x = s * _axis.x;
|
||||||
y = s * _axis.y;
|
y = s * _axis.y;
|
||||||
z = s * _axis.z;
|
z = s * _axis.z;
|
||||||
w = std::cos(half_angle);
|
w = ImCos(half_angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DQuat ImPlot3DQuat::FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3DPoint& v1) {
|
ImPlot3DQuat ImPlot3DQuat::FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3DPoint& v1) {
|
||||||
@ -2669,7 +2832,7 @@ ImPlot3DQuat ImPlot3DQuat::FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3
|
|||||||
|
|
||||||
// Handle edge cases: if vectors are very close or identical
|
// Handle edge cases: if vectors are very close or identical
|
||||||
const float epsilon = 1e-6f;
|
const float epsilon = 1e-6f;
|
||||||
if (std::fabs(normalized_dot - 1.0f) < epsilon) {
|
if (ImFabs(normalized_dot - 1.0f) < epsilon) {
|
||||||
// v0 and v1 are nearly identical; return an identity quaternion
|
// v0 and v1 are nearly identical; return an identity quaternion
|
||||||
q.x = 0.0f;
|
q.x = 0.0f;
|
||||||
q.y = 0.0f;
|
q.y = 0.0f;
|
||||||
@ -2679,10 +2842,10 @@ ImPlot3DQuat ImPlot3DQuat::FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle edge case: if vectors are opposite
|
// Handle edge case: if vectors are opposite
|
||||||
if (std::fabs(normalized_dot + 1.0f) < epsilon) {
|
if (ImFabs(normalized_dot + 1.0f) < epsilon) {
|
||||||
// v0 and v1 are opposite; choose an arbitrary orthogonal axis
|
// v0 and v1 are opposite; choose an arbitrary orthogonal axis
|
||||||
ImPlot3DPoint arbitrary_axis = std::fabs(v0.x) > std::fabs(v0.z) ? ImPlot3DPoint(-v0.y, v0.x, 0.0f)
|
ImPlot3DPoint arbitrary_axis = ImFabs(v0.x) > ImFabs(v0.z) ? ImPlot3DPoint(-v0.y, v0.x, 0.0f)
|
||||||
: ImPlot3DPoint(0.0f, -v0.z, v0.y);
|
: ImPlot3DPoint(0.0f, -v0.z, v0.y);
|
||||||
arbitrary_axis.Normalize();
|
arbitrary_axis.Normalize();
|
||||||
q.x = arbitrary_axis.x;
|
q.x = arbitrary_axis.x;
|
||||||
q.y = arbitrary_axis.y;
|
q.y = arbitrary_axis.y;
|
||||||
@ -2694,19 +2857,19 @@ ImPlot3DQuat ImPlot3DQuat::FromTwoVectors(const ImPlot3DPoint& v0, const ImPlot3
|
|||||||
// General case
|
// General case
|
||||||
ImPlot3DPoint axis = v0.Cross(v1);
|
ImPlot3DPoint axis = v0.Cross(v1);
|
||||||
axis.Normalize();
|
axis.Normalize();
|
||||||
float angle = std::acos(normalized_dot);
|
float angle = ImAcos(normalized_dot);
|
||||||
float half_angle = angle * 0.5f;
|
float half_angle = angle * 0.5f;
|
||||||
float s = std::sin(half_angle);
|
float s = ImSin(half_angle);
|
||||||
q.x = s * axis.x;
|
q.x = s * axis.x;
|
||||||
q.y = s * axis.y;
|
q.y = s * axis.y;
|
||||||
q.z = s * axis.z;
|
q.z = s * axis.z;
|
||||||
q.w = std::cos(half_angle);
|
q.w = ImCos(half_angle);
|
||||||
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImPlot3DQuat::Length() const {
|
float ImPlot3DQuat::Length() const {
|
||||||
return std::sqrt(x * x + y * y + z * z + w * w);
|
return ImSqrt(x * x + y * y + z * z + w * w);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImPlot3DQuat ImPlot3DQuat::Normalized() const {
|
ImPlot3DQuat ImPlot3DQuat::Normalized() const {
|
||||||
@ -2785,12 +2948,12 @@ ImPlot3DQuat ImPlot3DQuat::Slerp(const ImPlot3DQuat& q1, const ImPlot3DQuat& q2,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the angle and the interpolation factors
|
// Compute the angle and the interpolation factors
|
||||||
float theta_0 = std::acos(dot); // Angle between input quaternions
|
float theta_0 = ImAcos(dot); // Angle between input quaternions
|
||||||
float theta = theta_0 * t; // Interpolated angle
|
float theta = theta_0 * t; // Interpolated angle
|
||||||
float sin_theta = std::sin(theta); // Sine of interpolated angle
|
float sin_theta = ImSin(theta); // Sine of interpolated angle
|
||||||
float sin_theta_0 = std::sin(theta_0); // Sine of original angle
|
float sin_theta_0 = ImSin(theta_0); // Sine of original angle
|
||||||
|
|
||||||
float s1 = std::cos(theta) - dot * sin_theta / sin_theta_0;
|
float s1 = ImCos(theta) - dot * sin_theta / sin_theta_0;
|
||||||
float s2 = sin_theta / sin_theta_0;
|
float s2 = sin_theta / sin_theta_0;
|
||||||
|
|
||||||
// Interpolate and return the result
|
// Interpolate and return the result
|
||||||
@ -2884,7 +3047,6 @@ void ImDrawList3D::SortedMoveToImGuiDrawList() {
|
|||||||
// Copy indices with triangle sorting based on distance from viewer
|
// Copy indices with triangle sorting based on distance from viewer
|
||||||
ImDrawIdx* idx_out = draw_list._IdxWritePtr;
|
ImDrawIdx* idx_out = draw_list._IdxWritePtr;
|
||||||
ImDrawIdx* idx_in = IdxBuffer.Data;
|
ImDrawIdx* idx_in = IdxBuffer.Data;
|
||||||
int triangles_added = 0;
|
|
||||||
for (int i = 0; i < tri_count; i++) {
|
for (int i = 0; i < tri_count; i++) {
|
||||||
int tri_i = tris[i].tri_idx;
|
int tri_i = tris[i].tri_idx;
|
||||||
int base_idx = tri_i * 3;
|
int base_idx = tri_i * 3;
|
||||||
@ -2901,7 +3063,6 @@ void ImDrawList3D::SortedMoveToImGuiDrawList() {
|
|||||||
idx_out[2] = (ImDrawIdx)(i2 + idx_offset);
|
idx_out[2] = (ImDrawIdx)(i2 + idx_offset);
|
||||||
|
|
||||||
idx_out += 3;
|
idx_out += 3;
|
||||||
triangles_added++;
|
|
||||||
}
|
}
|
||||||
draw_list._IdxWritePtr = idx_out;
|
draw_list._IdxWritePtr = idx_out;
|
||||||
|
|
||||||
@ -2945,14 +3106,6 @@ void ImPlot3DAxis::ApplyFit() {
|
|||||||
FitExtents.Max = -HUGE_VAL;
|
FitExtents.Max = -HUGE_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ImPlot3DAxis::PlotToNDC(float value) const {
|
|
||||||
return (value - Range.Min) / (Range.Max - Range.Min) - 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float ImPlot3DAxis::NDCToPlot(float value) const {
|
|
||||||
return Range.Min + (value + 0.5f) * (Range.Max - Range.Min);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ImPlot3DPlot
|
// [SECTION] ImPlot3DPlot
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -2985,6 +3138,10 @@ void ImPlot3DPlot::SetRange(const ImPlot3DPoint& min, const ImPlot3DPoint& max)
|
|||||||
Axes[2].SetRange(min.z, max.z);
|
Axes[2].SetRange(min.z, max.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ImPlot3DPlot::GetBoxZoom() const {
|
||||||
|
return ImMin(PlotRect.GetWidth(), PlotRect.GetHeight()) / 1.8f;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] ImPlot3DStyle
|
// [SECTION] ImPlot3DStyle
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -15,11 +15,17 @@
|
|||||||
// [SECTION] User Namespace
|
// [SECTION] User Namespace
|
||||||
// [SECTION] Helpers
|
// [SECTION] Helpers
|
||||||
// [SECTION] Plots
|
// [SECTION] Plots
|
||||||
|
// [SECTION] Axes
|
||||||
// [SECTION] Custom
|
// [SECTION] Custom
|
||||||
// [SECTION] Demo Window
|
// [SECTION] Demo Window
|
||||||
// [SECTION] Style Editor
|
// [SECTION] Style Editor
|
||||||
// [SECTION] User Namespace Implementation
|
// [SECTION] User Namespace Implementation
|
||||||
|
|
||||||
|
// We define this to avoid accidentally using the deprecated API
|
||||||
|
#ifndef IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
#define IMPLOT_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "implot3d.h"
|
#include "implot3d.h"
|
||||||
#include "implot3d_internal.h"
|
#include "implot3d_internal.h"
|
||||||
|
|
||||||
@ -122,7 +128,7 @@ void DemoScatterPlots() {
|
|||||||
ImPlot3D::PlotScatter("Data 1", xs1, ys1, zs1, 100);
|
ImPlot3D::PlotScatter("Data 1", xs1, ys1, zs1, 100);
|
||||||
ImPlot3D::PushStyleVar(ImPlot3DStyleVar_FillAlpha, 0.25f);
|
ImPlot3D::PushStyleVar(ImPlot3DStyleVar_FillAlpha, 0.25f);
|
||||||
ImPlot3D::SetNextMarkerStyle(ImPlot3DMarker_Square, 6, ImPlot3D::GetColormapColor(1), IMPLOT3D_AUTO, ImPlot3D::GetColormapColor(1));
|
ImPlot3D::SetNextMarkerStyle(ImPlot3DMarker_Square, 6, ImPlot3D::GetColormapColor(1), IMPLOT3D_AUTO, ImPlot3D::GetColormapColor(1));
|
||||||
ImPlot3D::PlotScatter("Data 2", xs2, ys2, zs1, 50);
|
ImPlot3D::PlotScatter("Data 2", xs2, ys2, zs2, 50);
|
||||||
ImPlot3D::PopStyleVar();
|
ImPlot3D::PopStyleVar();
|
||||||
ImPlot3D::EndPlot();
|
ImPlot3D::EndPlot();
|
||||||
}
|
}
|
||||||
@ -279,37 +285,91 @@ void DemoQuadPlots() {
|
|||||||
void DemoSurfacePlots() {
|
void DemoSurfacePlots() {
|
||||||
constexpr int N = 20;
|
constexpr int N = 20;
|
||||||
static float xs[N * N], ys[N * N], zs[N * N];
|
static float xs[N * N], ys[N * N], zs[N * N];
|
||||||
|
static float t = 0.0f;
|
||||||
|
t += ImGui::GetIO().DeltaTime;
|
||||||
|
|
||||||
// Define the range for X and Y
|
// Define the range for X and Y
|
||||||
constexpr float range_min = -5.0f;
|
constexpr float min_val = -1.0f;
|
||||||
constexpr float range_max = 5.0f;
|
constexpr float max_val = 1.0f;
|
||||||
constexpr float step = (range_max - range_min) / (N - 1);
|
constexpr float step = (max_val - min_val) / (N - 1);
|
||||||
|
|
||||||
// Populate the xs, ys, and zs arrays
|
// Populate the xs, ys, and zs arrays
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
for (int j = 0; j < N; j++) {
|
for (int j = 0; j < N; j++) {
|
||||||
int idx = i * N + j;
|
int idx = i * N + j;
|
||||||
xs[idx] = range_min + j * step; // X values are constant along rows
|
xs[idx] = min_val + j * step; // X values are constant along rows
|
||||||
ys[idx] = range_min + i * step; // Y values are constant along columns
|
ys[idx] = min_val + i * step; // Y values are constant along columns
|
||||||
zs[idx] = sinf(sqrt(xs[idx] * xs[idx] + ys[idx] * ys[idx])); // Z = sin(sqrt(X^2 + Y^2))
|
zs[idx] = ImSin(2 * t + ImSqrt((xs[idx] * xs[idx] + ys[idx] * ys[idx]))); // z = sin(2t + sqrt(x^2 + y^2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Choose fill color
|
||||||
|
ImGui::Text("Fill color");
|
||||||
|
static int selected_fill = 1; // Colormap by default
|
||||||
|
static ImVec4 solid_color = ImVec4(0.8f, 0.8f, 0.2f, 0.6f);
|
||||||
|
const char* colormaps[] = {"Viridis", "Plasma", "Hot", "Cool", "Pink", "Jet",
|
||||||
|
"Twilight", "RdBu", "BrBG", "PiYG", "Spectral", "Greys"};
|
||||||
|
static int sel_colormap = 5; // Jet by default
|
||||||
|
{
|
||||||
|
ImGui::Indent();
|
||||||
|
|
||||||
|
// Choose solid color
|
||||||
|
ImGui::RadioButton("Solid", &selected_fill, 0);
|
||||||
|
if (selected_fill == 0) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::ColorEdit4("##SurfaceSolidColor", (float*)&solid_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose colormap
|
||||||
|
ImGui::RadioButton("Colormap", &selected_fill, 1);
|
||||||
|
if (selected_fill == 1) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Combo("##SurfaceColormap", &sel_colormap, colormaps, IM_ARRAYSIZE(colormaps));
|
||||||
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose range
|
||||||
|
static bool custom_range = false;
|
||||||
|
static float range_min = -1.0f;
|
||||||
|
static float range_max = 1.0f;
|
||||||
|
ImGui::Checkbox("Custom range", &custom_range);
|
||||||
|
{
|
||||||
|
ImGui::Indent();
|
||||||
|
|
||||||
|
if (!custom_range)
|
||||||
|
ImGui::BeginDisabled();
|
||||||
|
ImGui::SliderFloat("Range min", &range_min, -1.0f, range_max - 0.01f);
|
||||||
|
ImGui::SliderFloat("Range max", &range_max, range_min + 0.01f, 1.0f);
|
||||||
|
if (!custom_range)
|
||||||
|
ImGui::EndDisabled();
|
||||||
|
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
// Begin the plot
|
// Begin the plot
|
||||||
ImPlot3D::PushColormap("Hot");
|
if (selected_fill == 1)
|
||||||
if (ImPlot3D::BeginPlot("Surface Plots")) {
|
ImPlot3D::PushColormap(colormaps[sel_colormap]);
|
||||||
|
if (ImPlot3D::BeginPlot("Surface Plots", ImVec2(-1, 400), ImPlot3DFlags_NoClip)) {
|
||||||
// Set styles
|
// Set styles
|
||||||
|
ImPlot3D::SetupAxesLimits(-1, 1, -1, 1, -1.5, 1.5);
|
||||||
ImPlot3D::PushStyleVar(ImPlot3DStyleVar_FillAlpha, 0.8f);
|
ImPlot3D::PushStyleVar(ImPlot3DStyleVar_FillAlpha, 0.8f);
|
||||||
|
if (selected_fill == 0)
|
||||||
|
ImPlot3D::SetNextFillStyle(solid_color);
|
||||||
ImPlot3D::SetNextLineStyle(ImPlot3D::GetColormapColor(1));
|
ImPlot3D::SetNextLineStyle(ImPlot3D::GetColormapColor(1));
|
||||||
|
|
||||||
// Plot the surface
|
// Plot the surface
|
||||||
ImPlot3D::PlotSurface("Wave Surface", xs, ys, zs, N, N);
|
if (custom_range)
|
||||||
|
ImPlot3D::PlotSurface("Wave Surface", xs, ys, zs, N, N, (double)range_min, (double)range_max);
|
||||||
|
else
|
||||||
|
ImPlot3D::PlotSurface("Wave Surface", xs, ys, zs, N, N);
|
||||||
|
|
||||||
// End the plot
|
// End the plot
|
||||||
ImPlot3D::PopStyleVar();
|
ImPlot3D::PopStyleVar();
|
||||||
ImPlot3D::EndPlot();
|
ImPlot3D::EndPlot();
|
||||||
}
|
}
|
||||||
ImPlot3D::PopColormap();
|
if (selected_fill == 1)
|
||||||
|
ImPlot3D::PopColormap();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemoMeshPlots() {
|
void DemoMeshPlots() {
|
||||||
@ -419,8 +479,8 @@ void DemoMarkersAndText() {
|
|||||||
|
|
||||||
// Filled markers
|
// Filled markers
|
||||||
for (int m = 0; m < ImPlot3DMarker_COUNT; ++m) {
|
for (int m = 0; m < ImPlot3DMarker_COUNT; ++m) {
|
||||||
xs[1] = xs[0] + ImCos(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5;
|
xs[1] = xs[0] + ImCos(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5f;
|
||||||
ys[1] = ys[0] + ImSin(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5;
|
ys[1] = ys[0] + ImSin(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5f;
|
||||||
|
|
||||||
ImGui::PushID(m);
|
ImGui::PushID(m);
|
||||||
ImPlot3D::SetNextMarkerStyle(m, mk_size, IMPLOT3D_AUTO_COL, mk_weight);
|
ImPlot3D::SetNextMarkerStyle(m, mk_size, IMPLOT3D_AUTO_COL, mk_weight);
|
||||||
@ -437,8 +497,8 @@ void DemoMarkersAndText() {
|
|||||||
|
|
||||||
// Open markers
|
// Open markers
|
||||||
for (int m = 0; m < ImPlot3DMarker_COUNT; ++m) {
|
for (int m = 0; m < ImPlot3DMarker_COUNT; ++m) {
|
||||||
xs[1] = xs[0] + ImCos(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5;
|
xs[1] = xs[0] + ImCos(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5f;
|
||||||
ys[1] = ys[0] - ImSin(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5;
|
ys[1] = ys[0] - ImSin(zs[0] / float(ImPlot3DMarker_COUNT) * 2 * IM_PI) * 0.5f;
|
||||||
|
|
||||||
ImGui::PushID(m);
|
ImGui::PushID(m);
|
||||||
ImPlot3D::SetNextMarkerStyle(m, mk_size, ImVec4(0, 0, 0, 0), mk_weight);
|
ImPlot3D::SetNextMarkerStyle(m, mk_size, ImVec4(0, 0, 0, 0), mk_weight);
|
||||||
@ -481,6 +541,53 @@ void DemoNaNValues() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// [SECTION] Axes
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void DemoBoxScale() {
|
||||||
|
constexpr int N = 100;
|
||||||
|
float xs[N], ys[N], zs[N];
|
||||||
|
for (int i = 0; i < N; ++i) {
|
||||||
|
float t = i / (float)(N - 1);
|
||||||
|
xs[i] = sinf(t * 2.0f * IM_PI);
|
||||||
|
ys[i] = cosf(t * 4.0f * IM_PI);
|
||||||
|
zs[i] = t * 2.0f - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float scale[3] = {1.0f, 1.0f, 1.0f};
|
||||||
|
ImGui::SliderFloat3("Box Scale", scale, 0.1f, 2.0f, "%.2f");
|
||||||
|
|
||||||
|
if (ImPlot3D::BeginPlot("##BoxScale")) {
|
||||||
|
ImPlot3D::SetupBoxScale(scale[0], scale[1], scale[2]);
|
||||||
|
ImPlot3D::PlotLine("3D Curve", xs, ys, zs, N);
|
||||||
|
ImPlot3D::EndPlot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DemoTickLabels() {
|
||||||
|
static bool custom_ticks = false;
|
||||||
|
static bool custom_labels = true;
|
||||||
|
ImGui::Checkbox("Show Custom Ticks", &custom_ticks);
|
||||||
|
if (custom_ticks) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Show Custom Labels", &custom_labels);
|
||||||
|
}
|
||||||
|
const double pi = 3.14;
|
||||||
|
const char* pi_str[] = {"PI"};
|
||||||
|
static double letters_ticks[] = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0};
|
||||||
|
static const char* letters_labels[] = {"A", "B", "C", "D", "E", "F"};
|
||||||
|
if (ImPlot3D::BeginPlot("##Ticks")) {
|
||||||
|
ImPlot3D::SetupAxesLimits(2, 5, 0, 1, 0, 1);
|
||||||
|
if (custom_ticks) {
|
||||||
|
ImPlot3D::SetupAxisTicks(ImAxis3D_X, &pi, 1, custom_labels ? pi_str : nullptr, true);
|
||||||
|
ImPlot3D::SetupAxisTicks(ImAxis3D_Y, letters_ticks, 6, custom_labels ? letters_labels : nullptr, false);
|
||||||
|
ImPlot3D::SetupAxisTicks(ImAxis3D_Z, 0, 1, 6, custom_labels ? letters_labels : nullptr, false);
|
||||||
|
}
|
||||||
|
ImPlot3D::EndPlot();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Custom
|
// [SECTION] Custom
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -635,7 +742,6 @@ void ShowDemoWindow(bool* p_open) {
|
|||||||
if (show_imgui_demo)
|
if (show_imgui_demo)
|
||||||
ImGui::ShowDemoWindow(&show_imgui_demo);
|
ImGui::ShowDemoWindow(&show_imgui_demo);
|
||||||
|
|
||||||
|
|
||||||
ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver);
|
||||||
ImGui::SetNextWindowSize(ImVec2(600, 750), ImGuiCond_FirstUseEver);
|
ImGui::SetNextWindowSize(ImVec2(600, 750), ImGuiCond_FirstUseEver);
|
||||||
ImGui::Begin("ImPlot3D Demo", p_open, ImGuiWindowFlags_MenuBar);
|
ImGui::Begin("ImPlot3D Demo", p_open, ImGuiWindowFlags_MenuBar);
|
||||||
@ -668,6 +774,11 @@ void ShowDemoWindow(bool* p_open) {
|
|||||||
DemoHeader("NaN Values", DemoNaNValues);
|
DemoHeader("NaN Values", DemoNaNValues);
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
if (ImGui::BeginTabItem("Axes")) {
|
||||||
|
DemoHeader("Box Scale", DemoBoxScale);
|
||||||
|
DemoHeader("Tick Labels", DemoTickLabels);
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
if (ImGui::BeginTabItem("Custom")) {
|
if (ImGui::BeginTabItem("Custom")) {
|
||||||
DemoHeader("Custom Styles", DemoCustomStyles);
|
DemoHeader("Custom Styles", DemoCustomStyles);
|
||||||
DemoHeader("Custom Rendering", DemoCustomRendering);
|
DemoHeader("Custom Rendering", DemoCustomRendering);
|
||||||
@ -862,11 +973,11 @@ void ShowStyleEditor(ImPlot3DStyle* ref) {
|
|||||||
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
filter.Draw("Filter colors", ImGui::GetFontSize() * 16);
|
||||||
|
|
||||||
static ImGuiColorEditFlags alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
static ImGuiColorEditFlags alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||||
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_None))
|
if (ImGui::RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque))
|
||||||
alpha_flags = ImGuiColorEditFlags_None;
|
alpha_flags = ImGuiColorEditFlags_AlphaOpaque;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_AlphaPreview))
|
if (ImGui::RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None))
|
||||||
alpha_flags = ImGuiColorEditFlags_AlphaPreview;
|
alpha_flags = ImGuiColorEditFlags_None;
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf))
|
if (ImGui::RadioButton("Both", alpha_flags == ImGuiColorEditFlags_AlphaPreviewHalf))
|
||||||
alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
alpha_flags = ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||||
|
@ -266,8 +266,8 @@ void SetNextLineStyle(const ImVec4& col, float weight) {
|
|||||||
void SetNextFillStyle(const ImVec4& col, float alpha) {
|
void SetNextFillStyle(const ImVec4& col, float alpha) {
|
||||||
ImPlot3DContext& gp = *GImPlot3D;
|
ImPlot3DContext& gp = *GImPlot3D;
|
||||||
ImPlot3DNextItemData& n = gp.NextItemData;
|
ImPlot3DNextItemData& n = gp.NextItemData;
|
||||||
gp.NextItemData.Colors[ImPlot3DCol_Fill] = col;
|
n.Colors[ImPlot3DCol_Fill] = col;
|
||||||
gp.NextItemData.FillAlpha = alpha;
|
n.FillAlpha = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetNextMarkerStyle(ImPlot3DMarker marker, float size, const ImVec4& fill, float weight, const ImVec4& outline) {
|
void SetNextMarkerStyle(ImPlot3DMarker marker, float size, const ImVec4& fill, float weight, const ImVec4& outline) {
|
||||||
@ -700,14 +700,14 @@ struct RendererQuadFill : RendererBase {
|
|||||||
|
|
||||||
template <class _Getter>
|
template <class _Getter>
|
||||||
struct RendererSurfaceFill : RendererBase {
|
struct RendererSurfaceFill : RendererBase {
|
||||||
RendererSurfaceFill(const _Getter& getter, int x_count, int y_count, ImU32 col) : RendererBase((x_count - 1) * (y_count - 1), 6, 4),
|
RendererSurfaceFill(const _Getter& getter, int x_count, int y_count, ImU32 col, double scale_min, double scale_max) : RendererBase((x_count - 1) * (y_count - 1), 6, 4),
|
||||||
Getter(getter),
|
Getter(getter),
|
||||||
UV({}),
|
XCount(x_count),
|
||||||
Min(0.0f),
|
YCount(y_count),
|
||||||
Max(0.0f),
|
Col(col),
|
||||||
XCount(x_count),
|
ScaleMin(scale_min),
|
||||||
YCount(y_count),
|
ScaleMax(scale_max) {}
|
||||||
Col(col) {}
|
|
||||||
void Init(ImDrawList3D& draw_list_3d) const {
|
void Init(ImDrawList3D& draw_list_3d) const {
|
||||||
UV = draw_list_3d._SharedData->TexUvWhitePixel;
|
UV = draw_list_3d._SharedData->TexUvWhitePixel;
|
||||||
|
|
||||||
@ -744,8 +744,14 @@ struct RendererSurfaceFill : RendererBase {
|
|||||||
const ImPlot3DNextItemData& n = GetItemData();
|
const ImPlot3DNextItemData& n = GetItemData();
|
||||||
if (n.IsAutoFill) {
|
if (n.IsAutoFill) {
|
||||||
float alpha = GImPlot3D->NextItemData.FillAlpha;
|
float alpha = GImPlot3D->NextItemData.FillAlpha;
|
||||||
|
float min = Min;
|
||||||
|
float max = Max;
|
||||||
|
if (ScaleMin != 0.0 || ScaleMax != 0.0) {
|
||||||
|
min = (float)ScaleMin;
|
||||||
|
max = (float)ScaleMax;
|
||||||
|
}
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
ImVec4 col = SampleColormap(ImClamp(ImRemap01(p_plot[i].z, Min, Max), 0.0f, 1.0f));
|
ImVec4 col = SampleColormap(ImClamp(ImRemap01(p_plot[i].z, min, max), 0.0f, 1.0f));
|
||||||
col.w *= alpha;
|
col.w *= alpha;
|
||||||
cols[i] = ImGui::ColorConvertFloat4ToU32(col);
|
cols[i] = ImGui::ColorConvertFloat4ToU32(col);
|
||||||
}
|
}
|
||||||
@ -810,6 +816,8 @@ struct RendererSurfaceFill : RendererBase {
|
|||||||
const int XCount;
|
const int XCount;
|
||||||
const int YCount;
|
const int YCount;
|
||||||
const ImU32 Col;
|
const ImU32 Col;
|
||||||
|
const double ScaleMin;
|
||||||
|
const double ScaleMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -851,7 +859,7 @@ template <typename _IndexerX, typename _IndexerY, typename _IndexerZ>
|
|||||||
struct GetterXYZ {
|
struct GetterXYZ {
|
||||||
GetterXYZ(_IndexerX x, _IndexerY y, _IndexerZ z, int count) : IndexerX(x), IndexerY(y), IndexerZ(z), Count(count) {}
|
GetterXYZ(_IndexerX x, _IndexerY y, _IndexerZ z, int count) : IndexerX(x), IndexerY(y), IndexerZ(z), Count(count) {}
|
||||||
template <typename I> IMPLOT3D_INLINE ImPlot3DPoint operator()(I idx) const {
|
template <typename I> IMPLOT3D_INLINE ImPlot3DPoint operator()(I idx) const {
|
||||||
return ImPlot3DPoint(IndexerX(idx), IndexerY(idx), IndexerZ(idx));
|
return ImPlot3DPoint((float)IndexerX(idx), (float)IndexerY(idx), (float)IndexerZ(idx));
|
||||||
}
|
}
|
||||||
const _IndexerX IndexerX;
|
const _IndexerX IndexerX;
|
||||||
const _IndexerY IndexerY;
|
const _IndexerY IndexerY;
|
||||||
@ -1240,14 +1248,14 @@ CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
template <typename _Getter>
|
template <typename _Getter>
|
||||||
void PlotSurfaceEx(const char* label_id, const _Getter& getter, int x_count, int y_count, ImPlot3DSurfaceFlags flags) {
|
void PlotSurfaceEx(const char* label_id, const _Getter& getter, int x_count, int y_count, double scale_min, double scale_max, ImPlot3DSurfaceFlags flags) {
|
||||||
if (BeginItemEx(label_id, getter, flags, ImPlot3DCol_Fill)) {
|
if (BeginItemEx(label_id, getter, flags, ImPlot3DCol_Fill)) {
|
||||||
const ImPlot3DNextItemData& n = GetItemData();
|
const ImPlot3DNextItemData& n = GetItemData();
|
||||||
|
|
||||||
// Render fill
|
// Render fill
|
||||||
if (getter.Count >= 4 && n.RenderFill) {
|
if (getter.Count >= 4 && n.RenderFill) {
|
||||||
const ImU32 col_fill = ImGui::GetColorU32(n.Colors[ImPlot3DCol_Fill]);
|
const ImU32 col_fill = ImGui::GetColorU32(n.Colors[ImPlot3DCol_Fill]);
|
||||||
RenderPrimitives<RendererSurfaceFill>(getter, x_count, y_count, col_fill);
|
RenderPrimitives<RendererSurfaceFill>(getter, x_count, y_count, col_fill, scale_min, scale_max);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render lines
|
// Render lines
|
||||||
@ -1267,16 +1275,16 @@ void PlotSurfaceEx(const char* label_id, const _Getter& getter, int x_count, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLOT3D_TMP void PlotSurface(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, ImPlot3DSurfaceFlags flags, int offset, int stride) {
|
IMPLOT3D_TMP void PlotSurface(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, double scale_min, double scale_max, ImPlot3DSurfaceFlags flags, int offset, int stride) {
|
||||||
int count = x_count * y_count;
|
int count = x_count * y_count;
|
||||||
if (count < 4)
|
if (count < 4)
|
||||||
return;
|
return;
|
||||||
GetterXYZ<IndexerIdx<T>, IndexerIdx<T>, IndexerIdx<T>> getter(IndexerIdx<T>(xs, count, offset, stride), IndexerIdx<T>(ys, count, offset, stride), IndexerIdx<T>(zs, count, offset, stride), count);
|
GetterXYZ<IndexerIdx<T>, IndexerIdx<T>, IndexerIdx<T>> getter(IndexerIdx<T>(xs, count, offset, stride), IndexerIdx<T>(ys, count, offset, stride), IndexerIdx<T>(zs, count, offset, stride), count);
|
||||||
return PlotSurfaceEx(label_id, getter, x_count, y_count, flags);
|
return PlotSurfaceEx(label_id, getter, x_count, y_count, scale_min, scale_max, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INSTANTIATE_MACRO(T) \
|
#define INSTANTIATE_MACRO(T) \
|
||||||
template IMPLOT3D_API void PlotSurface<T>(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, ImPlot3DSurfaceFlags flags, int offset, int stride);
|
template IMPLOT3D_API void PlotSurface<T>(const char* label_id, const T* xs, const T* ys, const T* zs, int x_count, int y_count, double scale_min, double scale_max, ImPlot3DSurfaceFlags flags, int offset, int stride);
|
||||||
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
CALL_INSTANTIATE_FOR_NUMERIC_TYPES()
|
||||||
#undef INSTANTIATE_MACRO
|
#undef INSTANTIATE_MACRO
|
||||||
|
|
||||||
|
@ -234,9 +234,9 @@ namespace hex::plugin::builtin {
|
|||||||
std::ignore = upperCase;
|
std::ignore = upperCase;
|
||||||
|
|
||||||
if (size == 4)
|
if (size == 4)
|
||||||
ImGui::ColorButton("##color", ImColor(data[0], data[1], data[2], data[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
ImGui::ColorButton("##color", ImColor(data[0], data[1], data[2], data[3]), ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||||
else
|
else
|
||||||
ImGui::ColorButton("##color", ImColor(0, 0, 0, 0xFF), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
ImGui::ColorButton("##color", ImColor(0, 0, 0, 0xFF), ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
bool drawEditing(u64 address, u8 *data, size_t size, bool upperCase, bool startedEditing) override {
|
||||||
@ -250,7 +250,7 @@ namespace hex::plugin::builtin {
|
|||||||
ImGui::OpenPopup("##color_popup");
|
ImGui::OpenPopup("##color_popup");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::ColorButton("##color", ImColor(m_currColor[0], m_currColor[1], m_currColor[2], m_currColor[3]), ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
ImGui::ColorButton("##color", ImColor(m_currColor[0], m_currColor[1], m_currColor[2], m_currColor[3]), ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoDragDrop, ImVec2(ImGui::GetColumnWidth(), ImGui::GetTextLineHeight()));
|
||||||
|
|
||||||
if (ImGui::BeginPopup("##color_popup")) {
|
if (ImGui::BeginPopup("##color_popup")) {
|
||||||
if (ImGui::ColorPicker4("##picker", m_currColor.data(), ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_InputRGB)) {
|
if (ImGui::ColorPicker4("##picker", m_currColor.data(), ImGuiColorEditFlags_AlphaBar | ImGuiColorEditFlags_InputRGB)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user