Merge branch 'master' into docking

# Conflicts:
#	docs/CHANGELOG.txt
#	imgui.cpp
#	imgui.h
#	imgui_draw.cpp
This commit is contained in:
ocornut 2022-02-17 18:47:43 +01:00
commit 9948535118
20 changed files with 169 additions and 124 deletions

View File

@ -246,7 +246,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -Wextra -Werror -Wno-zero-as-null-pointer-constant -Wno-double-promotion -Wno-variadic-macros -Wno-empty-body -o example_single_file example_single_file.cpp
- name: Build example_null (freetype) - name: Build example_null (freetype)
run: | run: |
@ -262,7 +262,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with ImWchar32) - name: Build example_null (with ImWchar32)
run: | run: |
@ -274,7 +274,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with large ImDrawIdx + pointer ImTextureID) - name: Build example_null (with large ImDrawIdx + pointer ImTextureID)
run: | run: |
@ -287,7 +287,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS) - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_FUNCTIONS)
run: | run: |
@ -299,7 +299,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO) - name: Build example_null (with IMGUI_DISABLE_OBSOLETE_KEYIO)
run: | run: |
@ -311,7 +311,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW) - name: Build example_null (with IMGUI_DISABLE_DEMO_WINDOWS and IMGUI_DISABLE_METRICS_WINDOW)
run: | run: |
@ -324,7 +324,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS) - name: Build example_null (with IMGUI_DISABLE_FILE_FUNCTIONS)
run: | run: |
@ -336,7 +336,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR) - name: Build example_null (with IMGUI_USE_BGRA_PACKED_COLOR)
run: | run: |
@ -348,7 +348,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA) - name: Build example_null (with IM_VEC2_CLASS_EXTRA and IM_VEC4_CLASS_EXTRA)
run: | run: |
@ -368,7 +368,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp g++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime, Clang) - name: Build example_null (without c++ runtime, Clang)
run: | run: |
@ -380,7 +380,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2 - name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2 run: make -C examples/example_glfw_opengl2
@ -397,7 +397,7 @@ jobs:
run: make -C examples/example_sdl_opengl3 run: make -C examples/example_sdl_opengl3
- name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES - name: Build with IMGUI_IMPL_VULKAN_NO_PROTOTYPES
run: g++ -c -I. -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp run: g++ -c -I. -std=c++11 -DIMGUI_IMPL_VULKAN_NO_PROTOTYPES=1 backends/imgui_impl_vulkan.cpp
MacOS: MacOS:
runs-on: macos-latest runs-on: macos-latest
@ -420,7 +420,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp clang++ -I. -std=c++11 -Wall -Wformat -o example_single_file example_single_file.cpp
- name: Build example_null (without c++ runtime) - name: Build example_null (without c++ runtime)
run: | run: |
@ -431,7 +431,7 @@ jobs:
#include "examples/example_null/main.cpp" #include "examples/example_null/main.cpp"
EOF EOF
clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp clang++ -I. -std=c++11 -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp
- name: Build example_glfw_opengl2 - name: Build example_glfw_opengl2
run: make -C examples/example_glfw_opengl2 run: make -C examples/example_glfw_opengl2

View File

@ -102,6 +102,22 @@ Other changes:
VERSION 1.88 WIP (In Progress) VERSION 1.88 WIP (In Progress)
----------------------------------------------------------------------- -----------------------------------------------------------------------
Breaking changes:
Other Changes:
- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
return value is overriden by focus when gamepad/keyboard navigation is active.
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
- Stack Tool: Added option to copy item path to clipboard. (#4631)
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
- Misc: Added constexpr to ImVec2/ImVec4 inline constructors. (#4995) [@Myriachan]
- Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov]
- ImVector: Fixed erase() with empty range. (#5009) [@thedmd]
- Drawlist: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
Docking+Viewports Branch: Docking+Viewports Branch:
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize - Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize

View File

@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
LIBS += -L/usr/local/lib -L/opt/homebrew/lib LIBS += -L/usr/local/lib -L/opt/homebrew/lib
LIBS += -lglfw LIBS += -lglfw
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include -I/opt/homebrew/include
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glut.cpp $(IMGUI_DIR)/backends/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -17,7 +17,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS += -I$(IMGUI_DIR) CXXFLAGS += -std=c++11 -I$(IMGUI_DIR)
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =
@ -52,7 +52,7 @@ endif
ifeq ($(UNAME_S), Darwin) #APPLE ifeq ($(UNAME_S), Darwin) #APPLE
ECHO_MESSAGE = "Mac OS X" ECHO_MESSAGE = "Mac OS X"
ifeq ($(WITH_EXTRA_WARNINGS), 1) ifeq ($(WITH_EXTRA_WARNINGS), 1)
CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-c++11-long-long -Wno-poison-system-directories CXXFLAGS += -Weverything -Wno-reserved-id-macro -Wno-c++98-compat-pedantic -Wno-padded -Wno-poison-system-directories
endif endif
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)
endif endif

View File

@ -17,7 +17,7 @@ LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -f
LIBS += `sdl2-config --libs` LIBS += `sdl2-config --libs`
LIBS += -L/usr/local/lib LIBS += -L/usr/local/lib
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I/usr/local/include
CXXFLAGS += `sdl2-config --cflags` CXXFLAGS += `sdl2-config --cflags`
CXXFLAGS += -Wall -Wformat CXXFLAGS += -Wall -Wformat
CFLAGS = $(CXXFLAGS) CFLAGS = $(CXXFLAGS)

View File

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -23,7 +23,7 @@ OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
LINUX_GL_LIBS = -lGL LINUX_GL_LIBS = -lGL
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -22,7 +22,7 @@ SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl.cpp $(IMGUI_DIR)/backends/imgui_
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
UNAME_S := $(shell uname -s) UNAME_S := $(shell uname -s)
CXXFLAGS = -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
CXXFLAGS += -g -Wall -Wformat CXXFLAGS += -g -Wall -Wformat
LIBS = LIBS =

View File

@ -81,12 +81,12 @@
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4. //---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
// This will be inlined as part of ImVec2 and ImVec4 class declarations. // This will be inlined as part of ImVec2 and ImVec4 class declarations.
/* /*
#define IM_VEC2_CLASS_EXTRA \ #define IM_VEC2_CLASS_EXTRA \
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \ constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
operator MyVec2() const { return MyVec2(x,y); } operator MyVec2() const { return MyVec2(x,y); }
#define IM_VEC4_CLASS_EXTRA \ #define IM_VEC4_CLASS_EXTRA \
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \ constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
operator MyVec4() const { return MyVec4(x,y,z,w); } operator MyVec4() const { return MyVec4(x,y,z,w); }
*/ */

126
imgui.cpp
View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, 1.88 WIP
// (main code and documentation) // (main code and documentation)
// Help: // Help:
@ -1216,7 +1216,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
return; return;
ImGuiInputEvent e; ImGuiInputEvent e;
e.Type = ImGuiInputEventType_Char; e.Type = ImGuiInputEventType_Text;
e.Source = ImGuiInputSource_Keyboard; e.Source = ImGuiInputSource_Keyboard;
e.Text.Char = c; e.Text.Char = c;
g.InputEventsQueue.push_back(e); g.InputEventsQueue.push_back(e);
@ -1286,7 +1286,7 @@ void ImGuiIO::ClearInputKeys()
KeysData[n].DownDurationPrev = -1.0f; KeysData[n].DownDurationPrev = -1.0f;
} }
KeyCtrl = KeyShift = KeyAlt = KeySuper = false; KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
KeyMods = KeyModsPrev = ImGuiKeyModFlags_None; KeyMods = ImGuiKeyModFlags_None;
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++) for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f; NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
} }
@ -2614,15 +2614,14 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
void ImGuiListClipper::End() void ImGuiListClipper::End()
{ {
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
ItemsCount = -1;
// Restore temporary buffer and fix back pointers which may be invalidated when nesting
if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData) if (ImGuiListClipperData* data = (ImGuiListClipperData*)TempData)
{ {
// In theory here we should assert that we are already at the right position, but it seems saner to just seek at the end and not assert/crash the user.
if (ItemsCount >= 0 && ItemsCount < INT_MAX && DisplayStart >= 0)
ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
// Restore temporary buffer and fix back pointers which may be invalidated when nesting
IM_ASSERT(data->ListClipper == this); IM_ASSERT(data->ListClipper == this);
data->StepNo = data->Ranges.Size; data->StepNo = data->Ranges.Size;
if (--g.ClipperTempDataStacked > 0) if (--g.ClipperTempDataStacked > 0)
@ -2632,6 +2631,7 @@ void ImGuiListClipper::End()
} }
TempData = NULL; TempData = NULL;
} }
ItemsCount = -1;
} }
void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max) void ImGuiListClipper::ForceDisplayRangeByIndices(int item_min, int item_max)
@ -2764,8 +2764,8 @@ bool ImGuiListClipper::Step()
// Advance the cursor to the end of the list and then returns 'false' to end the loop. // Advance the cursor to the end of the list and then returns 'false' to end the loop.
if (ItemsCount < INT_MAX) if (ItemsCount < INT_MAX)
ImGuiListClipper_SeekCursorForItem(this, ItemsCount); ImGuiListClipper_SeekCursorForItem(this, ItemsCount);
ItemsCount = -1;
End();
return false; return false;
} }
@ -3544,7 +3544,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
if (g.NavDisableMouseHover && !g.NavDisableHighlight) if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride))
{ {
if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
return false; return false;
@ -3607,8 +3607,6 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return false; return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max)) if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false; return false;
if (g.NavDisableMouseHover)
return false;
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
{ {
g.HoveredIdDisabled = true; g.HoveredIdDisabled = true;
@ -3644,6 +3642,9 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
IM_DEBUG_BREAK(); IM_DEBUG_BREAK();
} }
if (g.NavDisableMouseHover)
return false;
return true; return true;
} }
@ -4089,9 +4090,6 @@ static void ImGui::UpdateKeyboardInputs()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO; ImGuiIO& io = g.IO;
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
io.KeyMods = GetMergedKeyModFlags();
// Import legacy keys or verify they are not used // Import legacy keys or verify they are not used
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
if (io.BackendUsingLegacyKeyArrays == 0) if (io.BackendUsingLegacyKeyArrays == 0)
@ -4133,6 +4131,9 @@ static void ImGui::UpdateKeyboardInputs()
} }
#endif #endif
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
io.KeyMods = GetMergedKeyModFlags();
// Clear gamepad data if disabled // Clear gamepad data if disabled
if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0) if ((io.BackendFlags & ImGuiBackendFlags_HasGamepad) == 0)
for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++) for (int i = ImGuiKey_Gamepad_BEGIN; i < ImGuiKey_Gamepad_END; i++)
@ -5107,7 +5108,6 @@ void ImGui::EndFrame()
// Clear Input data for next frame // Clear Input data for next frame
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
g.IO.InputQueueCharacters.resize(0); g.IO.InputQueueCharacters.resize(0);
g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
CallContextHooks(&g, ImGuiContextHookType_EndFramePost); CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
@ -8254,14 +8254,8 @@ bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
const float t = g.IO.MouseDownDuration[button]; const float t = g.IO.MouseDownDuration[button];
if (t == 0.0f) if (t == 0.0f)
return true; return true;
if (repeat && t > g.IO.KeyRepeatDelay) if (repeat && t > g.IO.KeyRepeatDelay)
{ return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
// FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
if (amount > 0)
return true;
}
return false; return false;
} }
@ -8483,7 +8477,7 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
} }
} }
} }
else if (e->Type == ImGuiInputEventType_Char) else if (e->Type == ImGuiInputEventType_Text)
{ {
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with // Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled)) if (trickle_fast_inputs && (key_changed || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
@ -11452,7 +11446,7 @@ static void ImGui::NavUpdateWindowing()
// - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer. // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
// - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway. // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0) if (nav_keyboard_active && IsKeyPressed(ImGuiKey_ModAlt))
{ {
g.NavWindowingToggleLayer = true; g.NavWindowingToggleLayer = true;
g.NavInputSource = ImGuiInputSource_Keyboard; g.NavInputSource = ImGuiInputSource_Keyboard;
@ -11465,13 +11459,12 @@ static void ImGui::NavUpdateWindowing()
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
// Apply layer toggle on release // Apply layer toggle on release
// Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
// Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss. // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer) if (IsKeyReleased(ImGuiKey_ModAlt) && g.NavWindowingToggleLayer)
if (g.ActiveId == 0 || g.ActiveIdAllowOverlap) if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev)) if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
apply_toggle_layer = true; apply_toggle_layer = true;
if (!io.KeyAlt) if (!IsKeyDown(ImGuiKey_ModAlt))
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
} }
@ -17956,7 +17949,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
int active_id_using_key_input_count = 0; int active_id_using_key_input_count = 0;
for (int n = 0; n < ImGuiKey_NamedKey_COUNT; n++) for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0; active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count); Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
@ -18674,27 +18667,44 @@ void ImGui::DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* dat
ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel]; ImGuiStackLevelInfo* info = &tool->Results[tool->StackLevel];
IM_ASSERT(info->ID == id && info->QueryFrameCount > 0); IM_ASSERT(info->ID == id && info->QueryFrameCount > 0);
int data_len;
switch (data_type) switch (data_type)
{ {
case ImGuiDataType_S32: case ImGuiDataType_S32:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%d", (int)(intptr_t)data_id);
break; break;
case ImGuiDataType_String: case ImGuiDataType_String:
data_len = data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "%.*s", data_id_end ? (int)((const char*)data_id_end - (const char*)data_id) : (int)strlen((const char*)data_id), (const char*)data_id);
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "\"%.*s\"", data_len, (const char*)data_id);
break; break;
case ImGuiDataType_Pointer: case ImGuiDataType_Pointer:
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id); ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "(void*)0x%p", data_id);
break; break;
case ImGuiDataType_ID: case ImGuiDataType_ID:
if (info->Desc[0] == 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one. if (info->Desc[0] != 0) // PushOverrideID() is often used to avoid hashing twice, which would lead to 2 calls to DebugHookIdInfo(). We prioritize the first one.
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id); return;
ImFormatString(info->Desc, IM_ARRAYSIZE(info->Desc), "0x%08X [override]", id);
break; break;
default: default:
IM_ASSERT(0); IM_ASSERT(0);
} }
info->QuerySuccess = true; info->QuerySuccess = true;
info->DataType = data_type;
}
static int StackToolFormatLevelInfo(ImGuiStackTool* tool, int n, bool format_for_ui, char* buf, size_t buf_size)
{
ImGuiStackLevelInfo* info = &tool->Results[n];
ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? ImGui::FindWindowByID(info->ID) : NULL;
if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked)
return ImFormatString(buf, buf_size, format_for_ui ? "\"%s\" [window]" : "%s", window->Name);
if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
return ImFormatString(buf, buf_size, (format_for_ui && info->DataType == ImGuiDataType_String) ? "\"%s\"" : "%s", info->Desc);
if (tool->StackLevel < tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
return (*buf = 0);
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (const char* label = ImGuiTestEngine_FindItemDebugLabel(GImGui, info->ID)) // Source: ImGuiTestEngine's ItemInfo()
return ImFormatString(buf, buf_size, format_for_ui ? "??? \"%s\"" : "%s", label);
#endif
return ImFormatString(buf, buf_size, "???");
} }
// Stack Tool: Display UI // Stack Tool: Display UI
@ -18710,6 +18720,7 @@ void ImGui::ShowStackToolWindow(bool* p_open)
} }
// Display hovered/active status // Display hovered/active status
ImGuiStackTool* tool = &g.DebugStackTool;
const ImGuiID hovered_id = g.HoveredIdPreviousFrame; const ImGuiID hovered_id = g.HoveredIdPreviousFrame;
const ImGuiID active_id = g.ActiveId; const ImGuiID active_id = g.ActiveId;
#ifdef IMGUI_ENABLE_TEST_ENGINE #ifdef IMGUI_ENABLE_TEST_ENGINE
@ -18720,8 +18731,33 @@ void ImGui::ShowStackToolWindow(bool* p_open)
SameLine(); SameLine();
MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details."); MetricsHelpMarker("Hover an item with the mouse to display elements of the ID Stack leading to the item's final ID.\nEach level of the stack correspond to a PushID() call.\nAll levels of the stack are hashed together to make the final ID of a widget (ID displayed at the bottom level of the stack).\nRead FAQ entry about the ID stack for details.");
// CTRL+C to copy path
const float time_since_copy = (float)g.Time - tool->CopyToClipboardLastTime;
Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC);
SameLine();
TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*");
if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiKey_ModCtrl) && IsKeyPressed(ImGuiKey_C))
{
tool->CopyToClipboardLastTime = (float)g.Time;
char* p = g.TempBuffer;
char* p_end = p + IM_ARRAYSIZE(g.TempBuffer);
for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++)
{
*p++ = '/';
char level_desc[256];
StackToolFormatLevelInfo(tool, stack_n, false, level_desc, IM_ARRAYSIZE(level_desc));
for (int n = 0; level_desc[n] && p + 2 < p_end; n++)
{
if (level_desc[n] == '/')
*p++ = '\\';
*p++ = level_desc[n];
}
}
*p = '\0';
SetClipboardText(g.TempBuffer);
}
// Display decorated stack // Display decorated stack
ImGuiStackTool* tool = &g.DebugStackTool;
tool->LastActiveFrame = g.FrameCount; tool->LastActiveFrame = g.FrameCount;
if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders)) if (tool->Results.Size > 0 && BeginTable("##table", 3, ImGuiTableFlags_Borders))
{ {
@ -18735,23 +18771,9 @@ void ImGui::ShowStackToolWindow(bool* p_open)
ImGuiStackLevelInfo* info = &tool->Results[n]; ImGuiStackLevelInfo* info = &tool->Results[n];
TableNextColumn(); TableNextColumn();
Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0); Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
TableNextColumn(); TableNextColumn();
ImGuiWindow* window = (info->Desc[0] == 0 && n == 0) ? FindWindowByID(info->ID) : NULL; StackToolFormatLevelInfo(tool, n, true, g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer));
if (window) // Source: window name (because the root ID don't call GetID() and so doesn't get hooked) TextUnformatted(g.TempBuffer);
Text("\"%s\" [window]", window->Name);
else if (info->QuerySuccess) // Source: GetID() hooks (prioritize over ItemInfo() because we frequently use patterns like: PushID(str), Button("") where they both have same id)
TextUnformatted(info->Desc);
else if (tool->StackLevel >= tool->Results.Size) // Only start using fallback below when all queries are done, so during queries we don't flickering ??? markers.
{
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (const char* label = ImGuiTestEngine_FindItemDebugLabel(&g, info->ID)) // Source: ImGuiTestEngine's ItemInfo()
Text("??? \"%s\"", label);
else
#endif
TextUnformatted("???");
}
TableNextColumn(); TableNextColumn();
Text("0x%08X", info->ID); Text("0x%08X", info->ID);
if (n == tool->Results.Size - 1) if (n == tool->Results.Size - 1)

