Squashed 'external/imgui/imgui/' changes from 6ccc561a2ab..00ad3c65bc2
00ad3c65bc2 Version 1.90.7 f814ef816fb Commented out CaptureKeyboardFromApp(), CaptureMouseFromApp(). Commented out obsolete IsKeyPressedMap() from imgui_internal.h (can call IsKeyPressed). Comments b9084949bd7 Fixed typo in IsMouseDragging and GetMouseDragDelta's documentation. (#7620) 86931393a36 Shortcuts: Revert "SetShortcutRouting: require explicit routing. (#456) 7832e6a70e6 Shortcuts: Routing: fixed mixed keys<>chars filtering not applying on global routes. (#456, #7618) 85d982011e9 Shortcuts: fixed priority of route calculation (higher first). (#456, #7618) ce4e210dcb6 Shotcuts: renamed ImGuiInputFlags_RouteGlobalOverFocused -> ImGuiInputFlags_RouteOverFocused, ImGuiInputFlags_RouteGlobalOverActive -> ImGuiInputFlags_RouteOverActive in previsiion of using them with a Hovered route. (#456) 5ce3d299555 Shortcuts: rename ImGuiInputFlags_RouteGlobalHighest to ImGuiInputFlags_RouteGlobalOverActive, made ImGuiInputFlags_RouteGlobalOverFocused and ImGuiInputFlags_RouteGlobalOverActive flags. (#456) 650cb51bf10 Shortcuts: renamed ImGuiInputFlags_RouteActiveItem to ImGuiInputFlags_RouteActive. (#456, #7618) ef9d525f02c Shortcuts: added ImGuiInputFlags_RouteActiveItem. (#456, #7618) + rearrange Changelog 16b72f2d210 Comments 29439bdd27c Windows: BeginChild(): fixed auto-fit calculation when using either (not both) ResizeX/ResizeY and double-clicking on a border. (#1710) 374b9a7fb43 Demo: Documents: refactor + add Renaming option. (#7233) c150ad50c46 Shortcuts: claim mods ownership once pressed. (#456, #2637, #2620, #2891, #3370, #3724, #4828, #5108, #5242, #5641) 1002cfa6d2d Demo, Shortcut(): amend Shortcuts demo. (#456) 7c71e66370d Shortcuts, SetShortcutRouting: move ImGuiInputFlags_RouteFromRootWindow evaluation to SetShortcutRouting() for now. (#456) d5a600e9c64 Shortcuts, SetShortcutRouting: added ImGuiInputFlags_RouteFromRootWindow. Made it possible for SetShortcutRouting() to query for another location. 0eb025f4847 Internals: move ItemHandleShortcut() next to Shortcut(), it's calling it anyhow. (#456) a689fa262ae SetShortcutRouting: require explicit routing. (#456) c06e6340cde Shortcuts: added ImGuiInputFlags_Tooltip. (#456) 77e41718940 Shortcuts: added flags to SetNextItemShortcut(). (#456) 197f8904fe8 Shortcuts, Nav: make SetNextItemShortcut() work when another item is active. Made NavCalcPreferredRefPos() take account for remote activation. (#456) dc5caa483cd Demo: added "Shortcuts" section. (#456, #2637) fc512a24741 Inputs: Added Shortcut(), SetNextItemShortcut(). Added ImGuiInputFlags, ImGuiInputFlags_RouteXXXX. (#456, #2637) 85513de2476 Internals, Inputs: *Breaking* Swapped parameter order of owner-aware versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(). (#456) 900b29055c5 Internals, Inputs: *Breaking* Swapped parameter order of Shortcut(). (#456) 55748cdbe12 Internals, Inputs: *Breaking* Renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner: avoid confusion with non zero value, makes IsKeyPressed() calls using ImGuiKeyOwner_NoOwner more explicit. ec1d2be96f3 Examples: Win32+DX9,DX10,DX11,DX12: rework main loop to handle minimization and screen locking. (#2496, #3907, #6308, #7615) 6d1a6f1c748 Internals, Inputs: Comments, alignment. 4c3eac2c10e Backends: OpenGL3: Fixed zealous warning by initializing last_pixel_unpack_buffer. (#7614) a1566c5e1ba Tables: fixed 28a283b breaking PageDown on tables with no interactive items. aa725ca79dc Inputs: moving ImGuiInputFlags_RouteAlways into ImGuiInputFlags_RouteTypeMask_ cd48059dc53 Tables: comments about skipping access to table data in coarse clipping path. 28a283b4603 Windows: BeginChild(), Tables:fixed visibility of fully clipped child windows and tables to Test Engine. aa5a6098ee2 Fixed typos in comments (#7599) d39ca33b63a Fixed false positive with PVS-Studio. ae8218a3eaf Inputs, Shortcut: fixes some edge cases for GetKeyChordName(), clarify that it is aimed at display. (#456) 25e279ee73f Inputs: Treat ctrl-left-click as right click when ConfigMacOSXBehaviors is set. (#2343) b4f564c1ed7 Internals: Shortcuts: *Breaking* : rename ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal, ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobalOverFocused, ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobalHighest (#456) 5107e58b0f3 Inputs: amend changelog and clarify how the swap might be a breaking change for a minority of users. (#2343) 8bd5d1d42f0 Inputs: Fixed swapping of keys associated to mods. Fixed warnings. (#2343, #4084, #5923, #456) 77471066471 Inputs: swap Ctrl and Cmd on macOS X, remove ImGuiMod_Shortcut. (#2343, #4084, #5923, #456) 07dbcf1f70d Fixed typos. (#7593) 93daf232233 Examples: SDL3: updates for latest SDL3 API changes. e45efa9951a Backends: SDL3: Rename SDLK_QUOTE and SDLK_BACKQUOTE to SDLK_APOSTROPHE and SDLK_GRAVE. (#7580) 5d973a87d45 Backends: SDL_Renderer2/SDL_Renderer3: and ImGui_ImplSDLRenderer2_RenderDrawData() and ImGui_ImplSDLRenderer3_RenderDrawData() now takes a SDL_Renderer* parameter. af2fbf043df Backends/Internals: Don't use IME and clipboard default win32 functions when WINAPI_FAMILY_GAMES (#7585) e4576914cb9 Internals: amend f806c76 to better match docking + fixed unused static forward declaration warning. d0524df8879 Internals: slight refactor FindHoveredWindow() -> FindHoveredWindowEx() toward reducing far-away code duplication. f806c76e97b Tables, Dpi: added dummy g.DpiScale storage (to be altered in docking), using to scale tables border hit thickness. f0912833ba9 Update FAQ.md (#7581) ac90e1bd5bd Backends: Win32: replace bd != nullptr assert with early out. (#6275) 0a5d40a0161 Update FAQ.md d06b8b58d84 Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed. 5e236804541 Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller code and compiled version of dear imgui. (#7568) 510eb8f4801 Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) f48aae600a2 Version 1.90.7 WIP git-subtree-dir: external/imgui/imgui git-subtree-split: 00ad3c65bc256a16521288505f26fb335440f8f5
This commit is contained in:
332
imgui_demo.cpp
332
imgui_demo.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.90.6
|
||||
// dear imgui, v1.90.7
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -266,6 +266,9 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
// Most functions would normally just assert/crash if the context is missing.
|
||||
IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing Dear ImGui context. Refer to examples app!");
|
||||
|
||||
// Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues.
|
||||
IMGUI_CHECKVERSION();
|
||||
|
||||
// Examples Apps (accessible from the "Examples" menu)
|
||||
static bool show_app_main_menu_bar = false;
|
||||
static bool show_app_console = false;
|
||||
@@ -488,6 +491,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback.");
|
||||
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
|
||||
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);
|
||||
ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors.");
|
||||
ImGui::Text("Also see Style->Rendering for rendering options.");
|
||||
|
||||
ImGui::SeparatorText("Debug");
|
||||
@@ -6180,12 +6184,14 @@ static void ShowDemoWindowInputs()
|
||||
// Display inputs submitted to ImGuiIO
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Inputs");
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode("Inputs"))
|
||||
bool inputs_opened = ImGui::TreeNode("Inputs");
|
||||
ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"This is a simplified view. See more detailed input state:\n"
|
||||
"- in 'Tools->Metrics/Debugger->Inputs'.\n"
|
||||
"- in 'Tools->Debug Log->IO'.");
|
||||
if (inputs_opened)
|
||||
{
|
||||
HelpMarker(
|
||||
"This is a simplified view. See more detailed input state:\n"
|
||||
"- in 'Tools->Metrics/Debugger->Inputs'.\n"
|
||||
"- in 'Tools->Debug Log->IO'.");
|
||||
if (ImGui::IsMousePosValid())
|
||||
ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y);
|
||||
else
|
||||
@@ -6216,15 +6222,17 @@ static void ShowDemoWindowInputs()
|
||||
// Display ImGuiIO output flags
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Outputs");
|
||||
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
|
||||
if (ImGui::TreeNode("Outputs"))
|
||||
bool outputs_opened = ImGui::TreeNode("Outputs");
|
||||
ImGui::SameLine();
|
||||
HelpMarker(
|
||||
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
|
||||
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
|
||||
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
|
||||
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
|
||||
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
|
||||
"rules leading to how those flags are set).");
|
||||
if (outputs_opened)
|
||||
{
|
||||
HelpMarker(
|
||||
"The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui "
|
||||
"to instruct your application of how to route inputs. Typically, when a value is true, it means "
|
||||
"Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n"
|
||||
"The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, "
|
||||
"and underlying application should ignore mouse inputs (in practice there are many and more subtle "
|
||||
"rules leading to how those flags are set).");
|
||||
ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse);
|
||||
ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
|
||||
ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
|
||||
@@ -6258,6 +6266,102 @@ static void ShowDemoWindowInputs()
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Demonstrate using Shortcut() and Routing Policies.
|
||||
// The general flow is:
|
||||
// - Code interested in a chord (e.g. "Ctrl+A") declares their intent.
|
||||
// - Multiple locations may be interested in same chord! Routing helps find a winner.
|
||||
// - Every frame, we resolve all claims and assign one owner if the modifiers are matching.
|
||||
// - The lower-level function is 'bool SetShortcutRouting()', returns true when caller got the route.
|
||||
// - Most of the times, SetShortcutRouting() is not called directly. User mostly calls Shortcut() with routing flags.
|
||||
// - If you call Shortcut() WITHOUT any routing option, it uses ImGuiInputFlags_RouteFocused.
|
||||
// TL;DR: Most uses will simply be:
|
||||
// - Shortcut(ImGuiMod_Ctrl | ImGuiKey_A); // Use ImGuiInputFlags_RouteFocused policy.
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Shortcuts");
|
||||
if (ImGui::TreeNode("Shortcuts"))
|
||||
{
|
||||
static ImGuiInputFlags route_options = ImGuiInputFlags_Repeat;
|
||||
static ImGuiInputFlags route_type = ImGuiInputFlags_RouteFocused;
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &route_options, ImGuiInputFlags_Repeat);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteActive", &route_type, ImGuiInputFlags_RouteActive);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &route_type, ImGuiInputFlags_RouteFocused);
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &route_type, ImGuiInputFlags_RouteGlobal);
|
||||
ImGui::Indent();
|
||||
ImGui::BeginDisabled(route_type != ImGuiInputFlags_RouteGlobal);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverFocused", &route_options, ImGuiInputFlags_RouteOverFocused);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverActive", &route_options, ImGuiInputFlags_RouteOverActive);
|
||||
ImGui::CheckboxFlags("ImGuiInputFlags_RouteUnlessBgFocused", &route_options, ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::Unindent();
|
||||
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &route_type, ImGuiInputFlags_RouteAlways);
|
||||
ImGuiInputFlags flags = route_type | route_options; // Merged flags
|
||||
if (route_type != ImGuiInputFlags_RouteGlobal)
|
||||
route_options &= ~(ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused);
|
||||
|
||||
ImGui::SeparatorText("Using SetNextItemShortcut()");
|
||||
ImGui::Text("Ctrl+S");
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, flags | ImGuiInputFlags_Tooltip);
|
||||
ImGui::Button("Save");
|
||||
ImGui::Text("Alt+F");
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Alt | ImGuiKey_F, flags | ImGuiInputFlags_Tooltip);
|
||||
static float f = 0.5f;
|
||||
ImGui::SliderFloat("Factor", &f, 0.0f, 1.0f);
|
||||
|
||||
ImGui::SeparatorText("Using Shortcut()");
|
||||
const float line_height = ImGui::GetTextLineHeightWithSpacing();
|
||||
const ImGuiKeyChord key_chord = ImGuiMod_Ctrl | ImGuiKey_A;
|
||||
|
||||
ImGui::Text("Ctrl+A");
|
||||
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 1.0f, 0.1f));
|
||||
|
||||
ImGui::BeginChild("WindowA", ImVec2(-FLT_MIN, line_height * 14), true);
|
||||
ImGui::Text("Press CTRL+A and see who receives it!");
|
||||
ImGui::Separator();
|
||||
|
||||
// 1: Window polling for CTRL+A
|
||||
ImGui::Text("(in WindowA)");
|
||||
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
|
||||
|
||||
// 2: InputText also polling for CTRL+A: it always uses _RouteFocused internally (gets priority when active)
|
||||
// (Commmented because the owner-aware version of Shortcut() is still in imgui_internal.h)
|
||||
//char str[16] = "Press CTRL+A";
|
||||
//ImGui::Spacing();
|
||||
//ImGui::InputText("InputTextB", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly);
|
||||
//ImGuiID item_id = ImGui::GetItemID();
|
||||
//ImGui::SameLine(); HelpMarker("Internal widgets always use _RouteFocused");
|
||||
//ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags, item_id) ? "PRESSED" : "...");
|
||||
|
||||
// 3: Dummy child is not claiming the route: focusing them shouldn't steal route away from WindowA
|
||||
ImGui::BeginChild("ChildD", ImVec2(-FLT_MIN, line_height * 4), true);
|
||||
ImGui::Text("(in ChildD: not using same Shortcut)");
|
||||
ImGui::Text("IsWindowFocused: %d", ImGui::IsWindowFocused());
|
||||
ImGui::EndChild();
|
||||
|
||||
// 4: Child window polling for CTRL+A. It is deeper than WindowA and gets priority when focused.
|
||||
ImGui::BeginChild("ChildE", ImVec2(-FLT_MIN, line_height * 4), true);
|
||||
ImGui::Text("(in ChildE: using same Shortcut)");
|
||||
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
|
||||
ImGui::EndChild();
|
||||
|
||||
// 5: In a popup
|
||||
if (ImGui::Button("Open Popup"))
|
||||
ImGui::OpenPopup("PopupF");
|
||||
if (ImGui::BeginPopup("PopupF"))
|
||||
{
|
||||
ImGui::Text("(in PopupF)");
|
||||
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
|
||||
// (Commmented because the owner-aware version of Shortcut() is still in imgui_internal.h)
|
||||
//ImGui::InputText("InputTextG", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly);
|
||||
//ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags, ImGui::GetItemID()) ? "PRESSED" : "...");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
// Display mouse cursors
|
||||
IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors");
|
||||
if (ImGui::TreeNode("Mouse Cursors"))
|
||||
@@ -7122,6 +7226,7 @@ struct ExampleAppConsole
|
||||
}
|
||||
|
||||
// Options, Filter
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Options"))
|
||||
ImGui::OpenPopup("Options");
|
||||
ImGui::SameLine();
|
||||
@@ -7130,7 +7235,7 @@ struct ExampleAppConsole
|
||||
|
||||
// Reserve enough left-over height for 1 separator + 1 input text
|
||||
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar))
|
||||
if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NavFlattened))
|
||||
{
|
||||
if (ImGui::BeginPopupContextWindow())
|
||||
{
|
||||
@@ -8324,92 +8429,119 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// Simplified structure to mimic a Document model
|
||||
struct MyDocument
|
||||
{
|
||||
const char* Name; // Document title
|
||||
char Name[32]; // Document title
|
||||
int UID; // Unique ID (necessary as we can change title)
|
||||
bool Open; // Set when open (we keep an array of all available documents to simplify demo code!)
|
||||
bool OpenPrev; // Copy of Open from last update.
|
||||
bool Dirty; // Set when the document has been modified
|
||||
bool WantClose; // Set when the document
|
||||
ImVec4 Color; // An arbitrary variable associated to the document
|
||||
|
||||
MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
MyDocument(int uid, const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
Name = name;
|
||||
UID = uid;
|
||||
snprintf(Name, sizeof(Name), "%s", name);
|
||||
Open = OpenPrev = open;
|
||||
Dirty = false;
|
||||
WantClose = false;
|
||||
Color = color;
|
||||
}
|
||||
void DoOpen() { Open = true; }
|
||||
void DoQueueClose() { WantClose = true; }
|
||||
void DoForceClose() { Open = false; Dirty = false; }
|
||||
void DoSave() { Dirty = false; }
|
||||
};
|
||||
|
||||
struct ExampleAppDocuments
|
||||
{
|
||||
ImVector<MyDocument> Documents;
|
||||
ImVector<MyDocument*> CloseQueue;
|
||||
MyDocument* RenamingDoc = NULL;
|
||||
bool RenamingStarted = false;
|
||||
|
||||
ExampleAppDocuments()
|
||||
{
|
||||
Documents.push_back(MyDocument(0, "Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument(1, "Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f)));
|
||||
Documents.push_back(MyDocument(2, "Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f)));
|
||||
Documents.push_back(MyDocument(3, "Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument(4, "A Rather Long Title", false, ImVec4(0.4f, 0.8f, 0.8f, 1.0f)));
|
||||
Documents.push_back(MyDocument(5, "Some Document", false, ImVec4(0.8f, 0.8f, 1.0f, 1.0f)));
|
||||
}
|
||||
|
||||
// As we allow to change document name, we append a never-changing document ID so tabs are stable
|
||||
void GetTabName(MyDocument* doc, char* out_buf, size_t out_buf_size)
|
||||
{
|
||||
snprintf(out_buf, out_buf_size, "%s###doc%d", doc->Name, doc->UID);
|
||||
}
|
||||
|
||||
// Display placeholder contents for the Document
|
||||
static void DisplayContents(MyDocument* doc)
|
||||
void DisplayDocContents(MyDocument* doc)
|
||||
{
|
||||
ImGui::PushID(doc);
|
||||
ImGui::Text("Document \"%s\"", doc->Name);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, doc->Color);
|
||||
ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::Button("Modify", ImVec2(100, 0)))
|
||||
doc->Dirty = true;
|
||||
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_R, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Rename.."))
|
||||
{
|
||||
RenamingDoc = doc;
|
||||
RenamingStarted = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Save", ImVec2(100, 0)))
|
||||
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Modify"))
|
||||
doc->Dirty = true;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Save"))
|
||||
doc->DoSave();
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::Button("Close"))
|
||||
CloseQueue.push_back(doc);
|
||||
ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior.
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
// Display context menu for the Document
|
||||
static void DisplayContextMenu(MyDocument* doc)
|
||||
void DisplayDocContextMenu(MyDocument* doc)
|
||||
{
|
||||
if (!ImGui::BeginPopupContextItem())
|
||||
return;
|
||||
|
||||
char buf[256];
|
||||
sprintf(buf, "Save %s", doc->Name);
|
||||
if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open))
|
||||
if (ImGui::MenuItem(buf, "Ctrl+S", false, doc->Open))
|
||||
doc->DoSave();
|
||||
if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open))
|
||||
doc->DoQueueClose();
|
||||
if (ImGui::MenuItem("Rename...", "Ctrl+R", false, doc->Open))
|
||||
RenamingDoc = doc;
|
||||
if (ImGui::MenuItem("Close", "Ctrl+W", false, doc->Open))
|
||||
CloseQueue.push_back(doc);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
};
|
||||
|
||||
struct ExampleAppDocuments
|
||||
{
|
||||
ImVector<MyDocument> Documents;
|
||||
|
||||
ExampleAppDocuments()
|
||||
// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface.
|
||||
// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo,
|
||||
// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for
|
||||
// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has
|
||||
// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively
|
||||
// give the impression of a flicker for one frame.
|
||||
// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch.
|
||||
// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag.
|
||||
void NotifyOfDocumentsClosedElsewhere()
|
||||
{
|
||||
Documents.push_back(MyDocument("Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f)));
|
||||
Documents.push_back(MyDocument("Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f)));
|
||||
Documents.push_back(MyDocument("A Rather Long Title", false));
|
||||
Documents.push_back(MyDocument("Some Document", false));
|
||||
for (MyDocument& doc : Documents)
|
||||
{
|
||||
if (!doc.Open && doc.OpenPrev)
|
||||
ImGui::SetTabItemClosed(doc.Name);
|
||||
doc.OpenPrev = doc.Open;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface.
|
||||
// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo,
|
||||
// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for
|
||||
// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has
|
||||
// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively
|
||||
// give the impression of a flicker for one frame.
|
||||
// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch.
|
||||
// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag.
|
||||
static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app)
|
||||
{
|
||||
for (MyDocument& doc : app.Documents)
|
||||
{
|
||||
if (!doc.Open && doc.OpenPrev)
|
||||
ImGui::SetTabItemClosed(doc.Name);
|
||||
doc.OpenPrev = doc.Open;
|
||||
}
|
||||
}
|
||||
|
||||
void ShowExampleAppDocuments(bool* p_open)
|
||||
{
|
||||
static ExampleAppDocuments app;
|
||||
@@ -8443,8 +8575,8 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
}
|
||||
if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0))
|
||||
for (MyDocument& doc : app.Documents)
|
||||
doc.DoQueueClose();
|
||||
if (ImGui::MenuItem("Exit", "Ctrl+F4") && p_open)
|
||||
app.CloseQueue.push_back(&doc);
|
||||
if (ImGui::MenuItem("Exit") && p_open)
|
||||
*p_open = false;
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
@@ -8482,7 +8614,7 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
if (ImGui::BeginTabBar("##tabs", tab_bar_flags))
|
||||
{
|
||||
if (opt_reorderable)
|
||||
NotifyOfDocumentsClosedElsewhere(app);
|
||||
app.NotifyOfDocumentsClosedElsewhere();
|
||||
|
||||
// [DEBUG] Stress tests
|
||||
//if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1; // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on.
|
||||
@@ -8494,20 +8626,23 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
if (!doc.Open)
|
||||
continue;
|
||||
|
||||
// As we allow to change document name, we append a never-changing document id so tabs are stable
|
||||
char doc_name_buf[64];
|
||||
app.GetTabName(&doc, doc_name_buf, sizeof(doc_name_buf));
|
||||
ImGuiTabItemFlags tab_flags = (doc.Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0);
|
||||
bool visible = ImGui::BeginTabItem(doc.Name, &doc.Open, tab_flags);
|
||||
bool visible = ImGui::BeginTabItem(doc_name_buf, &doc.Open, tab_flags);
|
||||
|
||||
// Cancel attempt to close when unsaved add to save queue so we can display a popup.
|
||||
if (!doc.Open && doc.Dirty)
|
||||
{
|
||||
doc.Open = true;
|
||||
doc.DoQueueClose();
|
||||
app.CloseQueue.push_back(&doc);
|
||||
}
|
||||
|
||||
MyDocument::DisplayContextMenu(&doc);
|
||||
app.DisplayDocContextMenu(&doc);
|
||||
if (visible)
|
||||
{
|
||||
MyDocument::DisplayContents(&doc);
|
||||
app.DisplayDocContents(&doc);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
@@ -8516,33 +8651,44 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
}
|
||||
}
|
||||
|
||||
// Update closing queue
|
||||
static ImVector<MyDocument*> close_queue;
|
||||
if (close_queue.empty())
|
||||
// Display renaming UI
|
||||
if (app.RenamingDoc != NULL)
|
||||
{
|
||||
// Close queue is locked once we started a popup
|
||||
for (MyDocument& doc : app.Documents)
|
||||
if (doc.WantClose)
|
||||
if (app.RenamingStarted)
|
||||
ImGui::OpenPopup("Rename");
|
||||
if (ImGui::BeginPopup("Rename"))
|
||||
{
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 30);
|
||||
if (ImGui::InputText("###Name", app.RenamingDoc->Name, IM_ARRAYSIZE(app.RenamingDoc->Name), ImGuiInputTextFlags_EnterReturnsTrue))
|
||||
{
|
||||
doc.WantClose = false;
|
||||
close_queue.push_back(&doc);
|
||||
ImGui::CloseCurrentPopup();
|
||||
app.RenamingDoc = NULL;
|
||||
}
|
||||
if (app.RenamingStarted)
|
||||
ImGui::SetKeyboardFocusHere(-1);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.RenamingDoc = NULL;
|
||||
}
|
||||
app.RenamingStarted = false;
|
||||
}
|
||||
|
||||
// Display closing confirmation UI
|
||||
if (!close_queue.empty())
|
||||
if (!app.CloseQueue.empty())
|
||||
{
|
||||
int close_queue_unsaved_documents = 0;
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
if (close_queue[n]->Dirty)
|
||||
for (int n = 0; n < app.CloseQueue.Size; n++)
|
||||
if (app.CloseQueue[n]->Dirty)
|
||||
close_queue_unsaved_documents++;
|
||||
|
||||
if (close_queue_unsaved_documents == 0)
|
||||
{
|
||||
// Close documents when all are unsaved
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
close_queue[n]->DoForceClose();
|
||||
close_queue.clear();
|
||||
for (int n = 0; n < app.CloseQueue.Size; n++)
|
||||
app.CloseQueue[n]->DoForceClose();
|
||||
app.CloseQueue.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8553,37 +8699,35 @@ void ShowExampleAppDocuments(bool* p_open)
|
||||
ImGui::Text("Save change to the following items?");
|
||||
float item_height = ImGui::GetTextLineHeightWithSpacing();
|
||||
if (ImGui::BeginChild(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height), ImGuiChildFlags_FrameStyle))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
if (close_queue[n]->Dirty)
|
||||
ImGui::Text("%s", close_queue[n]->Name);
|
||||
}
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
if (doc->Dirty)
|
||||
ImGui::Text("%s", doc->Name);
|
||||
ImGui::EndChild();
|
||||
|
||||
ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f);
|
||||
if (ImGui::Button("Yes", button_size))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
{
|
||||
if (close_queue[n]->Dirty)
|
||||
close_queue[n]->DoSave();
|
||||
close_queue[n]->DoForceClose();
|
||||
if (doc->Dirty)
|
||||
doc->DoSave();
|
||||
doc->DoForceClose();
|
||||
}
|
||||
close_queue.clear();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("No", button_size))
|
||||
{
|
||||
for (int n = 0; n < close_queue.Size; n++)
|
||||
close_queue[n]->DoForceClose();
|
||||
close_queue.clear();
|
||||
for (MyDocument* doc : app.CloseQueue)
|
||||
doc->DoForceClose();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Cancel", button_size))
|
||||
{
|
||||
close_queue.clear();
|
||||
app.CloseQueue.clear();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
||||
Reference in New Issue
Block a user