Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_sdl2.cpp
#	backends/imgui_impl_sdl2.h
#	backends/imgui_impl_sdl3.cpp
#	backends/imgui_impl_sdl3.h
#	imgui.cpp
This commit is contained in:
ocornut 2023-02-10 17:05:06 +01:00
commit ea4565368e
21 changed files with 369 additions and 129 deletions

View File

@ -21,7 +21,7 @@ jobs:
VS_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\
MSBUILD_PATH: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
shell: powershell
@ -207,9 +207,9 @@ jobs:
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
Linux:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
@ -402,7 +402,7 @@ jobs:
MacOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
@ -462,7 +462,7 @@ jobs:
iOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build example_apple_metal
run: |
@ -470,9 +470,9 @@ jobs:
xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_ios CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
Emscripten:
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Dependencies
run: |
@ -497,9 +497,9 @@ jobs:
make -C examples/example_emscripten_wgpu
Android:
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build example_android_opengl3
run: |

View File

@ -10,9 +10,9 @@ on:
jobs:
PVS-Studio:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
with:
fetch-depth: 1

View File

@ -607,6 +607,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
#elif defined(__APPLE__)
main_viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(bd->Window);
#else
IM_UNUSED(main_viewport);
#endif
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
ImGui_ImplGlfw_InitPlatformInterface();

View File

@ -10,8 +10,8 @@
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@ -21,6 +21,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2023-02-07: Implement IME handler (io.SetPlatformImeDataFn will call SDL_SetTextInputRect()/SDL_StartTextInput()).
// 2023-02-07: *BREAKING CHANGE* Renamed this backend file from imgui_impl_sdl.cpp/.h to imgui_impl_sdl2.cpp/.h in prevision for the future release of SDL3.
// 2023-02-02: Avoid calling SDL_SetCursor() when cursor has not changed, as the function is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version).
// 2023-02-02: Added support for SDL 2.0.18+ preciseX/preciseY mouse wheel data for smooth scrolling + Scaling X value on Emscripten (bug?). (#4019, #6096)
@ -144,6 +145,25 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text)
SDL_SetClipboardText(text);
}
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
static void ImGui_ImplSDL2_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
{
if (data->WantVisible)
{
SDL_Rect r;
r.x = (int)data->InputPos.x;
r.y = (int)data->InputPos.y;
r.w = 1;
r.h = (int)data->InputLineHeight;
SDL_SetTextInputRect(&r);
SDL_StartTextInput();
}
else
{
SDL_StopTextInput();
}
}
static ImGuiKey ImGui_ImplSDL2_KeycodeToImGuiKey(int keycode)
{
switch (keycode)
@ -412,6 +432,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText;
io.ClipboardUserData = nullptr;
io.SetPlatformImeDataFn = ImGui_ImplSDL2_SetPlatformImeData;
// Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
@ -449,6 +470,13 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
#endif
// From 2.0.18: Enable native IME.
// IMPORTANT: This is used at the time of SDL_CreateWindow() so this will only affects secondary windows, if any.
// For the main window to be affected, your application needs to call this manually before calling SDL_CreateWindow().
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
#ifdef SDL_HINT_MOUSE_AUTO_CAPTURE
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");

View File

@ -9,8 +9,8 @@
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
// Missing features:
// [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME.
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

View File

@ -11,6 +11,7 @@
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
// Missing features:
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@ -86,6 +87,24 @@ static void ImGui_ImplSDL3_SetClipboardText(void*, const char* text)
SDL_SetClipboardText(text);
}
static void ImGui_ImplSDL3_SetPlatformImeData(ImGuiViewport*, ImGuiPlatformImeData* data)
{
if (data->WantVisible)
{
SDL_Rect r;
r.x = (int)data->InputPos.x;
r.y = (int)data->InputPos.y;
r.w = 1;
r.h = (int)data->InputLineHeight;
SDL_SetTextInputRect(&r);
SDL_StartTextInput();
}
else
{
SDL_StopTextInput();
}
}
static ImGuiKey ImGui_ImplSDL3_KeycodeToImGuiKey(int keycode)
{
switch (keycode)
@ -352,6 +371,7 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
io.SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
io.GetClipboardTextFn = ImGui_ImplSDL3_GetClipboardText;
io.ClipboardUserData = nullptr;
io.SetPlatformImeDataFn = ImGui_ImplSDL3_SetPlatformImeData;
// Load mouse cursors
bd->MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
@ -370,11 +390,11 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
main_viewport->PlatformHandle = (void*)window;
main_viewport->PlatformHandleRaw = nullptr;
SDL_SysWMinfo info;
if (SDL_GetWindowWMInfo(window, &info, SDL_SYSWM_CURRENT_VERSION))
if (SDL_GetWindowWMInfo(window, &info, SDL_SYSWM_CURRENT_VERSION) == 0)
{
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
#if defined(SDL_ENABLE_SYSWM_WINDOWS)
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
#elif defined(__APPLE__) && defined(SDL_ENABLE_SYSWM_COCOA)
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
#endif
}

View File

@ -11,6 +11,7 @@
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
// Missing features:
// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows).
// [x] Platform: Basic IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.

View File

@ -131,6 +131,9 @@ All changes:
to find a way to detect this and set io.ConfigMacOSXBehaviors manually (if you know a way
let us know!), or offer the "OSX-style behavior" option to their user.
- Window: Avoid rendering shapes for hidden resize grips.
- SeparatorText(): Added SeparatorText() widget. (#1643) [@phed, @ocornut]
- Added to style: float SeparatorTextBorderSize.
- Added to style: ImVec2 SeparatorTextAlign, SeparatorTextPadding.
- Tables: Raised max Columns count from 64 to 512. (#6094, #5305, #4876, #3572)
The previous limit was due to using 64-bit integers but we moved to bits-array
and tweaked the system enough to ensure no performance loss.
@ -165,6 +168,9 @@ All changes:
for smooth scrolling as reported by SDL. (#4019, #6096)
- Backends: SDL2: Avoid calling SDL_SetCursor() when cursor has not changed, as the function
is surprisingly costly on Mac with latest SDL (may be fixed in next SDL version). (#6113)
- Backends: SDL2: Implement IME handler to call SDL_SetTextInputRect()/SDL_StartTextInput().
It will only works with SDL 2.0.18+ if your code calls 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1")'
prior to calling SDL_CreateWindow(). Updated all examples accordingly. (#6071, #1953)
- Backends: SDL3: Added experimental imgui_impl_sdl3.cpp backend. (#6146) [@dovker, @ocornut]
SDL 3.0.0 has not yet been released, so it is possible that its specs/api will change before
release. This backend is provided as a convenience for early adopters etc. We don't recommend

View File

@ -35,6 +35,11 @@ int main(int, char**)
return -1;
}
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Setup window
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

View File

@ -63,6 +63,9 @@ int main(int, char**)
// Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail.
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal");
// Enable native IME.
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
if (window == NULL)
{

View File

@ -24,6 +24,11 @@ int main(int, char**)
return -1;
}
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Setup window
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

View File

@ -53,6 +53,11 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

View File

@ -27,6 +27,11 @@ int main(int, char**)
return -1;
}
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Create window with SDL_Renderer graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

View File

@ -350,6 +350,11 @@ int main(int, char**)
return -1;
}
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Create window with Vulkan graphics context
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);

View File

@ -53,6 +53,9 @@ int main(int, char**)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
// Enable native IME.
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

196
imgui.cpp
View File

@ -1143,6 +1143,9 @@ ImGuiStyle::ImGuiStyle()
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
SeparatorTextBorderSize = 3.0f; // Thickkness of border in SeparatorText()
SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
SeparatorTextPadding = ImVec2(20.0f,3.f);// Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
@ -1180,6 +1183,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor)
LogSliderDeadzone = ImFloor(LogSliderDeadzone * scale_factor);
TabRounding = ImFloor(TabRounding * scale_factor);
TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImFloor(TabMinWidthForCloseButton * scale_factor) : FLT_MAX;
SeparatorTextPadding = ImFloor(SeparatorTextPadding * scale_factor);
DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor);
DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor);
MouseCursorScale = ImFloor(MouseCursorScale * scale_factor);
@ -3086,6 +3090,9 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] =
{ 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
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding
};
static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx)
@ -3706,7 +3713,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst
ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
AutoFitFramesX = AutoFitFramesY = -1;
AutoPosLastDirection = ImGuiDir_None;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = 0;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
LastFrameActive = -1;
LastFrameJustFocused = -1;
@ -5058,10 +5065,12 @@ void ImGui::EndFrame()
ErrorCheckEndFrameSanityChecks();
// Notify Platform/OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
if (g.IO.SetPlatformImeDataFn && memcmp(&g.PlatformImeData, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0)
ImGuiPlatformImeData* ime_data = &g.PlatformImeData;
if (g.IO.SetPlatformImeDataFn && memcmp(ime_data, &g.PlatformImeDataPrev, sizeof(ImGuiPlatformImeData)) != 0)
{
ImGuiViewport* viewport = FindViewportByID(g.PlatformImeViewport);
g.IO.SetPlatformImeDataFn(viewport ? viewport : GetMainViewport(), &g.PlatformImeData);
IMGUI_DEBUG_LOG_IO("Calling io.SetPlatformImeDataFn(): WantVisible: %d, InputPos (%.2f,%.2f)\n", ime_data->WantVisible, ime_data->InputPos.x, ime_data->InputPos.y);
g.IO.SetPlatformImeDataFn(viewport ? viewport : GetMainViewport(), ime_data);
}
// Hide implicit/fallback "Debug" window if it hasn't been used
@ -5627,33 +5636,23 @@ static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created,
window->IsExplicitChild = new_is_explicit_child;
}
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags)
static void InitOrLoadWindowSettings(ImGuiWindow* window, ImGuiWindowSettings* settings)
{
ImGuiContext& g = *GImGui;
//IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags);
// Create window the first time
ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name);
window->Flags = flags;
g.WindowsById.SetVoidPtr(window->ID, window);
// Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
// Initial window state with e.g. default/arbitrary window position
// Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
const ImGuiViewport* main_viewport = ImGui::GetMainViewport();
window->Pos = main_viewport->Pos + ImVec2(60, 60);
window->ViewportPos = main_viewport->Pos;
window->SetWindowPosAllowFlags = window->SetWindowSizeAllowFlags = window->SetWindowCollapsedAllowFlags = window->SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
// User can disable loading and saving of settings. Tooltip and child windows also don't store settings.
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
{
// Retrieve settings from .ini file
window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
ApplyWindowSettings(window, settings);
}
if (settings != NULL)
{
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
ApplyWindowSettings(window, settings);
}
window->DC.CursorStartPos = window->DC.CursorMaxPos = window->DC.IdealMaxPos = window->Pos; // So first call to CalcWindowContentSizes() doesn't return crazy values
if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
if ((window->Flags & ImGuiWindowFlags_AlwaysAutoResize) != 0)
{
window->AutoFitFramesX = window->AutoFitFramesY = 2;
window->AutoFitOnlyGrows = false;
@ -5666,6 +5665,23 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags)
window->AutoFitFramesY = 2;
window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0);
}
}
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags)
{
// Create window the first time
//IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags);
ImGuiContext& g = *GImGui;
ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name);
window->Flags = flags;
g.WindowsById.SetVoidPtr(window->ID, window);
ImGuiWindowSettings* settings = NULL;
if (!(flags & ImGuiWindowFlags_NoSavedSettings))
if ((settings = ImGui::FindWindowSettingsByWindow(window)) != 0)
window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
InitOrLoadWindowSettings(window, settings);
if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus)
g.Windows.push_front(window); // Quite slow but rare and only once
@ -13114,15 +13130,17 @@ void ImGui::LogButtons()
//-----------------------------------------------------------------------------
// - UpdateSettings() [Internal]
// - MarkIniSettingsDirty() [Internal]
// - CreateNewWindowSettings() [Internal]
// - FindWindowSettings() [Internal]
// - FindOrCreateWindowSettings() [Internal]
// - FindSettingsHandler() [Internal]
// - ClearIniSettings() [Internal]
// - LoadIniSettingsFromDisk()
// - LoadIniSettingsFromMemory()
// - SaveIniSettingsToDisk()
// - SaveIniSettingsToMemory()
//-----------------------------------------------------------------------------
// - CreateNewWindowSettings() [Internal]
// - FindWindowSettingsByID() [Internal]
// - FindWindowSettingsByWindow() [Internal]
// - ClearWindowSettings() [Internal]
// - WindowSettingsHandler_***() [Internal]
//-----------------------------------------------------------------------------
@ -13169,44 +13187,6 @@ void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
g.SettingsDirtyTimer = g.IO.IniSavingRate;
}
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
{
ImGuiContext& g = *GImGui;
#if !IMGUI_DEBUG_INI_SETTINGS
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
if (const char* p = strstr(name, "###"))
name = p;
#endif
const size_t name_len = strlen(name);
// Allocate chunk
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
IM_PLACEMENT_NEW(settings) ImGuiWindowSettings();
settings->ID = ImHashStr(name, name_len);
memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator
return settings;
}
ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
if (settings->ID == id)
return settings;
return NULL;
}
ImGuiWindowSettings* ImGui::FindOrCreateWindowSettings(const char* name)
{
if (ImGuiWindowSettings* settings = FindWindowSettings(ImHashStr(name)))
return settings;
return CreateNewWindowSettings(name);
}
void ImGui::AddSettingsHandler(const ImGuiSettingsHandler* handler)
{
ImGuiContext& g = *GImGui;
@ -13231,6 +13211,7 @@ ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name)
return NULL;
}
// Clear all settings (windows, tables, docking etc.)
void ImGui::ClearIniSettings()
{
ImGuiContext& g = *GImGui;
@ -13355,6 +13336,62 @@ const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
return g.SettingsIniData.c_str();
}
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
{
ImGuiContext& g = *GImGui;
#if !IMGUI_DEBUG_INI_SETTINGS
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
if (const char* p = strstr(name, "###"))
name = p;
#endif
const size_t name_len = strlen(name);
// Allocate chunk
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
IM_PLACEMENT_NEW(settings) ImGuiWindowSettings();
settings->ID = ImHashStr(name, name_len);
memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator
return settings;
}
// We don't provide a FindWindowSettingsByName() because Docking system doesn't always hold on names.
// This is called once per window .ini entry + once per newly instantiated window.
ImGuiWindowSettings* ImGui::FindWindowSettingsByID(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
if (settings->ID == id)
return settings;
return NULL;
}
// This is faster if you are holding on a Window already as we don't need to perform a search.
ImGuiWindowSettings* ImGui::FindWindowSettingsByWindow(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
if (window->SettingsOffset != -1)
return g.SettingsWindows.ptr_from_offset(window->SettingsOffset);
return FindWindowSettingsByID(window->ID);
}
// This will revert window to its initial state, including enabling the ImGuiCond_FirstUseEver/ImGuiCond_Once conditions once more.
void ImGui::ClearWindowSettings(const char* name)
{
//IMGUI_DEBUG_LOG("ClearWindowSettings('%s')\n", name);
ImGuiWindow* window = FindWindowByName(name);
if (window != NULL)
{
window->Flags |= ImGuiWindowFlags_NoSavedSettings;
InitOrLoadWindowSettings(window, NULL);
}
if (ImGuiWindowSettings* settings = window ? FindWindowSettingsByWindow(window) : FindWindowSettingsByID(ImHashStr(name)))
settings->WantDelete = true;
}
static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandler*)
{
ImGuiContext& g = *ctx;
@ -13365,9 +13402,12 @@ static void WindowSettingsHandler_ClearAll(ImGuiContext* ctx, ImGuiSettingsHandl
static void* WindowSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)
{
ImGuiWindowSettings* settings = ImGui::FindOrCreateWindowSettings(name);
ImGuiID id = settings->ID;
*settings = ImGuiWindowSettings(); // Clear existing if recycling previous entry
ImGuiID id = ImHashStr(name);
ImGuiWindowSettings* settings = ImGui::FindWindowSettingsByID(id);
if (settings)
*settings = ImGuiWindowSettings(); // Clear existing if recycling previous entry
else
settings = ImGui::CreateNewWindowSettings(name);
settings->ID = id;
settings->WantApply = true;
return (void*)settings;
@ -13413,7 +13453,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
continue;
ImGuiWindowSettings* settings = (window->SettingsOffset != -1) ? g.SettingsWindows.ptr_from_offset(window->SettingsOffset) : ImGui::FindWindowSettings(window->ID);
ImGuiWindowSettings* settings = ImGui::FindWindowSettingsByWindow(window);
if (!settings)
{
settings = ImGui::CreateNewWindowSettings(window->Name);
@ -13429,12 +13469,15 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
settings->ClassId = window->WindowClass.ClassId;
settings->DockOrder = window->DockOrder;
settings->Collapsed = window->Collapsed;
settings->WantDelete = false;
}
// Write to text buffer
buf->reserve(buf->size() + g.SettingsWindows.size() * 6); // ballpark reserve
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
{
if (settings->WantDelete)
continue;
const char* settings_name = settings->GetName();
buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
if (settings->ViewportId != 0 && settings->ViewportId != ImGui::IMGUI_VIEWPORT_DEFAULT_ID)
@ -14906,7 +14949,7 @@ static void ImGui::DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx)
{
ImGuiDockNodeSettings* settings = &dc->NodesSettings[settings_n];
if (settings->ParentWindowId != 0)
if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->ParentWindowId))
if (ImGuiWindowSettings* window_settings = FindWindowSettingsByID(settings->ParentWindowId))
if (window_settings->DockId)
if (ImGuiDockContextPruneNodeData* data = pool.GetByKey(window_settings->DockId))
data->CountChildNodes++;
@ -17404,7 +17447,7 @@ void ImGui::DockBuilderDockWindow(const char* window_name, ImGuiID node_id)
else
{
// Apply to settings
ImGuiWindowSettings* settings = FindWindowSettings(window_id);
ImGuiWindowSettings* settings = FindWindowSettingsByID(window_id);
if (settings == NULL)
settings = CreateNewWindowSettings(window_name);
settings->DockId = node_id;
@ -17685,8 +17728,11 @@ void ImGui::DockBuilderCopyWindowSettings(const char* src_name, const char* dst_
dst_window->SizeFull = src_window->SizeFull;
dst_window->Collapsed = src_window->Collapsed;
}
else if (ImGuiWindowSettings* dst_settings = FindOrCreateWindowSettings(dst_name))
else
{
ImGuiWindowSettings* dst_settings = FindWindowSettingsByID(ImHashStr(dst_name));
if (!dst_settings)
dst_settings = CreateNewWindowSettings(dst_name);
ImVec2ih window_pos_2ih = ImVec2ih(src_window->Pos);
if (src_window->ViewportId != 0 && src_window->ViewportId != IMGUI_VIEWPORT_DEFAULT_ID)
{
@ -17732,7 +17778,7 @@ void ImGui::DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_docks
ImGuiID src_dock_id = 0;
if (ImGuiWindow* src_window = FindWindowByID(src_window_id))
src_dock_id = src_window->DockId;
else if (ImGuiWindowSettings* src_window_settings = FindWindowSettings(src_window_id))
else if (ImGuiWindowSettings* src_window_settings = FindWindowSettingsByID(src_window_id))
src_dock_id = src_window_settings->DockId;
ImGuiID dst_dock_id = 0;
for (int dock_remap_n = 0; dock_remap_n < node_remap_pairs.Size; dock_remap_n += 2)
@ -19072,7 +19118,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
{
if (ImGuiWindow* window = FindWindowByID(settings->SelectedTabId))
selected_tab_name = window->Name;
else if (ImGuiWindowSettings* window_settings = FindWindowSettings(settings->SelectedTabId))
else if (ImGuiWindowSettings* window_settings = FindWindowSettingsByID(settings->SelectedTabId))
selected_tab_name = window_settings->GetName();
}
BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings->ID, settings->ParentNodeId, settings->SelectedTabId, selected_tab_name ? selected_tab_name : settings->SelectedTabId ? "N/A" : "");
@ -19774,8 +19820,12 @@ void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label)
void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings* settings)
{
if (settings->WantDelete)
BeginDisabled();
Text("0x%08X \"%s\" Pos (%d,%d) Size (%d,%d) Collapsed=%d",
settings->ID, settings->GetName(), settings->Pos.x, settings->Pos.y, settings->Size.x, settings->Size.y, settings->Collapsed);
if (settings->WantDelete)
EndDisabled();
}
void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label)

View File

@ -23,7 +23,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
#define IMGUI_VERSION "1.89.3 WIP"
#define IMGUI_VERSION_NUM 18927
#define IMGUI_VERSION_NUM 18928
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
#define IMGUI_HAS_DOCK // Docking WIP branch
@ -502,6 +502,7 @@ namespace ImGui
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2);
IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text()
IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1);
IMGUI_API void SeparatorText(const char* label); // currently: formatted text with an horizontal line
// Widgets: Main
// - Most widgets return true when the value has been changed or when pressed/selected
@ -1683,6 +1684,9 @@ enum ImGuiStyleVar_
ImGuiStyleVar_TabRounding, // float TabRounding
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize
ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign
ImGuiStyleVar_SeparatorTextPadding,// ImVec2 SeparatorTextPadding
ImGuiStyleVar_COUNT
};
@ -1937,6 +1941,9 @@ struct ImGuiStyle
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
float SeparatorTextBorderSize; // Thickkness of border in SeparatorText()
ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center).
ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly!
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.

View File

@ -443,6 +443,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (ImGui::TreeNode("Configuration##2"))
{
ImGui::SeparatorText("General");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", &io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::SameLine(); HelpMarker("Enable keyboard controls.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
@ -502,6 +503,10 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Checkbox("io.ConfigInputTrickleEventQueue", &io.ConfigInputTrickleEventQueue);
ImGui::SameLine(); HelpMarker("Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.");
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
ImGui::SeparatorText("Widgets");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
ImGui::Checkbox("io.ConfigInputTextEnterKeepActive", &io.ConfigInputTextEnterKeepActive);
@ -512,11 +517,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something).");
ImGui::Text("Also see Style->Rendering for rendering options.");
ImGui::TreePop();
ImGui::Separator();
ImGui::Spacing();
}
IMGUI_DEMO_MARKER("Configuration/Backend Flags");
@ -537,7 +540,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &backend_flags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &backend_flags, ImGuiBackendFlags_RendererHasViewports);
ImGui::TreePop();
ImGui::Separator();
ImGui::Spacing();
}
IMGUI_DEMO_MARKER("Configuration/Style");
@ -546,7 +549,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
HelpMarker("The same contents can be accessed in 'Tools->Style Editor' or by calling the ShowStyleEditor() function.");
ImGui::ShowStyleEditor();
ImGui::TreePop();
ImGui::Separator();
ImGui::Spacing();
}
IMGUI_DEMO_MARKER("Configuration/Capture, Logging");
@ -615,6 +618,8 @@ static void ShowDemoWindowWidgets()
IMGUI_DEMO_MARKER("Widgets/Basic");
if (ImGui::TreeNode("Basic"))
{
ImGui::SeparatorText("General");
IMGUI_DEMO_MARKER("Widgets/Basic/Button");
static int clicked = 0;
if (ImGui::Button("Button"))
@ -704,6 +709,8 @@ static void ShowDemoWindowWidgets()
ImGui::LabelText("label", "Value");
ImGui::SeparatorText("Inputs");
{
// To wire InputText() with std::string or any other custom string type,
// see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file.
@ -746,6 +753,8 @@ static void ShowDemoWindowWidgets()
ImGui::InputFloat3("input float3", vec4a);
}
ImGui::SeparatorText("Drags");
{
IMGUI_DEMO_MARKER("Widgets/Basic/DragInt, DragFloat");
static int i1 = 50, i2 = 42;
@ -762,6 +771,8 @@ static void ShowDemoWindowWidgets()
ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns");
}
ImGui::SeparatorText("Sliders");
{
IMGUI_DEMO_MARKER("Widgets/Basic/SliderInt, SliderFloat");
static int i1 = 0;
@ -788,6 +799,8 @@ static void ShowDemoWindowWidgets()
ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.");
}
ImGui::SeparatorText("Selectors/Pickers");
{
IMGUI_DEMO_MARKER("Widgets/Basic/ColorEdit3, ColorEdit4");
static float col1[3] = { 1.0f, 0.0f, 0.2f };
@ -1748,7 +1761,7 @@ static void ShowDemoWindowWidgets()
}
// Use functions to generate output
// FIXME: This is rather awkward because current plot API only pass in indices.
// FIXME: This is actually VERY awkward because current plot API only pass in indices.
// We probably want an API passing floats and user provide sample rate/count.
struct Funcs
{
@ -1756,7 +1769,7 @@ static void ShowDemoWindowWidgets()
static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; }
};
static int func_type = 0, display_count = 70;
ImGui::Separator();
ImGui::SeparatorText("Functions");
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
ImGui::Combo("func", &func_type, "Sin\0Saw\0");
ImGui::SameLine();
@ -1799,6 +1812,7 @@ static void ShowDemoWindowWidgets()
static bool drag_and_drop = true;
static bool options_menu = true;
static bool hdr = false;
ImGui::SeparatorText("Options");
ImGui::Checkbox("With Alpha Preview", &alpha_preview);
ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
@ -1807,6 +1821,7 @@ static void ShowDemoWindowWidgets()
ImGuiColorEditFlags misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (drag_and_drop ? 0 : ImGuiColorEditFlags_NoDragDrop) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions);
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit");
ImGui::SeparatorText("Inline color editor");
ImGui::Text("Color widget:");
ImGui::SameLine(); HelpMarker(
"Click on the color square to open a color picker.\n"
@ -1904,7 +1919,7 @@ static void ShowDemoWindowWidgets()
ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags | (no_border ? ImGuiColorEditFlags_NoBorder : 0), ImVec2(80, 80));
IMGUI_DEMO_MARKER("Widgets/Color/ColorPicker");
ImGui::Text("Color picker:");
ImGui::SeparatorText("Color picker");
static bool alpha = true;
static bool alpha_bar = true;
static bool side_preview = true;
@ -2075,7 +2090,7 @@ static void ShowDemoWindowWidgets()
const float drag_speed = 0.2f;
static bool drag_clamp = false;
IMGUI_DEMO_MARKER("Widgets/Data Types/Drags");
ImGui::Text("Drags:");
ImGui::SeparatorText("Drags");
ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp);
ImGui::SameLine(); HelpMarker(
"As with every widget in dear imgui, we never modify values unless there is a user interaction.\n"
@ -2095,7 +2110,7 @@ static void ShowDemoWindowWidgets()
ImGui::DragScalar("drag double log",ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", ImGuiSliderFlags_Logarithmic);
IMGUI_DEMO_MARKER("Widgets/Data Types/Sliders");
ImGui::Text("Sliders");
ImGui::SeparatorText("Sliders");
ImGui::SliderScalar("slider s8 full", ImGuiDataType_S8, &s8_v, &s8_min, &s8_max, "%d");
ImGui::SliderScalar("slider u8 full", ImGuiDataType_U8, &u8_v, &u8_min, &u8_max, "%u");
ImGui::SliderScalar("slider s16 full", ImGuiDataType_S16, &s16_v, &s16_min, &s16_max, "%d");
@ -2120,7 +2135,7 @@ static void ShowDemoWindowWidgets()
ImGui::SliderScalar("slider double low log",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", ImGuiSliderFlags_Logarithmic);
ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams");
ImGui::Text("Sliders (reverse)");
ImGui::SeparatorText("Sliders (reverse)");
ImGui::SliderScalar("slider s8 reverse", ImGuiDataType_S8, &s8_v, &s8_max, &s8_min, "%d");
ImGui::SliderScalar("slider u8 reverse", ImGuiDataType_U8, &u8_v, &u8_max, &u8_min, "%u");
ImGui::SliderScalar("slider s32 reverse", ImGuiDataType_S32, &s32_v, &s32_fifty, &s32_zero, "%d");
@ -2130,7 +2145,7 @@ static void ShowDemoWindowWidgets()
IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs");
static bool inputs_step = true;
ImGui::Text("Inputs");
ImGui::SeparatorText("Inputs");
ImGui::Checkbox("Show step buttons", &inputs_step);
ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d");
ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u");
@ -2154,22 +2169,23 @@ static void ShowDemoWindowWidgets()
static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
static int vec4i[4] = { 1, 5, 100, 255 };
ImGui::SeparatorText("2-wide");
ImGui::InputFloat2("input float2", vec4f);
ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f);
ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f);
ImGui::InputInt2("input int2", vec4i);
ImGui::DragInt2("drag int2", vec4i, 1, 0, 255);
ImGui::SliderInt2("slider int2", vec4i, 0, 255);
ImGui::Spacing();
ImGui::SeparatorText("3-wide");
ImGui::InputFloat3("input float3", vec4f);
ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f);
ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f);
ImGui::InputInt3("input int3", vec4i);
ImGui::DragInt3("drag int3", vec4i, 1, 0, 255);
ImGui::SliderInt3("slider int3", vec4i, 0, 255);
ImGui::Spacing();
ImGui::SeparatorText("4-wide");
ImGui::InputFloat4("input float4", vec4f);
ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f);
ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f);
@ -2601,6 +2617,8 @@ static void ShowDemoWindowLayout()
IMGUI_DEMO_MARKER("Layout/Child windows");
if (ImGui::TreeNode("Child windows"))
{
ImGui::SeparatorText("Child windows");
HelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window.");
static bool disable_mouse_wheel = false;
static bool disable_menu = false;
@ -2653,7 +2671,7 @@ static void ShowDemoWindowLayout()
ImGui::PopStyleVar();
}
ImGui::Separator();
ImGui::SeparatorText("Misc/Advanced");
// Demonstrate a few extra things
// - Changing ImGuiCol_ChildBg (which is transparent black in default styles)
@ -3417,8 +3435,7 @@ static void ShowDemoWindowPopups()
ImGui::TextUnformatted(selected_fish == -1 ? "<None>" : names[selected_fish]);
if (ImGui::BeginPopup("my_select_popup"))
{
ImGui::Text("Aquarium");
ImGui::Separator();
ImGui::SeparatorText("Aquarium");
for (int i = 0; i < IM_ARRAYSIZE(names); i++)
if (ImGui::Selectable(names[i]))
selected_fish = i;
@ -3595,7 +3612,7 @@ static void ShowDemoWindowPopups()
if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n");
ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!");
ImGui::Separator();
//static int unused_i = 0;
@ -6240,7 +6257,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{
if (ImGui::BeginTabItem("Sizes"))
{
ImGui::Text("Main");
ImGui::SeparatorText("Main");
ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f");
ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.0f, "%.0f");
@ -6250,13 +6267,15 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f");
ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f");
ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f");
ImGui::Text("Borders");
ImGui::SeparatorText("Borders");
ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
ImGui::Text("Rounding");
ImGui::SeparatorText("Rounding");
ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
@ -6264,7 +6283,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
ImGui::Text("Alignment");
ImGui::SeparatorText("Widgets");
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
int window_menu_button_position = style.WindowMenuButtonPosition + 1;
if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0"))
@ -6274,10 +6294,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");
ImGui::SliderFloat2("SelectableTextAlign", (float*)&style.SelectableTextAlign, 0.0f, 1.0f, "%.2f");
ImGui::SameLine(); HelpMarker("Alignment applies when a selectable is larger than its text content.");
ImGui::Text("Safe Area Padding");
ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
ImGui::SliderFloat("SeparatorTextBorderSize", &style.SeparatorTextBorderSize, 0.0f, 10.0f, "%.0f");
ImGui::SliderFloat2("SeparatorTextAlign", (float*)&style.SeparatorTextAlign, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat2("SeparatorTextPadding", (float*)&style.SeparatorTextPadding, 0.0f, 40.0f, "%0.f");
ImGui::SliderFloat("LogSliderDeadzone", &style.LogSliderDeadzone, 0.0f, 12.0f, "%.0f");
ImGui::SeparatorText("Misc");
ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).");
ImGui::EndTabItem();
}
@ -6587,6 +6610,7 @@ static void ShowExampleMenuFile()
IM_ASSERT(0);
}
if (ImGui::MenuItem("Checked", NULL, true)) {}
ImGui::Separator();
if (ImGui::MenuItem("Quit", "Alt+F4")) {}
}

