mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-15 19:43:28 +01:00
Merge commit 'caca55c642d16cf1c2649831c5d06b1f26146d12' into docking
# Conflicts: # examples/imgui_impl_sdl.cpp # imgui.cpp
This commit is contained in:
commit
05c3e0b898
@ -109,16 +109,22 @@ Other Changes:
|
||||
branch pressing arrow keys while dragging a window from a tab could trigger an assert. (#3025)
|
||||
- ColorButton: Added ImGuiColorEditFlags_NoBorder flag to remove the border normally enforced
|
||||
by default for standalone ColorButton.
|
||||
- BeginMenu: Using same ID multiple times appends content to a menu. (#1207)
|
||||
- BeginMenu: Fixed a bug where SetNextWindowXXX data before a BeginMenu() would not be cleared
|
||||
when the menu is not open. (#3030)
|
||||
- InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*'
|
||||
glyph. (#2149, #515)
|
||||
- Window: Fixed a bug with child window inheriting ItemFlags from their parent when the child
|
||||
window also manipulate the ItemFlags stack. (#3024) [@Stanbroek]
|
||||
- Font: Fixed non-ASCII space occasionally creating unnecessary empty polygons.
|
||||
- Demo: Added a black and white gradient to Demo>Examples>Custom Rendering.
|
||||
- Demo: Added black and white and color gradients to Demo>Examples>Custom Rendering.
|
||||
- Backends: Win32: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(),
|
||||
ImGui_ImplWin32_GetDpiScaleForMonitor() helpers functions (backported from the docking branch).
|
||||
Those functions makes it easier for example apps to support hi-dpi features without setting up
|
||||
a manifest.
|
||||
- Backends: SDL: Added ImGui_ImplSDL2_InitForMetal() for API consistency (even though the function
|
||||
currently does nothing).
|
||||
- Backends: SDL: Fixed mapping for ImGuiKey_KeyPadEnter. (#3031) [@Davido71]
|
||||
- Examples: Added SDL2+Metal example application. (#3017) [@coding-jackalope]
|
||||
|
||||
|
||||
|
@ -194,7 +194,7 @@ Ongoing Dear ImGui development is financially supported by users and private spo
|
||||
- [Blizzard](https://careers.blizzard.com/en-us/openings/engineering/all/all/all/1), [Google](https://github.com/google/filament), [Nvidia](https://developer.nvidia.com/nvidia-omniverse), [Ubisoft](https://montreal.ubisoft.com/en/ubisoft-sponsors-user-interface-library-for-c-dear-imgui/)
|
||||
|
||||
*Double-chocolate and Salty caramel sponsors*
|
||||
- [DotEmu](http://www.dotemu.com), [Framefield](http://framefield.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/)
|
||||
- [Activision](https://careers.activision.com/c/programmingsoftware-engineering-jobs), [DotEmu](http://www.dotemu.com), [Framefield](http://framefield.com), [Hexagon](https://hexagonxalt.com/the-technology/xalt-visualization), [Kylotonn](https://www.kylotonn.com), [Media Molecule](http://www.mediamolecule.com), [Mesh Consultants](https://www.meshconsultants.ca), [Mobigame](http://www.mobigame.net), [Nadeo](https://www.nadeo.com), [Supercell](http://www.supercell.com), [Remedy Entertainment](https://www.remedygames.com/), [Unit 2 Games](https://unit2games.com/)
|
||||
|
||||
From November 2014 to December 2019, ongoing development has also been financially supported by its users on Patreon and through individual donations. Please see [detailed list of Dear ImGui supporters](https://github.com/ocornut/imgui/wiki/Sponsors).
|
||||
|
||||
|
@ -87,6 +87,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- input text: option to Tab after an Enter validation.
|
||||
- input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
|
||||
- input text: easier ways to update buffer (from source char*) while owned. preserve some sort of cursor position for multi-line text.
|
||||
- input text: add flag (e.g. ImGuiInputTextFlags_EscapeClearsBuffer) to clear instead of revert. what to do with focus? (also see #2890)
|
||||
- input text: add discard flag (e.g. ImGuiInputTextFlags_DiscardActiveBuffer) or make it easier to clear active focus for text replacement during edition (#725)
|
||||
- input text: display bug when clicking a drag/slider after an input text in a different window has all-selected text (order dependent). actually a very old bug but no one appears to have noticed it.
|
||||
- input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
|
||||
@ -191,6 +192,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
|
||||
- tabs: persistent order/focus in BeginTabBar() api (#261, #351)
|
||||
- tabs: TabItem could honor SetNextItemWidth()?
|
||||
- tabs: explicit api (even if internal) to cleanly manipulate tab order.
|
||||
- tabs: Mouse wheel over tab bar could scroll? (#2702)
|
||||
|
||||
|
||||
- image/image button: misalignment on padded/bordered button?
|
||||
- image/image button: parameters are confusing, image() has tint_col,border_col whereas imagebutton() has bg_col/tint_col. Even thou they are different parameters ordering could be more consistent. can we fix that?
|
||||
@ -239,7 +243,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- tooltip: tooltips with delay timers? or general timer policy? (instantaneous vs timed): IsItemHovered() with timer + implicit aabb-id for items with no ID. (#1485)
|
||||
- tooltip: drag tooltip hovering over source widget with IsItemHovered/SetTooltip flickers.
|
||||
|
||||
- menus: calling BeginMenu() twice with a same name doesn't append as Begin() does for regular windows (#1207)
|
||||
- menus: menu bars inside modal windows are acting weird.
|
||||
- status-bar: add a per-window status bar helper similar to what menu-bar does.
|
||||
- shortcuts: local-style shortcut api, e.g. parse "&Save"
|
||||
|
@ -20,6 +20,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2).
|
||||
// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state).
|
||||
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
||||
// 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter.
|
||||
@ -187,7 +188,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, void* sdl_gl_context)
|
||||
io.KeyMap[ImGuiKey_Space] = SDL_SCANCODE_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_SCANCODE_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = SDL_SCANCODE_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_RETURN2;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = SDL_SCANCODE_KP_ENTER;
|
||||
io.KeyMap[ImGuiKey_A] = SDL_SCANCODE_A;
|
||||
io.KeyMap[ImGuiKey_C] = SDL_SCANCODE_C;
|
||||
io.KeyMap[ImGuiKey_V] = SDL_SCANCODE_V;
|
||||
|
592
imgui.cpp
592
imgui.cpp
@ -51,7 +51,7 @@ CODE
|
||||
|
||||
// [SECTION] FORWARD DECLARATIONS
|
||||
// [SECTION] CONTEXT AND MEMORY ALLOCATORS
|
||||
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
||||
// [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
||||
// [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
|
||||
// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
|
||||
// [SECTION] MISC HELPERS/UTILITIES (File functions)
|
||||
@ -61,6 +61,7 @@ CODE
|
||||
// [SECTION] ImGuiTextFilter
|
||||
// [SECTION] ImGuiTextBuffer
|
||||
// [SECTION] ImGuiListClipper
|
||||
// [SECTION] STYLING
|
||||
// [SECTION] RENDER HELPERS
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] ERROR CHECKING
|
||||
@ -916,10 +917,12 @@ static void ErrorCheckEndFrame();
|
||||
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write);
|
||||
|
||||
// Misc
|
||||
static void UpdateSettings();
|
||||
static void UpdateMouseInputs();
|
||||
static void UpdateMouseWheel();
|
||||
static bool UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
||||
static void UpdateTabFocus();
|
||||
static void UpdateDebugToolItemPicker();
|
||||
static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
||||
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
||||
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
||||
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||||
@ -979,7 +982,7 @@ static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper;
|
||||
static void* GImAllocatorUserData = NULL;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
||||
// [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiStyle::ImGuiStyle()
|
||||
@ -2296,11 +2299,15 @@ bool ImGuiListClipper::Step()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] RENDER HELPERS
|
||||
// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change.
|
||||
// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state.
|
||||
// [SECTION] STYLING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
ImGuiStyle& ImGui::GetStyle()
|
||||
{
|
||||
IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
|
||||
return GImGui->Style;
|
||||
}
|
||||
|
||||
ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul)
|
||||
{
|
||||
ImGuiStyle& style = GImGui->Style;
|
||||
@ -2333,6 +2340,192 @@ ImU32 ImGui::GetColorU32(ImU32 col)
|
||||
return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
|
||||
}
|
||||
|
||||
// FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32
|
||||
void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColorMod backup;
|
||||
backup.Col = idx;
|
||||
backup.BackupValue = g.Style.Colors[idx];
|
||||
g.ColorModifiers.push_back(backup);
|
||||
g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
|
||||
}
|
||||
|
||||
void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColorMod backup;
|
||||
backup.Col = idx;
|
||||
backup.BackupValue = g.Style.Colors[idx];
|
||||
g.ColorModifiers.push_back(backup);
|
||||
g.Style.Colors[idx] = col;
|
||||
}
|
||||
|
||||
void ImGui::PopStyleColor(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
while (count > 0)
|
||||
{
|
||||
ImGuiColorMod& backup = g.ColorModifiers.back();
|
||||
g.Style.Colors[backup.Col] = backup.BackupValue;
|
||||
g.ColorModifiers.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
struct ImGuiStyleVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count;
|
||||
ImU32 Offset;
|
||||
void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); }
|
||||
};
|
||||
|
||||
static const ImGuiStyleVarInfo GStyleVarInfo[] =
|
||||
{
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||||
};
|
||||
|
||||
static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx)
|
||||
{
|
||||
IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
|
||||
IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT);
|
||||
return &GStyleVarInfo[idx];
|
||||
}
|
||||
|
||||
void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
|
||||
{
|
||||
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(0 && "Called PushStyleVar() float variant but variable is not a float!");
|
||||
}
|
||||
|
||||
void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
|
||||
{
|
||||
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!");
|
||||
}
|
||||
|
||||
void ImGui::PopStyleVar(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
while (count > 0)
|
||||
{
|
||||
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
|
||||
ImGuiStyleMod& backup = g.StyleModifiers.back();
|
||||
const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx);
|
||||
void* data = info->GetVarPtr(&g.Style);
|
||||
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
||||
else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
|
||||
g.StyleModifiers.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
||||
{
|
||||
// Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1";
|
||||
switch (idx)
|
||||
{
|
||||
case ImGuiCol_Text: return "Text";
|
||||
case ImGuiCol_TextDisabled: return "TextDisabled";
|
||||
case ImGuiCol_WindowBg: return "WindowBg";
|
||||
case ImGuiCol_ChildBg: return "ChildBg";
|
||||
case ImGuiCol_PopupBg: return "PopupBg";
|
||||
case ImGuiCol_Border: return "Border";
|
||||
case ImGuiCol_BorderShadow: return "BorderShadow";
|
||||
case ImGuiCol_FrameBg: return "FrameBg";
|
||||
case ImGuiCol_FrameBgHovered: return "FrameBgHovered";
|
||||
case ImGuiCol_FrameBgActive: return "FrameBgActive";
|
||||
case ImGuiCol_TitleBg: return "TitleBg";
|
||||
case ImGuiCol_TitleBgActive: return "TitleBgActive";
|
||||
case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed";
|
||||
case ImGuiCol_MenuBarBg: return "MenuBarBg";
|
||||
case ImGuiCol_ScrollbarBg: return "ScrollbarBg";
|
||||
case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab";
|
||||
case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
|
||||
case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
|
||||
case ImGuiCol_CheckMark: return "CheckMark";
|
||||
case ImGuiCol_SliderGrab: return "SliderGrab";
|
||||
case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
|
||||
case ImGuiCol_Button: return "Button";
|
||||
case ImGuiCol_ButtonHovered: return "ButtonHovered";
|
||||
case ImGuiCol_ButtonActive: return "ButtonActive";
|
||||
case ImGuiCol_Header: return "Header";
|
||||
case ImGuiCol_HeaderHovered: return "HeaderHovered";
|
||||
case ImGuiCol_HeaderActive: return "HeaderActive";
|
||||
case ImGuiCol_Separator: return "Separator";
|
||||
case ImGuiCol_SeparatorHovered: return "SeparatorHovered";
|
||||
case ImGuiCol_SeparatorActive: return "SeparatorActive";
|
||||
case ImGuiCol_ResizeGrip: return "ResizeGrip";
|
||||
case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered";
|
||||
case ImGuiCol_ResizeGripActive: return "ResizeGripActive";
|
||||
case ImGuiCol_Tab: return "Tab";
|
||||
case ImGuiCol_TabHovered: return "TabHovered";
|
||||
case ImGuiCol_TabActive: return "TabActive";
|
||||
case ImGuiCol_TabUnfocused: return "TabUnfocused";
|
||||
case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive";
|
||||
case ImGuiCol_DockingPreview: return "DockingPreview";
|
||||
case ImGuiCol_DockingEmptyBg: return "DockingEmptyBg";
|
||||
case ImGuiCol_PlotLines: return "PlotLines";
|
||||
case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
|
||||
case ImGuiCol_PlotHistogram: return "PlotHistogram";
|
||||
case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
|
||||
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
|
||||
case ImGuiCol_DragDropTarget: return "DragDropTarget";
|
||||
case ImGuiCol_NavHighlight: return "NavHighlight";
|
||||
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
|
||||
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
|
||||
case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg";
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] RENDER HELPERS
|
||||
// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change.
|
||||
// Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
||||
{
|
||||
const char* text_display_end = text;
|
||||
@ -3202,24 +3395,6 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui.
|
||||
// Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit
|
||||
// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. your user code
|
||||
// may see different structures than what imgui.cpp sees, which is problematic.
|
||||
// We usually require settings to be in imconfig.h to make sure that they are accessible to all compilation units involved with Dear ImGui.
|
||||
bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx)
|
||||
{
|
||||
bool error = false;
|
||||
if (strcmp(version, IMGUI_VERSION)!=0) { error = true; IM_ASSERT(strcmp(version,IMGUI_VERSION)==0 && "Mismatched version string!"); }
|
||||
if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
|
||||
if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
|
||||
if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
|
||||
if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); }
|
||||
if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); }
|
||||
if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); }
|
||||
return !error;
|
||||
}
|
||||
|
||||
void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
|
||||
{
|
||||
GImAllocatorAllocFunc = alloc_func;
|
||||
@ -3258,12 +3433,6 @@ ImGuiPlatformIO& ImGui::GetPlatformIO()
|
||||
return GImGui->PlatformIO;
|
||||
}
|
||||
|
||||
ImGuiStyle& ImGui::GetStyle()
|
||||
{
|
||||
IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
|
||||
return GImGui->Style;
|
||||
}
|
||||
|
||||
// Same value as passed to the old io.RenderDrawListsFn function. Valid after Render() and until the next call to NewFrame()
|
||||
ImDrawData* ImGui::GetDrawData()
|
||||
{
|
||||
@ -3555,7 +3724,7 @@ static void ImGui::UpdateMouseInputs()
|
||||
ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
|
||||
if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist)
|
||||
g.IO.MouseDoubleClicked[i] = true;
|
||||
g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click
|
||||
g.IO.MouseClickedTime[i] = -DBL_MAX; // so the third click isn't turned into a double-click
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3667,6 +3836,42 @@ void ImGui::UpdateMouseWheel()
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::UpdateTabFocus()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// Pressing TAB activate widget focus
|
||||
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
|
||||
if (g.ActiveId == 0 && g.FocusTabPressed)
|
||||
{
|
||||
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
|
||||
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
|
||||
g.FocusRequestNextWindow = g.NavWindow;
|
||||
g.FocusRequestNextCounterRegular = INT_MAX;
|
||||
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
|
||||
g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
|
||||
else
|
||||
g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
|
||||
}
|
||||
|
||||
// Turn queued focus request into current one
|
||||
g.FocusRequestCurrWindow = NULL;
|
||||
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
|
||||
if (g.FocusRequestNextWindow != NULL)
|
||||
{
|
||||
ImGuiWindow* window = g.FocusRequestNextWindow;
|
||||
g.FocusRequestCurrWindow = window;
|
||||
if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
|
||||
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
|
||||
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
|
||||
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
|
||||
g.FocusRequestNextWindow = NULL;
|
||||
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
|
||||
}
|
||||
|
||||
g.NavIdTabCounter = INT_MAX;
|
||||
}
|
||||
|
||||
// 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)
|
||||
void ImGui::UpdateHoveredWindowAndCaptureFlags()
|
||||
{
|
||||
@ -3813,34 +4018,21 @@ void ImGui::NewFrame()
|
||||
NewFrameSanityChecks();
|
||||
g.ConfigFlagsCurrFrame = g.IO.ConfigFlags;
|
||||
|
||||
// Load settings on first frame (if not explicitly loaded manually before)
|
||||
if (!g.SettingsLoaded)
|
||||
{
|
||||
IM_ASSERT(g.SettingsWindows.empty());
|
||||
if (g.IO.IniFilename)
|
||||
LoadIniSettingsFromDisk(g.IO.IniFilename);
|
||||
g.SettingsLoaded = true;
|
||||
}
|
||||
|
||||
// Save settings (with a delay after the last modification, so we don't spam disk too much)
|
||||
if (g.SettingsDirtyTimer > 0.0f)
|
||||
{
|
||||
g.SettingsDirtyTimer -= g.IO.DeltaTime;
|
||||
if (g.SettingsDirtyTimer <= 0.0f)
|
||||
{
|
||||
if (g.IO.IniFilename != NULL)
|
||||
SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||
else
|
||||
g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
|
||||
g.SettingsDirtyTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
// Load settings on first frame, save settings when modified (after a delay)
|
||||
UpdateSettings();
|
||||
|
||||
g.Time += g.IO.DeltaTime;
|
||||
g.WithinFrameScope = true;
|
||||
g.FrameCount += 1;
|
||||
g.TooltipOverrideCount = 0;
|
||||
g.WindowsActiveCount = 0;
|
||||
g.MenusIdSubmittedThisFrame.resize(0);
|
||||
|
||||
// Calculate frame-rate for the user, as a purely luxurious feature
|
||||
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
|
||||
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
|
||||
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
|
||||
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
||||
|
||||
UpdateViewportsNewFrame();
|
||||
|
||||
@ -3875,7 +4067,7 @@ void ImGui::NewFrame()
|
||||
if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId)
|
||||
KeepAliveID(g.DragDropPayload.SourceId);
|
||||
|
||||
// Clear reference to active widget if the widget isn't alive anymore
|
||||
// Update HoveredId data
|
||||
if (!g.HoveredIdPreviousFrame)
|
||||
g.HoveredIdTimer = 0.0f;
|
||||
if (!g.HoveredIdPreviousFrame || (g.HoveredId && g.ActiveId == g.HoveredId))
|
||||
@ -3887,6 +4079,8 @@ void ImGui::NewFrame()
|
||||
g.HoveredIdPreviousFrame = g.HoveredId;
|
||||
g.HoveredId = 0;
|
||||
g.HoveredIdAllowOverlap = false;
|
||||
|
||||
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
|
||||
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
|
||||
ClearActiveID();
|
||||
if (g.ActiveId)
|
||||
@ -3899,12 +4093,13 @@ void ImGui::NewFrame()
|
||||
g.ActiveIdHasBeenEditedThisFrame = false;
|
||||
g.ActiveIdPreviousFrameIsAlive = false;
|
||||
g.ActiveIdIsJustActivated = false;
|
||||
if (g.TempInputTextId != 0 && g.ActiveId != g.TempInputTextId)
|
||||
g.TempInputTextId = 0;
|
||||
if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
|
||||
g.TempInputId = 0;
|
||||
if (g.ActiveId == 0)
|
||||
{
|
||||
g.ActiveIdUsingNavDirMask = g.ActiveIdUsingNavInputMask = 0;
|
||||
g.ActiveIdUsingKeyInputMask = 0;
|
||||
g.ActiveIdUsingNavDirMask = 0x00;
|
||||
g.ActiveIdUsingNavInputMask = 0x00;
|
||||
g.ActiveIdUsingKeyInputMask = 0x00;
|
||||
}
|
||||
|
||||
// Drag and drop
|
||||
@ -3924,12 +4119,6 @@ void ImGui::NewFrame()
|
||||
// Update mouse input state
|
||||
UpdateMouseInputs();
|
||||
|
||||
// Calculate frame-rate for the user, as a purely luxurious feature
|
||||
g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
|
||||
g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
|
||||
g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
|
||||
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
||||
|
||||
// Undocking
|
||||
// (needs to be before UpdateMouseMovingWindowNewFrame so the window is already offset and following the mouse on the detaching frame)
|
||||
DockContextUpdateUndocking(&g);
|
||||
@ -3955,36 +4144,8 @@ void ImGui::NewFrame()
|
||||
// Mouse wheel scrolling, scale
|
||||
UpdateMouseWheel();
|
||||
|
||||
// Pressing TAB activate widget focus
|
||||
g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
|
||||
if (g.ActiveId == 0 && g.FocusTabPressed)
|
||||
{
|
||||
// Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
|
||||
// manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
|
||||
g.FocusRequestNextWindow = g.NavWindow;
|
||||
g.FocusRequestNextCounterRegular = INT_MAX;
|
||||
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
|
||||
g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
|
||||
else
|
||||
g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
|
||||
}
|
||||
|
||||
// Turn queued focus request into current one
|
||||
g.FocusRequestCurrWindow = NULL;
|
||||
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
|
||||
if (g.FocusRequestNextWindow != NULL)
|
||||
{
|
||||
ImGuiWindow* window = g.FocusRequestNextWindow;
|
||||
g.FocusRequestCurrWindow = window;
|
||||
if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
|
||||
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
|
||||
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
|
||||
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
|
||||
g.FocusRequestNextWindow = NULL;
|
||||
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
|
||||
}
|
||||
|
||||
g.NavIdTabCounter = INT_MAX;
|
||||
// Update legacy TAB focus
|
||||
UpdateTabFocus();
|
||||
|
||||
// Mark all windows as not visible and compact unused memory.
|
||||
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
|
||||
@ -4167,6 +4328,7 @@ void ImGui::Shutdown(ImGuiContext* context)
|
||||
g.ShrinkWidthBuffer.clear();
|
||||
|
||||
g.PrivateClipboard.clear();
|
||||
g.MenusIdSubmittedThisFrame.clear();
|
||||
g.InputTextState.ClearFreeMemory();
|
||||
|
||||
g.SettingsWindows.clear();
|
||||
@ -5366,7 +5528,7 @@ ImGuiID ImGui::GetWindowResizeID(ImGuiWindow* window, int n)
|
||||
|
||||
// Handle resize for: Resize Grips, Borders, Gamepad
|
||||
// Return true when using auto-fit (double click on resize grip)
|
||||
static bool ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
|
||||
static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindowFlags flags = window->Flags;
|
||||
@ -6237,7 +6399,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
if (handle_borders_and_resize_grips && !window->Collapsed)
|
||||
if (UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
||||
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
|
||||
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
|
||||
window->ResizeBorderHeld = (signed char)border_held;
|
||||
|
||||
@ -6453,19 +6615,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical;
|
||||
window->DC.FocusCounterRegular = window->DC.FocusCounterTabStop = -1;
|
||||
|
||||
window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_;
|
||||
window->DC.ItemWidth = window->ItemWidthDefault;
|
||||
window->DC.TextWrapPos = -1.0f; // disabled
|
||||
window->DC.ItemFlagsStack.resize(0);
|
||||
window->DC.ItemWidthStack.resize(0);
|
||||
window->DC.TextWrapPosStack.resize(0);
|
||||
window->DC.GroupStack.resize(0);
|
||||
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags))
|
||||
{
|
||||
window->DC.ItemFlags = parent_window->DC.ItemFlags;
|
||||
window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_;
|
||||
if (parent_window)
|
||||
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
|
||||
}
|
||||
|
||||
if (window->AutoFitFramesX > 0)
|
||||
window->AutoFitFramesX--;
|
||||
@ -6932,185 +7090,6 @@ void ImGui::PopTextWrapPos()
|
||||
window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back();
|
||||
}
|
||||
|
||||
// FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32
|
||||
void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColorMod backup;
|
||||
backup.Col = idx;
|
||||
backup.BackupValue = g.Style.Colors[idx];
|
||||
g.ColorModifiers.push_back(backup);
|
||||
g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
|
||||
}
|
||||
|
||||
void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiColorMod backup;
|
||||
backup.Col = idx;
|
||||
backup.BackupValue = g.Style.Colors[idx];
|
||||
g.ColorModifiers.push_back(backup);
|
||||
g.Style.Colors[idx] = col;
|
||||
}
|
||||
|
||||
void ImGui::PopStyleColor(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
while (count > 0)
|
||||
{
|
||||
ImGuiColorMod& backup = g.ColorModifiers.back();
|
||||
g.Style.Colors[backup.Col] = backup.BackupValue;
|
||||
g.ColorModifiers.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
struct ImGuiStyleVarInfo
|
||||
{
|
||||
ImGuiDataType Type;
|
||||
ImU32 Count;
|
||||
ImU32 Offset;
|
||||
void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); }
|
||||
};
|
||||
|
||||
static const ImGuiStyleVarInfo GStyleVarInfo[] =
|
||||
{
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
||||
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||||
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||||
};
|
||||
|
||||
static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx)
|
||||
{
|
||||
IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
|
||||
IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT);
|
||||
return &GStyleVarInfo[idx];
|
||||
}
|
||||
|
||||
void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
|
||||
{
|
||||
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(0 && "Called PushStyleVar() float variant but variable is not a float!");
|
||||
}
|
||||
|
||||
void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
|
||||
{
|
||||
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||||
if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
|
||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
||||
*pvar = val;
|
||||
return;
|
||||
}
|
||||
IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!");
|
||||
}
|
||||
|
||||
void ImGui::PopStyleVar(int count)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
while (count > 0)
|
||||
{
|
||||
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
|
||||
ImGuiStyleMod& backup = g.StyleModifiers.back();
|
||||
const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx);
|
||||
void* data = info->GetVarPtr(&g.Style);
|
||||
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
||||
else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
|
||||
g.StyleModifiers.pop_back();
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
||||
{
|
||||
// Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1";
|
||||
switch (idx)
|
||||
{
|
||||
case ImGuiCol_Text: return "Text";
|
||||
case ImGuiCol_TextDisabled: return "TextDisabled";
|
||||
case ImGuiCol_WindowBg: return "WindowBg";
|
||||
case ImGuiCol_ChildBg: return "ChildBg";
|
||||
case ImGuiCol_PopupBg: return "PopupBg";
|
||||
case ImGuiCol_Border: return "Border";
|
||||
case ImGuiCol_BorderShadow: return "BorderShadow";
|
||||
case ImGuiCol_FrameBg: return "FrameBg";
|
||||
case ImGuiCol_FrameBgHovered: return "FrameBgHovered";
|
||||
case ImGuiCol_FrameBgActive: return "FrameBgActive";
|
||||
case ImGuiCol_TitleBg: return "TitleBg";
|
||||
case ImGuiCol_TitleBgActive: return "TitleBgActive";
|
||||
case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed";
|
||||
case ImGuiCol_MenuBarBg: return "MenuBarBg";
|
||||
case ImGuiCol_ScrollbarBg: return "ScrollbarBg";
|
||||
case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab";
|
||||
case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
|
||||
case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
|
||||
case ImGuiCol_CheckMark: return "CheckMark";
|
||||
case ImGuiCol_SliderGrab: return "SliderGrab";
|
||||
case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
|
||||
case ImGuiCol_Button: return "Button";
|
||||
case ImGuiCol_ButtonHovered: return "ButtonHovered";
|
||||
case ImGuiCol_ButtonActive: return "ButtonActive";
|
||||
case ImGuiCol_Header: return "Header";
|
||||
case ImGuiCol_HeaderHovered: return "HeaderHovered";
|
||||
case ImGuiCol_HeaderActive: return "HeaderActive";
|
||||
case ImGuiCol_Separator: return "Separator";
|
||||
case ImGuiCol_SeparatorHovered: return "SeparatorHovered";
|
||||
case ImGuiCol_SeparatorActive: return "SeparatorActive";
|
||||
case ImGuiCol_ResizeGrip: return "ResizeGrip";
|
||||
case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered";
|
||||
case ImGuiCol_ResizeGripActive: return "ResizeGripActive";
|
||||
case ImGuiCol_Tab: return "Tab";
|
||||
case ImGuiCol_TabHovered: return "TabHovered";
|
||||
case ImGuiCol_TabActive: return "TabActive";
|
||||
case ImGuiCol_TabUnfocused: return "TabUnfocused";
|
||||
case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive";
|
||||
case ImGuiCol_DockingPreview: return "DockingPreview";
|
||||
case ImGuiCol_DockingEmptyBg: return "DockingEmptyBg";
|
||||
case ImGuiCol_PlotLines: return "PlotLines";
|
||||
case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
|
||||
case ImGuiCol_PlotHistogram: return "PlotHistogram";
|
||||
case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
|
||||
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
|
||||
case ImGuiCol_DragDropTarget: return "DragDropTarget";
|
||||
case ImGuiCol_NavHighlight: return "NavHighlight";
|
||||
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
|
||||
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
|
||||
case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg";
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
|
||||
{
|
||||
if (window->RootWindow == potential_parent)
|
||||
@ -7872,11 +7851,28 @@ void ImGui::Unindent(float indent_w)
|
||||
window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] ERROR CHECKING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui.
|
||||
// Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit
|
||||
// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. your user code
|
||||
// may see different structures than what imgui.cpp sees, which is problematic.
|
||||
// We usually require settings to be in imconfig.h to make sure that they are accessible to all compilation units involved with Dear ImGui.
|
||||
bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx)
|
||||
{
|
||||
bool error = false;
|
||||
if (strcmp(version, IMGUI_VERSION)!=0) { error = true; IM_ASSERT(strcmp(version,IMGUI_VERSION)==0 && "Mismatched version string!"); }
|
||||
if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
|
||||
if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
|
||||
if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
|
||||
if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); }
|
||||
if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); }
|
||||
if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); }
|
||||
return !error;
|
||||
}
|
||||
|
||||
static void ImGui::ErrorCheckEndFrame()
|
||||
{
|
||||
// Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
|
||||
@ -7920,7 +7916,6 @@ static void ImGui::ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool
|
||||
IM_ASSERT(p == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] SCROLLING
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -8585,7 +8580,6 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
return window->Pos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -9703,7 +9697,6 @@ void ImGui::NavUpdateWindowingOverlay()
|
||||
PopStyleVar();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DRAG AND DROP
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -10002,7 +9995,6 @@ void ImGui::EndDragDropTarget()
|
||||
g.DragDropWithinSourceOrTarget = false;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] LOGGING/CAPTURING
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -10222,6 +10214,34 @@ void ImGui::LogButtons()
|
||||
// [SECTION] SETTINGS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Called by NewFrame()
|
||||
void ImGui::UpdateSettings()
|
||||
{
|
||||
// Load settings on first frame (if not explicitly loaded manually before)
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!g.SettingsLoaded)
|
||||
{
|
||||
IM_ASSERT(g.SettingsWindows.empty());
|
||||
if (g.IO.IniFilename)
|
||||
LoadIniSettingsFromDisk(g.IO.IniFilename);
|
||||
g.SettingsLoaded = true;
|
||||
}
|
||||
|
||||
// Save settings (with a delay after the last modification, so we don't spam disk too much)
|
||||
if (g.SettingsDirtyTimer > 0.0f)
|
||||
{
|
||||
g.SettingsDirtyTimer -= g.IO.DeltaTime;
|
||||
if (g.SettingsDirtyTimer <= 0.0f)
|
||||
{
|
||||
if (g.IO.IniFilename != NULL)
|
||||
SaveIniSettingsToDisk(g.IO.IniFilename);
|
||||
else
|
||||
g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
|
||||
g.SettingsDirtyTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::MarkIniSettingsDirty()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
26
imgui.h
26
imgui.h
@ -226,7 +226,7 @@ struct ImVec4
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ImGui: Dear ImGui end-user API
|
||||
// (Inside a namespace so you can add extra functions in your own separate file. Please don't modify imgui source files!)
|
||||
// (This is a namespace. You can add extra ImGui:: functions in your own separate file. Please don't modify imgui source files!)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace ImGui
|
||||
@ -242,16 +242,16 @@ namespace ImGui
|
||||
|
||||
// Main
|
||||
IMGUI_API ImGuiIO& GetIO(); // access the IO structure (mouse/keyboard/gamepad inputs, time, various configuration options/flags)
|
||||
IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame.
|
||||
IMGUI_API ImGuiStyle& GetStyle(); // access the Style structure (colors, sizes). Always use PushStyleCol(), PushStyleVar() to modify style mid-frame!
|
||||
IMGUI_API void NewFrame(); // start a new Dear ImGui frame, you can submit any command from this point until Render()/EndFrame().
|
||||
IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(), you likely don't need to call that yourself directly. If you don't need to render data (skipping rendering) you may call EndFrame() but you'll have wasted CPU already! If you don't need to render, better to not create any imgui windows and not call NewFrame() at all!
|
||||
IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can get call GetDrawData() to obtain it and run your rendering function. (Obsolete: this used to call io.RenderDrawListsFn(). Nowadays, we allow and prefer calling your render function yourself.)
|
||||
IMGUI_API void EndFrame(); // ends the Dear ImGui frame. automatically called by Render(). If you don't need to render data (skipping rendering) you may call EndFrame() without Render()... but you'll have wasted CPU already! If you don't need to render, better to not create any windows and not call NewFrame() at all!
|
||||
IMGUI_API void Render(); // ends the Dear ImGui frame, finalize the draw data. You can get call GetDrawData() to obtain it and run your rendering function (up to v1.60, this used to call io.RenderDrawListsFn(). Nowadays, we allow and prefer calling your render function yourself.)
|
||||
IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render.
|
||||
|
||||
// Demo, Debug, Information
|
||||
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create Demo window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application!
|
||||
IMGUI_API void ShowAboutWindow(bool* p_open = NULL); // create About window. display Dear ImGui version, credits and build/system information.
|
||||
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Metrics/Debug window. display Dear ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc.
|
||||
IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create Debug/Metrics window. display Dear ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc.
|
||||
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style)
|
||||
IMGUI_API bool ShowStyleSelector(const char* label); // add style selector block (not a window), essentially a combo listing the default styles.
|
||||
IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.
|
||||
@ -357,11 +357,11 @@ namespace ImGui
|
||||
IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied
|
||||
|
||||
// Parameters stacks (current window)
|
||||
IMGUI_API void PushItemWidth(float item_width); // set width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
|
||||
IMGUI_API void PushItemWidth(float item_width); // push width of items for common large "item+label" widgets. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side). 0.0f = default to ~2/3 of windows width,
|
||||
IMGUI_API void PopItemWidth();
|
||||
IMGUI_API void SetNextItemWidth(float item_width); // set width of the _next_ common large "item+label" widget. >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side)
|
||||
IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position. NOT necessarily the width of last item unlike most 'Item' functions.
|
||||
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
|
||||
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x = 0.0f); // push word-wrapping position for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space
|
||||
IMGUI_API void PopTextWrapPos();
|
||||
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets
|
||||
IMGUI_API void PopAllowKeyboardFocus();
|
||||
@ -372,6 +372,9 @@ namespace ImGui
|
||||
// - By "cursor" we mean the current output position.
|
||||
// - The typical widget behavior is to output themselves at the current cursor position, then move the cursor one line down.
|
||||
// - You can call SameLine() between widgets to undo the last carriage return and output at the right of the preceeding widget.
|
||||
// - Attention! We currently have inconsistencies between window-local and absolute positions we will aim to fix with future API:
|
||||
// Window-local coordinates: SameLine(), GetCursorPos(), SetCursorPos(), GetCursorStartPos(), GetContentRegionMax(), GetWindowContentRegion*(), PushTextWrapPos()
|
||||
// Absolute coordinate: GetCursorScreenPos(), SetCursorScreenPos(), all ImDrawList:: functions.
|
||||
IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator.
|
||||
IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f); // call between widgets or groups to layout them horizontally. X position given in window coordinates.
|
||||
IMGUI_API void NewLine(); // undo a SameLine() or force a new line when in an horizontal-layout context.
|
||||
@ -568,7 +571,8 @@ namespace ImGui
|
||||
|
||||
// Widgets: Menus
|
||||
// - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar.
|
||||
// - Use BeginMainMenuBar() to create a menu bar at the top of the screen.
|
||||
// - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it.
|
||||
// - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it.
|
||||
IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window).
|
||||
IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true!
|
||||
IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar.
|
||||
@ -609,7 +613,7 @@ namespace ImGui
|
||||
// - You can also use SameLine(pos_x) to mimic simplified columns.
|
||||
// - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!)
|
||||
// - There is a maximum of 64 columns.
|
||||
// - Currently working on new 'Tables' api which will replace columns (see GitHub #2957)
|
||||
// - Currently working on new 'Tables' api which will replace columns around Q2 2020 (see GitHub #2957).
|
||||
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true);
|
||||
IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished
|
||||
IMGUI_API int GetColumnIndex(); // get current column index
|
||||
@ -704,11 +708,13 @@ namespace ImGui
|
||||
IMGUI_API const char* GetStyleColorName(ImGuiCol idx); // get a string corresponding to the enum value (for display, saving, etc.).
|
||||
IMGUI_API void SetStateStorage(ImGuiStorage* storage); // replace current window storage with our own (if you want to manipulate it yourself, typically clear subsection of it)
|
||||
IMGUI_API ImGuiStorage* GetStateStorage();
|
||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can.
|
||||
IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame
|
||||
IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window)
|
||||
|
||||
// Text Utilities
|
||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
|
||||
|
||||
// Color Utilities
|
||||
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in);
|
||||
IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in);
|
||||
|
@ -3659,6 +3659,7 @@ static void ShowExampleMenuFile()
|
||||
}
|
||||
if (ImGui::MenuItem("Save", "Ctrl+S")) {}
|
||||
if (ImGui::MenuItem("Save As..")) {}
|
||||
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
{
|
||||
@ -3670,13 +3671,12 @@ static void ShowExampleMenuFile()
|
||||
ImGui::EndChild();
|
||||
static float f = 0.5f;
|
||||
static int n = 0;
|
||||
static bool b = true;
|
||||
ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
|
||||
ImGui::InputFloat("Input", &f, 0.1f);
|
||||
ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
|
||||
ImGui::Checkbox("Check", &b);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Colors"))
|
||||
{
|
||||
float sz = ImGui::GetTextLineHeight();
|
||||
@ -3691,6 +3691,17 @@ static void ShowExampleMenuFile()
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
// Here we demonstrate appending again to the "Options" menu (which we already created above)
|
||||
// Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice.
|
||||
// In a real code-base using it would make senses to use this feature from very different code locations.
|
||||
if (ImGui::BeginMenu("Options")) // <-- Append!
|
||||
{
|
||||
static bool b = true;
|
||||
ImGui::Checkbox("SomeOption", &b);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Disabled", false)) // Disabled
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
@ -4540,16 +4551,37 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
|
||||
if (ImGui::BeginTabBar("##TabBar"))
|
||||
{
|
||||
// Primitives
|
||||
if (ImGui::BeginTabItem("Primitives"))
|
||||
{
|
||||
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
|
||||
|
||||
// Draw gradients
|
||||
// (note that those are currently exacerbating our sRGB/Linear issues)
|
||||
ImGui::Text("Gradients");
|
||||
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), ImGui::GetFrameHeight());
|
||||
{
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
draw_list->AddRectFilledMultiColor(p, ImVec2(p.x + gradient_size.x, p.y + gradient_size.y), col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient1", gradient_size);
|
||||
}
|
||||
{
|
||||
ImVec2 p = ImGui::GetCursorScreenPos();
|
||||
ImU32 col_a = ImGui::GetColorU32(ImVec4(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
ImU32 col_b = ImGui::GetColorU32(ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
draw_list->AddRectFilledMultiColor(p, ImVec2(p.x + gradient_size.x, p.y + gradient_size.y), col_a, col_b, col_b, col_a);
|
||||
ImGui::InvisibleButton("##gradient2", gradient_size);
|
||||
}
|
||||
|
||||
// Draw a bunch of primitives
|
||||
ImGui::Text("All primitives");
|
||||
static float sz = 36.0f;
|
||||
static float thickness = 3.0f;
|
||||
static int ngon_sides = 6;
|
||||
static bool circle_segments_override = false;
|
||||
static int circle_segments_override_v = 12;
|
||||
static ImVec4 colf = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||
ImGui::PushItemWidth(-ImGui::GetFontSize() * 10);
|
||||
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
|
||||
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
|
||||
ImGui::SliderInt("N-gon sides", &ngon_sides, 3, 12);
|
||||
@ -4597,26 +4629,6 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255));
|
||||
ImGui::Dummy(ImVec2((sz + spacing) * 9.8f, (sz + spacing) * 3));
|
||||
|
||||
// Draw black and white gradients
|
||||
static int gradient_steps = 16;
|
||||
ImGui::Separator();
|
||||
ImGui::AlignTextToFramePadding();
|
||||
ImGui::Text("Gradient steps");
|
||||
ImGui::SameLine(); if (ImGui::RadioButton("16", gradient_steps == 16)) { gradient_steps = 16; }
|
||||
ImGui::SameLine(); if (ImGui::RadioButton("32", gradient_steps == 32)) { gradient_steps = 32; }
|
||||
ImGui::SameLine(); if (ImGui::RadioButton("256", gradient_steps == 256)) { gradient_steps = 256; }
|
||||
ImVec2 gradient_size = ImVec2(ImGui::CalcItemWidth(), 64.0f);
|
||||
x = ImGui::GetCursorScreenPos().x;
|
||||
y = ImGui::GetCursorScreenPos().y;
|
||||
for (int n = 0; n < gradient_steps; n++)
|
||||
{
|
||||
float f0 = n / (float)gradient_steps;
|
||||
float f1 = (n + 1) / (float)gradient_steps;
|
||||
ImU32 col32 = ImGui::GetColorU32(ImVec4(f0, f0, f0, 1.0f));
|
||||
draw_list->AddRectFilled(ImVec2(x + gradient_size.x * f0, y), ImVec2(x + gradient_size.x * f1, y + gradient_size.y), col32);
|
||||
}
|
||||
ImGui::InvisibleButton("##gradient", gradient_size);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
@ -4684,9 +4696,9 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
ImVec2 window_size = ImGui::GetWindowSize();
|
||||
ImVec2 window_center = ImVec2(window_pos.x + window_size.x * 0.5f, window_pos.y + window_size.y * 0.5f);
|
||||
if (draw_bg)
|
||||
ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 48, 10+4);
|
||||
ImGui::GetBackgroundDrawList()->AddCircle(window_center, window_size.x * 0.6f, IM_COL32(255, 0, 0, 200), 0, 10+4);
|
||||
if (draw_fg)
|
||||
ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 48, 10);
|
||||
ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 0, 10);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
|
@ -1307,7 +1307,7 @@ struct ImGuiContext
|
||||
ImVec2 LastValidMousePos;
|
||||
ImGuiInputTextState InputTextState;
|
||||
ImFont InputTextPasswordFont;
|
||||
ImGuiID TempInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
|
||||
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
|
||||
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
|
||||
float ColorEditLastHue; // Backup of last Hue associated to LastColor[3], so we can restore Hue in lossy RGB<>HSV round trips
|
||||
float ColorEditLastSat; // Backup of last Saturation associated to LastColor[3], so we can restore Saturation in lossy RGB<>HSV round trips
|
||||
@ -1319,6 +1319,7 @@ struct ImGuiContext
|
||||
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
|
||||
int TooltipOverrideCount;
|
||||
ImVector<char> PrivateClipboard; // If no custom clipboard handler is defined
|
||||
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
|
||||
|
||||
// Platform support
|
||||
ImVec2 PlatformImePos; // Cursor position request & last passed to the OS Input Method Editor
|
||||
@ -1462,7 +1463,7 @@ struct ImGuiContext
|
||||
CurrentTabBar = NULL;
|
||||
|
||||
LastValidMousePos = ImVec2(0.0f, 0.0f);
|
||||
TempInputTextId = 0;
|
||||
TempInputId = 0;
|
||||
ColorEditOptions = ImGuiColorEditFlags__OptionsDefault;
|
||||
ColorEditLastHue = ColorEditLastSat = 0.0f;
|
||||
ColorEditLastColor[0] = ColorEditLastColor[1] = ColorEditLastColor[2] = FLT_MAX;
|
||||
@ -2098,8 +2099,9 @@ namespace ImGui
|
||||
|
||||
// InputText
|
||||
IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format);
|
||||
inline bool TempInputTextIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputTextId == id); }
|
||||
IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags);
|
||||
IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format);
|
||||
inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); }
|
||||
|
||||
// Color
|
||||
IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags);
|
||||
|
@ -68,6 +68,9 @@ Index of this file:
|
||||
#if __has_warning("-Wdouble-promotion")
|
||||
#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
|
||||
#endif
|
||||
#if __has_warning("-Wdeprecated-enum-enum-conversion")
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated
|
||||
#endif
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||||
@ -2116,7 +2119,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an input box
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
bool temp_input_is_active = TempInputTextIsActive(id);
|
||||
bool temp_input_is_active = TempInputIsActive(id);
|
||||
bool temp_input_start = false;
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
@ -2137,7 +2140,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
}
|
||||
}
|
||||
if (temp_input_is_active || temp_input_start)
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
@ -2568,7 +2571,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
|
||||
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
bool temp_input_is_active = TempInputTextIsActive(id);
|
||||
bool temp_input_is_active = TempInputIsActive(id);
|
||||
bool temp_input_start = false;
|
||||
if (!temp_input_is_active)
|
||||
{
|
||||
@ -2588,7 +2591,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
}
|
||||
}
|
||||
if (temp_input_is_active || temp_input_start)
|
||||
return TempInputTextScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
return TempInputScalar(frame_bb, id, label, data_type, p_data, format);
|
||||
|
||||
// Draw frame
|
||||
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
|
||||
@ -2867,32 +2870,39 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
|
||||
|
||||
// Create text input in place of another active widget (e.g. used when doing a CTRL+Click on drag/slider widgets)
|
||||
// FIXME: Facilitate using this in variety of other situations.
|
||||
bool ImGui::TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format)
|
||||
bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// On the first frame, g.TempInputTextId == 0, then on subsequent frames it becomes == id.
|
||||
// We clear ActiveID on the first frame to allow the InputText() taking it back.
|
||||
const bool init = (g.TempInputTextId != id);
|
||||
ImGuiContext& g = *GImGui;
|
||||
const bool init = (g.TempInputId != id);
|
||||
if (init)
|
||||
ClearActiveID();
|
||||
|
||||
g.CurrentWindow->DC.CursorPos = bb.Min;
|
||||
bool value_changed = InputTextEx(label, NULL, buf, buf_size, bb.GetSize(), flags);
|
||||
if (init)
|
||||
{
|
||||
// First frame we started displaying the InputText widget, we expect it to take the active id.
|
||||
IM_ASSERT(g.ActiveId == id);
|
||||
g.TempInputId = g.ActiveId;
|
||||
}
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
char fmt_buf[32];
|
||||
char data_buf[32];
|
||||
format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf));
|
||||
DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format);
|
||||
ImStrTrimBlanks(data_buf);
|
||||
|
||||
g.CurrentWindow->DC.CursorPos = bb.Min;
|
||||
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_NoMarkEdited;
|
||||
flags |= ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal);
|
||||
bool value_changed = InputTextEx(label, NULL, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags);
|
||||
if (init)
|
||||
{
|
||||
// First frame we started displaying the InputText widget, we expect it to take the active id.
|
||||
IM_ASSERT(g.ActiveId == id);
|
||||
g.TempInputTextId = g.ActiveId;
|
||||
}
|
||||
bool value_changed = TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags);
|
||||
if (value_changed)
|
||||
{
|
||||
value_changed = DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialTextA.Data, data_type, p_data, NULL);
|
||||
@ -5576,7 +5586,9 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
|
||||
return false;
|
||||
|
||||
ImGuiID id = window->GetID(label);
|
||||
flags |= ImGuiTreeNodeFlags_CollapsingHeader | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton : 0);
|
||||
flags |= ImGuiTreeNodeFlags_CollapsingHeader;
|
||||
if (p_open)
|
||||
flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton;
|
||||
bool is_open = TreeNodeBehavior(id, flags, label);
|
||||
if (p_open)
|
||||
{
|
||||
@ -6239,11 +6251,30 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
ImGuiContext& g = *GImGui;
|
||||
const ImGuiStyle& style = g.Style;
|
||||
const ImGuiID id = window->GetID(label);
|
||||
bool menu_is_open = IsPopupOpen(id);
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu))
|
||||
flags |= ImGuiWindowFlags_ChildWindow;
|
||||
|
||||
// If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin().
|
||||
// We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame.
|
||||
// If somehow this is ever becoming a problem we can switch to use e.g. a ImGuiStorager mapping key to last frame used.
|
||||
if (g.MenusIdSubmittedThisFrame.contains(id))
|
||||
{
|
||||
if (menu_is_open)
|
||||
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
else
|
||||
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
|
||||
return menu_is_open;
|
||||
}
|
||||
|
||||
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
|
||||
g.MenusIdSubmittedThisFrame.push_back(id);
|
||||
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
bool pressed;
|
||||
bool menu_is_open = IsPopupOpen(id);
|
||||
bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].OpenParentId == window->IDStack.back());
|
||||
ImGuiWindow* backed_nav_window = g.NavWindow;
|
||||
if (menuset_is_open)
|
||||
@ -6362,13 +6393,13 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
|
||||
if (menu_is_open)
|
||||
{
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
SetNextWindowPos(popup_pos, ImGuiCond_Always);
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
||||
flags |= ImGuiWindowFlags_ChildWindow;
|
||||
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
|
||||
}
|
||||
else
|
||||
{
|
||||
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
|
||||
}
|
||||
|
||||
return menu_is_open;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user