Nav: collapse button is interactve, allow collapsing, tidying up, resize speed takes account of framebuffer scale (#323)

This commit is contained in:
ocornut 2016-07-30 10:56:52 +02:00
parent 4735802096
commit b2aaab873d
2 changed files with 47 additions and 24 deletions

View File

@ -1718,14 +1718,13 @@ ImGuiWindow::ImGuiWindow(const char* name)
Name = ImStrdup(name); Name = ImStrdup(name);
ID = ImHash(name, 0); ID = ImHash(name, 0);
IDStack.push_back(ID); IDStack.push_back(ID);
MoveId = GetID("#MOVE");
Flags = 0; Flags = 0;
IndexWithinParent = 0; IndexWithinParent = 0;
PosFloat = Pos = ImVec2(0.0f, 0.0f); PosFloat = Pos = ImVec2(0.0f, 0.0f);
Size = SizeFull = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f);
SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f);
WindowPadding = ImVec2(0.0f, 0.0f); WindowPadding = ImVec2(0.0f, 0.0f);
MoveId = GetID("#MOVE");
Scroll = ImVec2(0.0f, 0.0f); Scroll = ImVec2(0.0f, 0.0f);
ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
@ -1735,6 +1734,7 @@ ImGuiWindow::ImGuiWindow(const char* name)
Active = WasActive = false; Active = WasActive = false;
Accessed = false; Accessed = false;
Collapsed = false; Collapsed = false;
CollapseToggleWanted = false;
SkipItems = false; SkipItems = false;
BeginCount = 0; BeginCount = 0;
PopupId = 0; PopupId = 0;
@ -4501,7 +4501,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse))
{ {
ImRect title_bar_rect = window->TitleBarRect(); ImRect title_bar_rect = window->TitleBarRect();
if (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]) if (window->CollapseToggleWanted || (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0]))
{ {
window->Collapsed = !window->Collapsed; window->Collapsed = !window->Collapsed;
if (!(flags & ImGuiWindowFlags_NoSavedSettings)) if (!(flags & ImGuiWindowFlags_NoSavedSettings))
@ -4513,6 +4513,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
{ {
window->Collapsed = false; window->Collapsed = false;
} }
window->CollapseToggleWanted = false;
// SIZE // SIZE
@ -4718,11 +4719,9 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
ImVec2 nav_resize_delta(0.0f, 0.0f); ImVec2 nav_resize_delta(0.0f, 0.0f);
if (g.NavWindowingTarget == window) if (g.NavWindowingTarget == window)
{ {
const float resize_speed = ImFloor(40 * g.FontSize * g.IO.DeltaTime); const float resize_speed = ImFloor(600 * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
if (IsKeyDownMap(ImGuiKey_NavLeft)) nav_resize_delta.x -= resize_speed; nav_resize_delta = NavGetMovingDir() * resize_speed;
if (IsKeyDownMap(ImGuiKey_NavRight)) nav_resize_delta.x += resize_speed; held |= (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f); // For coloring
if (IsKeyDownMap(ImGuiKey_NavUp)) nav_resize_delta.y -= resize_speed;
if (IsKeyDownMap(ImGuiKey_NavDown)) nav_resize_delta.y += resize_speed;
} }
ImVec2 size_target(FLT_MAX,FLT_MAX); ImVec2 size_target(FLT_MAX,FLT_MAX);
@ -4737,7 +4736,6 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// FIXME-NAVIGATION: Should store and accumulate into a separate size buffer to handle sizing constraints properly // FIXME-NAVIGATION: Should store and accumulate into a separate size buffer to handle sizing constraints properly
g.NavWindowingToggleLayer = false; g.NavWindowingToggleLayer = false;
size_target = window->SizeFull + nav_resize_delta; size_target = window->SizeFull + nav_resize_delta;
held = true; // For coloring
} }
else if (held) else if (held)
{ {
@ -4877,20 +4875,38 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us
// Title bar // Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar)) if (!(flags & ImGuiWindowFlags_NoTitleBar))
{ {
// Close & collapse button are on layer 1 (same as menus) and don't default focus
const bool backup_allow_nav_default_focus = window->DC.AllowNavDefaultFocus;
if (window->Flags & ImGuiWindowFlags_MenuBar)
window->DC.AllowNavDefaultFocus = false;
window->DC.NavLayerCurrent++;
// Close button
if (p_open != NULL) if (p_open != NULL)
{ {
const float pad = 2.0f; const float PAD = 2.0f;
const float rad = (window->TitleBarHeight() - pad*2.0f) * 0.5f; const float rad = (window->TitleBarHeight() - PAD*2.0f) * 0.5f;
window->DC.NavLayerCurrent++; if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-PAD - rad, PAD + rad), rad))
if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-pad - rad, pad + rad), rad))
*p_open = false; *p_open = false;
window->DC.NavLayerCurrent--;
} }
// Collapse button
const ImVec2 text_size = CalcTextSize(name, NULL, true); const ImVec2 text_size = CalcTextSize(name, NULL, true);
if (!(flags & ImGuiWindowFlags_NoCollapse)) if (!(flags & ImGuiWindowFlags_NoCollapse) && g.IO.NavUsable)
{
ImGuiID id = window->GetID("#COLLAPSE");
ImRect bb(window->Pos + style.FramePadding + ImVec2(1,1), window->Pos + style.FramePadding + ImVec2(g.FontSize,g.FontSize) - ImVec2(1,1));
ItemAdd(bb, &id); // To allow navigation
if (ButtonBehavior(bb, id, NULL, NULL))
window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function
RenderNavHighlight(id, bb);
RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true); RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f, true);
}
window->DC.NavLayerCurrent--;
window->DC.AllowNavDefaultFocus = backup_allow_nav_default_focus;
// Title text (FIXME: refactor text alignment facilities along with RenderText helpers)
ImVec2 text_min = window->Pos + style.FramePadding; ImVec2 text_min = window->Pos + style.FramePadding;
ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y); ImVec2 text_max = window->Pos + ImVec2(window->Size.x - style.FramePadding.x, style.FramePadding.y*2 + text_size.y);
ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton() ImVec2 clip_max = ImVec2(window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x), text_max.y); // Match the size of CloseWindowButton()
@ -6264,12 +6280,7 @@ bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius)
ImGuiWindow* window = GetCurrentWindow(); ImGuiWindow* window = GetCurrentWindow();
const ImRect bb(pos - ImVec2(radius,radius), pos + ImVec2(radius,radius)); const ImRect bb(pos - ImVec2(radius,radius), pos + ImVec2(radius,radius));
const bool backup_allow_nav_default_focus = window->DC.AllowNavDefaultFocus; // We could exposethis as a flag to ItemAdd() but it is such a unique case for now if (!ItemAdd(bb, &id)) // To allow navigation
if (window->Flags & ImGuiWindowFlags_MenuBar)
window->DC.AllowNavDefaultFocus = false;
const bool added = ItemAdd(bb, &id); // To allow navigation
window->DC.AllowNavDefaultFocus = backup_allow_nav_default_focus;
if (!added)
return false; return false;
bool hovered, held; bool hovered, held;
@ -7015,6 +7026,16 @@ int ImGui::ParseFormatPrecision(const char* fmt, int default_precision)
return precision; return precision;
} }
ImVec2 ImGui::NavGetMovingDir()
{
ImVec2 dir(0.0f, 0.0f);
if (IsKeyDownMap(ImGuiKey_NavLeft)) dir.x -= 1.0f;
if (IsKeyDownMap(ImGuiKey_NavRight)) dir.x += 1.0f;
if (IsKeyDownMap(ImGuiKey_NavUp)) dir.y -= 1.0f;
if (IsKeyDownMap(ImGuiKey_NavDown)) dir.y += 1.0f;
return dir;
}
// Adjustment delta for slider/drag/etc. // Adjustment delta for slider/drag/etc.
// FIXME-NAVIGATION: Accelerate over time? Expose more settings? Handle faster/slower modifiers here instead of widget level? // FIXME-NAVIGATION: Accelerate over time? Expose more settings? Handle faster/slower modifiers here instead of widget level?
ImVec2 ImGui::NavGetTweakDelta() ImVec2 ImGui::NavGetTweakDelta()

View File

@ -691,6 +691,7 @@ struct IMGUI_API ImGuiWindow
bool WasActive; bool WasActive;
bool Accessed; // Set to true when any widget access the current window bool Accessed; // Set to true when any widget access the current window
bool Collapsed; // Set when collapsing window to become only title-bar bool Collapsed; // Set when collapsing window to become only title-bar
bool CollapseToggleWanted;
bool SkipItems; // == Visible && !Collapsed bool SkipItems; // == Visible && !Collapsed
int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) 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) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
@ -783,6 +784,7 @@ namespace ImGui
IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing);
IMGUI_API ImVec2 NavGetTweakDelta(); IMGUI_API ImVec2 NavGetTweakDelta();
IMGUI_API ImVec2 NavGetMovingDir();
inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); } inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); }
inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }