Renamed majority of use of "opened" to "open" for clarity. Renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(). (#625, #579)

This commit is contained in:
ocornut 2016-05-02 12:32:16 +02:00
parent 1b9894cfb4
commit 89d5026187
4 changed files with 183 additions and 182 deletions

235
imgui.cpp
View File

@ -53,7 +53,7 @@
============== ==============
- double-click title bar to collapse window - double-click title bar to collapse window
- click upper right corner to close a window, available when 'bool* p_opened' is passed to ImGui::Begin() - click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin()
- click and drag on lower right corner to resize window - click and drag on lower right corner to resize window
- click and drag on any empty space to move window - click and drag on any empty space to move window
- double-click/double-tap on lower right corner grip to auto-fit to content - double-click/double-tap on lower right corner grip to auto-fit to content
@ -152,6 +152,7 @@
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
Also read releases logs https://github.com/ocornut/imgui/releases for more details. Also read releases logs https://github.com/ocornut/imgui/releases for more details.
- 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection.
- 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen). - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen).
- 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer. - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer.
- 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337). - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
@ -196,7 +197,7 @@
- 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete). - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
- 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete). - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
- 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
- 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "opened" state of a popup. BeginPopup() returns true if the popup is opened. - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened.
- 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
- 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete).
- 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
@ -365,7 +366,7 @@
TreePop(); TreePop();
} }
- When working with trees, ID are used to preserve the opened/closed state of each tree node. - When working with trees, ID are used to preserve the open/close state of each tree node.
Depending on your use cases you may want to use strings, indices or pointers as ID. Depending on your use cases you may want to use strings, indices or pointers as ID.
e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change. e.g. when displaying a single object that may change over time (1-1 relationship), using a static string as ID will preserve your node open/closed state when the targeted object change.
e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense!
@ -444,7 +445,7 @@
- window: background options for child windows, border option (disable rounding) - window: background options for child windows, border option (disable rounding)
- window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip) - window: add a way to clear an existing window instead of appending (e.g. for tooltip override using a consistent api rather than the deferred tooltip)
- window: resizing from any sides? + mouse cursor directives for app. - window: resizing from any sides? + mouse cursor directives for app.
!- window: begin with *p_opened == false should return false. !- window: begin with *p_open == false should return false.
- window: get size/pos helpers given names (see discussion in #249) - window: get size/pos helpers given names (see discussion in #249)
- window: a collapsed window can be stuck behind the main menu bar? - window: a collapsed window can be stuck behind the main menu bar?
- window: when window is small, prioritize resize button over close button. - window: when window is small, prioritize resize button over close button.
@ -2032,7 +2033,7 @@ void ImGui::NewFrame()
for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
{ {
if (g.IO.MouseClicked[i]) if (g.IO.MouseClicked[i])
g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenedPopupStack.empty()); g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
mouse_any_down |= g.IO.MouseDown[i]; mouse_any_down |= g.IO.MouseDown[i];
if (g.IO.MouseDown[i]) if (g.IO.MouseDown[i])
if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i]) if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[mouse_earliest_button_down] > g.IO.MouseClickedTime[i])
@ -2042,7 +2043,7 @@ void ImGui::NewFrame()
if (g.CaptureMouseNextFrame != -1) if (g.CaptureMouseNextFrame != -1)
g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0); g.IO.WantCaptureMouse = (g.CaptureMouseNextFrame != 0);
else else
g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenedPopupStack.empty()); g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.ActiveId != 0) || (!g.OpenPopupStack.empty());
g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0); g.IO.WantCaptureKeyboard = (g.CaptureKeyboardNextFrame != -1) ? (g.CaptureKeyboardNextFrame != 0) : (g.ActiveId != 0);
g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId); g.IO.WantTextInput = (g.ActiveId != 0 && g.InputTextState.Id == g.ActiveId);
g.MouseCursor = ImGuiMouseCursor_Arrow; g.MouseCursor = ImGuiMouseCursor_Arrow;
@ -2141,7 +2142,7 @@ void ImGui::Shutdown()
g.ColorModifiers.clear(); g.ColorModifiers.clear();
g.StyleModifiers.clear(); g.StyleModifiers.clear();
g.FontStack.clear(); g.FontStack.clear();
g.OpenedPopupStack.clear(); g.OpenPopupStack.clear();
g.CurrentPopupStack.clear(); g.CurrentPopupStack.clear();
for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) for (int i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++)
g.RenderDrawLists[i].clear(); g.RenderDrawLists[i].clear();
@ -2712,7 +2713,7 @@ void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border,
} }
// Render a triangle to denote expanded/collapsed state // Render a triangle to denote expanded/collapsed state
void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool shadow) void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool is_open, float scale, bool shadow)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
@ -2722,7 +2723,7 @@ void ImGui::RenderCollapseTriangle(ImVec2 p_min, bool opened, float scale, bool
ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale); ImVec2 center = p_min + ImVec2(h*0.50f, h*0.50f*scale);
ImVec2 a, b, c; ImVec2 a, b, c;
if (opened) if (is_open)
{ {
center.y -= r*0.25f; center.y -= r*0.25f;
a = center + ImVec2(0,1)*r; a = center + ImVec2(0,1)*r;
@ -2994,7 +2995,7 @@ ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup()
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
if (g.CurrentPopupStack.Size > 0) if (g.CurrentPopupStack.Size > 0)
return g.OpenedPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen; return g.OpenPopupStack[g.CurrentPopupStack.Size-1].MousePosOnOpen;
return g.IO.MousePos; return g.IO.MousePos;
} }
@ -3157,8 +3158,8 @@ void ImGui::EndTooltip()
static bool IsPopupOpen(ImGuiID id) static bool IsPopupOpen(ImGuiID id)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
const bool opened = g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].PopupID == id; const bool is_open = g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupID == id;
return opened; return is_open;
} }
// Mark popup as open (toggle toward open state). // Mark popup as open (toggle toward open state).
@ -3172,12 +3173,12 @@ void ImGui::OpenPopupEx(const char* str_id, bool reopen_existing)
ImGuiID id = window->GetID(str_id); ImGuiID id = window->GetID(str_id);
int current_stack_size = g.CurrentPopupStack.Size; int current_stack_size = g.CurrentPopupStack.Size;
ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here) ImGuiPopupRef popup_ref = ImGuiPopupRef(id, window, window->GetID("##menus"), g.IO.MousePos); // Tagged as new ref because constructor sets Window to NULL (we are passing the ParentWindow info here)
if (g.OpenedPopupStack.Size < current_stack_size + 1) if (g.OpenPopupStack.Size < current_stack_size + 1)
g.OpenedPopupStack.push_back(popup_ref); g.OpenPopupStack.push_back(popup_ref);
else if (reopen_existing || g.OpenedPopupStack[current_stack_size].PopupID != id) else if (reopen_existing || g.OpenPopupStack[current_stack_size].PopupID != id)
{ {
g.OpenedPopupStack.resize(current_stack_size+1); g.OpenPopupStack.resize(current_stack_size+1);
g.OpenedPopupStack[current_stack_size] = popup_ref; g.OpenPopupStack[current_stack_size] = popup_ref;
} }
} }
@ -3189,7 +3190,7 @@ void ImGui::OpenPopup(const char* str_id)
static void CloseInactivePopups() static void CloseInactivePopups()
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
if (g.OpenedPopupStack.empty()) if (g.OpenPopupStack.empty())
return; return;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
@ -3197,9 +3198,9 @@ static void CloseInactivePopups()
int n = 0; int n = 0;
if (g.FocusedWindow) if (g.FocusedWindow)
{ {
for (n = 0; n < g.OpenedPopupStack.Size; n++) for (n = 0; n < g.OpenPopupStack.Size; n++)
{ {
ImGuiPopupRef& popup = g.OpenedPopupStack[n]; ImGuiPopupRef& popup = g.OpenPopupStack[n];
if (!popup.Window) if (!popup.Window)
continue; continue;
IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0);
@ -3207,21 +3208,21 @@ static void CloseInactivePopups()
continue; continue;
bool has_focus = false; bool has_focus = false;
for (int m = n; m < g.OpenedPopupStack.Size && !has_focus; m++) for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++)
has_focus = (g.OpenedPopupStack[m].Window && g.OpenedPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow); has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == g.FocusedWindow->RootWindow);
if (!has_focus) if (!has_focus)
break; break;
} }
} }
if (n < g.OpenedPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a useful breakpoint on the line below
g.OpenedPopupStack.resize(n); g.OpenPopupStack.resize(n);
} }
static ImGuiWindow* GetFrontMostModalRootWindow() static ImGuiWindow* GetFrontMostModalRootWindow()
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
for (int n = g.OpenedPopupStack.Size-1; n >= 0; n--) for (int n = g.OpenPopupStack.Size-1; n >= 0; n--)
if (ImGuiWindow* front_most_popup = g.OpenedPopupStack.Data[n].Window) if (ImGuiWindow* front_most_popup = g.OpenPopupStack.Data[n].Window)
if (front_most_popup->Flags & ImGuiWindowFlags_Modal) if (front_most_popup->Flags & ImGuiWindowFlags_Modal)
return front_most_popup; return front_most_popup;
return NULL; return NULL;
@ -3231,10 +3232,10 @@ static void ClosePopupToLevel(int remaining)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
if (remaining > 0) if (remaining > 0)
ImGui::FocusWindow(g.OpenedPopupStack[remaining-1].Window); ImGui::FocusWindow(g.OpenPopupStack[remaining-1].Window);
else else
ImGui::FocusWindow(g.OpenedPopupStack[0].ParentWindow); ImGui::FocusWindow(g.OpenPopupStack[0].ParentWindow);
g.OpenedPopupStack.resize(remaining); g.OpenPopupStack.resize(remaining);
} }
static void ClosePopup(ImGuiID id) static void ClosePopup(ImGuiID id)
@ -3242,7 +3243,7 @@ static void ClosePopup(ImGuiID id)
if (!IsPopupOpen(id)) if (!IsPopupOpen(id))
return; return;
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
ClosePopupToLevel(g.OpenedPopupStack.Size - 1); ClosePopupToLevel(g.OpenPopupStack.Size - 1);
} }
// Close the popup we have begin-ed into. // Close the popup we have begin-ed into.
@ -3250,9 +3251,9 @@ void ImGui::CloseCurrentPopup()
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
int popup_idx = g.CurrentPopupStack.Size - 1; int popup_idx = g.CurrentPopupStack.Size - 1;
if (popup_idx < 0 || popup_idx > g.OpenedPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupID != g.OpenedPopupStack[popup_idx].PopupID) if (popup_idx < 0 || popup_idx > g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupID != g.OpenPopupStack[popup_idx].PopupID)
return; return;
while (popup_idx > 0 && g.OpenedPopupStack[popup_idx].Window && (g.OpenedPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu))
popup_idx--; popup_idx--;
ClosePopupToLevel(popup_idx); ClosePopupToLevel(popup_idx);
} }
@ -3284,18 +3285,18 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
else else
ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame
bool opened = ImGui::Begin(name, NULL, flags); bool is_open = ImGui::Begin(name, NULL, flags);
if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders;
if (!opened) // opened can be 'false' when the popup is completely clipped (e.g. zero size display) if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
ImGui::EndPopup(); ImGui::EndPopup();
return opened; return is_open;
} }
bool ImGui::BeginPopup(const char* str_id) bool ImGui::BeginPopup(const char* str_id)
{ {
if (GImGui->OpenedPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance if (GImGui->OpenPopupStack.Size <= GImGui->CurrentPopupStack.Size) // Early out for performance
{ {
ClearSetNextWindowData(); // We behave like Begin() and need to consume those values ClearSetNextWindowData(); // We behave like Begin() and need to consume those values
return false; return false;
@ -3303,7 +3304,7 @@ bool ImGui::BeginPopup(const char* str_id)
return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders); return BeginPopupEx(str_id, ImGuiWindowFlags_ShowBorders);
} }
bool ImGui::BeginPopupModal(const char* name, bool* p_opened, ImGuiWindowFlags extra_flags) bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags extra_flags)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
@ -3315,16 +3316,16 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_opened, ImGuiWindowFlags e
} }
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings;
bool opened = ImGui::Begin(name, p_opened, flags); bool is_open = ImGui::Begin(name, p_open, flags);
if (!opened || (p_opened && !*p_opened)) // Opened can be 'false' when the popup is completely clipped (e.g. zero size display) if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
{ {
ImGui::EndPopup(); ImGui::EndPopup();
if (opened) if (is_open)
ClosePopup(id); ClosePopup(id);
return false; return false;
} }
return opened; return is_open;
} }
void ImGui::EndPopup() void ImGui::EndPopup()
@ -3583,14 +3584,14 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
// - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file). // - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file).
// You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file. // You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file.
// - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned. // - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned.
// - Passing 'bool* p_opened' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. // - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
// - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin(). // - Passing non-zero 'size' is roughly equivalent to calling SetNextWindowSize(size, ImGuiSetCond_FirstUseEver) prior to calling Begin().
bool ImGui::Begin(const char* name, bool* p_opened, ImGuiWindowFlags flags) bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{ {
return ImGui::Begin(name, p_opened, ImVec2(0.f, 0.f), -1.0f, flags); return ImGui::Begin(name, p_open, ImVec2(0.f, 0.f), -1.0f, flags);
} }
bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags) bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha, ImGuiWindowFlags flags)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
@ -3627,7 +3628,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
bool window_was_active = (window->LastFrameActive == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on bool window_was_active = (window->LastFrameActive == current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
if (flags & ImGuiWindowFlags_Popup) if (flags & ImGuiWindowFlags_Popup)
{ {
ImGuiPopupRef& popup_ref = g.OpenedPopupStack[g.CurrentPopupStack.Size]; ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size];
window_was_active &= (window->PopupID == popup_ref.PopupID); window_was_active &= (window->PopupID == popup_ref.PopupID);
window_was_active &= (window == popup_ref.Window); window_was_active &= (window == popup_ref.Window);
popup_ref.Window = window; popup_ref.Window = window;
@ -4085,12 +4086,12 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
// Title bar // Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar)) if (!(flags & ImGuiWindowFlags_NoTitleBar))
{ {
if (p_opened != NULL) if (p_open != NULL)
{ {
const float pad = 2.0f; const float pad = 2.0f;
const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f; const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f;
if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad)) if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad))
*p_opened = false; *p_open = false;
} }
const ImVec2 text_size = CalcTextSize(name, NULL, true); const ImVec2 text_size = CalcTextSize(name, NULL, true);
@ -4099,9 +4100,9 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
ImVec2 text_min = window->Pos + style.FramePadding; ImVec2 text_min = window->Pos + style.FramePadding;
ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y); ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y);
ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_opened ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton() ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton()
bool pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0; bool pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0;
bool pad_right = (p_opened != NULL); bool pad_right = (p_open != NULL);
if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left; if (style.WindowTitleAlign & ImGuiAlign_Center) pad_right = pad_left;
if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x; if (pad_left) text_min.x += g.FontSize + style.ItemInnerSpacing.x;
if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x; if (pad_right) text_max.x -= g.FontSize + style.ItemInnerSpacing.x;
@ -5598,7 +5599,7 @@ void ImGui::LogButtons()
LogToClipboard(g.LogAutoExpandMaxDepth); LogToClipboard(g.LogAutoExpandMaxDepth);
} }
bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags) bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags)
{ {
if (flags & ImGuiTreeNodeFlags_AlwaysOpen) if (flags & ImGuiTreeNodeFlags_AlwaysOpen)
return true; return true;
@ -5608,13 +5609,13 @@ bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags)
ImGuiWindow* window = g.CurrentWindow; ImGuiWindow* window = g.CurrentWindow;
ImGuiStorage* storage = window->DC.StateStorage; ImGuiStorage* storage = window->DC.StateStorage;
bool opened; bool is_open;
if (g.SetNextTreeNodeOpenedCond != 0) if (g.SetNextTreeNodeOpenCond != 0)
{ {
if (g.SetNextTreeNodeOpenedCond & ImGuiSetCond_Always) if (g.SetNextTreeNodeOpenCond & ImGuiSetCond_Always)
{ {
opened = g.SetNextTreeNodeOpenedVal; is_open = g.SetNextTreeNodeOpenVal;
storage->SetInt(id, opened); storage->SetInt(id, is_open);
} }
else else
{ {
@ -5622,27 +5623,27 @@ bool ImGui::TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags)
const int stored_value = storage->GetInt(id, -1); const int stored_value = storage->GetInt(id, -1);
if (stored_value == -1) if (stored_value == -1)
{ {
opened = g.SetNextTreeNodeOpenedVal; is_open = g.SetNextTreeNodeOpenVal;
storage->SetInt(id, opened); storage->SetInt(id, is_open);
} }
else else
{ {
opened = stored_value != 0; is_open = stored_value != 0;
} }
} }
g.SetNextTreeNodeOpenedCond = 0; g.SetNextTreeNodeOpenCond = 0;
} }
else else
{ {
opened = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0; is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0;
} }
// When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). // When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior).
// NB- If we are above max depth we still allow manually opened nodes to be logged. // NB- If we are above max depth we still allow manually opened nodes to be logged.
if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth)
opened = true; is_open = true;
return opened; return is_open;
} }
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
@ -5678,12 +5679,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
// (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not) // (Ideally we'd want to add a flag for the user to specify we want want the hit test to be done up to the right side of the content or not)
const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y); const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y);
bool opened = TreeNodeBehaviorIsOpened(id, flags); bool is_open = TreeNodeBehaviorIsOpen(id, flags);
if (!ItemAdd(interact_bb, &id)) if (!ItemAdd(interact_bb, &id))
{ {
if (opened && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
TreePushRawID(id); TreePushRawID(id);
return opened; return is_open;
} }
// Flags that affects opening behavior: // Flags that affects opening behavior:
@ -5704,8 +5705,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
toggled |= g.IO.MouseDoubleClicked[0]; toggled |= g.IO.MouseDoubleClicked[0];
if (toggled) if (toggled)
{ {
opened = !opened; is_open = !is_open;
window->DC.StateStorage->SetInt(id, opened); window->DC.StateStorage->SetInt(id, is_open);
} }
} }
if (flags & ImGuiTreeNodeFlags_AllowOverlapMode) if (flags & ImGuiTreeNodeFlags_AllowOverlapMode)
@ -5718,7 +5719,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
{ {
// Framed type // Framed type
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), opened, 1.0f, true); RenderCollapseTriangle(bb.Min + padding + ImVec2(0.0f, text_base_offset_y), is_open, 1.0f, true);
if (g.LogEnabled) if (g.LogEnabled)
{ {
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
@ -5742,15 +5743,15 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
if (flags & ImGuiTreeNodeFlags_AlwaysOpen) if (flags & ImGuiTreeNodeFlags_AlwaysOpen)
RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y)); RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
else else
RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), opened, 0.70f, false); RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f, false);
if (g.LogEnabled) if (g.LogEnabled)
LogRenderedText(text_pos, ">"); LogRenderedText(text_pos, ">");
RenderText(text_pos, label, label_end, false); RenderText(text_pos, label, label_end, false);
} }
if (opened && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
TreePushRawID(id); TreePushRawID(id);
return opened; return is_open;
} }
bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags)
@ -5772,7 +5773,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
return false; return false;
ImGuiID id = window->GetID(label); ImGuiID id = window->GetID(label);
bool opened = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label); bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowOverlapMode : 0), label);
if (p_open) if (p_open)
{ {
// Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
@ -5782,7 +5783,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
*p_open = false; *p_open = false;
} }
return opened; return is_open;
} }
bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags)
@ -5830,36 +5831,36 @@ bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char*
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
bool opened = TreeNodeExV(str_id, flags, fmt, args); bool is_open = TreeNodeExV(str_id, flags, fmt, args);
va_end(args); va_end(args);
return opened; return is_open;
} }
bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
bool opened = TreeNodeExV(ptr_id, flags, fmt, args); bool is_open = TreeNodeExV(ptr_id, flags, fmt, args);
va_end(args); va_end(args);
return opened; return is_open;
} }
bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) bool ImGui::TreeNode(const char* str_id, const char* fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
bool opened = TreeNodeExV(str_id, 0, fmt, args); bool is_open = TreeNodeExV(str_id, 0, fmt, args);
va_end(args); va_end(args);
return opened; return is_open;
} }
bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...)
{ {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
bool opened = TreeNodeExV(ptr_id, 0, fmt, args); bool is_open = TreeNodeExV(ptr_id, 0, fmt, args);
va_end(args); va_end(args);
return opened; return is_open;
} }
bool ImGui::TreeNode(const char* label) bool ImGui::TreeNode(const char* label)
@ -5882,11 +5883,11 @@ float ImGui::GetTreeNodeToLabelSpacing(ImGuiTreeNodeFlags flags)
return off_from_start; return off_from_start;
} }
void ImGui::SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond) void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond)
{ {
ImGuiState& g = *GImGui; ImGuiState& g = *GImGui;
g.SetNextTreeNodeOpenedVal = opened; g.SetNextTreeNodeOpenVal = is_open;
g.SetNextTreeNodeOpenedCond = cond ? cond : ImGuiSetCond_Always; g.SetNextTreeNodeOpenCond = cond ? cond : ImGuiSetCond_Always;
} }
void ImGui::PushID(const char* str_id) void ImGui::PushID(const char* str_id)
@ -8171,12 +8172,12 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f); const float arrow_size = (g.FontSize + style.FramePadding.x * 2.0f);
const bool hovered = IsHovered(frame_bb, id); const bool hovered = IsHovered(frame_bb, id);
bool popup_opened = IsPopupOpen(id); bool popup_open = IsPopupOpen(id);
bool popup_opened_now = false; bool popup_opened_now = false;
const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f));
RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding);
RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_opened || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING
RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true); RenderCollapseTriangle(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y) + style.FramePadding, true);
if (*current_item >= 0 && *current_item < items_count) if (*current_item >= 0 && *current_item < items_count)
@ -8203,7 +8204,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
{ {
FocusWindow(window); FocusWindow(window);
OpenPopup(label); OpenPopup(label);
popup_opened = popup_opened_now = true; popup_open = popup_opened_now = true;
} }
} }
} }
@ -8555,9 +8556,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
ImGuiWindow* backed_focused_window = g.FocusedWindow; ImGuiWindow* backed_focused_window = g.FocusedWindow;
bool pressed; bool pressed;
bool opened = IsPopupOpen(id); bool menu_is_open = IsPopupOpen(id);
bool menuset_opened = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus")); bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentMenuSet == window->GetID("##menus"));
if (menuset_opened) if (menuset_is_open)
g.FocusedWindow = window; g.FocusedWindow = window;
ImVec2 popup_pos, pos = window->DC.CursorPos; ImVec2 popup_pos, pos = window->DC.CursorPos;
@ -8567,7 +8568,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f);
float w = label_size.x; float w = label_size.x;
pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); pressed = ImGui::Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
ImGui::PopStyleVar(); ImGui::PopStyleVar();
ImGui::SameLine(); ImGui::SameLine();
window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f);
@ -8577,14 +8578,14 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame
float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w); float extra_w = ImMax(0.0f, ImGui::GetContentRegionAvail().x - w);
pressed = ImGui::Selectable(label, opened, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); pressed = ImGui::Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f));
if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); if (!enabled) ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false); RenderCollapseTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.20f, 0.0f), false);
if (!enabled) ImGui::PopStyleColor(); if (!enabled) ImGui::PopStyleColor();
} }
bool hovered = enabled && IsHovered(window->DC.LastItemRect, id); bool hovered = enabled && IsHovered(window->DC.LastItemRect, id);
if (menuset_opened) if (menuset_is_open)
g.FocusedWindow = backed_focused_window; g.FocusedWindow = backed_focused_window;
bool want_open = false, want_close = false; bool want_open = false, want_close = false;
@ -8592,9 +8593,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
{ {
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_within_opened_triangle = false; bool moving_within_opened_triangle = false;
if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window) if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window)
{ {
if (ImGuiWindow* next_window = g.OpenedPopupStack[g.CurrentPopupStack.Size].Window) if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window)
{ {
ImRect next_window_rect = next_window->Rect(); ImRect next_window_rect = next_window->Rect();
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
@ -8609,39 +8610,39 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
} }
} }
want_close = (opened && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
want_open = (!opened && hovered && !moving_within_opened_triangle) || (!opened && hovered && pressed); want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
} }
else if (opened && pressed && menuset_opened) // menu-bar: click open menu to close else if (menu_is_open && pressed && menuset_is_open) // menu-bar: click open menu to close
{ {
want_close = true; want_close = true;
want_open = opened = false; want_open = menu_is_open = false;
} }
else if (pressed || (hovered && menuset_opened && !opened)) // menu-bar: first click to open, then hover to open others else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // menu-bar: first click to open, then hover to open others
want_open = true; want_open = true;
if (want_close && IsPopupOpen(id)) if (want_close && IsPopupOpen(id))
ClosePopupToLevel(GImGui->CurrentPopupStack.Size); ClosePopupToLevel(GImGui->CurrentPopupStack.Size);
if (!opened && want_open && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size) if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size)
{ {
// Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame.
ImGui::OpenPopup(label); ImGui::OpenPopup(label);
return false; return false;
} }
opened |= want_open; menu_is_open |= want_open;
if (want_open) if (want_open)
ImGui::OpenPopup(label); ImGui::OpenPopup(label);
if (opened) if (menu_is_open)
{ {
ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always); ImGui::SetNextWindowPos(popup_pos, ImGuiSetCond_Always);
ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu);
opened = BeginPopupEx(label, flags); // opened can be 'false' when the popup is completely clipped (e.g. zero size display) menu_is_open = BeginPopupEx(label, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
} }
return opened; return menu_is_open;
} }
void ImGui::EndMenu() void ImGui::EndMenu()
@ -9399,9 +9400,9 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {}
// HELP // HELP
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ImGui::ShowMetricsWindow(bool* opened) void ImGui::ShowMetricsWindow(bool* p_open)
{ {
if (ImGui::Begin("ImGui Metrics", opened)) if (ImGui::Begin("ImGui Metrics", p_open))
{ {
ImGui::Text("ImGui %s", ImGui::GetVersion()); ImGui::Text("ImGui %s", ImGui::GetVersion());
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
@ -9415,15 +9416,15 @@ void ImGui::ShowMetricsWindow(bool* opened)
{ {
static void NodeDrawList(ImDrawList* draw_list, const char* label) static void NodeDrawList(ImDrawList* draw_list, const char* label)
{ {
bool node_opened = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size); bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);
if (draw_list == ImGui::GetWindowDrawList()) if (draw_list == ImGui::GetWindowDrawList())
{ {
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered)
if (node_opened) ImGui::TreePop(); if (node_open) ImGui::TreePop();
return; return;
} }
if (!node_opened) if (!node_open)
return; return;
ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list
@ -9436,7 +9437,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData);
continue; continue;
} }
bool draw_opened = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); bool node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %-4d %s vtx, tex = %p, clip_rect = (%.0f,%.0f)..(%.0f,%.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
if (show_clip_rects && ImGui::IsItemHovered()) if (show_clip_rects && ImGui::IsItemHovered())
{ {
ImRect clip_rect = pcmd->ClipRect; ImRect clip_rect = pcmd->ClipRect;
@ -9447,7 +9448,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255)); clip_rect.Floor(); overlay_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(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255));
} }
if (!draw_opened) if (!node_open)
continue; continue;
for (int i = elem_offset; i+2 < elem_offset + (int)pcmd->ElemCount; i += 3) for (int i = elem_offset; i+2 < elem_offset + (int)pcmd->ElemCount; i += 3)
{ {
@ -9498,12 +9499,12 @@ void ImGui::ShowMetricsWindow(bool* opened)
Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList"); Funcs::NodeDrawList(g.RenderDrawLists[0][i], "DrawList");
ImGui::TreePop(); ImGui::TreePop();
} }
if (ImGui::TreeNode("Popups", "Opened Popups Stack (%d)", g.OpenedPopupStack.Size)) if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size))
{ {
for (int i = 0; i < g.OpenedPopupStack.Size; i++) for (int i = 0; i < g.OpenPopupStack.Size; i++)
{ {
ImGuiWindow* window = g.OpenedPopupStack[i].Window; ImGuiWindow* window = g.OpenPopupStack[i].Window;
ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenedPopupStack[i].PopupID, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupID, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : "");
} }
ImGui::TreePop(); ImGui::TreePop();
} }

