Refactored rare transient bool stacks into a set of flags, added unexposed ImGuiItemFlags_SelectableDontClosePopup (#323)

This commit is contained in:
ocornut 2016-08-07 20:05:24 +02:00
parent 785f51227a
commit 8828889d5e
2 changed files with 52 additions and 32 deletions

View File

@ -2111,7 +2111,7 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id, const ImRect* nav_bb_ar
{ {
const ImRect& nav_bb = nav_bb_arg ? *nav_bb_arg : bb; const ImRect& nav_bb = nav_bb_arg ? *nav_bb_arg : bb;
const ImRect nav_bb_rel(nav_bb.Min - g.NavWindow->Pos, nav_bb.Max - g.NavWindow->Pos); const ImRect nav_bb_rel(nav_bb.Min - g.NavWindow->Pos, nav_bb.Max - g.NavWindow->Pos);
if (g.NavInitDefaultRequest && g.NavLayer == window->DC.NavLayerCurrent && window->DC.AllowNavDefaultFocus) if (g.NavInitDefaultRequest && g.NavLayer == window->DC.NavLayerCurrent && (window->DC.ItemFlags & ImGuiItemFlags_AllowNavDefaultFocus))
{ {
g.NavInitDefaultRequest = g.NavInitDefaultResultExplicit = false; // Clear flag immediately, first item gets default, also simplify the if() in ItemAdd() g.NavInitDefaultRequest = g.NavInitDefaultResultExplicit = false; // Clear flag immediately, first item gets default, also simplify the if() in ItemAdd()
g.NavInitDefaultResultId = *id; g.NavInitDefaultResultId = *id;
@ -2186,7 +2186,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const bool allow_keyboard_focus = window->DC.AllowKeyboardFocus; const bool allow_keyboard_focus = (window->DC.ItemFlags & ImGuiItemFlags_AllowKeyboardFocus) != 0;
window->FocusIdxAllCounter++; window->FocusIdxAllCounter++;
if (allow_keyboard_focus) if (allow_keyboard_focus)
window->FocusIdxTabCounter++; window->FocusIdxTabCounter++;
@ -5027,14 +5027,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; 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.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
window->DC.AllowKeyboardFocus = window->DC.AllowNavDefaultFocus = true; window->DC.ItemFlagsStack.resize(0);
window->DC.ButtonRepeat = false;
window->DC.ItemWidthStack.resize(0); window->DC.ItemWidthStack.resize(0);
window->DC.TextWrapPosStack.resize(0); window->DC.TextWrapPosStack.resize(0);
window->DC.AllowKeyboardFocusStack.resize(0);
window->DC.ButtonRepeatStack.resize(0);
window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect; window->DC.ColorEditMode = ImGuiColorEditMode_UserSelect;
window->DC.ColumnsCurrent = 0; window->DC.ColumnsCurrent = 0;
window->DC.ColumnsCount = 1; window->DC.ColumnsCount = 1;
@ -5045,6 +5043,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
window->DC.GroupStack.resize(0); window->DC.GroupStack.resize(0);
window->MenuColumns.Update(3, style.ItemSpacing.x, !window_was_active); window->MenuColumns.Update(3, style.ItemSpacing.x, !window_was_active);
if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags))
{
window->DC.ItemFlags = parent_window->DC.ItemFlags;
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
}
if (window->AutoFitFramesX > 0) if (window->AutoFitFramesX > 0)
window->AutoFitFramesX--; window->AutoFitFramesX--;
if (window->AutoFitFramesY > 0) if (window->AutoFitFramesY > 0)
@ -5062,9 +5066,9 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (!(flags & ImGuiWindowFlags_NoTitleBar)) if (!(flags & ImGuiWindowFlags_NoTitleBar))
{ {
// Close & collapse button are on layer 1 (same as menus) and don't default focus // Close & collapse button are on layer 1 (same as menus) and don't default focus
const bool backup_allow_nav_default_focus = window->DC.AllowNavDefaultFocus; const ImGuiItemFlags backup_item_options = window->DC.ItemFlags;
if (window->Flags & ImGuiWindowFlags_MenuBar) if (window->Flags & ImGuiWindowFlags_MenuBar)
window->DC.AllowNavDefaultFocus = false; window->DC.ItemFlags &= ~ImGuiItemFlags_AllowNavDefaultFocus;
window->DC.NavLayerCurrent++; window->DC.NavLayerCurrent++;
// Close button // Close button
@ -5090,7 +5094,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
} }
window->DC.NavLayerCurrent--; window->DC.NavLayerCurrent--;
window->DC.AllowNavDefaultFocus = backup_allow_nav_default_focus; window->DC.ItemFlags = backup_item_options;
// Title text (FIXME: refactor text alignment facilities along with RenderText helpers) // Title text (FIXME: refactor text alignment facilities along with RenderText helpers)
ImVec2 text_min = window->Pos + style.FramePadding; ImVec2 text_min = window->Pos + style.FramePadding;
@ -5402,32 +5406,41 @@ void ImGui::PopFont()
SetCurrentFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back()); SetCurrentFont(g.FontStack.empty() ? g.IO.Fonts->Fonts[0] : g.FontStack.back());
} }
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled)
{ {
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
window->DC.AllowKeyboardFocus = allow_keyboard_focus; if (enabled)
window->DC.AllowKeyboardFocusStack.push_back(allow_keyboard_focus); window->DC.ItemFlags |= option;
else
window->DC.ItemFlags &= ~option;
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
}
void ImGui::PopItemFlag()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ItemFlagsStack.pop_back();
window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back();
}
void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
{
PushItemFlag(ImGuiItemFlags_AllowKeyboardFocus, allow_keyboard_focus);
} }
void ImGui::PopAllowKeyboardFocus() void ImGui::PopAllowKeyboardFocus()
{ {
ImGuiWindow* window = GetCurrentWindow(); PopItemFlag();
window->DC.AllowKeyboardFocusStack.pop_back();
window->DC.AllowKeyboardFocus = window->DC.AllowKeyboardFocusStack.empty() ? true : window->DC.AllowKeyboardFocusStack.back();
} }
void ImGui::PushButtonRepeat(bool repeat) void ImGui::PushButtonRepeat(bool repeat)
{ {
ImGuiWindow* window = GetCurrentWindow(); PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat);
window->DC.ButtonRepeat = repeat;
window->DC.ButtonRepeatStack.push_back(repeat);
} }
void ImGui::PopButtonRepeat() void ImGui::PopButtonRepeat()
{ {
ImGuiWindow* window = GetCurrentWindow(); PopItemFlag();
window->DC.ButtonRepeatStack.pop_back();
window->DC.ButtonRepeat = window->DC.ButtonRepeatStack.empty() ? false : window->DC.ButtonRepeatStack.back();
} }
void ImGui::PushTextWrapPos(float wrap_pos_x) void ImGui::PushTextWrapPos(float wrap_pos_x)
@ -5507,7 +5520,6 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
*pvar = val; *pvar = val;
} }
void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -6413,7 +6425,7 @@ bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags
if (!ItemAdd(bb, &id)) if (!ItemAdd(bb, &id))
return false; return false;
if (window->DC.ButtonRepeat) flags |= ImGuiButtonFlags_Repeat; if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) flags |= ImGuiButtonFlags_Repeat;
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags);
@ -9481,7 +9493,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor();
// Automatically close popups // Automatically close popups
if (pressed && !(flags & ImGuiSelectableFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !((window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)))
CloseCurrentPopup(); CloseCurrentPopup();
return pressed; return pressed;
} }

