mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated ImGui.
This commit is contained in:
102
3rdparty/dear-imgui/imgui.cpp
vendored
102
3rdparty/dear-imgui/imgui.cpp
vendored
@@ -1070,6 +1070,7 @@ static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb
|
||||
static ImVec2 NavCalcPreferredRefPos();
|
||||
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
|
||||
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
|
||||
static int FindWindowFocusIndex(ImGuiWindow* window);
|
||||
|
||||
// Misc
|
||||
static void UpdateMouseInputs();
|
||||
@@ -2881,7 +2882,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
|
||||
return false;
|
||||
|
||||
// Test if interactions on this window are blocked by an active popup or modal
|
||||
// Test if interactions on this window are blocked by an active popup or modal.
|
||||
// The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here.
|
||||
if (!IsWindowContentHoverable(window, flags))
|
||||
return false;
|
||||
|
||||
@@ -3214,8 +3216,9 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
}
|
||||
}
|
||||
|
||||
// With right mouse button we close popups without changing focus
|
||||
// (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
||||
// With right mouse button we close popups without changing focus based on where the mouse is aimed
|
||||
// Instead, focus will be restored to the window under the bottom-most closed popup.
|
||||
// (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
||||
if (g.IO.MouseClicked[1])
|
||||
{
|
||||
// Find the top-most window between HoveredWindow and the front most Modal Window.
|
||||
@@ -3232,7 +3235,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
if (window == g.HoveredWindow)
|
||||
hovered_window_above_modal = true;
|
||||
}
|
||||
ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
||||
ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3604,13 +3607,13 @@ void ImGui::NewFrame()
|
||||
|
||||
// Closing the focused window restore focus to the first active root window in descending z-order
|
||||
if (g.NavWindow && !g.NavWindow->WasActive)
|
||||
FocusPreviousWindowIgnoringOne(NULL);
|
||||
FocusTopMostWindowUnderOne(NULL, NULL);
|
||||
|
||||
// No window should be open at the beginning of the frame.
|
||||
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
|
||||
g.CurrentWindowStack.resize(0);
|
||||
g.BeginPopupStack.resize(0);
|
||||
ClosePopupsOverWindow(g.NavWindow);
|
||||
ClosePopupsOverWindow(g.NavWindow, false);
|
||||
|
||||
// Create implicit/fallback window - which we will only render it if the user has added something to it.
|
||||
// We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
|
||||
@@ -5004,7 +5007,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0);
|
||||
if (flags & ImGuiWindowFlags_Popup)
|
||||
{
|
||||
ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed
|
||||
window_just_activated_by_user |= (window != popup_ref.Window);
|
||||
}
|
||||
@@ -5037,7 +5040,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
CheckStacksSize(window, true);
|
||||
if (flags & ImGuiWindowFlags_Popup)
|
||||
{
|
||||
ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
popup_ref.Window = window;
|
||||
g.BeginPopupStack.push_back(popup_ref);
|
||||
window->PopupId = popup_ref.PopupId;
|
||||
@@ -5414,10 +5417,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// Update various regions. Variables they depends on are set above in this function.
|
||||
// FIXME: window->ContentsRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
||||
// NB: WindowBorderSize is included in WindowPadding _and_ ScrollbarSizes so we need to cancel one out.
|
||||
window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
|
||||
window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight();
|
||||
window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x + window->WindowBorderSize));
|
||||
window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y + window->WindowBorderSize));
|
||||
window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x + ImMin(window->ScrollbarSizes.x, window->WindowBorderSize)));
|
||||
window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y + ImMin(window->ScrollbarSizes.y, window->WindowBorderSize)));
|
||||
|
||||
// Save clipped aabb so we can access it in constant-time in FindHoveredWindow()
|
||||
window->OuterRectClipped = window->Rect();
|
||||
@@ -5707,6 +5711,9 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
//IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL);
|
||||
}
|
||||
|
||||
// Close popups if any
|
||||
ClosePopupsOverWindow(window, false);
|
||||
|
||||
// Passing NULL allow to disable keyboard focus
|
||||
if (!window)
|
||||
return;
|
||||
@@ -5726,10 +5733,18 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||
BringWindowToDisplayFront(window);
|
||||
}
|
||||
|
||||
void ImGui::FocusPreviousWindowIgnoringOne(ImGuiWindow* ignore_window)
|
||||
void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (int i = g.WindowsFocusOrder.Size - 1; i >= 0; i--)
|
||||
|
||||
int start_idx = g.WindowsFocusOrder.Size - 1;
|
||||
if (under_this_window != NULL)
|
||||
{
|
||||
int under_this_window_idx = FindWindowFocusIndex(under_this_window);
|
||||
if (under_this_window_idx != -1)
|
||||
start_idx = under_this_window_idx - 1;
|
||||
}
|
||||
for (int i = start_idx; i >= 0; i--)
|
||||
{
|
||||
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
||||
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
||||
@@ -5741,6 +5756,7 @@ void ImGui::FocusPreviousWindowIgnoringOne(ImGuiWindow* ignore_window)
|
||||
return;
|
||||
}
|
||||
}
|
||||
FocusWindow(NULL);
|
||||
}
|
||||
|
||||
void ImGui::SetNextItemWidth(float item_width)
|
||||
@@ -6946,10 +6962,10 @@ void ImGui::OpenPopupEx(ImGuiID id)
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* parent_window = g.CurrentWindow;
|
||||
int current_stack_size = g.BeginPopupStack.Size;
|
||||
ImGuiPopupRef popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
||||
ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
|
||||
popup_ref.PopupId = id;
|
||||
popup_ref.Window = NULL;
|
||||
popup_ref.ParentWindow = parent_window;
|
||||
popup_ref.SourceWindow = g.NavWindow;
|
||||
popup_ref.OpenFrameCount = g.FrameCount;
|
||||
popup_ref.OpenParentId = parent_window->IDStack.back();
|
||||
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
|
||||
@@ -6996,7 +7012,7 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window)
|
||||
void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.OpenPopupStack.empty())
|
||||
@@ -7010,49 +7026,51 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window)
|
||||
// Find the highest popup which is a descendant of the reference window (generally reference window = NavWindow)
|
||||
for (; popup_count_to_keep < g.OpenPopupStack.Size; popup_count_to_keep++)
|
||||
{
|
||||
ImGuiPopupRef& popup = g.OpenPopupStack[popup_count_to_keep];
|
||||
ImGuiPopupData& popup = g.OpenPopupStack[popup_count_to_keep];
|
||||
if (!popup.Window)
|
||||
continue;
|
||||
IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0);
|
||||
if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow)
|
||||
continue;
|
||||
|
||||
// Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow)
|
||||
bool popup_or_descendent_has_focus = false;
|
||||
for (int m = popup_count_to_keep; m < g.OpenPopupStack.Size && !popup_or_descendent_has_focus; m++)
|
||||
if (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow)
|
||||
popup_or_descendent_has_focus = true;
|
||||
if (!popup_or_descendent_has_focus)
|
||||
// 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)
|
||||
if (popup_window->RootWindow == ref_window->RootWindow)
|
||||
popup_or_descendent_is_ref_window = true;
|
||||
if (!popup_or_descendent_is_ref_window)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("ClosePopupsOverWindow(%s) -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep);
|
||||
ClosePopupToLevel(popup_count_to_keep, false);
|
||||
ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup);
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::ClosePopupToLevel(int remaining, bool apply_focus_to_window_under)
|
||||
void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
|
||||
{
|
||||
IM_ASSERT(remaining >= 0);
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* focus_window = (remaining > 0) ? g.OpenPopupStack[remaining-1].Window : g.OpenPopupStack[0].ParentWindow;
|
||||
IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
|
||||
ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
|
||||
ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
|
||||
g.OpenPopupStack.resize(remaining);
|
||||
|
||||
// FIXME: This code is faulty and we may want to eventually to replace or remove the 'apply_focus_to_window_under=true' path completely.
|
||||
// Instead of using g.OpenPopupStack[remaining-1].Window etc. we should find the highest root window that is behind the popups we are closing.
|
||||
// The current code will set focus to the parent of the popup window which is incorrect.
|
||||
// It rarely manifested until now because UpdateMouseMovingWindowNewFrame() would call FocusWindow() again on the clicked window,
|
||||
// leading to a chain of focusing A (clicked window) then B (parent window of the popup) then A again.
|
||||
// However if the clicked window has the _NoMove flag set we would be left with B focused.
|
||||
// For now, we have disabled this path when called from ClosePopupsOverWindow() because the users of ClosePopupsOverWindow() don't need to alter focus anyway,
|
||||
// but we should inspect and fix this properly.
|
||||
if (apply_focus_to_window_under)
|
||||
if (restore_focus_to_window_under_popup)
|
||||
{
|
||||
if (g.NavLayer == 0)
|
||||
focus_window = NavRestoreLastChildNavWindow(focus_window);
|
||||
FocusWindow(focus_window);
|
||||
if (focus_window && !focus_window->WasActive && popup_window)
|
||||
{
|
||||
// Fallback
|
||||
FocusTopMostWindowUnderOne(popup_window, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g.NavLayer == 0 && focus_window)
|
||||
focus_window = NavRestoreLastChildNavWindow(focus_window);
|
||||
FocusWindow(focus_window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8131,7 +8149,7 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags)
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
static int FindWindowFocusIndex(ImGuiWindow* window) // FIXME-OPT O(N)
|
||||
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) // FIXME-OPT O(N)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
for (int i = g.WindowsFocusOrder.Size-1; i >= 0; i--)
|
||||
@@ -8156,7 +8174,7 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
|
||||
if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal)
|
||||
return;
|
||||
|
||||
const int i_current = FindWindowFocusIndex(g.NavWindowingTarget);
|
||||
const int i_current = ImGui::FindWindowFocusIndex(g.NavWindowingTarget);
|
||||
ImGuiWindow* window_target = FindWindowNavFocusable(i_current + focus_change_dir, -INT_MAX, focus_change_dir);
|
||||
if (!window_target)
|
||||
window_target = FindWindowNavFocusable((focus_change_dir < 0) ? (g.WindowsFocusOrder.Size - 1) : 0, i_current, focus_change_dir);
|
||||
@@ -8268,11 +8286,11 @@ static void ImGui::NavUpdateWindowing()
|
||||
// Apply final focus
|
||||
if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
|
||||
{
|
||||
ClearActiveID();
|
||||
g.NavDisableHighlight = false;
|
||||
g.NavDisableMouseHover = true;
|
||||
apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window);
|
||||
ClosePopupsOverWindow(apply_focus_window);
|
||||
ClearActiveID();
|
||||
ClosePopupsOverWindow(apply_focus_window, false);
|
||||
FocusWindow(apply_focus_window);
|
||||
if (apply_focus_window->NavLastIds[0] == 0)
|
||||
NavInitWindow(apply_focus_window, false);
|
||||
|
||||
7
3rdparty/dear-imgui/imgui_demo.cpp
vendored
7
3rdparty/dear-imgui/imgui_demo.cpp
vendored
@@ -2209,6 +2209,13 @@ static void ShowDemoWindowPopups()
|
||||
if (ImGui::BeginMenu("Sub-menu"))
|
||||
{
|
||||
ImGui::MenuItem("Click me");
|
||||
if (ImGui::Button("Stacked Popup"))
|
||||
ImGui::OpenPopup("another popup");
|
||||
if (ImGui::BeginPopup("another popup"))
|
||||
{
|
||||
ImGui::Text("I am the last one here.");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
||||
34
3rdparty/dear-imgui/imgui_internal.h
vendored
34
3rdparty/dear-imgui/imgui_internal.h
vendored
@@ -65,13 +65,14 @@ struct ImGuiColorMod; // Stacked color modifier, backup of modifie
|
||||
struct ImGuiColumnData; // Storage data for a single column
|
||||
struct ImGuiColumns; // Storage data for a columns set
|
||||
struct ImGuiContext; // Main 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 ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
|
||||
struct ImGuiNavMoveResult; // Result of a directional navigation move query result
|
||||
struct ImGuiNextWindowData; // Storage for SetNexWindow** functions
|
||||
struct ImGuiPopupRef; // Storage for current popup stack
|
||||
struct ImGuiPopupData; // Storage for current popup stack
|
||||
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
|
||||
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
|
||||
struct ImGuiTabBar; // Storage for a tab bar
|
||||
@@ -501,7 +502,6 @@ struct ImVec1
|
||||
ImVec1(float _x) { x = _x; }
|
||||
};
|
||||
|
||||
|
||||
// 2D axis aligned bounding-box
|
||||
// NB: we can't rely on ImVec2 math operators being available here
|
||||
struct IMGUI_API ImRect
|
||||
@@ -538,6 +538,14 @@ struct IMGUI_API ImRect
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
};
|
||||
|
||||
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size; // Size in byte
|
||||
const char* PrintFmt; // Default printf format for the type
|
||||
const char* ScanFmt; // Default scanf format for the type
|
||||
};
|
||||
|
||||
// Stacked color modifier, backup of modified data so we can restore it
|
||||
struct ImGuiColorMod
|
||||
{
|
||||
@@ -640,15 +648,17 @@ struct ImGuiSettingsHandler
|
||||
};
|
||||
|
||||
// Storage for current popup stack
|
||||
struct ImGuiPopupRef
|
||||
struct ImGuiPopupData
|
||||
{
|
||||
ImGuiID PopupId; // Set on OpenPopup()
|
||||
ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
|
||||
ImGuiWindow* ParentWindow; // Set on OpenPopup()
|
||||
ImGuiWindow* SourceWindow; // Set on OpenPopup() copy of NavWindow at the time of opening the popup
|
||||
int OpenFrameCount; // Set on OpenPopup()
|
||||
ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items)
|
||||
ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
|
||||
ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
|
||||
|
||||
ImGuiPopupData() { PopupId = 0; Window = SourceWindow = NULL; OpenFrameCount = -1; OpenParentId = 0; }
|
||||
};
|
||||
|
||||
struct ImGuiColumnData
|
||||
@@ -848,8 +858,8 @@ struct ImGuiContext
|
||||
ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
|
||||
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
|
||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
|
||||
ImVector<ImGuiPopupRef> OpenPopupStack; // Which popups are open (persistent)
|
||||
ImVector<ImGuiPopupRef> BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
|
||||
ImVector<ImGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
|
||||
ImVector<ImGuiPopupData>BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
|
||||
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
|
||||
bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions
|
||||
ImGuiCond NextTreeNodeOpenCond;
|
||||
@@ -1382,7 +1392,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
|
||||
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
|
||||
IMGUI_API void FocusWindow(ImGuiWindow* window);
|
||||
IMGUI_API void FocusPreviousWindowIgnoringOne(ImGuiWindow* ignore_window);
|
||||
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window);
|
||||
IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window);
|
||||
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window);
|
||||
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window);
|
||||
@@ -1456,8 +1466,8 @@ namespace ImGui
|
||||
|
||||
// Popups, Modals, Tooltips
|
||||
IMGUI_API void OpenPopupEx(ImGuiID id);
|
||||
IMGUI_API void ClosePopupToLevel(int remaining, bool apply_focus_to_window_under);
|
||||
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window);
|
||||
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
|
||||
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
|
||||
IMGUI_API bool IsPopupOpen(ImGuiID id); // Test for id within current popup stack level (currently begin-ed into); this doesn't scan the whole popup stack!
|
||||
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
|
||||
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true);
|
||||
@@ -1557,6 +1567,12 @@ namespace ImGui
|
||||
template<typename T, typename FLOAT_T> IMGUI_API float SliderCalcRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, float power, float linear_zero_pos);
|
||||
template<typename T, typename SIGNED_T> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
|
||||
|
||||
// Data type helpers
|
||||
IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type);
|
||||
IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format);
|
||||
IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2);
|
||||
IMGUI_API bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format);
|
||||
|
||||
// InputText
|
||||
IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool TempInputTextScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format);
|
||||
|
||||
105
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
105
3rdparty/dear-imgui/imgui_widgets.cpp
vendored
@@ -104,11 +104,6 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1);
|
||||
// [SECTION] Forward Declarations
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Data Type helpers
|
||||
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format);
|
||||
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2);
|
||||
static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format);
|
||||
|
||||
// For InputTextEx()
|
||||
static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data);
|
||||
static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end);
|
||||
@@ -1539,6 +1534,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
|
||||
// [SECTION] Data Type and Data Formatting Helpers [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
// - PatchFormatStringFloatToInt()
|
||||
// - DataTypeGetInfo()
|
||||
// - DataTypeFormatString()
|
||||
// - DataTypeApplyOp()
|
||||
// - DataTypeApplyOpFromText()
|
||||
@@ -1546,13 +1542,6 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa
|
||||
// - RoundScalarWithFormat<>()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiDataTypeInfo
|
||||
{
|
||||
size_t Size;
|
||||
const char* PrintFmt; // Unused
|
||||
const char* ScanFmt;
|
||||
};
|
||||
|
||||
static const ImGuiDataTypeInfo GDataTypeInfo[] =
|
||||
{
|
||||
{ sizeof(char), "%d", "%d" }, // ImGuiDataType_S8
|
||||
@@ -1597,7 +1586,13 @@ static const char* PatchFormatStringFloatToInt(const char* fmt)
|
||||
return fmt;
|
||||
}
|
||||
|
||||
static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
||||
const ImGuiDataTypeInfo* ImGui::DataTypeGetInfo(ImGuiDataType data_type)
|
||||
{
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
return &GDataTypeInfo[data_type];
|
||||
}
|
||||
|
||||
int ImGui::DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format)
|
||||
{
|
||||
// Signedness doesn't matter when pushing integer arguments
|
||||
if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32)
|
||||
@@ -1620,7 +1615,7 @@ static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType da
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2)
|
||||
void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2)
|
||||
{
|
||||
IM_ASSERT(op == '+' || op == '-');
|
||||
switch (data_type)
|
||||
@@ -1672,7 +1667,7 @@ static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void*
|
||||
|
||||
// User can input math operators (e.g. +100) to edit a numerical values.
|
||||
// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess..
|
||||
static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format)
|
||||
bool ImGui::DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format)
|
||||
{
|
||||
while (ImCharIsBlankA(*buf))
|
||||
buf++;
|
||||
@@ -1696,11 +1691,12 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
// Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all.
|
||||
IM_ASSERT(data_type < ImGuiDataType_COUNT);
|
||||
int data_backup[2];
|
||||
IM_ASSERT(GDataTypeInfo[data_type].Size <= sizeof(data_backup));
|
||||
memcpy(data_backup, data_ptr, GDataTypeInfo[data_type].Size);
|
||||
const ImGuiDataTypeInfo* type_info = ImGui::DataTypeGetInfo(data_type);
|
||||
IM_ASSERT(type_info->Size <= sizeof(data_backup));
|
||||
memcpy(data_backup, data_ptr, type_info->Size);
|
||||
|
||||
if (format == NULL)
|
||||
format = GDataTypeInfo[data_type].ScanFmt;
|
||||
format = type_info->ScanFmt;
|
||||
|
||||
// FIXME-LEGACY: The aim is to remove those operators and write a proper expression evaluator at some point..
|
||||
int arg1i = 0;
|
||||
@@ -1769,7 +1765,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b
|
||||
IM_ASSERT(0);
|
||||
}
|
||||
|
||||
return memcmp(data_backup, data_ptr, GDataTypeInfo[data_type].Size) != 0;
|
||||
return memcmp(data_backup, data_ptr, type_info->Size) != 0;
|
||||
}
|
||||
|
||||
static float GetMinimumStepAtDecimalPrecision(int decimal_precision)
|
||||
@@ -1990,11 +1986,9 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, floa
|
||||
return false;
|
||||
|
||||
// Default format string when passing NULL
|
||||
// Patch old "%.0f" format string to use "%d", read function comments for more details.
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
if (format == NULL)
|
||||
format = GDataTypeInfo[data_type].PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||
format = PatchFormatStringFloatToInt(format);
|
||||
|
||||
// Tabbing or CTRL-clicking on Drag turns it into an input box
|
||||
@@ -2450,11 +2444,9 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, co
|
||||
return false;
|
||||
|
||||
// Default format string when passing NULL
|
||||
// Patch old "%.0f" format string to use "%d", read function comments for more details.
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
if (format == NULL)
|
||||
format = GDataTypeInfo[data_type].PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||
format = PatchFormatStringFloatToInt(format);
|
||||
|
||||
// Tabbing or CTRL-clicking on Slider turns it into an input box
|
||||
@@ -2606,11 +2598,9 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
return false;
|
||||
|
||||
// Default format string when passing NULL
|
||||
// Patch old "%.0f" format string to use "%d", read function comments for more details.
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
if (format == NULL)
|
||||
format = GDataTypeInfo[data_type].PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0)
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) // (FIXME-LEGACY: Patch old "%.0f" format string to use "%d", read function more details.)
|
||||
format = PatchFormatStringFloatToInt(format);
|
||||
|
||||
const bool hovered = ItemHoverable(frame_bb, id);
|
||||
@@ -2792,9 +2782,8 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_p
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiStyle& style = g.Style;
|
||||
|
||||
IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT);
|
||||
if (format == NULL)
|
||||
format = GDataTypeInfo[data_type].PrintFmt;
|
||||
format = DataTypeGetInfo(data_type)->PrintFmt;
|
||||
|
||||
char buf[64];
|
||||
DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, format);
|
||||
@@ -5844,9 +5833,10 @@ void ImGui::EndMainMenuBar()
|
||||
EndMenuBar();
|
||||
|
||||
// When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window
|
||||
// FIXME: With this strategy we won't be able to restore a NULL focus.
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.CurrentWindow == g.NavWindow && g.NavLayer == 0)
|
||||
FocusPreviousWindowIgnoringOne(g.NavWindow);
|
||||
FocusTopMostWindowUnderOne(g.NavWindow, NULL);
|
||||
|
||||
End();
|
||||
}
|
||||
@@ -5972,31 +5962,36 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
|
||||
if (menuset_is_open)
|
||||
g.NavWindow = backed_nav_window;
|
||||
|
||||
bool want_open = false, want_close = false;
|
||||
bool want_open = false;
|
||||
bool want_close = false;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
||||
{
|
||||
// Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu
|
||||
// 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;
|
||||
if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].ParentWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
||||
{
|
||||
if (ImGuiWindow* next_window = g.OpenPopupStack[g.BeginPopupStack.Size].Window)
|
||||
{
|
||||
// FIXME-DPI: Values should be derived from a master "scale" factor.
|
||||
ImRect next_window_rect = next_window->Rect();
|
||||
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
|
||||
ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
|
||||
ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
|
||||
float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
|
||||
ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
|
||||
tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
|
||||
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
|
||||
moving_within_opened_triangle = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
|
||||
//window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); window->DrawList->PopClipRect(); // Debug
|
||||
}
|
||||
}
|
||||
bool moving_toward_other_child_menu = false;
|
||||
|
||||
want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle);
|
||||
want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed);
|
||||
ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL;
|
||||
if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar))
|
||||
{
|
||||
// FIXME-DPI: Values should be derived from a master "scale" factor.
|
||||
ImRect next_window_rect = child_menu_window->Rect();
|
||||
ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
|
||||
ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
|
||||
ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
|
||||
float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
|
||||
ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
|
||||
tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
|
||||
tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
|
||||
moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
|
||||
//GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
|
||||
}
|
||||
if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
|
||||
want_close = true;
|
||||
|
||||
if (!menu_is_open && hovered && pressed) // Click to open
|
||||
want_open = true;
|
||||
else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
|
||||
want_open = true;
|
||||
|
||||
if (g.NavActivateId == id)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user