diff --git a/imgui.cpp b/imgui.cpp index 54f5e229..5abfb843 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -714,7 +714,6 @@ namespace ImGui static void NavUpdate(); static void NavUpdateWindowing(); static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id); -static void ClearDragDrop(); static void FocusPreviousWindow(); } @@ -1869,7 +1868,6 @@ ImGuiWindow::ImGuiWindow(const char* name) ID = ImHash(name, 0); IDStack.push_back(ID); Flags = 0; - OrderWithinParent = 0; PosFloat = Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); @@ -1890,6 +1888,8 @@ ImGuiWindow::ImGuiWindow(const char* name) SkipItems = false; Appearing = false; CloseButton = false; + BeginOrderWithinParent = -1; + BeginOrderWithinContext = -1; BeginCount = 0; PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; @@ -3066,6 +3066,7 @@ void ImGui::NewFrame() g.Time += g.IO.DeltaTime; g.FrameCount += 1; g.TooltipOverrideCount = 0; + g.WindowsActiveCount = 0; g.OverlayDrawList.Clear(); g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); g.OverlayDrawList.PushClipRectFullScreen(); @@ -3589,7 +3590,7 @@ static int ChildWindowComparer(const void* lhs, const void* rhs) return d; if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) return d; - return (a->OrderWithinParent - b->OrderWithinParent); + return (a->BeginOrderWithinParent - b->BeginOrderWithinParent); } static void AddWindowToSortedBuffer(ImVector& out_sorted_windows, ImGuiWindow* window) @@ -5354,7 +5355,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // window->RootNavWindow = window->RootNavWindow->ParentWindow; window->Active = true; - window->OrderWithinParent = 0; + window->BeginOrderWithinParent = 0; + window->BeginOrderWithinContext = g.WindowsActiveCount++; window->BeginCount = 0; window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); window->LastFrameActive = current_frame; @@ -5477,7 +5479,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Position child window if (flags & ImGuiWindowFlags_ChildWindow) { - window->OrderWithinParent = parent_window->DC.ChildWindows.Size; + window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); } if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api) @@ -7834,7 +7836,6 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags ImGuiContext& g = *GImGui; float button_sz = g.FontSize * 0.5f; ImGuiItemHoveredDataBackup last_item_backup; - last_item_backup.Backup(); if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) *p_open = false; last_item_backup.Restore(); @@ -12321,7 +12322,7 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) // DRAG AND DROP //----------------------------------------------------------------------------- -static void ImGui::ClearDragDrop() +void ImGui::ClearDragDrop() { ImGuiContext& g = *GImGui; g.DragDropActive = false; @@ -12510,6 +12511,12 @@ bool ImGui::BeginDragDropTarget() return true; } +bool ImGui::IsDragDropPayloadBeingAccepted() +{ + ImGuiContext& g = *GImGui; + return g.DragDropActive && g.DragDropAcceptIdPrev != 0; +} + const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { ImGuiContext& g = *GImGui; diff --git a/imgui.h b/imgui.h index 35759135..88588576 100644 --- a/imgui.h +++ b/imgui.h @@ -81,8 +81,8 @@ typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ -typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ @@ -635,7 +635,7 @@ enum ImGuiHoveredFlags_ ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 2, // Return true even if a popup window is normally blocking access to this item/window //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 3, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 4, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 5, // Return true even if the position is overlapped by another window ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped }; @@ -1095,6 +1095,7 @@ public: inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } + inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } }; // Helper: execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. diff --git a/imgui_internal.h b/imgui_internal.h index f85e4bb5..22ce501a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -458,6 +458,7 @@ struct ImGuiContext ImVector WindowsSortBuffer; ImVector CurrentWindowStack; ImGuiStorage WindowsById; + int WindowsActiveCount; ImGuiWindow* CurrentWindow; // Being drawn into ImGuiWindow* HoveredWindow; // Will catch mouse inputs ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) @@ -606,6 +607,7 @@ struct ImGuiContext Time = 0.0f; FrameCount = 0; FrameCountEnded = FrameCountRendered = -1; + WindowsActiveCount = 0; CurrentWindow = NULL; HoveredWindow = NULL; HoveredRootWindow = NULL; @@ -815,7 +817,6 @@ struct IMGUI_API ImGuiWindow char* Name; ImGuiID ID; // == ImHash(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ - int OrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. ImVec2 PosFloat; ImVec2 Pos; // Position rounded-up to nearest pixel ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) @@ -842,6 +843,8 @@ struct IMGUI_API ImGuiWindow bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool CloseButton; // Set when the window has a close button (p_open != NULL) + int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. + int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues. int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; @@ -908,8 +911,9 @@ struct ImGuiItemHoveredDataBackup ImRect LastItemRect; bool LastItemRectHoveredRect; - void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemRect = window->DC.LastItemRect; LastItemRectHoveredRect = window->DC.LastItemRectHoveredRect; } - void Restore() { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemRect = LastItemRect; window->DC.LastItemRectHoveredRect = LastItemRectHoveredRect; } + 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; } }; //----------------------------------------------------------------------------- @@ -973,6 +977,8 @@ namespace ImGui IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f); IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); + IMGUI_API void ClearDragDrop(); + IMGUI_API bool IsDragDropPayloadBeingAccepted(); // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().