Update imgui to 1.69.

This commit is contained in:
Bartosz Taudul 2019-03-15 00:55:53 +01:00
parent e6ca8fc75f
commit 98b4b69386
10 changed files with 1594 additions and 970 deletions

View File

@ -1,4 +1,4 @@
// dear imgui, v1.68 // dear imgui, v1.69
// (main code and documentation) // (main code and documentation)
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
@ -58,9 +58,9 @@ CODE
// [SECTION] FORWARD DECLARATIONS // [SECTION] FORWARD DECLARATIONS
// [SECTION] CONTEXT AND MEMORY ALLOCATORS // [SECTION] CONTEXT AND MEMORY ALLOCATORS
// [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO) // [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
// [SECTION] MISC HELPER/UTILITIES (Maths, String, Format, Hash, File functions) // [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
// [SECTION] MISC HELPER/UTILITIES (ImText* functions) // [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
// [SECTION] MISC HELPER/UTILITIES (Color functions) // [SECTION] MISC HELPERS/UTILITIES (Color functions)
// [SECTION] ImGuiStorage // [SECTION] ImGuiStorage
// [SECTION] ImGuiTextFilter // [SECTION] ImGuiTextFilter
// [SECTION] ImGuiTextBuffer // [SECTION] ImGuiTextBuffer
@ -364,6 +364,8 @@ CODE
When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details. You can read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
- 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value! - 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
- 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already). - 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
- 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead! - 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
@ -769,7 +771,7 @@ CODE
Q: How can I use my own math types instead of ImVec2/ImVec4? Q: How can I use my own math types instead of ImVec2/ImVec4?
A: You can edit imconfig.h and setup the IM_VEC2_CLASS_EXTRA/IM_VEC4_CLASS_EXTRA macros to add implicit type conversions. A: You can edit imconfig.h and setup the IM_VEC2_CLASS_EXTRA/IM_VEC4_CLASS_EXTRA macros to add implicit type conversions.
This way you'll be able to use your own types everywhere, e.g. passsing glm::vec2 to ImGui functions instead of ImVec2. This way you'll be able to use your own types everywhere, e.g. passing glm::vec2 to ImGui functions instead of ImVec2.
Q: How can I load a different font than the default? Q: How can I load a different font than the default?
A: Use the font atlas to load the TTF/OTF file you want: A: Use the font atlas to load the TTF/OTF file you want:
@ -873,7 +875,8 @@ CODE
A: - You can create a dummy window. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags. A: - You can create a dummy window. Call Begin() with the NoBackground | NoDecoration | NoSavedSettings | NoInputs flags.
(The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse) (The ImGuiWindowFlags_NoDecoration flag itself is a shortcut for NoTitleBar | NoResize | NoScrollbar | NoCollapse)
Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like.
- You can call ImGui::GetOverlayDrawList() and use this draw list to display contents over every other imgui windows. - You can call ImGui::GetBackgroundDrawList() or ImGui::GetForegroundDrawList() and use those draw list to display
contents behind or over every other imgui windows.
- You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create
your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data. your own ImDrawListSharedData, and then call your rendered code with your own ImDrawList or ImDrawData data.
@ -955,7 +958,7 @@ CODE
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
#pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. #pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic.
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
@ -1022,7 +1025,7 @@ static void NavUpdateWindowingList();
static void NavUpdateMoveResult(); static void NavUpdateMoveResult();
static float NavUpdatePageUpPageDown(int allowed_dir_flags); static float NavUpdatePageUpPageDown(int allowed_dir_flags);
static inline void NavUpdateAnyRequestFlag(); static inline void NavUpdateAnyRequestFlag();
static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id); static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
static ImVec2 NavCalcPreferredRefPos(); static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindow(ImGuiWindow* nav_window); static void NavSaveLastChildNavWindow(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window); static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
@ -1226,7 +1229,7 @@ void ImGuiIO::ClearInputCharacters()
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] MISC HELPER/UTILITIES (Maths, String, Format, Hash, File functions) // [SECTION] MISC HELPERS/UTILITIES (Maths, String, Format, Hash, File functions)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p)
@ -1479,27 +1482,27 @@ ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
// - If we reach ### in the string we discard the hash so far and reset to the seed. // - If we reach ### in the string we discard the hash so far and reset to the seed.
// - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build) // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
// FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
ImU32 ImHashStr(const char* data, size_t data_size, ImU32 seed) ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
{ {
seed = ~seed; seed = ~seed;
ImU32 crc = seed; ImU32 crc = seed;
const unsigned char* src = (const unsigned char*)data; const unsigned char* data = (const unsigned char*)data_p;
const ImU32* crc32_lut = GCrc32LookupTable; const ImU32* crc32_lut = GCrc32LookupTable;
if (data_size != 0) if (data_size != 0)
{ {
while (data_size-- != 0) while (data_size-- != 0)
{ {
unsigned char c = *src++; unsigned char c = *data++;
if (c == '#' && src[0] == '#' && src[1] == '#') if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#')
crc = seed; crc = seed;
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
} }
} }
else else
{ {
while (unsigned char c = *src++) while (unsigned char c = *data++)
{ {
if (c == '#' && src[0] == '#' && src[1] == '#') if (c == '#' && data[0] == '#' && data[1] == '#')
crc = seed; crc = seed;
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
} }
@ -1749,7 +1752,7 @@ int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_e
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] MISC HELPER/UTILTIES (Color functions) // [SECTION] MISC HELPERS/UTILTIES (Color functions)
// Note: The Convert functions are early design which are not consistent with other API. // Note: The Convert functions are early design which are not consistent with other API.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2549,10 +2552,6 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
NavLastIds[0] = NavLastIds[1] = 0; NavLastIds[0] = NavLastIds[1] = 0;
NavRectRel[0] = NavRectRel[1] = ImRect(); NavRectRel[0] = NavRectRel[1] = ImRect();
NavLastChildNavWindow = NULL; NavLastChildNavWindow = NULL;
FocusIdxAllCounter = FocusIdxTabCounter = -1;
FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX;
FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX;
} }
ImGuiWindow::~ImGuiWindow() ImGuiWindow::~ImGuiWindow()
@ -2892,26 +2891,39 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged
return false; return false;
} }
bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop) // Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
// Increment counters
const bool is_tab_stop = (window->DC.ItemFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0; const bool is_tab_stop = (window->DC.ItemFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
window->FocusIdxAllCounter++; window->DC.FocusCounterAll++;
if (is_tab_stop) if (is_tab_stop)
window->FocusIdxTabCounter++; window->DC.FocusCounterTab++;
// Process keyboard input at this point: TAB/Shift-TAB to tab out of the currently focused item. // Process TAB/Shift-TAB to tab *OUT* of the currently focused item.
// Note that we can always TAB out of a widget that doesn't allow tabbing in. // (Note that we can always TAB out of a widget that doesn't allow tabbing in)
if (tab_stop && (g.ActiveId == id) && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab)) if (g.ActiveId == id && g.FocusTabPressed && !(g.ActiveIdBlockNavInputFlags & (1 << ImGuiNavInput_KeyTab_)) && g.FocusRequestNextWindow == NULL)
window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items.
if (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent)
return true;
if (is_tab_stop && window->FocusIdxTabCounter == window->FocusIdxTabRequestCurrent)
{ {
g.NavJustTabbedId = id; g.FocusRequestNextWindow = window;
return true; g.FocusRequestNextCounterTab = window->DC.FocusCounterTab + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items.
}
// Handle focus requests
if (g.FocusRequestCurrWindow == window)
{
if (window->DC.FocusCounterAll == g.FocusRequestCurrCounterAll)
return true;
if (is_tab_stop && window->DC.FocusCounterTab == g.FocusRequestCurrCounterTab)
{
g.NavJustTabbedId = id;
return true;
}
// If another item is about to be focused, we clear our own active id
if (g.ActiveId == id)
ClearActiveID();
} }
return false; return false;
@ -2919,8 +2931,8 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop
void ImGui::FocusableItemUnregister(ImGuiWindow* window) void ImGui::FocusableItemUnregister(ImGuiWindow* window)
{ {
window->FocusIdxAllCounter--; window->DC.FocusCounterAll--;
window->FocusIdxTabCounter--; window->DC.FocusCounterTab--;
} }
ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_x, float default_y) ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_x, float default_y)
@ -3066,15 +3078,20 @@ int ImGui::GetFrameCount()
return GImGui->FrameCount; return GImGui->FrameCount;
} }
static ImDrawList* GetOverlayDrawList(ImGuiWindow*) ImDrawList* ImGui::GetBackgroundDrawList()
{ {
// This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'viewport' branches. return &GImGui->BackgroundDrawList;
return &GImGui->OverlayDrawList;
} }
ImDrawList* ImGui::GetOverlayDrawList() static ImDrawList* GetForegroundDrawList(ImGuiWindow*)
{ {
return &GImGui->OverlayDrawList; // This seemingly unnecessary wrapper simplifies compatibility between the 'master' and 'docking' branches.
return &GImGui->ForegroundDrawList;
}
ImDrawList* ImGui::GetForegroundDrawList()
{
return &GImGui->ForegroundDrawList;
} }
ImDrawListSharedData* ImGui::GetDrawListSharedData() ImDrawListSharedData* ImGui::GetDrawListSharedData()
@ -3367,12 +3384,13 @@ void ImGui::NewFrame()
// (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument) // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument)
IM_ASSERT(g.Initialized); IM_ASSERT(g.Initialized);
IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!"); IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!"); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!"); IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!");
IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!"); IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!");
IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting.");
for (int n = 0; n < ImGuiKey_COUNT; n++) for (int n = 0; n < ImGuiKey_COUNT; n++)
IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)");
@ -3420,10 +3438,15 @@ void ImGui::NewFrame()
g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
g.OverlayDrawList.Clear(); g.BackgroundDrawList.Clear();
g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.BackgroundDrawList.PushTextureID(g.IO.Fonts->TexID);
g.OverlayDrawList.PushClipRectFullScreen(); g.BackgroundDrawList.PushClipRectFullScreen();
g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); g.BackgroundDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
g.ForegroundDrawList.Clear();
g.ForegroundDrawList.PushTextureID(g.IO.Fonts->TexID);
g.ForegroundDrawList.PushClipRectFullScreen();
g.ForegroundDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0);
// Mark rendering data as invalid to prevent user who may have a handle on it to use it. // Mark rendering data as invalid to prevent user who may have a handle on it to use it.
g.DrawData.Clear(); g.DrawData.Clear();
@ -3499,13 +3522,34 @@ void ImGui::NewFrame()
UpdateMouseWheel(); UpdateMouseWheel();
// Pressing TAB activate widget focus // Pressing TAB activate widget focus
if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab, false)) 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.FocusRequestNextCounterAll = INT_MAX;
if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
g.NavWindow->FocusIdxTabRequestNext = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1); g.FocusRequestNextCounterTab = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
else else
g.NavWindow->FocusIdxTabRequestNext = g.IO.KeyShift ? -1 : 0; g.FocusRequestNextCounterTab = g.IO.KeyShift ? -1 : 0;
} }
// Turn queued focus request into current one
g.FocusRequestCurrWindow = NULL;
g.FocusRequestCurrCounterAll = g.FocusRequestCurrCounterTab = INT_MAX;
if (g.FocusRequestNextWindow != NULL)
{
ImGuiWindow* window = g.FocusRequestNextWindow;
g.FocusRequestCurrWindow = window;
if (g.FocusRequestNextCounterAll != INT_MAX && window->DC.FocusCounterAll != -1)
g.FocusRequestCurrCounterAll = ImModPositive(g.FocusRequestNextCounterAll, window->DC.FocusCounterAll + 1);
if (g.FocusRequestNextCounterTab != INT_MAX && window->DC.FocusCounterTab != -1)
g.FocusRequestCurrCounterTab = ImModPositive(g.FocusRequestNextCounterTab, window->DC.FocusCounterTab + 1);
g.FocusRequestNextWindow = NULL;
g.FocusRequestNextCounterAll = g.FocusRequestNextCounterTab = INT_MAX;
}
g.NavIdTabCounter = INT_MAX; g.NavIdTabCounter = INT_MAX;
// Mark all windows as not visible // Mark all windows as not visible
@ -3601,11 +3645,10 @@ void ImGui::Shutdown(ImGuiContext* context)
g.OpenPopupStack.clear(); g.OpenPopupStack.clear();
g.BeginPopupStack.clear(); g.BeginPopupStack.clear();
g.DrawDataBuilder.ClearFreeMemory(); g.DrawDataBuilder.ClearFreeMemory();
g.OverlayDrawList.ClearFreeMemory(); g.BackgroundDrawList.ClearFreeMemory();
g.ForegroundDrawList.ClearFreeMemory();
g.PrivateClipboard.clear(); g.PrivateClipboard.clear();
g.InputTextState.TextW.clear(); g.InputTextState.ClearFreeMemory();
g.InputTextState.InitialText.clear();
g.InputTextState.TempBuffer.clear();
for (int i = 0; i < g.SettingsWindows.Size; i++) for (int i = 0; i < g.SettingsWindows.Size; i++)
IM_DELETE(g.SettingsWindows[i].Name); IM_DELETE(g.SettingsWindows[i].Name);
@ -3617,7 +3660,7 @@ void ImGui::Shutdown(ImGuiContext* context)
fclose(g.LogFile); fclose(g.LogFile);
g.LogFile = NULL; g.LogFile = NULL;
} }
g.LogClipboard.clear(); g.LogBuffer.clear();
g.Initialized = false; g.Initialized = false;
} }
@ -3860,6 +3903,9 @@ void ImGui::Render()
// Gather ImDrawList to render (for each active window) // Gather ImDrawList to render (for each active window)
g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0; g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsRenderWindows = 0;
g.DrawDataBuilder.Clear(); g.DrawDataBuilder.Clear();
if (!g.BackgroundDrawList.VtxBuffer.empty())
AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.BackgroundDrawList);
ImGuiWindow* windows_to_render_front_most[2]; ImGuiWindow* windows_to_render_front_most[2];
windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL; windows_to_render_front_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL;
windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL; windows_to_render_front_most[1] = g.NavWindowingTarget ? g.NavWindowingList : NULL;
@ -3876,10 +3922,10 @@ void ImGui::Render()
// Draw software mouse cursor if requested // Draw software mouse cursor if requested
if (g.IO.MouseDrawCursor) if (g.IO.MouseDrawCursor)
RenderMouseCursor(&g.OverlayDrawList, g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor); RenderMouseCursor(&g.ForegroundDrawList, g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor);
if (!g.OverlayDrawList.VtxBuffer.empty()) if (!g.ForegroundDrawList.VtxBuffer.empty())
AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.ForegroundDrawList);
// Setup ImDrawData structure for end-user // Setup ImDrawData structure for end-user
SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData);
@ -4724,7 +4770,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
bool hovered, held; bool hovered, held;
ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
//GetOverlayDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
if (hovered || held) if (hovered || held)
g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
@ -4749,7 +4795,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
bool hovered, held; bool hovered, held;
ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS);
ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
//GetOverlayDrawList(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255)); //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held) if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
{ {
g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
@ -5150,12 +5196,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding;
// Prepare for item focus requests
window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1);
window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == INT_MAX || window->FocusIdxTabCounter == -1) ? INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1);
window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1;
window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX;
// Apply scrolling // Apply scrolling
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true); window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
@ -5265,9 +5305,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Scrollbars // Scrollbars
if (window->ScrollbarX) if (window->ScrollbarX)
Scrollbar(ImGuiLayoutType_Horizontal); Scrollbar(ImGuiAxis_X);
if (window->ScrollbarY) if (window->ScrollbarY)
Scrollbar(ImGuiLayoutType_Vertical); Scrollbar(ImGuiAxis_Y);
// Render resize grips (after their input handling so we don't have a frame of latency) // Render resize grips (after their input handling so we don't have a frame of latency)
if (!(flags & ImGuiWindowFlags_NoResize)) if (!(flags & ImGuiWindowFlags_NoResize))
@ -5327,10 +5367,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext;
window->DC.NavLayerActiveMaskNext = 0x00; window->DC.NavLayerActiveMaskNext = 0x00;
window->DC.MenuBarAppending = false; window->DC.MenuBarAppending = false;
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f;
window->DC.ChildWindows.resize(0); window->DC.ChildWindows.resize(0);
window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.LayoutType = ImGuiLayoutType_Vertical;
window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical;
window->DC.FocusCounterAll = window->DC.FocusCounterTab = -1;
window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_; window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_;
window->DC.ItemWidth = window->ItemWidthDefault; window->DC.ItemWidth = window->ItemWidthDefault;
window->DC.TextWrapPos = -1.0f; // disabled window->DC.TextWrapPos = -1.0f; // disabled
@ -6443,9 +6483,11 @@ void ImGui::ActivateItem(ImGuiID id)
void ImGui::SetKeyboardFocusHere(int offset) void ImGui::SetKeyboardFocusHere(int offset)
{ {
IM_ASSERT(offset >= -1); // -1 is allowed but not below IM_ASSERT(offset >= -1); // -1 is allowed but not below
ImGuiWindow* window = GetCurrentWindow(); ImGuiContext& g = *GImGui;
window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; ImGuiWindow* window = g.CurrentWindow;
window->FocusIdxTabRequestNext = INT_MAX; g.FocusRequestNextWindow = window;
g.FocusRequestNextCounterAll = window->DC.FocusCounterAll + 1 + offset;
g.FocusRequestNextCounterTab = INT_MAX;
} }
void ImGui::SetItemDefaultFocus() void ImGui::SetItemDefaultFocus()
@ -6528,13 +6570,13 @@ ImGuiID ImGui::GetID(const void* ptr_id)
bool ImGui::IsRectVisible(const ImVec2& size) bool ImGui::IsRectVisible(const ImVec2& size)
{ {
ImGuiWindow* window = GImGui->CurrentWindow;; ImGuiWindow* window = GImGui->CurrentWindow;
return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
} }
bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
{ {
ImGuiWindow* window = GImGui->CurrentWindow;; ImGuiWindow* window = GImGui->CurrentWindow;
return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
} }
@ -6552,7 +6594,6 @@ void ImGui::BeginGroup()
group_data.BackupGroupOffset = window->DC.GroupOffset; group_data.BackupGroupOffset = window->DC.GroupOffset;
group_data.BackupCurrentLineSize = window->DC.CurrentLineSize; group_data.BackupCurrentLineSize = window->DC.CurrentLineSize;
group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset;
group_data.BackupLogLinePosY = window->DC.LogLinePosY;
group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive; group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive; group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
group_data.AdvanceCursor = true; group_data.AdvanceCursor = true;
@ -6561,14 +6602,15 @@ void ImGui::BeginGroup()
window->DC.Indent = window->DC.GroupOffset; window->DC.Indent = window->DC.GroupOffset;
window->DC.CursorMaxPos = window->DC.CursorPos; window->DC.CursorMaxPos = window->DC.CursorPos;
window->DC.CurrentLineSize = ImVec2(0.0f, 0.0f); window->DC.CurrentLineSize = ImVec2(0.0f, 0.0f);
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return if (g.LogEnabled)
g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
} }
void ImGui::EndGroup() void ImGui::EndGroup()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls
ImGuiGroupData& group_data = window->DC.GroupStack.back(); ImGuiGroupData& group_data = window->DC.GroupStack.back();
@ -6581,7 +6623,8 @@ void ImGui::EndGroup()
window->DC.GroupOffset = group_data.BackupGroupOffset; window->DC.GroupOffset = group_data.BackupGroupOffset;
window->DC.CurrentLineSize = group_data.BackupCurrentLineSize; window->DC.CurrentLineSize = group_data.BackupCurrentLineSize;
window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset;
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; // To enforce Log carriage return if (g.LogEnabled)
g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
if (group_data.AdvanceCursor) if (group_data.AdvanceCursor)
{ {
@ -7022,8 +7065,8 @@ ImRect ImGui::GetWindowAllowedExtentRect(ImGuiWindow*)
ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy) ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy)
{ {
ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size);
//GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
//GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); //GetForegroundDrawList()->AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
// Combo Box policy (we want a connecting edge) // Combo Box policy (we want a connecting edge)
if (policy == ImGuiPopupPositionPolicy_ComboBox) if (policy == ImGuiPopupPositionPolicy_ComboBox)
@ -7115,11 +7158,6 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
return window->Pos; return window->Pos;
} }
//-----------------------------------------------------------------------------
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
//-----------------------------------------------------------------------------
// (this section is filled in the 'viewport' and 'docking' branches)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
@ -7222,7 +7260,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max)) if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max))
{ {
ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
ImDrawList* draw_list = ImGui::GetOverlayDrawList(window); ImDrawList* draw_list = ImGui::GetForegroundDrawList(window);
draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100)); draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
draw_list->AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150)); draw_list->AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150));
@ -7234,7 +7272,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand)
if (quadrant == g.NavMoveDir) if (quadrant == g.NavMoveDir)
{ {
ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
ImDrawList* draw_list = ImGui::GetOverlayDrawList(window); ImDrawList* draw_list = ImGui::GetForegroundDrawList(window);
draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf);
} }
@ -7315,7 +7353,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
// Process Move Request (scoring for navigation) // Process Move Request (scoring for navigation)
// FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRectScreen + scoring from a rect wrapped according to current wrapping policy) // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRectScreen + scoring from a rect wrapped according to current wrapping policy)
if ((g.NavId != id || (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & ImGuiItemFlags_NoNav)) if ((g.NavId != id || (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled|ImGuiItemFlags_NoNav)))
{ {
ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
#if IMGUI_DEBUG_NAV_SCORING #if IMGUI_DEBUG_NAV_SCORING
@ -7353,7 +7391,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
g.NavLayer = window->DC.NavLayerCurrent; g.NavLayer = window->DC.NavLayerCurrent;
g.NavIdIsAlive = true; g.NavIdIsAlive = true;
g.NavIdTabCounter = window->FocusIdxTabCounter; g.NavIdTabCounter = window->DC.FocusCounterTab;
window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position) window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position)
} }
} }
@ -7540,7 +7578,7 @@ ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInput
static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect) static void NavScrollToBringItemIntoView(ImGuiWindow* window, const ImRect& item_rect)
{ {
ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1)); ImRect window_rect(window->InnerMainRect.Min - ImVec2(1, 1), window->InnerMainRect.Max + ImVec2(1, 1));
//GetOverlayDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG] //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG]
if (window_rect.Contains(item_rect)) if (window_rect.Contains(item_rect))
return; return;
@ -7593,9 +7631,13 @@ static void ImGui::NavUpdate()
NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_); NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_);
NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ ); NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ );
NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ ); NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ );
if (g.IO.KeyCtrl) g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; NAV_MAP_KEY(ImGuiKey_Tab, ImGuiNavInput_KeyTab_ );
if (g.IO.KeyShift) g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; if (g.IO.KeyCtrl)
if (g.IO.KeyAlt) g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f; g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
if (g.IO.KeyShift)
g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
if (g.IO.KeyAlt && !g.IO.KeyCtrl) // AltGR is Alt+Ctrl, also even on keyboards without AltGR we don't want Alt+Ctrl to open menu.
g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f;
#undef NAV_MAP_KEY #undef NAV_MAP_KEY
} }
memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration)); memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration));
@ -7827,11 +7869,15 @@ static void ImGui::NavUpdate()
g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
//g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
g.NavScoringCount = 0; g.NavScoringCount = 0;
#if IMGUI_DEBUG_NAV_RECTS #if IMGUI_DEBUG_NAV_RECTS
if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) GetOverlayDrawList(g.NavWindow)->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] if (g.NavWindow)
if (g.NavWindow) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); GetOverlayDrawList(g.NavWindow)->AddCircleFilled(p, 3.0f, col); GetOverlayDrawList(g.NavWindow)->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } {
ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG]
if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); }
}
#endif #endif
} }
@ -7970,7 +8016,9 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
} }
// Window management mode (hold to: change focus/move/resize, tap to: toggle menu layer) // Windowing management mode
// Keyboard: CTRL+Tab (change focus/move/resize), Alt (toggle menu layer)
// Gamepad: Hold Menu/Square (change focus/move/resize), Tap Menu/Square (toggle menu layer)
static void ImGui::NavUpdateWindowing() static void ImGui::NavUpdateWindowing()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -8073,6 +8121,7 @@ static void ImGui::NavUpdateWindowing()
g.NavDisableMouseHover = true; g.NavDisableMouseHover = true;
apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window);
ClosePopupsOverWindow(apply_focus_window); ClosePopupsOverWindow(apply_focus_window);
ClearActiveID();
FocusWindow(apply_focus_window); FocusWindow(apply_focus_window);
if (apply_focus_window->NavLastIds[0] == 0) if (apply_focus_window->NavLastIds[0] == 0)
NavInitWindow(apply_focus_window, false); NavInitWindow(apply_focus_window, false);
@ -8156,10 +8205,18 @@ void ImGui::NextColumn()
return; return;
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
if (columns->Count == 1)
{
window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
IM_ASSERT(columns->Current == 0);
return;
}
PopItemWidth(); PopItemWidth();
PopClipRect(); PopClipRect();
ImGuiColumnsSet* columns = window->DC.ColumnsSet;
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
if (++columns->Current < columns->Count) if (++columns->Current < columns->Count)
{ {
@ -8169,6 +8226,7 @@ void ImGui::NextColumn()
} }
else else
{ {
// New line
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DrawList->ChannelsSetCurrent(0); window->DrawList->ChannelsSetCurrent(0);
columns->Current = 0; columns->Current = 0;
@ -8323,7 +8381,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
IM_ASSERT(columns_count > 1); IM_ASSERT(columns_count >= 1);
IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported
// Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget.
@ -8377,8 +8435,11 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
column->ClipRect.ClipWith(window->ClipRect); column->ClipRect.ClipWith(window->ClipRect);
} }
window->DrawList->ChannelsSplit(columns->Count); if (columns->Count > 1)
PushColumnClipRect(); {
window->DrawList->ChannelsSplit(columns->Count);
PushColumnClipRect();
}
PushItemWidth(GetColumnWidth() * 0.65f); PushItemWidth(GetColumnWidth() * 0.65f);
} }
@ -8390,8 +8451,11 @@ void ImGui::EndColumns()
IM_ASSERT(columns != NULL); IM_ASSERT(columns != NULL);
PopItemWidth(); PopItemWidth();
PopClipRect(); if (columns->Count > 1)
window->DrawList->ChannelsMerge(); {
PopClipRect();
window->DrawList->ChannelsMerge();
}
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
window->DC.CursorPos.y = columns->LineMaxY; window->DC.CursorPos.y = columns->LineMaxY;
@ -8760,11 +8824,6 @@ void ImGui::EndDragDropTarget()
g.DragDropWithinSourceOrTarget = false; g.DragDropWithinSourceOrTarget = false;
} }
//-----------------------------------------------------------------------------
// [SECTION] DOCKING
//-----------------------------------------------------------------------------
// (this section is filled in the 'docking' branch)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] LOGGING/CAPTURING // [SECTION] LOGGING/CAPTURING
@ -8785,7 +8844,7 @@ void ImGui::LogText(const char* fmt, ...)
if (g.LogFile) if (g.LogFile)
vfprintf(g.LogFile, fmt, args); vfprintf(g.LogFile, fmt, args);
else else
g.LogClipboard.appendfv(fmt, args); g.LogBuffer.appendfv(fmt, args);
va_end(args); va_end(args);
} }
@ -8799,17 +8858,20 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
if (!text_end) if (!text_end)
text_end = FindRenderedTextEnd(text, text_end); text_end = FindRenderedTextEnd(text, text_end);
const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1);
if (ref_pos) if (ref_pos)
window->DC.LogLinePosY = ref_pos->y; g.LogLinePosY = ref_pos->y;
if (log_new_line)
g.LogLineFirstItem = true;
const char* text_remaining = text; const char* text_remaining = text;
if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth
g.LogStartDepth = window->DC.TreeDepth; g.LogDepthRef = window->DC.TreeDepth;
const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
for (;;) for (;;)
{ {
// Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry.
// We don't add a trailing \n to allow a subsequent item on the same line to be captured.
const char* line_start = text_remaining; const char* line_start = text_remaining;
const char* line_end = ImStreolRange(line_start, text_end); const char* line_end = ImStreolRange(line_start, text_end);
const bool is_first_line = (line_start == text); const bool is_first_line = (line_start == text);
@ -8818,9 +8880,18 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
{ {
const int char_count = (int)(line_end - line_start); const int char_count = (int)(line_end - line_start);
if (log_new_line || !is_first_line) if (log_new_line || !is_first_line)
LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, line_start); LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, line_start);
else if (g.LogLineFirstItem)
LogText("%*s%.*s", tree_depth * 4, "", char_count, line_start);
else else
LogText(" %.*s", char_count, line_start); LogText(" %.*s", char_count, line_start);
g.LogLineFirstItem = false;
}
else if (log_new_line)
{
// An empty "" string at a different Y position should output a carriage return.
LogText(IM_NEWLINE);
break;
} }
if (is_last_line) if (is_last_line)
@ -8829,64 +8900,71 @@ void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char*
} }
} }
// Start logging ImGui output to TTY // Start logging/capturing text output
void ImGui::LogToTTY(int max_depth) void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.LogEnabled)
return;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(g.LogEnabled == false);
IM_ASSERT(g.LogFile == NULL); IM_ASSERT(g.LogFile == NULL);
g.LogFile = stdout; IM_ASSERT(g.LogBuffer.empty());
g.LogEnabled = true; g.LogEnabled = true;
g.LogStartDepth = window->DC.TreeDepth; g.LogType = type;
if (max_depth >= 0) g.LogDepthRef = window->DC.TreeDepth;
g.LogAutoExpandMaxDepth = max_depth; g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
g.LogLinePosY = FLT_MAX;
g.LogLineFirstItem = true;
} }
// Start logging ImGui output to given file void ImGui::LogToTTY(int auto_open_depth)
void ImGui::LogToFile(int max_depth, const char* filename)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.LogEnabled) if (g.LogEnabled)
return; return;
ImGuiWindow* window = g.CurrentWindow; LogBegin(ImGuiLogType_TTY, auto_open_depth);
g.LogFile = stdout;
}
// Start logging/capturing text output to given file
void ImGui::LogToFile(int auto_open_depth, const char* filename)
{
ImGuiContext& g = *GImGui;
if (g.LogEnabled)
return;
// FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still
// be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
// By opening the file in binary mode "ab" we have consistent output everywhere.
if (!filename) if (!filename)
{
filename = g.IO.LogFilename; filename = g.IO.LogFilename;
if (!filename) if (!filename || !filename[0])
return; return;
} FILE* f = ImFileOpen(filename, "ab");
if (f == NULL)
IM_ASSERT(g.LogFile == NULL);
g.LogFile = ImFileOpen(filename, "ab");
if (!g.LogFile)
{ {
IM_ASSERT(0); IM_ASSERT(0);
return; return;
} }
g.LogEnabled = true;
g.LogStartDepth = window->DC.TreeDepth; LogBegin(ImGuiLogType_File, auto_open_depth);
if (max_depth >= 0) g.LogFile = f;
g.LogAutoExpandMaxDepth = max_depth;
} }
// Start logging ImGui output to clipboard // Start logging/capturing text output to clipboard
void ImGui::LogToClipboard(int max_depth) void ImGui::LogToClipboard(int auto_open_depth)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
if (g.LogEnabled) if (g.LogEnabled)
return; return;
ImGuiWindow* window = g.CurrentWindow; LogBegin(ImGuiLogType_Clipboard, auto_open_depth);
}
IM_ASSERT(g.LogFile == NULL); void ImGui::LogToBuffer(int auto_open_depth)
g.LogFile = NULL; {
g.LogEnabled = true; ImGuiContext& g = *GImGui;
g.LogStartDepth = window->DC.TreeDepth; if (g.LogEnabled)
if (max_depth >= 0) return;
g.LogAutoExpandMaxDepth = max_depth; LogBegin(ImGuiLogType_Buffer, auto_open_depth);
} }
void ImGui::LogFinish() void ImGui::LogFinish()
@ -8896,23 +8974,33 @@ void ImGui::LogFinish()
return; return;
LogText(IM_NEWLINE); LogText(IM_NEWLINE);
if (g.LogFile != NULL) switch (g.LogType)
{ {
if (g.LogFile == stdout) case ImGuiLogType_TTY:
fflush(g.LogFile); fflush(g.LogFile);
else break;
fclose(g.LogFile); case ImGuiLogType_File:
g.LogFile = NULL; fclose(g.LogFile);
} break;
if (g.LogClipboard.size() > 1) case ImGuiLogType_Buffer:
{ break;
SetClipboardText(g.LogClipboard.begin()); case ImGuiLogType_Clipboard:
g.LogClipboard.clear(); if (!g.LogBuffer.empty())
SetClipboardText(g.LogBuffer.begin());
break;
case ImGuiLogType_None:
IM_ASSERT(0);
break;
} }
g.LogEnabled = false; g.LogEnabled = false;
g.LogType = ImGuiLogType_None;
g.LogFile = NULL;
g.LogBuffer.clear();
} }
// Helper to display logging buttons // Helper to display logging buttons
// FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!)
void ImGui::LogButtons() void ImGui::LogButtons()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -8923,18 +9011,18 @@ void ImGui::LogButtons()
const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
PushItemWidth(80.0f); PushItemWidth(80.0f);
PushAllowKeyboardFocus(false); PushAllowKeyboardFocus(false);
SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL);
PopAllowKeyboardFocus(); PopAllowKeyboardFocus();
PopItemWidth(); PopItemWidth();
PopID(); PopID();
// Start logging at the end of the function so that the buttons don't appear in the log // Start logging at the end of the function so that the buttons don't appear in the log
if (log_to_tty) if (log_to_tty)
LogToTTY(g.LogAutoExpandMaxDepth); LogToTTY();
if (log_to_file) if (log_to_file)
LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); LogToFile();
if (log_to_clipboard) if (log_to_clipboard)
LogToClipboard(g.LogAutoExpandMaxDepth); LogToClipboard();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9156,6 +9244,21 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
} }
} }
//-----------------------------------------------------------------------------
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
//-----------------------------------------------------------------------------
// (this section is filled in the 'docking' branch)
//-----------------------------------------------------------------------------
// [SECTION] DOCKING
//-----------------------------------------------------------------------------
// (this section is filled in the 'docking' branch)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] PLATFORM DEPENDENT HELPERS // [SECTION] PLATFORM DEPENDENT HELPERS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9309,9 +9412,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return; return;
} }
ImDrawList* overlay_draw_list = GetOverlayDrawList(window); // Render additional visuals into the top-most draw list ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list
if (window && IsItemHovered()) if (window && IsItemHovered())
overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255));
if (!node_open) if (!node_open)
return; return;
@ -9333,8 +9436,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImRect vtxs_rect; ImRect vtxs_rect;
for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255)); clip_rect.Floor(); fg_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255));
vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255)); vtxs_rect.Floor(); fg_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255));
} }
if (!pcmd_node_open) if (!pcmd_node_open)
continue; continue;
@ -9358,10 +9461,10 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui::Selectable(buf, false); ImGui::Selectable(buf, false);
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
{ {
ImDrawListFlags backup_flags = overlay_draw_list->Flags; ImDrawListFlags backup_flags = fg_draw_list->Flags;
overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles.
overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); fg_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f);
overlay_draw_list->Flags = backup_flags; fg_draw_list->Flags = backup_flags;
} }
} }
ImGui::TreePop(); ImGui::TreePop();
@ -9498,9 +9601,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
char buf[32]; char buf[32];
ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext); ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext);
float font_size = ImGui::GetFontSize() * 2; float font_size = ImGui::GetFontSize() * 2;
ImDrawList* overlay_draw_list = GetOverlayDrawList(window); ImDrawList* fg_draw_list = GetForegroundDrawList(window);
overlay_draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255)); fg_draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
overlay_draw_list->AddText(NULL, font_size, window->Pos, IM_COL32(255, 255, 255, 255), buf); fg_draw_list->AddText(NULL, font_size, window->Pos, IM_COL32(255, 255, 255, 255), buf);
} }
} }
ImGui::End(); ImGui::End();

