Update imgui to 1.72.

This commit is contained in:
Bartosz Taudul 2019-07-30 22:53:52 +02:00
parent ca3571fd2b
commit 526f3a55bc
10 changed files with 1205 additions and 865 deletions

View File

@ -28,12 +28,13 @@
//---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty)
// It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp. // It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp.
//#define IMGUI_DISABLE_DEMO_WINDOWS //#define IMGUI_DISABLE_DEMO_WINDOWS
//#define IMGUI_DISABLE_METRICS_WINDOW
//---- Don't implement some functions to reduce linkage requirements. //---- Don't implement some functions to reduce linkage requirements.
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc.
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. //#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow.
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime). //#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
//#define IMGUI_DISABLE_OSX_FUNCTIONS // [OSX] Won't use and link with any OSX function (clipboard). //#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices').
//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf. //#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf.
//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h. //#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h.
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions(). //#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
@ -75,6 +76,14 @@
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data); //typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
//#define ImDrawCallback MyImDrawCallback //#define ImDrawCallback MyImDrawCallback
//---- Debug Tools
// Use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.
//#define IM_DEBUG_BREAK IM_ASSERT(0)
//#define IM_DEBUG_BREAK __debugbreak()
// Have the Item Picker break in the ItemAdd() function instead of ItemHoverable() - which is earlier in the code, will catch a few extra items, allow picking items other than Hovered one.
// This adds a small runtime cost which is why it is not enabled by default.
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files. //---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
/* /*
namespace ImGui namespace ImGui

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.71 // dear imgui, v1.72
// (headers) // (headers)
// See imgui.cpp file for documentation. // See imgui.cpp file for documentation.
@ -46,8 +46,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.71" #define IMGUI_VERSION "1.72"
#define IMGUI_VERSION_NUM 17100 #define IMGUI_VERSION_NUM 17200
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
// Define attributes of all API symbols declarations (e.g. for DLL under Windows) // Define attributes of all API symbols declarations (e.g. for DLL under Windows)
@ -83,9 +83,10 @@ Index of this file:
#if __has_warning("-Wzero-as-null-pointer-constant") #if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif #endif
#elif defined(__GNUC__) && __GNUC__ >= 8 #elif defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess" #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -125,30 +126,29 @@ typedef void* ImTextureID; // User data to identify a texture (this is
typedef unsigned int ImGuiID; // Unique ID used by widgets (typically hashed from a stack of string) typedef unsigned int ImGuiID; // Unique ID used by widgets (typically hashed from a stack of string)
typedef unsigned short ImWchar; // A single U16 character for keyboard input/display. We encode them as multi bytes UTF-8 when used in strings. typedef unsigned short ImWchar; // A single U16 character for keyboard input/display. We encode them as multi bytes UTF-8 when used in strings.
typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling
typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for Set*() typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions
typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type
typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction
typedef int ImGuiKey; // -> enum ImGuiKey_ // Enum: A key identifier (ImGui-side enum) typedef int ImGuiKey; // -> enum ImGuiKey_ // Enum: A key identifier (ImGui-side enum)
typedef int ImGuiNavInput; // -> enum ImGuiNavInput_ // Enum: An input identifier for navigation typedef int ImGuiNavInput; // -> enum ImGuiNavInput_ // Enum: An input identifier for navigation
typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect*() etc. typedef int ImDrawCornerFlags; // -> enum ImDrawCornerFlags_ // Flags: for ImDrawList::AddRect(), AddRectFilled() etc.
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit*(), ColorPicker*() typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: for ColorEdit4(), ColorPicker4() etc.
typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: for Columns(), BeginColumns()
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo() typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo()
typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for *DragDrop*() typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for BeginDragDropSource(), AcceptDragDropPayload()
typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused()
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText*() typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable() typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar() typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: for BeginTabBar()
typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem() typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem()
typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode*(),CollapsingHeader() typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader()
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin*() typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data); typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data);
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
@ -274,17 +274,17 @@ namespace ImGui
IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Sizes will be rounded down. Use callback to apply non-trivial programmatic constraints.
IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin() IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ scrollable client area, which enforce the range of scrollbars). Not including window decorations (title bar, menu bar, etc.) nor WindowPadding. set an axis to 0.0f to leave it automatic. call before Begin()
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin()
IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin()
IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground. IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.
IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects.
IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects.
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed().
IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus(). IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / top-most. prefer using SetNextWindowFocus().
IMGUI_API void SetWindowFontScale(float scale); // set font scale. Adjust IO.FontGlobalScale if you want to scale all windows IMGUI_API void SetWindowFontScale(float scale); // set font scale. Adjust IO.FontGlobalScale if you want to scale all windows. This is an old API! For correct scaling, prefer to reload font + rebuild ImFontAtlas + call style.ScaleAllSizes().
IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position. IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position.
IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis.
IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state
IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / top-most. use NULL to remove focus.
// Content region // Content region
// - Those functions are bound to be redesigned soon (they are confusing, incomplete and return values in local window coordinates which increases confusion) // - Those functions are bound to be redesigned soon (they are confusing, incomplete and return values in local window coordinates which increases confusion)
@ -301,7 +301,9 @@ namespace ImGui
IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
IMGUI_API void SetScrollHereX(float center_x_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_x_ratio=0.0: left, 0.5: center, 1.0: right. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position. IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
// Parameters stacks (shared) // Parameters stacks (shared)
@ -325,7 +327,7 @@ namespace ImGui
IMGUI_API void PushItemWidth(float item_width); // set width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width, IMGUI_API void PushItemWidth(float item_width); // set width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
IMGUI_API void PopItemWidth(); IMGUI_API void PopItemWidth();
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side) IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side)
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
IMGUI_API void PopTextWrapPos(); IMGUI_API void PopTextWrapPos();
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
@ -494,7 +496,6 @@ namespace ImGui
IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call TreePush/TreePop yourself if desired. IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call TreePush/TreePop yourself if desired.
IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API void TreePop(); // ~ Unindent()+PopId()
IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing()
IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
@ -867,7 +868,7 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window
//ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is obstructed or overlapped by another window
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 7, // Return true even if the item is disabled ImGuiHoveredFlags_AllowWhenDisabled = 1 << 7, // Return true even if the item is disabled
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
@ -898,7 +899,7 @@ enum ImGuiDragDropFlags_
// A primary data type // A primary data type
enum ImGuiDataType_ enum ImGuiDataType_
{ {
ImGuiDataType_S8, // char ImGuiDataType_S8, // signed char / char (with sensible compilers)
ImGuiDataType_U8, // unsigned char ImGuiDataType_U8, // unsigned char
ImGuiDataType_S16, // short ImGuiDataType_S16, // short
ImGuiDataType_U16, // unsigned short ImGuiDataType_U16, // unsigned short
@ -940,6 +941,7 @@ enum ImGuiKey_
ImGuiKey_Space, ImGuiKey_Space,
ImGuiKey_Enter, ImGuiKey_Enter,
ImGuiKey_Escape, ImGuiKey_Escape,
ImGuiKey_KeyPadEnter,
ImGuiKey_A, // for text edit CTRL+A: select all ImGuiKey_A, // for text edit CTRL+A: select all
ImGuiKey_C, // for text edit CTRL+C: copy ImGuiKey_C, // for text edit CTRL+C: copy
ImGuiKey_V, // for text edit CTRL+V: paste ImGuiKey_V, // for text edit CTRL+V: paste
@ -1038,7 +1040,7 @@ enum ImGuiCol_
ImGuiCol_Button, ImGuiCol_Button,
ImGuiCol_ButtonHovered, ImGuiCol_ButtonHovered,
ImGuiCol_ButtonActive, ImGuiCol_ButtonActive,
ImGuiCol_Header, ImGuiCol_Header, // Header* colors are used for CollapsingHeader, TreeNode, Selectable, MenuItem
ImGuiCol_HeaderHovered, ImGuiCol_HeaderHovered,
ImGuiCol_HeaderActive, ImGuiCol_HeaderActive,
ImGuiCol_Separator, ImGuiCol_Separator,
@ -1068,7 +1070,6 @@ enum ImGuiCol_
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiCol_ModalWindowDarkening = ImGuiCol_ModalWindowDimBg // [renamed in 1.63] , ImGuiCol_ModalWindowDarkening = ImGuiCol_ModalWindowDimBg // [renamed in 1.63]
, ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg // [renamed in 1.53] , ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg // [renamed in 1.53]
, ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive // [renamed in 1.51]
//ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered, // [unused since 1.60+] the close button now uses regular button colors. //ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered, // [unused since 1.60+] the close button now uses regular button colors.
//ImGuiCol_ComboBg, // [unused since 1.53+] ComboBg has been merged with PopupBg, so a redirect isn't accurate. //ImGuiCol_ComboBg, // [unused since 1.53+] ComboBg has been merged with PopupBg, so a redirect isn't accurate.
#endif #endif
@ -1187,11 +1188,6 @@ enum ImGuiCond_
ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed)
ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file) ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the object/window has no persistently saved data (no entry in .ini file)
ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time) ImGuiCond_Appearing = 1 << 3 // Set the variable if the object/window is appearing after being hidden/inactive (or the first time)
// Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing // [renamed in 1.51]
#endif
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1306,6 +1302,7 @@ struct ImGuiStyle
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
float TabBorderSize; // Thickness of border around tabs. float TabBorderSize; // Thickness of border around tabs.
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
ImVec2 SelectableTextAlign; // Alignment of selectable text when selectable is larger than text. Defaults to (0.0f, 0.0f) (top-left aligned). ImVec2 SelectableTextAlign; // Alignment of selectable text when selectable is larger than text. Defaults to (0.0f, 0.0f) (top-left aligned).
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows. ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows.
@ -1347,7 +1344,7 @@ struct ImGuiIO
float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds.
void* UserData; // = NULL // Store your own data for retrieval by callbacks. void* UserData; // = NULL // Store your own data for retrieval by callbacks.
ImFontAtlas*Fonts; // <auto> // Load, rasterize and pack one or more fonts into a single texture. ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture.
float FontGlobalScale; // = 1.0f // Global scale all fonts float FontGlobalScale; // = 1.0f // Global scale all fonts
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.
ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0]. ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].
@ -1535,8 +1532,10 @@ struct ImGuiPayload
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.72 (from July 2019)
static inline void TreeAdvanceToLabelPos() { SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()); }
// OBSOLETED in 1.71 (from June 2019) // OBSOLETED in 1.71 (from June 2019)
static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); } static inline void SetNextTreeNodeOpen(bool open, ImGuiCond cond = 0) { SetNextItemOpen(open, cond); }
// OBSOLETED in 1.70 (from May 2019) // OBSOLETED in 1.70 (from May 2019)
static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; } static inline float GetContentRegionAvailWidth() { return GetContentRegionAvail().x; }
// OBSOLETED in 1.69 (from Mar 2019) // OBSOLETED in 1.69 (from Mar 2019)
@ -1565,11 +1564,6 @@ namespace ImGui
static inline bool IsRootWindowOrAnyChildHovered() { return IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); } static inline bool IsRootWindowOrAnyChildHovered() { return IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); }
static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); }
static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); } static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); }
// OBSOLETED in 1.51 (between Jun 2017 and Aug 2017)
static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); }
static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // This was misleading and partly broken. You probably want to use the ImGui::GetIO().WantCaptureMouse flag instead.
static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); }
static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); }
} }
typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent typedef ImGuiInputTextCallback ImGuiTextEditCallback; // OBSOLETED in 1.63 (from Aug 2018): made the names consistent
typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
@ -1588,11 +1582,6 @@ struct ImGuiOnceUponAFrame
operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; }
}; };
// Helper: Macro for ImGuiOnceUponAFrame. Attention: The macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf; if (imgui_oaf) // OBSOLETED in 1.51, will remove!
#endif
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
struct ImGuiTextFilter struct ImGuiTextFilter
{ {
@ -1604,21 +1593,19 @@ struct ImGuiTextFilter
bool IsActive() const { return !Filters.empty(); } bool IsActive() const { return !Filters.empty(); }
// [Internal] // [Internal]
struct TextRange struct ImGuiTextRange
{ {
const char* b; const char* b;
const char* e; const char* e;
TextRange() { b = e = NULL; } ImGuiTextRange() { b = e = NULL; }
TextRange(const char* _b, const char* _e) { b = _b; e = _e; } ImGuiTextRange(const char* _b, const char* _e) { b = _b; e = _e; }
const char* begin() const { return b; } bool empty() const { return b == e; }
const char* end () const { return e; } IMGUI_API void split(char separator, ImVector<ImGuiTextRange>* out) const;
bool empty() const { return b == e; }
IMGUI_API void split(char separator, ImVector<TextRange>* out) const;
}; };
char InputBuf[256]; char InputBuf[256];
ImVector<TextRange> Filters; ImVector<ImGuiTextRange>Filters;
int CountGrep; int CountGrep;
}; };
// Helper: Growable text buffer for logging/accumulating text // Helper: Growable text buffer for logging/accumulating text
@ -1626,7 +1613,7 @@ struct ImGuiTextFilter
struct ImGuiTextBuffer struct ImGuiTextBuffer
{ {
ImVector<char> Buf; ImVector<char> Buf;
static char EmptyString[1]; IMGUI_API static char EmptyString[1];
ImGuiTextBuffer() { } ImGuiTextBuffer() { }
inline char operator[](int i) { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; } inline char operator[](int i) { IM_ASSERT(Buf.Data != NULL); return Buf.Data[i]; }
@ -1652,15 +1639,17 @@ struct ImGuiTextBuffer
// Types are NOT stored, so it is up to you to make sure your Key don't collide with different types. // Types are NOT stored, so it is up to you to make sure your Key don't collide with different types.
struct ImGuiStorage struct ImGuiStorage
{ {
struct Pair // [Internal]
struct ImGuiStoragePair
{ {
ImGuiID key; ImGuiID key;
union { int val_i; float val_f; void* val_p; }; union { int val_i; float val_f; void* val_p; };
Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } ImGuiStoragePair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } ImGuiStoragePair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } ImGuiStoragePair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; }
}; };
ImVector<Pair> Data;
ImVector<ImGuiStoragePair> Data;
// - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
// - Set***() functions find pair, insertion on demand if missing. // - Set***() functions find pair, insertion on demand if missing.
@ -1837,7 +1826,8 @@ struct ImDrawListSplitter
int _Count; // Number of active channels (1+) int _Count; // Number of active channels (1+)
ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size) ImVector<ImDrawChannel> _Channels; // Draw channels (not resized down so _Count might be < Channels.Size)
inline ImDrawListSplitter() { Clear(); } inline ImDrawListSplitter() { Clear(); }
inline ~ImDrawListSplitter() { ClearFreeMemory(); }
inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame inline void Clear() { _Current = 0; _Count = 1; } // Do not clear Channels[] so our allocations are reused next frame
IMGUI_API void ClearFreeMemory(); IMGUI_API void ClearFreeMemory();
IMGUI_API void Split(ImDrawList* draw_list, int count); IMGUI_API void Split(ImDrawList* draw_list, int count);
@ -1847,6 +1837,7 @@ struct ImDrawListSplitter
enum ImDrawCornerFlags_ enum ImDrawCornerFlags_
{ {
ImDrawCornerFlags_None = 0,
ImDrawCornerFlags_TopLeft = 1 << 0, // 0x1 ImDrawCornerFlags_TopLeft = 1 << 0, // 0x1
ImDrawCornerFlags_TopRight = 1 << 1, // 0x2 ImDrawCornerFlags_TopRight = 1 << 1, // 0x2
ImDrawCornerFlags_BotLeft = 1 << 2, // 0x4 ImDrawCornerFlags_BotLeft = 1 << 2, // 0x4
@ -1907,8 +1898,8 @@ struct ImDrawList
// Primitives // Primitives
IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size), rounding_corners_flags: 4-bits corresponding to which corner to round IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size), rounding_corners_flags: 4-bits corresponding to which corner to round
IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All); // a: upper-left, b: lower-right (== upper-left + size)
IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f); IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
@ -1920,7 +1911,7 @@ struct ImDrawList
IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL);
IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = IM_COL32_WHITE); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = IM_COL32_WHITE);
IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = IM_COL32_WHITE); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = IM_COL32_WHITE);
IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
@ -1934,7 +1925,7 @@ struct ImDrawList
IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle
IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All);
// Advanced // Advanced
IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles.
@ -2039,6 +2030,19 @@ struct ImFontGlyphRangesBuilder
IMGUI_API void BuildRanges(ImVector<ImWchar>* out_ranges); // Output new ranges IMGUI_API void BuildRanges(ImVector<ImWchar>* out_ranges); // Output new ranges
}; };
// See ImFontAtlas::AddCustomRectXXX functions.
struct ImFontAtlasCustomRect
{
unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data.
unsigned short Width, Height; // Input // Desired rectangle dimension
unsigned short X, Y; // Output // Packed position in Atlas
float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance
ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset
ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font
ImFontAtlasCustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; }
bool IsPacked() const { return X != 0xFFFF; }
};
enum ImFontAtlasFlags_ enum ImFontAtlasFlags_
{ {
ImFontAtlasFlags_None = 0, ImFontAtlasFlags_None = 0,
@ -2103,7 +2107,7 @@ struct ImFontAtlas
IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese
IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters
IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietname characters IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietnamese characters
//------------------------------------------- //-------------------------------------------
// [BETA] Custom Rectangles/Glyphs API // [BETA] Custom Rectangles/Glyphs API
@ -2114,24 +2118,13 @@ struct ImFontAtlas
// You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point),
// so you can render e.g. custom colorful icons and use them as regular glyphs. // so you can render e.g. custom colorful icons and use them as regular glyphs.
// Read misc/fonts/README.txt for more details about using colorful icons. // Read misc/fonts/README.txt for more details about using colorful icons.
struct CustomRect IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList
{ IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font.
unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data. const ImFontAtlasCustomRect*GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; }
unsigned short Width, Height; // Input // Desired rectangle dimension
unsigned short X, Y; // Output // Packed position in Atlas
float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance
ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset
ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font
CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; }
bool IsPacked() const { return X != 0xFFFF; }
};
IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList
IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font.
const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; }
// [Internal] // [Internal]
IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); IMGUI_API void CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max);
IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]);
//------------------------------------------- //-------------------------------------------
// Members // Members
@ -2152,11 +2145,12 @@ struct ImFontAtlas
ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight) ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight)
ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel
ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. ImVector<ImFont*> Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font.
ImVector<CustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas. ImVector<ImFontAtlasCustomRect> CustomRects; // Rectangles for packing custom texture data into the atlas.
ImVector<ImFontConfig> ConfigData; // Internal data ImVector<ImFontConfig> ConfigData; // Internal data
int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+ typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
#endif #endif
}; };
@ -2217,7 +2211,7 @@ struct ImFont
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#elif defined(__GNUC__) && __GNUC__ >= 8 #elif defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif

View File

@ -1,4 +1,4 @@
// dear imgui, v1.71 // dear imgui, v1.72
// (demo code) // (demo code)
// Message to the person tempted to delete this file when integrating Dear ImGui into their code base: // Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
@ -89,13 +89,12 @@ Index of this file:
#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier //
#endif #endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
#pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure) #pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure)
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#if (__GNUC__ >= 6) #pragma GCC diagnostic ignored "-Wmisleading-indentation" // [__GNUC__ >= 6] warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
#pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub.
#endif
#endif #endif
// Play it nice with Windows users. Notepad in 2017 still doesn't display text data with Unix-style \n. // Play it nice with Windows users. Notepad in 2017 still doesn't display text data with Unix-style \n.
@ -540,8 +539,19 @@ static void ShowDemoWindowWidgets()
static float f1=0.123f, f2=0.0f; static float f1=0.123f, f2=0.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f); ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f);
static float angle = 0.0f; static float angle = 0.0f;
ImGui::SliderAngle("slider angle", &angle); ImGui::SliderAngle("slider angle", &angle);
// Using the format string to display a name instead of an integer.
// Here we completely omit '%d' from the format string, so it'll only display a name.
// This technique can also be used with DragInt().
enum Element { Element_Fire, Element_Earth, Element_Air, Element_Water, Element_COUNT };
const char* element_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" };
static int current_element = Element_Fire;
const char* current_element_name = (current_element >= 0 && current_element < Element_COUNT) ? element_names[current_element] : "Unknown";
ImGui::SliderInt("slider enum", &current_element, 0, Element_COUNT - 1, current_element_name);
ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.");
} }
{ {
@ -629,7 +639,7 @@ static void ShowDemoWindowWidgets()
{ {
// Items 3..5 are Tree Leaves // Items 3..5 are Tree Leaves
// The only reason we use TreeNode at all is to allow selection of the leaf. // The only reason we use TreeNode at all is to allow selection of the leaf.
// Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text(). // Otherwise we can use BulletText() or advance the cursor by GetTreeNodeToLabelSpacing() and call Text().
node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet
ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
@ -969,7 +979,7 @@ static void ShowDemoWindowWidgets()
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly); ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly);
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput); ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine); ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), flags); ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1025,7 +1035,7 @@ static void ShowDemoWindowWidgets()
static ImVector<char> my_str; static ImVector<char> my_str;
if (my_str.empty()) if (my_str.empty())
my_str.push_back(0); my_str.push_back(0);
Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16)); Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16));
ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity()); ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1086,7 +1096,8 @@ static void ShowDemoWindowWidgets()
if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; }
} }
// Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width,
// or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth.
ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f)); ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f));
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::Text("Progress Bar"); ImGui::Text("Progress Bar");
@ -1112,7 +1123,7 @@ static void ShowDemoWindowWidgets()
ImGui::Checkbox("With Drag and Drop", &drag_and_drop); ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options."); ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
int 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); 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::Text("Color widget:"); ImGui::Text("Color widget:");
ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n");
@ -1145,7 +1156,7 @@ static void ShowDemoWindowWidgets()
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, misc_flags);
ImGui::SameLine(); ImGui::SameLine(0, ImGui::GetStyle().ItemInnerSpacing.x);
open_popup |= ImGui::Button("Palette"); open_popup |= ImGui::Button("Palette");
if (open_popup) if (open_popup)
{ {
@ -1545,28 +1556,22 @@ static void ShowDemoWindowWidgets()
static bool b = false; static bool b = false;
static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f }; static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
static char str[16] = {}; static char str[16] = {};
ImGui::RadioButton("Text", &item_type, 0); ImGui::Combo("Item Type", &item_type, "Text\0Button\0Button (w/ repeat)\0Checkbox\0SliderFloat\0InputText\0InputFloat\0InputFloat3\0ColorEdit4\0MenuItem\0TreeNode (w/ double-click)\0ListBox\0");
ImGui::RadioButton("Button", &item_type, 1); ImGui::SameLine();
ImGui::RadioButton("Checkbox", &item_type, 2); HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions.");
ImGui::RadioButton("SliderFloat", &item_type, 3);
ImGui::RadioButton("InputText", &item_type, 4);
ImGui::RadioButton("InputFloat3", &item_type, 5);
ImGui::RadioButton("ColorEdit4", &item_type, 6);
ImGui::RadioButton("MenuItem", &item_type, 7);
ImGui::RadioButton("TreeNode (w/ double-click)", &item_type, 8);
ImGui::RadioButton("ListBox", &item_type, 9);
ImGui::Separator();
bool ret = false; bool ret = false;
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
if (item_type == 2) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater)
if (item_type == 3) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item if (item_type == 3) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox
if (item_type == 4) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing) if (item_type == 4) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item
if (item_type == 5) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) if (item_type == 5) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing)
if (item_type == 6) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) if (item_type == 6) { ret = ImGui::InputFloat("ITEM: InputFloat", col4f, 1.0f); } // Testing +/- buttons on scalar input
if (item_type == 7) { ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy) if (item_type == 7) { ret = ImGui::InputFloat3("ITEM: InputFloat3", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged)
if (item_type == 8) { ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy. if (item_type == 8) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged)
if (item_type == 9) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } if (item_type == 9) { ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy)
if (item_type == 10){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy.
if (item_type == 11){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
ImGui::BulletText( ImGui::BulletText(
"Return value = %d\n" "Return value = %d\n"
"IsItemFocused() = %d\n" "IsItemFocused() = %d\n"
@ -1728,7 +1733,7 @@ static void ShowDemoWindowLayout()
{ {
char buf[32]; char buf[32];
sprintf(buf, "%03d", i); sprintf(buf, "%03d", i);
ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); ImGui::Button(buf, ImVec2(-FLT_MIN, 0.0f));
ImGui::NextColumn(); ImGui::NextColumn();
} }
ImGui::EndChild(); ImGui::EndChild();
@ -1744,7 +1749,7 @@ static void ShowDemoWindowLayout()
// - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from the POV of the parent window) // - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from the POV of the parent window)
// See "Widgets" -> "Querying Status (Active/Focused/Hovered etc.)" section for more details about this. // See "Widgets" -> "Querying Status (Active/Focused/Hovered etc.)" section for more details about this.
{ {
ImGui::SetCursorPosX(50); ImGui::SetCursorPosX(ImGui::GetCursorPosX() + 10);
ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100)); ImGui::PushStyleColor(ImGuiCol_ChildBg, IM_COL32(255, 0, 0, 100));
ImGui::BeginChild("blah", ImVec2(200, 100), true, ImGuiWindowFlags_None); ImGui::BeginChild("blah", ImVec2(200, 100), true, ImGuiWindowFlags_None);
for (int n = 0; n < 50; n++) for (int n = 0; n < 50; n++)
@ -1788,9 +1793,9 @@ static void ShowDemoWindowLayout()
ImGui::Text("SetNextItemWidth/PushItemWidth(-1)"); ImGui::Text("SetNextItemWidth/PushItemWidth(-1)");
ImGui::SameLine(); HelpMarker("Align to right edge"); ImGui::SameLine(); HelpMarker("Align to right edge");
ImGui::PushItemWidth(-1); ImGui::PushItemWidth(-1);
ImGui::DragFloat("float##5a", &f); ImGui::DragFloat("##float5a", &f);
ImGui::DragFloat("float##5b", &f); ImGui::DragFloat("##float5b", &f);
ImGui::DragFloat("float##5c", &f); ImGui::DragFloat("##float5c", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::TreePop(); ImGui::TreePop();
@ -1957,7 +1962,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Groups")) if (ImGui::TreeNode("Groups"))
{ {
HelpMarker("Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it."); HelpMarker("BeginGroup() basically locks the horizontal position for new line. EndGroup() bundles the whole group so that you can use \"item\" functions such as IsItemHovered()/IsItemActive() or SameLine() etc. on the whole group.");
ImGui::BeginGroup(); ImGui::BeginGroup();
{ {
ImGui::BeginGroup(); ImGui::BeginGroup();
@ -2056,21 +2061,22 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Scrolling")) if (ImGui::TreeNode("Scrolling"))
{ {
HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); // Vertical scroll functions
HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given vertical position.");
static bool track = true; static bool track = true;
static int track_line = 50; static int track_item = 50;
static float scroll_to_off_px = 0.0f; static float scroll_to_off_px = 0.0f;
static float scroll_to_pos_px = 200.0f; static float scroll_to_pos_px = 200.0f;
ImGui::Checkbox("Track", &track); ImGui::Checkbox("Track", &track);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::SameLine(140); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d"); ImGui::SameLine(140); track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
bool scroll_to_off = ImGui::Button("Scroll Offset"); bool scroll_to_off = ImGui::Button("Scroll Offset");
ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off_y", &scroll_to_off_px, 1.00f, 0, 9999, "+%.0f px"); ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, 9999, "+%.0f px");
bool scroll_to_pos = ImGui::Button("Scroll To Pos"); bool scroll_to_pos = ImGui::Button("Scroll To Pos");
ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos_y", &scroll_to_pos_px, 1.00f, 0, 9999, "Y = %.0f px"); ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, 0, 9999, "X/Y = %.0f px");
ImGui::PopItemWidth(); ImGui::PopItemWidth();
if (scroll_to_off || scroll_to_pos) if (scroll_to_off || scroll_to_pos)
@ -2078,28 +2084,31 @@ static void ShowDemoWindowLayout()
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
float child_w = (ImGui::GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5; float child_w = (ImGui::GetContentRegionAvail().x - 4 * style.ItemSpacing.x) / 5;
if (child_w < 1.0f)
child_w = 1.0f;
ImGui::PushID("##VerticalScrolling");
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
if (i > 0) ImGui::SameLine(); if (i > 0) ImGui::SameLine();
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); const char* names[] = { "Top", "25%", "Center", "75%", "Bottom" };
ImGui::TextUnformatted(names[i]);
ImGuiWindowFlags child_flags = ImGuiWindowFlags_MenuBar; ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true, ImGuiWindowFlags_None);
ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(child_w, 200.0f), true, child_flags);
if (scroll_to_off) if (scroll_to_off)
ImGui::SetScrollY(scroll_to_off_px); ImGui::SetScrollY(scroll_to_off_px);
if (scroll_to_pos) if (scroll_to_pos)
ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f); ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_pos_px, i * 0.25f);
for (int line = 0; line < 100; line++) for (int item = 0; item < 100; item++)
{ {
if (track && line == track_line) if (track && item == track_item)
{ {
ImGui::TextColored(ImVec4(1,1,0,1), "Line %d", line); ImGui::TextColored(ImVec4(1,1,0,1), "Item %d", item);
ImGui::SetScrollHereY(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom ImGui::SetScrollHereY(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom
} }
else else
{ {
ImGui::Text("Line %d", line); ImGui::Text("Item %d", item);
} }
} }
float scroll_y = ImGui::GetScrollY(); float scroll_y = ImGui::GetScrollY();
@ -2108,11 +2117,44 @@ static void ShowDemoWindowLayout()
ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y); ImGui::Text("%.0f/%.0f", scroll_y, scroll_max_y);
ImGui::EndGroup(); ImGui::EndGroup();
} }
ImGui::TreePop(); ImGui::PopID();
}
if (ImGui::TreeNode("Horizontal Scrolling")) // Horizontal scroll functions
{ ImGui::Spacing();
HelpMarker("Use SetScrollHereX() or SetScrollFromPosX() to scroll to a given horizontal position.\n\nUsing the \"Scroll To Pos\" button above will make the discontinuity at edges visible: scrolling to the top/bottom/left/right-most item will add an additional WindowPadding to reflect on reaching the edge of the list.\n\nBecause the clipping rectangle of most window hides half worth of WindowPadding on the left/right, using SetScrollFromPosX(+1) will usually result in clipped text whereas the equivalent SetScrollFromPosY(+1) wouldn't.");
ImGui::PushID("##HorizontalScrolling");
for (int i = 0; i < 5; i++)
{
float child_height = ImGui::GetTextLineHeight() + style.ScrollbarSize + style.WindowPadding.y * 2.0f;
ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(-100, child_height), true, ImGuiWindowFlags_HorizontalScrollbar);
if (scroll_to_off)
ImGui::SetScrollX(scroll_to_off_px);
if (scroll_to_pos)
ImGui::SetScrollFromPosX(ImGui::GetCursorStartPos().x + scroll_to_pos_px, i * 0.25f);
for (int item = 0; item < 100; item++)
{
if (track && item == track_item)
{
ImGui::TextColored(ImVec4(1, 1, 0, 1), "Item %d", item);
ImGui::SetScrollHereX(i * 0.25f); // 0.0f:left, 0.5f:center, 1.0f:right
}
else
{
ImGui::Text("Item %d", item);
}
ImGui::SameLine();
}
float scroll_x = ImGui::GetScrollX();
float scroll_max_x = ImGui::GetScrollMaxX();
ImGui::EndChild();
ImGui::SameLine();
const char* names[] = { "Left", "25%", "Center", "75%", "Right" };
ImGui::Text("%s\n%.0f/%.0f", names[i], scroll_x, scroll_max_x);
ImGui::Spacing();
}
ImGui::PopID();
// Miscellaneous Horizontal Scrolling Demo
HelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); HelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin().");
static int lines = 7; static int lines = 7;
ImGui::SliderInt("Lines", &lines, 1, 15); ImGui::SliderInt("Lines", &lines, 1, 15);
@ -2520,7 +2562,7 @@ static void ShowDemoWindowColumns()
char label[32]; char label[32];
sprintf(label, "Item %d", n); sprintf(label, "Item %d", n);
if (ImGui::Selectable(label)) {} if (ImGui::Selectable(label)) {}
//if (ImGui::Button(label, ImVec2(-1,0))) {} //if (ImGui::Button(label, ImVec2(-FLT_MIN,0.0f))) {}
ImGui::NextColumn(); ImGui::NextColumn();
} }
ImGui::Columns(1); ImGui::Columns(1);
@ -2559,19 +2601,27 @@ static void ShowDemoWindowColumns()
// NB: Future columns API should allow automatic horizontal borders. // NB: Future columns API should allow automatic horizontal borders.
static bool h_borders = true; static bool h_borders = true;
static bool v_borders = true; static bool v_borders = true;
static int columns_count = 4;
const int lines_count = 3;
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::DragInt("##columns_count", &columns_count, 0.1f, 2, 10, "%d columns");
if (columns_count < 2)
columns_count = 2;
ImGui::SameLine();
ImGui::Checkbox("horizontal", &h_borders); ImGui::Checkbox("horizontal", &h_borders);
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox("vertical", &v_borders); ImGui::Checkbox("vertical", &v_borders);
ImGui::Columns(4, NULL, v_borders); ImGui::Columns(columns_count, NULL, v_borders);
for (int i = 0; i < 4 * 3; i++) for (int i = 0; i < columns_count * lines_count; i++)
{ {
if (h_borders && ImGui::GetColumnIndex() == 0) if (h_borders && ImGui::GetColumnIndex() == 0)
ImGui::Separator(); ImGui::Separator();
ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i); ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i);
ImGui::Text("Width %.2f", ImGui::GetColumnWidth()); ImGui::Text("Width %.2f", ImGui::GetColumnWidth());
ImGui::Text("Avail %.2f", ImGui::GetContentRegionAvail().x);
ImGui::Text("Offset %.2f", ImGui::GetColumnOffset()); ImGui::Text("Offset %.2f", ImGui::GetColumnOffset());
ImGui::Text("Long text that is likely to clip"); ImGui::Text("Long text that is likely to clip");
ImGui::Button("Button", ImVec2(-1.0f, 0.0f)); ImGui::Button("Button", ImVec2(-FLT_MIN, 0.0f));
ImGui::NextColumn(); ImGui::NextColumn();
} }
ImGui::Columns(1); ImGui::Columns(1);
@ -3113,6 +3163,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::Text("Alignment"); ImGui::Text("Alignment");
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
ImGui::Combo("WindowMenuButtonPosition", (int*)&style.WindowMenuButtonPosition, "Left\0Right\0"); ImGui::Combo("WindowMenuButtonPosition", (int*)&style.WindowMenuButtonPosition, "Left\0Right\0");
ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0");
ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");
ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content."); ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.");
ImGui::Text("Safe Area Padding"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); ImGui::Text("Safe Area Padding"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
@ -3256,8 +3307,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::TreePop(); ImGui::TreePop();
} }
HelpMarker("Those are old settings provided for convenience.\nHowever, the _correct_ way of scaling your UI is currently to reload your font at the designed size, rebuild the font atlas, and call style.ScaleAllSizes() on a reference ImGuiStyle structure.");
static float window_scale = 1.0f; static float window_scale = 1.0f;
if (ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.2f")) // scale only this window if (ImGui::DragFloat("window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.2f")) // scale only this window
ImGui::SetWindowFontScale(window_scale); ImGui::SetWindowFontScale(window_scale);
ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.2f"); // scale everything ImGui::DragFloat("global scale", &io.FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.2f"); // scale everything
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -3408,7 +3460,7 @@ struct ExampleAppConsole
Commands.push_back("CLEAR"); Commands.push_back("CLEAR");
Commands.push_back("CLASSIFY"); // "classify" is only here to provide an example of "C"+[tab] completing to "CL" and displaying matches. Commands.push_back("CLASSIFY"); // "classify" is only here to provide an example of "C"+[tab] completing to "CL" and displaying matches.
AutoScroll = true; AutoScroll = true;
ScrollToBottom = true; ScrollToBottom = false;
AddLog("Welcome to Dear ImGui!"); AddLog("Welcome to Dear ImGui!");
} }
~ExampleAppConsole() ~ExampleAppConsole()
@ -3429,7 +3481,6 @@ struct ExampleAppConsole
for (int i = 0; i < Items.Size; i++) for (int i = 0; i < Items.Size; i++)
free(Items[i]); free(Items[i]);
Items.clear(); Items.clear();
ScrollToBottom = true;
} }
void AddLog(const char* fmt, ...) IM_FMTARGS(2) void AddLog(const char* fmt, ...) IM_FMTARGS(2)
@ -3442,8 +3493,6 @@ struct ExampleAppConsole
buf[IM_ARRAYSIZE(buf)-1] = 0; buf[IM_ARRAYSIZE(buf)-1] = 0;
va_end(args); va_end(args);
Items.push_back(Strdup(buf)); Items.push_back(Strdup(buf));
if (AutoScroll)
ScrollToBottom = true;
} }
void Draw(const char* title, bool* p_open) void Draw(const char* title, bool* p_open)
@ -3472,8 +3521,7 @@ struct ExampleAppConsole
if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine();
if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine(); if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine();
if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine(); if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine();
bool copy_to_clipboard = ImGui::SmallButton("Copy"); ImGui::SameLine(); bool copy_to_clipboard = ImGui::SmallButton("Copy");
if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true;
//static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); }
ImGui::Separator(); ImGui::Separator();
@ -3481,9 +3529,7 @@ struct ExampleAppConsole
// Options menu // Options menu
if (ImGui::BeginPopup("Options")) if (ImGui::BeginPopup("Options"))
{ {
if (ImGui::Checkbox("Auto-scroll", &AutoScroll)) ImGui::Checkbox("Auto-scroll", &AutoScroll);
if (AutoScroll)
ScrollToBottom = true;
ImGui::EndPopup(); ImGui::EndPopup();
} }
@ -3532,9 +3578,11 @@ struct ExampleAppConsole
} }
if (copy_to_clipboard) if (copy_to_clipboard)
ImGui::LogFinish(); ImGui::LogFinish();
if (ScrollToBottom)
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false; ScrollToBottom = false;
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::EndChild(); ImGui::EndChild();
ImGui::Separator(); ImGui::Separator();
@ -3726,13 +3774,11 @@ struct ExampleAppLog
ImGuiTextBuffer Buf; ImGuiTextBuffer Buf;
ImGuiTextFilter Filter; ImGuiTextFilter Filter;
ImVector<int> LineOffsets; // Index to lines offset. We maintain this with AddLog() calls, allowing us to have a random access on lines ImVector<int> LineOffsets; // Index to lines offset. We maintain this with AddLog() calls, allowing us to have a random access on lines
bool AutoScroll; bool AutoScroll; // Keep scrolling if already at the bottom
bool ScrollToBottom;
ExampleAppLog() ExampleAppLog()
{ {
AutoScroll = true; AutoScroll = true;
ScrollToBottom = false;
Clear(); Clear();
} }
@ -3753,8 +3799,6 @@ struct ExampleAppLog
for (int new_size = Buf.size(); old_size < new_size; old_size++) for (int new_size = Buf.size(); old_size < new_size; old_size++)
if (Buf[old_size] == '\n') if (Buf[old_size] == '\n')
LineOffsets.push_back(old_size + 1); LineOffsets.push_back(old_size + 1);
if (AutoScroll)
ScrollToBottom = true;
} }
void Draw(const char* title, bool* p_open = NULL) void Draw(const char* title, bool* p_open = NULL)
@ -3768,9 +3812,7 @@ struct ExampleAppLog
// Options menu // Options menu
if (ImGui::BeginPopup("Options")) if (ImGui::BeginPopup("Options"))
{ {
if (ImGui::Checkbox("Auto-scroll", &AutoScroll)) ImGui::Checkbox("Auto-scroll", &AutoScroll);
if (AutoScroll)
ScrollToBottom = true;
ImGui::EndPopup(); ImGui::EndPopup();
} }
@ -3835,9 +3877,9 @@ struct ExampleAppLog
} }
ImGui::PopStyleVar(); ImGui::PopStyleVar();
if (ScrollToBottom) if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false;
ImGui::EndChild(); ImGui::EndChild();
ImGui::End(); ImGui::End();
} }
@ -4022,7 +4064,7 @@ static void ShowExampleAppLongText(bool* p_open)
static ImGuiTextBuffer log; static ImGuiTextBuffer log;
static int lines = 0; static int lines = 0;
ImGui::Text("Printing unusually long amount of text."); ImGui::Text("Printing unusually long amount of text.");
ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0"); ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped\0Multiple calls to Text(), not clipped (slow)\0");
ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
if (ImGui::Button("Clear")) { log.clear(); lines = 0; } if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
ImGui::SameLine(); ImGui::SameLine();

View File

@ -1,4 +1,4 @@
// dear imgui, v1.71 // dear imgui, v1.72
// (drawing and font code) // (drawing and font code)
/* /*
@ -72,13 +72,12 @@ Index of this file:
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif #endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
#pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer #pragma GCC diagnostic ignored "-Wstack-protector" // warning: stack protector not protecting local variables: variable length buffer
#if __GNUC__ >= 8 #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#pragma GCC diagnostic ignored "-Wclass-memaccess" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -261,7 +260,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f);
colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f); colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f);
@ -317,7 +316,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
@ -365,7 +364,7 @@ void ImDrawList::Clear()
CmdBuffer.resize(0); CmdBuffer.resize(0);
IdxBuffer.resize(0); IdxBuffer.resize(0);
VtxBuffer.resize(0); VtxBuffer.resize(0);
Flags = _Data->InitialFlags; Flags = _Data ? _Data->InitialFlags : ImDrawListFlags_None;
_VtxCurrentOffset = 0; _VtxCurrentOffset = 0;
_VtxCurrentIdx = 0; _VtxCurrentIdx = 0;
_VtxWritePtr = NULL; _VtxWritePtr = NULL;
@ -392,7 +391,7 @@ void ImDrawList::ClearFreeMemory()
ImDrawList* ImDrawList::CloneOutput() const ImDrawList* ImDrawList::CloneOutput() const
{ {
ImDrawList* dst = IM_NEW(ImDrawList(NULL)); ImDrawList* dst = IM_NEW(ImDrawList(_Data));
dst->CmdBuffer = CmdBuffer; dst->CmdBuffer = CmdBuffer;
dst->IdxBuffer = IdxBuffer; dst->IdxBuffer = IdxBuffer;
dst->VtxBuffer = VtxBuffer; dst->VtxBuffer = VtxBuffer;
@ -944,7 +943,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV
} }
} }
void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawCornerFlags rounding_corners)
{ {
rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f); rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f);
rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f); rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f);
@ -979,24 +978,24 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic
} }
// a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly. // a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly.
void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags, float thickness) void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners, float thickness)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
if (Flags & ImDrawListFlags_AntiAliasedLines) if (Flags & ImDrawListFlags_AntiAliasedLines)
PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.50f,0.50f), rounding, rounding_corners_flags); PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.50f,0.50f), rounding, rounding_corners);
else else
PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.49f,0.49f), rounding, rounding_corners_flags); // Better looking lower-right corner and rounded non-AA shapes. PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.49f,0.49f), rounding, rounding_corners); // Better looking lower-right corner and rounded non-AA shapes.
PathStroke(col, true, thickness); PathStroke(col, true, thickness);
} }
void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags) void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
if (rounding > 0.0f) if (rounding > 0.0f)
{ {
PathRect(a, b, rounding, rounding_corners_flags); PathRect(a, b, rounding, rounding_corners);
PathFillConvex(col); PathFillConvex(col);
} }
else else
@ -1165,7 +1164,7 @@ void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, cons
PopTextureID(); PopTextureID();
} }
void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners) void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, ImDrawCornerFlags rounding_corners)
{ {
if ((col & IM_COL32_A_MASK) == 0) if ((col & IM_COL32_A_MASK) == 0)
return; return;
@ -1262,7 +1261,7 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
// Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command. // Calculate our final buffer sizes. Also fix the incorrect IdxOffset values in each command.
int new_cmd_buffer_count = 0; int new_cmd_buffer_count = 0;
int new_idx_buffer_count = 0; int new_idx_buffer_count = 0;
ImDrawCmd* last_cmd = (_Count > 0 && _Channels[0]._CmdBuffer.Size > 0) ? &_Channels[0]._CmdBuffer.back() : NULL; ImDrawCmd* last_cmd = (_Count > 0 && draw_list->CmdBuffer.Size > 0) ? &draw_list->CmdBuffer.back() : NULL;
int idx_offset = last_cmd ? last_cmd->IdxOffset + last_cmd->ElemCount : 0; int idx_offset = last_cmd ? last_cmd->IdxOffset + last_cmd->ElemCount : 0;
for (int i = 1; i < _Count; i++) for (int i = 1; i < _Count; i++)
{ {
@ -1305,7 +1304,7 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx) void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
{ {
IM_ASSERT(idx < _Count); IM_ASSERT(idx >= 0 && idx < _Count);
if (_Current == idx) if (_Current == idx)
return; return;
// Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap() // Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
@ -1721,7 +1720,7 @@ int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height)
IM_ASSERT(id >= 0x10000); IM_ASSERT(id >= 0x10000);
IM_ASSERT(width > 0 && width <= 0xFFFF); IM_ASSERT(width > 0 && width <= 0xFFFF);
IM_ASSERT(height > 0 && height <= 0xFFFF); IM_ASSERT(height > 0 && height <= 0xFFFF);
CustomRect r; ImFontAtlasCustomRect r;
r.ID = id; r.ID = id;
r.Width = (unsigned short)width; r.Width = (unsigned short)width;
r.Height = (unsigned short)height; r.Height = (unsigned short)height;
@ -1734,7 +1733,7 @@ int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int
IM_ASSERT(font != NULL); IM_ASSERT(font != NULL);
IM_ASSERT(width > 0 && width <= 0xFFFF); IM_ASSERT(width > 0 && width <= 0xFFFF);
IM_ASSERT(height > 0 && height <= 0xFFFF); IM_ASSERT(height > 0 && height <= 0xFFFF);
CustomRect r; ImFontAtlasCustomRect r;
r.ID = id; r.ID = id;
r.Width = (unsigned short)width; r.Width = (unsigned short)width;
r.Height = (unsigned short)height; r.Height = (unsigned short)height;
@ -1745,7 +1744,7 @@ int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int
return CustomRects.Size - 1; // Return index return CustomRects.Size - 1; // Return index
} }
void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) void ImFontAtlas::CalcCustomRectUV(const ImFontAtlasCustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max)
{ {
IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates
IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed
@ -1761,7 +1760,7 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou
return false; return false;
IM_ASSERT(CustomRectIds[0] != -1); IM_ASSERT(CustomRectIds[0] != -1);
ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; ImFontAtlasCustomRect& r = CustomRects[CustomRectIds[0]];
IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID);
ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y);
ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1];
@ -2120,7 +2119,7 @@ void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opa
stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque; stbrp_context* pack_context = (stbrp_context*)stbrp_context_opaque;
IM_ASSERT(pack_context != NULL); IM_ASSERT(pack_context != NULL);
ImVector<ImFontAtlas::CustomRect>& user_rects = atlas->CustomRects; ImVector<ImFontAtlasCustomRect>& user_rects = atlas->CustomRects;
IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong.
ImVector<stbrp_rect> pack_rects; ImVector<stbrp_rect> pack_rects;
@ -2146,7 +2145,7 @@ static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas)
{ {
IM_ASSERT(atlas->CustomRectIds[0] >= 0); IM_ASSERT(atlas->CustomRectIds[0] >= 0);
IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); IM_ASSERT(atlas->TexPixelsAlpha8 != NULL);
ImFontAtlas::CustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; ImFontAtlasCustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]];
IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID);
IM_ASSERT(r.IsPacked()); IM_ASSERT(r.IsPacked());
@ -2181,7 +2180,7 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas)
// Register custom rectangle glyphs // Register custom rectangle glyphs
for (int i = 0; i < atlas->CustomRects.Size; i++) for (int i = 0; i < atlas->CustomRects.Size; i++)
{ {
const ImFontAtlas::CustomRect& r = atlas->CustomRects[i]; const ImFontAtlasCustomRect& r = atlas->CustomRects[i];
if (r.Font == NULL || r.ID > 0x10000) if (r.Font == NULL || r.ID > 0x10000)
continue; continue;
@ -2693,7 +2692,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
} }
// We ignore blank width at the end of the line (they can be skipped) // We ignore blank width at the end of the line (they can be skipped)
if (line_width + word_width >= wrap_width) if (line_width + word_width > wrap_width)
{ {
// Words that cannot possibly fit within an entire line will be cut anywhere. // Words that cannot possibly fit within an entire line will be cut anywhere.
if (word_width < wrap_width) if (word_width < wrap_width)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.71 // dear imgui, v1.72
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -56,9 +56,8 @@ Index of this file:
#endif #endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#if __GNUC__ >= 8 #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
#endif #endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -92,6 +91,7 @@ struct ImGuiWindowSettings; // Storage for window settings stored in .in
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior() typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior()
typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: BeginColumns()
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior() typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
@ -141,12 +141,15 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_NEWLINE "\n" #define IM_NEWLINE "\n"
#endif #endif
#define IM_TABSIZE (4) #define IM_TABSIZE (4)
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1] #define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
// Debug Logging
#ifndef IMGUI_DEBUG_LOG
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
#endif
// Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall
#ifdef _MSC_VER #ifdef _MSC_VER
#define IMGUI_CDECL __cdecl #define IMGUI_CDECL __cdecl
@ -358,7 +361,8 @@ enum ImGuiSelectableFlagsPrivate_
ImGuiSelectableFlags_PressedOnClick = 1 << 21, ImGuiSelectableFlags_PressedOnClick = 1 << 21,
ImGuiSelectableFlags_PressedOnRelease = 1 << 22, ImGuiSelectableFlags_PressedOnRelease = 1 << 22,
ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // FIXME: We may be able to remove this (added in 6251d379 for menus) ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // FIXME: We may be able to remove this (added in 6251d379 for menus)
ImGuiSelectableFlags_AllowItemOverlap = 1 << 24 ImGuiSelectableFlags_AllowItemOverlap = 1 << 24,
ImGuiSelectableFlags_DrawHoveredWhenHeld= 1 << 25 // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow.
}; };
// Extend ImGuiTreeNodeFlags_ // Extend ImGuiTreeNodeFlags_
@ -385,6 +389,7 @@ enum ImGuiItemFlags_
ImGuiItemFlags_NoNav = 1 << 3, // false ImGuiItemFlags_NoNav = 1 << 3, // false
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
ImGuiItemFlags_Default_ = 0 ImGuiItemFlags_Default_ = 0
}; };
@ -400,7 +405,7 @@ enum ImGuiItemStatusFlags_
ImGuiItemStatusFlags_Deactivated = 1 << 5 // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_Deactivated = 1 << 5 // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
, // [imgui-test only] , // [imgui_tests only]
ImGuiItemStatusFlags_Openable = 1 << 10, // ImGuiItemStatusFlags_Openable = 1 << 10, //
ImGuiItemStatusFlags_Opened = 1 << 11, // ImGuiItemStatusFlags_Opened = 1 << 11, //
ImGuiItemStatusFlags_Checkable = 1 << 12, // ImGuiItemStatusFlags_Checkable = 1 << 12, //
@ -704,6 +709,7 @@ struct ImGuiColumns
float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns() float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect HostClipRect; // Backup of ClipRect at the time of BeginColumns() ImRect HostClipRect; // Backup of ClipRect at the time of BeginColumns()
ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns; ImVector<ImGuiColumnData> Columns;
ImGuiColumns() { Clear(); } ImGuiColumns() { Clear(); }
@ -825,13 +831,13 @@ struct ImGuiShrinkWidthItem
float Width; float Width;
}; };
struct ImGuiTabBarRef struct ImGuiPtrOrIndex
{ {
ImGuiTabBar* Ptr; // Either field can be set, not both. Dock node tab bars are loose while BeginTabBar() ones are in a pool. void* Ptr; // Either field can be set, not both. e.g. Dock node tab bars are loose while BeginTabBar() ones are in a pool.
int IndexInMainPool; int Index; // Usually index in a main pool.
ImGuiTabBarRef(ImGuiTabBar* ptr) { Ptr = ptr; IndexInMainPool = -1; } ImGuiPtrOrIndex(void* ptr) { Ptr = ptr; Index = -1; }
ImGuiTabBarRef(int index_in_main_pool) { Ptr = NULL; IndexInMainPool = index_in_main_pool; } ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -866,6 +872,9 @@ struct ImGuiContext
ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow.
ImGuiWindow* WheelingWindow;
ImVec2 WheelingWindowRefMousePos;
float WheelingWindowTimer;
// Item/widgets state and tracking information // Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget ImGuiID HoveredId; // Hovered widget
@ -919,7 +928,7 @@ struct ImGuiContext
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring. ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring.
int NavScoringCount; // Metrics for debugging int NavScoringCount; // Metrics for debugging
ImGuiWindow* NavWindowingTarget; // When selecting a window (holding Menu+FocusPrev/Next, or equivalent of CTRL-TAB) this window is temporarily displayed front-most. ImGuiWindow* NavWindowingTarget; // When selecting a window (holding Menu+FocusPrev/Next, or equivalent of CTRL-TAB) this window is temporarily displayed top-most.
ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f
ImGuiWindow* NavWindowingList; ImGuiWindow* NavWindowingList;
float NavWindowingTimer; float NavWindowingTimer;
@ -981,9 +990,9 @@ struct ImGuiContext
unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads
// Tab bars // Tab bars
ImPool<ImGuiTabBar> TabBars;
ImGuiTabBar* CurrentTabBar; ImGuiTabBar* CurrentTabBar;
ImVector<ImGuiTabBarRef> CurrentTabBarStack; ImPool<ImGuiTabBar> TabBars;
ImVector<ImGuiPtrOrIndex> CurrentTabBarStack;
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer; ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
// Widget state // Widget state
@ -1026,6 +1035,10 @@ struct ImGuiContext
int LogDepthToExpand; int LogDepthToExpand;
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call. int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
// Debug Tools
bool DebugItemPickerActive;
ImGuiID DebugItemPickerBreakID; // Will call IM_DEBUG_BREAK() when encountering this id
// Misc // Misc
float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds.
int FramerateSecPerFrameIdx; int FramerateSecPerFrameIdx;
@ -1052,6 +1065,8 @@ struct ImGuiContext
HoveredWindow = NULL; HoveredWindow = NULL;
HoveredRootWindow = NULL; HoveredRootWindow = NULL;
MovingWindow = NULL; MovingWindow = NULL;
WheelingWindow = NULL;
WheelingWindowTimer = 0.0f;
HoveredId = 0; HoveredId = 0;
HoveredIdAllowOverlap = false; HoveredIdAllowOverlap = false;
@ -1151,6 +1166,9 @@ struct ImGuiContext
LogDepthRef = 0; LogDepthRef = 0;
LogDepthToExpand = LogDepthToExpandDefault = 2; LogDepthToExpand = LogDepthToExpandDefault = 2;
DebugItemPickerActive = false;
DebugItemPickerBreakID = 0;
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = 0; FramerateSecPerFrameIdx = 0;
FramerateSecPerFrameAccum = 0.0f; FramerateSecPerFrameAccum = 0.0f;
@ -1299,7 +1317,7 @@ struct IMGUI_API ImGuiWindow
// The best way to understand what those rectangles are is to use the 'Metrics -> Tools -> Show windows rectangles' viewer. // The best way to understand what those rectangles are is to use the 'Metrics -> Tools -> Show windows rectangles' viewer.
// The main 'OuterRect', omitted as a field, is window->Rect(). // The main 'OuterRect', omitted as a field, is window->Rect().
ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window. ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
ImRect InnerRect; // Inner rectangle (omit title bar, menu bar) ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar)
ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect. ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentsRegionRect over time (from 1.71+ onward). ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentsRegionRect over time (from 1.71+ onward).
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back(). ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
@ -1310,7 +1328,7 @@ struct IMGUI_API ImGuiWindow
ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items
ImGuiStorage StateStorage; ImGuiStorage StateStorage;
ImVector<ImGuiColumns> ColumnsStorage; ImVector<ImGuiColumns> ColumnsStorage;
float FontWindowScale; // User scale multiplier per-window float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
int SettingsIdx; // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back) int SettingsIdx; // Index into SettingsWindow[] (indices 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)
@ -1337,12 +1355,12 @@ public:
ImGuiID GetIDFromRectangle(const ImRect& r_abs); ImGuiID GetIDFromRectangle(const ImRect& r_abs);
// We don't use g.FontSize because the window may be != g.CurrentWidow. // We don't use g.FontSize because the window may be != g.CurrentWidow.
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 { return GImGui->FontBaseSize * FontWindowScale; } float CalcFontSize() const { ImGuiContext& g = *GImGui; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; }
float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; }
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())); }
float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; }
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()); }
}; };
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data. // Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
@ -1411,7 +1429,7 @@ struct ImGuiTabBar
float ScrollingSpeed; float ScrollingSpeed;
ImGuiTabBarFlags Flags; ImGuiTabBarFlags Flags;
ImGuiID ReorderRequestTabId; ImGuiID ReorderRequestTabId;
int ReorderRequestDir; ImS8 ReorderRequestDir;
bool WantLayout; bool WantLayout;
bool VisibleTabWasSubmitted; bool VisibleTabWasSubmitted;
short LastTabItemIdx; // For BeginTabItem()/EndTabItem() short LastTabItemIdx; // For BeginTabItem()/EndTabItem()
@ -1451,8 +1469,8 @@ namespace ImGui
IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window); IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
IMGUI_API void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); IMGUI_API void SetScrollX(ImGuiWindow* window, float new_scroll_x);
IMGUI_API void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); IMGUI_API void SetScrollY(ImGuiWindow* window, float new_scroll_y);
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow* window);
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0);
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);
@ -1520,7 +1538,7 @@ namespace ImGui
IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack! IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack!
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
IMGUI_API ImGuiWindow* GetFrontMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostPopupModal();
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default);
@ -1538,6 +1556,7 @@ namespace ImGui
IMGUI_API void SetNavIDWithRectRel(ImGuiID id, int nav_layer, const ImRect& rect_rel); IMGUI_API void SetNavIDWithRectRel(ImGuiID id, int nav_layer, const ImRect& rect_rel);
// Inputs // Inputs
inline bool IsMouseDragPastThreshold(int button, float lock_threshold = -1.0f);
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { const int key_index = GImGui->IO.KeyMap[key]; return (key_index >= 0) ? IsKeyPressed(key_index, repeat) : false; } inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { const int key_index = GImGui->IO.KeyMap[key]; return (key_index >= 0) ? IsKeyPressed(key_index, repeat) : false; }
inline bool IsNavInputDown(ImGuiNavInput n) { return GImGui->IO.NavInputs[n] > 0.0f; } inline bool IsNavInputDown(ImGuiNavInput n) { return GImGui->IO.NavInputs[n] > 0.0f; }
inline bool IsNavInputPressed(ImGuiNavInput n, ImGuiInputReadMode mode) { return GetNavInputAmount(n, mode) > 0.0f; } inline bool IsNavInputPressed(ImGuiNavInput n, ImGuiInputReadMode mode) { return GetNavInputAmount(n, mode) > 0.0f; }
@ -1556,6 +1575,8 @@ namespace ImGui
IMGUI_API void PopColumnsBackground(); IMGUI_API void PopColumnsBackground();
IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count);
IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); IMGUI_API ImGuiColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id);
IMGUI_API float GetColumnOffsetFromNorm(const ImGuiColumns* columns, float offset_norm);
IMGUI_API float GetColumnNormFromOffset(const ImGuiColumns* columns, float offset);
// Tab Bars // Tab Bars
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags); IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
@ -1649,6 +1670,9 @@ namespace ImGui
IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1);
IMGUI_API void ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); IMGUI_API void ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp);
// Debug Tools
inline void DebugStartItemPicker() { GImGui->DebugItemPickerActive = true; }
} // namespace ImGui } // namespace ImGui
// ImFontAtlas internals // ImFontAtlas internals
@ -1660,7 +1684,19 @@ IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas);
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);
// Test engine hooks (imgui-test) // Debug Tools
// Use 'Metrics->Tools->Item Picker' to break into the call-stack of a specific item.
#ifndef IM_DEBUG_BREAK
#if defined(__clang__)
#define IM_DEBUG_BREAK() __builtin_debugtrap()
#elif defined (_MSC_VER)
#define IM_DEBUG_BREAK() __debugbreak()
#else
#define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger!
#endif
#endif // #ifndef IM_DEBUG_BREAK
// Test Engine Hooks (imgui_tests)
//#define IMGUI_ENABLE_TEST_ENGINE //#define IMGUI_ENABLE_TEST_ENGINE
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx); extern void ImGuiTestEngineHook_PreNewFrame(ImGuiContext* ctx);

View File

@ -1,4 +1,4 @@
// dear imgui, v1.71 // dear imgui, v1.72
// (widgets code) // (widgets code)
/* /*
@ -24,6 +24,7 @@ Index of this file:
// [SECTION] Widgets: MenuItem, BeginMenu, EndMenu, etc. // [SECTION] Widgets: MenuItem, BeginMenu, EndMenu, etc.
// [SECTION] Widgets: BeginTabBar, EndTabBar, etc. // [SECTION] Widgets: BeginTabBar, EndTabBar, etc.
// [SECTION] Widgets: BeginTabItem, EndTabItem, etc. // [SECTION] Widgets: BeginTabItem, EndTabItem, etc.
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
*/ */
@ -63,10 +64,9 @@ Index of this file:
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
#endif #endif
#elif defined(__GNUC__) #elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
#if __GNUC__ >= 8 #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#pragma GCC diagnostic ignored "-Wclass-memaccess" // warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -626,8 +626,6 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
flags |= ImGuiButtonFlags_Repeat; flags |= ImGuiButtonFlags_Repeat;
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
if (pressed)
MarkItemEdited(id);
// Render // Render
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
@ -896,13 +894,13 @@ void ImGui::Scrollbar(ImGuiAxis axis)
ImRect bb; ImRect bb;
if (axis == ImGuiAxis_X) if (axis == ImGuiAxis_X)
{ {
bb.Min = ImVec2(inner_rect.Min.x, outer_rect.Max.y - border_size - scrollbar_size); bb.Min = ImVec2(inner_rect.Min.x, ImMax(outer_rect.Min.y, outer_rect.Max.y - border_size - scrollbar_size));
bb.Max = ImVec2(inner_rect.Max.x, outer_rect.Max.y); bb.Max = ImVec2(inner_rect.Max.x, outer_rect.Max.y);
rounding_corners |= ImDrawCornerFlags_BotLeft; rounding_corners |= ImDrawCornerFlags_BotLeft;
} }
else else
{ {
bb.Min = ImVec2(outer_rect.Max.x - border_size - scrollbar_size, inner_rect.Min.y); bb.Min = ImVec2(ImMax(outer_rect.Min.x, outer_rect.Max.x - border_size - scrollbar_size), inner_rect.Min.y);
bb.Max = ImVec2(outer_rect.Max.x, window->InnerRect.Max.y); bb.Max = ImVec2(outer_rect.Max.x, window->InnerRect.Max.y);
rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0; rounding_corners |= ((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0;
} }
@ -1002,10 +1000,17 @@ bool ImGui::Checkbox(const char* label, bool* v)
const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz)); const ImRect check_bb(pos, pos + ImVec2(square_sz, square_sz));
RenderNavHighlight(total_bb, id); RenderNavHighlight(total_bb, id);
RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding);
if (*v) ImU32 check_col = GetColorU32(ImGuiCol_CheckMark);
if (window->DC.ItemFlags & ImGuiItemFlags_MixedValue)
{
// Undocumented tristate/mixed/indeterminate checkbox (#2644)
ImVec2 pad(ImMax(1.0f, (float)(int)(square_sz / 3.6f)), ImMax(1.0f, (float)(int)(square_sz / 3.6f)));
window->DrawList->AddRectFilled(check_bb.Min + pad, check_bb.Max - pad, check_col, style.FrameRounding);
}
else if (*v)
{ {
const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f)); const float pad = ImMax(1.0f, (float)(int)(square_sz / 6.0f));
RenderCheckMark(check_bb.Min + ImVec2(pad, pad), GetColorU32(ImGuiCol_CheckMark), square_sz - pad*2.0f); RenderCheckMark(check_bb.Min + ImVec2(pad, pad), check_col, square_sz - pad*2.0f);
} }
if (g.LogEnabled) if (g.LogEnabled)
@ -1083,6 +1088,7 @@ bool ImGui::RadioButton(const char* label, bool active)
return pressed; return pressed;
} }
// FIXME: This would work nicely if it was a public template, e.g. 'template<T> RadioButton(const char* label, T* v, T v_button)', but I'm not sure how we would expose it..
bool ImGui::RadioButton(const char* label, int* v, int v_button) bool ImGui::RadioButton(const char* label, int* v, int v_button)
{ {
const bool pressed = RadioButton(label, *v == v_button); const bool pressed = RadioButton(label, *v == v_button);
@ -1426,7 +1432,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button); ImU32 bg_col = GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
ImU32 text_col = GetColorU32(ImGuiCol_Text); ImU32 text_col = GetColorU32(ImGuiCol_Text);
window->DrawList->AddRectFilled(ImVec2(value_x2, frame_bb.Min.y), frame_bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); window->DrawList->AddRectFilled(ImVec2(value_x2, frame_bb.Min.y), frame_bb.Max, bg_col, style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right);
RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down); if (value_x2 + arrow_size - style.FramePadding.x <= frame_bb.Max.x)
RenderArrow(window->DrawList, ImVec2(value_x2 + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), text_col, ImGuiDir_Down, 1.0f);
} }
RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding); RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding);
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
@ -3631,8 +3638,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Home)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } else if (IsKeyPressedMap(ImGuiKey_End)) { state->OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } else if (IsKeyPressedMap(ImGuiKey_Delete) && !is_readonly) { state->OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); }
@ -3647,7 +3654,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
} }
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
} }
else if (IsKeyPressedMap(ImGuiKey_Enter)) else if (IsKeyPressedMap(ImGuiKey_Enter) || IsKeyPressedMap(ImGuiKey_KeyPadEnter))
{ {
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
@ -3987,9 +3994,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize);
else if (cursor_offset.y - size.y >= scroll_y) else if (cursor_offset.y - size.y >= scroll_y)
scroll_y = cursor_offset.y - size.y; scroll_y = cursor_offset.y - size.y;
draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag draw_pos.y += (draw_window->Scroll.y - scroll_y); // Manipulate cursor pos immediately avoid a frame of lag
draw_window->Scroll.y = scroll_y; draw_window->Scroll.y = scroll_y;
draw_pos.y = draw_window->DC.CursorPos.y;
} }
state->CursorFollow = false; state->CursorFollow = false;
@ -4130,8 +4136,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
const float square_sz = GetFrameHeight(); const float square_sz = GetFrameHeight();
const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); const float w_full = CalcItemWidth();
const float w_items_all = CalcItemWidth() - w_extra; const float w_button = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x);
const float w_inputs = w_full - w_button;
const char* label_display_end = FindRenderedTextEnd(label); const char* label_display_end = FindRenderedTextEnd(label);
g.NextItemData.ClearFlags(); g.NextItemData.ClearFlags();
@ -4175,11 +4182,15 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
bool value_changed = false; bool value_changed = false;
bool value_changed_as_float = false; bool value_changed_as_float = false;
const ImVec2 pos = window->DC.CursorPos;
const float inputs_offset_x = (style.ColorButtonPosition == ImGuiDir_Left) ? w_button : 0.0f;
window->DC.CursorPos.x = pos.x + inputs_offset_x;
if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) if ((flags & (ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_DisplayHSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0)
{ {
// RGB/HSV 0..255 Sliders // RGB/HSV 0..255 Sliders
const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); const float w_item_one = ImMax(1.0f, (float)(int)((w_inputs - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); const float w_item_last = ImMax(1.0f, (float)(int)(w_inputs - (w_item_one + style.ItemInnerSpacing.x) * (components-1)));
const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x);
static const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; static const char* ids[4] = { "##X", "##Y", "##Z", "##W" };
@ -4223,7 +4234,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255), ImClamp(i[3],0,255)); ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255), ImClamp(i[3],0,255));
else else
ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255)); ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255));
SetNextItemWidth(w_items_all); SetNextItemWidth(w_inputs);
if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase))
{ {
value_changed = true; value_changed = true;
@ -4243,8 +4254,8 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
ImGuiWindow* picker_active_window = NULL; ImGuiWindow* picker_active_window = NULL;
if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) if (!(flags & ImGuiColorEditFlags_NoSmallPreview))
{ {
if (!(flags & ImGuiColorEditFlags_NoInputs)) const float button_offset_x = ((flags & ImGuiColorEditFlags_NoInputs) || (style.ColorButtonPosition == ImGuiDir_Left)) ? 0.0f : w_inputs + style.ItemInnerSpacing.x;
SameLine(0, style.ItemInnerSpacing.x); window->DC.CursorPos = ImVec2(pos.x + button_offset_x, pos.y);
const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f);
if (ColorButton("##ColorButton", col_v4, flags)) if (ColorButton("##ColorButton", col_v4, flags))
@ -4278,7 +4289,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel))
{ {
SameLine(0, style.ItemInnerSpacing.x); window->DC.CursorPos = ImVec2(pos.x + w_full + style.ItemInnerSpacing.x, pos.y + style.FramePadding.y);
TextEx(label, label_display_end); TextEx(label, label_display_end);
} }
@ -4827,9 +4838,6 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered)
ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags__InputMask | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags__InputMask | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf));
if (pressed)
MarkItemEdited(id);
return pressed; return pressed;
} }
@ -4983,7 +4991,6 @@ void ImGui::ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags fl
// - TreeNodeBehavior() [Internal] // - TreeNodeBehavior() [Internal]
// - TreePush() // - TreePush()
// - TreePop() // - TreePop()
// - TreeAdvanceToLabelPos()
// - GetTreeNodeToLabelSpacing() // - GetTreeNodeToLabelSpacing()
// - SetNextItemOpen() // - SetNextItemOpen()
// - CollapsingHeader() // - CollapsingHeader()
@ -5231,13 +5238,13 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection; window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
// Render // Render
const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
const ImU32 text_col = GetColorU32(ImGuiCol_Text); const ImU32 text_col = GetColorU32(ImGuiCol_Text);
const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y); const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y);
ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_TypeThin; ImGuiNavHighlightFlags nav_highlight_flags = ImGuiNavHighlightFlags_TypeThin;
if (display_frame) if (display_frame)
{ {
// Framed type // Framed type
const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding); RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, true, style.FrameRounding);
RenderNavHighlight(frame_bb, id, nav_highlight_flags); RenderNavHighlight(frame_bb, id, nav_highlight_flags);
RenderArrow(window->DrawList, frame_bb.Min + ImVec2(padding.x, text_base_offset_y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); RenderArrow(window->DrawList, frame_bb.Min + ImVec2(padding.x, text_base_offset_y), text_col, is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
@ -5262,6 +5269,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
// Unframed typed for tree nodes // Unframed typed for tree nodes
if (hovered || selected) if (hovered || selected)
{ {
const ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false); RenderFrame(frame_bb.Min, frame_bb.Max, bg_col, false);
RenderNavHighlight(frame_bb, id, nav_highlight_flags); RenderNavHighlight(frame_bb, id, nav_highlight_flags);
} }
@ -5324,12 +5332,6 @@ void ImGui::TreePop()
PopID(); PopID();
} }
void ImGui::TreeAdvanceToLabelPos()
{
ImGuiContext& g = *GImGui;
g.CurrentWindow->DC.CursorPos.x += GetTreeNodeToLabelSpacing();
}
// Horizontal distance preceding label when using TreeNode() or Bullet() // Horizontal distance preceding label when using TreeNode() or Bullet()
float ImGui::GetTreeNodeToLabelSpacing() float ImGui::GetTreeNodeToLabelSpacing()
{ {
@ -5488,6 +5490,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection; window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_ToggledSelection;
// Render // Render
if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld))
hovered = true;
if (hovered || selected) if (hovered || selected)
{ {
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
@ -5931,6 +5935,10 @@ void ImGui::EndMainMenuBar()
End(); End();
} }
// FIXME: Provided a rectangle perhaps e.g. a BeginMenuBarEx() could be used anywhere..
// Currently the main responsibility of this function being to setup clip-rect + horizontal layout + menu navigation layer.
// Ideally we also want this to be responsible for claiming space out of the main window scrolling rectangle, in which case ImGuiWindowFlags_MenuBar will become unnecessary.
// Then later the same system could be used for multiple menu-bars, scrollbars, side-bars.
bool ImGui::BeginMenuBar() bool ImGui::BeginMenuBar()
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -5940,7 +5948,7 @@ bool ImGui::BeginMenuBar()
return false; return false;
IM_ASSERT(!window->DC.MenuBarAppending); IM_ASSERT(!window->DC.MenuBarAppending);
BeginGroup(); // Backup position on layer 0 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.
@ -6269,18 +6277,18 @@ static int IMGUI_CDECL TabItemComparerByVisibleOffset(const void* lhs, const voi
return (int)(a->Offset - b->Offset); return (int)(a->Offset - b->Offset);
} }
static ImGuiTabBar* GetTabBarFromTabBarRef(const ImGuiTabBarRef& ref) static ImGuiTabBar* GetTabBarFromTabBarRef(const ImGuiPtrOrIndex& ref)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
return ref.Ptr ? ref.Ptr : g.TabBars.GetByIndex(ref.IndexInMainPool); return ref.Ptr ? (ImGuiTabBar*)ref.Ptr : g.TabBars.GetByIndex(ref.Index);
} }
static ImGuiTabBarRef GetTabBarRefFromTabBar(ImGuiTabBar* tab_bar) static ImGuiPtrOrIndex GetTabBarRefFromTabBar(ImGuiTabBar* tab_bar)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.TabBars.Contains(tab_bar)) if (g.TabBars.Contains(tab_bar))
return ImGuiTabBarRef(g.TabBars.GetIndex(tab_bar)); return ImGuiPtrOrIndex(g.TabBars.GetIndex(tab_bar));
return ImGuiTabBarRef(tab_bar); return ImGuiPtrOrIndex(tab_bar);
} }
bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags)
@ -6339,7 +6347,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
window->DC.CursorPos.x = tab_bar->BarRect.Min.x; window->DC.CursorPos.x = tab_bar->BarRect.Min.x;
// Draw separator // Draw separator
const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_Tab); const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive);
const float y = tab_bar->BarRect.Max.y - 1.0f; const float y = tab_bar->BarRect.Max.y - 1.0f;
{ {
const float separator_min_x = tab_bar->BarRect.Min.x - ImFloor(window->WindowPadding.x * 0.5f); const float separator_min_x = tab_bar->BarRect.Min.x - ImFloor(window->WindowPadding.x * 0.5f);
@ -6635,7 +6643,7 @@ void ImGui::TabBarQueueChangeTabOrder(ImGuiTabBar* tab_bar, const ImGuiTabItem*
IM_ASSERT(dir == -1 || dir == +1); IM_ASSERT(dir == -1 || dir == +1);
IM_ASSERT(tab_bar->ReorderRequestTabId == 0); IM_ASSERT(tab_bar->ReorderRequestTabId == 0);
tab_bar->ReorderRequestTabId = tab->ID; tab_bar->ReorderRequestTabId = tab->ID;
tab_bar->ReorderRequestDir = dir; tab_bar->ReorderRequestDir = (ImS8)dir;
} }
static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar) static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar)
@ -7082,3 +7090,425 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
return close_button_pressed; return close_button_pressed;
} }
//-------------------------------------------------------------------------
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
//-------------------------------------------------------------------------
// - GetColumnIndex()
// - GetColumnCount()
// - GetColumnOffset()
// - GetColumnWidth()
// - SetColumnOffset()
// - SetColumnWidth()
// - PushColumnClipRect() [Internal]
// - PushColumnsBackground() [Internal]
// - PopColumnsBackground() [Internal]
// - FindOrCreateColumns() [Internal]
// - GetColumnsID() [Internal]
// - BeginColumns()
// - NextColumn()
// - EndColumns()
// - Columns()
//-------------------------------------------------------------------------
int ImGui::GetColumnIndex()
{
ImGuiWindow* window = GetCurrentWindowRead();
return window->DC.CurrentColumns ? window->DC.CurrentColumns->Current : 0;
}
int ImGui::GetColumnsCount()
{
ImGuiWindow* window = GetCurrentWindowRead();
return window->DC.CurrentColumns ? window->DC.CurrentColumns->Count : 1;
}
float ImGui::GetColumnOffsetFromNorm(const ImGuiColumns* columns, float offset_norm)
{
return offset_norm * (columns->OffMaxX - columns->OffMinX);
}
float ImGui::GetColumnNormFromOffset(const ImGuiColumns* columns, float offset)
{
return offset / (columns->OffMaxX - columns->OffMinX);
}
static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f;
static float GetDraggedColumnOffset(ImGuiColumns* columns, int column_index)
{
// Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing
// window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning.
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(column_index > 0); // We are not supposed to drag column 0.
IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index));
float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x;
x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing);
if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths))
x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing);
return x;
}
float ImGui::GetColumnOffset(int column_index)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns == NULL)
return 0.0f;
if (column_index < 0)
column_index = columns->Current;
IM_ASSERT(column_index < columns->Columns.Size);
const float t = columns->Columns[column_index].OffsetNorm;
const float x_offset = ImLerp(columns->OffMinX, columns->OffMaxX, t);
return x_offset;
}
static float GetColumnWidthEx(ImGuiColumns* columns, int column_index, bool before_resize = false)
{
if (column_index < 0)
column_index = columns->Current;
float offset_norm;
if (before_resize)
offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize;
else
offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm;
return ImGui::GetColumnOffsetFromNorm(columns, offset_norm);
}
float ImGui::GetColumnWidth(int column_index)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns == NULL)
return GetContentRegionAvail().x;
if (column_index < 0)
column_index = columns->Current;
return GetColumnOffsetFromNorm(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm);
}
void ImGui::SetColumnOffset(int column_index, float offset)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
if (column_index < 0)
column_index = columns->Current;
IM_ASSERT(column_index < columns->Columns.Size);
const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1);
const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f;
if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow))
offset = ImMin(offset, columns->OffMaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index));
columns->Columns[column_index].OffsetNorm = GetColumnNormFromOffset(columns, offset - columns->OffMinX);
if (preserve_width)
SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width));
}
void ImGui::SetColumnWidth(int column_index, float width)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
if (column_index < 0)
column_index = columns->Current;
SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width);
}
void ImGui::PushColumnClipRect(int column_index)
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
if (column_index < 0)
column_index = columns->Current;
ImGuiColumnData* column = &columns->Columns[column_index];
PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false);
}
// Get into the columns background draw command (which is generally the same draw command as before we called BeginColumns)
void ImGui::PushColumnsBackground()
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
window->DrawList->ChannelsSetCurrent(0);
int cmd_size = window->DrawList->CmdBuffer.Size;
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
IM_UNUSED(cmd_size);
IM_ASSERT(cmd_size == window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
}
void ImGui::PopColumnsBackground()
{
ImGuiWindow* window = GetCurrentWindowRead();
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
return;
window->DrawList->ChannelsSetCurrent(columns->Current + 1);
PopClipRect();
}
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
{
// We have few columns per window so for now we don't need bother much with turning this into a faster lookup.
for (int n = 0; n < window->ColumnsStorage.Size; n++)
if (window->ColumnsStorage[n].ID == id)
return &window->ColumnsStorage[n];
window->ColumnsStorage.push_back(ImGuiColumns());
ImGuiColumns* columns = &window->ColumnsStorage.back();
columns->ID = id;
return columns;
}
ImGuiID ImGui::GetColumnsID(const char* str_id, int columns_count)
{
ImGuiWindow* window = GetCurrentWindow();
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
// In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer.
PushID(0x11223347 + (str_id ? 0 : columns_count));
ImGuiID id = window->GetID(str_id ? str_id : "columns");
PopID();
return id;
}
void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1);
IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported
// Acquire storage for the columns set
ImGuiID id = GetColumnsID(str_id, columns_count);
ImGuiColumns* columns = FindOrCreateColumns(window, id);
IM_ASSERT(columns->ID == id);
columns->Current = 0;
columns->Count = columns_count;
columns->Flags = flags;
window->DC.CurrentColumns = columns;
columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostClipRect = window->ClipRect;
columns->HostWorkRect = window->WorkRect;
// Set state for first column
// We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
const float column_padding = g.Style.ItemSpacing.x;
const float half_clip_extend_x = ImFloor(ImMax(window->WindowPadding.x * 0.5f, window->WindowBorderSize));
const float max_1 = window->WorkRect.Max.x + column_padding - ImMax(column_padding - window->WindowPadding.x, 0.0f);
const float max_2 = window->WorkRect.Max.x + half_clip_extend_x;
columns->OffMinX = window->DC.Indent.x - column_padding + ImMax(column_padding - window->WindowPadding.x, 0.0f);
columns->OffMaxX = ImMax(ImMin(max_1, max_2) - window->Pos.x, columns->OffMinX + 1.0f);
columns->LineMinY = columns->LineMaxY = window->DC.CursorPos.y;
// Clear data if columns count changed
if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1)
columns->Columns.resize(0);
// Initialize default widths
columns->IsFirstFrame = (columns->Columns.Size == 0);
if (columns->Columns.Size == 0)
{
columns->Columns.reserve(columns_count + 1);
for (int n = 0; n < columns_count + 1; n++)
{
ImGuiColumnData column;
column.OffsetNorm = n / (float)columns_count;
columns->Columns.push_back(column);
}
}
for (int n = 0; n < columns_count; n++)
{
// Compute clipping rectangle
ImGuiColumnData* column = &columns->Columns[n];
float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n));
float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f);
column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX);
column->ClipRect.ClipWith(window->ClipRect);
}
if (columns->Count > 1)
{
window->DrawList->ChannelsSplit(1 + columns->Count);
window->DrawList->ChannelsSetCurrent(1);
PushColumnClipRect(0);
}
// We don't generally store Indent.x inside ColumnsOffset because it may be manipulated by the user.
float offset_0 = GetColumnOffset(columns->Current);
float offset_1 = GetColumnOffset(columns->Current + 1);
float width = offset_1 - offset_0;
PushItemWidth(width * 0.65f);
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
}
void ImGui::NextColumn()
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems || window->DC.CurrentColumns == NULL)
return;
ImGuiContext& g = *GImGui;
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns->Count == 1)
{
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
IM_ASSERT(columns->Current == 0);
return;
}
PopItemWidth();
PopClipRect();
const float column_padding = g.Style.ItemSpacing.x;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
if (++columns->Current < columns->Count)
{
// Columns 1+ ignore IndentX (by canceling it out)
// FIXME-COLUMNS: Unnecessary, could be locked?
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
window->DrawList->ChannelsSetCurrent(columns->Current + 1);
}
else
{
// New row/line
// Column 0 honor IndentX
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
window->DrawList->ChannelsSetCurrent(1);
columns->Current = 0;
columns->LineMinY = columns->LineMaxY;
}
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
window->DC.CursorPos.y = columns->LineMinY;
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
window->DC.CurrLineTextBaseOffset = 0.0f;
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
float offset_0 = GetColumnOffset(columns->Current);
float offset_1 = GetColumnOffset(columns->Current + 1);
float width = offset_1 - offset_0;
PushItemWidth(width * 0.65f);
window->WorkRect.Max.x = window->Pos.x + offset_1 - column_padding;
}
void ImGui::EndColumns()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow();
ImGuiColumns* columns = window->DC.CurrentColumns;
IM_ASSERT(columns != NULL);
PopItemWidth();
if (columns->Count > 1)
{
PopClipRect();
window->DrawList->ChannelsMerge();
}
const ImGuiColumnsFlags flags = columns->Flags;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
window->DC.CursorPos.y = columns->LineMaxY;
if (!(flags & ImGuiColumnsFlags_GrowParentContentsSize))
window->DC.CursorMaxPos.x = columns->HostCursorMaxPosX; // Restore cursor max pos, as columns don't grow parent
// Draw columns borders and handle resize
// The IsBeingResized flag ensure we preserve pre-resize columns width so back-and-forth are not lossy
bool is_being_resized = false;
if (!(flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems)
{
// We clip Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.
const float y1 = ImMax(columns->HostCursorPosY, window->ClipRect.Min.y);
const float y2 = ImMin(window->DC.CursorPos.y, window->ClipRect.Max.y);
int dragging_column = -1;
for (int n = 1; n < columns->Count; n++)
{
ImGuiColumnData* column = &columns->Columns[n];
float x = window->Pos.x + GetColumnOffset(n);
const ImGuiID column_id = columns->ID + ImGuiID(n);
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
KeepAliveID(column_id);
if (IsClippedEx(column_hit_rect, column_id, false))
continue;
bool hovered = false, held = false;
if (!(flags & ImGuiColumnsFlags_NoResize))
{
ButtonBehavior(column_hit_rect, column_id, &hovered, &held);
if (hovered || held)
g.MouseCursor = ImGuiMouseCursor_ResizeEW;
if (held && !(column->Flags & ImGuiColumnsFlags_NoResize))
dragging_column = n;
}
// Draw column
const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
const float xi = (float)(int)x;
window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col);
}
// Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame.
if (dragging_column != -1)
{
if (!columns->IsBeingResized)
for (int n = 0; n < columns->Count + 1; n++)
columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm;
columns->IsBeingResized = is_being_resized = true;
float x = GetDraggedColumnOffset(columns, dragging_column);
SetColumnOffset(dragging_column, x);
}
}
columns->IsBeingResized = is_being_resized;
window->WorkRect = columns->HostWorkRect;
window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
}
// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing]
void ImGui::Columns(int columns_count, const char* id, bool border)
{
ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count >= 1);
ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder);
//flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior
ImGuiColumns* columns = window->DC.CurrentColumns;
if (columns != NULL && columns->Count == columns_count && columns->Flags == flags)
return;
if (columns != NULL)
EndColumns();
if (columns_count != 1)
BeginColumns(id, columns_count, flags);
}
//-------------------------------------------------------------------------

