From 000c1fc2216cf400fd6adb80fad8bc29dab63e0a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 16 Oct 2018 10:25:32 +0200 Subject: [PATCH] Demo: Added comments / tweaks related to the popups. --- imgui.h | 2 +- imgui_demo.cpp | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/imgui.h b/imgui.h index dd089716e..b3efc4b12 100644 --- a/imgui.h +++ b/imgui.h @@ -484,7 +484,7 @@ namespace ImGui IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! - IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. + IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item (note: actually triggers on the mouse _released_ event to be consistent with popup behaviors). return true when just opened. IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 79c44efa2..dd8015f29 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1880,6 +1880,21 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::CollapsingHeader("Popups & Modal windows")) { + // Popups are windows with a few special properties: + // - They block normal mouse hovering detection outside them. (*) + // - Unless modal, they can be closed by clicking anywhere outside them, or by pressing ESCAPE. + // - Their visibility state (~bool) is held internally by imgui instead of being held by the programmer as we are used to with regular Begin() calls. + // (*) One can use IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup) to bypass it and detect hovering even when normally blocked by a popup. + // Those three properties are intimately connected. The library needs to hold their visibility state because it can close popups at any time. + + // Typical use for regular windows: + // bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End(); + // Typical use for popups: + // if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup") { [...] EndPopup(); } + + // With popups we have to go through a library call (here OpenPopup) to manipulate the visibility state. + // This may be a bit confusing at first but it should quickly make sense. Follow on the examples below. + if (ImGui::TreeNode("Popups")) { ImGui::TextWrapped("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it."); @@ -1891,10 +1906,10 @@ void ImGui::ShowDemoWindow(bool* p_open) // Simple selection popup // (If you want to show the current selection inside the Button itself, you may want to build a string using the "###" operator to preserve a constant ID with a variable label) if (ImGui::Button("Select..")) - ImGui::OpenPopup("select"); + ImGui::OpenPopup("my_select_popup"); ImGui::SameLine(); ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); - if (ImGui::BeginPopup("select")) + if (ImGui::BeginPopup("my_select_popup")) { ImGui::Text("Aquarium"); ImGui::Separator(); @@ -1906,8 +1921,8 @@ void ImGui::ShowDemoWindow(bool* p_open) // Showing a menu with toggles if (ImGui::Button("Toggle..")) - ImGui::OpenPopup("toggle"); - if (ImGui::BeginPopup("toggle")) + ImGui::OpenPopup("my_toggle_popup"); + if (ImGui::BeginPopup("my_toggle_popup")) { for (int i = 0; i < IM_ARRAYSIZE(names); i++) ImGui::MenuItem(names[i], "", &toggles[i]); @@ -1938,9 +1953,10 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::EndPopup(); } - if (ImGui::Button("Popup Menu..")) - ImGui::OpenPopup("FilePopup"); - if (ImGui::BeginPopup("FilePopup")) + // Call the more complete ShowExampleMenuFile which we use in various places of this demo + if (ImGui::Button("File Menu..")) + ImGui::OpenPopup("my_file_popup"); + if (ImGui::BeginPopup("my_file_popup")) { ShowExampleMenuFile(); ImGui::EndPopup(); @@ -1952,7 +1968,7 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::TreeNode("Context menus")) { // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: - // if (IsItemHovered() && IsMouseClicked(0)) + // if (IsItemHovered() && IsMouseReleased(0)) // OpenPopup(id); // return BeginPopup(id); // For more advanced uses you may want to replicate and cuztomize this code. This the comments inside BeginPopupContextItem() implementation. @@ -1968,10 +1984,18 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::EndPopup(); } + // We can also use OpenPopupOnItemClick() which is the same as BeginPopupContextItem() but without the Begin call. + // So here we will make it that clicking on the text field with the right mouse button (1) will toggle the visibility of the popup above. + ImGui::Text("(You can also right-click me to the same popup as above.)"); + ImGui::OpenPopupOnItemClick("item context menu", 1); + + // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). + // BeginPopupContextItem() will use the last item ID as the popup ID. + // In addition here, we want to include your editable label inside the button label. We use the ### operator to override the ID (read FAQ about ID for details) static char name[32] = "Label1"; char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label ImGui::Button(buf); - if (ImGui::BeginPopupContextItem()) // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). + if (ImGui::BeginPopupContextItem()) { ImGui::Text("Edit name:"); ImGui::InputText("##edit", name, IM_ARRAYSIZE(name));