mirror of
https://github.com/ocornut/imgui.git
synced 2026-01-13 00:24:20 +00:00
merge v1.92.4
This commit is contained in:
parent
c425843be3
commit
44cff4493c
64 changed files with 1674 additions and 514 deletions
188
imgui.cpp
188
imgui.cpp
|
|
@ -1,4 +1,4 @@
|
|||
// dear imgui, v1.92.3
|
||||
// dear imgui, v1.92.4
|
||||
// (main code and documentation)
|
||||
|
||||
// Help:
|
||||
|
|
@ -392,6 +392,10 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
|||
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2025/10/14 (1.92.4) - TreeNode, Selectable, Clipper: commented out legacy names which were obsoleted in 1.89.7 (July 2023) and 1.89.9 (Sept 2023);
|
||||
- ImGuiTreeNodeFlags_AllowItemOverlap --> ImGuiTreeNodeFlags_AllowOverlap
|
||||
- ImGuiSelectableFlags_AllowItemOverlap --> ImGuiSelectableFlags_AllowOverlap
|
||||
- ImGuiListClipper::IncludeRangeByIndices() --> ImGuiListClipper::IncludeItemsByIndex()
|
||||
- 2025/08/08 (1.92.2) - Backends: SDL_GPU3: Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
|
||||
- 2025/07/31 (1.92.2) - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. Kept inline redirection enum (will obsolete).
|
||||
- 2025/06/25 (1.92.0) - Layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM
|
||||
|
|
@ -1055,6 +1059,7 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
|||
associated with it.
|
||||
|
||||
Q: What is this library called?
|
||||
Q: What is the difference between Dear ImGui and traditional UI toolkits?
|
||||
Q: Which version should I get?
|
||||
>> This library is called "Dear ImGui", please don't call it "ImGui" :)
|
||||
>> See https://www.dearimgui.com/faq for details.
|
||||
|
|
@ -3692,6 +3697,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx)
|
|||
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
|
||||
case ImGuiCol_TreeLines: return "TreeLines";
|
||||
case ImGuiCol_DragDropTarget: return "DragDropTarget";
|
||||
case ImGuiCol_UnsavedMarker: return "UnsavedMarker";
|
||||
case ImGuiCol_NavCursor: return "NavCursor";
|
||||
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
|
||||
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
|
||||
|
|
@ -3814,7 +3820,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons
|
|||
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
|
||||
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) from 'ellipsis_max_x' which may be beyond it.
|
||||
// This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
|
||||
// (BREAKING) On 2025/04/16 we removed the 'float clip_max_x' parameters which was preceeding 'float ellipsis_max' and was the same value for 99% of users.
|
||||
// (BREAKING) On 2025/04/16 we removed the 'float clip_max_x' parameters which was preceding 'float ellipsis_max' and was the same value for 99% of users.
|
||||
void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
|
@ -4159,6 +4165,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
|||
DragDropSourceFrameCount = -1;
|
||||
DragDropMouseButton = -1;
|
||||
DragDropTargetId = 0;
|
||||
DragDropTargetFullViewport = 0;
|
||||
DragDropAcceptFlags = ImGuiDragDropFlags_None;
|
||||
DragDropAcceptIdCurrRectSurface = 0.0f;
|
||||
DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
|
||||
|
|
@ -4326,7 +4333,7 @@ void ImGui::Shutdown()
|
|||
for (ImFontAtlas* atlas : g.FontAtlases)
|
||||
{
|
||||
UnregisterFontAtlas(atlas);
|
||||
if (atlas->OwnerContext == &g)
|
||||
if (atlas->RefCount == 0)
|
||||
{
|
||||
atlas->Locked = false;
|
||||
IM_DELETE(atlas);
|
||||
|
|
@ -4636,7 +4643,8 @@ void ImGui::MarkItemEdited(ImGuiID id)
|
|||
|
||||
// We accept a MarkItemEdited() on drag and drop targets (see https://github.com/ocornut/imgui/issues/1875#issuecomment-978243343)
|
||||
// We accept 'ActiveIdPreviousFrame == id' for InputText() returning an edit after it has been taken ActiveId away (#4714)
|
||||
IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id || (g.CurrentMultiSelect != NULL && g.BoxSelectState.IsActive));
|
||||
// FIXME: This assert is getting a bit meaningless over time. It helped detect some unusual use cases but eventually it is becoming an unnecessary restriction.
|
||||
IM_ASSERT(g.DragDropActive || g.ActiveId == id || g.ActiveId == 0 || g.ActiveIdPreviousFrame == id || g.NavJustMovedToId || (g.CurrentMultiSelect != NULL && g.BoxSelectState.IsActive));
|
||||
|
||||
//IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
|
||||
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_Edited;
|
||||
|
|
@ -6647,8 +6655,20 @@ static ImGuiCol GetWindowBgColorIdx(ImGuiWindow* window)
|
|||
return ImGuiCol_WindowBg;
|
||||
}
|
||||
|
||||
static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size)
|
||||
static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target_arg, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size)
|
||||
{
|
||||
ImVec2 corner_target = corner_target_arg;
|
||||
if (window->Flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
|
||||
{
|
||||
ImGuiWindow* parent_window = window->ParentWindow;
|
||||
ImGuiWindowFlags parent_flags = parent_window->Flags;
|
||||
ImRect limit_rect = parent_window->InnerRect;
|
||||
limit_rect.Expand(ImVec2(-ImMax(parent_window->WindowPadding.x, parent_window->WindowBorderSize), -ImMax(parent_window->WindowPadding.y, parent_window->WindowBorderSize)));
|
||||
if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar))
|
||||
corner_target.x = ImClamp(corner_target.x, limit_rect.Min.x, limit_rect.Max.x);
|
||||
if (parent_flags & ImGuiWindowFlags_NoScrollbar)
|
||||
corner_target.y = ImClamp(corner_target.y, limit_rect.Min.y, limit_rect.Max.y);
|
||||
}
|
||||
ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left
|
||||
ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right
|
||||
ImVec2 size_expected = pos_max - pos_min;
|
||||
|
|
@ -6793,7 +6813,8 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
|||
}
|
||||
|
||||
// Only lower-left grip is visible before hovering/activating
|
||||
if (resize_grip_n == 0 || held || hovered)
|
||||
const bool resize_grip_visible = held || hovered || (resize_grip_n == 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0);
|
||||
if (resize_grip_visible)
|
||||
resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
|
||||
}
|
||||
|
||||
|
|
@ -6868,17 +6889,6 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si
|
|||
ImVec2 clamp_min(border_n == ImGuiDir_Right ? clamp_rect.Min.x : -FLT_MAX, border_n == ImGuiDir_Down || (border_n == ImGuiDir_Up && window_move_from_title_bar) ? clamp_rect.Min.y : -FLT_MAX);
|
||||
ImVec2 clamp_max(border_n == ImGuiDir_Left ? clamp_rect.Max.x : +FLT_MAX, border_n == ImGuiDir_Up ? clamp_rect.Max.y : +FLT_MAX);
|
||||
border_target = ImClamp(border_target, clamp_min, clamp_max);
|
||||
if (flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent
|
||||
{
|
||||
ImGuiWindow* parent_window = window->ParentWindow;
|
||||
ImGuiWindowFlags parent_flags = parent_window->Flags;
|
||||
ImRect border_limit_rect = parent_window->InnerRect;
|
||||
border_limit_rect.Expand(ImVec2(-ImMax(parent_window->WindowPadding.x, parent_window->WindowBorderSize), -ImMax(parent_window->WindowPadding.y, parent_window->WindowBorderSize)));
|
||||
if ((axis == ImGuiAxis_X) && ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar)))
|
||||
border_target.x = ImClamp(border_target.x, border_limit_rect.Min.x, border_limit_rect.Max.x);
|
||||
if ((axis == ImGuiAxis_Y) && (parent_flags & ImGuiWindowFlags_NoScrollbar))
|
||||
border_target.y = ImClamp(border_target.y, border_limit_rect.Min.y, border_limit_rect.Max.y);
|
||||
}
|
||||
if (!ignore_resize)
|
||||
CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target);
|
||||
}
|
||||
|
|
@ -7165,7 +7175,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
|
|||
marker_pos.y = (layout_r.Min.y + layout_r.Max.y) * 0.5f;
|
||||
if (marker_pos.x > layout_r.Min.x)
|
||||
{
|
||||
RenderBullet(window->DrawList, marker_pos, GetColorU32(ImGuiCol_Text));
|
||||
RenderBullet(window->DrawList, marker_pos, GetColorU32(ImGuiCol_UnsavedMarker));
|
||||
clip_r.Max.x = ImMin(clip_r.Max.x, marker_pos.x - (int)(marker_size_x * 0.5f));
|
||||
}
|
||||
}
|
||||
|
|
@ -7182,7 +7192,7 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags
|
|||
window->RootWindow = parent_window->RootWindow;
|
||||
if (parent_window && (flags & ImGuiWindowFlags_Popup))
|
||||
window->RootWindowPopupTree = parent_window->RootWindowPopupTree;
|
||||
if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)))
|
||||
if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)))
|
||||
window->RootWindowForTitleBarHighlight = parent_window->RootWindowForTitleBarHighlight;
|
||||
while (window->RootWindowForNav->ChildFlags & ImGuiChildFlags_NavFlattened)
|
||||
{
|
||||
|
|
@ -7291,7 +7301,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||
|
||||
// Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
|
||||
ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back().Window;
|
||||
ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow;
|
||||
ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) ? parent_window_in_stack : NULL) : window->ParentWindow;
|
||||
IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
|
||||
|
||||
// We allow window memory to be compacted so recreate the base stack when needed.
|
||||
|
|
@ -7655,9 +7665,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||
handle_borders_and_resize_grips = false;
|
||||
|
||||
// Handle manual resize: Resize Grips, Borders, Gamepad
|
||||
// Child windows can only be resized when they have the flags set. The resize grip allows resizing in both directions, so it should appear only if both flags are set.
|
||||
int border_hovered = -1, border_held = -1;
|
||||
ImU32 resize_grip_col[4] = {};
|
||||
const int resize_grip_count = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup)) ? 0 : g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||
int resize_grip_count;
|
||||
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup))
|
||||
resize_grip_count = ((window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY)) ? 1 : 0;
|
||||
else
|
||||
resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
|
||||
|
||||
const float resize_grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
|
||||
if (handle_borders_and_resize_grips && !window->Collapsed)
|
||||
if (int auto_fit_mask = UpdateWindowManualResize(window, size_auto_fit, &border_hovered, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
|
||||
|
|
@ -8833,6 +8849,8 @@ void ImGui::RegisterFontAtlas(ImFontAtlas* atlas)
|
|||
atlas->RefCount++;
|
||||
g.FontAtlases.push_back(atlas);
|
||||
ImFontAtlasAddDrawListSharedData(atlas, &g.DrawListSharedData);
|
||||
for (ImTextureData* tex : atlas->TexList)
|
||||
tex->RefCount = (unsigned short)atlas->RefCount;
|
||||
}
|
||||
|
||||
void ImGui::UnregisterFontAtlas(ImFontAtlas* atlas)
|
||||
|
|
@ -8842,6 +8860,8 @@ void ImGui::UnregisterFontAtlas(ImFontAtlas* atlas)
|
|||
ImFontAtlasRemoveDrawListSharedData(atlas, &g.DrawListSharedData);
|
||||
g.FontAtlases.find_erase(atlas);
|
||||
atlas->RefCount--;
|
||||
for (ImTextureData* tex : atlas->TexList)
|
||||
tex->RefCount = (unsigned short)atlas->RefCount;
|
||||
}
|
||||
|
||||
// Use ImDrawList::_SetTexture(), making our shared g.FontStack[] authoritative against window-local ImDrawList.
|
||||
|
|
@ -9363,7 +9383,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt)
|
|||
routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore;
|
||||
routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry
|
||||
routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner;
|
||||
routing_entry->RoutingNextScore = 255;
|
||||
routing_entry->RoutingNextScore = 0;
|
||||
if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner)
|
||||
continue;
|
||||
rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer
|
||||
|
|
@ -9432,23 +9452,24 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord)
|
|||
return routing_data;
|
||||
}
|
||||
|
||||
// Current score encoding (lower is highest priority):
|
||||
// - 0: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive
|
||||
// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active)
|
||||
// - 2: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused
|
||||
// - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack)
|
||||
// - 254: ImGuiInputFlags_RouteGlobal
|
||||
// - 255: never route
|
||||
// Current score encoding
|
||||
// - 0: Never route
|
||||
// - 1: ImGuiInputFlags_RouteGlobal (lower priority)
|
||||
// - 100..199: ImGuiInputFlags_RouteFocused (if window in focus-stack)
|
||||
// 200: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused
|
||||
// 300: ImGuiInputFlags_RouteActive or ImGuiInputFlags_RouteFocused (if item active)
|
||||
// 400: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive
|
||||
// - 500..599: ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteOverActive (if window in focus-stack) (higher priority)
|
||||
// 'flags' should include an explicit routing policy
|
||||
static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (flags & ImGuiInputFlags_RouteFocused)
|
||||
{
|
||||
// ActiveID gets top priority
|
||||
// ActiveID gets high priority
|
||||
// (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it)
|
||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||
return 1;
|
||||
return 300;
|
||||
|
||||
// Score based on distance to focused window (lower is better)
|
||||
// Assuming both windows are submitting a routing request,
|
||||
|
|
@ -9458,25 +9479,32 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
|||
// - When Window/ChildB is focused -> Window scores 4 (best), Window/ChildB doesn't have a score.
|
||||
// This essentially follow the window->ParentWindowForFocusRoute chain.
|
||||
if (focus_scope_id == 0)
|
||||
return 255;
|
||||
return 0;
|
||||
for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++)
|
||||
if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id)
|
||||
return 3 + index_in_focus_path;
|
||||
return 255;
|
||||
{
|
||||
if (flags & ImGuiInputFlags_RouteOverActive) // && g.ActiveId != 0 && g.ActiveId != owner_id)
|
||||
return 599 - index_in_focus_path;
|
||||
else
|
||||
return 199 - index_in_focus_path;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else if (flags & ImGuiInputFlags_RouteActive)
|
||||
{
|
||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||
return 1;
|
||||
return 255;
|
||||
return 300;
|
||||
return 0;
|
||||
}
|
||||
else if (flags & ImGuiInputFlags_RouteGlobal)
|
||||
{
|
||||
if (flags & ImGuiInputFlags_RouteOverActive)
|
||||
return 0;
|
||||
return 400;
|
||||
if (owner_id != 0 && g.ActiveId == owner_id)
|
||||
return 300;
|
||||
if (flags & ImGuiInputFlags_RouteOverFocused)
|
||||
return 2;
|
||||
return 254;
|
||||
return 200;
|
||||
return 1;
|
||||
}
|
||||
IM_ASSERT(0);
|
||||
return 0;
|
||||
|
|
@ -9516,8 +9544,10 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
|||
else
|
||||
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteTypeMask_)); // Check that only 1 routing flag is used
|
||||
IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_NoOwner);
|
||||
if (flags & (ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused))
|
||||
if (flags & (ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteUnlessBgFocused))
|
||||
IM_ASSERT(flags & ImGuiInputFlags_RouteGlobal);
|
||||
if (flags & ImGuiInputFlags_RouteOverActive)
|
||||
IM_ASSERT(flags & (ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteFocused));
|
||||
|
||||
// Add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified.
|
||||
key_chord = FixupKeyChord(key_chord);
|
||||
|
|
@ -9572,17 +9602,17 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, I
|
|||
|
||||
const int score = CalcRoutingScore(focus_scope_id, owner_id, flags);
|
||||
IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score);
|
||||
if (score == 255)
|
||||
if (score == 0)
|
||||
return false;
|
||||
|
||||
// Submit routing for NEXT frame (assuming score is sufficient)
|
||||
// FIXME: Could expose a way to use a "serve last" policy for same score resolution (using <= instead of <).
|
||||
// FIXME: Could expose a way to use a "serve last" policy for same score resolution (using >= instead of >).
|
||||
ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord);
|
||||
//const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score <= routing_data->RoutingNextScore) : (score < routing_data->RoutingNextScore);
|
||||
if (score < routing_data->RoutingNextScore)
|
||||
//const bool set_route = (flags & ImGuiInputFlags_ServeLast) ? (score >= routing_data->RoutingNextScore) : (score > routing_data->RoutingNextScore);
|
||||
if (score > routing_data->RoutingNextScore)
|
||||
{
|
||||
routing_data->RoutingNext = owner_id;
|
||||
routing_data->RoutingNextScore = (ImU8)score;
|
||||
routing_data->RoutingNextScore = (ImU16)score;
|
||||
}
|
||||
|
||||
// Return routing state for CURRENT frame
|
||||
|
|
@ -13431,7 +13461,7 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
|
|||
ImRect ref_rect;
|
||||
if (activated_shortcut)
|
||||
ref_rect = g.LastItemData.NavRect;
|
||||
else
|
||||
else if (window != NULL)
|
||||
ref_rect = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]);
|
||||
|
||||
// Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?)
|
||||
|
|
@ -14709,6 +14739,31 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id)
|
|||
g.DragDropTargetRect = bb;
|
||||
g.DragDropTargetClipRect = window->ClipRect; // May want to be overridden by user depending on use case?
|
||||
g.DragDropTargetId = id;
|
||||
g.DragDropTargetFullViewport = 0;
|
||||
g.DragDropWithinTarget = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Typical usage would be:
|
||||
// if (!ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
|
||||
// if (ImGui::BeginDragDropTargetViewport(ImGui::GetMainViewport(), NULL))
|
||||
// But we are leaving the hover test to the caller for maximum flexibility.
|
||||
bool ImGui::BeginDragDropTargetViewport(ImGuiViewport* viewport, const ImRect* p_bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!g.DragDropActive)
|
||||
return false;
|
||||
|
||||
ImRect bb = p_bb ? *p_bb : ((ImGuiViewportP*)viewport)->GetWorkRect();
|
||||
ImGuiID id = viewport->ID;
|
||||
if (!IsMouseHoveringRect(bb.Min, bb.Max, false) || (id == g.DragDropPayload.SourceId))
|
||||
return false;
|
||||
|
||||
IM_ASSERT(g.DragDropWithinTarget == false && g.DragDropWithinSource == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget()
|
||||
g.DragDropTargetRect = bb;
|
||||
g.DragDropTargetClipRect = bb;
|
||||
g.DragDropTargetId = id;
|
||||
g.DragDropTargetFullViewport = id;
|
||||
g.DragDropWithinTarget = true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -14779,8 +14834,17 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|||
// Render default drop visuals
|
||||
payload.Preview = was_accepted_previously;
|
||||
flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame)
|
||||
if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview)
|
||||
RenderDragDropTargetRect(r, g.DragDropTargetClipRect);
|
||||
const bool draw_target_rect = payload.Preview && !(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect);
|
||||
if (draw_target_rect && g.DragDropTargetFullViewport != 0)
|
||||
{
|
||||
ImRect bb = g.DragDropTargetRect;
|
||||
bb.Expand(-3.5f);
|
||||
RenderDragDropTargetRectEx(GetForegroundDrawList(), bb);
|
||||
}
|
||||
else if (draw_target_rect)
|
||||
{
|
||||
RenderDragDropTargetRectForItem(r);
|
||||
}
|
||||
|
||||
g.DragDropAcceptFrameCount = g.FrameCount;
|
||||
if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1)
|
||||
|
|
@ -14796,21 +14860,26 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
|||
}
|
||||
|
||||
// FIXME-STYLE FIXME-DRAGDROP: Settle on a proper default visuals for drop target.
|
||||
void ImGui::RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect)
|
||||
void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImRect bb_display = bb;
|
||||
bb_display.ClipWith(item_clip_rect); // Clip THEN expand so we have a way to visualize that target is not entirely visible.
|
||||
bb_display.ClipWith(g.DragDropTargetClipRect); // Clip THEN expand so we have a way to visualize that target is not entirely visible.
|
||||
bb_display.Expand(3.5f);
|
||||
bool push_clip_rect = !window->ClipRect.Contains(bb_display);
|
||||
if (push_clip_rect)
|
||||
window->DrawList->PushClipRectFullScreen();
|
||||
window->DrawList->AddRect(bb_display.Min, bb_display.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); // FIXME-DPI
|
||||
RenderDragDropTargetRectEx(window->DrawList, bb_display);
|
||||
if (push_clip_rect)
|
||||
window->DrawList->PopClipRect();
|
||||
}
|
||||
|
||||
void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb)
|
||||
{
|
||||
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, 0, 2.0f); // FIXME-DPI
|
||||
}
|
||||
|
||||
const ImGuiPayload* ImGui::GetDragDropPayload()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
|
@ -15453,6 +15522,23 @@ void ImGui::LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count)
|
|||
// (this section is more complete in the 'docking' branch)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void ImGuiPlatformIO::ClearPlatformHandlers()
|
||||
{
|
||||
Platform_GetClipboardTextFn = NULL;
|
||||
Platform_SetClipboardTextFn = NULL;
|
||||
Platform_ClipboardUserData = NULL;
|
||||
Platform_OpenInShellFn = NULL;
|
||||
Platform_OpenInShellUserData = NULL;
|
||||
Platform_SetImeDataFn = NULL;
|
||||
Platform_ImeUserData = NULL;
|
||||
}
|
||||
|
||||
void ImGuiPlatformIO::ClearRendererHandlers()
|
||||
{
|
||||
Renderer_TextureMaxWidth = Renderer_TextureMaxHeight = 0;
|
||||
Renderer_RenderState = NULL;
|
||||
}
|
||||
|
||||
ImGuiViewport* ImGui::GetMainViewport()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue