Updated ImGui.

This commit is contained in:
Бранимир Караџић 2020-08-11 21:06:37 -07:00
parent 0a4099b13c
commit 1a2bfbb06f
4 changed files with 49 additions and 23 deletions

View File

@ -2929,6 +2929,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
}
g.ActiveId = id;
g.ActiveIdAllowOverlap = false;
g.ActiveIdNoClearOnFocusLoss = false;
g.ActiveIdWindow = window;
g.ActiveIdHasBeenEditedThisFrame = false;
if (id)
@ -2946,7 +2947,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
void ImGui::ClearActiveID()
{
SetActiveID(0, NULL);
SetActiveID(0, NULL); // g.ActiveId = 0;
}
void ImGui::SetHoveredID(ImGuiID id)
@ -3102,6 +3103,15 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged
return false;
}
// This is also inlined in ItemAdd()
// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect!
void ImGui::SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags item_flags, const ImRect& item_rect)
{
window->DC.LastItemId = item_id;
window->DC.LastItemStatusFlags = item_flags;
window->DC.LastItemRect = item_rect;
}
// Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id)
{
@ -3294,6 +3304,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
FocusWindow(window);
SetActiveID(window->MoveId, window);
g.NavDisableHighlight = true;
g.ActiveIdNoClearOnFocusLoss = true;
g.ActiveIdClickOffset = g.IO.MousePos - window->RootWindow->Pos;
bool can_move_window = true;
@ -5982,9 +5993,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
// This is useful to allow creating context menus on title bar only, etc.
window->DC.LastItemId = window->MoveId;
window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
window->DC.LastItemRect = title_bar_rect;
SetLastItemData(window, window->MoveId, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect);
#ifdef IMGUI_ENABLE_TEST_ENGINE
if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
IMGUI_TEST_ENGINE_ITEM_ADD(window->DC.LastItemRect, window->DC.LastItemId);
@ -6090,7 +6100,7 @@ void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* current_front_window = g.Windows.back();
if (current_front_window == window || current_front_window->RootWindow == window)
if (current_front_window == window || current_front_window->RootWindow == window) // Cheap early out (could be better)
return;
for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window
if (g.Windows[i] == window)
@ -6141,9 +6151,12 @@ void ImGui::FocusWindow(ImGuiWindow* window)
ImGuiWindow* focus_front_window = window ? window->RootWindow : NULL; // NB: In docking branch this is window->RootWindowDockStop
ImGuiWindow* display_front_window = window ? window->RootWindow : NULL;
// Steal focus on active widgets
// Steal active widgets. Some of the cases it triggers includes:
// - Focus a window while an InputText in another window is active, if focus happens before the old InputText can run.
// - When using Nav to activate menu items (due to timing of activating on press->new window appears->losing ActiveId)
if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window)
ClearActiveID();
if (!g.ActiveIdNoClearOnFocusLoss)
ClearActiveID();
// Passing NULL allow to disable keyboard focus
if (!window)
@ -6961,6 +6974,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
#endif
}
// Equivalent to calling SetLastItemData()
window->DC.LastItemId = id;
window->DC.LastItemRect = bb;
window->DC.LastItemStatusFlags = ImGuiItemStatusFlags_None;
@ -7684,13 +7698,14 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
}
}
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
// This function closes any popups that are over 'ref_window'.
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
{
ImGuiContext& g = *GImGui;
if (g.OpenPopupStack.Size == 0)
return;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
// Don't close our own child popup windows.
int popup_count_to_keep = 0;
if (ref_window)
@ -7705,13 +7720,20 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow)
continue;
// Trim the stack when popups are not direct descendant of the reference window (the reference window is often the NavWindow)
bool popup_or_descendent_is_ref_window = false;
for (int m = popup_count_to_keep; m < g.OpenPopupStack.Size && !popup_or_descendent_is_ref_window; m++)
if (ImGuiWindow* popup_window = g.OpenPopupStack[m].Window)
// Trim the stack unless the popup is a direct parent of the reference window (the reference window is often the NavWindow)
// - With this stack of window, clicking/focusing Popup1 will close Popup2 and Popup3:
// Window -> Popup1 -> Popup2 -> Popup3
// - Each popups may contain child windows, which is why we compare ->RootWindow!
// Window -> Popup1 -> Popup1_Child -> Popup2 -> Popup2_Child
bool ref_window_is_descendent_of_popup = false;
for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++)
if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window)
if (popup_window->RootWindow == ref_window->RootWindow)
popup_or_descendent_is_ref_window = true;
if (!popup_or_descendent_is_ref_window)
{
ref_window_is_descendent_of_popup = true;
break;
}
if (!ref_window_is_descendent_of_popup)
break;
}
}