View File

@ -1,9 +1,9 @@
// dear imgui, v1.68 // dear imgui, v1.69
// (headers) // (headers)
// See imgui.cpp file for documentation. // See imgui.cpp file for documentation.
// Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code.
// Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. // Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase.
// Get latest version at https://github.com/ocornut/imgui // Get latest version at https://github.com/ocornut/imgui
/* /*
@ -26,7 +26,7 @@ Index of this file:
#pragma once #pragma once
// Configuration file (edit imconfig.h or define IMGUI_USER_CONFIG to your own filename) // Configuration file with compile-time options (edit imconfig.h or define IMGUI_USER_CONFIG to your own filename)
#ifdef IMGUI_USER_CONFIG #ifdef IMGUI_USER_CONFIG
#include IMGUI_USER_CONFIG #include IMGUI_USER_CONFIG
#endif #endif
@ -44,9 +44,9 @@ Index of this file:
#include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp #include <string.h> // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp
// Version // Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY00 then bounced up to XYY01 when release tagging happens) // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.68" #define IMGUI_VERSION "1.69"
#define IMGUI_VERSION_NUM 16801 #define IMGUI_VERSION_NUM 16900
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert))
// Define attributes of all API symbols declarations (e.g. for DLL under Windows) // Define attributes of all API symbols declarations (e.g. for DLL under Windows)
@ -150,6 +150,10 @@ typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data);
typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data);
// Scalar data types // Scalar data types
typedef signed char ImS8; // 8-bit signed integer == char
typedef unsigned char ImU8; // 8-bit unsigned integer
typedef signed short ImS16; // 16-bit signed integer
typedef unsigned short ImU16; // 16-bit unsigned integer
typedef signed int ImS32; // 32-bit signed integer == int typedef signed int ImS32; // 32-bit signed integer == int
typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors)
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
@ -215,12 +219,12 @@ namespace ImGui
// Demo, Debug, Information // Demo, Debug, Information
IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create demo/test 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 ShowDemoWindow(bool* p_open = NULL); // create demo/test 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 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 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 metrics/debug 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 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 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. IMGUI_API void ShowFontSelector(const char* label); // add font selector block (not a window), essentially a combo listing the loaded fonts.
IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls).
IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.23" IMGUI_API const char* GetVersion(); // get the compiled version string e.g. "1.23" (essentially the compiled value for IMGUI_VERSION)
// Styles // Styles
IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default) IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // new, recommended style (default)
@ -263,7 +267,7 @@ namespace ImGui
IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y) IMGUI_API float GetWindowHeight(); // get current window height (shortcut for GetWindowSize().y)
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()
IMGUI_API float GetContentRegionAvailWidth(); // IMGUI_API float GetContentRegionAvailWidth(); // == GetContentRegionAvail().x
IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates
IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates
IMGUI_API float GetWindowContentRegionWidth(); // IMGUI_API float GetWindowContentRegionWidth(); //
@ -293,7 +297,7 @@ namespace ImGui
IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()]
IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()]
IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. IMGUI_API void SetScrollHereY(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead.
IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position visible. Generally GetCursorStartPos() + offset to compute a valid position.
// Parameters stacks (shared) // Parameters stacks (shared)
IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font
@ -385,7 +389,7 @@ namespace ImGui
// - Most widgets return true when the value has been changed or when pressed/selected // - Most widgets return true when the value has been changed or when pressed/selected
IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button
IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text
IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, frequently useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.)
IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); // square button with an arrow shape
IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0));
IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding
@ -446,6 +450,7 @@ namespace ImGui
// - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc. // - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc.
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0); IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags flags = 0);
@ -459,7 +464,8 @@ namespace ImGui
IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* step = NULL, const void* step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0); IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* step = NULL, const void* step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags flags = 0);
// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.) // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.)
// - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x // - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible.
// - You can pass the address of a first float element out of a contiguous structure, e.g. &myvector.x
IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);
IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0);
IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0);
@ -470,7 +476,7 @@ namespace ImGui
// Widgets: Trees // Widgets: Trees
// - TreeNode functions return true when the node is open, in which case you need to also call TreePop() when you are finished displaying the tree node contents. // - TreeNode functions return true when the node is open, in which case you need to also call TreePop() when you are finished displaying the tree node contents.
IMGUI_API bool TreeNode(const char* label); IMGUI_API bool TreeNode(const char* label);
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to completely decorelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to easily decorelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // " IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // "
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2); IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2);
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2); IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2);
@ -528,7 +534,7 @@ namespace ImGui
// Tooltips // Tooltips
IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items). IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of items).
IMGUI_API void EndTooltip(); IMGUI_API void EndTooltip();
IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip, typically use with ImGui::IsItemHovered(). override any previous call to SetTooltip().
IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1);
// Popups, Modals // Popups, Modals
@ -572,9 +578,9 @@ namespace ImGui
// Logging/Capture // Logging/Capture
// - All text output from the interface can be captured into tty/file/clipboard. By default, tree nodes are automatically opened during logging. // - All text output from the interface can be captured into tty/file/clipboard. By default, tree nodes are automatically opened during logging.
IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty (stdout) IMGUI_API void LogToTTY(int auto_open_depth = -1); // start logging to tty (stdout)
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file IMGUI_API void LogToFile(int auto_open_depth = -1, const char* filename = NULL); // start logging to file
IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard IMGUI_API void LogToClipboard(int auto_open_depth = -1); // start logging to OS clipboard
IMGUI_API void LogFinish(); // stop logging (close file, etc.) IMGUI_API void LogFinish(); // stop logging (close file, etc.)
IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard
IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed)
@ -582,7 +588,7 @@ namespace ImGui
// Drag and Drop // Drag and Drop
// [BETA API] API may evolve! // [BETA API] API may evolve!
IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource()
IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui.
IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true!
IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive a payload. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive a payload. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget()
IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released.
@ -610,9 +616,9 @@ namespace ImGui
IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive). IMGUI_API bool IsItemActivated(); // was the last item just made active (item was previously inactive).
IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing. IMGUI_API bool IsItemDeactivated(); // was the last item just made inactive (item was previously active). Useful for Undo/Redo patterns with widgets that requires continuous editing.
IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item). IMGUI_API bool IsItemDeactivatedAfterEdit(); // was the last item just made inactive and made a value change when it was active? (e.g. Slider/Drag moved). Useful for Undo/Redo patterns with widgets that requires continuous editing. Note that you may get false positives (some widgets such as Combo()/ListBox()/Selectable() will return true even when clicking an already selected item).
IMGUI_API bool IsAnyItemHovered(); IMGUI_API bool IsAnyItemHovered(); // is any item hovered?
IMGUI_API bool IsAnyItemActive(); IMGUI_API bool IsAnyItemActive(); // is any item active?
IMGUI_API bool IsAnyItemFocused(); IMGUI_API bool IsAnyItemFocused(); // is any item focused?
IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectMin(); // get upper-left bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space) IMGUI_API ImVec2 GetItemRectMax(); // get lower-right bounding rectangle of the last item (screen space)
IMGUI_API ImVec2 GetItemRectSize(); // get size of last item IMGUI_API ImVec2 GetItemRectSize(); // get size of last item
@ -623,9 +629,10 @@ namespace ImGui
IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame. IMGUI_API double GetTime(); // get global imgui time. incremented by io.DeltaTime every frame.
IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame. IMGUI_API int GetFrameCount(); // get global imgui frame count. incremented by 1 every frame.
IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text IMGUI_API ImDrawList* GetBackgroundDrawList(); // this draw list will be the first rendering one. Useful to quickly draw shapes/text behind dear imgui contents.
IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances IMGUI_API ImDrawList* GetForegroundDrawList(); // this draw list will be the last rendered one. Useful to quickly draw shapes/text over dear imgui contents.
IMGUI_API const char* GetStyleColorName(ImGuiCol idx); IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); // you may use this when creating your own ImDrawList instances.
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 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 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 ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
@ -652,7 +659,7 @@ namespace ImGui
IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down)
IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold
IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block. IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings, but disregarding of other consideration of focus/window ordering/popup-block.
IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // by convention we use (-FLT_MAX,-FLT_MAX) to denote that there is no mouse
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse position at the time of opening popup we have BeginPopup() into IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse position at the time of opening popup we have BeginPopup() into
IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position. This is locked and return 0.0f until the mouse moves past a distance threshold at least once. If lock_threshold < -1.0f uses io.MouseDraggingThreshold IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position. This is locked and return 0.0f until the mouse moves past a distance threshold at least once. If lock_threshold < -1.0f uses io.MouseDraggingThreshold
@ -671,12 +678,12 @@ namespace ImGui
// - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually. // - Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually.
IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename). IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename).
IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source. IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source.
IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext).
IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings.
// Memory Utilities // Memory Allocators
// - All those functions are not reliant on the current context. // - All those functions are not reliant on the current context.
// - If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again. // - If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again because we use global storage for those.
IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL); IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL);
IMGUI_API void* MemAlloc(size_t size); IMGUI_API void* MemAlloc(size_t size);
IMGUI_API void MemFree(void* ptr); IMGUI_API void MemFree(void* ptr);
@ -694,7 +701,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar
ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip
ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window
ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically) ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programmatically)
ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set.
ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it
ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame
@ -704,7 +711,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar
ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section.
ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state
ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programmatically giving it focus)
ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)
@ -737,7 +744,7 @@ enum ImGuiInputTextFlags_
ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z
ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs
ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function.
ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling) ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling)
ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling) ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling)
ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer. ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer.
@ -826,7 +833,7 @@ enum ImGuiTabItemFlags_
{ {
ImGuiTabItemFlags_None = 0, ImGuiTabItemFlags_None = 0,
ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker. ImGuiTabItemFlags_UnsavedDocument = 1 << 0, // Append '*' to title without affecting the ID, as a convenience to avoid using the ### operator. Also: tab is selected on closure and closure is deferred by one frame to allow code to undo it without flicker.
ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programatically make the tab selected when calling BeginTabItem() ImGuiTabItemFlags_SetSelected = 1 << 1, // Trigger flag to programmatically make the tab selected when calling BeginTabItem()
ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false. ImGuiTabItemFlags_NoCloseWithMiddleMouseButton = 1 << 2, // Disable behavior of closing tabs (that are submitted with p_open != NULL) with middle mouse button. You can still repro this behavior on user's side with if (IsItemHovered() && IsMouseClicked(2)) *p_open = false.
ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem() ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
}; };
@ -884,10 +891,14 @@ enum ImGuiDragDropFlags_
// A primary data type // A primary data type
enum ImGuiDataType_ enum ImGuiDataType_
{ {
ImGuiDataType_S8, // char
ImGuiDataType_U8, // unsigned char
ImGuiDataType_S16, // short
ImGuiDataType_U16, // unsigned short
ImGuiDataType_S32, // int ImGuiDataType_S32, // int
ImGuiDataType_U32, // unsigned int ImGuiDataType_U32, // unsigned int
ImGuiDataType_S64, // long long, __int64 ImGuiDataType_S64, // long long / __int64
ImGuiDataType_U64, // unsigned long long, unsigned __int64 ImGuiDataType_U64, // unsigned long long / unsigned __int64
ImGuiDataType_Float, // float ImGuiDataType_Float, // float
ImGuiDataType_Double, // double ImGuiDataType_Double, // double
ImGuiDataType_COUNT ImGuiDataType_COUNT
@ -958,6 +969,7 @@ enum ImGuiNavInput_
// [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them.
// Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[]. // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[].
ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt
ImGuiNavInput_KeyTab_, // tab // = Tab key
ImGuiNavInput_KeyLeft_, // move left // = Arrow keys ImGuiNavInput_KeyLeft_, // move left // = Arrow keys
ImGuiNavInput_KeyRight_, // move right ImGuiNavInput_KeyRight_, // move right
ImGuiNavInput_KeyUp_, // move up ImGuiNavInput_KeyUp_, // move up
@ -1059,7 +1071,7 @@ enum ImGuiCol_
// NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. // NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type.
enum ImGuiStyleVar_ enum ImGuiStyleVar_
{ {
// Enum name ......................// Member in ImGuiStyle structure (see ImGuiStyle for descriptions) // Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions)
ImGuiStyleVar_Alpha, // float Alpha ImGuiStyleVar_Alpha, // float Alpha
ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding
ImGuiStyleVar_WindowRounding, // float WindowRounding ImGuiStyleVar_WindowRounding, // float WindowRounding
@ -1095,7 +1107,7 @@ enum ImGuiStyleVar_
enum ImGuiColorEditFlags_ enum ImGuiColorEditFlags_
{ {
ImGuiColorEditFlags_None = 0, ImGuiColorEditFlags_None = 0,
ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the input pointer). ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (will only read 3 components from the input pointer).
ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square. ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square.
ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview.
ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs)
@ -1105,24 +1117,35 @@ enum ImGuiColorEditFlags_
ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead.
ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source. ImGuiColorEditFlags_NoDragDrop = 1 << 9, // // ColorEdit: disable drag and drop target. ColorButton: disable drag and drop source.
// User Options (right-click on widget to change some of them). You can set application defaults using SetColorEditOptions(). The idea is that you probably don't want to override them in most of your calls, let the user choose and/or call SetColorEditOptions() during startup. // User Options (right-click on widget to change some of them).
ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. ImGuiColorEditFlags_AlphaBar = 1 << 16, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker.
ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. ImGuiColorEditFlags_AlphaPreview = 1 << 17, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque.
ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 18, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque.
ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well). ImGuiColorEditFlags_HDR = 1 << 19, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well).
ImGuiColorEditFlags_RGB = 1 << 20, // [Inputs] // ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using RGB/HSV/HEX. ImGuiColorEditFlags_DisplayRGB = 1 << 20, // [Display] // ColorEdit: override _display_ type among RGB/HSV/Hex. ColorPicker: select any combination using one or more of RGB/HSV/Hex.
ImGuiColorEditFlags_HSV = 1 << 21, // [Inputs] // " ImGuiColorEditFlags_DisplayHSV = 1 << 21, // [Display] // "
ImGuiColorEditFlags_HEX = 1 << 22, // [Inputs] // " ImGuiColorEditFlags_DisplayHex = 1 << 22, // [Display] // "
ImGuiColorEditFlags_Uint8 = 1 << 23, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255. ImGuiColorEditFlags_Uint8 = 1 << 23, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255.
ImGuiColorEditFlags_Float = 1 << 24, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. ImGuiColorEditFlags_Float = 1 << 24, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers.
ImGuiColorEditFlags_PickerHueBar = 1 << 25, // [PickerMode] // ColorPicker: bar for Hue, rectangle for Sat/Value. ImGuiColorEditFlags_PickerHueBar = 1 << 25, // [Picker] // ColorPicker: bar for Hue, rectangle for Sat/Value.
ImGuiColorEditFlags_PickerHueWheel = 1 << 26, // [PickerMode] // ColorPicker: wheel for Hue, triangle for Sat/Value. ImGuiColorEditFlags_PickerHueWheel = 1 << 26, // [Picker] // ColorPicker: wheel for Hue, triangle for Sat/Value.
ImGuiColorEditFlags_InputRGB = 1 << 27, // [Input] // ColorEdit, ColorPicker: input and output data in RGB format.
ImGuiColorEditFlags_InputHSV = 1 << 28, // [Input] // ColorEdit, ColorPicker: input and output data in HSV format.
// Defaults Options. You can set application defaults using SetColorEditOptions(). The intent is that you probably don't want to
// override them in most of your calls. Let the user choose via the option menu and/or call SetColorEditOptions() once during startup.
ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_DisplayRGB|ImGuiColorEditFlags_InputRGB|ImGuiColorEditFlags_PickerHueBar,
// [Internal] Masks // [Internal] Masks
ImGuiColorEditFlags__InputsMask = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, ImGuiColorEditFlags__DisplayMask = ImGuiColorEditFlags_DisplayRGB|ImGuiColorEditFlags_DisplayHSV|ImGuiColorEditFlags_DisplayHex,
ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_Float, ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_Float,
ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar, ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar,
ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_PickerHueBar // Change application default using SetColorEditOptions() ImGuiColorEditFlags__InputMask = ImGuiColorEditFlags_InputRGB|ImGuiColorEditFlags_InputHSV
// Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex
#endif
}; };
// Enumeration for GetMouseCursor() // Enumeration for GetMouseCursor()
@ -1308,7 +1331,7 @@ struct ImGuiIO
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by back-end implementations. bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by back-end implementations.
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63) bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63)
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63) bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be the a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected. bool ConfigWindowsMoveFromTitleBarOnly; // = false // [BETA] Set to true to only allow moving windows when clicked+dragged from the title bar. Windows without a title bar are not affected.
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1485,6 +1508,8 @@ struct ImGuiPayload
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui namespace ImGui
{ {
// OBSOLETED in 1.69 (from Mar 2019)
static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); }
// OBSOLETED in 1.66 (from Sep 2018) // OBSOLETED in 1.66 (from Sep 2018)
static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); } static inline void SetScrollHere(float center_ratio=0.5f){ SetScrollHereY(center_ratio); }
// OBSOLETED in 1.63 (between Aug 2018 and Sept 2018) // OBSOLETED in 1.63 (between Aug 2018 and Sept 2018)
@ -1528,7 +1553,7 @@ typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData;
// Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions. // Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
struct ImNewDummy {}; struct ImNewDummy {};
inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; } inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; }
inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symetrical new() inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symmetrical new()
#define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR) #define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR)
#define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE #define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE
template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } } template<typename T> void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } }
@ -1694,7 +1719,7 @@ struct ImGuiListClipper
#define IM_COL32_BLACK IM_COL32(0,0,0,255) // Opaque black #define IM_COL32_BLACK IM_COL32(0,0,0,255) // Opaque black
#define IM_COL32_BLACK_TRANS IM_COL32(0,0,0,0) // Transparent black = 0x00000000 #define IM_COL32_BLACK_TRANS IM_COL32(0,0,0,0) // Transparent black = 0x00000000
// Helper: ImColor() implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float) // Helper: ImColor() implicitly converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
// Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API. // Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. MAY OBSOLETE. // **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class. MAY OBSOLETE.
// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. Explicitly cast to ImU32 or ImVec4 if needed. // **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats. Explicitly cast to ImU32 or ImVec4 if needed.
@ -1842,8 +1867,8 @@ struct ImDrawList
IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF);
IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF);
IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All);
IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness);
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order.
IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0);
// Stateful path API, add points then finish with PathFillConvex() or PathStroke() // Stateful path API, add points then finish with PathFillConvex() or PathStroke()
@ -2022,6 +2047,7 @@ struct ImFontAtlas
IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese IMGUI_API const ImWchar* GetGlyphRangesChineseSimplifiedCommon();// Default + Half-Width + Japanese Hiragana/Katakana + set of 2500 CJK Unified Ideographs for common simplified Chinese
IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters
IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters
IMGUI_API const ImWchar* GetGlyphRangesVietnamese(); // Default + Vietname characters
//------------------------------------------- //-------------------------------------------
// Custom Rectangles/Glyphs API // Custom Rectangles/Glyphs API

View File

@ -1,4 +1,4 @@
// dear imgui, v1.68 // dear imgui, v1.69
// (demo code) // (demo code)
// Message to the person tempted to delete this file when integrating Dear ImGui into their code base: // Message to the person tempted to delete this file when integrating Dear ImGui into their code base:
@ -126,7 +126,7 @@ static void ShowExampleAppCustomRendering(bool* p_open);
static void ShowExampleMenuFile(); static void ShowExampleMenuFile();
// Helper to display a little (?) mark which shows a tooltip when hovered. // Helper to display a little (?) mark which shows a tooltip when hovered.
static void ShowHelpMarker(const char* desc) static void HelpMarker(const char* desc)
{ {
ImGui::TextDisabled("(?)"); ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
@ -311,9 +311,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
{ {
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::SameLine(); ShowHelpMarker("Required back-end to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); ImGui::SameLine(); HelpMarker("Required back-end to feed in gamepad inputs in io.NavInputs[] and set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details.");
ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos);
ImGui::SameLine(); ShowHelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos.");
ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouse); ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouse);
if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) // Create a way to restore this flag otherwise we could be stuck completely! if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) // Create a way to restore this flag otherwise we could be stuck completely!
{ {
@ -326,21 +326,21 @@ void ImGui::ShowDemoWindow(bool* p_open)
io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; io.ConfigFlags &= ~ImGuiConfigFlags_NoMouse;
} }
ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::SameLine(); ShowHelpMarker("Instruct back-end to not alter mouse cursor shape and visibility."); ImGui::SameLine(); HelpMarker("Instruct back-end to not alter mouse cursor shape and visibility.");
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); ShowHelpMarker("Set to false to disable blinking cursor, for users who consider it distracting"); ImGui::SameLine(); HelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges); ImGui::Checkbox("io.ConfigWindowsResizeFromEdges", &io.ConfigWindowsResizeFromEdges);
ImGui::SameLine(); ShowHelpMarker("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::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.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor);
ImGui::SameLine(); ShowHelpMarker("Instruct Dear ImGui to render a mouse cursor for you. 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::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor for you. 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::TreePop(); ImGui::TreePop();
ImGui::Separator(); ImGui::Separator();
} }
if (ImGui::TreeNode("Backend Flags")) if (ImGui::TreeNode("Backend Flags"))
{ {
ShowHelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities."); HelpMarker("Those flags are set by the back-ends (imgui_impl_xxx files) to specify their capabilities.");
ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying the back-end flags. ImGuiBackendFlags backend_flags = io.BackendFlags; // Make a local copy to avoid modifying the back-end flags.
ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad); ImGui::CheckboxFlags("io.BackendFlags: HasGamepad", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasGamepad);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors); ImGui::CheckboxFlags("io.BackendFlags: HasMouseCursors", (unsigned int *)&backend_flags, ImGuiBackendFlags_HasMouseCursors);
@ -359,7 +359,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
if (ImGui::TreeNode("Capture/Logging")) if (ImGui::TreeNode("Capture/Logging"))
{ {
ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded."); ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded.");
ShowHelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button."); HelpMarker("Try opening any of the contents below in this window and then click one of the \"Log To\" button.");
ImGui::LogButtons(); ImGui::LogButtons();
ImGui::TextWrapped("You can also call ImGui::LogText() to output directly to the log without a visual output."); ImGui::TextWrapped("You can also call ImGui::LogText() to output directly to the log without a visual output.");
if (ImGui::Button("Copy \"Hello, world!\" to clipboard")) if (ImGui::Button("Copy \"Hello, world!\" to clipboard"))
@ -476,17 +476,20 @@ static void ShowDemoWindowWidgets()
const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" }; const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO" };
static int item_current = 0; static int item_current = 0;
ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items)); ImGui::Combo("combo", &item_current, items, IM_ARRAYSIZE(items));
ImGui::SameLine(); ShowHelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n"); ImGui::SameLine(); HelpMarker("Refer to the \"Combo\" section below for an explanation of the full BeginCombo/EndCombo API, and demonstration of various flags.\n");
} }
{ {
static char str0[128] = "Hello, world!"; static char str0[128] = "Hello, world!";
static int i0 = 123;
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
ImGui::SameLine(); ShowHelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp)."); ImGui::SameLine(); HelpMarker("USER:\nHold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n\nPROGRAMMER:\nYou can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated in imgui_demo.cpp).");
static char str1[128] = "";
ImGui::InputTextWithHint("input text (w/ hint)", "enter text here", str1, IM_ARRAYSIZE(str1));
static int i0 = 123;
ImGui::InputInt("input int", &i0); ImGui::InputInt("input int", &i0);
ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); ImGui::SameLine(); HelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n");
static float f0 = 0.001f; static float f0 = 0.001f;
ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f"); ImGui::InputFloat("input float", &f0, 0.01f, 1.0f, "%.3f");
@ -496,7 +499,7 @@ static void ShowDemoWindowWidgets()
static float f1 = 1.e10f; static float f1 = 1.e10f;
ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e"); ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e");
ImGui::SameLine(); ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n"); ImGui::SameLine(); HelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n");
static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f };
ImGui::InputFloat3("input float3", vec4a); ImGui::InputFloat3("input float3", vec4a);
@ -505,7 +508,7 @@ static void ShowDemoWindowWidgets()
{ {
static int i1 = 50, i2 = 42; static int i1 = 50, i2 = 42;
ImGui::DragInt("drag int", &i1, 1); ImGui::DragInt("drag int", &i1, 1);
ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); ImGui::SameLine(); HelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value.");
ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%"); ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%");
@ -517,7 +520,7 @@ static void ShowDemoWindowWidgets()
{ {
static int i1=0; static int i1=0;
ImGui::SliderInt("slider int", &i1, -1, 3); ImGui::SliderInt("slider int", &i1, -1, 3);
ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); ImGui::SameLine(); HelpMarker("CTRL+click to input value.");
static float f1=0.123f, f2=0.0f; static float f1=0.123f, f2=0.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
@ -530,7 +533,7 @@ static void ShowDemoWindowWidgets()
static float col1[3] = { 1.0f,0.0f,0.2f }; static float col1[3] = { 1.0f,0.0f,0.2f };
static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; static float col2[4] = { 0.4f,0.7f,0.0f,0.5f };
ImGui::ColorEdit3("color 1", col1); ImGui::ColorEdit3("color 1", col1);
ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nClick and hold to use drag and drop.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nClick and hold to use drag and drop.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n");
ImGui::ColorEdit4("color 2", col2); ImGui::ColorEdit4("color 2", col2);
} }
@ -573,7 +576,7 @@ static void ShowDemoWindowWidgets()
if (ImGui::TreeNode("Advanced, with Selectable nodes")) if (ImGui::TreeNode("Advanced, with Selectable nodes"))
{ {
ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); HelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open.");
static bool align_label_with_current_x_position = false; static bool align_label_with_current_x_position = false;
ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position);
ImGui::Text("Hello!"); ImGui::Text("Hello!");
@ -660,7 +663,7 @@ static void ShowDemoWindowWidgets()
ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink");
ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow");
ImGui::TextDisabled("Disabled"); ImGui::TextDisabled("Disabled");
ImGui::SameLine(); ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle."); ImGui::SameLine(); HelpMarker("The TextDisabled color is stored in ImGuiStyle.");
ImGui::TreePop(); ImGui::TreePop();
} }
@ -767,6 +770,7 @@ static void ShowDemoWindowWidgets()
// Expose flags as checkbox for the demo // Expose flags as checkbox for the demo
static ImGuiComboFlags flags = 0; static ImGuiComboFlags flags = 0;
ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft); ImGui::CheckboxFlags("ImGuiComboFlags_PopupAlignLeft", (unsigned int*)&flags, ImGuiComboFlags_PopupAlignLeft);
ImGui::SameLine(); HelpMarker("Only makes a difference if the popup is larger than the combo");
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton)) if (ImGui::CheckboxFlags("ImGuiComboFlags_NoArrowButton", (unsigned int*)&flags, ImGuiComboFlags_NoArrowButton))
flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both flags &= ~ImGuiComboFlags_NoPreview; // Clear the other flag, as we cannot combine both
if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview)) if (ImGui::CheckboxFlags("ImGuiComboFlags_NoPreview", (unsigned int*)&flags, ImGuiComboFlags_NoPreview))
@ -837,7 +841,7 @@ static void ShowDemoWindowWidgets()
} }
if (ImGui::TreeNode("Selection State: Multiple Selection")) if (ImGui::TreeNode("Selection State: Multiple Selection"))
{ {
ShowHelpMarker("Hold CTRL and click to select multiple items."); HelpMarker("Hold CTRL and click to select multiple items.");
static bool selection[5] = { false, false, false, false, false }; static bool selection[5] = { false, false, false, false, false };
for (int n = 0; n < 5; n++) for (int n = 0; n < 5; n++)
{ {
@ -897,7 +901,7 @@ static void ShowDemoWindowWidgets()
} }
if (ImGui::TreeNode("Alignment")) if (ImGui::TreeNode("Alignment"))
{ {
ShowHelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar()."); HelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar().");
static bool selected[3*3] = { true, false, true, false, true, false, true, false, true }; static bool selected[3*3] = { true, false, true, false, true, false, true, false, true };
for (int y = 0; y < 3; y++) for (int y = 0; y < 3; y++)
{ {
@ -917,46 +921,89 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Filtered Text Input")) if (ImGui::TreeNode("Text Input"))
{ {
static char buf1[64] = ""; ImGui::InputText("default", buf1, 64); if (ImGui::TreeNode("Multi-line Text Input"))
static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); {
static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); // Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); // and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); static char text[1024 * 16] =
struct TextFilters { static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } }; "/*\n"
static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n"
" the hexadecimal encoding of one offending instruction,\n"
" more formally, the invalid operand with locked CMPXCHG8B\n"
" instruction bug, is a design flaw in the majority of\n"
" Intel Pentium, Pentium MMX, and Pentium OverDrive\n"
" processors (all in the P5 microarchitecture).\n"
"*/\n\n"
"label:\n"
"\tlock cmpxchg8b eax\n";
ImGui::Text("Password input"); static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
static char bufpass[64] = "password123"; HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp)");
ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", (unsigned int*)&flags, ImGuiInputTextFlags_ReadOnly);
ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", (unsigned int*)&flags, ImGuiInputTextFlags_AllowTabInput);
ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", (unsigned int*)&flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop();
}
ImGui::TreePop(); if (ImGui::TreeNode("Filtered Text Input"))
} {
static char buf1[64] = ""; ImGui::InputText("default", buf1, 64);
static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal);
static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase);
static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank);
struct TextFilters { static int FilterImGuiLetters(ImGuiInputTextCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } };
static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters);
if (ImGui::TreeNode("Multi-line Text Input")) ImGui::Text("Password input");
{ static char bufpass[64] = "password123";
// Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank);
// and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings. ImGui::SameLine(); HelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n");
static bool read_only = false; ImGui::InputTextWithHint("password (w/ hint)", "<password>", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank);
static char text[1024*16] = ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank);
"/*\n" ImGui::TreePop();
" The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" }
" the hexadecimal encoding of one offending instruction,\n"
" more formally, the invalid operand with locked CMPXCHG8B\n" if (ImGui::TreeNode("Resize Callback"))
" instruction bug, is a design flaw in the majority of\n" {
" Intel Pentium, Pentium MMX, and Pentium OverDrive\n" // If you have a custom string type you would typically create a ImGui::InputText() wrapper than takes your type as input.
" processors (all in the P5 microarchitecture).\n" // See misc/cpp/imgui_stdlib.h and .cpp for an implementation of this using std::string.
"*/\n\n" HelpMarker("Demonstrate using ImGuiInputTextFlags_CallbackResize to wire your resizable string type to InputText().\n\nSee misc/cpp/imgui_stdlib.h for an implementation of this for std::string.");
"label:\n" struct Funcs
"\tlock cmpxchg8b eax\n"; {
static int MyResizeCallback(ImGuiInputTextCallbackData* data)
{
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
{
ImVector<char>* my_str = (ImVector<char>*)data->UserData;
IM_ASSERT(my_str->begin() == data->Buf);
my_str->resize(data->BufSize); // NB: On resizing calls, generally data->BufSize == data->BufTextLen + 1
data->Buf = my_str->begin();
}
return 0;
}
// Tip: Because ImGui:: is a namespace you can add your own function into the namespace from your own source files.
static bool MyInputTextMultiline(const char* label, ImVector<char>* my_str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0)
{
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
return ImGui::InputTextMultiline(label, my_str->begin(), (size_t)my_str->size(), size, flags | ImGuiInputTextFlags_CallbackResize, Funcs::MyResizeCallback, (void*)my_str);
}
};
// For this demo we are using ImVector as a string container.
// Note that because we need to store a terminating zero character, our size/capacity are 1 more than usually reported by a typical string class.
static ImVector<char> my_str;
if (my_str.empty())
my_str.push_back(0);
Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16));
ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
ImGui::TreePop();
}
ShowHelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp)");
ImGui::Checkbox("Read-only", &read_only);
ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput | (read_only ? ImGuiInputTextFlags_ReadOnly : 0);
ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), flags);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1036,22 +1083,22 @@ static void ShowDemoWindowWidgets()
ImGui::Checkbox("With Alpha Preview", &alpha_preview); ImGui::Checkbox("With Alpha Preview", &alpha_preview);
ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview);
ImGui::Checkbox("With Drag and Drop", &drag_and_drop); ImGui::Checkbox("With Drag and Drop", &drag_and_drop);
ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); ShowHelpMarker("Right-click on the individual color widget to show options."); ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); HelpMarker("Right-click on the individual color widget to show options.");
ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); HelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets.");
int 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); int 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::Text("Color widget:"); ImGui::Text("Color widget:");
ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); ImGui::SameLine(); HelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n");
ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags);
ImGui::Text("Color widget HSV with Alpha:"); ImGui::Text("Color widget HSV with Alpha:");
ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_HSV | misc_flags); ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_DisplayHSV | misc_flags);
ImGui::Text("Color widget with Float Display:"); ImGui::Text("Color widget with Float Display:");
ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags);
ImGui::Text("Color button with Picker:"); ImGui::Text("Color button with Picker:");
ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); ImGui::SameLine(); HelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup.");
ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags);
ImGui::Text("Color button with Custom Picker Popup:"); ImGui::Text("Color button with Custom Picker Popup:");
@ -1127,7 +1174,7 @@ static void ShowDemoWindowWidgets()
static bool side_preview = true; static bool side_preview = true;
static bool ref_color = false; static bool ref_color = false;
static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f); static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f);
static int inputs_mode = 2; static int display_mode = 0;
static int picker_mode = 0; static int picker_mode = 0;
ImGui::Checkbox("With Alpha", &alpha); ImGui::Checkbox("With Alpha", &alpha);
ImGui::Checkbox("With Alpha Bar", &alpha_bar); ImGui::Checkbox("With Alpha Bar", &alpha_bar);
@ -1142,28 +1189,39 @@ static void ShowDemoWindowWidgets()
ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags);
} }
} }
ImGui::Combo("Inputs Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); ImGui::Combo("Display Mode", &display_mode, "Auto/Current\0None\0RGB Only\0HSV Only\0Hex Only\0");
ImGui::SameLine(); HelpMarker("ColorEdit defaults to displaying RGB inputs if you don't specify a display mode, but the user can change it with a right-click.\n\nColorPicker defaults to displaying RGB+HSV+Hex if you don't specify a display mode.\n\nYou can change the defaults using SetColorEditOptions().");
ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0");
ImGui::SameLine(); ShowHelpMarker("User can right-click the picker to change mode."); ImGui::SameLine(); HelpMarker("User can right-click the picker to change mode.");
ImGuiColorEditFlags flags = misc_flags; ImGuiColorEditFlags flags = misc_flags;
if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4()
if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar;
if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview;
if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar;
if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel;
if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; if (display_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; // Disable all RGB/HSV/Hex displays
if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; if (display_mode == 2) flags |= ImGuiColorEditFlags_DisplayRGB; // Override display mode
if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; if (display_mode == 3) flags |= ImGuiColorEditFlags_DisplayHSV;
if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; if (display_mode == 4) flags |= ImGuiColorEditFlags_DisplayHex;
ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL);
ImGui::Text("Programmatically set defaults:"); ImGui::Text("Programmatically set defaults:");
ImGui::SameLine(); ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); ImGui::SameLine(); HelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible.");
if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) if (ImGui::Button("Default: Uint8 + HSV + Hue Bar"))
ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_PickerHueBar); ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_PickerHueBar);
if (ImGui::Button("Default: Float + HDR + Hue Wheel")) if (ImGui::Button("Default: Float + HDR + Hue Wheel"))
ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel); ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel);
// HSV encoded support (to avoid RGB<>HSV round trips and singularities when S==0 or V==0)
static ImVec4 color_stored_as_hsv(0.23f, 1.0f, 1.0f, 1.0f);
ImGui::Spacing();
ImGui::Text("HSV encoded colors");
ImGui::SameLine(); HelpMarker("By default, colors are given to ColorEdit and ColorPicker in RGB, but ImGuiColorEditFlags_InputHSV allows you to store colors as HSV and pass them to ColorEdit and ColorPicker as HSV. This comes with the added benefit that you can manipulate hue values with the picker even when saturation or value are zero.");
ImGui::Text("Color widget with InputHSV:");
ImGui::ColorEdit4("HSV shown as HSV##1", (float*)&color_stored_as_hsv, ImGuiColorEditFlags_DisplayRGB | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
ImGui::ColorEdit4("HSV shown as RGB##1", (float*)&color_stored_as_hsv, ImGuiColorEditFlags_DisplayHSV | ImGuiColorEditFlags_InputHSV | ImGuiColorEditFlags_Float);
ImGui::DragFloat4("Raw HSV values", (float*)&color_stored_as_hsv, 0.01f, 0.0f, 1.0f);
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1197,6 +1255,10 @@ static void ShowDemoWindowWidgets()
ImS64 LLONG_MAX = 9223372036854775807LL; ImS64 LLONG_MAX = 9223372036854775807LL;
ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1); ImU64 ULLONG_MAX = (2ULL * 9223372036854775807LL + 1);
#endif #endif
const char s8_zero = 0, s8_one = 1, s8_fifty = 50, s8_min = -128, s8_max = 127;
const ImU8 u8_zero = 0, u8_one = 1, u8_fifty = 50, u8_min = 0, u8_max = 255;
const short s16_zero = 0, s16_one = 1, s16_fifty = 50, s16_min = -32768, s16_max = 32767;
const ImU16 u16_zero = 0, u16_one = 1, u16_fifty = 50, u16_min = 0, u16_max = 65535;
const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2; const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2;
const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2; const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2;
const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2; const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2;
@ -1205,6 +1267,10 @@ static void ShowDemoWindowWidgets()
const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0; const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000.0, f64_hi_a = +1000000000000000.0;
// State // State
static char s8_v = 127;
static ImU8 u8_v = 255;
static short s16_v = 32767;
static ImU16 u16_v = 65535;
static ImS32 s32_v = -1; static ImS32 s32_v = -1;
static ImU32 u32_v = (ImU32)-1; static ImU32 u32_v = (ImU32)-1;
static ImS64 s64_v = -1; static ImS64 s64_v = -1;
@ -1215,17 +1281,25 @@ static void ShowDemoWindowWidgets()
const float drag_speed = 0.2f; const float drag_speed = 0.2f;
static bool drag_clamp = false; static bool drag_clamp = false;
ImGui::Text("Drags:"); ImGui::Text("Drags:");
ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value."); ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); HelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value.");
ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL);
ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL);
ImGui::DragScalar("drag u16", ImGuiDataType_U16, &u16_v, drag_speed, drag_clamp ? &u16_zero : NULL, drag_clamp ? &u16_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL); ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL);
ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms"); ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL);
ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL); ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL);
ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 1.0f); ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 1.0f);
ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); ShowHelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range."); ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); HelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range.");
ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams", 1.0f); ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams", 1.0f);
ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f); ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f);
ImGui::Text("Sliders"); ImGui::Text("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");
ImGui::SliderScalar("slider u16 full", ImGuiDataType_U16, &u16_v, &u16_min, &u16_max, "%u");
ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d"); ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d");
ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d"); ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d");
ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d"); ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d");
@ -1248,6 +1322,10 @@ static void ShowDemoWindowWidgets()
static bool inputs_step = true; static bool inputs_step = true;
ImGui::Text("Inputs"); ImGui::Text("Inputs");
ImGui::Checkbox("Show step buttons", &inputs_step); 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");
ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d");
ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u");
ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d");
ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal);
ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u");
@ -1439,20 +1517,23 @@ static void ShowDemoWindowWidgets()
static int item_type = 1; static int item_type = 1;
static bool b = false; static bool b = false;
static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f }; static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
static char str[16] = {};
ImGui::RadioButton("Text", &item_type, 0); ImGui::RadioButton("Text", &item_type, 0);
ImGui::RadioButton("Button", &item_type, 1); ImGui::RadioButton("Button", &item_type, 1);
ImGui::RadioButton("Checkbox", &item_type, 2); ImGui::RadioButton("Checkbox", &item_type, 2);
ImGui::RadioButton("SliderFloat", &item_type, 3); ImGui::RadioButton("SliderFloat", &item_type, 3);
ImGui::RadioButton("ColorEdit4", &item_type, 4); ImGui::RadioButton("InputText", &item_type, 4);
ImGui::RadioButton("ListBox", &item_type, 5); ImGui::RadioButton("ColorEdit4", &item_type, 5);
ImGui::RadioButton("ListBox", &item_type, 6);
ImGui::Separator(); ImGui::Separator();
bool ret = false; bool ret = false;
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
if (item_type == 2) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox if (item_type == 2) { ret = ImGui::Checkbox("ITEM: Checkbox", &b); } // Testing checkbox
if (item_type == 3) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item if (item_type == 3) { ret = ImGui::SliderFloat("ITEM: SliderFloat", &col4f[0], 0.0f, 1.0f); } // Testing basic item
if (item_type == 4) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged) if (item_type == 4) { ret = ImGui::InputText("ITEM: InputText", &str[0], IM_ARRAYSIZE(str)); } // Testing input text (which handles tabbing)
if (item_type == 5) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); } if (item_type == 5) { ret = ImGui::ColorEdit4("ITEM: ColorEdit4", col4f); } // Testing multi-component items (IsItemXXX flags are reported merged)
if (item_type == 6) { const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
ImGui::BulletText( ImGui::BulletText(
"Return value = %d\n" "Return value = %d\n"
"IsItemFocused() = %d\n" "IsItemFocused() = %d\n"
@ -1559,7 +1640,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Child windows")) if (ImGui::TreeNode("Child windows"))
{ {
ShowHelpMarker("Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window."); 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_mouse_wheel = false;
static bool disable_menu = false; static bool disable_menu = false;
ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel);
@ -1643,31 +1724,31 @@ static void ShowDemoWindowLayout()
{ {
static float f = 0.0f; static float f = 0.0f;
ImGui::Text("PushItemWidth(100)"); ImGui::Text("PushItemWidth(100)");
ImGui::SameLine(); ShowHelpMarker("Fixed width."); ImGui::SameLine(); HelpMarker("Fixed width.");
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("float##1", &f); ImGui::DragFloat("float##1", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)"); ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)");
ImGui::SameLine(); ShowHelpMarker("Half of window width."); ImGui::SameLine(); HelpMarker("Half of window width.");
ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f);
ImGui::DragFloat("float##2", &f); ImGui::DragFloat("float##2", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)"); ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)");
ImGui::SameLine(); ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); ImGui::SameLine(); HelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)");
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f);
ImGui::DragFloat("float##3", &f); ImGui::DragFloat("float##3", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(-100)"); ImGui::Text("PushItemWidth(-100)");
ImGui::SameLine(); ShowHelpMarker("Align to right edge minus 100"); ImGui::SameLine(); HelpMarker("Align to right edge minus 100");
ImGui::PushItemWidth(-100); ImGui::PushItemWidth(-100);
ImGui::DragFloat("float##4", &f); ImGui::DragFloat("float##4", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
ImGui::Text("PushItemWidth(-1)"); ImGui::Text("PushItemWidth(-1)");
ImGui::SameLine(); ShowHelpMarker("Align to right edge"); ImGui::SameLine(); HelpMarker("Align to right edge");
ImGui::PushItemWidth(-1); ImGui::PushItemWidth(-1);
ImGui::DragFloat("float##5", &f); ImGui::DragFloat("float##5", &f);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
@ -1836,7 +1917,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Groups")) if (ImGui::TreeNode("Groups"))
{ {
ShowHelpMarker("Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it."); HelpMarker("Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it.");
ImGui::BeginGroup(); ImGui::BeginGroup();
{ {
ImGui::BeginGroup(); ImGui::BeginGroup();
@ -1880,7 +1961,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Text Baseline Alignment")) if (ImGui::TreeNode("Text Baseline Alignment"))
{ {
ShowHelpMarker("This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets."); HelpMarker("This is testing the vertical alignment that gets applied on text to keep it aligned with widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets.");
ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); ImGui::Text("One\nTwo\nThree"); ImGui::SameLine();
ImGui::Text("Hello\nWorld"); ImGui::SameLine(); ImGui::Text("Hello\nWorld"); ImGui::SameLine();
@ -1935,7 +2016,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Scrolling")) if (ImGui::TreeNode("Scrolling"))
{ {
ShowHelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position."); HelpMarker("Use SetScrollHereY() or SetScrollFromPosY() to scroll to a given position.");
static bool track = true; static bool track = true;
static int track_line = 50, scroll_to_px = 200; static int track_line = 50, scroll_to_px = 200;
@ -1977,7 +2058,7 @@ static void ShowDemoWindowLayout()
if (ImGui::TreeNode("Horizontal Scrolling")) if (ImGui::TreeNode("Horizontal Scrolling"))
{ {
ShowHelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); HelpMarker("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag.\n\nYou may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin().");
static int lines = 7; static int lines = 7;
ImGui::SliderInt("Lines", &lines, 1, 15); ImGui::SliderInt("Lines", &lines, 1, 15);
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f);
@ -2149,7 +2230,7 @@ static void ShowDemoWindowPopups()
// We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the Begin call. // We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the Begin call.
// So here we will make it that clicking on the text field with the right mouse button (1) will toggle the visibility of the popup above. // So here we will make it that clicking on the text field with the right mouse button (1) will toggle the visibility of the popup above.
ImGui::Text("(You can also right-click me to the same popup as above.)"); ImGui::Text("(You can also right-click me to open the same popup as above.)");
ImGui::OpenPopupOnItemClick("item context menu", 1); ImGui::OpenPopupOnItemClick("item context menu", 1);
// When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem().
@ -2430,7 +2511,7 @@ static void ShowDemoWindowColumns()
} }
bool node_open = ImGui::TreeNode("Tree within single cell"); bool node_open = ImGui::TreeNode("Tree within single cell");
ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); ImGui::SameLine(); HelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell.");
if (node_open) if (node_open)
{ {
ImGui::Columns(2, "tree items"); ImGui::Columns(2, "tree items");
@ -2513,7 +2594,7 @@ static void ShowDemoWindowMisc()
ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("3", buf, IM_ARRAYSIZE(buf));
ImGui::PushAllowKeyboardFocus(false); ImGui::PushAllowKeyboardFocus(false);
ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf));
//ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); //ImGui::SameLine(); HelpMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets.");
ImGui::PopAllowKeyboardFocus(); ImGui::PopAllowKeyboardFocus();
ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); ImGui::InputText("5", buf, IM_ARRAYSIZE(buf));
ImGui::TreePop(); ImGui::TreePop();
@ -2591,7 +2672,7 @@ static void ShowDemoWindowMisc()
ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]);
ImGui::Text("Hover to see mouse cursors:"); ImGui::Text("Hover to see mouse cursors:");
ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); ImGui::SameLine(); HelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it.");
for (int i = 0; i < ImGuiMouseCursor_COUNT; i++) for (int i = 0; i < ImGuiMouseCursor_COUNT; i++)
{ {
char label[32]; char label[32];
@ -2769,7 +2850,7 @@ void ImGui::ShowFontSelector(const char* label)
ImGui::EndCombo(); ImGui::EndCombo();
} }
ImGui::SameLine(); ImGui::SameLine();
ShowHelpMarker( HelpMarker(
"- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n"
"- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n"
"- Read FAQ and documentation in misc/fonts/ for more details.\n" "- Read FAQ and documentation in misc/fonts/ for more details.\n"
@ -2812,7 +2893,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
if (ImGui::Button("Revert Ref")) if (ImGui::Button("Revert Ref"))
style = *ref; style = *ref;
ImGui::SameLine(); ImGui::SameLine();
ShowHelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); HelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere.");
ImGui::Separator(); ImGui::Separator();
@ -2845,9 +2926,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f"); ImGui::SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
ImGui::Text("Alignment"); ImGui::Text("Alignment");
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content."); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); 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(); ShowHelpMarker("Alignment applies when a selectable 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(); ShowHelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); 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::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f");
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
@ -2882,7 +2963,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine(); ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine();
ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine();
ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); ImGui::SameLine(); ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); ImGui::SameLine();
ShowHelpMarker("In the color list:\nLeft-click on colored square to open color picker,\nRight-click to open edit options menu."); HelpMarker("In the color list:\nLeft-click on colored square to open color picker,\nRight-click to open edit options menu.");
ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
ImGui::PushItemWidth(-160); ImGui::PushItemWidth(-160);
@ -2914,7 +2995,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImFontAtlas* atlas = io.Fonts; ImFontAtlas* atlas = io.Fonts;
ShowHelpMarker("Read FAQ and misc/fonts/README.txt for details on font loading."); HelpMarker("Read FAQ and misc/fonts/README.txt for details on font loading.");
ImGui::PushItemWidth(120); ImGui::PushItemWidth(120);
for (int i = 0; i < atlas->Fonts.Size; i++) for (int i = 0; i < atlas->Fonts.Size; i++)
{ {
@ -2928,7 +3009,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::Text("The quick brown fox jumps over the lazy dog"); ImGui::Text("The quick brown fox jumps over the lazy dog");
ImGui::PopFont(); ImGui::PopFont();
ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font
ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); ImGui::SameLine(); HelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)");
ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f"); ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, "%.0f");
ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar);
@ -2997,7 +3078,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
if (ImGui::BeginTabItem("Rendering")) if (ImGui::BeginTabItem("Rendering"))
{ {
ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); HelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well.");
ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill);
ImGui::PushItemWidth(100); ImGui::PushItemWidth(100);
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, "%.2f", 2.0f); ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, "%.2f", 2.0f);
@ -3671,7 +3752,7 @@ static void ShowExampleAppPropertyEditor(bool* p_open)
return; return;
} }
ShowHelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); HelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API.");
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2)); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2));
ImGui::Columns(2); ImGui::Columns(2);
@ -3950,97 +4031,121 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// In this example we are not using the maths operators! // In this example we are not using the maths operators!
ImDrawList* draw_list = ImGui::GetWindowDrawList(); ImDrawList* draw_list = ImGui::GetWindowDrawList();
// Primitives if (ImGui::BeginTabBar("##TabBar"))
ImGui::Text("Primitives");
static float sz = 36.0f;
static float thickness = 4.0f;
static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
ImGui::ColorEdit4("Color", &col.x);
{ {
const ImVec2 p = ImGui::GetCursorScreenPos(); // Primitives
const ImU32 col32 = ImColor(col); if (ImGui::BeginTabItem("Primitives"))
float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
for (int n = 0; n < 2; n++)
{ {
// First line uses a thickness of 1.0, second line uses the configurable thickness static float sz = 36.0f;
float th = (n == 0) ? 1.0f : thickness; static float thickness = 4.0f;
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6, th); x += sz+spacing; // Hexagon static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, th); x += sz+spacing; // Circle ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f");
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, th); x += sz+spacing; ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f");
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, th); x += sz+spacing; ImGui::ColorEdit4("Color", &col.x);
draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, th); x += sz+spacing; const ImVec2 p = ImGui::GetCursorScreenPos();
draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, th); x += sz+spacing; const ImU32 col32 = ImColor(col);
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, th); x += sz+spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f;
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) for (int n = 0; n < 2; n++)
draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, th); x += sz+spacing; // Diagonal line
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, th);
x = p.x + 4;
y += sz+spacing;
}
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 6); x += sz+spacing; // Hexagon
draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; // Circle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing;
draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+thickness), col32); x += sz+spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+thickness, y+sz), col32); x += spacing+spacing; // Vertical line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+1, y+1), col32); x += sz; // Pixel (faster than AddLine)
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)*8, (sz+spacing)*3));
}
ImGui::Separator();
{
static ImVector<ImVec2> points;
static bool adding_line = false;
ImGui::Text("Canvas example");
if (ImGui::Button("Clear")) points.clear();
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255));
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size);
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_in_canvas);
if (!ImGui::IsMouseDown(0))
adding_line = adding_preview = false;
}
if (ImGui::IsItemHovered())
{
if (!adding_line && ImGui::IsMouseClicked(0))
{ {
// First line uses a thickness of 1.0, second line uses the configurable thickness
float th = (n == 0) ? 1.0f : thickness;
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 6, th); x += sz + spacing; // Hexagon
draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 20, th); x += sz + spacing; // Circle
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 0.0f, ImDrawCornerFlags_All, th); x += sz + spacing;
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_All, th); x += sz + spacing;
draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight, th); x += sz + spacing;
draw_list->AddTriangle(ImVec2(x + sz*0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32, th); x += sz + spacing;
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col32, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col32, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!)
draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, th); x += sz + spacing; // Diagonal line
draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz*1.3f, y + sz*0.3f), ImVec2(x + sz - sz*1.3f, y + sz - sz*0.3f), ImVec2(x + sz, y + sz), col32, th);
x = p.x + 4;
y += sz + spacing;
}
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 6); x += sz + spacing; // Hexagon
draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col32, 32); x += sz + spacing; // Circle
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight); x += sz + spacing;
draw_list->AddTriangleFilled(ImVec2(x + sz*0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32); x += sz + spacing;
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col32); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col32); x += spacing + spacing; // Vertical line (faster than AddLine, but only handle integer thickness)
draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col32); x += sz; // Pixel (faster than AddLine)
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.5f, (sz + spacing) * 3));
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Canvas"))
{
static ImVector<ImVec2> points;
static bool adding_line = false;
if (ImGui::Button("Clear")) points.clear();
if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } }
ImGui::Text("Left-click and drag to add lines,\nRight-click to undo");
// Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered()
// But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos().
// If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max).
ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available
if (canvas_size.x < 50.0f) canvas_size.x = 50.0f;
if (canvas_size.y < 50.0f) canvas_size.y = 50.0f;
draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255));
draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255));
bool adding_preview = false;
ImGui::InvisibleButton("canvas", canvas_size);
ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y);
if (adding_line)
{
adding_preview = true;
points.push_back(mouse_pos_in_canvas); points.push_back(mouse_pos_in_canvas);
adding_line = true; if (!ImGui::IsMouseDown(0))
adding_line = adding_preview = false;
} }
if (ImGui::IsMouseClicked(1) && !points.empty()) if (ImGui::IsItemHovered())
{ {
adding_line = adding_preview = false; if (!adding_line && ImGui::IsMouseClicked(0))
points.pop_back(); {
points.pop_back(); points.push_back(mouse_pos_in_canvas);
adding_line = true;
}
if (ImGui::IsMouseClicked(1) && !points.empty())
{
adding_line = adding_preview = false;
points.pop_back();
points.pop_back();
}
} }
draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2)
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f);
draw_list->PopClipRect();
if (adding_preview)
points.pop_back();
ImGui::EndTabItem();
} }
draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.)
for (int i = 0; i < points.Size - 1; i += 2) if (ImGui::BeginTabItem("BG/FG draw lists"))
draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); {
draw_list->PopClipRect(); static bool draw_bg = true;
if (adding_preview) static bool draw_fg = true;
points.pop_back(); ImGui::Checkbox("Draw in Background draw list", &draw_bg);
ImGui::Checkbox("Draw in Foreground draw list", &draw_fg);
ImVec2 window_pos = ImGui::GetWindowPos();
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), 32, 10);
if (draw_fg)
ImGui::GetForegroundDrawList()->AddCircle(window_center, window_size.y * 0.6f, IM_COL32(0, 255, 0, 200), 32, 10);
ImGui::EndTabItem();
}
ImGui::EndTabBar();
} }
ImGui::End(); ImGui::End();
} }

