@@ -7817,6 +7817,8 @@ static void DemoWindowColumns()
78177817// [SECTION] DemoWindowInputs()
78187818//-----------------------------------------------------------------------------
78197819
7820+ #include "imgui_internal.h" // FIXME Until the new key owner/routing system are in public API this section of the demo needs internal (and is kept in a branch).
7821+
78207822static void DemoWindowInputs()
78217823{
78227824 if (ImGui::CollapsingHeader("Inputs & Focus"))
@@ -8002,7 +8004,112 @@ static void DemoWindowInputs()
80028004 }
80038005 ImGui::EndChild();
80048006 ImGui::PopStyleColor();
8007+ ImGui::TreePop();
8008+ }
8009+
8010+ // Ownership, Routings
8011+ IMGUI_DEMO_MARKER("Inputs & Focus/Key Ownership");
8012+ if (ImGui::TreeNode("Key Ownership"))
8013+ {
8014+ HelpMarker("See 'Tools->Metrics/Debugger->Inputs' to visualize ownership/routing data.");
8015+
8016+ // Demonstrate basic key ownership system
8017+ // Standard widgets all claim and test for key ownership
8018+ // (note that the ActiveId and HoveredId systems also generally prevents multiple items from interacting, but at a different level)
8019+ if (ImGui::TreeNode("1. Standard widgets taking input ownership"))
8020+ {
8021+ HelpMarker("Standard widgets claim and test for key ownership.\n\n\"Keys\" include mouse buttons, gamepad axises etc.");
8022+
8023+ const ImGuiKey key = ImGuiKey_MouseLeft; // Note how mouse and gamepad are also included in ImGuiKey: same data type for all.
8024+ const char* key_name = ImGui::GetKeyName(key);
8025+ ImGui::Text("Press '%s'", key_name);
8026+
8027+ ImGui::Text("1st read: (button)");
8028+ ImGui::Button("Click and Hold Me Tight!");
8029+
8030+ // Assume this is another piece of code running later.
8031+ // The *default* value for owner is ImGuiKeyOwner_Any, same as calling the simplified function:
8032+ // IsKeyDown(key) == IsKeyDown(key, ImGuiKeyOwner_Any)
8033+ // IsKeyPressed(key) == IsKeyPressed(key, ImGuiKeyOwner_Any)
8034+ // But notice the "bool repeat = true" parameter in old signature 'IsKeyPressed(key, repeat)'
8035+ // with the new signature becomes 'IsKeyPressed(key, owner, ImGuiInputFlags_Repeat)'
8036+ ImGui::Text("2nd read: (NOT owner-aware)");
8037+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
8038+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key) ? "PRESSED!" : "..");
8039+
8040+ ImGui::Text("3rd read: (owner-aware: ImGuiKeyOwner_NoOwner)");
8041+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, ImGuiKeyOwner_NoOwner) ? "DOWN!" : "..");
8042+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ? "PRESSED!" : "..");
8043+
8044+ ImGuiID another_owner = ImGui::GetID("AnotherItem");
8045+ ImGui::Text("4nd read: (owner-aware: different owner)");
8046+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, another_owner) ? "DOWN!" : "..");
8047+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, another_owner) ? "PRESSED!" : "..");
8048+
8049+ ImGui::TreePop();
8050+ }
8051+
8052+ if (ImGui::TreeNode("2. Calling SetKeyOwner()"))
8053+ {
8054+ const ImGuiKey key = ImGuiKey_A;
8055+ const char* key_name = ImGui::GetKeyName(key);
8056+ ImGui::Text("Press '%s'", key_name);
8057+
8058+ ImGui::Text("1st read:");
8059+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
8060+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
8061+ ImGui::Text("...when pressed, call SetKeyOwner() with an owner ID.");
8062+ ImGuiID owner_1 = ImGui::GetID("MyItemID");
8063+ if (ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, owner_1))
8064+ ImGui::SetKeyOwner(key, owner_1);
8065+
8066+ // Assume this is another piece of code running later.
8067+ // (same comments as in section 1)
8068+ ImGui::Text("2nd read: (NOT owner-aware)");
8069+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
8070+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key) ? "PRESSED!" : "..");
8071+
8072+ ImGui::Text("3rd read: (owner-aware: ImGuiKeyOwner_NoOwner)");
8073+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, ImGuiKeyOwner_NoOwner) ? "DOWN!" : "..");
8074+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ? "PRESSED!" : "..");
80058075
8076+ ImGuiID another_owner = ImGui::GetID("AnotherItem");
8077+ ImGui::Text("4th read: (owner-aware: different owner)");
8078+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, another_owner) ? "DOWN!" : "..");
8079+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, another_owner) ? "PRESSED!" : "..");
8080+
8081+ ImGui::TreePop();
8082+ }
8083+
8084+ // Demonstrate using SetKeyOwner() with ImGuiInputFlags_LockThisFrame / ImGuiInputFlags_LockUntilRelease flags.
8085+ // - Using an owner id solves all/most cases as long as everyone is "owner-id-aware",
8086+ // meaning they call the long form of IsKeyXXX function. This is the preferred way to do things.
8087+ // - Using ImGuiInputFlags_LockXXXX flags is a way to prevent code that is NOT owner-id-aware from accessing the key.
8088+ // Think of it as "eating" a key completely: only same owner ID can access the key/button.
8089+ if (ImGui::TreeNode("3. Calling SetKeyOwner() with ImGuiInputFlags_LockXXX flags for non-owner-aware code"))
8090+ {
8091+ const ImGuiKey key = ImGuiKey_B;
8092+ const char* key_name = ImGui::GetKeyName(key);
8093+ ImGui::Text("Press '%s'", key_name);
8094+ static bool lock_this_frame = false;
8095+ static bool lock_until_release = false;
8096+
8097+ ImGui::Text("1st read:");
8098+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
8099+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
8100+ ImGui::Text("...when pressed, call SetKeyOwner() with:");
8101+ ImGui::Checkbox("ImGuiInputFlags_LockThisFrame", &lock_this_frame);
8102+ ImGui::Checkbox("ImGuiInputFlags_LockUntilRelease", &lock_until_release);
8103+ if (ImGui::IsKeyPressed(key, false) && (lock_this_frame || lock_until_release))
8104+ ImGui::SetKeyOwner(key, 0, (lock_this_frame ? ImGuiInputFlags_LockThisFrame : 0) | (lock_until_release ? ImGuiInputFlags_LockUntilRelease : 0));
8105+
8106+ // Assume this is another piece of code running later. The calls are not owner-aware,
8107+ // due to the lock they won't be able to see the key.
8108+ ImGui::Text("2nd read: (NOT owner-aware)");
8109+ ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
8110+ ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
8111+ ImGui::TreePop();
8112+ }
80068113 ImGui::TreePop();
80078114 }
80088115
0 commit comments