|  |  |  | @ -291,56 +291,6 @@ bool button_with_pos(ImTextureID user_texture_id, const ImVec2 &size, const ImVe | 
		
	
		
			
				|  |  |  |  |     return pressed; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool menu_item_with_icon(const char* label, const char* shortcut, ImU32 icon_color, bool selected, bool enabled/* = true*/) { | 
		
	
		
			
				|  |  |  |  |     ImGuiWindow* window = ImGui::GetCurrentWindow(); | 
		
	
		
			
				|  |  |  |  |     if (window->SkipItems) | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ImGuiContext& g = *GImGui; | 
		
	
		
			
				|  |  |  |  |     ImGuiStyle& style = g.Style; | 
		
	
		
			
				|  |  |  |  |     ImVec2 pos = window->DC.CursorPos; | 
		
	
		
			
				|  |  |  |  |     ImVec2 label_size = ImGui::CalcTextSize(label, NULL, true); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // 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.
 | 
		
	
		
			
				|  |  |  |  |     ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | (enabled ? 0 : ImGuiSelectableFlags_Disabled); | 
		
	
		
			
				|  |  |  |  |     bool pressed; | 
		
	
		
			
				|  |  |  |  |     if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
 | 
		
	
		
			
				|  |  |  |  |         // Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
 | 
		
	
		
			
				|  |  |  |  |         float w = label_size.x; | 
		
	
		
			
				|  |  |  |  |         window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); | 
		
	
		
			
				|  |  |  |  |         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); | 
		
	
		
			
				|  |  |  |  |         pressed = ImGui::Selectable(label, selected, flags, ImVec2(w, 0.0f)); | 
		
	
		
			
				|  |  |  |  |         ImGui::PopStyleVar(); | 
		
	
		
			
				|  |  |  |  |         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().
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         // Menu item inside a vertical menu
 | 
		
	
		
			
				|  |  |  |  |         // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
 | 
		
	
		
			
				|  |  |  |  |         //  Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
 | 
		
	
		
			
				|  |  |  |  |         float shortcut_w = shortcut ? ImGui::CalcTextSize(shortcut, NULL).x : 0.0f; | 
		
	
		
			
				|  |  |  |  |         float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
 | 
		
	
		
			
				|  |  |  |  |         float extra_w = std::max(0.0f, ImGui::GetContentRegionAvail().x - min_w); | 
		
	
		
			
				|  |  |  |  |         pressed = ImGui::Selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); | 
		
	
		
			
				|  |  |  |  |         ImVec2 pos_min = pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f); | 
		
	
		
			
				|  |  |  |  |         ImGui::RenderFrame(pos_min, pos_min + ImVec2(14, 14), icon_color); | 
		
	
		
			
				|  |  |  |  |         if (shortcut_w > 0.0f) | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); | 
		
	
		
			
				|  |  |  |  |             ImGui::RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); | 
		
	
		
			
				|  |  |  |  |             ImGui::PopStyleColor(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if (selected) | 
		
	
		
			
				|  |  |  |  |             ImGui::RenderCheckMark(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0)); | 
		
	
		
			
				|  |  |  |  |     return pressed; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | ImGuiWrapper::ImGuiWrapper() | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     ImGui::CreateContext(); | 
		
	
	
		
			
				
					|  |  |  | @ -1170,14 +1120,17 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // mark a label with a ColorMarkerHovered, if item is hovered
 | 
		
	
		
			
				|  |  |  |  |     char marked_label[512]; //255 symbols is not enough for translated string (e.t. to Russian)
 | 
		
	
		
			
				|  |  |  |  |     if (hovered) | 
		
	
		
			
				|  |  |  |  |     if (hovered || selected) { | 
		
	
		
			
				|  |  |  |  |         sprintf(marked_label, "%c%s", ImGui::ColorMarkerHovered, label); | 
		
	
		
			
				|  |  |  |  |         ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 1.0f, 1.0f, 1.0f)); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         strcpy(marked_label, label); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); | 
		
	
		
			
				|  |  |  |  |     ImGui::RenderTextClipped(text_min, text_max, marked_label, NULL, &label_size, style.SelectableTextAlign, &bb); | 
		
	
		
			
				|  |  |  |  |     if (flags & ImGuiSelectableFlags_Disabled) ImGui::PopStyleColor(); | 
		
	
		
			
				|  |  |  |  |     if (hovered || selected) ImGui::PopStyleColor(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Automatically close popups
 | 
		
	
		
			
				|  |  |  |  |     if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(g.CurrentItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) | 
		
	
	
		
			
				
					|  |  |  | @ -1187,6 +1140,228 @@ static bool selectable(const char* label, bool selected, ImGuiSelectableFlags fl | 
		
	
		
			
				|  |  |  |  |     return pressed; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool begin_menu(const char *label, bool enabled) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     ImGuiWindow *window = ImGui::GetCurrentWindow(); | 
		
	
		
			
				|  |  |  |  |     if (window->SkipItems) return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ImGuiContext &    g            = *GImGui; | 
		
	
		
			
				|  |  |  |  |     const ImGuiStyle &style        = g.Style; | 
		
	
		
			
				|  |  |  |  |     const ImGuiID     id           = window->GetID(label); | 
		
	
		
			
				|  |  |  |  |     bool              menu_is_open = ImGui::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)
 | 
		
	
		
			
				|  |  |  |  |     ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | | 
		
	
		
			
				|  |  |  |  |                              ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus; | 
		
	
		
			
				|  |  |  |  |     if (window->Flags & (ImGuiWindowFlags_Popup | 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().
 | 
		
	
		
			
				|  |  |  |  |     // We are relying on a O(N) search - so O(N log N) over the frame - which seems like the most efficient for the expected small amount of BeginMenu() calls per frame.
 | 
		
	
		
			
				|  |  |  |  |     // If somehow this is ever becoming a problem we can switch to use e.g. ImGuiStorage mapping key to last frame used.
 | 
		
	
		
			
				|  |  |  |  |     if (g.MenusIdSubmittedThisFrame.contains(id)) { | 
		
	
		
			
				|  |  |  |  |         if (menu_is_open) | 
		
	
		
			
				|  |  |  |  |             menu_is_open = ImGui::BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
 | 
		
	
		
			
				|  |  |  |  |         else | 
		
	
		
			
				|  |  |  |  |             g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
 | 
		
	
		
			
				|  |  |  |  |         return menu_is_open; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
 | 
		
	
		
			
				|  |  |  |  |     g.MenusIdSubmittedThisFrame.push_back(id); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ImVec2 label_size = ImGui::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()); | 
		
	
		
			
				|  |  |  |  |     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)
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // 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().
 | 
		
	
		
			
				|  |  |  |  |     // e.g. Menus tend to overlap each other horizontally to amplify relative Z-ordering.
 | 
		
	
		
			
				|  |  |  |  |     ImVec2 popup_pos, pos = window->DC.CursorPos; | 
		
	
		
			
				|  |  |  |  |     if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { | 
		
	
		
			
				|  |  |  |  |         // Menu inside an horizontal menu bar
 | 
		
	
		
			
				|  |  |  |  |         // Selectable extend their highlight by half ItemSpacing in each direction.
 | 
		
	
		
			
				|  |  |  |  |         // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin()
 | 
		
	
		
			
				|  |  |  |  |         popup_pos = ImVec2(pos.x - 1.0f - IM_FLOOR(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight()); | 
		
	
		
			
				|  |  |  |  |         window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); | 
		
	
		
			
				|  |  |  |  |         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); | 
		
	
		
			
				|  |  |  |  |         float w = label_size.x; | 
		
	
		
			
				|  |  |  |  |         pressed = selectable(label, menu_is_open, | 
		
	
		
			
				|  |  |  |  |                              ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | | 
		
	
		
			
				|  |  |  |  |                                  (!enabled ? ImGuiSelectableFlags_Disabled : 0), | 
		
	
		
			
				|  |  |  |  |                              ImVec2(w, 0.0f)); | 
		
	
		
			
				|  |  |  |  |         ImGui::PopStyleVar(); | 
		
	
		
			
				|  |  |  |  |         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().
 | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         // Menu inside a menu
 | 
		
	
		
			
				|  |  |  |  |         // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
 | 
		
	
		
			
				|  |  |  |  |         //  Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
 | 
		
	
		
			
				|  |  |  |  |         popup_pos      = ImVec2(pos.x, pos.y - style.WindowPadding.y); | 
		
	
		
			
				|  |  |  |  |         float min_w    = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame
 | 
		
	
		
			
				|  |  |  |  |         float extra_w  = ImMax(0.0f, ImGui::GetContentRegionAvail().x - min_w); | 
		
	
		
			
				|  |  |  |  |         pressed        = selectable(label, menu_is_open, | 
		
	
		
			
				|  |  |  |  |                              ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | | 
		
	
		
			
				|  |  |  |  |                                  ImGuiSelectableFlags_SpanAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), | 
		
	
		
			
				|  |  |  |  |                              ImVec2(min_w, 0.0f)); | 
		
	
		
			
				|  |  |  |  |         ImU32 text_col = ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled); | 
		
	
		
			
				|  |  |  |  |         ImGui::RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     const bool hovered = enabled && ImGui::ItemHoverable(window->DC.LastItemRect, id); | 
		
	
		
			
				|  |  |  |  |     if (menuset_is_open) g.NavWindow = backed_nav_window; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     bool want_open  = false; | 
		
	
		
			
				|  |  |  |  |     bool want_close = false; | 
		
	
		
			
				|  |  |  |  |     if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
 | 
		
	
		
			
				|  |  |  |  |     { | 
		
	
		
			
				|  |  |  |  |         // Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu
 | 
		
	
		
			
				|  |  |  |  |         // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
 | 
		
	
		
			
				|  |  |  |  |         bool moving_toward_other_child_menu = false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         ImGuiWindow *child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? | 
		
	
		
			
				|  |  |  |  |                                              g.OpenPopupStack[g.BeginPopupStack.Size].Window : | 
		
	
		
			
				|  |  |  |  |                                              NULL; | 
		
	
		
			
				|  |  |  |  |         if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar)) { | 
		
	
		
			
				|  |  |  |  |             // FIXME-DPI: Values should be derived from a master "scale" factor.
 | 
		
	
		
			
				|  |  |  |  |             ImRect next_window_rect = child_menu_window->Rect(); | 
		
	
		
			
				|  |  |  |  |             ImVec2 ta               = g.IO.MousePos - g.IO.MouseDelta; | 
		
	
		
			
				|  |  |  |  |             ImVec2 tb               = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); | 
		
	
		
			
				|  |  |  |  |             ImVec2 tc               = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); | 
		
	
		
			
				|  |  |  |  |             float  extra            = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
 | 
		
	
		
			
				|  |  |  |  |             ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f;          // to avoid numerical issues
 | 
		
	
		
			
				|  |  |  |  |             tb.y = ta.y + | 
		
	
		
			
				|  |  |  |  |                    ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
 | 
		
	
		
			
				|  |  |  |  |             tc.y                           = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); | 
		
	
		
			
				|  |  |  |  |             moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); | 
		
	
		
			
				|  |  |  |  |             // GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu) | 
		
	
		
			
				|  |  |  |  |             want_close = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (!menu_is_open && hovered && pressed) // Click to open
 | 
		
	
		
			
				|  |  |  |  |             want_open = true; | 
		
	
		
			
				|  |  |  |  |         else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
 | 
		
	
		
			
				|  |  |  |  |             want_open = true; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (g.NavActivateId == id) { | 
		
	
		
			
				|  |  |  |  |             want_close = menu_is_open; | 
		
	
		
			
				|  |  |  |  |             want_open  = !menu_is_open; | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
 | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             want_open = true; | 
		
	
		
			
				|  |  |  |  |             ImGui::NavMoveRequestCancel(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         // Menu bar
 | 
		
	
		
			
				|  |  |  |  |         if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it
 | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             want_close = true; | 
		
	
		
			
				|  |  |  |  |             want_open = menu_is_open = false; | 
		
	
		
			
				|  |  |  |  |         } else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others
 | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             want_open = true; | 
		
	
		
			
				|  |  |  |  |         } else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open
 | 
		
	
		
			
				|  |  |  |  |         { | 
		
	
		
			
				|  |  |  |  |             want_open = true; | 
		
	
		
			
				|  |  |  |  |             ImGui::NavMoveRequestCancel(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }'
 | 
		
	
		
			
				|  |  |  |  |         want_close = true; | 
		
	
		
			
				|  |  |  |  |     if (want_close && ImGui::IsPopupOpen(id, ImGuiPopupFlags_None)) ImGui::ClosePopupToLevel(g.BeginPopupStack.Size, true); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Openable | (menu_is_open ? ImGuiItemStatusFlags_Opened : 0)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.BeginPopupStack.Size) { | 
		
	
		
			
				|  |  |  |  |         // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame.
 | 
		
	
		
			
				|  |  |  |  |         ImGui::OpenPopup(label); | 
		
	
		
			
				|  |  |  |  |         return false; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     menu_is_open |= want_open; | 
		
	
		
			
				|  |  |  |  |     if (want_open) ImGui::OpenPopup(label); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (menu_is_open) { | 
		
	
		
			
				|  |  |  |  |         ImGui::SetNextWindowPos(popup_pos, | 
		
	
		
			
				|  |  |  |  |                                 ImGuiCond_Always);     // Note: this is super misleading! The value will serve as reference for FindBestWindowPosForPopup(), not actual pos.
 | 
		
	
		
			
				|  |  |  |  |         menu_is_open = ImGui::BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
 | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
 | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return menu_is_open; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void end_menu()  | 
		
	
		
			
				|  |  |  |  | {  | 
		
	
		
			
				|  |  |  |  |     ImGui::EndMenu();  | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | bool menu_item_with_icon(const char *label, const char *shortcut, ImVec2 icon_size /* = ImVec2(0, 0)*/, ImU32 icon_color /* = 0*/, bool selected /* = false*/, bool enabled /* = true*/) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     ImGuiWindow *window = ImGui::GetCurrentWindow(); | 
		
	
		
			
				|  |  |  |  |     if (window->SkipItems) return false; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     ImGuiContext &g          = *GImGui; | 
		
	
		
			
				|  |  |  |  |     ImGuiStyle &  style      = g.Style; | 
		
	
		
			
				|  |  |  |  |     ImVec2        pos        = window->DC.CursorPos; | 
		
	
		
			
				|  |  |  |  |     ImVec2        label_size = ImGui::CalcTextSize(label, NULL, true); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     // 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.
 | 
		
	
		
			
				|  |  |  |  |     ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover | (enabled ? 0 : ImGuiSelectableFlags_Disabled); | 
		
	
		
			
				|  |  |  |  |     bool                 pressed; | 
		
	
		
			
				|  |  |  |  |     if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { | 
		
	
		
			
				|  |  |  |  |         // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful
 | 
		
	
		
			
				|  |  |  |  |         // Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
 | 
		
	
		
			
				|  |  |  |  |         float w = label_size.x; | 
		
	
		
			
				|  |  |  |  |         window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); | 
		
	
		
			
				|  |  |  |  |         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); | 
		
	
		
			
				|  |  |  |  |         pressed = ImGui::Selectable(label, selected, flags, ImVec2(w, 0.0f)); | 
		
	
		
			
				|  |  |  |  |         ImGui::PopStyleVar(); | 
		
	
		
			
				|  |  |  |  |         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().
 | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |         // Menu item inside a vertical menu
 | 
		
	
		
			
				|  |  |  |  |         // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
 | 
		
	
		
			
				|  |  |  |  |         //  Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
 | 
		
	
		
			
				|  |  |  |  |         float shortcut_w = shortcut ? ImGui::CalcTextSize(shortcut, NULL).x : 0.0f; | 
		
	
		
			
				|  |  |  |  |         float min_w      = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
 | 
		
	
		
			
				|  |  |  |  |         float extra_w    = std::max(0.0f, ImGui::GetContentRegionAvail().x - min_w); | 
		
	
		
			
				|  |  |  |  |         pressed          = selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (icon_size.x != 0 && icon_size.y != 0) { | 
		
	
		
			
				|  |  |  |  |             float selectable_pos_y = pos.y + -0.5f * style.ItemSpacing.y; | 
		
	
		
			
				|  |  |  |  |             float icon_pos_y = selectable_pos_y + (label_size.y + style.ItemSpacing.y - icon_size.y) / 2; | 
		
	
		
			
				|  |  |  |  |             float icon_pos_x = pos.x + window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f; | 
		
	
		
			
				|  |  |  |  |             ImVec2 icon_pos = ImVec2(icon_pos_x, icon_pos_y); | 
		
	
		
			
				|  |  |  |  |             ImGui::RenderFrame(icon_pos, icon_pos + icon_size, icon_color); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |         if (shortcut_w > 0.0f) { | 
		
	
		
			
				|  |  |  |  |             ImGui::PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); | 
		
	
		
			
				|  |  |  |  |             ImGui::RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); | 
		
	
		
			
				|  |  |  |  |             ImGui::PopStyleColor(); | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |         if (selected) { | 
		
	
		
			
				|  |  |  |  |             //ImGui::RenderCheckMark(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f),
 | 
		
	
		
			
				|  |  |  |  |             //                       ImGui::GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f);
 | 
		
	
		
			
				|  |  |  |  |         } | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     IMGUI_TEST_ENGINE_ITEM_INFO(window->DC.LastItemId, label, window->DC.LastItemStatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0)); | 
		
	
		
			
				|  |  |  |  |     return pressed; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | // Scroll so that the hovered item is at the top of the window
 | 
		
	
		
			
				|  |  |  |  | static void scroll_y(int hover_id) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
	
		
			
				
					|  |  |  | @ -1445,13 +1620,13 @@ std::vector<unsigned char> ImGuiWrapper::load_svg(const std::string& bitmap_name | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | //BBS
 | 
		
	
		
			
				|  |  |  |  | void ImGuiWrapper::push_toolbar_style() | 
		
	
		
			
				|  |  |  |  | void ImGuiWrapper::push_toolbar_style(const float scale) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f)); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0f, 10.0f) * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 3.0f * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f) * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(50/255.0f, 58/255.0f, 61/255.0f, 1.00f));       // 1
 | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleColor(ImGuiCol_WindowBg, ImGuiWrapper::COL_WINDOW_BG);          // 2
 | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleColor(ImGuiCol_TitleBg, ImGuiWrapper::COL_TITLE_BG);            // 3
 | 
		
	
	
		
			
				
					|  |  |  | @ -1476,11 +1651,11 @@ void ImGuiWrapper::pop_toolbar_style() | 
		
	
		
			
				|  |  |  |  |     ImGui::PopStyleVar(5); | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | void ImGuiWrapper::push_menu_style() | 
		
	
		
			
				|  |  |  |  | void ImGuiWrapper::push_menu_style(const float scale) | 
		
	
		
			
				|  |  |  |  | { | 
		
	
		
			
				|  |  |  |  |     ImGuiWrapper::push_toolbar_style(); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f)); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f); | 
		
	
		
			
				|  |  |  |  |     ImGuiWrapper::push_toolbar_style(scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10.0f, 10.0f) * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_PopupRounding, 4.0f * scale); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleVar(ImGuiStyleVar_PopupBorderSize, 0.0f); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BG); | 
		
	
		
			
				|  |  |  |  |     ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.00f, 0.68f, 0.26f, 1.0f)); | 
		
	
	
		
			
				
					|  |  |  | 
 |