mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
WIP Menus: tidying up, fixed hovering in parent popup menu item from child popup (individual popups acts as hovering barrier) (#126)
This commit is contained in:
parent
9bdacaf08d
commit
6da8a77fa3
75
imgui.cpp
75
imgui.cpp
@ -7262,27 +7262,26 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
ImGuiID id = window->GetID(label);
|
||||||
const ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true);
|
||||||
|
ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
||||||
const ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y);
|
ImVec2 pos = window->DC.CursorPos;
|
||||||
const ImVec2 pos = window->DC.CursorPos;
|
|
||||||
ImRect bb(pos, pos + size);
|
ImRect bb(pos, pos + size);
|
||||||
ItemSize(bb);
|
ItemSize(bb);
|
||||||
|
|
||||||
// Fill horizontal space.
|
// Fill horizontal space.
|
||||||
const ImVec2 window_padding = window->WindowPadding();
|
ImVec2 window_padding = window->WindowPadding();
|
||||||
const float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x);
|
float w_draw = ImMax(label_size.x, window->Pos.x + ImGui::GetContentRegionMax().x - window_padding.x - window->DC.CursorPos.x);
|
||||||
const ImVec2 size_draw(size_draw_arg.x != 0.0f ? size_draw_arg.x : w_draw, size_draw_arg.y != 0.0f ? size_draw_arg.y : size.y);
|
ImVec2 size_draw(size_draw_arg.x != 0.0f ? size_draw_arg.x : w_draw, size_draw_arg.y != 0.0f ? size_draw_arg.y : size.y);
|
||||||
ImRect bb_with_spacing(pos, pos + size_draw);
|
ImRect bb_with_spacing(pos, pos + size_draw);
|
||||||
if (size_draw_arg.x == 0.0f)
|
if (size_draw_arg.x == 0.0f)
|
||||||
bb_with_spacing.Max.x += window_padding.x;
|
bb_with_spacing.Max.x += window_padding.x;
|
||||||
|
|
||||||
// Selectables are tightly packed together, we extend the box to cover spacing between selectable.
|
// Selectables are tightly packed together, we extend the box to cover spacing between selectable.
|
||||||
const float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f);
|
float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f);
|
||||||
const float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f);
|
float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f);
|
||||||
const float spacing_R = style.ItemSpacing.x - spacing_L;
|
float spacing_R = style.ItemSpacing.x - spacing_L;
|
||||||
const float spacing_D = style.ItemSpacing.y - spacing_U;
|
float spacing_D = style.ItemSpacing.y - spacing_U;
|
||||||
bb_with_spacing.Min.x -= spacing_L;
|
bb_with_spacing.Min.x -= spacing_L;
|
||||||
bb_with_spacing.Min.y -= spacing_U;
|
bb_with_spacing.Min.y -= spacing_U;
|
||||||
bb_with_spacing.Max.x += spacing_R;
|
bb_with_spacing.Max.x += spacing_R;
|
||||||
@ -7291,7 +7290,7 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool hovered, held;
|
bool hovered, held;
|
||||||
bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, menu_item ? (ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_FlattenChilds) : 0);
|
bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, true, menu_item ? ImGuiButtonFlags_PressedOnClick : 0);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
if (hovered || selected)
|
if (hovered || selected)
|
||||||
@ -7299,8 +7298,6 @@ static bool SelectableEx(const char* label, bool selected, const ImVec2& size_ar
|
|||||||
const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
const ImU32 col = window->Color((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
|
||||||
RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding);
|
RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, style.FrameRounding);
|
||||||
}
|
}
|
||||||
|
|
||||||
//const ImVec2 off = ImVec2(ImMax(0.0f, size.x - text_size.x) * 0.5f, ImMax(0.0f, size.y - text_size.y) * 0.5f);
|
|
||||||
RenderTextClipped(bb.Min, label, NULL, &label_size, bb_with_spacing.Max);
|
RenderTextClipped(bb.Min, label, NULL, &label_size, bb_with_spacing.Max);
|
||||||
|
|
||||||
// Automatically close popups
|
// Automatically close popups
|
||||||
@ -7342,9 +7339,9 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg)
|
|||||||
ImVec2 size;
|
ImVec2 size;
|
||||||
size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f;
|
size.x = (size_arg.x != 0.0f) ? (size_arg.x) : ImGui::CalcItemWidth() + style.FramePadding.x * 2.0f;
|
||||||
size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y;
|
size.y = (size_arg.y != 0.0f) ? (size_arg.y) : ImGui::GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y;
|
||||||
const ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
|
ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y));
|
||||||
const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size);
|
||||||
const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f));
|
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;
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
ImGui::BeginGroup();
|
||||||
@ -7437,7 +7434,6 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected)
|
|||||||
float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
|
float extra_w = ImMax(0.0f, window->Pos.x + ImGui::GetContentRegionMax().x - pos.x - w);
|
||||||
|
|
||||||
bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), true);
|
bool pressed = SelectableEx(label, false, ImVec2(w, 0.0f), ImVec2(0.0f, 0.0f), true);
|
||||||
|
|
||||||
if (shortcut_size.x > 0.0f)
|
if (shortcut_size.x > 0.0f)
|
||||||
{
|
{
|
||||||
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]);
|
||||||
@ -7501,15 +7497,13 @@ bool ImGui::BeginMenu(const char* label)
|
|||||||
const ImGuiStyle& style = g.Style;
|
const ImGuiStyle& style = g.Style;
|
||||||
const ImGuiID id = window->GetID(label);
|
const ImGuiID id = window->GetID(label);
|
||||||
|
|
||||||
ImVec2 pos;
|
ImVec2 pos, popup_pos, backup_pos = window->DC.CursorPos;
|
||||||
ImVec2 popup_pos;
|
|
||||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||||
ImVec2 backup_pos = window->DC.CursorPos;
|
|
||||||
ImGuiWindow* backed_focused_window = g.FocusedWindow;
|
ImGuiWindow* backed_focused_window = g.FocusedWindow;
|
||||||
|
|
||||||
bool pressed;
|
bool pressed;
|
||||||
bool opened = IsPopupOpen(id);
|
bool opened = IsPopupOpen(id);
|
||||||
bool menuset_opened = (g.OpenedPopupStack.size() > g.CurrentPopupStack.size() && g.OpenedPopupStack[g.CurrentPopupStack.size()].ParentMenuSet == window->GetID("##menus"));
|
bool menuset_opened = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenedPopupStack.size() > g.CurrentPopupStack.size() && g.OpenedPopupStack[g.CurrentPopupStack.size()].ParentMenuSet == window->GetID("##menus"));
|
||||||
if (menuset_opened)
|
if (menuset_opened)
|
||||||
g.FocusedWindow = window;
|
g.FocusedWindow = window;
|
||||||
|
|
||||||
@ -7539,31 +7533,22 @@ bool ImGui::BeginMenu(const char* label)
|
|||||||
if (menuset_opened)
|
if (menuset_opened)
|
||||||
g.FocusedWindow = backed_focused_window;
|
g.FocusedWindow = backed_focused_window;
|
||||||
|
|
||||||
|
bool want_open = false;
|
||||||
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
|
||||||
|
want_open = (!opened && hovered);
|
||||||
|
else if (pressed && menuset_opened)
|
||||||
{
|
{
|
||||||
if (!opened && hovered)
|
ClosePopup(label); // click again to toggle
|
||||||
{
|
want_open = opened = false;
|
||||||
ImGui::OpenPopup(label);
|
|
||||||
opened = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (menuset_opened && pressed)
|
|
||||||
{
|
|
||||||
ClosePopup(label);
|
|
||||||
opened = pressed = false;
|
|
||||||
}
|
|
||||||
else if (menuset_opened)
|
|
||||||
pressed |= hovered;
|
|
||||||
else
|
|
||||||
pressed |= (hovered && !g.OpenedPopupStack.empty() && g.OpenedPopupStack.back().PopupID != id && g.OpenedPopupStack.back().ParentWindow == window);
|
|
||||||
if (pressed)
|
|
||||||
{
|
|
||||||
ImGui::OpenPopup(label); // FIXME-MENUS: toggle
|
|
||||||
opened = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (pressed)
|
||||||
|
want_open = true;
|
||||||
|
else if (hovered && menuset_opened)
|
||||||
|
want_open = true;
|
||||||
|
|
||||||
|
opened |= want_open;
|
||||||
|
if (want_open)
|
||||||
|
ImGui::OpenPopup(label);
|
||||||
|
|
||||||
if (opened)
|
if (opened)
|
||||||
{
|
{
|
||||||
|
2
imgui.h
2
imgui.h
@ -232,7 +232,7 @@ namespace ImGui
|
|||||||
IMGUI_API void EndTooltip();
|
IMGUI_API void EndTooltip();
|
||||||
|
|
||||||
// Popup
|
// Popup
|
||||||
IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. will close when user click outside, or activate menu items, or CloseCurrentPopup() is called within a BeginPopup/EndPopup block.
|
IMGUI_API void OpenPopup(const char* str_id); // mark popup as open. close childs popups if any. will close popup when user click outside, or activate menu items, or CloseCurrentPopup() is called within a BeginPopup/EndPopup block.
|
||||||
IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true!
|
IMGUI_API bool BeginPopup(const char* str_id); // return true if popup if opened and start outputting to it. only call EndPopup() if BeginPopup() returned true!
|
||||||
IMGUI_API void EndPopup();
|
IMGUI_API void EndPopup();
|
||||||
IMGUI_API void CloseCurrentPopup();
|
IMGUI_API void CloseCurrentPopup();
|
||||||
|
Loading…
Reference in New Issue
Block a user