View File

@ -36,6 +36,7 @@
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#endif #endif
@ -645,7 +646,8 @@ static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size
bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags) bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags)
{ {
// FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html // FreeType memory management: https://www.freetype.org/freetype2/docs/design/design-4.html
FT_MemoryRec_ memory_rec = { 0 }; FT_MemoryRec_ memory_rec = {};
memory_rec.user = NULL;
memory_rec.alloc = &FreeType_Alloc; memory_rec.alloc = &FreeType_Alloc;
memory_rec.free = &FreeType_Free; memory_rec.free = &FreeType_Free;
memory_rec.realloc = &FreeType_Realloc; memory_rec.realloc = &FreeType_Realloc;

View File

@ -15,6 +15,7 @@
// 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)
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
// 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter(). // 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter().
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized. // 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
@ -151,6 +152,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE; io.KeyMap[ImGuiKey_Space] = GLFW_KEY_SPACE;
io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER;
io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE;
io.KeyMap[ImGuiKey_KeyPadEnter] = GLFW_KEY_KP_ENTER;
io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; io.KeyMap[ImGuiKey_A] = GLFW_KEY_A;
io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; io.KeyMap[ImGuiKey_C] = GLFW_KEY_C;
io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; io.KeyMap[ImGuiKey_V] = GLFW_KEY_V;

View File

@ -77,7 +77,7 @@
// Auto-detect GL version // Auto-detect GL version
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && TARGET_OS_IOS) || (defined(__ANDROID__)) #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
#elif defined(__EMSCRIPTEN__) #elif defined(__EMSCRIPTEN__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
@ -87,7 +87,11 @@
#if defined(IMGUI_IMPL_OPENGL_ES2) #if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#elif defined(IMGUI_IMPL_OPENGL_ES3) #elif defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
#include <OpenGLES/ES3/gl.h> // Use GL ES 3
#else
#include <GLES3/gl3.h> // Use GL ES 3 #include <GLES3/gl3.h> // Use GL ES 3
#endif
#else #else
// About Desktop OpenGL function loaders: // About Desktop OpenGL function loaders:
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.