Skip to content

Commit

Permalink
Demo: added "Shortcuts" section. (#456, #2637)
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornut committed May 23, 2024
1 parent fc512a2 commit dc5caa4
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Other changes:
- Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed.
Broken during a refactor refactor for 1.89. Holding Shift/R1 to speed up wasn't broken.
- Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet]
- Demo: Added "Inputs & Focus -> Shortcuts" section. (#456, #2637)
- Examples: Win32+DX9,DX10,DX11,DX12: rework main loop to handle minimization and screen
locking without burning resources by running unthrottled code. (#2496, #3907, #6308, #7615)
- Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller
Expand Down
97 changes: 92 additions & 5 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6262,6 +6262,86 @@ 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"))
{
ImGui::SeparatorText("Using SetNextItemShortcut()");
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S);
ImGui::Button("Save");
ImGui::SetItemTooltip("Ctrl+S"); // FIXME: Tooltip could be automatically submitted by SetNextItemShortcut

ImGui::SeparatorText("Using Shortcut()");
const float line_height = ImGui::GetTextLineHeightWithSpacing();
const ImGuiKeyChord key_chord = ImGuiMod_Ctrl | ImGuiKey_A;
static ImGuiInputFlags other_flags = ImGuiInputFlags_Repeat;
static ImGuiInputFlags routing_flags = ImGuiInputFlags_RouteFocused;
ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &other_flags, ImGuiInputFlags_Repeat);
ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &routing_flags, ImGuiInputFlags_RouteFocused);
ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &routing_flags, ImGuiInputFlags_RouteAlways);
ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &routing_flags, ImGuiInputFlags_RouteGlobal);
ImGui::RadioButton("ImGuiInputFlags_RouteGlobalOverFocused", &routing_flags, ImGuiInputFlags_RouteGlobalOverFocused);
ImGui::RadioButton("ImGuiInputFlags_RouteGlobalHighest", &routing_flags, ImGuiInputFlags_RouteGlobalHighest);
ImGui::CheckboxFlags("ImGuiInputFlags_RouteUnlessBgFocused", &other_flags, ImGuiInputFlags_RouteUnlessBgFocused);
const ImGuiInputFlags flags = other_flags | routing_flags; // Merged flags

ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");

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::TreePop();
}

// Display mouse cursors
IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors");
if (ImGui::TreeNode("Mouse Cursors"))
Expand Down Expand Up @@ -7126,6 +7206,7 @@ struct ExampleAppConsole
}

// Options, Filter
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O); // FIXME
if (ImGui::Button("Options"))
ImGui::OpenPopup("Options");
ImGui::SameLine();
Expand Down Expand Up @@ -8356,11 +8437,17 @@ struct MyDocument
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)))
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M);
if (ImGui::Button("Modify (Ctrl+M)"))
doc->Dirty = true;
ImGui::SameLine();
if (ImGui::Button("Save", ImVec2(100, 0)))
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S);
if (ImGui::Button("Save (Ctrl+S)"))
doc->DoSave();
ImGui::SameLine();
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W);
if (ImGui::Button("Close (Ctrl+W)"))
doc->DoQueueClose();
ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior.
ImGui::PopID();
}
Expand All @@ -8373,9 +8460,9 @@ struct MyDocument

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))
if (ImGui::MenuItem("Close", "Ctrl+W", false, doc->Open))
doc->DoQueueClose();
ImGui::EndPopup();
}
Expand Down Expand Up @@ -8448,7 +8535,7 @@ 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)
if (ImGui::MenuItem("Exit") && p_open)
*p_open = false;
ImGui::EndMenu();
}
Expand Down

0 comments on commit dc5caa4

Please sign in to comment.