Skip to content

Commit 24bd33a

Browse files
committed
Menus: Some renaming, comments, add to demo. Amend 0342a3c. (#1207)
1 parent 0342a3c commit 24bd33a

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

imgui.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -3623,7 +3623,7 @@ void ImGui::NewFrame()
36233623
g.FrameCount += 1;
36243624
g.TooltipOverrideCount = 0;
36253625
g.WindowsActiveCount = 0;
3626-
g.RenderedMenusId.resize(0);
3626+
g.MenusIdSubmittedThisFrame.resize(0);
36273627

36283628
// Setup current font and draw list shared data
36293629
g.IO.Fonts->Locked = true;
@@ -3915,6 +3915,7 @@ void ImGui::Shutdown(ImGuiContext* context)
39153915
g.ShrinkWidthBuffer.clear();
39163916

39173917
g.PrivateClipboard.clear();
3918+
g.MenusIdSubmittedThisFrame.clear();
39183919
g.InputTextState.ClearFreeMemory();
39193920

39203921
g.SettingsWindows.clear();

imgui.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ namespace ImGui
559559

560560
// Widgets: Menus
561561
// - Use BeginMenuBar() on a window ImGuiWindowFlags_MenuBar to append to its menu bar.
562-
// - Use BeginMainMenuBar() to create a menu bar at the top of the screen.
562+
// - Use BeginMainMenuBar() to create a menu bar at the top of the screen and append to it.
563+
// - Use BeginMenu() to create a menu. You can call BeginMenu() multiple time with the same identifier to append more items to it.
563564
IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window).
564565
IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true!
565566
IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar.

imgui_demo.cpp

+34-2
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,27 @@ void ImGui::ShowDemoWindow(bool* p_open)
288288
// Menu Bar
289289
if (ImGui::BeginMenuBar())
290290
{
291+
if (ImGui::BeginMenu("Foo"))
292+
{
293+
if (ImGui::BeginMenu("AAA"))
294+
{
295+
ImGui::EndMenu();
296+
}
297+
if (ImGui::BeginMenu("BBB"))
298+
{
299+
ImGui::EndMenu();
300+
}
301+
if (ImGui::BeginMenu("AAA"))
302+
{
303+
ImGui::EndMenu();
304+
}
305+
if (ImGui::BeginMenu("BBB"))
306+
{
307+
ImGui::EndMenu();
308+
}
309+
ImGui::EndMenu();
310+
}
311+
291312
if (ImGui::BeginMenu("Menu"))
292313
{
293314
ShowExampleMenuFile();
@@ -3580,6 +3601,7 @@ static void ShowExampleMenuFile()
35803601
}
35813602
if (ImGui::MenuItem("Save", "Ctrl+S")) {}
35823603
if (ImGui::MenuItem("Save As..")) {}
3604+
35833605
ImGui::Separator();
35843606
if (ImGui::BeginMenu("Options"))
35853607
{
@@ -3591,13 +3613,12 @@ static void ShowExampleMenuFile()
35913613
ImGui::EndChild();
35923614
static float f = 0.5f;
35933615
static int n = 0;
3594-
static bool b = true;
35953616
ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
35963617
ImGui::InputFloat("Input", &f, 0.1f);
35973618
ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
3598-
ImGui::Checkbox("Check", &b);
35993619
ImGui::EndMenu();
36003620
}
3621+
36013622
if (ImGui::BeginMenu("Colors"))
36023623
{
36033624
float sz = ImGui::GetTextLineHeight();
@@ -3612,6 +3633,17 @@ static void ShowExampleMenuFile()
36123633
}
36133634
ImGui::EndMenu();
36143635
}
3636+
3637+
// Here we demonstrate appending again to the "Options" menu (which we already created above)
3638+
// Of course in this demo it is a little bit silly that this function calls BeginMenu("Options") twice.
3639+
// In a real code-base using it would make senses to use this feature from very different code locations.
3640+
if (ImGui::BeginMenu("Options")) // <-- Append!
3641+
{
3642+
static bool b = true;
3643+
ImGui::Checkbox("SomeOption", &b);
3644+
ImGui::EndMenu();
3645+
}
3646+
36153647
if (ImGui::BeginMenu("Disabled", false)) // Disabled
36163648
{
36173649
IM_ASSERT(0);

imgui_internal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,7 @@ struct ImGuiContext
11591159
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
11601160
int TooltipOverrideCount;
11611161
ImVector<char> PrivateClipboard; // If no custom clipboard handler is defined
1162-
ImVector<ImGuiID> RenderedMenusId; // A list of menu IDs that were rendered at least once
1162+
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
11631163

11641164
// Platform support
11651165
ImVec2 PlatformImePos; // Cursor position request & last passed to the OS Input Method Editor

imgui_widgets.cpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -6223,25 +6223,26 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
62236223
const ImGuiStyle& style = g.Style;
62246224
const ImGuiID id = window->GetID(label);
62256225
bool menu_is_open = IsPopupOpen(id);
6226-
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
62276226

62286227
// 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)
6229-
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
6228+
ImGuiWindowFlags flags = ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNavFocus;
6229+
if (window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu))
62306230
flags |= ImGuiWindowFlags_ChildWindow;
62316231

6232-
if (g.RenderedMenusId.contains(id))
6232+
// If a menu with same the ID was already submitted, we will append to it, matching the behavior of Begin().
6233+
// 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.
6234+
// If somehow this is ever becoming a problem we can switch to use e.g. a ImGuiStorager mapping key to last frame used.
6235+
if (g.MenusIdSubmittedThisFrame.contains(id))
62336236
{
6234-
// Menu with same ID was already created - append to it.
62356237
if (menu_is_open)
62366238
menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
6237-
if (!menu_is_open)
6238-
g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
6239+
else
6240+
g.NextWindowData.ClearFlags(); // we behave like Begin() and need to consume those values
62396241
return menu_is_open;
62406242
}
6241-
else
6242-
{
6243-
g.RenderedMenusId.push_back(id); // Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu.
6244-
}
6243+
6244+
// Tag menu as used. Next time BeginMenu() with same ID is called it will append to existing menu
6245+
g.MenusIdSubmittedThisFrame.push_back(id);
62456246

62466247
ImVec2 label_size = CalcTextSize(label, NULL, true);
62476248
bool pressed;

0 commit comments

Comments
 (0)