View File

@ -2328,6 +2328,7 @@ void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* f
font->ClearOutputData();
font->FontSize = font_config->SizePixels;
font->ConfigData = font_config;
font->ConfigDataCount = 0;
font->ContainerAtlas = atlas;
font->Ascent = ascent;
font->Descent = descent;

View File

@ -96,7 +96,7 @@ struct ImGuiContext; // Main Dear ImGui context
struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum
struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box
struct ImGuiItemHoveredDataBackup; // Backup and restore IsItemHovered() internal data
struct ImGuiLastItemDataBackup; // Backup and restore IsItemHovered() internal data
struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
struct ImGuiNavMoveResult; // Result of a gamepad/keyboard directional navigation move query result
struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
@ -1127,10 +1127,10 @@ struct ImGuiContext
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame
ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Will catch mouse inputs
ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
ImGuiWindow* HoveredRootWindow; // == HoveredWindow ? HoveredWindow->RootWindow : NULL, merely a shortcut to avoid null test in some situation.
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow.
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow.
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
ImVec2 WheelingWindowRefMousePos;
float WheelingWindowTimer;
@ -1147,6 +1147,7 @@ struct ImGuiContext
float ActiveIdTimer;
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused.
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
@ -1351,6 +1352,7 @@ struct ImGuiContext
ActiveIdTimer = 0.0f;
ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false;
ActiveIdNoClearOnFocusLoss = false;
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
@ -1630,7 +1632,7 @@ struct IMGUI_API ImGuiWindow
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
ImDrawList DrawListInst;
ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL.
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window.
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window == Top-level window.
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
@ -1664,14 +1666,14 @@ public:
};
// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data.
struct ImGuiItemHoveredDataBackup
struct ImGuiLastItemDataBackup
{
ImGuiID LastItemId;
ImGuiItemStatusFlags LastItemStatusFlags;
ImRect LastItemRect;
ImRect LastItemDisplayRect;
ImGuiItemHoveredDataBackup() { Backup(); }
ImGuiLastItemDataBackup() { Backup(); }
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemStatusFlags = window->DC.LastItemStatusFlags; LastItemRect = window->DC.LastItemRect; LastItemDisplayRect = window->DC.LastItemDisplayRect; }
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; }
};
@ -1839,6 +1841,7 @@ namespace ImGui
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
IMGUI_API void SetLastItemData(ImGuiWindow* window, ImGuiID item_id, ImGuiItemStatusFlags status_flags, const ImRect& item_rect);
IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id); // Return true if focus is requested
IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);

View File

@ -5676,7 +5676,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags
// FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc.
// FIXME: CloseButton can overlap into text, need find a way to clip the text somehow.
ImGuiContext& g = *GImGui;
ImGuiItemHoveredDataBackup last_item_backup;
ImGuiLastItemDataBackup last_item_backup;
float button_size = g.FontSize;
float button_x = ImMax(window->DC.LastItemRect.Min.x, window->DC.LastItemRect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
float button_y = window->DC.LastItemRect.Min.y;
@ -7425,7 +7425,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
close_button_visible = true;
if (close_button_visible)
{
ImGuiItemHoveredDataBackup last_item_backup;
ImGuiLastItemDataBackup last_item_backup;
const float close_button_sz = g.FontSize;
PushStyleVar(ImGuiStyleVar_FramePadding, frame_padding);
if (CloseButton(close_button_id, ImVec2(bb.Max.x - frame_padding.x * 2.0f - close_button_sz, bb.Min.y)))