mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-06 13:08:47 +02:00
Merge branch 'master' into docking
# Conflicts: # docs/CHANGELOG.txt # examples/example_glfw_vulkan/main.cpp # examples/example_sdl_vulkan/main.cpp # imgui.cpp
This commit is contained in:
115
imgui.cpp
115
imgui.cpp
@ -428,7 +428,7 @@ CODE
|
||||
- 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete).
|
||||
- 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
|
||||
- 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
|
||||
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
|
||||
- 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with an arbitrary small value!
|
||||
- 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
|
||||
- 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
|
||||
- 2019/01/06 (1.67) - renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
|
||||
@ -811,7 +811,7 @@ static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock
|
||||
|
||||
// Docking
|
||||
static const float DOCKING_TRANSPARENT_PAYLOAD_ALPHA = 0.50f; // For use with io.ConfigDockingTransparentPayload. Apply to Viewport _or_ WindowBg in host viewport.
|
||||
static const float DOCKING_SPLITTER_SIZE = 2.0f;
|
||||
static const float DOCKING_SPLITTER_SIZE = 2.0f;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] FORWARD DECLARATIONS
|
||||
@ -820,7 +820,7 @@ static const float DOCKING_SPLITTER_SIZE = 2.0f;
|
||||
static void SetCurrentWindow(ImGuiWindow* window);
|
||||
static void FindHoveredWindow();
|
||||
static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags);
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window);
|
||||
|
||||
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
|
||||
static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
|
||||
@ -1700,8 +1700,8 @@ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
|
||||
// Not optimal but we very rarely use this function.
|
||||
int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
|
||||
{
|
||||
unsigned int dummy = 0;
|
||||
return ImTextCharFromUtf8(&dummy, in_text, in_text_end);
|
||||
unsigned int unused = 0;
|
||||
return ImTextCharFromUtf8(&unused, in_text, in_text_end);
|
||||
}
|
||||
|
||||
static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
|
||||
@ -2197,7 +2197,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
|
||||
*out_items_display_end = end;
|
||||
}
|
||||
|
||||
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
||||
static void SetCursorPosYAndSetupForPrevLine(float pos_y, float line_height)
|
||||
{
|
||||
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
||||
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
||||
@ -2229,7 +2229,7 @@ void ImGuiListClipper::Begin(int count, float items_height)
|
||||
{
|
||||
ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
|
||||
if (DisplayStart > 0)
|
||||
SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
|
||||
SetCursorPosYAndSetupForPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
|
||||
StepNo = 2;
|
||||
}
|
||||
}
|
||||
@ -2240,7 +2240,7 @@ void ImGuiListClipper::End()
|
||||
return;
|
||||
// In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
|
||||
if (ItemsCount < INT_MAX)
|
||||
SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
|
||||
SetCursorPosYAndSetupForPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
|
||||
ItemsCount = -1;
|
||||
StepNo = 3;
|
||||
}
|
||||
@ -2274,7 +2274,7 @@ bool ImGuiListClipper::Step()
|
||||
StepNo = 3;
|
||||
return true;
|
||||
}
|
||||
if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
|
||||
if (StepNo == 2) // Step 2: empty step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
|
||||
{
|
||||
IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0);
|
||||
StepNo = 3;
|
||||
@ -3098,7 +3098,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
if ((window->DC.ItemFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
return false;
|
||||
|
||||
// Special handling for the dummy item after Begin() which represent the title bar or tab.
|
||||
// Special handling for calling after Begin() which represent the title bar or tab.
|
||||
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
|
||||
if ((window->DC.LastItemId == window->ID || window->DC.LastItemId == window->MoveId) && window->WriteAccessed)
|
||||
return false;
|
||||
@ -3158,6 +3158,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)
|
||||
{
|
||||
@ -3524,8 +3533,8 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
||||
g.MovingWindow = NULL;
|
||||
|
||||
// Cancel moving if clicked over an item which was disabled or inhibited by popups
|
||||
if (g.HoveredId == 0 && g.HoveredIdDisabled)
|
||||
// Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already)
|
||||
if (g.HoveredIdDisabled)
|
||||
g.MovingWindow = NULL;
|
||||
}
|
||||
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
|
||||
@ -5047,7 +5056,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
|
||||
{
|
||||
FocusWindow(child_window);
|
||||
NavInitWindow(child_window, false);
|
||||
SetActiveID(id + 1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
|
||||
SetActiveID(id + 1, child_window); // Steal ActiveId with another arbitrary id so that key-press won't activate child item
|
||||
g.ActiveIdSource = ImGuiInputSource_Nav;
|
||||
}
|
||||
return ret;
|
||||
@ -6390,7 +6399,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight());
|
||||
|
||||
// Apply scrolling
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
|
||||
window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
|
||||
|
||||
// DRAWING
|
||||
@ -6472,6 +6481,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
|
||||
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
|
||||
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
|
||||
window->ParentWorkRect = window->WorkRect;
|
||||
|
||||
// [LEGACY] Content Region
|
||||
// FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
|
||||
@ -6581,17 +6591,9 @@ 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.
|
||||
if (window->DockIsActive)
|
||||
{
|
||||
window->DC.LastItemId = window->ID;
|
||||
window->DC.LastItemStatusFlags = window->DockTabItemStatusFlags;
|
||||
window->DC.LastItemRect = window->DockTabItemRect;
|
||||
}
|
||||
SetLastItemData(window, window->ID, window->DockTabItemStatusFlags, window->DockTabItemRect);
|
||||
else
|
||||
{
|
||||
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))
|
||||
@ -7696,6 +7698,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;
|
||||
@ -8063,30 +8066,20 @@ void ImGui::EndGroup()
|
||||
// [SECTION] SCROLLING
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges)
|
||||
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImVec2 scroll = window->Scroll;
|
||||
if (window->ScrollTarget.x < FLT_MAX)
|
||||
{
|
||||
float cr_x = window->ScrollTargetCenterRatio.x;
|
||||
float target_x = window->ScrollTarget.x;
|
||||
if (snap_on_edges && cr_x <= 0.0f && target_x <= window->WindowPadding.x)
|
||||
target_x = 0.0f;
|
||||
else if (snap_on_edges && cr_x >= 1.0f && target_x >= window->ContentSize.x + window->WindowPadding.x + g.Style.ItemSpacing.x)
|
||||
target_x = window->ContentSize.x + window->WindowPadding.x * 2.0f;
|
||||
scroll.x = target_x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
|
||||
}
|
||||
if (window->ScrollTarget.y < FLT_MAX)
|
||||
{
|
||||
// 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
|
||||
float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
float cr_y = window->ScrollTargetCenterRatio.y;
|
||||
float target_y = window->ScrollTarget.y;
|
||||
if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
|
||||
target_y = 0.0f;
|
||||
if (snap_on_edges && cr_y >= 1.0f && target_y >= window->ContentSize.y + window->WindowPadding.y + g.Style.ItemSpacing.y)
|
||||
target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f;
|
||||
scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height);
|
||||
}
|
||||
scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f));
|
||||
@ -8118,7 +8111,7 @@ ImVec2 ImGui::ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_
|
||||
else if (item_rect.Max.y >= window_rect.Max.y)
|
||||
SetScrollFromPosY(window, item_rect.Max.y - window->Pos.y + g.Style.ItemSpacing.y, 1.0f);
|
||||
|
||||
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false);
|
||||
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||
delta_scroll = next_scroll - window->Scroll;
|
||||
}
|
||||
|
||||
@ -8179,10 +8172,10 @@ void ImGui::SetScrollY(ImGuiWindow* window, float new_scroll_y)
|
||||
window->ScrollTargetCenterRatio.y = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
// Note that a local position will vary depending on initial scroll value
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
|
||||
{
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
|
||||
window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x);
|
||||
window->ScrollTargetCenterRatio.x = center_x_ratio;
|
||||
@ -8190,10 +8183,8 @@ void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x
|
||||
|
||||
void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
|
||||
{
|
||||
// We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
|
||||
IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
|
||||
const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
|
||||
local_y -= decoration_up_height;
|
||||
local_y -= window->TitleBarHeight() + window->MenuBarHeight(); // FIXME: Would be nice to have a more standardized access to our scrollable/client rect
|
||||
window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y);
|
||||
window->ScrollTargetCenterRatio.y = center_y_ratio;
|
||||
}
|
||||
@ -8210,15 +8201,34 @@ void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
|
||||
SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio);
|
||||
}
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge,
|
||||
// So the difference between WindowPadding and ItemSpacing will be in the visible area after scrolling.
|
||||
// When we refactor the scrolling API this may be configurable with a flag?
|
||||
// Note that the effect for this won't be visible on X axis with default Style settings as WindowPadding.x == ItemSpacing.x by default.
|
||||
static float CalcScrollSnap(float target, float snap_min, float snap_max, float snap_threshold, float center_ratio)
|
||||
{
|
||||
if (target <= snap_min + snap_threshold)
|
||||
return ImLerp(snap_min, target, center_ratio);
|
||||
if (target >= snap_max - snap_threshold)
|
||||
return ImLerp(target, snap_max, center_ratio);
|
||||
return target;
|
||||
}
|
||||
|
||||
// center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
|
||||
void ImGui::SetScrollHereX(float center_x_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float target_x = window->DC.LastItemRect.Min.x - window->Pos.x; // Left of last item, in window space
|
||||
float last_item_width = window->DC.LastItemRect.GetWidth();
|
||||
target_x += (last_item_width * center_x_ratio) + (g.Style.ItemSpacing.x * (center_x_ratio - 0.5f) * 2.0f); // Precisely aim before, in the middle or after the last item.
|
||||
SetScrollFromPosX(target_x, center_x_ratio);
|
||||
float spacing_x = g.Style.ItemSpacing.x;
|
||||
float target_x = ImLerp(window->DC.LastItemRect.Min.x - spacing_x, window->DC.LastItemRect.Max.x + spacing_x, center_x_ratio);
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge
|
||||
const float snap_x_threshold = ImMax(0.0f, window->WindowPadding.x - spacing_x);
|
||||
const float snap_x_min = window->DC.CursorStartPos.x - window->WindowPadding.x;
|
||||
const float snap_x_max = window->DC.CursorStartPos.x + window->ContentSize.x + window->WindowPadding.x;
|
||||
target_x = CalcScrollSnap(target_x, snap_x_min, snap_x_max, snap_x_threshold, center_x_ratio);
|
||||
|
||||
SetScrollFromPosX(window, target_x - window->Pos.x, center_x_ratio);
|
||||
}
|
||||
|
||||
// center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
|
||||
@ -8226,9 +8236,16 @@ void ImGui::SetScrollHereY(float center_y_ratio)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space
|
||||
target_y += (window->DC.PrevLineSize.y * center_y_ratio) + (g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
|
||||
SetScrollFromPosY(target_y, center_y_ratio);
|
||||
float spacing_y = g.Style.ItemSpacing.y;
|
||||
float target_y = ImLerp(window->DC.CursorPosPrevLine.y - spacing_y, window->DC.CursorPosPrevLine.y + window->DC.PrevLineSize.y + spacing_y, center_y_ratio);
|
||||
|
||||
// Tweak: snap on edges when aiming at an item very close to the edge
|
||||
const float snap_y_threshold = ImMax(0.0f, window->WindowPadding.y - spacing_y);
|
||||
const float snap_y_min = window->DC.CursorStartPos.y - window->WindowPadding.y;
|
||||
const float snap_y_max = window->DC.CursorStartPos.y + window->ContentSize.y + window->WindowPadding.y;
|
||||
target_y = CalcScrollSnap(target_y, snap_y_min, snap_y_max, snap_y_threshold, center_y_ratio);
|
||||
|
||||
SetScrollFromPosY(window, target_y - window->Pos.y, center_y_ratio);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -8590,7 +8607,7 @@ void ImGui::EndPopup()
|
||||
g.WithinEndChild = false;
|
||||
}
|
||||
|
||||
// Open a popup if mouse is released over the item
|
||||
// Open a popup if mouse button is released over the item
|
||||
bool ImGui::OpenPopupContextItem(const char* str_id, ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiWindow* window = GImGui->CurrentWindow;
|
||||
|
Reference in New Issue
Block a user