View File

@ -1781,6 +1781,7 @@ struct ImGuiWindowSettings
short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible.
bool Collapsed;
bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
bool WantDelete; // Set to invalidate/delete the settings entry
ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); DockOrder = -1; }
char* GetName() { return (char*)(this + 1); }
@ -2998,13 +2999,16 @@ namespace ImGui
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window);
IMGUI_API void ClearIniSettings();
IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name);
IMGUI_API void AddSettingsHandler(const ImGuiSettingsHandler* handler);
IMGUI_API void RemoveSettingsHandler(const char* type_name);
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
// Settings - Windows
IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
IMGUI_API ImGuiWindowSettings* FindWindowSettingsByID(ImGuiID id);
IMGUI_API ImGuiWindowSettings* FindWindowSettingsByWindow(ImGuiWindow* window);
IMGUI_API void ClearWindowSettings(const char* name);
// Localization
IMGUI_API void LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count);
inline const char* LocalizeGetMsg(ImGuiLocKey key) { ImGuiContext& g = *GImGui; const char* msg = g.LocalizationTable[key]; return msg ? msg : "*Missing Text*"; }
@ -3369,6 +3373,7 @@ namespace ImGui
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col, ImGuiButtonFlags flags = 0);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API void SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_width);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);

View File

@ -1144,12 +1144,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
EndPopup();
}
// [Part 13] Sanitize and build sort specs before we have a change to use them for display.
// [Part 12] Sanitize and build sort specs before we have a change to use them for display.
// This path will only be exercised when sort specs are modified before header rows (e.g. init or visibility change)
if (table->IsSortSpecsDirty && (table->Flags & ImGuiTableFlags_Sortable))
TableSortSpecsBuild(table);
// [Part 14] Setup inner window decoration size (for scrolling / nav tracking to properly take account of frozen rows/columns)
// [Part 13] Setup inner window decoration size (for scrolling / nav tracking to properly take account of frozen rows/columns)
if (table->FreezeColumnsRequest > 0)
table->InnerWindow->DecoInnerSizeX1 = table->Columns[table->DisplayOrderToIndex[table->FreezeColumnsRequest - 1]].MaxX - table->OuterRect.Min.x;
if (table->FreezeRowsRequest > 0)