View File

@ -47,6 +47,7 @@ typedef int ImGuiLayoutType; // enum ImGuiLayoutType_
typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_ typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_
typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_ typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_
typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_ typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_
typedef int ImGuiItemFlags; // enum ImGuiItemFlags_
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// STB libraries // STB libraries
@ -574,6 +575,16 @@ struct ImGuiContext
} }
}; };
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
enum ImGuiItemFlags_
{
ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // [true]
ImGuiItemFlags_AllowNavDefaultFocus = 1 << 1, // [true]
ImGuiItemFlags_ButtonRepeat = 1 << 2, // [false] // Button() can be held will a repeat behavior
ImGuiItemFlags_SelectableDontClosePopup = 1 << 3, // [false] // MenuItem/Selectable() automatically closes owner Popup window
ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus|ImGuiItemFlags_AllowNavDefaultFocus
};
// Transient per-window data, reset at the beginning of the frame // Transient per-window data, reset at the beginning of the frame
// FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered. // FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered.
struct IMGUI_API ImGuiDrawContext struct IMGUI_API ImGuiDrawContext
@ -602,15 +613,12 @@ struct IMGUI_API ImGuiDrawContext
ImGuiLayoutType LayoutType; ImGuiLayoutType LayoutType;
// 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]
float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true] ImVector<ImGuiItemFlags>ItemFlagsStack;
bool AllowNavDefaultFocus; // (not exposed via stack)
bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false]
ImVector<float> ItemWidthStack; ImVector<float> ItemWidthStack;
ImVector<float> TextWrapPosStack; ImVector<float> TextWrapPosStack;
ImVector<bool> AllowKeyboardFocusStack;
ImVector<bool> ButtonRepeatStack;
ImVector<ImGuiGroupData>GroupStack; ImVector<ImGuiGroupData>GroupStack;
ImGuiColorEditMode ColorEditMode; ImGuiColorEditMode ColorEditMode;
int StackSizesBackup[6]; // Store size of various stacks for asserting int StackSizesBackup[6]; // Store size of various stacks for asserting
@ -647,8 +655,7 @@ struct IMGUI_API ImGuiDrawContext
StateStorage = NULL; StateStorage = NULL;
LayoutType = ImGuiLayoutType_Vertical; LayoutType = ImGuiLayoutType_Vertical;
ItemWidth = 0.0f; ItemWidth = 0.0f;
ButtonRepeat = false; ItemFlags = ImGuiItemFlags_Default_;
AllowKeyboardFocus = AllowNavDefaultFocus = true;
TextWrapPos = -1.0f; TextWrapPos = -1.0f;
ColorEditMode = ImGuiColorEditMode_RGB; ColorEditMode = ImGuiColorEditMode_RGB;
memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
@ -782,8 +789,9 @@ namespace ImGui
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);
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing);
IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate);
// NB: All position are in absolute pixels coordinates (not window coordinates) // NB: All position are in absolute pixels coordinates (not window coordinates)