mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-04 03:58:47 +02:00
Merge branch 'master' into docking
# Conflicts: # backends/imgui_impl_opengl3.cpp # backends/imgui_impl_osx.h # backends/imgui_impl_osx.mm # imgui.cpp
This commit is contained in:
@ -3703,11 +3703,11 @@ static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
|
||||
static int is_word_boundary_from_left(ImGuiInputTextState* obj, int idx) { if (obj->Flags & ImGuiInputTextFlags_Password) return 0; return idx > 0 ? (!is_separator(obj->TextW[idx - 1]) && is_separator(obj->TextW[idx])) : 1; }
|
||||
static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(ImGuiInputTextState* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_MAC(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
|
||||
#ifdef __APPLE__ // FIXME: Move setting to IO structure
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_MAC
|
||||
#else
|
||||
static int STB_TEXTEDIT_MOVEWORDRIGHT_WIN(ImGuiInputTextState* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
|
||||
#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_WIN
|
||||
#endif
|
||||
|
||||
@ -6883,6 +6883,23 @@ void ImGui::EndMainMenuBar()
|
||||
End();
|
||||
}
|
||||
|
||||
static bool IsRootOfOpenMenuSet()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if ((g.OpenPopupStack.Size <= g.BeginPopupStack.Size) || (window->Flags & ImGuiWindowFlags_ChildMenu))
|
||||
return false;
|
||||
|
||||
// Initially we used 'OpenParentId' to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) based on parent ID.
|
||||
// This would however prevent the use of e.g. PuhsID() user code submitting menus.
|
||||
// Previously this worked between popup and a first child menu because the first child menu always had the _ChildWindow flag,
|
||||
// making hovering on parent popup possible while first child menu was focused - but this was generally a bug with other side effects.
|
||||
// Instead we don't treat Popup specifically (in order to consistently support menu features in them), maybe the first child menu of a Popup
|
||||
// doesn't have the _ChildWindow flag, and we rely on this IsRootOfOpenMenuSet() check to allow hovering between root window/popup and first chilld menu.
|
||||
const ImGuiPopupData* upper_popup = &g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||
return (/*upper_popup->OpenParentId == window->IDStack.back() &&*/ upper_popup->Window && (upper_popup->Window->Flags & ImGuiWindowFlags_ChildMenu));
|
||||
}
|
||||
|
||||
bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@ -6895,8 +6912,9 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
bool menu_is_open = IsPopupOpen(id, ImGuiPopupFlags_None);
|
||||
|
||||
// Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu)
|
||||
// The first menu in a hierarchy isn't so hovering doesn't get accross (otherwise e.g. resizing borders with ImGuiButtonFlags_FlattenChildren would react), but top-most BeginMenu() will bypass that limitation.
|
||||
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
|
||||
if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu))
|
||||
if (window->Flags & ImGuiWindowFlags_ChildMenu)
|
||||
flags |= ImGuiWindowFlags_ChildWindow;
|
||||
|
||||
// If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin().
|
||||
@ -6915,11 +6933,12 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
g.MenusIdSubmittedThisFrame.push_back(id);
|
||||
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
bool pressed;
|
||||
bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].OpenParentId == window->IDStack.back());
|
||||
|
||||
// Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent without always being a Child window)
|
||||
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
||||
ImGuiWindow* backed_nav_window = g.NavWindow;
|
||||
if (menuset_is_open)
|
||||
g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent)
|
||||
g.NavWindow = window;
|
||||
|
||||
// The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu,
|
||||
// However the final position is going to be different! It is chosen by FindBestWindowPosForPopup().
|
||||
@ -6929,6 +6948,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
|
||||
if (!enabled)
|
||||
BeginDisabled();
|
||||
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
bool pressed;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
// Menu inside an horizontal menu bar
|
||||
@ -7088,13 +7108,19 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImVec2 label_size = CalcTextSize(label, NULL, true);
|
||||
|
||||
const bool menuset_is_open = IsRootOfOpenMenuSet();
|
||||
ImGuiWindow* backed_nav_window = g.NavWindow;
|
||||
if (menuset_is_open)
|
||||
g.NavWindow = window;
|
||||
|
||||
// We've been using the equivalent of ImGuiSelectableFlags_SetNavIdOnHover on all Selectable() since early Nav system days (commit 43ee5d73),
|
||||
// but I am unsure whether this should be kept at all. For now moved it to be an opt-in feature used by menus only.
|
||||
bool pressed;
|
||||
PushID(label);
|
||||
if (!enabled)
|
||||
BeginDisabled();
|
||||
const ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover;
|
||||
|
||||
const ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover;
|
||||
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
|
||||
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
|
||||
{
|
||||
@ -7104,7 +7130,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
|
||||
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
|
||||
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
|
||||
pressed = Selectable("", selected, flags, ImVec2(w, 0.0f));
|
||||
pressed = Selectable("", selected, selectable_flags, ImVec2(w, 0.0f));
|
||||
PopStyleVar();
|
||||
RenderText(text_pos, label);
|
||||
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
|
||||
@ -7119,7 +7145,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
|
||||
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, shortcut_w, checkmark_w); // Feedback for next frame
|
||||
float stretch_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
|
||||
pressed = Selectable("", false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
||||
pressed = Selectable("", false, selectable_flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
|
||||
RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
|
||||
if (icon_w > 0.0f)
|
||||
RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
|
||||
@ -7136,6 +7162,8 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
|
||||
if (!enabled)
|
||||
EndDisabled();
|
||||
PopID();
|
||||
if (menuset_is_open)
|
||||
g.NavWindow = backed_nav_window;
|
||||
|
||||
return pressed;
|
||||
}
|
||||
|
Reference in New Issue
Block a user