View File

@ -1390,6 +1390,7 @@ void ImGui::AlignTextToFramePadding()
}
// Horizontal/vertical separating line
// FIXME: Surprisingly, this seemingly simple widget is adjacent to MANY different legacy/tricky layout issues.
void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
@ -1399,20 +1400,19 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
ImGuiContext& g = *GImGui;
IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected
float thickness_draw = 1.0f;
float thickness_layout = 0.0f;
const float thickness = 1.0f; // Cannot use g.Style.SeparatorTextSize yet for various reasons.
if (flags & ImGuiSeparatorFlags_Vertical)
{
// Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
// Vertical separator, for menu bars (use current line height).
float y1 = window->DC.CursorPos.y;
float y2 = window->DC.CursorPos.y + window->DC.CurrLineSize.y;
const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + thickness_draw, y2));
ItemSize(ImVec2(thickness_layout, 0.0f));
const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + thickness, y2));
ItemSize(ImVec2(thickness, 0.0f));
if (!ItemAdd(bb, 0))
return;
// Draw
window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator));
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled)
LogText(" |");
}
@ -1440,13 +1440,14 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
// We don't provide our width to the layout so that it doesn't get feed back into AutoFit
// FIXME: This prevents ->CursorMaxPos based bounding box evaluation from working (e.g. TableEndCell)
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw));
ItemSize(ImVec2(0.0f, thickness_layout));
const float thickness_for_layout = (thickness == 1.0f) ? 0.0f : thickness; // FIXME: See 1.70/1.71 Separator() change: makes legacy 1-px separator not affect layout yet. Should change.
const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness));
ItemSize(ImVec2(0.0f, thickness_for_layout));
const bool item_visible = ItemAdd(bb, 0);
if (item_visible)
{
// Draw
window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_Separator));
if (g.LogEnabled)
LogRenderedText(&bb.Min, "--------------------------------\n");
@ -1472,6 +1473,71 @@ void ImGui::Separator()
SeparatorEx(flags);
}
void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end, float extra_w)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiStyle& style = g.Style;
const ImVec2 label_size = CalcTextSize(label, label_end, false);
const ImVec2 pos = window->DC.CursorPos;
const ImVec2 padding = style.SeparatorTextPadding;
const float separator_thickness = style.SeparatorTextBorderSize;
const ImVec2 min_size(label_size.x + extra_w + padding.x * 2.0f, ImMax(label_size.y + padding.y * 2.0f, separator_thickness));
const ImRect bb(pos, ImVec2(window->WorkRect.Max.x, pos.y + min_size.y));
const float text_baseline_y = ImFloor((bb.GetHeight() - label_size.y) * style.SeparatorTextAlign.y + 0.99999f); //ImMax(padding.y, ImFloor((style.SeparatorTextSize - label_size.y) * 0.5f));
ItemSize(min_size, text_baseline_y);
if (!ItemAdd(bb, id))
return;
const float sep1_x1 = pos.x;
const float sep2_x2 = bb.Max.x;
const float seps_y = ImFloor((bb.Min.y + bb.Max.y) * 0.5f + 0.99999f);
const float label_avail_w = ImMax(0.0f, sep2_x2 - sep1_x1 - padding.x * 2.0f);
const ImVec2 label_pos(pos.x + padding.x + ImMax(0.0f, (label_avail_w - label_size.x - extra_w) * style.SeparatorTextAlign.x), pos.y + text_baseline_y); // FIXME-ALIGN
// This allows using SameLine() to position something in the 'extra_w'
window->DC.CursorPosPrevLine.x = label_pos.x + label_size.x;
const ImU32 separator_col = GetColorU32(ImGuiCol_Separator);
if (label_size.x > 0.0f)
{
const float sep1_x2 = label_pos.x - style.ItemSpacing.x;
const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x;
if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), separator_col, separator_thickness);
if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness);
if (g.LogEnabled)
LogSetNextTextDecoration("---", NULL);
RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, bb.Max.x, label, label_end, &label_size);
}
else
{
if (g.LogEnabled)
LogText("---");
if (separator_thickness > 0.0f)
window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness);
}
}
void ImGui::SeparatorText(const char* label)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
// The SeparatorText() vs SeparatorTextEx() distinction is designed to be considerate that we may want:
// - allow headers to be draggable items (would require a stable ID + a noticeable highlight)
// - this high-level entry point to allow formatting? (may require ID separate from formatted string)
// - because of this we probably can't turn 'const char* label' into 'const char* fmt, ...'
// Otherwise, we can decide that users wanting to drag this would layout a dedicated drag-item,
// and then we can turn this into a format function.
SeparatorTextEx(0, label, FindRenderedTextEnd(label), 0.0f);
}
// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise.
bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay, ImU32 bg_col)
{