20
imgui.h
View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (headers) // (headers)
// Help: // Help:
@ -64,8 +64,8 @@ Index of this file:
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.87" #define IMGUI_VERSION "1.88 WIP"
#define IMGUI_VERSION_NUM 18701 #define IMGUI_VERSION_NUM 18707
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE #define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch #define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -255,8 +255,8 @@ IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec2 struct ImVec2
{ {
float x, y; float x, y;
ImVec2() { x = y = 0.0f; } constexpr ImVec2() : x(0.0f), y(0.0f) { }
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 <= 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 <= 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
@ -267,9 +267,9 @@ struct ImVec2
// ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type] // ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type]
struct ImVec4 struct ImVec4
{ {
float x, y, z, w; float x, y, z, w;
ImVec4() { x = y = z = w = 0.0f; } constexpr ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } constexpr ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { }
#ifdef IM_VEC4_CLASS_EXTRA #ifdef IM_VEC4_CLASS_EXTRA
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
#endif #endif
@ -1327,6 +1327,7 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // IsItemHovered() only: Return true even if the position is obstructed or overlapped by another window
ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // IsItemHovered() only: Return true even if the item is disabled
ImGuiHoveredFlags_NoNavOverride = 1 << 10, // Disable using gamepad/keyboard navigation state when active, always query mouse.
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
}; };
@ -1893,7 +1894,7 @@ struct ImVector
inline void pop_back() { IM_ASSERT(Size > 0); Size--; } inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
inline void push_front(const T& v) { if (Size == 0) push_back(v); else insert(Data, v); } inline void push_front(const T& v) { if (Size == 0) push_back(v); else insert(Data, v); }
inline T* erase(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; } inline T* erase(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(T)); Size--; return Data + off; }
inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last > it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; } inline T* erase(const T* it, const T* it_last){ IM_ASSERT(it >= Data && it < Data + Size && it_last >= it && it_last <= Data + Size); const ptrdiff_t count = it_last - it; const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + count, ((size_t)Size - (size_t)off - (size_t)count) * sizeof(T)); Size -= (int)count; return Data + off; }
inline T* erase_unsorted(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; } inline T* erase_unsorted(const T* it) { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; if (it < Data + Size - 1) memcpy(Data + off, Data + Size - 1, sizeof(T)); Size--; return Data + off; }
inline T* insert(const T* it, const T& v) { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; } inline T* insert(const T* it, const T& v) { IM_ASSERT(it >= Data && it <= Data + Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(T)); memcpy(&Data[off], &v, sizeof(v)); Size++; return Data + off; }
inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; }
@ -2121,7 +2122,6 @@ struct ImGuiIO
// Other state maintained from data above + IO function calls // Other state maintained from data above + IO function calls
ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame() ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
ImGuiKeyModFlags KeyModsPrev; // Key mods flags (from previous frame)
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)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (demo code) // (demo code)
// Help: // Help:

View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (drawing and font code) // (drawing and font code)
/* /*
@ -1214,8 +1214,8 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa
const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_min_segment_angle = a_min_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX; const float a_max_segment_angle = a_max_sample * IM_PI * 2.0f / IM_DRAWLIST_ARCFAST_SAMPLE_MAX;
const bool a_emit_start = (a_min_segment_angle - a_min) != 0.0f; const bool a_emit_start = ImAbs(a_min_segment_angle - a_min) >= 1e-5f;
const bool a_emit_end = (a_max - a_max_segment_angle) != 0.0f; const bool a_emit_end = ImAbs(a_max - a_max_segment_angle) >= 1e-5f;
_Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0))); _Path.reserve(_Path.Size + (a_mid_samples + 1 + (a_emit_start ? 1 : 0) + (a_emit_end ? 1 : 0)));
if (a_emit_start) if (a_emit_start)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (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!
@ -481,17 +481,17 @@ IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec1 struct ImVec1
{ {
float x; float x;
ImVec1() { x = 0.0f; } constexpr ImVec1() : x(0.0f) { }
ImVec1(float _x) { x = _x; } constexpr ImVec1(float _x) : x(_x) { }
}; };
// Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
struct ImVec2ih struct ImVec2ih
{ {
short x, y; short x, y;
ImVec2ih() { x = y = 0; } constexpr ImVec2ih() : x(0), y(0) {}
ImVec2ih(short _x, short _y) { x = _x; y = _y; } constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {}
explicit ImVec2ih(const ImVec2& rhs) { x = (short)rhs.x; y = (short)rhs.y; } constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
}; };
// Helper: ImRect (2D axis aligned bounding-box) // Helper: ImRect (2D axis aligned bounding-box)
@ -501,10 +501,10 @@ struct IMGUI_API ImRect
ImVec2 Min; // Upper-left ImVec2 Min; // Upper-left
ImVec2 Max; // Lower-right ImVec2 Max; // Lower-right
ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); }
@ -559,11 +559,11 @@ struct ImBitArray
ImBitArray() { ClearAllBits(); } ImBitArray() { ClearAllBits(); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
bool TestBit(int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); } bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
void SetBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArraySetBit(Storage, n + OFFSET); } void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
void ClearBit(int n) { IM_ASSERT(n + OFFSET < BITCOUNT); ImBitArrayClearBit(Storage, n + OFFSET); } void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n + OFFSET, n2 + OFFSET); } // Works on range [n..n2) void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
bool operator[](int n) const { IM_ASSERT(n + OFFSET < BITCOUNT); return ImBitArrayTestBit(Storage, n + OFFSET); } bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return ImBitArrayTestBit(Storage, n); }
}; };
// Helper: ImBitVector // Helper: ImBitVector
@ -1192,7 +1192,7 @@ enum ImGuiInputEventType
ImGuiInputEventType_MouseButton, ImGuiInputEventType_MouseButton,
ImGuiInputEventType_MouseViewport, ImGuiInputEventType_MouseViewport,
ImGuiInputEventType_Key, ImGuiInputEventType_Key,
ImGuiInputEventType_Char, ImGuiInputEventType_Text,
ImGuiInputEventType_Focus, ImGuiInputEventType_Focus,
ImGuiInputEventType_COUNT ImGuiInputEventType_COUNT
}; };
@ -1686,7 +1686,8 @@ struct ImGuiStackLevelInfo
ImGuiID ID; ImGuiID ID;
ImS8 QueryFrameCount; // >= 1: Query in progress ImS8 QueryFrameCount; // >= 1: Query in progress
bool QuerySuccess; // Obtained result from DebugHookIdInfo() bool QuerySuccess; // Obtained result from DebugHookIdInfo()
char Desc[58]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) ImGuiDataType DataType : 8;
char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed.
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); } ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); }
}; };
@ -1698,8 +1699,10 @@ struct ImGuiStackTool
int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
ImGuiID QueryId; // ID to query details for ImGuiID QueryId; // ID to query details for
ImVector<ImGuiStackLevelInfo> Results; ImVector<ImGuiStackLevelInfo> Results;
bool CopyToClipboardOnCtrlC;
float CopyToClipboardLastTime;
ImGuiStackTool() { memset(this, 0, sizeof(*this)); } ImGuiStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (tables and columns code) // (tables and columns code)
/* /*

View File

@ -1,4 +1,4 @@
// dear imgui, v1.87 // dear imgui, v1.88 WIP
// (widgets code) // (widgets code)
/* /*
@ -82,6 +82,7 @@ Index of this file:
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
#endif #endif
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -6937,7 +6938,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
if (!enabled) if (!enabled)
EndDisabled(); EndDisabled();
const bool hovered = (g.HoveredId == id) && enabled; const bool hovered = (g.HoveredId == id) && enabled && !g.NavDisableMouseHover;
if (menuset_is_open) if (menuset_is_open)
g.NavWindow = backed_nav_window; g.NavWindow = backed_nav_window;

View File

@ -15,7 +15,7 @@
// You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui // You can also find a precompiled Windows binary in the binary/demo package available from https://github.com/ocornut/imgui
// Usage: // Usage:
// binary_to_compressed_c.exe [-base85] [-nocompress] <inputfile> <symbolname> // binary_to_compressed_c.exe [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>
// Usage example: // Usage example:
// # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp // # binary_to_compressed_c.exe myfont.ttf MyFont > myfont.cpp
// # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp // # binary_to_compressed_c.exe -base85 myfont.ttf MyFont > myfont.cpp
@ -31,23 +31,25 @@ typedef unsigned int stb_uint;
typedef unsigned char stb_uchar; typedef unsigned char stb_uchar;
stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len); stb_uint stb_compress(stb_uchar* out, stb_uchar* in, stb_uint len);
static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression); static bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static);
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
if (argc < 3) if (argc < 3)
{ {
printf("Syntax: %s [-base85] [-nocompress] <inputfile> <symbolname>\n", argv[0]); printf("Syntax: %s [-base85] [-nocompress] [-nostatic] <inputfile> <symbolname>\n", argv[0]);
return 0; return 0;
} }
int argn = 1; int argn = 1;
bool use_base85_encoding = false; bool use_base85_encoding = false;
bool use_compression = true; bool use_compression = true;
if (argv[argn][0] == '-') bool use_static = true;
while (argn < (argc - 2) && argv[argn][0] == '-')
{ {
if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; } if (strcmp(argv[argn], "-base85") == 0) { use_base85_encoding = true; argn++; }
else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; } else if (strcmp(argv[argn], "-nocompress") == 0) { use_compression = false; argn++; }
else if (strcmp(argv[argn], "-nostatic") == 0) { use_static = false; argn++; }
else else
{ {
fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]); fprintf(stderr, "Unknown argument: '%s'\n", argv[argn]);
@ -55,7 +57,7 @@ int main(int argc, char** argv)
} }
} }
bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression); bool ret = binary_to_compressed_c(argv[argn], argv[argn + 1], use_base85_encoding, use_compression, use_static);
if (!ret) if (!ret)
fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]); fprintf(stderr, "Error opening or reading file: '%s'\n", argv[argn]);
return ret ? 0 : 1; return ret ? 0 : 1;
@ -67,7 +69,7 @@ char Encode85Byte(unsigned int x)
return (x >= '\\') ? x + 1 : x; return (x >= '\\') ? x + 1 : x;
} }
bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression) bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_base85_encoding, bool use_compression, bool use_static)
{ {
// Read file // Read file
FILE* f = fopen(filename, "rb"); FILE* f = fopen(filename, "rb");
@ -90,10 +92,11 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
FILE* out = stdout; FILE* out = stdout;
fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz); fprintf(out, "// File: '%s' (%d bytes)\n", filename, (int)data_sz);
fprintf(out, "// Exported using binary_to_compressed_c.cpp\n"); fprintf(out, "// Exported using binary_to_compressed_c.cpp\n");
const char* static_str = use_static ? "static " : "";
const char* compressed_str = use_compression ? "compressed_" : ""; const char* compressed_str = use_compression ? "compressed_" : "";
if (use_base85_encoding) if (use_base85_encoding)
{ {
fprintf(out, "static const char %s_%sdata_base85[%d+1] =\n \"", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5); fprintf(out, "%sconst char %s_%sdata_base85[%d+1] =\n \"", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*5);
char prev_c = 0; char prev_c = 0;
for (int src_i = 0; src_i < compressed_sz; src_i += 4) for (int src_i = 0; src_i < compressed_sz; src_i += 4)
{ {
@ -112,8 +115,8 @@ bool binary_to_compressed_c(const char* filename, const char* symbol, bool use_b
} }
else else
{ {
fprintf(out, "static const unsigned int %s_%ssize = %d;\n", symbol, compressed_str, (int)compressed_sz); fprintf(out, "%sconst unsigned int %s_%ssize = %d;\n", static_str, symbol, compressed_str, (int)compressed_sz);
fprintf(out, "static const unsigned int %s_%sdata[%d/4] =\n{", symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4); fprintf(out, "%sconst unsigned int %s_%sdata[%d/4] =\n{", static_str, symbol, compressed_str, (int)((compressed_sz + 3) / 4)*4);
int column = 0; int column = 0;
for (int i = 0; i < compressed_sz; i += 4) for (int i = 0; i < compressed_sz; i += 4)
{ {