View File

@ -1,4 +1,4 @@
// dear imgui, v1.68 // dear imgui, v1.69
// (drawing and font code) // (drawing and font code)
/* /*
@ -55,7 +55,7 @@ Index of this file:
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok.
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference is.
#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
#if __has_warning("-Wzero-as-null-pointer-constant") #if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
@ -83,7 +83,7 @@ Index of this file:
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Compile time options: // Compile time options:
//#define IMGUI_STB_NAMESPACE ImGuiStb //#define IMGUI_STB_NAMESPACE ImStb
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h" //#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION //#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
@ -163,7 +163,7 @@ namespace IMGUI_STB_NAMESPACE
#endif #endif
#ifdef IMGUI_STB_NAMESPACE #ifdef IMGUI_STB_NAMESPACE
} // namespace ImGuiStb } // namespace ImStb
using namespace IMGUI_STB_NAMESPACE; using namespace IMGUI_STB_NAMESPACE;
#endif #endif
@ -407,7 +407,7 @@ ImDrawList* ImDrawList::CloneOutput() const
// Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds
#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) #define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen)
#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) #define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : (ImTextureID)NULL)
void ImDrawList::AddDrawCmd() void ImDrawList::AddDrawCmd()
{ {
@ -2346,6 +2346,23 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai()
return &ranges[0]; return &ranges[0];
} }
const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese()
{
static const ImWchar ranges[] =
{
0x0020, 0x00FF, // Basic Latin
0x0102, 0x0103,
0x0110, 0x0111,
0x0128, 0x0129,
0x0168, 0x0169,
0x01A0, 0x01A1,
0x01AF, 0x01B0,
0x1EA0, 0x1EF9,
0,
};
return &ranges[0];
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] ImFontGlyphRangesBuilder // [SECTION] ImFontGlyphRangesBuilder
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
// dear imgui, v1.68 // dear imgui, v1.69
// (internal structures/api) // (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@ -83,6 +83,7 @@ struct ImGuiWindowSettings; // Storage for window settings stored in .in
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior() typedef int ImGuiButtonFlags; // -> enum ImGuiButtonFlags_ // Flags: for ButtonEx(), ButtonBehavior()
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior()
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
@ -90,13 +91,13 @@ typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags:
typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests
typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for Separator() - internal typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for Separator() - internal
typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for SliderBehavior() typedef int ImGuiSliderFlags; // -> enum ImGuiSliderFlags_ // Flags: for SliderBehavior()
typedef int ImGuiDragFlags; // -> enum ImGuiDragFlags_ // Flags: for DragBehavior() typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// STB libraries includes // STB libraries includes
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
namespace ImGuiStb namespace ImStb
{ {
#undef STB_TEXTEDIT_STRING #undef STB_TEXTEDIT_STRING
@ -104,9 +105,11 @@ namespace ImGuiStb
#define STB_TEXTEDIT_STRING ImGuiInputTextState #define STB_TEXTEDIT_STRING ImGuiInputTextState
#define STB_TEXTEDIT_CHARTYPE ImWchar #define STB_TEXTEDIT_CHARTYPE ImWchar
#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f #define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f
#define STB_TEXTEDIT_UNDOSTATECOUNT 99
#define STB_TEXTEDIT_UNDOCHARCOUNT 999
#include "imstb_textedit.h" #include "imstb_textedit.h"
} // namespace ImGuiStb } // namespace ImStb
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Context pointer // Context pointer
@ -223,12 +226,15 @@ static inline double ImAtof(const char* s)
static inline float ImFloorStd(float x) { return floorf(x); } // we already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by stb_truetype) static inline float ImFloorStd(float x) { return floorf(x); } // we already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by stb_truetype)
static inline float ImCeil(float x) { return ceilf(x); } static inline float ImCeil(float x) { return ceilf(x); }
#endif #endif
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support for variety of types: signed/unsigned int/long long float/double, using templates here but we could also redefine them 6 times // - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support for variety of types: signed/unsigned int/long long float/double
// (Exceptionally using templates here but we could also redefine them for variety of types)
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
// - Misc maths helpers // - Misc maths helpers
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
@ -242,6 +248,7 @@ static inline float ImLengthSqr(const ImVec4& lhs)
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; } static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; }
static inline float ImFloor(float f) { return (float)(int)f; } static inline float ImFloor(float f) { return (float)(int)f; }
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
@ -275,7 +282,8 @@ struct IMGUI_API ImPool
T* GetByIndex(ImPoolIdx n) { return &Data[n]; } T* GetByIndex(ImPoolIdx n) { return &Data[n]; }
ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Data.Data && p < Data.Data + Data.Size); return (ImPoolIdx)(p - Data.Data); } ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Data.Data && p < Data.Data + Data.Size); return (ImPoolIdx)(p - Data.Data); }
T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Data[*p_idx]; *p_idx = FreeIdx; return Add(); } T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Data[*p_idx]; *p_idx = FreeIdx; return Add(); }
void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Data[idx].~T(); } Map.Clear(); Data.clear(); FreeIdx = 0; } bool Contains(const T* p) const { return (p >= Data.Data && p < Data.Data + Data.Size); }
void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Data[idx].~T(); } Map.Clear(); Data.clear(); FreeIdx = 0; }
T* Add() { int idx = FreeIdx; if (idx == Data.Size) { Data.resize(Data.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Data[idx]; } IM_PLACEMENT_NEW(&Data[idx]) T(); return &Data[idx]; } T* Add() { int idx = FreeIdx; if (idx == Data.Size) { Data.resize(Data.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Data[idx]; } IM_PLACEMENT_NEW(&Data[idx]) T(); return &Data[idx]; }
void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); } void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); }
void Remove(ImGuiID key, ImPoolIdx idx) { Data[idx].~T(); *(int*)&Data[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); } void Remove(ImGuiID key, ImPoolIdx idx) { Data[idx].~T(); *(int*)&Data[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); }
@ -375,6 +383,12 @@ enum ImGuiItemStatusFlags_
#endif #endif
}; };
enum ImGuiTextFlags_
{
ImGuiTextFlags_None = 0,
ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0
};
// FIXME: this is in development, not exposed/functional as a generic feature yet. // FIXME: this is in development, not exposed/functional as a generic feature yet.
// Horizontal/Vertical enums are fixed to 0/1 so they may be used to index ImVec2 // Horizontal/Vertical enums are fixed to 0/1 so they may be used to index ImVec2
enum ImGuiLayoutType_ enum ImGuiLayoutType_
@ -383,6 +397,15 @@ enum ImGuiLayoutType_
ImGuiLayoutType_Vertical = 1 ImGuiLayoutType_Vertical = 1
}; };
enum ImGuiLogType
{
ImGuiLogType_None = 0,
ImGuiLogType_TTY,
ImGuiLogType_File,
ImGuiLogType_Buffer,
ImGuiLogType_Clipboard
};
// X/Y enums are fixed to 0/1 so they may be used to index ImVec2 // X/Y enums are fixed to 0/1 so they may be used to index ImVec2
enum ImGuiAxis enum ImGuiAxis
{ {
@ -537,7 +560,6 @@ struct ImGuiGroupData
ImVec1 BackupGroupOffset; ImVec1 BackupGroupOffset;
ImVec2 BackupCurrentLineSize; ImVec2 BackupCurrentLineSize;
float BackupCurrentLineTextBaseOffset; float BackupCurrentLineTextBaseOffset;
float BackupLogLinePosY;
ImGuiID BackupActiveIdIsAlive; ImGuiID BackupActiveIdIsAlive;
bool BackupActiveIdPreviousFrameIsAlive; bool BackupActiveIdPreviousFrameIsAlive;
bool AdvanceCursor; bool AdvanceCursor;
@ -546,10 +568,9 @@ struct ImGuiGroupData
// Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper. // Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper.
struct IMGUI_API ImGuiMenuColumns struct IMGUI_API ImGuiMenuColumns
{ {
int Count;
float Spacing; float Spacing;
float Width, NextWidth; float Width, NextWidth;
float Pos[4], NextWidths[4]; float Pos[3], NextWidths[3];
ImGuiMenuColumns(); ImGuiMenuColumns();
void Update(int count, float spacing, bool clear); void Update(int count, float spacing, bool clear);
@ -561,16 +582,17 @@ struct IMGUI_API ImGuiMenuColumns
struct IMGUI_API ImGuiInputTextState struct IMGUI_API ImGuiInputTextState
{ {
ImGuiID ID; // widget id owning the text state ImGuiID ID; // widget id owning the text state
int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 len is valid even if TextA is not.
ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
ImVector<char> InitialText; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) ImVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity.
ImVector<char> TempBuffer; // temporary buffer for callback and other other operations. size=capacity. ImVector<char> InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
int CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument)
int BufCapacityA; // end-user buffer capacity int BufCapacityA; // end-user buffer capacity
float ScrollX; float ScrollX; // horizontal scrolling/offset
ImGuiStb::STB_TexteditState StbState; ImStb::STB_TexteditState Stb; // state for stb_textedit.h
float CursorAnim; float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
bool CursorFollow; bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
bool SelectedAllMouseLock; bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
// Temporarily set when active // Temporarily set when active
ImGuiInputTextFlags UserFlags; ImGuiInputTextFlags UserFlags;
@ -578,11 +600,14 @@ struct IMGUI_API ImGuiInputTextState
void* UserCallbackData; void* UserCallbackData;
ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } ImGuiInputTextState() { memset(this, 0, sizeof(*this)); }
void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking
void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } void CursorClamp() { Stb.cursor = ImMin(Stb.cursor, CurLenW); Stb.select_start = ImMin(Stb.select_start, CurLenW); Stb.select_end = ImMin(Stb.select_end, CurLenW); }
bool HasSelection() const { return StbState.select_start != StbState.select_end; } bool HasSelection() const { return Stb.select_start != Stb.select_end; }
void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; }
void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = 0; } void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; }
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
}; };
@ -617,7 +642,7 @@ struct ImGuiPopupRef
ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
ImGuiWindow* ParentWindow; // Set on OpenPopup() ImGuiWindow* ParentWindow; // Set on OpenPopup()
int OpenFrameCount; // Set on OpenPopup() int OpenFrameCount; // Set on OpenPopup()
ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items)
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
}; };
@ -748,8 +773,17 @@ struct ImGuiNextWindowData
struct ImGuiTabBarSortItem struct ImGuiTabBarSortItem
{ {
int Index; int Index;
float Width; float Width;
};
struct ImGuiTabBarRef
{
ImGuiTabBar* Ptr; // Either field can be set, not both. Dock node tab bars are loose while BeginTabBar() ones are in a pool.
int IndexInMainPool;
ImGuiTabBarRef(ImGuiTabBar* ptr) { Ptr = ptr; IndexInMainPool = -1; }
ImGuiTabBarRef(int index_in_main_pool) { Ptr = NULL; IndexInMainPool = index_in_main_pool; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -857,11 +891,21 @@ struct ImGuiContext
ImGuiNavMoveResult NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) ImGuiNavMoveResult NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag)
// Tabbing system (older than Nav, active even if Nav is disabled. FIXME-NAV: This needs a redesign!)
ImGuiWindow* FocusRequestCurrWindow; //
ImGuiWindow* FocusRequestNextWindow; //
int FocusRequestCurrCounterAll; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int FocusRequestCurrCounterTab; // Tab item being requested for focus, stored as an index
int FocusRequestNextCounterAll; // Stored for next frame
int FocusRequestNextCounterTab; // "
bool FocusTabPressed; //
// Render // Render
ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user
ImDrawDataBuilder DrawDataBuilder; ImDrawDataBuilder DrawDataBuilder;
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays ImDrawList BackgroundDrawList; // First draw list to be rendered.
ImDrawList ForegroundDrawList; // Last draw list to be rendered. This is where we the render software mouse cursor (if io.MouseDrawCursor is set) and most debug overlays.
ImGuiMouseCursor MouseCursor; ImGuiMouseCursor MouseCursor;
// Drag and Drop // Drag and Drop
@ -882,8 +926,9 @@ struct ImGuiContext
unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads
// Tab bars // Tab bars
ImPool<ImGuiTabBar> TabBars; ImPool<ImGuiTabBar> TabBars;
ImVector<ImGuiTabBar*> CurrentTabBar; ImGuiTabBar* CurrentTabBar;
ImVector<ImGuiTabBarRef> CurrentTabBarStack;
ImVector<ImGuiTabBarSortItem> TabSortByWidthBuffer; ImVector<ImGuiTabBarSortItem> TabSortByWidthBuffer;
// Widget state // Widget state
@ -916,10 +961,14 @@ struct ImGuiContext
// Logging // Logging
bool LogEnabled; bool LogEnabled;
ImGuiLogType LogType;
FILE* LogFile; // If != NULL log to stdout/ file FILE* LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogClipboard; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
int LogStartDepth; float LogLinePosY;
int LogAutoExpandMaxDepth; bool LogLineFirstItem;
int LogDepthRef;
int LogDepthToExpand;
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
// Misc // Misc
float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds.
@ -930,7 +979,7 @@ struct ImGuiContext
int WantTextInputNextFrame; int WantTextInputNextFrame;
char TempBuffer[1024*3+1]; // Temporary text buffer char TempBuffer[1024*3+1]; // Temporary text buffer
ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL) ImGuiContext(ImFontAtlas* shared_font_atlas) : BackgroundDrawList(NULL), ForegroundDrawList(NULL)
{ {
Initialized = false; Initialized = false;
FrameScopeActive = FrameScopePushedImplicitWindow = false; FrameScopeActive = FrameScopePushedImplicitWindow = false;
@ -997,9 +1046,16 @@ struct ImGuiContext
NavMoveRequestForward = ImGuiNavForward_None; NavMoveRequestForward = ImGuiNavForward_None;
NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None;
FocusRequestCurrWindow = FocusRequestNextWindow = NULL;
FocusRequestCurrCounterAll = FocusRequestCurrCounterTab = INT_MAX;
FocusRequestNextCounterAll = FocusRequestNextCounterTab = INT_MAX;
FocusTabPressed = false;
DimBgRatio = 0.0f; DimBgRatio = 0.0f;
OverlayDrawList._Data = &DrawListSharedData; BackgroundDrawList._Data = &DrawListSharedData;
OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging BackgroundDrawList._OwnerName = "##Background"; // Give it a name for debugging
ForegroundDrawList._Data = &DrawListSharedData;
ForegroundDrawList._OwnerName = "##Foreground"; // Give it a name for debugging
MouseCursor = ImGuiMouseCursor_Arrow; MouseCursor = ImGuiMouseCursor_Arrow;
DragDropActive = DragDropWithinSourceOrTarget = false; DragDropActive = DragDropWithinSourceOrTarget = false;
@ -1013,6 +1069,8 @@ struct ImGuiContext
DragDropAcceptFrameCount = -1; DragDropAcceptFrameCount = -1;
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
CurrentTabBar = NULL;
ScalarAsInputTextId = 0; ScalarAsInputTextId = 0;
ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault;
DragCurrentAccumDirty = false; DragCurrentAccumDirty = false;
@ -1029,9 +1087,12 @@ struct ImGuiContext
SettingsDirtyTimer = 0.0f; SettingsDirtyTimer = 0.0f;
LogEnabled = false; LogEnabled = false;
LogType = ImGuiLogType_None;
LogFile = NULL; LogFile = NULL;
LogStartDepth = 0; LogLinePosY = FLT_MAX;
LogAutoExpandMaxDepth = 2; LogLineFirstItem = false;
LogDepthRef = 0;
LogDepthToExpand = LogDepthToExpandDefault = 2;
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
FramerateSecPerFrameIdx = 0; FramerateSecPerFrameIdx = 0;
@ -1057,7 +1118,6 @@ struct IMGUI_API ImGuiWindowTempData
float CurrentLineTextBaseOffset; float CurrentLineTextBaseOffset;
ImVec2 PrevLineSize; ImVec2 PrevLineSize;
float PrevLineTextBaseOffset; float PrevLineTextBaseOffset;
float LogLinePosY;
int TreeDepth; int TreeDepth;
ImU32 TreeDepthMayJumpToParentOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 ImU32 TreeDepthMayJumpToParentOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31
ImGuiID LastItemId; ImGuiID LastItemId;
@ -1076,6 +1136,8 @@ struct IMGUI_API ImGuiWindowTempData
ImGuiStorage* StateStorage; ImGuiStorage* StateStorage;
ImGuiLayoutType LayoutType; ImGuiLayoutType LayoutType;
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
int FocusCounterAll; // Counter for focus/tabbing system. Start at -1 and increase as assigned via FocusableItemRegister() (FIXME-NAV: Needs redesign)
int FocusCounterTab; // (same, but only count widgets which you can Tab through)
// We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings.
ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default] ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default]
@ -1097,7 +1159,6 @@ struct IMGUI_API ImGuiWindowTempData
CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f);
CurrentLineSize = PrevLineSize = ImVec2(0.0f, 0.0f); CurrentLineSize = PrevLineSize = ImVec2(0.0f, 0.0f);
CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f;
LogLinePosY = -1.0f;
TreeDepth = 0; TreeDepth = 0;
TreeDepthMayJumpToParentOnPop = 0x00; TreeDepthMayJumpToParentOnPop = 0x00;
LastItemId = 0; LastItemId = 0;
@ -1112,8 +1173,10 @@ struct IMGUI_API ImGuiWindowTempData
MenuBarOffset = ImVec2(0.0f, 0.0f); MenuBarOffset = ImVec2(0.0f, 0.0f);
StateStorage = NULL; StateStorage = NULL;
LayoutType = ParentLayoutType = ImGuiLayoutType_Vertical; LayoutType = ParentLayoutType = ImGuiLayoutType_Vertical;
ItemWidth = 0.0f; FocusCounterAll = FocusCounterTab = -1;
ItemFlags = ImGuiItemFlags_Default_; ItemFlags = ImGuiItemFlags_Default_;
ItemWidth = 0.0f;
TextWrapPos = -1.0f; TextWrapPos = -1.0f;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
@ -1198,15 +1261,6 @@ struct IMGUI_API ImGuiWindow
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1) ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space
// Navigation / Focus
// FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext
int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through)
int FocusIdxAllRequestCurrent; // Item being requested for focus
int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus
int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame)
int FocusIdxTabRequestNext; // "
public: public:
ImGuiWindow(ImGuiContext* context, const char* name); ImGuiWindow(ImGuiContext* context, const char* name);
~ImGuiWindow(); ~ImGuiWindow();
@ -1245,7 +1299,7 @@ struct ImGuiItemHoveredDataBackup
enum ImGuiTabBarFlagsPrivate_ enum ImGuiTabBarFlagsPrivate_
{ {
ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node [we don't use this in the master branch but it facilitate branch syncing to keep this around]
ImGuiTabBarFlags_IsFocused = 1 << 21, ImGuiTabBarFlags_IsFocused = 1 << 21,
ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs
}; };
@ -1286,6 +1340,8 @@ struct ImGuiTabBar
float OffsetNextTab; // Distance from BarRect.Min.x, incremented with each BeginTabItem() call, not used if ImGuiTabBarFlags_Reorderable if set. float OffsetNextTab; // Distance from BarRect.Min.x, incremented with each BeginTabItem() call, not used if ImGuiTabBarFlags_Reorderable if set.
float ScrollingAnim; float ScrollingAnim;
float ScrollingTarget; float ScrollingTarget;
float ScrollingTargetDistToVisibility;
float ScrollingSpeed;
ImGuiTabBarFlags Flags; ImGuiTabBarFlags Flags;
ImGuiID ReorderRequestTabId; ImGuiID ReorderRequestTabId;
int ReorderRequestDir; int ReorderRequestDir;
@ -1376,7 +1432,7 @@ namespace ImGui
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL); IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id); // Return true if focus is requested
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
@ -1384,6 +1440,10 @@ namespace ImGui
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag(); IMGUI_API void PopItemFlag();
// Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
// Popups, Modals, Tooltips // Popups, Modals, Tooltips
IMGUI_API void OpenPopupEx(ImGuiID id); IMGUI_API void OpenPopupEx(ImGuiID id);
IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under); IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under);
@ -1459,12 +1519,13 @@ namespace ImGui
IMGUI_API void RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col); IMGUI_API void RenderPixelEllipsis(ImDrawList* draw_list, ImVec2 pos, int count, ImU32 col);
// Widgets // Widgets
IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0);
IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos);
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags); IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
IMGUI_API void Scrollbar(ImGuiLayoutType direction); IMGUI_API void Scrollbar(ImGuiAxis axis);
IMGUI_API ImGuiID GetScrollbarID(ImGuiLayoutType direction); IMGUI_API ImGuiID GetScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API void VerticalSeparator(); // 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. IMGUI_API void VerticalSeparator(); // 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.
// Widgets low-level behaviors // Widgets low-level behaviors
@ -1479,13 +1540,13 @@ namespace ImGui
// Template functions are instantiated in imgui_widgets.cpp for a finite number of types. // Template functions are instantiated in imgui_widgets.cpp for a finite number of types.
// To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036). // To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link to existing instances and silence Clang warnings (see #2036).
// e.g. " extern template IMGUI_API float RoundScalarWithFormatT<float, float>(const char* format, ImGuiDataType data_type, float v); " // e.g. " extern template IMGUI_API float RoundScalarWithFormatT<float, float>(const char* format, ImGuiDataType data_type, float v); "
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, const T v_min, const T v_max, const char* format, float power, ImGuiDragFlags flags); template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, float power, ImGuiDragFlags flags);
template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, const T v_min, const T v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb); template<typename T, typename SIGNED_T, typename FLOAT_T> IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, float power, ImGuiSliderFlags flags, ImRect* out_grab_bb);
template<typename T, typename FLOAT_T> IMGUI_API float SliderCalcRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float power, float linear_zero_pos); template<typename T, typename FLOAT_T> IMGUI_API float SliderCalcRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float power, float linear_zero_pos);
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
// InputText // InputText
IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); 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 InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
// Color // Color

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
#pragma once #pragma once
#include "../imgui/imgui.h" // IMGUI_API, ImFontAtlas #include "imgui.h" // IMGUI_API, ImFontAtlas
namespace ImGuiFreeType namespace ImGuiFreeType
{ {

View File

@ -15,6 +15,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-03-12: Misc: Preserve DisplayFramebufferScale when main window is minimized.
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
// 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them. // 2018-11-07: Inputs: When installing our GLFW callbacks, we save user's previously installed ones - if any - and chain call them.
// 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. // 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls.
@ -313,7 +314,8 @@ void ImGui_ImplGlfw_NewFrame()
glfwGetWindowSize(g_Window, &w, &h); glfwGetWindowSize(g_Window, &w, &h);
glfwGetFramebufferSize(g_Window, &display_w, &display_h); glfwGetFramebufferSize(g_Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h); io.DisplaySize = ImVec2((float)w, (float)h);
io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
// Setup time step // Setup time step
double current_time = glfwGetTime(); double current_time = glfwGetTime();

View File

@ -1,6 +1,7 @@
// dear imgui: Renderer for OpenGL3 / OpenGL ES2 / OpenGL ES3 (modern OpenGL with shaders / programmatic pipeline) // dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// (Note: We are using GL3W as a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc..)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
@ -11,10 +12,12 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2019-03-03: OpenGL: Fix support for ES 2.0 (WebGL 1.0).
// 2019-02-20: OpenGL: Fix for OSX not supporting OpenGL 4.5, we don't try to read GL_CLIP_ORIGIN even if defined by the headers/loader.
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display. // 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450). // 2019-02-01: OpenGL: Using GLSL 410 shaders for any version over 410 (e.g. 430, 450).
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
// 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT). // 2018-11-13: OpenGL: Support for GL 4.5's glClipControl(GL_UPPER_LEFT) / GL_CLIP_ORIGIN.
// 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used. // 2018-08-29: OpenGL: Added support for more OpenGL loaders: glew and glad, with comments indicative that any loader can be used.
// 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES". // 2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
// 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation. // 2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
@ -38,17 +41,17 @@
// version version string // version version string
//---------------------------------------- //----------------------------------------
// 2.0 110 "#version 110" // 2.0 110 "#version 110"
// 2.1 120 // 2.1 120 "#version 120"
// 3.0 130 // 3.0 130 "#version 130"
// 3.1 140 // 3.1 140 "#version 140"
// 3.2 150 "#version 150" // 3.2 150 "#version 150"
// 3.3 330 // 3.3 330 "#version 330 core"
// 4.0 400 // 4.0 400 "#version 400 core"
// 4.1 410 "#version 410 core" // 4.1 410 "#version 410 core"
// 4.2 420 // 4.2 420 "#version 410 core"
// 4.3 430 // 4.3 430 "#version 430 core"
// ES 2.0 100 "#version 100" // ES 2.0 100 "#version 100" = WebGL 1.0
// ES 3.0 300 "#version 300 es" // ES 3.0 300 "#version 300 es" = WebGL 2.0
//---------------------------------------- //----------------------------------------
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
@ -67,20 +70,24 @@
#include "TargetConditionals.h" #include "TargetConditionals.h"
#endif #endif
// iOS, Android and Emscripten can use GL ES 3 // Auto-detect GL version
// Call ImGui_ImplOpenGL3_Init() with "#version 300 es" #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && TARGET_OS_IOS) || (defined(__ANDROID__)) || (defined(__EMSCRIPTEN__)) #if (defined(__APPLE__) && TARGET_OS_IOS) || (defined(__ANDROID__))
#define USE_GL_ES3 #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
#elif defined(__EMSCRIPTEN__)
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
#endif
#endif #endif
#ifdef USE_GL_ES3 #if defined(IMGUI_IMPL_OPENGL_ES2)
// OpenGL ES 3 #include <GLES2/gl2.h>
#elif defined(IMGUI_IMPL_OPENGL_ES3)
#include <GLES3/gl3.h> // Use GL ES 3 #include <GLES3/gl3.h> // Use GL ES 3
#else #else
// Regular OpenGL // About Desktop OpenGL function loaders:
// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad. // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> #include <GL/gl3w.h>
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
@ -107,7 +114,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
io.BackendRendererName = "imgui_impl_opengl3"; io.BackendRendererName = "imgui_impl_opengl3";
// Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure. // Store GLSL version string so we can refer to it later in case we recreate shaders. Note: GLSL version is NOT the same as GL version. Leave this to NULL if unsure.
#ifdef USE_GL_ES3 #if defined(IMGUI_IMPL_OPENGL_ES2)
if (glsl_version == NULL)
glsl_version = "#version 100";
#elif defined(IMGUI_IMPL_OPENGL_ES3)
if (glsl_version == NULL) if (glsl_version == NULL)
glsl_version = "#version 300 es"; glsl_version = "#version 300 es";
#else #else
@ -152,7 +162,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
#endif #endif
GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#endif
#ifdef GL_POLYGON_MODE #ifdef GL_POLYGON_MODE
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
#endif #endif
@ -169,7 +181,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
bool clip_origin_lower_left = true; bool clip_origin_lower_left = true;
#ifdef GL_CLIP_ORIGIN #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT) GLenum last_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&last_clip_origin); // Support for GL 4.5's glClipControl(GL_UPPER_LEFT)
if (last_clip_origin == GL_UPPER_LEFT) if (last_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false; clip_origin_lower_left = false;
@ -206,11 +218,14 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#ifdef GL_SAMPLER_BINDING #ifdef GL_SAMPLER_BINDING
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif #endif
#ifndef IMGUI_IMPL_OPENGL_ES2
// Recreate the VAO every time // Recreate the VAO every time
// (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.)
GLuint vao_handle = 0; GLuint vao_handle = 0;
glGenVertexArrays(1, &vao_handle); glGenVertexArrays(1, &vao_handle);
glBindVertexArray(vao_handle); glBindVertexArray(vao_handle);
#endif
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glEnableVertexAttribArray(g_AttribLocationPosition); glEnableVertexAttribArray(g_AttribLocationPosition);
glEnableVertexAttribArray(g_AttribLocationUV); glEnableVertexAttribArray(g_AttribLocationUV);
@ -268,7 +283,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx); idx_buffer_offset += pcmd->ElemCount * sizeof(ImDrawIdx);
} }
} }
#ifndef IMGUI_IMPL_OPENGL_ES2
glDeleteVertexArrays(1, &vao_handle); glDeleteVertexArrays(1, &vao_handle);
#endif
// Restore modified GL state // Restore modified GL state
glUseProgram(last_program); glUseProgram(last_program);
@ -277,7 +294,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
glBindSampler(0, last_sampler); glBindSampler(0, last_sampler);
#endif #endif
glActiveTexture(last_active_texture); glActiveTexture(last_active_texture);
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array);
#endif
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha);
glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha);
@ -307,7 +326,9 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
glBindTexture(GL_TEXTURE_2D, g_FontTexture); glBindTexture(GL_TEXTURE_2D, g_FontTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#ifdef GL_UNPACK_ROW_LENGTH
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
#endif
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier // Store our identifier
@ -369,10 +390,13 @@ static bool CheckProgram(GLuint handle, const char* desc)
bool ImGui_ImplOpenGL3_CreateDeviceObjects() bool ImGui_ImplOpenGL3_CreateDeviceObjects()
{ {
// Backup GL state // Backup GL state
GLint last_texture, last_array_buffer, last_vertex_array; GLint last_texture, last_array_buffer;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
GLint last_vertex_array;
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
#endif
// Parse GLSL version string // Parse GLSL version string
int glsl_version = 130; int glsl_version = 130;
@ -536,7 +560,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
// Restore modified GL state // Restore modified GL state
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_ES2
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array);
#endif
return true; return true;
} }

View File

@ -1,6 +1,7 @@
// dear imgui: Renderer for OpenGL3 / OpenGL ES2 / OpenGL ES3 (modern OpenGL with shaders / programmatic pipeline) // dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
// - Desktop GL: 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..) // This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
// (Note: We are using GL3W as a helper library to access OpenGL functions since there is no standard header to access modern OpenGL functions easily. Alternatives are GLEW, Glad, etc..)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp.
@ -9,19 +10,23 @@
// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
// https://github.com/ocornut/imgui // https://github.com/ocornut/imgui
// About OpenGL function loaders: // About Desktop OpenGL function loaders:
// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually. // Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad. // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
// About GLSL version: // About GLSL version:
// The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string. // The 'glsl_version' initialization parameter should be NULL (default) or a "#version XXX" string.
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es" // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp. // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
#pragma once #pragma once
// Set default OpenGL loader to be gl3w // Specific OpenGL versions
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
// Set default OpenGL3 loader to be gl3w
#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ #if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
&& !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \