mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-28 01:20:55 +01:00
TabBar: Use mouse position instead of hardcoded +1/-1 offset when reordering tabs.
Fixes tab reordering in test engine when using fast mode.
This commit is contained in:
parent
a58271c079
commit
475c0fcc39
@ -2423,6 +2423,7 @@ namespace ImGui
|
|||||||
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||||
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||||
IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir);
|
IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir);
|
||||||
|
IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos);
|
||||||
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
|
IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar);
|
||||||
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags);
|
IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags);
|
||||||
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button);
|
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button);
|
||||||
|
@ -7447,6 +7447,50 @@ void ImGui::TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, in
|
|||||||
tab_bar->ReorderRequestDir = (ImS8)dir;
|
tab_bar->ReorderRequestDir = (ImS8)dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGui::TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(tab_bar->ReorderRequestTabId == 0);
|
||||||
|
|
||||||
|
if ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int source_idx = tab_bar->Tabs.index_from_ptr(tab);
|
||||||
|
float bar_x = tab_bar->BarRect.Min.x;
|
||||||
|
int dir = bar_x + tab->Offset > mouse_pos.x ? -1 : +1;
|
||||||
|
int target_idx = source_idx;
|
||||||
|
|
||||||
|
for (int i = source_idx; 0 <= i && i < tab_bar->Tabs.Size; i += dir)
|
||||||
|
{
|
||||||
|
const ImGuiTabItem* target_tab = &tab_bar->Tabs[i];
|
||||||
|
|
||||||
|
// Reorder only within tab groups with _Leading, _Trailing flag or without either of them.
|
||||||
|
if ((target_tab->Flags & ImGuiTabItemFlags_Leading) != (tab->Flags & ImGuiTabItemFlags_Leading))
|
||||||
|
break;
|
||||||
|
if ((target_tab->Flags & ImGuiTabItemFlags_Trailing) != (tab->Flags & ImGuiTabItemFlags_Trailing))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Do not reorder past tabs with _NoReorder flag.
|
||||||
|
if (target_tab->Flags & ImGuiTabItemFlags_NoReorder)
|
||||||
|
break;
|
||||||
|
|
||||||
|
target_idx = i; // target_tab can be swapped with dragged tab.
|
||||||
|
|
||||||
|
// Current tab is destination tab under mouse position. Also include space after tab, so when mouse cursor is
|
||||||
|
// between tabs we would not continue checking further tabs that are not hovered.
|
||||||
|
if (dir > 0 && mouse_pos.x < bar_x + target_tab->Offset + target_tab->Width + g.Style.ItemInnerSpacing.x) // End of tab is past mouse_pos.
|
||||||
|
break;
|
||||||
|
if (dir < 0 && mouse_pos.x > bar_x + target_tab->Offset - g.Style.ItemInnerSpacing.x) // Mouse pos is past start of tab.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_idx != source_idx)
|
||||||
|
{
|
||||||
|
tab_bar->ReorderRequestTabId = tab->ID;
|
||||||
|
tab_bar->ReorderRequestDir = (ImS8)(target_idx - source_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ImGui::TabBarProcessReorder(ImGuiTabBar* tab_bar)
|
bool ImGui::TabBarProcessReorder(ImGuiTabBar* tab_bar)
|
||||||
{
|
{
|
||||||
ImGuiTabItem* tab1 = TabBarFindTabByID(tab_bar, tab_bar->ReorderRequestTabId);
|
ImGuiTabItem* tab1 = TabBarFindTabByID(tab_bar, tab_bar->ReorderRequestTabId);
|
||||||
@ -7466,7 +7510,18 @@ bool ImGui::TabBarProcessReorder(ImGuiTabBar* tab_bar)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGuiTabItem item_tmp = *tab1;
|
ImGuiTabItem item_tmp = *tab1;
|
||||||
*tab1 = *tab2;
|
ImGuiTabItem* src, *dst;
|
||||||
|
if (tab_bar->ReorderRequestDir > 0)
|
||||||
|
{
|
||||||
|
dst = tab1;
|
||||||
|
src = tab1 + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst = tab2 + 1;
|
||||||
|
src = tab2;
|
||||||
|
}
|
||||||
|
memmove(dst, src, abs(tab_bar->ReorderRequestDir) * sizeof(ImGuiTabItem));
|
||||||
*tab2 = item_tmp;
|
*tab2 = item_tmp;
|
||||||
|
|
||||||
if (tab_bar->Flags & ImGuiTabBarFlags_SaveSettings)
|
if (tab_bar->Flags & ImGuiTabBarFlags_SaveSettings)
|
||||||
@ -7796,13 +7851,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
|||||||
// While moving a tab it will jump on the other side of the mouse, so we also test for MouseDelta.x
|
// 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)
|
if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < bb.Min.x)
|
||||||
{
|
{
|
||||||
if (tab_bar->Flags & ImGuiTabBarFlags_Reorderable)
|
TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos);
|
||||||
TabBarQueueReorder(tab_bar, tab, -1);
|
|
||||||
}
|
}
|
||||||
else if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > bb.Max.x)
|
else if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > bb.Max.x)
|
||||||
{
|
{
|
||||||
if (tab_bar->Flags & ImGuiTabBarFlags_Reorderable)
|
TabBarQueueReorderFromMousePos(tab_bar, tab, g.IO.MousePos);
|
||||||
TabBarQueueReorder(tab_bar, tab, +1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user