mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 22:16:53 +07:00
switch imgui branch to docking
This commit is contained in:
175
sources/3rdparty/imgui/imgui_widgets.cpp
vendored
175
sources/3rdparty/imgui/imgui_widgets.cpp
vendored
@@ -466,7 +466,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||
flags |= ImGuiButtonFlags_PressedOnClickRelease;
|
||||
|
||||
ImGuiWindow* backup_hovered_window = g.HoveredWindow;
|
||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window;
|
||||
const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window->RootWindow;
|
||||
if (flatten_hovered_children)
|
||||
g.HoveredWindow = window;
|
||||
|
||||
@@ -749,7 +749,8 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos)//, float size)
|
||||
return pressed;
|
||||
}
|
||||
|
||||
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
||||
// The Collapse button also functions as a Dock Menu button.
|
||||
bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@@ -760,16 +761,22 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos)
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None);
|
||||
|
||||
// Render
|
||||
//bool is_dock_menu = (window->DockNodeAsHost && !window->Collapsed);
|
||||
ImVec2 off = dock_node ? ImVec2(IM_FLOOR(-g.Style.ItemInnerSpacing.x * 0.5f) + 0.5f, 0.0f) : ImVec2(0.0f, 0.0f);
|
||||
ImU32 bg_col = GetColorU32((held && hovered) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button);
|
||||
ImU32 text_col = GetColorU32(ImGuiCol_Text);
|
||||
ImVec2 center = bb.GetCenter();
|
||||
if (hovered || held)
|
||||
window->DrawList->AddCircleFilled(center/*+ ImVec2(0.0f, -0.5f)*/, g.FontSize * 0.5f + 1.0f, bg_col, 12);
|
||||
RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
||||
window->DrawList->AddCircleFilled(center + off + ImVec2(0,-0.5f), g.FontSize * 0.5f + 1.0f, bg_col, 12);
|
||||
|
||||
if (dock_node)
|
||||
RenderArrowDockMenu(window->DrawList, bb.Min + g.Style.FramePadding, g.FontSize, text_col);
|
||||
else
|
||||
RenderArrow(window->DrawList, bb.Min + g.Style.FramePadding, text_col, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f);
|
||||
|
||||
// Switch to moving the window after mouse is moved beyond the initial drag threshold
|
||||
if (IsItemActive() && IsMouseDragging())
|
||||
StartMouseMovingWindow(window);
|
||||
if (IsItemActive() && IsMouseDragging(0))
|
||||
StartMouseMovingWindowOrNode(window, dock_node, true);
|
||||
|
||||
return pressed;
|
||||
}
|
||||
@@ -4107,7 +4114,10 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.)
|
||||
if (!is_readonly)
|
||||
g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1.0f, cursor_screen_pos.y - g.FontSize);
|
||||
{
|
||||
g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize);
|
||||
g.PlatformImePosViewport = window->Viewport;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -6027,7 +6037,7 @@ bool ImGui::BeginMenuBar()
|
||||
// We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect.
|
||||
// We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy.
|
||||
ImRect bar_rect = window->MenuBarRect();
|
||||
ImRect clip_rect(IM_ROUND(bar_rect.Min.x), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding)), IM_ROUND(bar_rect.Max.y));
|
||||
ImRect clip_rect(IM_ROUND(bar_rect.Min.x + window->WindowBorderSize), IM_ROUND(bar_rect.Min.y + window->WindowBorderSize), IM_ROUND(ImMax(bar_rect.Min.x, bar_rect.Max.x - ImMax(window->WindowRounding, window->WindowBorderSize))), IM_ROUND(bar_rect.Max.y));
|
||||
clip_rect.ClipWith(window->OuterRectClipped);
|
||||
PushClipRect(clip_rect.Min, clip_rect.Max, false);
|
||||
|
||||
@@ -6085,12 +6095,14 @@ void ImGui::EndMenuBar()
|
||||
bool ImGui::BeginMainMenuBar()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiViewport* viewport = g.Viewports[0];
|
||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f));
|
||||
SetNextWindowPos(ImVec2(0.0f, 0.0f));
|
||||
SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y));
|
||||
SetNextWindowPos(viewport->Pos);
|
||||
SetNextWindowSize(ImVec2(viewport->Size.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y));
|
||||
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our onw viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
|
||||
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0));
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar;
|
||||
bool is_open = Begin("##MainMenuBar", NULL, window_flags) && BeginMenuBar();
|
||||
PopStyleVar(2);
|
||||
g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
||||
@@ -6334,8 +6346,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected,
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: BeginTabBar, EndTabBar, etc.
|
||||
//-------------------------------------------------------------------------
|
||||
// [BETA API] API may evolve! This code has been extracted out of the Docking branch,
|
||||
// and some of the construct which are not used in Master may be left here to facilitate merging.
|
||||
// [BETA API] API may evolve!
|
||||
//-------------------------------------------------------------------------
|
||||
// - BeginTabBar()
|
||||
// - BeginTabBarEx() [Internal]
|
||||
@@ -6344,6 +6355,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected,
|
||||
// - TabBarCalcTabID() [Internal]
|
||||
// - TabBarCalcMaxTabWidth() [Internal]
|
||||
// - TabBarFindTabById() [Internal]
|
||||
// - TabBarAddTab() [Internal]
|
||||
// - TabBarRemoveTab() [Internal]
|
||||
// - TabBarCloseTab() [Internal]
|
||||
// - TabBarScrollClamp()v
|
||||
@@ -6411,10 +6423,10 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags)
|
||||
ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id);
|
||||
ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2);
|
||||
tab_bar->ID = id;
|
||||
return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused);
|
||||
return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused, NULL);
|
||||
}
|
||||
|
||||
bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImGuiTabBarFlags flags)
|
||||
bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
@@ -6431,7 +6443,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||
if (tab_bar->CurrFrameVisible == g.FrameCount)
|
||||
{
|
||||
//IMGUI_DEBUG_LOG("BeginTabBarEx already called this frame\n", g.FrameCount);
|
||||
IM_ASSERT(0);
|
||||
//IM_ASSERT(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6458,6 +6470,13 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||
// Draw separator
|
||||
const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive);
|
||||
const float y = tab_bar->BarRect.Max.y - 1.0f;
|
||||
if (dock_node != NULL)
|
||||
{
|
||||
const float separator_min_x = dock_node->Pos.x + window->WindowBorderSize;
|
||||
const float separator_max_x = dock_node->Pos.x + dock_node->Size.x - window->WindowBorderSize;
|
||||
window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
const float separator_min_x = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f);
|
||||
const float separator_max_x = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f);
|
||||
@@ -6578,7 +6597,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
// Additionally, when using TabBarAddTab() to manipulate tab bar order we occasionally insert new tabs that don't have a width yet,
|
||||
// and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window.
|
||||
const char* tab_name = tab_bar->GetTabName(tab);
|
||||
const bool has_close_button = (tab->Flags & ImGuiTabItemFlags_NoCloseButton) ? false : true;
|
||||
const bool has_close_button = tab->Window ? tab->Window->HasCloseButton : ((tab->Flags & ImGuiTabItemFlags_NoCloseButton) == 0);
|
||||
tab->ContentWidth = TabItemCalcSize(tab_name, has_close_button).x;
|
||||
|
||||
width_total_contents += (tab_n > 0 ? g.Style.ItemInnerSpacing.x : 0.0f) + tab->ContentWidth;
|
||||
@@ -6642,6 +6661,10 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
tab_bar->VisibleTabId = tab_bar->SelectedTabId;
|
||||
tab_bar->VisibleTabWasSubmitted = false;
|
||||
|
||||
// CTRL+TAB can override visible tab temporarily
|
||||
if (g.NavWindowingTarget != NULL && g.NavWindowingTarget->DockNode && g.NavWindowingTarget->DockNode->TabBar == tab_bar)
|
||||
tab_bar->VisibleTabId = scroll_track_selected_tab_id = g.NavWindowingTarget->ID;
|
||||
|
||||
// Update scrolling
|
||||
if (scroll_track_selected_tab_id)
|
||||
if (ImGuiTabItem* scroll_track_selected_tab = TabBarFindTabByID(tab_bar, scroll_track_selected_tab_id))
|
||||
@@ -6698,6 +6721,38 @@ ImGuiTabItem* ImGui::TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: See references to #2304 in TODO.txt
|
||||
ImGuiTabItem* ImGui::TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar)
|
||||
{
|
||||
ImGuiTabItem* most_recently_selected_tab = NULL;
|
||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
{
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
|
||||
if (most_recently_selected_tab == NULL || most_recently_selected_tab->LastFrameSelected < tab->LastFrameSelected)
|
||||
if (tab->Window && tab->Window->WasActive)
|
||||
most_recently_selected_tab = tab;
|
||||
}
|
||||
return most_recently_selected_tab;
|
||||
}
|
||||
|
||||
// The purpose of this call is to register tab in advance so we can control their order at the time they appear.
|
||||
// Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function.
|
||||
void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(TabBarFindTabByID(tab_bar, window->ID) == NULL);
|
||||
IM_ASSERT(g.CurrentTabBar == NULL); // Can't work while the tab bar is active as our tab doesn't have an X offset yet
|
||||
|
||||
ImGuiTabItem new_tab;
|
||||
new_tab.ID = window->ID;
|
||||
new_tab.Flags = tab_flags;
|
||||
new_tab.LastFrameVisible = tab_bar->CurrFrameVisible; // Required so BeginTabBar() doesn't ditch the tab
|
||||
if (new_tab.LastFrameVisible == -1)
|
||||
new_tab.LastFrameVisible = g.FrameCount - 1;
|
||||
new_tab.Window = window; // Required so tab bar layout can compute the tab width before tab submission
|
||||
tab_bar->Tabs.push_back(new_tab);
|
||||
}
|
||||
|
||||
// The *TabId fields be already set by the docking system _before_ the actual TabItem was created, so we clear them regardless.
|
||||
void ImGui::TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id)
|
||||
{
|
||||
@@ -6851,8 +6906,7 @@ static ImGuiTabItem* ImGui::TabBarTabListPopupButton(ImGuiTabBar* tab_bar)
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: BeginTabItem, EndTabItem, etc.
|
||||
//-------------------------------------------------------------------------
|
||||
// [BETA API] API may evolve! This code has been extracted out of the Docking branch,
|
||||
// and some of the construct which are not used in Master may be left here to facilitate merging.
|
||||
// [BETA API] API may evolve!
|
||||
//-------------------------------------------------------------------------
|
||||
// - BeginTabItem()
|
||||
// - EndTabItem()
|
||||
@@ -6876,7 +6930,7 @@ bool ImGui::BeginTabItem(const char* label, bool* p_open, ImGuiTabItemFlags f
|
||||
IM_ASSERT_USER_ERROR(tab_bar, "BeginTabItem() Needs to be called between BeginTabBar() and EndTabBar()!");
|
||||
return false;
|
||||
}
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags);
|
||||
bool ret = TabItemEx(tab_bar, label, p_open, flags, NULL);
|
||||
if (ret && !(flags & ImGuiTabItemFlags_NoPushId))
|
||||
{
|
||||
ImGuiTabItem* tab = &tab_bar->Tabs[tab_bar->LastTabItemIdx];
|
||||
@@ -6904,7 +6958,7 @@ void ImGui::EndTabItem()
|
||||
window->IDStack.pop_back();
|
||||
}
|
||||
|
||||
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags)
|
||||
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window)
|
||||
{
|
||||
// Layout whole tab bar if not already done
|
||||
if (tab_bar->WantLayout)
|
||||
@@ -6952,10 +7006,20 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
const bool tab_appearing = (tab->LastFrameVisible + 1 < g.FrameCount);
|
||||
tab->LastFrameVisible = g.FrameCount;
|
||||
tab->Flags = flags;
|
||||
tab->Window = docked_window;
|
||||
|
||||
// Append name with zero-terminator
|
||||
tab->NameOffset = tab_bar->TabsNames.size();
|
||||
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_DockNode)
|
||||
{
|
||||
IM_ASSERT(tab->Window != NULL);
|
||||
tab->NameOffset = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
IM_ASSERT(tab->Window == NULL);
|
||||
tab->NameOffset = tab_bar->TabsNames.size();
|
||||
tab_bar->TabsNames.append(label, label + strlen(label) + 1); // Append name _with_ the zero-terminator.
|
||||
}
|
||||
|
||||
// If we are not reorderable, always reset offset based on submission order.
|
||||
// (We already handled layout and sizing using the previous known order, but sizing is not affected by order!)
|
||||
@@ -6978,7 +7042,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
tab_bar->VisibleTabWasSubmitted = true;
|
||||
|
||||
// On the very first frame of a tab bar we let first tab contents be visible to minimize appearing glitches
|
||||
if (!tab_contents_visible && tab_bar->SelectedTabId == 0 && tab_bar_appearing)
|
||||
if (!tab_contents_visible && tab_bar->SelectedTabId == 0 && tab_bar_appearing && docked_window == NULL)
|
||||
if (tab_bar->Tabs.Size == 1 && !(tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs))
|
||||
tab_contents_visible = true;
|
||||
|
||||
@@ -7021,7 +7085,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
|
||||
// Click to Select a tab
|
||||
ImGuiButtonFlags button_flags = (ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_AllowItemOverlap);
|
||||
if (g.DragDropActive)
|
||||
if (g.DragDropActive && !g.DragDropPayload.IsDataType(IMGUI_PAYLOAD_TYPE_WINDOW))
|
||||
button_flags |= ImGuiButtonFlags_PressedOnDragDropHold;
|
||||
bool hovered, held;
|
||||
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
|
||||
@@ -7033,23 +7097,66 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (!held)
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// Drag and drop: re-order tabs
|
||||
if (held && !tab_appearing && IsMouseDragging(0))
|
||||
// Drag and drop a single floating window node moves it
|
||||
ImGuiDockNode* node = docked_window ? docked_window->DockNode : NULL;
|
||||
const bool single_floating_window_node = node && node->IsFloatingNode() && (node->Windows.Size == 1);
|
||||
if (held && single_floating_window_node && IsMouseDragging(0, 0.0f))
|
||||
{
|
||||
if (!g.DragDropActive && (tab_bar->Flags & ImGuiTabBarFlags_Reorderable))
|
||||
// Move
|
||||
StartMouseMovingWindow(docked_window);
|
||||
}
|
||||
else if (held && !tab_appearing && IsMouseDragging(0))
|
||||
{
|
||||
// Drag and drop: re-order tabs
|
||||
float drag_distance_from_edge_x = 0.0f;
|
||||
if (!g.DragDropActive && ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (docked_window != NULL)))
|
||||
{
|
||||
// While moving a tab it will jump on the other side of the mouse, so we also test for MouseDelta.x
|
||||
if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < bb.Min.x)
|
||||
{
|
||||
drag_distance_from_edge_x = bb.Min.x - g.IO.MousePos.x;
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_Reorderable)
|
||||
TabBarQueueChangeTabOrder(tab_bar, tab, -1);
|
||||
}
|
||||
else if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > bb.Max.x)
|
||||
{
|
||||
drag_distance_from_edge_x = g.IO.MousePos.x - bb.Max.x;
|
||||
if (tab_bar->Flags & ImGuiTabBarFlags_Reorderable)
|
||||
TabBarQueueChangeTabOrder(tab_bar, tab, +1);
|
||||
}
|
||||
}
|
||||
|
||||
// Extract a Dockable window out of it's tab bar
|
||||
if (docked_window != NULL && !(docked_window->Flags & ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
// We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar
|
||||
bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id);
|
||||
|
||||
if (!undocking_tab) //&& (!g.IO.ConfigDockingWithShift || g.IO.KeyShift)
|
||||
{
|
||||
float threshold_base = g.FontSize;
|
||||
//float threshold_base = g.IO.ConfigDockingWithShift ? g.FontSize * 0.5f : g.FontSize;
|
||||
float threshold_x = (threshold_base * 2.2f);
|
||||
float threshold_y = (threshold_base * 1.5f) + ImClamp((ImFabs(g.IO.MouseDragMaxDistanceAbs[0].x) - threshold_base * 2.0f) * 0.20f, 0.0f, threshold_base * 4.0f);
|
||||
//GetForegroundDrawList()->AddRect(ImVec2(bb.Min.x - threshold_x, bb.Min.y - threshold_y), ImVec2(bb.Max.x + threshold_x, bb.Max.y + threshold_y), IM_COL32_WHITE); // [DEBUG]
|
||||
|
||||
float distance_from_edge_y = ImMax(bb.Min.y - g.IO.MousePos.y, g.IO.MousePos.y - bb.Max.y);
|
||||
if (distance_from_edge_y >= threshold_y)
|
||||
undocking_tab = true;
|
||||
else if (drag_distance_from_edge_x > threshold_x)
|
||||
if ((tab_bar->ReorderRequestDir < 0 && tab_bar->GetTabOrder(tab) == 0) || (tab_bar->ReorderRequestDir > 0 && tab_bar->GetTabOrder(tab) == tab_bar->Tabs.Size - 1))
|
||||
undocking_tab = true;
|
||||
}
|
||||
|
||||
if (undocking_tab)
|
||||
{
|
||||
// Undock
|
||||
DockContextQueueUndockWindow(&g, docked_window);
|
||||
g.MovingWindow = docked_window;
|
||||
g.ActiveId = g.MovingWindow->MoveId;
|
||||
g.ActiveIdClickOffset -= g.MovingWindow->Pos - bb.Min;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -7112,6 +7219,16 @@ void ImGui::SetTabItemClosed(const char* label)
|
||||
ImGuiID tab_id = TabBarCalcTabID(tab_bar, label);
|
||||
TabBarRemoveTab(tab_bar, tab_id);
|
||||
}
|
||||
else if (ImGuiWindow* window = FindWindowByName(label))
|
||||
{
|
||||
if (window->DockIsActive)
|
||||
if (ImGuiDockNode* node = window->DockNode)
|
||||
{
|
||||
ImGuiID tab_id = TabBarCalcTabID(node->TabBar, label);
|
||||
TabBarRemoveTab(node->TabBar, tab_id);
|
||||
window->DockTabWantClose = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImVec2 ImGui::TabItemCalcSize(const char* label, bool has_close_button)
|
||||
@@ -7135,7 +7252,7 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI
|
||||
IM_ASSERT(width > 0.0f);
|
||||
const float rounding = ImMax(0.0f, ImMin(g.Style.TabRounding, width * 0.5f - 1.0f));
|
||||
const float y1 = bb.Min.y + 1.0f;
|
||||
const float y2 = bb.Max.y - 1.0f;
|
||||
const float y2 = bb.Max.y + ((flags & ImGuiTabItemFlags_Preview) ? 0.0f : -1.0f);
|
||||
draw_list->PathLineTo(ImVec2(bb.Min.x, y2));
|
||||
draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9);
|
||||
draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12);
|
||||
|
||||
Reference in New Issue
Block a user