mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-18 06:06:35 +00:00
Merge branch 'master' into navigation
# Conflicts: # imgui.cpp # imgui_internal.h
This commit is contained in:
commit
db071184a0
65
imgui.cpp
65
imgui.cpp
@ -2393,18 +2393,17 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
|
||||
|
||||
window->DC.LastItemId = id;
|
||||
window->DC.LastItemRect = bb;
|
||||
window->DC.LastItemStatusFlags = 0;
|
||||
|
||||
// Clipping test
|
||||
const bool is_clipped = IsClippedEx(bb, id, false);
|
||||
if (is_clipped)
|
||||
{
|
||||
window->DC.LastItemRectHoveredRect = false;
|
||||
return false;
|
||||
}
|
||||
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
|
||||
|
||||
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
|
||||
window->DC.LastItemRectHoveredRect = IsMouseHoveringRect(bb.Min, bb.Max);
|
||||
if (IsMouseHoveringRect(bb.Min, bb.Max))
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2419,7 +2418,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
|
||||
return IsItemFocused();
|
||||
|
||||
// Test for bounding box overlap, as updated as ItemAdd()
|
||||
if (!window->DC.LastItemRectHoveredRect)
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function
|
||||
|
||||
@ -6051,8 +6050,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
|
||||
// After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of 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;
|
||||
window->DC.LastItemRectHoveredRect = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false);
|
||||
}
|
||||
|
||||
// Inner clipping rectangle
|
||||
@ -7898,12 +7897,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// We vertically grow up to current line height up the typical widget height.
|
||||
const float text_base_offset_y = ImMax(padding.y, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it
|
||||
const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2);
|
||||
ImRect bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height));
|
||||
ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height));
|
||||
if (display_frame)
|
||||
{
|
||||
// Framed header expand a little outside the default padding
|
||||
bb.Min.x -= (float)(int)(window->WindowPadding.x*0.5f) - 1;
|
||||
bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1;
|
||||
frame_bb.Min.x -= (float)(int)(window->WindowPadding.x*0.5f) - 1;
|
||||
frame_bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1;
|
||||
}
|
||||
|
||||
const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing
|
||||
@ -7912,7 +7911,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing
|
||||
// (Ideally we'd want to add a flag for the user to specify if we want the hit test to be done up to the right side of the content or not)
|
||||
const ImRect interact_bb = display_frame ? bb : ImRect(bb.Min.x, bb.Min.y, bb.Min.x + text_width + style.ItemSpacing.x*2, bb.Max.y);
|
||||
const ImRect interact_bb = display_frame ? frame_bb : ImRect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + text_width + style.ItemSpacing.x*2, frame_bb.Max.y);
|
||||
bool is_open = TreeNodeBehaviorIsOpen(id, flags);
|
||||
|
||||
// Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child.
|
||||
@ -7921,7 +7920,11 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavCloseFromChild) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
window->DC.TreeDepthMayCloseOnPop |= (1 << window->DC.TreeDepth);
|
||||
|
||||
if (!ItemAdd(interact_bb, id))
|
||||
bool item_add = ItemAdd(interact_bb, id);
|
||||
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDisplayRect;
|
||||
window->DC.LastItemDisplayRect = frame_bb;
|
||||
|
||||
if (!item_add)
|
||||
{
|
||||
if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
TreePushRawID(id);
|
||||
@ -7976,25 +7979,25 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
|
||||
// Render
|
||||
const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||
const ImVec2 text_pos = bb.Min + ImVec2(text_offset_x, text_base_offset_y);
|
||||
const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y);
|
||||
if (display_frame)
|
||||
{
|
||||
// Framed type
|
||||
RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding);
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
RenderTriangle(bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding);
|
||||
RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
RenderTriangle(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f);
|
||||
if (g.LogEnabled)
|
||||
{
|
||||
// NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here.
|
||||
const char log_prefix[] = "\n##";
|
||||
const char log_suffix[] = "##";
|
||||
LogRenderedText(&text_pos, log_prefix, log_prefix+3);
|
||||
RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
LogRenderedText(&text_pos, log_suffix+1, log_suffix+3);
|
||||
}
|
||||
else
|
||||
{
|
||||
RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size);
|
||||
RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -8002,13 +8005,14 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
// Unframed typed for tree nodes
|
||||
if (hovered || (flags & ImGuiTreeNodeFlags_Selected))
|
||||
{
|
||||
RenderFrame(bb.Min, bb.Max, col, false);
|
||||
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
RenderFrame(frame_bb.Min, frame_bb.Max, col, false);
|
||||
RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin);
|
||||
}
|
||||
|
||||
if (flags & ImGuiTreeNodeFlags_Bullet)
|
||||
RenderBullet(bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
|
||||
RenderBullet(frame_bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y));
|
||||
else if (!(flags & ImGuiTreeNodeFlags_Leaf))
|
||||
RenderTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
||||
RenderTriangle(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f);
|
||||
if (g.LogEnabled)
|
||||
LogRenderedText(&text_pos, ">");
|
||||
RenderText(text_pos, label, label_end, false);
|
||||
@ -10792,7 +10796,7 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
|
||||
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
|
||||
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
||||
ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
||||
window->DC.LastItemRect = bb;
|
||||
window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy.
|
||||
|
||||
BeginGroup();
|
||||
if (label_size.x > 0)
|
||||
@ -11600,7 +11604,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
EndGroup();
|
||||
|
||||
// Drag and Drop Target
|
||||
if (window->DC.LastItemRectHoveredRect && BeginDragDropTarget()) // NB: The LastItemRectHoveredRect test is merely an optional micro-optimization
|
||||
if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) && BeginDragDropTarget()) // NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test.
|
||||
{
|
||||
if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
{
|
||||
@ -12021,9 +12025,9 @@ bool ImGui::SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float
|
||||
|
||||
const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
|
||||
window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
|
||||
bool add = ItemAdd(bb, id);
|
||||
bool item_add = ItemAdd(bb, id);
|
||||
window->DC.ItemFlags = item_flags_backup;
|
||||
if (!add)
|
||||
if (!item_add)
|
||||
return false;
|
||||
|
||||
bool hovered, held;
|
||||
@ -12666,7 +12670,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button)
|
||||
// We build a throwaway ID based on current ID stack + relative AABB of items in window.
|
||||
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
|
||||
// We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
|
||||
bool is_hovered = window->DC.LastItemRectHoveredRect;
|
||||
bool is_hovered = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) != 0;
|
||||
if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window))
|
||||
return false;
|
||||
source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect);
|
||||
@ -12717,7 +12721,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button)
|
||||
}
|
||||
|
||||
if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern))
|
||||
window->DC.LastItemRectHoveredRect = false;
|
||||
window->DC.LastItemStatusFlags &= ~ImGuiItemStatusFlags_HoveredRect;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -12814,18 +12818,19 @@ bool ImGui::BeginDragDropTarget()
|
||||
return false;
|
||||
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!window->DC.LastItemRectHoveredRect)
|
||||
if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect))
|
||||
return false;
|
||||
if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
|
||||
return false;
|
||||
|
||||
const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
|
||||
ImGuiID id = window->DC.LastItemId;
|
||||
if (id == 0)
|
||||
id = window->GetIDFromRectangle(window->DC.LastItemRect);
|
||||
id = window->GetIDFromRectangle(display_rect);
|
||||
if (g.DragDropPayload.SourceId == id)
|
||||
return false;
|
||||
|
||||
g.DragDropTargetRect = window->DC.LastItemRect;
|
||||
g.DragDropTargetRect = display_rect;
|
||||
g.DragDropTargetId = id;
|
||||
return true;
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ struct ImGuiWindowSettings;
|
||||
typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_
|
||||
typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_
|
||||
typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_
|
||||
typedef int ImGuiItemStatusFlags; // flags: storage for DC.LastItemXXX // enum ImGuiItemStatusFlags_
|
||||
typedef int ImGuiNavHighlightFlags; // flags: for RenderNavHighlight() // enum ImGuiNavHighlightFlags_
|
||||
typedef int ImGuiNavDirSourceFlags; // flags: for GetNavInputAmount2d() // enum ImGuiNavDirSourceFlags_
|
||||
typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_
|
||||
@ -220,6 +221,13 @@ enum ImGuiSeparatorFlags_
|
||||
ImGuiSeparatorFlags_Vertical = 1 << 1
|
||||
};
|
||||
|
||||
// Storage for LastItem data
|
||||
enum ImGuiItemStatusFlags_
|
||||
{
|
||||
ImGuiItemStatusFlags_HoveredRect = 1 << 0,
|
||||
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1
|
||||
};
|
||||
|
||||
// FIXME: this is in development, not exposed/functional as a generic feature yet.
|
||||
enum ImGuiLayoutType_
|
||||
{
|
||||
@ -795,6 +803,7 @@ struct ImGuiContext
|
||||
};
|
||||
|
||||
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
|
||||
// This is going to be exposed in imgui.h when stabilized enough.
|
||||
enum ImGuiItemFlags_
|
||||
{
|
||||
ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true
|
||||
@ -822,8 +831,9 @@ struct IMGUI_API ImGuiDrawContext
|
||||
int TreeDepth;
|
||||
ImU32 TreeDepthMayCloseOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31
|
||||
ImGuiID LastItemId;
|
||||
ImRect LastItemRect;
|
||||
bool LastItemRectHoveredRect;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect; // Interaction rect
|
||||
ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect)
|
||||
bool NavHideHighlightOneFrame;
|
||||
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
|
||||
int NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
|
||||
@ -861,8 +871,8 @@ struct IMGUI_API ImGuiDrawContext
|
||||
TreeDepth = 0;
|
||||
TreeDepthMayCloseOnPop = 0x00;
|
||||
LastItemId = 0;
|
||||
LastItemRect = ImRect();
|
||||
LastItemRectHoveredRect = false;
|
||||
LastItemStatusFlags = 0;
|
||||
LastItemRect = LastItemDisplayRect = ImRect();
|
||||
NavHideHighlightOneFrame = false;
|
||||
NavHasScroll = false;
|
||||
NavLayerActiveMask = NavLayerActiveMaskNext = 0x00;
|
||||
@ -982,13 +992,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
|
||||
{
|
||||
ImGuiID LastItemId;
|
||||
ImRect LastItemRect;
|
||||
bool LastItemRectHoveredRect;
|
||||
ImGuiID LastItemId;
|
||||
ImGuiItemStatusFlags LastItemStatusFlags;
|
||||
ImRect LastItemRect;
|
||||
ImRect LastItemDisplayRect;
|
||||
|
||||
ImGuiItemHoveredDataBackup() { Backup(); }
|
||||
void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; }
|
||||
void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; }
|
||||
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; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user