mirror of
https://github.com/ocornut/imgui.git
synced 2024-12-01 11:39:15 +08:00
Merge branch 'master' into docking
# Conflicts: # docs/CHANGELOG.txt # imgui.cpp # imgui.h
This commit is contained in:
commit
3ea0fad204
@ -7,7 +7,7 @@
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-11-30: Renderer: Restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5.
|
||||
// 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-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
@ -37,6 +38,7 @@
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName/io.BackendRendererName so they can be displayed in the About Window.
|
||||
// 2018-06-13: Platform: Added clipboard support (from Allegro 5.1.12).
|
||||
// 2018-06-13: Renderer: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-06-13: Renderer: Stopped using al_draw_indexed_prim() as it is buggy in Allegro's DX9 backend.
|
||||
// 2018-06-13: Renderer: Backup/restore transform and clipping rectangle.
|
||||
// 2018-06-11: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors flag + honor ImGuiConfigFlags_NoMouseCursorChange flag.
|
||||
// 2018-04-18: Misc: Renamed file from imgui_impl_a5.cpp to imgui_impl_allegro5.cpp.
|
||||
@ -56,13 +58,27 @@
|
||||
#ifdef _WIN32
|
||||
#include <allegro5/allegro_windows.h>
|
||||
#endif
|
||||
#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM (ALLEGRO_VERSION_INT >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4127) // condition expression is constant
|
||||
#endif
|
||||
|
||||
struct ImDrawVertAllegro
|
||||
{
|
||||
ImVec2 pos;
|
||||
ImVec2 uv;
|
||||
ALLEGRO_COLOR col;
|
||||
};
|
||||
|
||||
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 float as well..
|
||||
// FIXME-OPT: Consider inlining al_map_rgba()?
|
||||
// see https://github.com/liballeg/allegro5/blob/master/src/pixels.c#L554
|
||||
// and https://github.com/liballeg/allegro5/blob/master/include/allegro5/internal/aintern_pixels.h
|
||||
#define DRAW_VERT_IMGUI_TO_ALLEGRO(DST, SRC) { (DST)->pos = (SRC)->pos; (DST)->uv = (SRC)->uv; unsigned char* c = (unsigned char*)&(SRC)->col; (DST)->col = al_map_rgba(c[0], c[1], c[2], c[3]); }
|
||||
|
||||
// Allegro Data
|
||||
struct ImGui_ImplAllegro5_Data
|
||||
{
|
||||
@ -73,6 +89,9 @@ struct ImGui_ImplAllegro5_Data
|
||||
ALLEGRO_VERTEX_DECL* VertexDecl;
|
||||
char* ClipboardTextData;
|
||||
|
||||
ImVector<ImDrawVertAllegro> BufVertices;
|
||||
ImVector<int> BufIndices;
|
||||
|
||||
ImGui_ImplAllegro5_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
@ -81,13 +100,6 @@ struct ImGui_ImplAllegro5_Data
|
||||
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
||||
static ImGui_ImplAllegro5_Data* ImGui_ImplAllegro5_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplAllegro5_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr; }
|
||||
|
||||
struct ImDrawVertAllegro
|
||||
{
|
||||
ImVec2 pos;
|
||||
ImVec2 uv;
|
||||
ALLEGRO_COLOR col;
|
||||
};
|
||||
|
||||
static void ImGui_ImplAllegro5_SetupRenderState(ImDrawData* draw_data)
|
||||
{
|
||||
// Setup blending
|
||||
@ -132,35 +144,40 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
|
||||
// Allegro's implementation of al_draw_indexed_prim() for DX9 is completely broken. Unindex our buffers ourselves.
|
||||
// FIXME-OPT: Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 float as well..
|
||||
static ImVector<ImDrawVertAllegro> vertices;
|
||||
vertices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
|
||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
vertices.resize(cmd_list->VtxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
dst_v->pos = src_v->pos;
|
||||
dst_v->uv = src_v->uv;
|
||||
unsigned char* c = (unsigned char*)&src_v->col;
|
||||
dst_v->col = al_map_rgba(c[0], c[1], c[2], c[3]);
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
|
||||
const int* indices = nullptr;
|
||||
if (sizeof(ImDrawIdx) == 2)
|
||||
{
|
||||
// FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices.. You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
||||
// FIXME-OPT: Allegro doesn't support 16-bit indices.
|
||||
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
||||
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
|
||||
static ImVector<int> indices_converted;
|
||||
indices_converted.resize(cmd_list->IdxBuffer.Size);
|
||||
bd->BufIndices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
|
||||
indices_converted[i] = (int)cmd_list->IdxBuffer.Data[i];
|
||||
indices = indices_converted.Data;
|
||||
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i];
|
||||
indices = bd->BufIndices.Data;
|
||||
}
|
||||
else if (sizeof(ImDrawIdx) == 4)
|
||||
{
|
||||
indices = (const int*)cmd_list->IdxBuffer.Data;
|
||||
}
|
||||
#else
|
||||
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
|
||||
vertices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Render command lists
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
@ -187,7 +204,11 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
// Apply scissor/clipping rectangle, Draw
|
||||
ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID();
|
||||
al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x - clip_min.x, clip_max.y - clip_min.y);
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
al_draw_indexed_prim(&vertices[0], bd->VertexDecl, texture, &indices[pcmd->IdxOffset], pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
#else
|
||||
al_draw_prim(&vertices[0], bd->VertexDecl, texture, pcmd->IdxOffset, pcmd->IdxOffset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
// dear imgui: Platform Backend for OSX / Cocoa
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..)
|
||||
// [ALPHA] Early backend, not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac.
|
||||
// - Not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac.
|
||||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
@ -1,6 +1,7 @@
|
||||
// dear imgui: Platform Backend for OSX / Cocoa
|
||||
// This needs to be used along with a Renderer (e.g. OpenGL2, OpenGL3, Vulkan, Metal..)
|
||||
// [ALPHA] Early backend, not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac.
|
||||
// - Not well tested. If you want a portable application, prefer using the GLFW or SDL platform Backends on Mac.
|
||||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
|
||||
// Implemented features:
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32-bits AND 64-bits applications)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
|
||||
// Implemented features:
|
||||
|
@ -98,16 +98,49 @@ Other changes:
|
||||
Note that Linux/Mac still have inconsistent support for multi-viewports. If you want to help see https://github.com/ocornut/imgui/issues/2117.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.2 WIP (In Progress)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Breaking changes:
|
||||
|
||||
Other changes:
|
||||
|
||||
- Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with
|
||||
zero triangles, which would makes the render loop of some backends assert (e.g. Metal with
|
||||
debugging, Allegro). (#4857, #5937)
|
||||
- Tables, Columns: Fixed cases where empty columns may lead to empty ImDrawCmd. (#4857, #5937)
|
||||
- Inputs, Scrolling: better selection of scrolling window when hovering nested windows
|
||||
and when backend/OS is emitting dual-axis wheeling inputs (typically touch pads on macOS).
|
||||
We now select a primary axis based on recent events, and select a target window based on it.
|
||||
We expect this behavior to be further improved/tweaked. (#3795, #4559) [@ocornut, @folays]
|
||||
- Text: fixed layouting of wrapped-text block when the last source line is above the
|
||||
clipping region. Regression added in 1.89. (#5720, #5919)
|
||||
- Fonts: added a 'void* UserData' field in ImFontAtlas, as a convenience for use by
|
||||
applications using multiple font atlases.
|
||||
- Demo: simplified "Inputs" section, moved contents to Metrics->Inputs.
|
||||
- Debug Tools: Metrics: added "Inputs" section, moved from Demo for consistency.
|
||||
- Misc: fixed parameters to IMGUI_DEBUG_LOG() not being dead-stripped when building
|
||||
with IMGUI_DISABLE_DEBUG_TOOLS is used. (#5901) [@Teselka]
|
||||
- Misc: fixed compile-time detection of SSE features on MSVC 32-bits builds. (#5943) [@TheMostDiligent]
|
||||
- Backends: Allegro5: restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5. (#5937) [@Espyo]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.89.1 (Released 2022-11-24)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.1
|
||||
|
||||
Other changes:
|
||||
|
||||
- Scrolling, Focus: fixed SetKeyboardFocusHere()/SetItemDefaultFocus() during a window-appearing
|
||||
frame (and associated lower-level functions e.g. ScrollToRectEx()) from not centering item. (#5902)
|
||||
- Inputs: fixed moving a window or drag and dropping from preventing input-owner-unaware code
|
||||
from accessing keys. (#5888, #4921, #456)
|
||||
- Inputs, IO: reworked ImGuiMod_Shortcut to redirect to Ctrl/Super at runtime instead of
|
||||
compile-time, being consistent with our support for io.ConfigMacOSXBehaviors and making it
|
||||
easier for bindings generators to process that value. (#5923, #456)
|
||||
- Inputs: fixed moving a window or drag and dropping from capturing mods. (#5888, #4921, #456)
|
||||
- Layout: fixed End()/EndChild() incorrectly asserting if users manipulates cursor position
|
||||
inside a collapsed/culled window and IMGUI_DISABLE_OBSOLETE_FUNCTIONS is enabled. (#5548, #5911)
|
||||
@ -150,6 +183,11 @@ Breaking changes:
|
||||
Without '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' this will silently be fixed until we obsolete it.
|
||||
(This incorrect pattern has been mentioned or suggested in: #4510, #3355, #1760, #1490, #4152, #150,
|
||||
threads have been amended to refer to this issue).
|
||||
- Inputs: ImGuiKey is now a typed enum, allowing ImGuiKey_XXX symbols to be named in debuggers. (#4921)
|
||||
This will require uses of legacy backend-dependent indices to be casted, e.g.
|
||||
- with imgui_impl_glfw: IsKeyPressed(GLFW_KEY_A) -> IsKeyPressed((ImGuiKey)GLFW_KEY_A);
|
||||
- with imgui_impl_win32: IsKeyPressed('A') -> IsKeyPressed((ImGuiKey)'A')
|
||||
- etc. however if you are upgrading code you might as well use the backend-agnostic IsKeyPressed(ImGuiKey_A) now.
|
||||
- Renamed and merged keyboard modifiers key enums and flags into a same set: (#4921, #456)
|
||||
- ImGuiKey_ModCtrl and ImGuiModFlags_Ctrl -> ImGuiMod_Ctrl
|
||||
- ImGuiKey_ModShift and ImGuiModFlags_Shift -> ImGuiMod_Shift
|
||||
@ -278,7 +316,6 @@ Other Changes:
|
||||
- ImDrawList: Not using alloca() anymore, lift single polygon size limits. (#5704, #1811)
|
||||
- Platform IME: [Windows] Removed call to ImmAssociateContextEx() leading to freeze on some setups.
|
||||
(#2589, #5535, #5264, #4972)
|
||||
- Misc: ImGuiKey is now a typed enum, allowing ImGuiKey_XXX symbols to be named in debuggers. (#4921)
|
||||
- Misc: better error reporting for PopStyleColor()/PopStyleVar() + easier to recover. (#1651)
|
||||
- Misc: io.Framerate moving average now converge in 60 frames instead of 120. (#5236, #4138)
|
||||
- Debug Tools: Debug Log: Visually locate items when hovering a 0xXXXXXXXX value. (#5855)
|
||||
|
@ -323,7 +323,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- font: fix AddRemapChar() to work before atlas has been built.
|
||||
- font: (api breaking) remove "TTF" from symbol names. also because it now supports OTF.
|
||||
- font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer?
|
||||
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
|
||||
- font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16-bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8?
|
||||
|
||||
- nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line? how about CTRL+Tab)
|
||||
! nav: never clear NavId on some setup (e.g. gamepad centric)
|
||||
|
334
imgui.cpp
334
imgui.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
@ -403,6 +403,11 @@ CODE
|
||||
the ImGuiKey_ModXXX were introduced in 1.87 and mostly used by backends.
|
||||
the ImGuiModFlags_XXX have been exposed in imgui.h but not really used by any public api only by third-party extensions.
|
||||
exceptionally commenting out the older ImGuiKeyModFlags_XXX names ahead of obsolescence schedule to reduce confusion and because they were not meant to be used anyway.
|
||||
- 2022/09/20 (1.89) - ImGuiKey is now a typed enum, allowing ImGuiKey_XXX symbols to be named in debuggers.
|
||||
this will require uses of legacy backend-dependent indices to be casted, e.g.
|
||||
- with imgui_impl_glfw: IsKeyPressed(GLFW_KEY_A) -> IsKeyPressed((ImGuiKey)GLFW_KEY_A);
|
||||
- with imgui_impl_win32: IsKeyPressed('A') -> IsKeyPressed((ImGuiKey)'A')
|
||||
- etc. However if you are upgrading code you might well use the better, backend-agnostic IsKeyPressed(ImGuiKey_A) now!
|
||||
- 2022/09/12 (1.89) - removed the bizarre legacy default argument for 'TreePush(const void* ptr = NULL)', always pass a pointer value explicitly. NULL/nullptr is ok but require cast, e.g. TreePush((void*)nullptr);
|
||||
- 2022/09/05 (1.89) - commented out redirecting functions/enums names that were marked obsolete in 1.77 and 1.78 (June 2020):
|
||||
- DragScalar(), DragScalarN(), DragFloat(), DragFloat2(), DragFloat3(), DragFloat4(): For old signatures ending with (..., const char* format, float power = 1.0f) -> use (..., format ImGuiSliderFlags_Logarithmic) if power != 1.0f.
|
||||
@ -1379,6 +1384,7 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
|
||||
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
|
||||
IM_ASSERT(ImGui::IsNamedKeyOrModKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API.
|
||||
IM_ASSERT(!ImGui::IsAliasKey(key)); // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events.
|
||||
IM_ASSERT(key != ImGuiMod_Shortcut); // We could easily support the translation here but it seems saner to not accept it (TestEngine perform a translation itself)
|
||||
|
||||
// Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data.
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
@ -2928,11 +2934,14 @@ bool ImGuiListClipper::Step()
|
||||
if (need_items_height && ItemsHeight > 0.0f)
|
||||
IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): computed ItemsHeight: %.2f.\n", ItemsHeight);
|
||||
if (ret)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): display %d to %d.\n", DisplayStart, DisplayEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): End.\n");
|
||||
if (!ret)
|
||||
End();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -4321,16 +4330,15 @@ static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt)
|
||||
rt->Entries.swap(rt->EntriesNext); // Swap new and old indexes
|
||||
}
|
||||
|
||||
// [Internal] Do not use directly (should read io.KeyMods instead)
|
||||
static ImGuiKeyChord GetMergedModsFromBools()
|
||||
// [Internal] Do not use directly
|
||||
static ImGuiKeyChord GetMergedModsFromKeys()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiKeyChord key_chord = 0;
|
||||
if (g.IO.KeyCtrl) { key_chord |= ImGuiMod_Ctrl; }
|
||||
if (g.IO.KeyShift) { key_chord |= ImGuiMod_Shift; }
|
||||
if (g.IO.KeyAlt) { key_chord |= ImGuiMod_Alt; }
|
||||
if (g.IO.KeySuper) { key_chord |= ImGuiMod_Super; }
|
||||
return key_chord;
|
||||
ImGuiKeyChord mods = 0;
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Ctrl)) { mods |= ImGuiMod_Ctrl; }
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Shift)) { mods |= ImGuiMod_Shift; }
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Alt)) { mods |= ImGuiMod_Alt; }
|
||||
if (ImGui::IsKeyDown(ImGuiMod_Super)) { mods |= ImGuiMod_Super; }
|
||||
return mods;
|
||||
}
|
||||
|
||||
static void ImGui::UpdateKeyboardInputs()
|
||||
@ -4403,16 +4411,24 @@ static void ImGui::UpdateKeyboardInputs()
|
||||
#undef NAV_MAP_KEY
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools, update aliases
|
||||
io.KeyMods = GetMergedModsFromBools();
|
||||
// Update aliases
|
||||
for (int n = 0; n < ImGuiMouseButton_COUNT; n++)
|
||||
UpdateAliasKey(MouseButtonToKey(n), io.MouseDown[n], io.MouseDown[n] ? 1.0f : 0.0f);
|
||||
UpdateAliasKey(ImGuiKey_MouseWheelX, io.MouseWheelH != 0.0f, io.MouseWheelH);
|
||||
UpdateAliasKey(ImGuiKey_MouseWheelY, io.MouseWheel != 0.0f, io.MouseWheel);
|
||||
|
||||
// Synchronize io.KeyMods and io.KeyXXX values.
|
||||
// - New backends (1.87+): send io.AddKeyEvent(ImGuiMod_XXX) -> -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
||||
// - Legacy backends: set io.KeyXXX bools -> (above) set key array from io.KeyXXX -> (here) deriving io.KeyMods + io.KeyXXX from key array.
|
||||
// So with legacy backends the 4 values will do a unnecessary back-and-forth but it makes the code simpler and future facing.
|
||||
io.KeyMods = GetMergedModsFromKeys();
|
||||
io.KeyCtrl = (io.KeyMods & ImGuiMod_Ctrl) != 0;
|
||||
io.KeyShift = (io.KeyMods & ImGuiMod_Shift) != 0;
|
||||
io.KeyAlt = (io.KeyMods & ImGuiMod_Alt) != 0;
|
||||
io.KeySuper = (io.KeyMods & ImGuiMod_Super) != 0;
|
||||
|
||||
// Clear gamepad data if disabled
|
||||
if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
|
||||
for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
|
||||
@ -4519,13 +4535,58 @@ static void LockWheelingWindow(ImGuiWindow* window, float wheel_amount)
|
||||
IMGUI_DEBUG_LOG_IO("LockWheelingWindow() \"%s\"\n", window ? window->Name : "NULL");
|
||||
g.WheelingWindow = window;
|
||||
g.WheelingWindowRefMousePos = g.IO.MousePos;
|
||||
if (window == NULL)
|
||||
{
|
||||
g.WheelingWindowStartFrame = -1;
|
||||
g.WheelingAxisAvg = ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static ImGuiWindow* FindBestWheelingWindow(const ImVec2& wheel)
|
||||
{
|
||||
// For each axis, find window in the hierarchy that may want to use scrolling
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* windows[2] = { NULL, NULL };
|
||||
for (int axis = 0; axis < 2; axis++)
|
||||
if (wheel[axis] != 0.0f)
|
||||
for (ImGuiWindow* window = windows[axis] = g.HoveredWindow; window->Flags & ImGuiWindowFlags_ChildWindow; window = windows[axis] = window->ParentWindow)
|
||||
{
|
||||
// Bubble up into parent window if:
|
||||
// - a child window doesn't allow any scrolling.
|
||||
// - a child window has the ImGuiWindowFlags_NoScrollWithMouse flag.
|
||||
//// - a child window doesn't need scrolling because it is already at the edge for the direction we are going in (FIXME-WIP)
|
||||
const bool has_scrolling = (window->ScrollMax[axis] != 0.0f);
|
||||
const bool inputs_disabled = (window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs);
|
||||
//const bool scrolling_past_limits = (wheel_v < 0.0f) ? (window->Scroll[axis] <= 0.0f) : (window->Scroll[axis] >= window->ScrollMax[axis]);
|
||||
if (has_scrolling && !inputs_disabled) // && !scrolling_past_limits)
|
||||
break; // select this window
|
||||
}
|
||||
if (windows[0] == NULL && windows[1] == NULL)
|
||||
return NULL;
|
||||
|
||||
// If there's only one window or only one axis then there's no ambiguity
|
||||
if (windows[0] == windows[1] || windows[0] == NULL || windows[1] == NULL)
|
||||
return windows[1] ? windows[1] : windows[0];
|
||||
|
||||
// If candidate are different windows we need to decide which one to prioritize
|
||||
// - First frame: only find a winner if one axis is zero.
|
||||
// - Subsequent frames: only find a winner when one is more than the other.
|
||||
if (g.WheelingWindowStartFrame == -1)
|
||||
g.WheelingWindowStartFrame = g.FrameCount;
|
||||
if ((g.WheelingWindowStartFrame == g.FrameCount && wheel.x != 0.0f && wheel.y != 0.0f) || (g.WheelingAxisAvg.x == g.WheelingAxisAvg.y))
|
||||
{
|
||||
g.WheelingWindowWheelRemainder = wheel;
|
||||
return NULL;
|
||||
}
|
||||
return (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? windows[0] : windows[1];
|
||||
}
|
||||
|
||||
void ImGui::UpdateMouseWheel()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Reset the locked window if we move the mouse or after the timer elapses
|
||||
// Reset the locked window if we move the mouse or after the timer elapses.
|
||||
// FIXME: Ideally we could refactor to have one timer for "changing window w/ same axis" and a shorter timer for "changing window or axis w/ other axis" (#3795)
|
||||
if (g.WheelingWindow != NULL)
|
||||
{
|
||||
g.WheelingWindowReleaseTimer -= g.IO.DeltaTime;
|
||||
@ -4538,8 +4599,6 @@ void ImGui::UpdateMouseWheel()
|
||||
ImVec2 wheel;
|
||||
wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_None) ? g.IO.MouseWheelH : 0.0f;
|
||||
wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_None) ? g.IO.MouseWheel : 0.0f;
|
||||
if (wheel.x == 0.0f && wheel.y == 0.0f)
|
||||
return;
|
||||
|
||||
//IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y);
|
||||
ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
|
||||
@ -4577,39 +4636,41 @@ void ImGui::UpdateMouseWheel()
|
||||
wheel.y = 0.0f;
|
||||
}
|
||||
|
||||
// Vertical Mouse Wheel scrolling
|
||||
// Bubble up into parent window if:
|
||||
// - a child window doesn't allow any scrolling.
|
||||
// - a child window doesn't need scrolling because it is already at the edge for the direction we are going in.
|
||||
// - a child window has the ImGuiWindowFlags_NoScrollWithMouse flag.
|
||||
if (wheel.y != 0.0f)
|
||||
{
|
||||
ImGuiWindow* window = mouse_window;
|
||||
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
|
||||
window = window->ParentWindow;
|
||||
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
||||
{
|
||||
LockWheelingWindow(mouse_window, wheel.y);
|
||||
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
||||
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
|
||||
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
||||
}
|
||||
}
|
||||
// Maintain a rough average of moving magnitude on both axises
|
||||
// FIXME: should by based on wall clock time rather than frame-counter
|
||||
g.WheelingAxisAvg.x = ImExponentialMovingAverage(g.WheelingAxisAvg.x, ImAbs(wheel.x), 30);
|
||||
g.WheelingAxisAvg.y = ImExponentialMovingAverage(g.WheelingAxisAvg.y, ImAbs(wheel.y), 30);
|
||||
|
||||
// Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held
|
||||
if (wheel.x != 0.0f)
|
||||
{
|
||||
ImGuiWindow* window = mouse_window;
|
||||
while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
|
||||
window = window->ParentWindow;
|
||||
// In the rare situation where FindBestWheelingWindow() had to defer first frame of wheeling due to ambiguous main axis, reinject it now.
|
||||
wheel += g.WheelingWindowWheelRemainder;
|
||||
g.WheelingWindowWheelRemainder = ImVec2(0.0f, 0.0f);
|
||||
if (wheel.x == 0.0f && wheel.y == 0.0f)
|
||||
return;
|
||||
|
||||
// Mouse wheel scrolling: find target and apply
|
||||
// - don't renew lock if axis doesn't apply on the window.
|
||||
// - select a main axis when both axises are being moved.
|
||||
if (ImGuiWindow* window = (g.WheelingWindow ? g.WheelingWindow : FindBestWheelingWindow(wheel)))
|
||||
if (!(window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))
|
||||
{
|
||||
LockWheelingWindow(mouse_window, wheel.x);
|
||||
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
||||
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
|
||||
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
||||
bool do_scroll[2] = { wheel.x != 0.0f && window->ScrollMax.x != 0.0f, wheel.y != 0.0f && window->ScrollMax.y != 0.0f };
|
||||
if (do_scroll[ImGuiAxis_X] && do_scroll[ImGuiAxis_Y])
|
||||
do_scroll[(g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? ImGuiAxis_Y : ImGuiAxis_X] = false;
|
||||
if (do_scroll[ImGuiAxis_X])
|
||||
{
|
||||
LockWheelingWindow(window, wheel.x);
|
||||
float max_step = window->InnerRect.GetWidth() * 0.67f;
|
||||
float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
|
||||
SetScrollX(window, window->Scroll.x - wheel.x * scroll_step);
|
||||
}
|
||||
if (do_scroll[ImGuiAxis_Y])
|
||||
{
|
||||
LockWheelingWindow(window, wheel.y);
|
||||
float max_step = window->InnerRect.GetHeight() * 0.67f;
|
||||
float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
|
||||
SetScrollY(window, window->Scroll.y - wheel.y * scroll_step);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
|
||||
@ -8566,9 +8627,12 @@ const char* ImGui::GetKeyName(ImGuiKey key)
|
||||
return GKeyNames[key - ImGuiKey_NamedKey_BEGIN];
|
||||
}
|
||||
|
||||
// ImGuiMod_Shortcut is translated to either Ctrl or Super.
|
||||
void ImGui::GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
ImFormatString(out_buf, (size_t)out_buf_size, "%s%s%s%s%s",
|
||||
(key_chord & ImGuiMod_Ctrl) ? "Ctrl+" : "",
|
||||
(key_chord & ImGuiMod_Shift) ? "Shift+" : "",
|
||||
@ -8644,6 +8708,8 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable;
|
||||
ImGuiKeyRoutingData* routing_data;
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
@ -8761,7 +8827,7 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI
|
||||
bool ImGui::TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id)
|
||||
{
|
||||
const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id);
|
||||
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord);
|
||||
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); // FIXME: Could avoid creating entry.
|
||||
return routing_data->RoutingCurr == routing_id;
|
||||
}
|
||||
|
||||
@ -9016,7 +9082,7 @@ static void DebugPrintInputEvent(const char* prefix, const ImGuiInputEvent* e)
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (e->Type == ImGuiInputEventType_MousePos) { if (e->MousePos.PosX == -FLT_MAX && e->MousePos.PosY == -FLT_MAX) IMGUI_DEBUG_LOG_IO("%s: MousePos (-FLT_MAX, -FLT_MAX)\n", prefix); else IMGUI_DEBUG_LOG_IO("%s: MousePos (%.1f, %.1f)\n", prefix, e->MousePos.PosX, e->MousePos.PosY); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseButton) { IMGUI_DEBUG_LOG_IO("%s: MouseButton %d %s\n", prefix, e->MouseButton.Button, e->MouseButton.Down ? "Down" : "Up"); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("%s: MouseWheel (%.1f, %.1f)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseWheel) { IMGUI_DEBUG_LOG_IO("%s: MouseWheel (%.3f, %.3f)\n", prefix, e->MouseWheel.WheelX, e->MouseWheel.WheelY); return; }
|
||||
if (e->Type == ImGuiInputEventType_MouseViewport){IMGUI_DEBUG_LOG_IO("%s: MouseViewport (0x%08X)\n", prefix, e->MouseViewport.HoveredViewportID); return; }
|
||||
if (e->Type == ImGuiInputEventType_Key) { IMGUI_DEBUG_LOG_IO("%s: Key \"%s\" %s\n", prefix, ImGui::GetKeyName(e->Key.Key), e->Key.Down ? "Down" : "Up"); return; }
|
||||
if (e->Type == ImGuiInputEventType_Text) { IMGUI_DEBUG_LOG_IO("%s: Text: %c (U+%08X)\n", prefix, e->Text.Char, e->Text.Char); return; }
|
||||
@ -9092,15 +9158,6 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
||||
key_changed = true;
|
||||
key_changed_mask.SetBit(key_data_index);
|
||||
|
||||
if (key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super)
|
||||
{
|
||||
if (key == ImGuiMod_Ctrl) { io.KeyCtrl = key_data->Down; }
|
||||
if (key == ImGuiMod_Shift) { io.KeyShift = key_data->Down; }
|
||||
if (key == ImGuiMod_Alt) { io.KeyAlt = key_data->Down; }
|
||||
if (key == ImGuiMod_Super) { io.KeySuper = key_data->Down; }
|
||||
io.KeyMods = GetMergedModsFromBools();
|
||||
}
|
||||
|
||||
// Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
io.KeysDown[key_data_index] = key_data->Down;
|
||||
@ -9257,12 +9314,14 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
|
||||
if (!SetShortcutRouting(key_chord, owner_id, flags))
|
||||
return false;
|
||||
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
if (key_chord & ImGuiMod_Shortcut)
|
||||
key_chord = ConvertShortcutMod(key_chord);
|
||||
ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
|
||||
if (g.IO.KeyMods != mods)
|
||||
return false;
|
||||
|
||||
// Special storage location for mods
|
||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||
if (key == ImGuiKey_None)
|
||||
key = ConvertSingleModFlagToKey(mods);
|
||||
|
||||
@ -9418,9 +9477,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
|
||||
// One possible reason leading to this assert is that your backends update inputs _AFTER_ NewFrame().
|
||||
// It is known that when some modal native windows called mid-frame takes focus away, some backends such as GLFW will
|
||||
// send key release events mid-frame. This would normally trigger this assertion and lead to sheared inputs.
|
||||
// We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0),
|
||||
// We silently accommodate for this case by ignoring the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0),
|
||||
// while still correctly asserting on mid-frame key press events.
|
||||
const ImGuiKeyChord key_mods = GetMergedModsFromBools();
|
||||
const ImGuiKeyChord key_mods = GetMergedModsFromKeys();
|
||||
IM_ASSERT((key_mods == 0 || g.IO.KeyMods == key_mods) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
|
||||
IM_UNUSED(key_mods);
|
||||
|
||||
@ -18416,6 +18475,55 @@ static int IMGUI_CDECL ViewportComparerByFrontMostStampCount(const void* lhs, co
|
||||
return b->LastFrontMostStampCount - a->LastFrontMostStampCount;
|
||||
}
|
||||
|
||||
// Draw an arbitrary US keyboard layout to visualize translated keys
|
||||
void ImGui::DebugRenderKeyboardPreview(ImDrawList* draw_list)
|
||||
{
|
||||
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 = 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.
|
||||
Dummy(board_max - board_min);
|
||||
if (!IsItemVisible())
|
||||
return;
|
||||
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 = key_min + key_size;
|
||||
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();
|
||||
}
|
||||
|
||||
// Helper tool to diagnose between text encoding issues and font loading issues. Pass your UTF-8 string and verify that there are correct.
|
||||
void ImGui::DebugTextEncoding(const char* str)
|
||||
{
|
||||
@ -18884,41 +18992,95 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
TreePop();
|
||||
}
|
||||
|
||||
if (TreeNode("Key Owners & Shortcut Routing"))
|
||||
if (TreeNode("Inputs"))
|
||||
{
|
||||
TextUnformatted("Key Owners:");
|
||||
if (BeginListBox("##owners", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 8)))
|
||||
Text("KEYBOARD/GAMEPAD/MOUSE KEYS");
|
||||
{
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
{
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
if (owner_data->OwnerCurr == ImGuiKeyOwner_None)
|
||||
continue;
|
||||
Text("%s: 0x%08X%s", GetKeyName(key), owner_data->OwnerCurr,
|
||||
owner_data->LockUntilRelease ? " LockUntilRelease" : owner_data->LockThisFrame ? " LockThisFrame" : "");
|
||||
DebugLocateItemOnHover(owner_data->OwnerCurr);
|
||||
}
|
||||
EndListBox();
|
||||
// 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.
|
||||
Indent();
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey) { return false; } };
|
||||
#else
|
||||
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
|
||||
//Text("Legacy raw:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key++) { if (io.KeysDown[key]) { SameLine(); Text("\"%s\" %d", GetKeyName(key), key); } }
|
||||
#endif
|
||||
Text("Keys down:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyDown(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); SameLine(); Text("(%.02f)", GetKeyData(key)->DownDuration); }
|
||||
Text("Keys pressed:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyPressed(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); }
|
||||
Text("Keys released:"); for (ImGuiKey key = ImGuiKey_KeysData_OFFSET; key < ImGuiKey_COUNT; key = (ImGuiKey)(key + 1)) { if (funcs::IsLegacyNativeDupe(key) || !IsKeyReleased(key)) continue; SameLine(); Text(IsNamedKey(key) ? "\"%s\"" : "\"%s\" %d", GetKeyName(key), key); }
|
||||
Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
|
||||
Text("Chars queue:"); for (int i = 0; i < io.InputQueueCharacters.Size; i++) { ImWchar c = io.InputQueueCharacters[i]; SameLine(); 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.
|
||||
DebugRenderKeyboardPreview(GetWindowDrawList());
|
||||
Unindent();
|
||||
}
|
||||
TextUnformatted("Shortcut Routing:");
|
||||
if (BeginListBox("##routes", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 8)))
|
||||
|
||||
Text("MOUSE STATE");
|
||||
{
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
Indent();
|
||||
if (IsMousePosValid())
|
||||
Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
|
||||
else
|
||||
Text("Mouse pos: <INVALID>");
|
||||
Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y);
|
||||
int count = IM_ARRAYSIZE(io.MouseDown);
|
||||
Text("Mouse down:"); for (int i = 0; i < count; i++) if (IsMouseDown(i)) { SameLine(); Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); }
|
||||
Text("Mouse clicked:"); for (int i = 0; i < count; i++) if (IsMouseClicked(i)) { SameLine(); Text("b%d (%d)", i, io.MouseClickedCount[i]); }
|
||||
Text("Mouse released:"); for (int i = 0; i < count; i++) if (IsMouseReleased(i)) { SameLine(); Text("b%d", i); }
|
||||
Text("Mouse wheel: %.1f", io.MouseWheel);
|
||||
Text("Pen Pressure: %.1f", io.PenPressure); // Note: currently unused
|
||||
Unindent();
|
||||
}
|
||||
|
||||
Text("MOUSE WHEELING");
|
||||
{
|
||||
Indent();
|
||||
Text("WheelingWindow: '%s'", g.WheelingWindow ? g.WheelingWindow->Name : "NULL");
|
||||
Text("WheelingWindowReleaseTimer: %.2f", g.WheelingWindowReleaseTimer);
|
||||
Text("WheelingAxisAvg[] = { %.3f, %.3f }, Main Axis: %s", g.WheelingAxisAvg.x, g.WheelingAxisAvg.y, (g.WheelingAxisAvg.x > g.WheelingAxisAvg.y) ? "X" : (g.WheelingAxisAvg.x < g.WheelingAxisAvg.y) ? "Y" : "<none>");
|
||||
Unindent();
|
||||
}
|
||||
|
||||
Text("KEY OWNERS");
|
||||
{
|
||||
Indent();
|
||||
if (BeginListBox("##owners", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 6)))
|
||||
{
|
||||
ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable;
|
||||
for (ImGuiKeyRoutingIndex idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; idx != -1; )
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
{
|
||||
char key_chord_name[64];
|
||||
ImGuiKeyRoutingData* routing_data = &rt->Entries[idx];
|
||||
GetKeyChordName(key | routing_data->Mods, key_chord_name, IM_ARRAYSIZE(key_chord_name));
|
||||
Text("%s: 0x%08X", key_chord_name, routing_data->RoutingCurr);
|
||||
DebugLocateItemOnHover(routing_data->RoutingCurr);
|
||||
idx = routing_data->NextEntryIndex;
|
||||
ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(key);
|
||||
if (owner_data->OwnerCurr == ImGuiKeyOwner_None)
|
||||
continue;
|
||||
Text("%s: 0x%08X%s", GetKeyName(key), owner_data->OwnerCurr,
|
||||
owner_data->LockUntilRelease ? " LockUntilRelease" : owner_data->LockThisFrame ? " LockThisFrame" : "");
|
||||
DebugLocateItemOnHover(owner_data->OwnerCurr);
|
||||
}
|
||||
EndListBox();
|
||||
}
|
||||
EndListBox();
|
||||
Unindent();
|
||||
}
|
||||
Text("SHORTCUT ROUTING");
|
||||
{
|
||||
Indent();
|
||||
if (BeginListBox("##routes", ImVec2(-FLT_MIN, GetTextLineHeightWithSpacing() * 6)))
|
||||
{
|
||||
for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1))
|
||||
{
|
||||
ImGuiKeyRoutingTable* rt = &g.KeysRoutingTable;
|
||||
for (ImGuiKeyRoutingIndex idx = rt->Index[key - ImGuiKey_NamedKey_BEGIN]; idx != -1; )
|
||||
{
|
||||
char key_chord_name[64];
|
||||
ImGuiKeyRoutingData* routing_data = &rt->Entries[idx];
|
||||
GetKeyChordName(key | routing_data->Mods, key_chord_name, IM_ARRAYSIZE(key_chord_name));
|
||||
Text("%s: 0x%08X", key_chord_name, routing_data->RoutingCurr);
|
||||
DebugLocateItemOnHover(routing_data->RoutingCurr);
|
||||
idx = routing_data->NextEntryIndex;
|
||||
}
|
||||
}
|
||||
EndListBox();
|
||||
}
|
||||
Text("(ActiveIdUsing: AllKeyboardKeys: %d, NavDirMask: 0x%X)", g.ActiveIdUsingAllKeyboardKeys, g.ActiveIdUsingNavDirMask);
|
||||
Unindent();
|
||||
}
|
||||
Text("(ActiveIdUsing: AllKeyboardKeys: %d, NavDirMask: 0x%X)", g.ActiveIdUsingAllKeyboardKeys, g.ActiveIdUsingNavDirMask);
|
||||
TreePop();
|
||||
}
|
||||
|
||||
|
21
imgui.h
21
imgui.h
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@ -22,8 +22,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
||||
#define IMGUI_VERSION "1.89.1"
|
||||
#define IMGUI_VERSION_NUM 18910
|
||||
#define IMGUI_VERSION "1.89.2 WIP"
|
||||
#define IMGUI_VERSION_NUM 18914
|
||||
#define IMGUI_HAS_TABLE
|
||||
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
|
||||
#define IMGUI_HAS_DOCK // Docking WIP branch
|
||||
@ -1491,7 +1491,7 @@ enum ImGuiKey : int
|
||||
ImGuiKey_GamepadRStickUp, // [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.
|
||||
ImGuiKey_MouseLeft, ImGuiKey_MouseRight, ImGuiKey_MouseMiddle, ImGuiKey_MouseX1, ImGuiKey_MouseX2, ImGuiKey_MouseWheelX, ImGuiKey_MouseWheelY,
|
||||
|
||||
@ -1512,12 +1512,8 @@ enum ImGuiKey : int
|
||||
ImGuiMod_Shift = 1 << 13,
|
||||
ImGuiMod_Alt = 1 << 14, // Option/Menu
|
||||
ImGuiMod_Super = 1 << 15, // Cmd/Super/Windows
|
||||
ImGuiMod_Mask_ = 0xF000,
|
||||
#if defined(__APPLE__)
|
||||
ImGuiMod_Shortcut = ImGuiMod_Super,
|
||||
#else
|
||||
ImGuiMod_Shortcut = ImGuiMod_Ctrl,
|
||||
#endif
|
||||
ImGuiMod_Shortcut = 1 << 11, // [Internal, read-only] Alias of ImGuiMod_Super (macOS) or ImGuiMod_Ctrl (otherwise), decided by io.ConfigMacOSXBehaviors.
|
||||
ImGuiMod_Mask_ = 0xF800, // 5-bits
|
||||
|
||||
// [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)
|
||||
@ -1991,7 +1987,7 @@ struct ImGuiIO
|
||||
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 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.
|
||||
float FontGlobalScale; // = 1.0f // Global scale all fonts
|
||||
@ -2118,7 +2114,7 @@ struct ImGuiIO
|
||||
bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows
|
||||
|
||||
// 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.
|
||||
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)
|
||||
@ -2925,6 +2921,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 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.
|
||||
void* UserData; // Store your own atlas related user-data (if e.g. you have multiple font atlas).
|
||||
|
||||
// [Internal]
|
||||
// NB: Access texture data via GetTexData*() calls! Which will setup a default font for you.
|
||||
|
202
imgui_demo.cpp
202
imgui_demo.cpp
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@ -5759,15 +5759,47 @@ namespace ImGui { extern ImGuiKeyData* GetKeyData(ImGuiKey key); }
|
||||
|
||||
static void ShowDemoWindowInputs()
|
||||
{
|
||||
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus");
|
||||
if (ImGui::CollapsingHeader("Inputs, Navigation & Focus"))
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus");
|
||||
if (ImGui::CollapsingHeader("Inputs & Focus"))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Display ImGuiIO output flags
|
||||
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Output");
|
||||
// Display inputs submitted to ImGuiIO
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Inputs");
|
||||
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"))
|
||||
{
|
||||
ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse);
|
||||
ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
|
||||
@ -5778,127 +5810,8 @@ static void ShowDemoWindowInputs()
|
||||
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();
|
||||
}
|
||||
|
||||
// Display mouse cursors
|
||||
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Mouse Cursors");
|
||||
if (ImGui::TreeNode("Mouse Cursors"))
|
||||
{
|
||||
const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" };
|
||||
IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT);
|
||||
|
||||
ImGuiMouseCursor current = ImGui::GetMouseCursor();
|
||||
ImGui::Text("Current mouse cursor = %d: %s", current, mouse_cursors_names[current]);
|
||||
ImGui::BeginDisabled(true);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Text("Hover to see mouse cursors:");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. "
|
||||
"If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, "
|
||||
"otherwise your backend needs to handle it.");
|
||||
for (int i = 0; i < ImGuiMouseCursor_COUNT; i++)
|
||||
{
|
||||
char label[32];
|
||||
sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]);
|
||||
ImGui::Bullet(); ImGui::Selectable(label, false);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetMouseCursor(i);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Display Keyboard/Mouse state
|
||||
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"))
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/IO Output: Capture override");
|
||||
if (ImGui::TreeNode("IO Output: Capture override"))
|
||||
{
|
||||
HelpMarker(
|
||||
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
|
||||
@ -5932,7 +5845,36 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Tabbing");
|
||||
// Display mouse cursors
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors");
|
||||
if (ImGui::TreeNode("Mouse Cursors"))
|
||||
{
|
||||
const char* mouse_cursors_names[] = { "Arrow", "TextInput", "ResizeAll", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE", "Hand", "NotAllowed" };
|
||||
IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT);
|
||||
|
||||
ImGuiMouseCursor current = ImGui::GetMouseCursor();
|
||||
ImGui::Text("Current mouse cursor = %d: %s", current, mouse_cursors_names[current]);
|
||||
ImGui::BeginDisabled(true);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", &io.BackendFlags, ImGuiBackendFlags_HasMouseCursors);
|
||||
ImGui::EndDisabled();
|
||||
|
||||
ImGui::Text("Hover to see mouse cursors:");
|
||||
ImGui::SameLine(); HelpMarker(
|
||||
"Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. "
|
||||
"If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, "
|
||||
"otherwise your backend needs to handle it.");
|
||||
for (int i = 0; i < ImGuiMouseCursor_COUNT; i++)
|
||||
{
|
||||
char label[32];
|
||||
sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]);
|
||||
ImGui::Bullet(); ImGui::Selectable(label, false);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetMouseCursor(i);
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Tabbing");
|
||||
if (ImGui::TreeNode("Tabbing"))
|
||||
{
|
||||
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
|
||||
@ -5948,7 +5890,7 @@ static void ShowDemoWindowInputs()
|
||||
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"))
|
||||
{
|
||||
bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine();
|
||||
@ -5990,7 +5932,7 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
IMGUI_DEMO_MARKER("Inputs, Navigation & Focus/Dragging");
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Dragging");
|
||||
if (ImGui::TreeNode("Dragging"))
|
||||
{
|
||||
ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (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
|
||||
void ImDrawList::_PopUnusedDrawCmd()
|
||||
{
|
||||
if (CmdBuffer.Size == 0)
|
||||
return;
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
if (curr_cmd->ElemCount == 0 && curr_cmd->UserCallback == NULL)
|
||||
while (CmdBuffer.Size > 0)
|
||||
{
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
if (curr_cmd->ElemCount != 0 || curr_cmd->UserCallback != NULL)
|
||||
return;// break;
|
||||
CmdBuffer.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPositionA().
|
||||
// If the specs for CalcWordWrapPositionA() were reworked to optionally return on \n we could combine both.
|
||||
// However it is still better than nothing performing the fast-forward!
|
||||
s = CalcWordWrapPositionA(scale, s, line_end, wrap_width);
|
||||
s = CalcWordWrapPositionA(scale, s, line_next, wrap_width);
|
||||
s = CalcWordWrapNextLineStartA(s, text_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = line_end ? line_end + 1 : text_end;
|
||||
s = line_next;
|
||||
}
|
||||
y += line_height;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (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!
|
||||
@ -56,7 +56,7 @@ Index of this file:
|
||||
#include <limits.h> // INT_MIN, INT_MAX
|
||||
|
||||
// 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
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
@ -219,7 +219,11 @@ namespace ImStb
|
||||
#endif
|
||||
|
||||
// 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__)
|
||||
#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_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)
|
||||
@ -483,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 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 float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Geometry
|
||||
@ -1056,6 +1061,7 @@ struct IMGUI_API ImGuiMenuColumns
|
||||
// For a given item ID, access with ImGui::GetInputTextState()
|
||||
struct IMGUI_API ImGuiInputTextState
|
||||
{
|
||||
ImGuiContext* Ctx; // parent dear imgui context
|
||||
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.
|
||||
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.
|
||||
@ -1071,7 +1077,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
bool Edited; // edited this frame
|
||||
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 ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
|
||||
int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
|
||||
@ -1312,7 +1318,7 @@ typedef ImS16 ImGuiKeyRoutingIndex;
|
||||
struct ImGuiKeyRoutingData
|
||||
{
|
||||
ImGuiKeyRoutingIndex NextEntryIndex;
|
||||
ImU16 Mods; // Technically we'd only need 4 bits but for simplify we store ImGuiMod_ values which need 16 bits.
|
||||
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)
|
||||
ImGuiID RoutingCurr;
|
||||
ImGuiID RoutingNext;
|
||||
@ -1943,7 +1949,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* 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;
|
||||
int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
|
||||
float WheelingWindowReleaseTimer;
|
||||
ImVec2 WheelingWindowWheelRemainder;
|
||||
ImVec2 WheelingAxisAvg;
|
||||
|
||||
// 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]
|
||||
@ -2202,6 +2211,7 @@ struct ImGuiContext
|
||||
ImVector<char> TempBuffer; // Temporary text buffer
|
||||
|
||||
ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
: InputTextState(this)
|
||||
{
|
||||
Initialized = false;
|
||||
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
|
||||
@ -2223,6 +2233,7 @@ struct ImGuiContext
|
||||
HoveredWindowUnderMovingWindow = NULL;
|
||||
MovingWindow = NULL;
|
||||
WheelingWindow = NULL;
|
||||
WheelingWindowStartFrame = -1;
|
||||
WheelingWindowReleaseTimer = 0.0f;
|
||||
|
||||
DebugHookIdInfo = 0;
|
||||
@ -3098,18 +3109,21 @@ namespace ImGui
|
||||
// Inputs
|
||||
// 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 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 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 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 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)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl;
|
||||
if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift;
|
||||
if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt;
|
||||
if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper;
|
||||
if (key == ImGuiMod_Shortcut) return (g.IO.ConfigMacOSXBehaviors ? ImGuiKey_ReservedForModSuper : ImGuiKey_ReservedForModCtrl);
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -3446,6 +3460,7 @@ namespace ImGui
|
||||
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 DebugNodeViewport(ImGuiViewportP* viewport);
|
||||
IMGUI_API void DebugRenderKeyboardPreview(ImDrawList* draw_list);
|
||||
IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb);
|
||||
|
||||
// Obsolete functions
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.89.1
|
||||
// dear imgui, v1.89.2 WIP
|
||||
// (widgets code)
|
||||
|
||||
/*
|
||||
@ -126,7 +126,7 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
|
||||
// For InputTextEx()
|
||||
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 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.
|
||||
@ -3571,9 +3571,9 @@ static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char**
|
||||
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;
|
||||
const float line_height = g.FontSize;
|
||||
const float scale = line_height / font->FontSize;
|
||||
@ -3622,14 +3622,14 @@ namespace ImStb
|
||||
|
||||
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 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 ImWchar STB_TEXTEDIT_NEWLINE = '\n';
|
||||
static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, ImGuiInputTextState* obj, int line_start_idx)
|
||||
{
|
||||
const ImWchar* text = obj->TextW.Data;
|
||||
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->x1 = size.x;
|
||||
r->baseline_y_delta = size.y;
|
||||
@ -3645,7 +3645,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_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_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_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
|
||||
|
||||
@ -4683,11 +4683,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
searches_result_line_no[1] = line_count;
|
||||
|
||||
// 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;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4756,7 +4756,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
}
|
||||
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
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user