30
imgui.h
View File

@ -110,15 +110,15 @@ namespace ImGui
IMGUI_API void Shutdown(); IMGUI_API void Shutdown();
IMGUI_API void ShowUserGuide(); // help block IMGUI_API void ShowUserGuide(); // help block
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // style editor block
IMGUI_API void ShowTestWindow(bool* opened = NULL); // test window demonstrating ImGui features IMGUI_API void ShowTestWindow(bool* p_open = NULL); // test window demonstrating ImGui features
IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window for debugging ImGui IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // metrics window for debugging ImGui
// Window // Window
IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false). IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false).
IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually. IMGUI_API bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually.
IMGUI_API void End(); // finish appending to current window, pop it off the window stack. IMGUI_API void End(); // finish appending to current window, pop it off the window stack.
IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400).
IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // " IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // "
IMGUI_API void EndChild(); IMGUI_API void EndChild();
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()
@ -320,7 +320,7 @@ namespace ImGui
IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layout purpose IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layout purpose
IMGUI_API void TreePush(const void* ptr_id = NULL); // " IMGUI_API void TreePush(const void* ptr_id = NULL); // "
IMGUI_API void TreePop(); IMGUI_API void TreePop();
IMGUI_API void SetNextTreeNodeOpened(bool opened, ImGuiSetCond cond = 0); // set next tree node/collapsing header to be opened. IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond = 0); // set next TreeNode/CollapsingHeader open state.
IMGUI_API float GetTreeNodeToLabelSpacing(ImGuiTreeNodeFlags flags = 0); // return horizontal distance between cursor and text label due to collapsing node. == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode IMGUI_API float GetTreeNodeToLabelSpacing(ImGuiTreeNodeFlags flags = 0); // return horizontal distance between cursor and text label due to collapsing node. == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. user doesn't have to call TreePop(). IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. user doesn't have to call TreePop().
IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
@ -360,15 +360,15 @@ namespace ImGui
// Popups // Popups
IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true! IMGUI_API bool BeginPopup(const char* str_id); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returned true!
IMGUI_API bool BeginPopupModal(const char* name, bool* p_opened = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside) IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags extra_flags = 0); // modal dialog (can't close them by clicking outside)
IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp! IMGUI_API bool BeginPopupContextItem(const char* str_id, int mouse_button = 1); // helper to open and begin popup when clicked on last item. read comments in .cpp!
IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window. IMGUI_API bool BeginPopupContextWindow(bool also_over_items = true, const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on current window.
IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window). IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (no window).
IMGUI_API void EndPopup(); IMGUI_API void EndPopup();
IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup.
// Logging: all text output from interface is redirected to tty/file/clipboard. Tree nodes are automatically opened. // Logging: all text output from interface is redirected to tty/file/clipboard. By default, tree nodes are automatically opened during logging.
IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file IMGUI_API void LogToFile(int max_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 max_depth = -1); // start logging to OS clipboard
@ -453,7 +453,7 @@ namespace ImGui
static inline bool CollapsingHeader(const char* label, const char* str_id, bool display_frame = true, bool default_open = false) { (void)str_id; (void)display_frame; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline bool CollapsingHeader(const char* label, const char* str_id, bool display_frame = true, bool default_open = false) { (void)str_id; (void)display_frame; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+
static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+
static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+
static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpened(open, 0); } // OBSOLETE 1.34+ static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpen(open, 0); } // OBSOLETE 1.34+
static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+ static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+
static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+
static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+ static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+
@ -528,15 +528,15 @@ enum ImGuiTreeNodeFlags_
ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected
ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader)
ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one ImGuiTreeNodeFlags_AllowOverlapMode = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one
ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when opened (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack
ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes)
ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be opened ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open
ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node
ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open.
ImGuiTreeNodeFlags_AlwaysOpen = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_AlwaysOpen = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes).
//ImGuiTreeNodeFlags_UnindentArrow = 1 << 9, // FIXME: TODO: Unindent tree so that Label is aligned to current X position //ImGuiTreeNodeFlags_UnindentArrow = 1 << 9, // FIXME: TODO: Unindent tree so that Label is aligned to current X position
//ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 10, // FIXME: TODO: Extend hit box horizontally even if not framed
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Automatically scroll on TreePop() if node got just opened and contents is not visible //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 11, // FIXME: TODO: Automatically scroll on TreePop() if node got just open and contents is not visible
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog
}; };

View File

@ -49,15 +49,15 @@
#ifndef IMGUI_DISABLE_TEST_WINDOWS #ifndef IMGUI_DISABLE_TEST_WINDOWS
static void ShowExampleAppConsole(bool* opened); static void ShowExampleAppConsole(bool* p_open);
static void ShowExampleAppLog(bool* opened); static void ShowExampleAppLog(bool* p_open);
static void ShowExampleAppLayout(bool* opened); static void ShowExampleAppLayout(bool* p_open);
static void ShowExampleAppPropertyEditor(bool* opened); static void ShowExampleAppPropertyEditor(bool* p_open);
static void ShowExampleAppLongText(bool* opened); static void ShowExampleAppLongText(bool* p_open);
static void ShowExampleAppAutoResize(bool* opened); static void ShowExampleAppAutoResize(bool* p_open);
static void ShowExampleAppFixedOverlay(bool* opened); static void ShowExampleAppFixedOverlay(bool* p_open);
static void ShowExampleAppManipulatingWindowTitle(bool* opened); static void ShowExampleAppManipulatingWindowTitle(bool* p_open);
static void ShowExampleAppCustomRendering(bool* opened); static void ShowExampleAppCustomRendering(bool* p_open);
static void ShowExampleAppMainMenuBar(); static void ShowExampleAppMainMenuBar();
static void ShowExampleMenuFile(); static void ShowExampleMenuFile();
@ -91,7 +91,7 @@ void ImGui::ShowUserGuide()
} }
// Demonstrate most ImGui features (big function!) // Demonstrate most ImGui features (big function!)
void ImGui::ShowTestWindow(bool* p_opened) void ImGui::ShowTestWindow(bool* p_open)
{ {
// Examples apps // Examples apps
static bool show_app_main_menu_bar = false; static bool show_app_main_menu_bar = false;
@ -150,7 +150,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse;
if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar;
ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("ImGui Demo", p_opened, window_flags)) if (!ImGui::Begin("ImGui Demo", p_open, window_flags))
{ {
// Early out if the window is collapsed, as an optimization. // Early out if the window is collapsed, as an optimization.
ImGui::End(); ImGui::End();
@ -293,12 +293,12 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGuiTreeNodeFlags node_flags = ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; ImGuiTreeNodeFlags node_flags = ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
if (i >= 3) if (i >= 3)
node_flags |= ImGuiTreeNodeFlags_AlwaysOpen; node_flags |= ImGuiTreeNodeFlags_AlwaysOpen;
bool opened = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable %s %d", (i >= 3) ? "Leaf" : "Node", i); bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable %s %d", (i >= 3) ? "Leaf" : "Node", i);
if (ImGui::IsItemClicked()) if (ImGui::IsItemClicked())
node_clicked = i; node_clicked = i;
if (opened) if (node_open)
{ {
ImGui::Text("Blah blah"); ImGui::Text("Selectable Blah blah");
ImGui::Text("Blah blah"); ImGui::Text("Blah blah");
ImGui::TreePop(); ImGui::TreePop();
} }
@ -1046,9 +1046,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data
ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). ImGui::AlignFirstTextHeightToWidgets(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit).
bool tree_opened = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content.
ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2");
if (tree_opened) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data
// Bullet // Bullet
ImGui::Button("Button##3"); ImGui::Button("Button##3");
@ -1437,9 +1437,9 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::TreePop(); ImGui::TreePop();
} }
bool node_opened = 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.\nThere's no storage of state per-cell."); ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell.\nThere's no storage of state per-cell.");
if (node_opened) if (node_open)
{ {
ImGui::Columns(2, "tree items"); ImGui::Columns(2, "tree items");
ImGui::Separator(); ImGui::Separator();
@ -1766,9 +1766,9 @@ static void ShowExampleMenuFile()
if (ImGui::MenuItem("Quit", "Alt+F4")) {} if (ImGui::MenuItem("Quit", "Alt+F4")) {}
} }
static void ShowExampleAppAutoResize(bool* opened) static void ShowExampleAppAutoResize(bool* p_open)
{ {
if (!ImGui::Begin("Example: Auto-resizing window", opened, ImGuiWindowFlags_AlwaysAutoResize)) if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1782,10 +1782,10 @@ static void ShowExampleAppAutoResize(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppFixedOverlay(bool* opened) static void ShowExampleAppFixedOverlay(bool* p_open)
{ {
ImGui::SetNextWindowPos(ImVec2(10,10)); ImGui::SetNextWindowPos(ImVec2(10,10));
if (!ImGui::Begin("Example: Fixed Overlay", opened, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImVec2(0,0), 0.3f, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1796,9 +1796,9 @@ static void ShowExampleAppFixedOverlay(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppManipulatingWindowTitle(bool* opened) static void ShowExampleAppManipulatingWindowTitle(bool* p_open)
{ {
(void)opened; (void)p_open;
// By default, Windows are uniquely identified by their title. // By default, Windows are uniquely identified by their title.
// You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file! // You can use the "##" and "###" markers to manipulate the display/ID. Read FAQ at the top of this file!
@ -1823,10 +1823,10 @@ static void ShowExampleAppManipulatingWindowTitle(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppCustomRendering(bool* opened) static void ShowExampleAppCustomRendering(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Custom rendering", opened)) if (!ImGui::Begin("Example: Custom rendering", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -1975,10 +1975,10 @@ struct ExampleAppConsole
ScrollToBottom = true; ScrollToBottom = true;
} }
void Draw(const char* title, bool* opened) void Draw(const char* title, bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin(title, opened)) if (!ImGui::Begin(title, p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -2191,10 +2191,10 @@ struct ExampleAppConsole
} }
}; };
static void ShowExampleAppConsole(bool* opened) static void ShowExampleAppConsole(bool* p_open)
{ {
static ExampleAppConsole console; static ExampleAppConsole console;
console.Draw("Example: Console", opened); console.Draw("Example: Console", p_open);
} }
// Usage: // Usage:
@ -2223,10 +2223,10 @@ struct ExampleAppLog
ScrollToBottom = true; ScrollToBottom = true;
} }
void Draw(const char* title, bool* p_opened = NULL) void Draw(const char* title, bool* p_open = NULL)
{ {
ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiSetCond_FirstUseEver);
ImGui::Begin(title, p_opened); ImGui::Begin(title, p_open);
if (ImGui::Button("Clear")) Clear(); if (ImGui::Button("Clear")) Clear();
ImGui::SameLine(); ImGui::SameLine();
bool copy = ImGui::Button("Copy"); bool copy = ImGui::Button("Copy");
@ -2261,7 +2261,7 @@ struct ExampleAppLog
} }
}; };
static void ShowExampleAppLog(bool* opened) static void ShowExampleAppLog(bool* p_open)
{ {
static ExampleAppLog log; static ExampleAppLog log;
@ -2275,19 +2275,19 @@ static void ShowExampleAppLog(bool* opened)
last_time = time; last_time = time;
} }
log.Draw("Example: Log", opened); log.Draw("Example: Log", p_open);
} }
static void ShowExampleAppLayout(bool* opened) static void ShowExampleAppLayout(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiSetCond_FirstUseEver);
if (ImGui::Begin("Example: Layout", opened, ImGuiWindowFlags_MenuBar)) if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar))
{ {
if (ImGui::BeginMenuBar()) if (ImGui::BeginMenuBar())
{ {
if (ImGui::BeginMenu("File")) if (ImGui::BeginMenu("File"))
{ {
if (ImGui::MenuItem("Close")) *opened = false; if (ImGui::MenuItem("Close")) *p_open = false;
ImGui::EndMenu(); ImGui::EndMenu();
} }
ImGui::EndMenuBar(); ImGui::EndMenuBar();
@ -2323,10 +2323,10 @@ static void ShowExampleAppLayout(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppPropertyEditor(bool* opened) static void ShowExampleAppPropertyEditor(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Property editor", opened)) if (!ImGui::Begin("Example: Property editor", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;
@ -2344,12 +2344,12 @@ static void ShowExampleAppPropertyEditor(bool* opened)
{ {
ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID.
ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. ImGui::AlignFirstTextHeightToWidgets(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high.
bool is_opened = ImGui::TreeNode("Object", "%s_%u", prefix, uid); bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid);
ImGui::NextColumn(); ImGui::NextColumn();
ImGui::AlignFirstTextHeightToWidgets(); ImGui::AlignFirstTextHeightToWidgets();
ImGui::Text("my sailor is rich"); ImGui::Text("my sailor is rich");
ImGui::NextColumn(); ImGui::NextColumn();
if (is_opened) if (node_open)
{ {
static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f };
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
@ -2395,10 +2395,10 @@ static void ShowExampleAppPropertyEditor(bool* opened)
ImGui::End(); ImGui::End();
} }
static void ShowExampleAppLongText(bool* opened) static void ShowExampleAppLongText(bool* p_open)
{ {
ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiSetCond_FirstUseEver);
if (!ImGui::Begin("Example: Long text display", opened)) if (!ImGui::Begin("Example: Long text display", p_open))
{ {
ImGui::End(); ImGui::End();
return; return;

View File

@ -381,7 +381,7 @@ struct ImGuiState
ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
ImVector<ImGuiPopupRef> OpenedPopupStack; // Which popups are open (persistent) ImVector<ImGuiPopupRef> OpenPopupStack; // Which popups are open (persistent)
ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame)
// Storage for SetNexWindow** and SetNextTreeNode*** functions // Storage for SetNexWindow** and SetNextTreeNode*** functions
@ -394,8 +394,8 @@ struct ImGuiState
ImGuiSetCond SetNextWindowContentSizeCond; ImGuiSetCond SetNextWindowContentSizeCond;
ImGuiSetCond SetNextWindowCollapsedCond; ImGuiSetCond SetNextWindowCollapsedCond;
bool SetNextWindowFocus; bool SetNextWindowFocus;
bool SetNextTreeNodeOpenedVal; bool SetNextTreeNodeOpenVal;
ImGuiSetCond SetNextTreeNodeOpenedCond; ImGuiSetCond SetNextTreeNodeOpenCond;
// Render // Render
ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user
@ -470,8 +470,8 @@ struct ImGuiState
SetNextWindowContentSizeCond = 0; SetNextWindowContentSizeCond = 0;
SetNextWindowCollapsedCond = 0; SetNextWindowCollapsedCond = 0;
SetNextWindowFocus = false; SetNextWindowFocus = false;
SetNextTreeNodeOpenedVal = false; SetNextTreeNodeOpenVal = false;
SetNextTreeNodeOpenedCond = 0; SetNextTreeNodeOpenCond = 0;
ScalarAsInputTextId = 0; ScalarAsInputTextId = 0;
ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f); ActiveClickDeltaToCenter = ImVec2(0.0f, 0.0f);
@ -705,7 +705,7 @@ namespace ImGui
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool opened, float scale = 1.0f, bool shadow = false); IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f, bool shadow = false);
IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderBullet(ImVec2 pos);
IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col);
IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
@ -729,7 +729,7 @@ namespace ImGui
IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
IMGUI_API bool TreeNodeBehaviorIsOpened(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging
IMGUI_API void TreePushRawID(ImGuiID id); IMGUI_API void TreePushRawID(ImGuiID id);
IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);