Update ImGui to 1.89.2 + docking.

This commit is contained in:
Bartosz Taudul 2023-01-05 19:15:58 +01:00
parent 04a428ab29
commit 096293110b
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
13 changed files with 1401 additions and 1086 deletions

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2014-2022 Omar Cornut Copyright (c) 2014-2023 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (headers) // (headers)
// Help: // Help:
@ -22,8 +22,8 @@
// Library Version // Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
#define IMGUI_VERSION "1.89 WIP" #define IMGUI_VERSION "1.89.2"
#define IMGUI_VERSION_NUM 18837 #define IMGUI_VERSION_NUM 18920
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch #define IMGUI_HAS_DOCK // Docking WIP branch
@ -177,7 +177,7 @@ typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A
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 ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle) typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle)
typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor identifier typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor shape
typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending) typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending)
typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling
typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor() typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor()
@ -261,8 +261,8 @@ struct ImVec2
float x, y; float x, y;
constexpr ImVec2() : x(0.0f), y(0.0f) { } constexpr ImVec2() : x(0.0f), y(0.0f) { }
constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { } constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { }
float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine.
#ifdef IM_VEC2_CLASS_EXTRA #ifdef IM_VEC2_CLASS_EXTRA
IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2.
#endif #endif
@ -370,6 +370,7 @@ namespace ImGui
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 / top-most. call before Begin() IMGUI_API void SetNextWindowFocus(); // set next window to be focused / top-most. call before Begin()
IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // set next window scrolling value (use < 0.0f to not affect a given axis).
IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily override the Alpha component of 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 override the Alpha component of ImGuiCol_WindowBg/ChildBg/PopupBg. you may also use ImGuiWindowFlags_NoBackground.
IMGUI_API void SetNextWindowViewport(ImGuiID viewport_id); // set next window viewport IMGUI_API void SetNextWindowViewport(ImGuiID viewport_id); // set next window viewport
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.
@ -391,6 +392,8 @@ namespace ImGui
IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be overridden with SetNextWindowContentSize(), in window coordinates IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be overridden with SetNextWindowContentSize(), in window coordinates
// Windows Scrolling // Windows Scrolling
// - Any change of Scroll will be applied at the beginning of next frame in the first call to Begin().
// - You may instead use SetNextWindowScroll() prior to calling Begin() to avoid this delay, as an alternative to using SetScrollX()/SetScrollY().
IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()] IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()]
IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()] IMGUI_API float GetScrollY(); // get scrolling amount [0 .. GetScrollMaxY()]
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()] IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0 .. GetScrollMaxX()]
@ -425,7 +428,7 @@ namespace ImGui
IMGUI_API void PopTextWrapPos(); IMGUI_API void PopTextWrapPos();
// Style read access // Style read access
// - Use the style editor (ShowStyleEditor() function) to interactively see what the colors are) // - Use the ShowStyleEditor() function to interactively see/edit the colors.
IMGUI_API ImFont* GetFont(); // get current font IMGUI_API ImFont* GetFont(); // get current font
IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied
IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API
@ -788,7 +791,7 @@ namespace ImGui
IMGUI_API int GetColumnsCount(); IMGUI_API int GetColumnsCount();
// Tab Bars, Tabs // Tab Bars, Tabs
// Note: Tabs are automatically created by the docking system. Use this to create tab bars/tabs yourself without docking being involved. // - Note: Tabs are automatically created by the docking system (when in 'docking' branch). Use this to create tab bars/tabs yourself.
IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar IMGUI_API bool BeginTabBar(const char* str_id, ImGuiTabBarFlags flags = 0); // create and append into a TabBar
IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true! IMGUI_API void EndTabBar(); // only call EndTabBar() if BeginTabBar() returns true!
IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected. IMGUI_API bool BeginTabItem(const char* label, bool* p_open = NULL, ImGuiTabItemFlags flags = 0); // create a Tab. Returns true if the Tab is selected.
@ -872,6 +875,7 @@ namespace ImGui
IMGUI_API bool IsAnyItemHovered(); // is any item hovered? IMGUI_API bool IsAnyItemHovered(); // is any item hovered?
IMGUI_API bool IsAnyItemActive(); // is any item active? IMGUI_API bool IsAnyItemActive(); // is any item active?
IMGUI_API bool IsAnyItemFocused(); // is any item focused? IMGUI_API bool IsAnyItemFocused(); // is any item focused?
IMGUI_API ImGuiID GetItemID(); // get ID of last item (~~ often same ImGui::GetID(label) beforehand)
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
@ -910,12 +914,11 @@ namespace ImGui
IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v);
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b);
// Inputs Utilities: Keyboard // Inputs Utilities: Keyboard/Mouse/Gamepad
// Without IMGUI_DISABLE_OBSOLETE_KEYIO: (legacy support) // - the ImGuiKey enum contains all possible keyboard, mouse and gamepad inputs (e.g. ImGuiKey_A, ImGuiKey_MouseLeft, ImGuiKey_GamepadDpadUp...).
// - For 'ImGuiKey key' you can still use your legacy native/user indices according to how your backend/engine stored them in io.KeysDown[]. // - before v1.87, we used ImGuiKey to carry native/user indices as defined by each backends. About use of those legacy ImGuiKey values:
// With IMGUI_DISABLE_OBSOLETE_KEYIO: (this is the way forward) // - without IMGUI_DISABLE_OBSOLETE_KEYIO (legacy support): you can still use your legacy native/user indices (< 512) according to how your backend/engine stored them in io.KeysDown[], but need to cast them to ImGuiKey.
// - Any use of 'ImGuiKey' will assert when key < 512 will be passed, previously reserved as native/user keys indices // - with IMGUI_DISABLE_OBSOLETE_KEYIO (this is the way forward): any use of ImGuiKey will assert with key < 512. GetKeyIndex() is pass-through and therefore deprecated (gone if IMGUI_DISABLE_OBSOLETE_KEYIO is defined).
// - GetKeyIndex() is pass-through and therefore deprecated (gone if IMGUI_DISABLE_OBSOLETE_KEYIO is defined)
IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held. IMGUI_API bool IsKeyDown(ImGuiKey key); // is key being held.
IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate IMGUI_API bool IsKeyPressed(ImGuiKey key, bool repeat = true); // was key pressed (went from !Down to Down)? if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate
IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)? IMGUI_API bool IsKeyReleased(ImGuiKey key); // was key released (went from Down to !Down)?
@ -923,7 +926,7 @@ namespace ImGui
IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared.
IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call. IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call.
// Inputs Utilities: Mouse // Inputs Utilities: Mouse specific
// - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right.
// - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle.
// - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold') // - Dragging operations are only reported after mouse has moved a certain distance away from the initial clicking position (see 'lock_threshold' and 'io.MouseDraggingThreshold')
@ -940,8 +943,8 @@ namespace ImGui
IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)
IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold)
IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); // IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); //
IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired mouse cursor shape. Important: reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you
IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired cursor type IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired mouse cursor shape
IMGUI_API void SetNextFrameWantCaptureMouse(bool want_capture_mouse); // Override io.WantCaptureMouse flag next frame (said flag is left for your application to handle, typical when true it instucts your app to ignore inputs). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse;" after the next NewFrame() call. IMGUI_API void SetNextFrameWantCaptureMouse(bool want_capture_mouse); // Override io.WantCaptureMouse flag next frame (said flag is left for your application to handle, typical when true it instucts your app to ignore inputs). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse;" after the next NewFrame() call.
// Clipboard Utilities // Clipboard Utilities
@ -1053,7 +1056,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input)
ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active)
ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (constrast to default behavior of Escape to revert) ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert)
// Obsolete names (will be removed soon) // Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@ -1352,7 +1355,7 @@ enum ImGuiDragDropFlags_
{ {
ImGuiDragDropFlags_None = 0, ImGuiDragDropFlags_None = 0,
// BeginDragDropSource() flags // BeginDragDropSource() flags
ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disables this behavior. ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // Disable preview tooltip. By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disables this behavior.
ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return false, to avoid subsequent user code submitting tooltips. This flag disables this behavior so you can still call IsItemHovered() on the source item. ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return false, to avoid subsequent user code submitting tooltips. This flag disables this behavior so you can still call IsItemHovered() on the source item.
ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item.
ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit.
@ -1404,9 +1407,10 @@ enum ImGuiSortDirection_
ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc. ImGuiSortDirection_Descending = 2 // Descending = 9->0, Z->A etc.
}; };
// A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value) // A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value): can represent Keyboard, Mouse and Gamepad values.
// All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87) // All our named keys are >= 512. Keys value 0 to 511 are left unused as legacy native/opaque key values (< 1.87).
// Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey. // Since >= 1.89 we increased typing (went from int to enum), some legacy code may need a cast to ImGuiKey.
// Read details about the 1.87 and 1.89 transition : https://github.com/ocornut/imgui/issues/4921
enum ImGuiKey : int enum ImGuiKey : int
{ {
// Keyboard // Keyboard
@ -1461,7 +1465,7 @@ enum ImGuiKey : int
ImGuiKey_KeypadEnter, ImGuiKey_KeypadEnter,
ImGuiKey_KeypadEqual, ImGuiKey_KeypadEqual,
// Gamepad (some of those are analog values, 0.0f to 1.0f) // GAME NAVIGATION ACTION // Gamepad (some of those are analog values, 0.0f to 1.0f) // NAVIGATION ACTION
// (download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets) // (download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets)
ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS) ImGuiKey_GamepadStart, // Menu (Xbox) + (Switch) Start/Options (PS)
ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS) ImGuiKey_GamepadBack, // View (Xbox) - (Switch) Share (PS)
@ -1488,7 +1492,7 @@ enum ImGuiKey : int
ImGuiKey_GamepadRStickUp, // [Analog] ImGuiKey_GamepadRStickUp, // [Analog]
ImGuiKey_GamepadRStickDown, // [Analog] ImGuiKey_GamepadRStickDown, // [Analog]
// Mouse Buttons (auto-submitted from AddMouseButtonEvent() calls) // Aliases: Mouse Buttons (auto-submitted from AddMouseButtonEvent() calls)
// - This is mirroring the data also written to io.MouseDown[], io.MouseWheel, in a format allowing them to be accessed via standard key API. // - This is mirroring the data also written to io.MouseDown[], io.MouseWheel, in a format allowing them to be accessed via standard key API.
ImGuiKey_MouseLeft, ImGuiKey_MouseRight, ImGuiKey_MouseMiddle, ImGuiKey_MouseX1, ImGuiKey_MouseX2, ImGuiKey_MouseWheelX, ImGuiKey_MouseWheelY, ImGuiKey_MouseLeft, ImGuiKey_MouseRight, ImGuiKey_MouseMiddle, ImGuiKey_MouseX1, ImGuiKey_MouseX2, ImGuiKey_MouseWheelX, ImGuiKey_MouseWheelY,
@ -1505,16 +1509,12 @@ enum ImGuiKey : int
// In practice: it's complicated; mods are often provided from different sources. Keyboard layout, IME, sticky keys and // In practice: it's complicated; mods are often provided from different sources. Keyboard layout, IME, sticky keys and
// backends tend to interfere and break that equivalence. The safer decision is to relay that ambiguity down to the end-user... // backends tend to interfere and break that equivalence. The safer decision is to relay that ambiguity down to the end-user...
ImGuiMod_None = 0, ImGuiMod_None = 0,
ImGuiMod_Ctrl = 1 << 12, ImGuiMod_Ctrl = 1 << 12, // Ctrl
ImGuiMod_Shift = 1 << 13, ImGuiMod_Shift = 1 << 13, // Shift
ImGuiMod_Alt = 1 << 14, // Option/Menu ImGuiMod_Alt = 1 << 14, // Option/Menu
ImGuiMod_Super = 1 << 15, // Cmd/Super/Windows ImGuiMod_Super = 1 << 15, // Cmd/Super/Windows
ImGuiMod_Mask_ = 0xF000, ImGuiMod_Shortcut = 1 << 11, // Alias for Ctrl (non-macOS) _or_ Super (macOS).
#if defined(__APPLE__) ImGuiMod_Mask_ = 0xF800, // 5-bits
ImGuiMod_Shortcut = ImGuiMod_Super,
#else
ImGuiMod_Shortcut = ImGuiMod_Ctrl,
#endif
// [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + the io.KeyMap[] array. // [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + the io.KeyMap[] array.
// We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE) // We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE)
@ -1988,7 +1988,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.
float HoverDelayNormal; // = 0.30 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayNormal) returns true. float HoverDelayNormal; // = 0.30 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayNormal) returns true.
float HoverDelayShort; // = 0.10 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayShort) returns true. float HoverDelayShort; // = 0.10 sec // Delay on hovering before IsItemHovered(ImGuiHoveredFlags_DelayShort) returns true.
void* UserData; // = NULL // Store your own data for retrieval by callbacks. void* UserData; // = NULL // Store your own data.
ImFontAtlas*Fonts; // <auto> // Font atlas: 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
@ -2115,7 +2115,7 @@ struct ImGuiIO
bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows
// Other state maintained from data above + IO function calls // Other state maintained from data above + IO function calls
ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags). Read-only, updated by NewFrame() ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. DOES NOT CONTAINS ImGuiMod_Shortcut which is pretranslated). Read-only, updated by NewFrame()
ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this. ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this.
bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
@ -2922,6 +2922,7 @@ struct ImFontAtlas
int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false). int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. If your rendering method doesn't rely on bilinear filtering you may set this to 0 (will also need to set AntiAliasedLinesUseTex = false).
bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert. bool Locked; // Marked as Locked by ImGui::NewFrame() so attempt to modify the atlas will assert.
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
// [Internal] // [Internal]
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
@ -3055,6 +3056,7 @@ struct ImGuiViewport
void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context). generally set by your Platform_CreateWindow function. void* PlatformUserData; // void* to hold custom data structure for the OS / platform (e.g. windowing info, render context). generally set by your Platform_CreateWindow function.
void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GLFWWindow*, SDL_Window*) void* PlatformHandle; // void* for FindViewportByPlatformHandle(). (e.g. suggested to use natural platform handle such as HWND, GLFWWindow*, SDL_Window*)
void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms), when using an abstraction layer like GLFW or SDL (where PlatformHandle would be a SDL_Window*) void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms), when using an abstraction layer like GLFW or SDL (where PlatformHandle would be a SDL_Window*)
bool PlatformWindowCreated; // Platform window has been created (Platform_CreateWindow() has been called). This is false during the first frame where a viewport is being created.
bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position) bool PlatformRequestMove; // Platform window requested move (e.g. window was moved by the OS / host window manager, authoritative position will be OS window position)
bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size) bool PlatformRequestResize; // Platform window requested resize (e.g. window was resized by the OS / host window manager, authoritative size will be OS window size)
bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4) bool PlatformRequestClose; // Platform window requested closure (e.g. window was moved by the OS / host window manager, e.g. pressing ALT-F4)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (demo code) // (demo code)
// Help: // Help:
@ -3511,11 +3511,14 @@ static void ShowDemoWindowPopups()
// and BeginPopupContextItem() will use the last item ID as the popup ID. // and BeginPopupContextItem() will use the last item ID as the popup ID.
{ {
const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" }; const char* names[5] = { "Label1", "Label2", "Label3", "Label4", "Label5" };
static int selected = -1;
for (int n = 0; n < 5; n++) for (int n = 0; n < 5; n++)
{ {
ImGui::Selectable(names[n]); if (ImGui::Selectable(names[n], selected == n))
selected = n;
if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id
{ {
selected = n;
ImGui::Text("This a popup for \"%s\"!", names[n]); ImGui::Text("This a popup for \"%s\"!", names[n]);
if (ImGui::Button("Close")) if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
@ -5116,18 +5119,23 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Synced instances")) if (ImGui::TreeNode("Synced instances"))
{ {
HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc."); HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc.");
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings;
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
ImGui::CheckboxFlags("ImGuiTableFlags_SizingFixedFit", &flags, ImGuiTableFlags_SizingFixedFit);
for (int n = 0; n < 3; n++) for (int n = 0; n < 3; n++)
{ {
char buf[32]; char buf[32];
sprintf(buf, "Synced Table %d", n); sprintf(buf, "Synced Table %d", n);
bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen); bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen);
if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings)) if (open && ImGui::BeginTable("Table", 3, flags, ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 5)))
{ {
ImGui::TableSetupColumn("One"); ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two"); ImGui::TableSetupColumn("Two");
ImGui::TableSetupColumn("Three"); ImGui::TableSetupColumn("Three");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
for (int cell = 0; cell < 9; cell++) const int cell_count = (n == 1) ? 27 : 9; // Make second table have a scrollbar to verify that additional decoration is not affecting column positions.
for (int cell = 0; cell < cell_count; cell++)
{ {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Text("this cell %d", cell); ImGui::Text("this cell %d", cell);
@ -5759,46 +5767,89 @@ namespace ImGui { extern ImGuiKeyData* GetKeyData(ImGuiKey key); }
static void ShowDemoWindowInputs() static void ShowDemoWindowInputs()
{ {
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus"); IMGUI_DEMO_MARKER("Inputs & Focus");
if (ImGui::CollapsingHeader("Inputs, Navigation & Focus")) if (ImGui::CollapsingHeader("Inputs & Focus"))
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
// Display ImGuiIO output flags // Display inputs submitted to ImGuiIO
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Output"); IMGUI_DEMO_MARKER("Inputs & Focus/Inputs");
ImGui::SetNextItemOpen(true, ImGuiCond_Once); ImGui::SetNextItemOpen(true, ImGuiCond_Once);
if (ImGui::TreeNode("Output")) if (ImGui::TreeNode("Inputs"))
{ {
HelpMarker(
"This is a simplified view. See more detailed input state:\n"
"- in 'Tools->Metrics/Debugger->Inputs'.\n"
"- in 'Tools->Debug Log->IO'.");
if (ImGui::IsMousePosValid())
ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
else
ImGui::Text("Mouse pos: <INVALID>");
ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y);
ImGui::Text("Mouse down:");
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
// We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allows displaying the data for old/new backends.
// User code should never have to go through such hoops: old code may use native keycodes, new code may use ImGuiKey codes.
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
#endif
ImGui::Text("Keys down:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !ImGui::IsKeyDown(key)) continue; ImGui::SameLine(); ImGui::Text((key < ImGuiKey_NamedKey_BEGIN) ? "\"%s\"" : "\"%s\" %d", ImGui::GetKeyName(key), key); ImGui::SameLine(); ImGui::Text("(%.02f)", ImGui::GetKeyData(key)->DownDuration); }
ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public.
ImGui::TreePop();
}
// Display ImGuiIO output flags
IMGUI_DEMO_MARKER("Inputs & Focus/Outputs");
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
if (ImGui::TreeNode("Outputs"))
{
HelpMarker(
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
"rules leading to how those flags are set).");
ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse); ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse);
ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose); ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard); ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
ImGui::Text("io.WantTextInput: %d", io.WantTextInput); ImGui::Text("io.WantTextInput: %d", io.WantTextInput);
ImGui::Text("io.WantSetMousePos: %d", io.WantSetMousePos); ImGui::Text("io.WantSetMousePos: %d", io.WantSetMousePos);
ImGui::Text("io.NavActive: %d, io.NavVisible: %d", io.NavActive, io.NavVisible); ImGui::Text("io.NavActive: %d, io.NavVisible: %d", io.NavActive, io.NavVisible);
IMGUI_DEMO_MARKER("Inputs & Focus/Outputs/WantCapture override");
if (ImGui::TreeNode("WantCapture override"))
{
HelpMarker(
"Hovering the colored canvas will override io.WantCaptureXXX fields.\n"
"Notice how normally (when set to none), the value of io.WantCaptureKeyboard would be false when hovering and true when clicking.");
static int capture_override_mouse = -1;
static int capture_override_keyboard = -1;
const char* capture_override_desc[] = { "None", "Set to false", "Set to true" };
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
ImGui::SliderInt("SetNextFrameWantCaptureMouse() on hover", &capture_override_mouse, -1, +1, capture_override_desc[capture_override_mouse + 1], ImGuiSliderFlags_AlwaysClamp);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
ImGui::SliderInt("SetNextFrameWantCaptureKeyboard() on hover", &capture_override_keyboard, -1, +1, capture_override_desc[capture_override_keyboard + 1], ImGuiSliderFlags_AlwaysClamp);
ImGui::ColorButton("##panel", ImVec4(0.7f, 0.1f, 0.7f, 1.0f), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoDragDrop, ImVec2(128.0f, 96.0f)); // Dummy item
if (ImGui::IsItemHovered() && capture_override_mouse != -1)
ImGui::SetNextFrameWantCaptureMouse(capture_override_mouse == 1);
if (ImGui::IsItemHovered() && capture_override_keyboard != -1)
ImGui::SetNextFrameWantCaptureKeyboard(capture_override_keyboard == 1);
ImGui::TreePop(); ImGui::TreePop();
} }
// Display Mouse state
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Mouse State");
if (ImGui::TreeNode("Mouse State"))
{
if (ImGui::IsMousePosValid())
ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
else
ImGui::Text("Mouse pos: <INVALID>");
ImGui::Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y);
int count = IM_ARRAYSIZE(io.MouseDown);
ImGui::Text("Mouse down:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseDown(i)) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
ImGui::Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d (%d)", i, ImGui::GetMouseClickedCount(i)); }
ImGui::Text("Mouse released:"); for (int i = 0; i < count; i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); }
ImGui::Text("Mouse wheel: %.1f", io.MouseWheel);
ImGui::Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused
ImGui::TreePop(); ImGui::TreePop();
} }
// Display mouse cursors // Display mouse cursors
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Mouse Cursors"); IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors");
if (ImGui::TreeNode("Mouse Cursors")) if (ImGui::TreeNode("Mouse Cursors"))
{ {
const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" }; const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" };
@ -5826,113 +5877,7 @@ static void ShowDemoWindowInputs()
ImGui::TreePop(); ImGui::TreePop();
} }
// Display Keyboard/Mouse state IMGUI_DEMO_MARKER("Inputs & Focus/Tabbing");
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Keyboard, Gamepad & Navigation State");
if (ImGui::TreeNode("Keyboard, Gamepad & Navigation State"))
{
// We iterate both legacy native range and named ImGuiKey ranges, which is a little odd but this allows displaying the data for old/new backends.
// User code should never have to go through such hoops: old code may use native keycodes, new code may use ImGuiKey codes.
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
const ImGuiKey key_first = (ImGuiKey)ImGuiKey_NamedKey_BEGIN;
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
const ImGuiKey key_first = (ImGuiKey)0;
//ImGui::Text("Legacy raw:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (io.KeysDown[key]) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } }
#endif
ImGui::Text("Keys down:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyDown(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d (%.02f)", ImGui::GetKeyName(key), key, ImGui::GetKeyData(key)->DownDuration); } }
ImGui::Text("Keys pressed:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyPressed(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } }
ImGui::Text("Keys released:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyReleased(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } }
ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
ImGui::Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; ImGui::SameLine(); ImGui::Text("\'%c\' (0x%04X)", (c > ' ' && c <= 255) ? (char)c : '?', c); } // FIXME: We should convert 'c' to UTF-8 here but the functions are not public.
// Draw an arbitrary US keyboard layout to visualize translated keys
{
const ImVec2 key_size = ImVec2(35.0f, 35.0f);
const float key_rounding = 3.0f;
const ImVec2 key_face_size = ImVec2(25.0f, 25.0f);
const ImVec2 key_face_pos = ImVec2(5.0f, 3.0f);
const float key_face_rounding = 2.0f;
const ImVec2 key_label_pos = ImVec2(7.0f, 4.0f);
const ImVec2 key_step = ImVec2(key_size.x - 1.0f, key_size.y - 1.0f);
const float key_row_offset = 9.0f;
ImVec2 board_min = ImGui::GetCursorScreenPos();
ImVec2 board_max = ImVec2(board_min.x + 3 * key_step.x + 2 * key_row_offset + 10.0f, board_min.y + 3 * key_step.y + 10.0f);
ImVec2 start_pos = ImVec2(board_min.x + 5.0f - key_step.x, board_min.y);
struct KeyLayoutData { int Row, Col; const char* Label; ImGuiKey Key; };
const KeyLayoutData keys_to_display[] =
{
{ 0, 0, "", ImGuiKey_Tab }, { 0, 1, "Q", ImGuiKey_Q }, { 0, 2, "W", ImGuiKey_W }, { 0, 3, "E", ImGuiKey_E }, { 0, 4, "R", ImGuiKey_R },
{ 1, 0, "", ImGuiKey_CapsLock }, { 1, 1, "A", ImGuiKey_A }, { 1, 2, "S", ImGuiKey_S }, { 1, 3, "D", ImGuiKey_D }, { 1, 4, "F", ImGuiKey_F },
{ 2, 0, "", ImGuiKey_LeftShift },{ 2, 1, "Z", ImGuiKey_Z }, { 2, 2, "X", ImGuiKey_X }, { 2, 3, "C", ImGuiKey_C }, { 2, 4, "V", ImGuiKey_V }
};
// Elements rendered manually via ImDrawList API are not clipped automatically.
// While not strictly necessary, here IsItemVisible() is used to avoid rendering these shapes when they are out of view.
ImGui::Dummy(ImVec2(board_max.x - board_min.x, board_max.y - board_min.y));
if (ImGui::IsItemVisible())
{
ImDrawList* draw_list = ImGui::GetWindowDrawList();
draw_list->PushClipRect(board_min, board_max, true);
for (int n = 0; n < IM_ARRAYSIZE(keys_to_display); n++)
{
const KeyLayoutData* key_data = &keys_to_display[n];
ImVec2 key_min = ImVec2(start_pos.x + key_data->Col * key_step.x + key_data->Row * key_row_offset, start_pos.y + key_data->Row * key_step.y);
ImVec2 key_max = ImVec2(key_min.x + key_size.x, key_min.y + key_size.y);
draw_list->AddRectFilled(key_min, key_max, IM_COL32(204, 204, 204, 255), key_rounding);
draw_list->AddRect(key_min, key_max, IM_COL32(24, 24, 24, 255), key_rounding);
ImVec2 face_min = ImVec2(key_min.x + key_face_pos.x, key_min.y + key_face_pos.y);
ImVec2 face_max = ImVec2(face_min.x + key_face_size.x, face_min.y + key_face_size.y);
draw_list->AddRect(face_min, face_max, IM_COL32(193, 193, 193, 255), key_face_rounding, ImDrawFlags_None, 2.0f);
draw_list->AddRectFilled(face_min, face_max, IM_COL32(252, 252, 252, 255), key_face_rounding);
ImVec2 label_min = ImVec2(key_min.x + key_label_pos.x, key_min.y + key_label_pos.y);
draw_list->AddText(label_min, IM_COL32(64, 64, 64, 255), key_data->Label);
if (ImGui::IsKeyDown(key_data->Key))
draw_list->AddRectFilled(key_min, key_max, IM_COL32(255, 0, 0, 128), key_rounding);
}
draw_list->PopClipRect();
}
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Capture override"))
{
HelpMarker(
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
"rules leading to how those flags are set).");
ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse);
ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
HelpMarker(
"Hovering the colored canvas will override io.WantCaptureXXX fields.\n"
"Notice how normally (when set to none), the value of io.WantCaptureKeyboard would be false when hovering and true when clicking.");
static int capture_override_mouse = -1;
static int capture_override_keyboard = -1;
const char* capture_override_desc[] = { "None", "Set to false", "Set to true" };
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
ImGui::SliderInt("SetNextFrameWantCaptureMouse()", &capture_override_mouse, -1, +1, capture_override_desc[capture_override_mouse + 1], ImGuiSliderFlags_AlwaysClamp);
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 15);
ImGui::SliderInt("SetNextFrameWantCaptureKeyboard()", &capture_override_keyboard, -1, +1, capture_override_desc[capture_override_keyboard + 1], ImGuiSliderFlags_AlwaysClamp);
ImGui::ColorButton("##panel", ImVec4(0.7f, 0.1f, 0.7f, 1.0f), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoDragDrop, ImVec2(256.0f, 192.0f)); // Dummy item
if (ImGui::IsItemHovered() && capture_override_mouse != -1)
ImGui::SetNextFrameWantCaptureMouse(capture_override_mouse == 1);
if (ImGui::IsItemHovered() && capture_override_keyboard != -1)
ImGui::SetNextFrameWantCaptureKeyboard(capture_override_keyboard == 1);
ImGui::TreePop();
}
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Tabbing");
if (ImGui::TreeNode("Tabbing")) if (ImGui::TreeNode("Tabbing"))
{ {
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
@ -5948,7 +5893,7 @@ static void ShowDemoWindowInputs()
ImGui::TreePop(); ImGui::TreePop();
} }
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Focus from code"); IMGUI_DEMO_MARKER("Inputs & Focus/Focus from code");
if (ImGui::TreeNode("Focus from code")) if (ImGui::TreeNode("Focus from code"))
{ {
bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine();
@ -5990,7 +5935,7 @@ static void ShowDemoWindowInputs()
ImGui::TreePop(); ImGui::TreePop();
} }
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Dragging"); IMGUI_DEMO_MARKER("Inputs & Focus/Dragging");
if (ImGui::TreeNode("Dragging")) if (ImGui::TreeNode("Dragging"))
{ {
ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
@ -6815,6 +6760,8 @@ struct ExampleAppConsole
if (copy_to_clipboard) if (copy_to_clipboard)
ImGui::LogFinish(); ImGui::LogFinish();
// Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame.
// Using a scrollbar or mouse-wheel will take away from the bottom edge.
if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())) if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
ScrollToBottom = false; ScrollToBottom = false;
@ -7123,6 +7070,8 @@ struct ExampleAppLog
} }
ImGui::PopStyleVar(); ImGui::PopStyleVar();
// Keep up at the bottom of the scroll region if we were already at the bottom at the beginning of the frame.
// Using a scrollbar or mouse-wheel will take away from the bottom edge.
if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) if (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
ImGui::SetScrollHereY(1.0f); ImGui::SetScrollHereY(1.0f);
} }
@ -7177,7 +7126,7 @@ static void ShowExampleAppLayout(bool* p_open)
{ {
if (ImGui::BeginMenu("File")) if (ImGui::BeginMenu("File"))
{ {
if (ImGui::MenuItem("Close")) *p_open = false; if (ImGui::MenuItem("Close", "Ctrl+W")) { *p_open = false; }
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMenuBar(); ImGui::EndMenuBar();

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (drawing and font code) // (drawing and font code)
/* /*
@ -455,11 +455,13 @@ void ImDrawList::AddDrawCmd()
// Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL // Note that this leaves the ImDrawList in a state unfit for further commands, as most code assume that CmdBuffer.Size > 0 && CmdBuffer.back().UserCallback == NULL
void ImDrawList::_PopUnusedDrawCmd() void ImDrawList::_PopUnusedDrawCmd()
{ {
if (CmdBuffer.Size == 0) while (CmdBuffer.Size > 0)
return; {
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL) if (curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL)
return;// break;
CmdBuffer.pop_back(); CmdBuffer.pop_back();
}
} }
void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data)
@ -3573,17 +3575,18 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im
while (y + line_height < clip_rect.y && s < text_end) while (y + line_height < clip_rect.y && s < text_end)
{ {
const char* line_end = (const char*)memchr(s, '\n', text_end - s); const char* line_end = (const char*)memchr(s, '\n', text_end - s);
const char* line_next = line_end ? line_end + 1 : text_end;
if (word_wrap_enabled) if (word_wrap_enabled)
{ {
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA(). // FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
// If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both. // If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both.
// However it is still better than nothing performing the fast-forward! // However it is still better than nothing performing the fast-forward!
s = CalcWordWrapPositionA(scale, s, line_end, wrap_width); s = CalcWordWrapPositionA(scale, s, line_next, wrap_width);
s = CalcWordWrapNextLineStartA(s, text_end); s = CalcWordWrapNextLineStartA(s, text_end);
} }
else else
{ {
s = line_end ? line_end + 1 : text_end; s = line_next;
} }
y += line_height; y += line_height;
} }

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (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!
@ -26,6 +26,7 @@ Index of this file:
// [SECTION] Docking support // [SECTION] Docking support
// [SECTION] Viewport support // [SECTION] Viewport support
// [SECTION] Settings support // [SECTION] Settings support
// [SECTION] Localization support
// [SECTION] Metrics, Debug tools // [SECTION] Metrics, Debug tools
// [SECTION] Generic context hooks // [SECTION] Generic context hooks
// [SECTION] ImGuiContext (main imgui context) // [SECTION] ImGuiContext (main imgui context)
@ -55,7 +56,7 @@ Index of this file:
#include <limits.h> // INT_MIN, INT_MAX #include <limits.h> // INT_MIN, INT_MAX
// Enable SSE intrinsics if available // Enable SSE intrinsics if available
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64) && !defined(IMGUI_DISABLE_SSE) #if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE)
#define IMGUI_ENABLE_SSE #define IMGUI_ENABLE_SSE
#include <immintrin.h> #include <immintrin.h>
#endif #endif
@ -125,6 +126,7 @@ struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
struct ImGuiLastItemData; // Status storage for last submitted items struct ImGuiLastItemData; // Status storage for last submitted items
struct ImGuiLocEntry; // A localization entry.
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result
struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
@ -148,9 +150,13 @@ struct ImGuiWindow; // Storage for one window
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
// Enumerations
// 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.
enum ImGuiLocKey : int; // -> enum ImGuiLocKey // Enum: a localization entry for translation.
typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
// Flags
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc. typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc.
@ -208,12 +214,16 @@ namespace ImStb
#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS #ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
#define IMGUI_DEBUG_PRINTF(_FMT,...) printf(_FMT, __VA_ARGS__) #define IMGUI_DEBUG_PRINTF(_FMT,...) printf(_FMT, __VA_ARGS__)
#else #else
#define IMGUI_DEBUG_PRINTF(_FMT,...) #define IMGUI_DEBUG_PRINTF(_FMT,...) ((void)0)
#endif #endif
#endif #endif
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam. // Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
#define IMGUI_DEBUG_LOG(...) ImGui::DebugLog(__VA_ARGS__) #define IMGUI_DEBUG_LOG(...) ImGui::DebugLog(__VA_ARGS__)
#else
#define IMGUI_DEBUG_LOG(...) ((void)0)
#endif
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) #define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
@ -477,6 +487,7 @@ static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a)
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; } static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
IM_MSVC_RUNTIME_CHECKS_RESTORE IM_MSVC_RUNTIME_CHECKS_RESTORE
// Helpers: Geometry // Helpers: Geometry
@ -890,10 +901,9 @@ enum ImGuiSelectableFlagsPrivate_
ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release) ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release)
ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release) ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release)
ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus)
ImGuiSelectableFlags_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, // Set Nav/Focus ID on mouse hover (used by MenuItem)
ImGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem) ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, // Disable padding each side with ItemSpacing * 0.5f
ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27, // Disable padding each side with ItemSpacing * 0.5f ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
ImGuiSelectableFlags_NoSetKeyOwner = 1 << 28, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
}; };
// Extend ImGuiTreeNodeFlags_ // Extend ImGuiTreeNodeFlags_
@ -1050,6 +1060,7 @@ struct IMGUI_API ImGuiMenuColumns
// For a given item ID, access with ImGui::GetInputTextState() // For a given item ID, access with ImGui::GetInputTextState()
struct IMGUI_API ImGuiInputTextState struct IMGUI_API ImGuiInputTextState
{ {
ImGuiContext* Ctx; // parent dear imgui context
ImGuiID ID; // widget id owning the text state ImGuiID ID; // widget id owning the text state
int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not. int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not.
ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
@ -1065,7 +1076,7 @@ struct IMGUI_API ImGuiInputTextState
bool Edited; // edited this frame bool Edited; // edited this frame
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set. ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } ImGuiInputTextState(ImGuiContext* ctx) { memset(this, 0, sizeof(*this)); Ctx = ctx;}
void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); } void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
int GetUndoAvailCount() const { return Stb.undostate.undo_point; } int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
@ -1228,8 +1239,10 @@ typedef ImBitArray<ImGuiKey_NamedKey_COUNT, -ImGuiKey_NamedKey_BEGIN> ImBitAr
#define ImGuiKey_Keyboard_END (ImGuiKey_GamepadStart) #define ImGuiKey_Keyboard_END (ImGuiKey_GamepadStart)
#define ImGuiKey_Gamepad_BEGIN (ImGuiKey_GamepadStart) #define ImGuiKey_Gamepad_BEGIN (ImGuiKey_GamepadStart)
#define ImGuiKey_Gamepad_END (ImGuiKey_GamepadRStickDown + 1) #define ImGuiKey_Gamepad_END (ImGuiKey_GamepadRStickDown + 1)
#define ImGuiKey_Aliases_BEGIN (ImGuiKey_MouseLeft) #define ImGuiKey_Mouse_BEGIN (ImGuiKey_MouseLeft)
#define ImGuiKey_Aliases_END (ImGuiKey_MouseWheelY + 1) #define ImGuiKey_Mouse_END (ImGuiKey_MouseWheelY + 1)
#define ImGuiKey_Aliases_BEGIN (ImGuiKey_Mouse_BEGIN)
#define ImGuiKey_Aliases_END (ImGuiKey_Mouse_END)
// [Internal] Named shortcuts for Navigation // [Internal] Named shortcuts for Navigation
#define ImGuiKey_NavKeyboardTweakSlow ImGuiMod_Ctrl #define ImGuiKey_NavKeyboardTweakSlow ImGuiMod_Ctrl
@ -1295,7 +1308,7 @@ struct ImGuiInputEvent
}; };
// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior. // Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
#define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitely used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. #define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
#define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner. #define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner.
typedef ImS16 ImGuiKeyRoutingIndex; typedef ImS16 ImGuiKeyRoutingIndex;
@ -1304,7 +1317,7 @@ typedef ImS16 ImGuiKeyRoutingIndex;
struct ImGuiKeyRoutingData struct ImGuiKeyRoutingData
{ {
ImGuiKeyRoutingIndex NextEntryIndex; ImGuiKeyRoutingIndex NextEntryIndex;
ImU16 Mods; ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImGuiMod_Shortcut is already translated to Ctrl/Super.
ImU8 RoutingNextScore; // Lower is better (0: perfect score) ImU8 RoutingNextScore; // Lower is better (0: perfect score)
ImGuiID RoutingCurr; ImGuiID RoutingCurr;
ImGuiID RoutingNext; ImGuiID RoutingNext;
@ -1312,7 +1325,7 @@ struct ImGuiKeyRoutingData
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; } ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; }
}; };
// Routing table maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching. // Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
// Stored in main context (1 instance) // Stored in main context (1 instance)
struct ImGuiKeyRoutingTable struct ImGuiKeyRoutingTable
{ {
@ -1324,8 +1337,8 @@ struct ImGuiKeyRoutingTable
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); } void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
}; };
// This extend ImGuiKeyData but only for named keys (legacy keys don't support the new features) // This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features)
// Stored in main context (1 per named key). In the future might be merged into ImGuiKeyData. // Stored in main context (1 per named key). In the future it might be merged into ImGuiKeyData.
struct ImGuiKeyOwnerData struct ImGuiKeyOwnerData
{ {
ImGuiID OwnerCurr; ImGuiID OwnerCurr;
@ -1355,8 +1368,8 @@ enum ImGuiInputFlags_
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
// Flags for SetKeyOwner(), SetItemKeyOwner() // Flags for SetKeyOwner(), SetItemKeyOwner()
ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will requires EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will requires EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when key is released or at end of frame is not down. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
// Routing policies for Shortcut() + low-level SetShortcutRouting() // Routing policies for Shortcut() + low-level SetShortcutRouting()
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it. // - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
@ -1713,7 +1726,6 @@ struct ImGuiViewportP : public ImGuiViewport
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
float LastAlpha; float LastAlpha;
short PlatformMonitor; short PlatformMonitor;
bool PlatformWindowCreated;
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set) ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays. ImDrawList* DrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
@ -1727,7 +1739,7 @@ struct ImGuiViewportP : public ImGuiViewport
ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f. ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f.
ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f. ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f.
ImGuiViewportP() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ImGuiViewportP() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); } ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[1]); }
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
@ -1781,6 +1793,31 @@ struct ImGuiSettingsHandler
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
}; };
//-----------------------------------------------------------------------------
// [SECTION] Localization support
//-----------------------------------------------------------------------------
// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack.
enum ImGuiLocKey : int
{
ImGuiLocKey_TableSizeOne,
ImGuiLocKey_TableSizeAllFit,
ImGuiLocKey_TableSizeAllDefault,
ImGuiLocKey_TableResetOrder,
ImGuiLocKey_WindowingMainMenuBar,
ImGuiLocKey_WindowingPopup,
ImGuiLocKey_WindowingUntitled,
ImGuiLocKey_DockingHideTabBar,
ImGuiLocKey_COUNT
};
struct ImGuiLocEntry
{
ImGuiLocKey Key;
const char* Text;
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] Metrics, Debug Tools // [SECTION] Metrics, Debug Tools
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1911,7 +1948,10 @@ struct ImGuiContext
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree. ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree.
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window. ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
ImVec2 WheelingWindowRefMousePos; ImVec2 WheelingWindowRefMousePos;
int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
float WheelingWindowReleaseTimer; float WheelingWindowReleaseTimer;
ImVec2 WheelingWindowWheelRemainder;
ImVec2 WheelingAxisAvg;
// Item/widgets state and tracking information // Item/widgets state and tracking information
ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
@ -1950,7 +1990,7 @@ struct ImGuiContext
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency) bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency)
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetActiveIdUsingKey(ImGuiKey_Escape); SetActiveIdUsingKey(ImGuiKey_NavGamepadCancel);' ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);'
#endif #endif
// Next window/item data // Next window/item data
@ -2131,6 +2171,9 @@ struct ImGuiContext
ImVector<ImGuiContextHook> Hooks; // Hooks for extensions (e.g. test engine) ImVector<ImGuiContextHook> Hooks; // Hooks for extensions (e.g. test engine)
ImGuiID HookIdNext; // Next available HookId ImGuiID HookIdNext; // Next available HookId
// Localization
const char* LocalizationTable[ImGuiLocKey_COUNT];
// Capture/Logging // Capture/Logging
bool LogEnabled; // Currently capturing bool LogEnabled; // Currently capturing
ImGuiLogType LogType; // Capture target ImGuiLogType LogType; // Capture target
@ -2167,6 +2210,7 @@ struct ImGuiContext
ImVector<char> TempBuffer; // Temporary text buffer ImVector<char> TempBuffer; // Temporary text buffer
ImGuiContext(ImFontAtlas* shared_font_atlas) ImGuiContext(ImFontAtlas* shared_font_atlas)
: InputTextState(this)
{ {
Initialized = false; Initialized = false;
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None; ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
@ -2188,6 +2232,7 @@ struct ImGuiContext
HoveredWindowUnderMovingWindow = NULL; HoveredWindowUnderMovingWindow = NULL;
MovingWindow = NULL; MovingWindow = NULL;
WheelingWindow = NULL; WheelingWindow = NULL;
WheelingWindowStartFrame = -1;
WheelingWindowReleaseTimer = 0.0f; WheelingWindowReleaseTimer = 0.0f;
DebugHookIdInfo = 0; DebugHookIdInfo = 0;
@ -2311,6 +2356,8 @@ struct ImGuiContext
SettingsDirtyTimer = 0.0f; SettingsDirtyTimer = 0.0f;
HookIdNext = 0; HookIdNext = 0;
memset(LocalizationTable, 0, sizeof(LocalizationTable));
LogEnabled = false; LogEnabled = false;
LogType = ImGuiLogType_None; LogType = ImGuiLogType_None;
LogNextPrefix = LogNextSuffix = NULL; LogNextPrefix = LogNextSuffix = NULL;
@ -2409,6 +2456,9 @@ struct IMGUI_API ImGuiWindow
ImVec2 WindowPadding; // Window padding at the time of Begin(). ImVec2 WindowPadding; // Window padding at the time of Begin().
float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc. float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
float WindowBorderSize; // Window border size at the time of Begin(). float WindowBorderSize; // Window border size at the time of Begin().
float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes).
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID MoveId; // == window->GetID("#MOVE")
ImGuiID TabId; // == window->GetID("#TAB") ImGuiID TabId; // == window->GetID("#TAB")
@ -2701,13 +2751,14 @@ struct ImGuiTableCellData
// Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs, does that needs they could be moved to ImGuiTableTempData ?) // Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs, does that needs they could be moved to ImGuiTableTempData ?)
struct ImGuiTableInstanceData struct ImGuiTableInstanceData
{ {
float LastOuterHeight; // Outer height from last frame // FIXME: multi-instance issue (#3955) float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame // FIXME: possible multi-instance issue? float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked)
float LastFrozenHeight; // Height of frozen section from last frame
ImGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = 0.0f; } ImGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; }
}; };
// FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData // FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData
struct IMGUI_API ImGuiTable struct IMGUI_API ImGuiTable
{ {
ImGuiID ID; ImGuiID ID;
@ -2812,6 +2863,8 @@ struct IMGUI_API ImGuiTable
bool IsResetDisplayOrderRequest; bool IsResetDisplayOrderRequest;
bool IsUnfrozenRows; // Set when we got past the frozen row. bool IsUnfrozenRows; // Set when we got past the frozen row.
bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable() bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable()
bool HasScrollbarYCurr; // Whether ANY instance of this table had a vertical scrollbar during the current frame.
bool HasScrollbarYPrev; // Whether ANY instance of this table had a vertical scrollbar during the previous.
bool MemoryCompacted; bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
@ -2961,8 +3014,11 @@ namespace ImGui
IMGUI_API void RemoveSettingsHandler(const char* type_name); IMGUI_API void RemoveSettingsHandler(const char* type_name);
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
// Localization
IMGUI_API void LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count);
inline const char* LocalizeGetMsg(ImGuiLocKey key) { ImGuiContext& g = *GImGui; const char* msg = g.LocalizationTable[key]; return msg ? msg : "*Missing Text*"; }
// Scrolling // Scrolling
IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // Use -1.0f on one axis to leave as-is
IMGUI_API void SetScrollX(ImGuiWindow* window, float scroll_x); IMGUI_API void SetScrollX(ImGuiWindow* window, float scroll_x);
IMGUI_API void SetScrollY(ImGuiWindow* window, float scroll_y); IMGUI_API void SetScrollY(ImGuiWindow* window, float scroll_y);
IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio); IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio);
@ -2977,7 +3033,6 @@ namespace ImGui
//#endif //#endif
// Basic Accessors // Basic Accessors
inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.LastItemData.ID; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand)
inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } inline ImGuiItemStatusFlags GetItemStatusFlags(){ ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; }
inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; }
inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; }
@ -3058,16 +3113,21 @@ namespace ImGui
// Inputs // Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; } inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; }
inline bool IsNamedKeyOrModKey(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super; } inline bool IsNamedKeyOrModKey(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super || key == ImGuiMod_Shortcut; }
inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; } inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; }
inline bool IsKeyboardKey(ImGuiKey key) { return key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END; }
inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; }
inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; }
inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; } inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; }
inline ImGuiKeyChord ConvertShortcutMod(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; IM_ASSERT_PARANOID(key_chord & ImGuiMod_Shortcut); return (key_chord & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); }
inline ImGuiKey ConvertSingleModFlagToKey(ImGuiKey key) inline ImGuiKey ConvertSingleModFlagToKey(ImGuiKey key)
{ {
ImGuiContext& g = *GImGui;
if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl; if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl;
if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift; if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift;
if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt; if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt;
if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper; if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper;
if (key == ImGuiMod_Shortcut) return (g.IO.ConfigMacOSXBehaviors ? ImGuiKey_ReservedForModSuper : ImGuiKey_ReservedForModCtrl);
return key; return key;
} }
@ -3075,7 +3135,7 @@ namespace ImGui
IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size); IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size);
inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); } inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); }
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f); IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
IMGUI_API ImVec2 GetKeyVector2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down); IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down);
IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis);
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate); IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate);
@ -3083,12 +3143,12 @@ namespace ImGui
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
// [EXPERIMENTAL] Low-Level: Key/Input Ownership // [EXPERIMENTAL] Low-Level: Key/Input Ownership
// - The idea is that instead of "eating" a given input, we can link to an owner. // - The idea is that instead of "eating" a given input, we can link to an owner id.
// - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead). // - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead).
// - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID. // - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
// - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0). // - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0).
// - Input ownership is automatically released on the frame after a key is released. Therefore: // - Input ownership is automatically released on the frame after a key is released. Therefore:
// - for ownership registration happening a result of a down/press event, the SetKeyOwner() call may be done once (common case). // - for ownership registration happening as a result of a down/press event, the SetKeyOwner() call may be done once (common case).
// - for ownership registration happening ahead of a down/press event, the SetKeyOwner() call needs to be made every frame (happens if e.g. claiming ownership on hover). // - for ownership registration happening ahead of a down/press event, the SetKeyOwner() call needs to be made every frame (happens if e.g. claiming ownership on hover).
// - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state. // - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state.
// - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step. // - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step.
@ -3103,7 +3163,7 @@ namespace ImGui
// - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag. // - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag.
// - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0) // - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0)
// - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'. // - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'.
// Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitely used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. // Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
// - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API. // - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API.
IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id); IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id);
IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat. IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat.
@ -3120,7 +3180,7 @@ namespace ImGui
// - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy. // - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy.
// - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame. // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame.
// - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route. // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
// - Multiple read sites may use a same owner and will all get the granted route. // - Multiple read sites may use the same owner id and will all get the granted route.
// - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location. // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
@ -3307,19 +3367,21 @@ namespace ImGui
// Widgets // Widgets
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0);
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);
// Widgets: Window Decorations
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos);
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node); IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node);
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
IMGUI_API void Scrollbar(ImGuiAxis axis); IMGUI_API void Scrollbar(ImGuiAxis axis);
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags); IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags);
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col);
IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners
IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir); IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);
// Widgets low-level behaviors // Widgets low-level behaviors
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
@ -3404,6 +3466,7 @@ namespace ImGui
IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label); IMGUI_API void DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label);
IMGUI_API void DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack); IMGUI_API void DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack);
IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport); IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport);
IMGUI_API void DebugRenderKeyboardPreview(ImDrawList* draw_list);
IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb); IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb);
// Obsolete functions // Obsolete functions

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (tables and columns code) // (tables and columns code)
/* /*
@ -395,6 +395,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->OuterRect = table->InnerWindow->Rect(); table->OuterRect = table->InnerWindow->Rect();
table->InnerRect = table->InnerWindow->InnerRect; table->InnerRect = table->InnerWindow->InnerRect;
IM_ASSERT(table->InnerWindow->WindowPadding.x == 0.0f && table->InnerWindow->WindowPadding.y == 0.0f && table->InnerWindow->WindowBorderSize == 0.0f); IM_ASSERT(table->InnerWindow->WindowPadding.x == 0.0f && table->InnerWindow->WindowPadding.y == 0.0f && table->InnerWindow->WindowBorderSize == 0.0f);
// When using multiple instances, ensure they have the same amount of horizontal decorations (aka vertical scrollbar) so stretched columns can be aligned)
if (instance_no == 0)
{
table->HasScrollbarYPrev = table->HasScrollbarYCurr;
table->HasScrollbarYCurr = false;
}
table->HasScrollbarYCurr |= (table->InnerWindow->ScrollMax.y > 0.0f);
} }
else else
{ {
@ -893,7 +901,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 4] Apply final widths based on requested widths // [Part 4] Apply final widths based on requested widths
const ImRect work_rect = table->WorkRect; const ImRect work_rect = table->WorkRect;
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1); const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth(); const float width_removed = (table->HasScrollbarYPrev && !table->InnerWindow->ScrollbarY) ? g.Style.ScrollbarSize : 0.0f; // To synchronize decoration width of synched tables with mismatching scrollbar state (#5920)
const float width_avail = ImMax(1.0f, (((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth()) - width_removed);
const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests; const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount; table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
@ -964,7 +973,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
column->NavLayerCurrent = (ImS8)((table->FreezeRowsCount > 0 || column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); column->NavLayerCurrent = (ImS8)(table->FreezeRowsCount > 0 ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main); // Use Count NOT request so Header line changes layer when frozen
if (offset_x_frozen && table->FreezeColumnsCount == visible_n) if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
{ {
@ -1124,6 +1133,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable)) if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
TableSortSpecsBuild(table); TableSortSpecsBuild(table);
// [Part 14] Setup inner window decoration size (for scrolling / nav tracking to properly take account of frozen rows/columns)
if (table->FreezeColumnsRequest > 0)
table->InnerWindow->DecoInnerSizeX1 = table->Columns[table->DisplayOrderToIndex[table->FreezeColumnsRequest - 1]].MaxX - table->OuterRect.Min.x;
if (table->FreezeRowsRequest > 0)
table->InnerWindow->DecoInnerSizeY1 = table_instance->LastFrozenHeight;
table_instance->LastFrozenHeight = 0.0f;
// Initial state // Initial state
ImGuiWindow* inner_window = table->InnerWindow; ImGuiWindow* inner_window = table->InnerWindow;
if (table->Flags & ImGuiTableFlags_NoClip) if (table->Flags & ImGuiTableFlags_NoClip)
@ -1839,17 +1855,15 @@ void ImGui::TableEndRow(ImGuiTable* table)
// get the new cursor position. // get the new cursor position.
if (unfreeze_rows_request) if (unfreeze_rows_request)
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{ table->Columns[column_n].NavLayerCurrent = ImGuiNavLayer_Main;
ImGuiTableColumn* column = &table->Columns[column_n];
column->NavLayerCurrent = (ImS8)((column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main);
}
if (unfreeze_rows_actual) if (unfreeze_rows_actual)
{ {
IM_ASSERT(table->IsUnfrozenRows == false); IM_ASSERT(table->IsUnfrozenRows == false);
const float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
table->IsUnfrozenRows = true; table->IsUnfrozenRows = true;
TableGetInstanceData(table, table->InstanceCurrent)->LastFrozenHeight = y0 - table->OuterRect.Min.y;
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect // BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y); table->BgClipRect.Min.y = table->Bg2ClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y; table->BgClipRect.Max.y = table->Bg2ClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen; table->Bg2DrawChannelCurrent = table->Bg2DrawChannelUnfrozen;
@ -3070,15 +3084,15 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
if (column != NULL) if (column != NULL)
{ {
const bool can_resize = !(column->Flags & ImGuiTableColumnFlags_NoResize) && column->IsEnabled; const bool can_resize = !(column->Flags & ImGuiTableColumnFlags_NoResize) && column->IsEnabled;
if (MenuItem("Size column to fit###SizeOne", NULL, false, can_resize)) if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableSizeOne), NULL, false, can_resize)) // "###SizeOne"
TableSetColumnWidthAutoSingle(table, column_n); TableSetColumnWidthAutoSingle(table, column_n);
} }
const char* size_all_desc; const char* size_all_desc;
if (table->ColumnsEnabledFixedCount == table->ColumnsEnabledCount && (table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame) if (table->ColumnsEnabledFixedCount == table->ColumnsEnabledCount && (table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame)
size_all_desc = "Size all columns to fit###SizeAll"; // All fixed size_all_desc = LocalizeGetMsg(ImGuiLocKey_TableSizeAllFit); // "###SizeAll" All fixed
else else
size_all_desc = "Size all columns to default###SizeAll"; // All stretch or mixed size_all_desc = LocalizeGetMsg(ImGuiLocKey_TableSizeAllDefault); // "###SizeAll" All stretch or mixed
if (MenuItem(size_all_desc, NULL)) if (MenuItem(size_all_desc, NULL))
TableSetColumnWidthAutoAll(table); TableSetColumnWidthAutoAll(table);
want_separator = true; want_separator = true;
@ -3087,7 +3101,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
// Ordering // Ordering
if (table->Flags & ImGuiTableFlags_Reorderable) if (table->Flags & ImGuiTableFlags_Reorderable)
{ {
if (MenuItem("Reset order", NULL, false, !table->IsDefaultDisplayOrder)) if (MenuItem(LocalizeGetMsg(ImGuiLocKey_TableResetOrder), NULL, false, !table->IsDefaultDisplayOrder))
table->IsResetDisplayOrderRequest = true; table->IsResetDisplayOrderRequest = true;
want_separator = true; want_separator = true;
} }

View File

@ -1,4 +1,4 @@
// dear imgui, v1.89 WIP // dear imgui, v1.89.2
// (widgets code) // (widgets code)
/* /*
@ -126,7 +126,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
// For InputTextEx() // For InputTextEx()
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source);
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false);
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// [SECTION] Widgets: Text, etc. // [SECTION] Widgets: Text, etc.
@ -544,13 +544,21 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id;
if (hovered) if (hovered)
{ {
// Poll mouse buttons
// - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId.
// - Technically we only need some values in one code path, but since this is gated by hovered test this is fine.
int mouse_button_clicked = -1;
int mouse_button_released = -1;
for (int button = 0; button < 3; button++)
if (flags & (ImGuiButtonFlags_MouseButtonLeft << button)) // Handle ImGuiButtonFlags_MouseButtonRight and ImGuiButtonFlags_MouseButtonMiddle here.
{
if (IsMouseClicked(button, test_owner_id) && mouse_button_clicked == -1) { mouse_button_clicked = button; }
if (IsMouseReleased(button, test_owner_id) && mouse_button_released == -1) { mouse_button_released = button; }
}
// Process initial action
if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt))
{ {
// Poll buttons
int mouse_button_clicked = -1;
if ((flags & ImGuiButtonFlags_MouseButtonLeft) && IsMouseClicked(0, test_owner_id)) { mouse_button_clicked = 0; }
else if ((flags & ImGuiButtonFlags_MouseButtonRight) && IsMouseClicked(1, test_owner_id)) { mouse_button_clicked = 1; }
else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && IsMouseClicked(2, test_owner_id)) { mouse_button_clicked = 2; }
if (mouse_button_clicked != -1 && g.ActiveId != id) if (mouse_button_clicked != -1 && g.ActiveId != id)
{ {
if (!(flags & ImGuiButtonFlags_NoSetKeyOwner)) if (!(flags & ImGuiButtonFlags_NoSetKeyOwner))
@ -578,10 +586,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
} }
if (flags & ImGuiButtonFlags_PressedOnRelease) if (flags & ImGuiButtonFlags_PressedOnRelease)
{ {
int mouse_button_released = -1;
if ((flags & ImGuiButtonFlags_MouseButtonLeft) && IsMouseReleased(0, test_owner_id)) { mouse_button_released = 0; }
else if ((flags & ImGuiButtonFlags_MouseButtonRight) && IsMouseReleased(1, test_owner_id)) { mouse_button_released = 1; }
else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && IsMouseReleased(2, test_owner_id)) { mouse_button_released = 2; }
if (mouse_button_released != -1) if (mouse_button_released != -1)
{ {
const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior
@ -3571,9 +3575,9 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
return line_count; return line_count;
} }
static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *ctx;
ImFont* font = g.Font; ImFont* font = g.Font;
const float line_height = g.FontSize; const float line_height = g.FontSize;
const float scale = line_height / font->FontSize; const float scale = line_height / font->FontSize;
@ -3622,14 +3626,14 @@ namespace ImStb
static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; } static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; }
static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { return obj->TextW[idx]; } static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { return obj->TextW[idx]; }
static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *GImGui; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); } static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); }
static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; } static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; }
static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; static ImWchar STB_TEXTEDIT_NEWLINE = '\n';
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx) static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
{ {
const ImWchar* text = obj->TextW.Data; const ImWchar* text = obj->TextW.Data;
const ImWchar* text_remaining = NULL; const ImWchar* text_remaining = NULL;
const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); const ImVec2 size = InputTextCalcTextSizeW(obj->Ctx, text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true);
r->x0 = 0.0f; r->x0 = 0.0f;
r->x1 = size.x; r->x1 = size.x;
r->baseline_y_delta = size.y; r->baseline_y_delta = size.y;
@ -3645,7 +3649,7 @@ static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx)
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { if (ImGui::GetIO().ConfigMacOSXBehaviors) return STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx); else return STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx); } static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(ImGuiInputTextState* obj, int idx) { ImGuiContext& g = *obj->Ctx; if (g.IO.ConfigMacOSXBehaviors) return STB_TEXTEDIT_MOVEWORDRIGHT_MAC(obj, idx); else return STB_TEXTEDIT_MOVEWORDRIGHT_WIN(obj, idx); }
#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h #define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL #define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
@ -4107,14 +4111,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
} }
if (g.ActiveId == id) if (g.ActiveId == id)
{ {
// Declare our inputs // Declare some inputs, the other are registered and polled via Shortcut() routing system.
if (user_clicked) if (user_clicked)
SetKeyOwner(ImGuiKey_MouseLeft, id); SetKeyOwner(ImGuiKey_MouseLeft, id);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory))
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
SetKeyOwner(ImGuiKey_Escape, id);
SetKeyOwner(ImGuiKey_NavGamepadCancel, id);
SetKeyOwner(ImGuiKey_Home, id); SetKeyOwner(ImGuiKey_Home, id);
SetKeyOwner(ImGuiKey_End, id); SetKeyOwner(ImGuiKey_End, id);
if (is_multiline) if (is_multiline)
@ -4123,10 +4125,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
SetKeyOwner(ImGuiKey_PageDown, id); SetKeyOwner(ImGuiKey_PageDown, id);
} }
if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character. if (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) // Disable keyboard tabbing out as we will use the \t character.
{
SetKeyOwner(ImGuiKey_Tab, id); SetKeyOwner(ImGuiKey_Tab, id);
} }
}
// We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function) // We have an edge case if ActiveId was set through another widget (e.g. widget being swapped), clear id immediately (don't wait until the end of the function)
if (g.ActiveId == id && state == NULL) if (g.ActiveId == id && state == NULL)
@ -4298,22 +4298,23 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
// Using Shortcut() with ImGuiInputFlags_RouteFocused flag to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText) // Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText)
// Otherwise we could simply assume that we own the keys as we are active. // Otherwise we could simply assume that we own the keys as we are active.
const ImGuiInputFlags shortcut_flags = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_Repeat; const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat;
const bool is_cut = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, shortcut_flags) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, shortcut_flags)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); const bool is_cut = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, f_repeat)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection());
const bool is_copy = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_C, id, shortcut_flags & ~ImGuiInputFlags_Repeat) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, id, shortcut_flags & ~ImGuiInputFlags_Repeat)) && !is_password && (!is_multiline || state->HasSelection()); const bool is_copy = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_C, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, id)) && !is_password && (!is_multiline || state->HasSelection());
const bool is_paste = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_V, id, shortcut_flags) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, id, shortcut_flags)) && !is_readonly; const bool is_paste = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_V, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, id, f_repeat)) && !is_readonly;
const bool is_undo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Z, id, shortcut_flags)) && !is_readonly && is_undoable; const bool is_undo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Z, id, f_repeat)) && !is_readonly && is_undoable;
const bool is_redo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Y, id, shortcut_flags) || (is_osx && Shortcut(ImGuiMod_Shortcut | ImGuiMod_Shift | ImGuiKey_Z, id, shortcut_flags))) && !is_readonly && is_undoable; const bool is_redo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Y, id, f_repeat) || (is_osx && Shortcut(ImGuiMod_Shortcut | ImGuiMod_Shift | ImGuiKey_Z, id, f_repeat))) && !is_readonly && is_undoable;
const bool is_select_all = Shortcut(ImGuiMod_Shortcut | ImGuiKey_A, id, shortcut_flags & ~ImGuiInputFlags_Repeat); const bool is_select_all = Shortcut(ImGuiMod_Shortcut | ImGuiKey_A, id);
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful. // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true); const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true);
const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false)); const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false));
const bool is_cancel = Shortcut(ImGuiKey_Escape, id, shortcut_flags) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadCancel, false)); const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat));
// FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of.
if (IsKeyPressed(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 (IsKeyPressed(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 (IsKeyPressed(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 (IsKeyPressed(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 (IsKeyPressed(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 (IsKeyPressed(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); }
@ -4686,11 +4687,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
searches_result_line_no[1] = line_count; searches_result_line_no[1] = line_count;
// Calculate 2d position by finding the beginning of the line and measuring distance // Calculate 2d position by finding the beginning of the line and measuring distance
cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; cursor_offset.x = InputTextCalcTextSizeW(&g, ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x;
cursor_offset.y = searches_result_line_no[0] * g.FontSize; cursor_offset.y = searches_result_line_no[0] * g.FontSize;
if (searches_result_line_no[1] >= 0) if (searches_result_line_no[1] >= 0)
{ {
select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; select_start_offset.x = InputTextCalcTextSizeW(&g, ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x;
select_start_offset.y = searches_result_line_no[1] * g.FontSize; select_start_offset.y = searches_result_line_no[1] * g.FontSize;
} }
@ -4759,7 +4760,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
} }
else else
{ {
ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); ImVec2 rect_size = InputTextCalcTextSizeW(&g, p, text_selected_end, &p, NULL, true);
if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines if (rect_size.x <= 0.0f) rect_size.x = IM_FLOOR(g.Font->GetCharAdvance((ImWchar)' ') * 0.50f); // So we can see selected empty lines
ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn));
rect.ClipWith(clip_rect); rect.ClipWith(clip_rect);
@ -4868,6 +4869,7 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state)
Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId); Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId);
DebugLocateItemOnHover(state->ID); DebugLocateItemOnHover(state->ID);
Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end); Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end);
Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x);
Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point); Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point);
if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state
{ {
@ -5115,7 +5117,10 @@ 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))
{ {
// Position not necessarily next to last submitted button (e.g. if style.ColorButtonPosition == ImGuiDir_Left),
// but we need to use SameLine() to setup baseline correctly. Might want to refactor SameLine() to simplify this.
SameLine(0.0f, style.ItemInnerSpacing.x); SameLine(0.0f, style.ItemInnerSpacing.x);
window->DC.CursorPos.x = pos.x + ((flags & ImGuiColorEditFlags_NoInputs) ? w_button : w_full + style.ItemInnerSpacing.x);
TextEx(label, label_display_end); TextEx(label, label_display_end);
} }
@ -6376,8 +6381,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; g.LastItemData.StatusFlags |= 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);
@ -7722,7 +7725,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal); window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, tab_bar->BarRect.Min.x + tab_bar->WidthAllTabsIdeal);
} }
// Dockable uses Name/ID in the global namespace. Non-dockable items use the ID stack. // Dockable windows uses Name/ID in the global namespace. Non-dockable items use the ID stack.
static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window) static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window)
{ {
if (docked_window != NULL) if (docked_window != NULL)
@ -8178,18 +8181,17 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
tab->Flags = flags; tab->Flags = flags;
tab->Window = docked_window; tab->Window = docked_window;
// Append name with zero-terminator // Append name _WITH_ the zero-terminator
// (regular tabs are permitted in a DockNode tab bar, but window tabs not permitted in a non-DockNode tab bar) // (regular tabs are permitted in a DockNode tab bar, but window tabs not permitted in a non-DockNode tab bar)
if (tab->Window != NULL) if (docked_window != NULL)
{ {
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode); IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
tab->NameOffset = -1; tab->NameOffset = -1;
} }
else else
{ {
IM_ASSERT(tab->Window == NULL);
tab->NameOffset = (ImS32)tab_bar->TabsNames.size(); tab->NameOffset = (ImS32)tab_bar->TabsNames.size();
tab_bar->TabsNames.append(label, label + strlen(label) + 1); // Append name _with_ the zero-terminator. tab_bar->TabsNames.append(label, label + strlen(label) + 1);
} }
// Update selected tab // Update selected tab

View File

@ -2,6 +2,7 @@
// This is a slightly modified version of stb_textedit.h 1.14. // This is a slightly modified version of stb_textedit.h 1.14.
// Those changes would need to be pushed into nothings/stb: // Those changes would need to be pushed into nothings/stb:
// - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321)
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000)
// Grep for [DEAR IMGUI] to find the changes. // Grep for [DEAR IMGUI] to find the changes.
// stb_textedit.h - v1.14 - public domain - Sean Barrett // stb_textedit.h - v1.14 - public domain - Sean Barrett
@ -524,29 +525,14 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
int z = STB_TEXTEDIT_STRINGLEN(str); int z = STB_TEXTEDIT_STRINGLEN(str);
int i=0, first; int i=0, first;
if (n == z) { if (n == z && single_line) {
// if it's at the end, then find the last line -- simpler than trying to // special case if it's at the end (may not be needed?)
// explicitly handle this case in the regular code
if (single_line) {
STB_TEXTEDIT_LAYOUTROW(&r, str, 0); STB_TEXTEDIT_LAYOUTROW(&r, str, 0);
find->y = 0; find->y = 0;
find->first_char = 0; find->first_char = 0;
find->length = z; find->length = z;
find->height = r.ymax - r.ymin; find->height = r.ymax - r.ymin;
find->x = r.x1; find->x = r.x1;
} else {
find->y = 0;
find->x = 0;
find->height = 1;
while (i < z) {
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
prev_start = i;
i += r.num_chars;
}
find->first_char = i;
find->length = 0;
find->prev_first = prev_start;
}
return; return;
} }
@ -557,9 +543,13 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s
STB_TEXTEDIT_LAYOUTROW(&r, str, i); STB_TEXTEDIT_LAYOUTROW(&r, str, i);
if (n < i + r.num_chars) if (n < i + r.num_chars)
break; break;
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
break; // [DEAR IMGUI]
prev_start = i; prev_start = i;
i += r.num_chars; i += r.num_chars;
find->y += r.baseline_y_delta; find->y += r.baseline_y_delta;
if (i == z) // [DEAR IMGUI]
break; // [DEAR IMGUI]
} }
find->first_char = first = i; find->first_char = first = i;

View File

@ -2008,7 +2008,7 @@ static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int gly
start = end; start = end;
} }
} }
if (fdselector == -1) stbtt__new_buf(NULL, 0); if (fdselector == -1) return stbtt__new_buf(NULL, 0); // [DEAR IMGUI] fixed, see #6007 and nothings/stb#1422
return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector));
} }

View File

@ -6,6 +6,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)
// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly.
// 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL. // 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL.
// 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. // 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs.
// 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format. // 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format.
@ -586,7 +587,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u
ImVector<stbrp_node> pack_nodes; ImVector<stbrp_node> pack_nodes;
pack_nodes.resize(num_nodes_for_packing_algorithm); pack_nodes.resize(num_nodes_for_packing_algorithm);
stbrp_context pack_context; stbrp_context pack_context;
stbrp_init_target(&pack_context, atlas->TexWidth, TEX_HEIGHT_MAX, pack_nodes.Data, pack_nodes.Size); stbrp_init_target(&pack_context, atlas->TexWidth - atlas->TexGlyphPadding, TEX_HEIGHT_MAX - atlas->TexGlyphPadding, pack_nodes.Data, pack_nodes.Size);
ImFontAtlasBuildPackCustomRects(atlas, &pack_context); ImFontAtlasBuildPackCustomRects(atlas, &pack_context);
// 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point. // 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point.

View File

@ -20,7 +20,9 @@
// 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)
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty.
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785) // 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported). // 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
@ -284,26 +286,16 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
} }
} }
static int ImGui_ImplGlfw_KeyToModifier(int key) // X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW
{ // See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630
if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL) static void ImGui_ImplGlfw_UpdateKeyModifiers()
return GLFW_MOD_CONTROL;
if (key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT)
return GLFW_MOD_SHIFT;
if (key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT)
return GLFW_MOD_ALT;
if (key == GLFW_KEY_LEFT_SUPER || key == GLFW_KEY_RIGHT_SUPER)
return GLFW_MOD_SUPER;
return 0;
}
static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.AddKeyEvent(ImGuiMod_Ctrl, (mods & GLFW_MOD_CONTROL) != 0); ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
io.AddKeyEvent(ImGuiMod_Shift, (mods & GLFW_MOD_SHIFT) != 0); io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS));
io.AddKeyEvent(ImGuiMod_Alt, (mods & GLFW_MOD_ALT) != 0); io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS));
io.AddKeyEvent(ImGuiMod_Super, (mods & GLFW_MOD_SUPER) != 0); io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS));
io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS));
} }
void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
@ -312,7 +304,7 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti
if (bd->PrevUserCallbackMousebutton != nullptr && window == bd->Window) if (bd->PrevUserCallbackMousebutton != nullptr && window == bd->Window)
bd->PrevUserCallbackMousebutton(window, button, action, mods); bd->PrevUserCallbackMousebutton(window, button, action, mods);
ImGui_ImplGlfw_UpdateKeyModifiers(mods); ImGui_ImplGlfw_UpdateKeyModifiers();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
if (button >= 0 && button < ImGuiMouseButton_COUNT) if (button >= 0 && button < ImGuiMouseButton_COUNT)
@ -339,7 +331,12 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
// This won't cover edge cases but this is at least going to cover common cases. // This won't cover edge cases but this is at least going to cover common cases.
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL) if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_EQUAL)
return key; return key;
GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr);
const char* key_name = glfwGetKeyName(key, scancode); const char* key_name = glfwGetKeyName(key, scancode);
glfwSetErrorCallback(prev_error_callback);
#if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5908)
(void)glfwGetError(NULL);
#endif
if (key_name && key_name[0] != 0 && key_name[1] == 0) if (key_name && key_name[0] != 0 && key_name[1] == 0)
{ {
const char char_names[] = "`-=[]\\,;\'./"; const char char_names[] = "`-=[]\\,;\'./";
@ -366,10 +363,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
if (action != GLFW_PRESS && action != GLFW_RELEASE) if (action != GLFW_PRESS && action != GLFW_RELEASE)
return; return;
// Workaround: X11 does not include current pressed/released modifier key in 'mods' flags. https://github.com/glfw/glfw/issues/1630 ImGui_ImplGlfw_UpdateKeyModifiers();
if (int keycode_to_mod = ImGui_ImplGlfw_KeyToModifier(keycode))
mods = (action == GLFW_PRESS) ? (mods | keycode_to_mod) : (mods & ~keycode_to_mod);
ImGui_ImplGlfw_UpdateKeyModifiers(mods);
if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows)) if (keycode >= 0 && keycode < IM_ARRAYSIZE(bd->KeyOwnerWindows))
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr; bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
@ -540,10 +534,10 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); bd->MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); bd->MouseCursors[ImGuiMouseCursor_NotAllowed] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
#endif #endif
glfwSetErrorCallback(prev_error_callback);
#if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5785) #if (GLFW_VERSION_COMBINED >= 3300) // Eat errors (see #5785)
(void)glfwGetError(NULL); (void)glfwGetError(NULL);
#endif #endif
glfwSetErrorCallback(prev_error_callback);
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any. // Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
if (install_callbacks) if (install_callbacks)

View File

@ -15,7 +15,8 @@
// 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)
// 2022-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. // 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes).
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'. // 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'.
// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127). // 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
@ -111,6 +112,10 @@
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#endif #endif
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types
#endif
// GL includes // GL includes
#if defined(IMGUI_IMPL_OPENGL_ES2) #if defined(IMGUI_IMPL_OPENGL_ES2)
@ -278,12 +283,15 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
} }
bd->GlVersion = (GLuint)(major * 100 + minor * 10); bd->GlVersion = (GLuint)(major * 100 + minor * 10);
bd->UseBufferSubData = false;
/*
// Query vendor to enable glBufferSubData kludge // Query vendor to enable glBufferSubData kludge
#ifdef _WIN32 #ifdef _WIN32
if (const char* vendor = (const char*)glGetString(GL_VENDOR)) if (const char* vendor = (const char*)glGetString(GL_VENDOR))
if (strncmp(vendor, "Intel", 5) == 0) if (strncmp(vendor, "Intel", 5) == 0)
bd->UseBufferSubData = true; bd->UseBufferSubData = true;
#endif #endif
*/
#else #else
bd->GlVersion = 200; // GLES 2 bd->GlVersion = 200; // GLES 2
#endif #endif
@ -506,9 +514,13 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
// Upload vertex/index buffers // Upload vertex/index buffers
// - On Intel windows drivers we got reports that regular glBufferData() led to accumulating leaks when using multi-viewports, so we started using orphaning + glBufferSubData(). (See https://github.com/ocornut/imgui/issues/4468) // - OpenGL drivers are in a very sorry state nowadays....
// - On NVIDIA drivers we got reports that using orphaning + glBufferSubData() led to glitches when using multi-viewports. // During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
// - OpenGL drivers are in a very sorry state in 2022, for now we are switching code path based on vendors. // of leaks on Intel GPU when using multi-viewports on Windows.
// - After this we kept hearing of various display corruptions issues. We started disabling on non-Intel GPU, but issues still got reported on Intel.
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert); const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx); const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
if (bd->UseBufferSubData) if (bd->UseBufferSubData)
@ -916,6 +928,9 @@ static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
ImGui::DestroyPlatformWindows(); ImGui::DestroyPlatformWindows();
} }
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif