소스 검색

Demo: added SetKeyOwner(), ImGuiInputFlags_LockThisFrame, ImGuiInputFlags_LockUntilRelease demo.

(relate to issues: 456, 2637, 2620, 2891, 3370, 3724, 4828, 5108, 5242, 5641)
ocornut 3 년 전
부모
커밋
8fb38b7a6e
1개의 변경된 파일107개의 추가작업 그리고 0개의 파일을 삭제
  1. 107 0
      imgui_demo.cpp

+ 107 - 0
imgui_demo.cpp

@@ -7747,6 +7747,8 @@ static void DemoWindowColumns()
 // [SECTION] DemoWindowInputs()
 //-----------------------------------------------------------------------------
 
+#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).
+
 static void DemoWindowInputs()
 {
     IMGUI_DEMO_MARKER("Inputs & Focus");
@@ -7928,7 +7930,112 @@ static void DemoWindowInputs()
             }
             ImGui::EndChild();
             ImGui::PopStyleColor();
+            ImGui::TreePop();
+        }
+
+        // Ownership, Routings
+        IMGUI_DEMO_MARKER("Inputs & Focus/Key Ownership");
+        if (ImGui::TreeNode("Key Ownership"))
+        {
+            HelpMarker("See 'Tools->Metrics/Debugger->Inputs' to visualize ownership/routing data.");
+
+            // Demonstrate basic key ownership system
+            // Standard widgets all claim and test for key ownership
+            // (note that the ActiveId and HoveredId systems also generally prevents multiple items from interacting, but at a different level)
+            if (ImGui::TreeNode("1. Standard widgets taking input ownership"))
+            {
+                HelpMarker("Standard widgets claim and test for key ownership.\n\n\"Keys\" include mouse buttons, gamepad axises etc.");
+
+                const ImGuiKey key = ImGuiKey_MouseLeft; // Note how mouse and gamepad are also included in ImGuiKey: same data type for all.
+                const char* key_name = ImGui::GetKeyName(key);
+                ImGui::Text("Press '%s'", key_name);
+
+                ImGui::Text("1st read: (button)");
+                ImGui::Button("Click and Hold Me Tight!");
+
+                // Assume this is another piece of code running later.
+                // The *default* value for owner is ImGuiKeyOwner_Any, same as calling the simplified function:
+                //     IsKeyDown(key) == IsKeyDown(key, ImGuiKeyOwner_Any)
+                //     IsKeyPressed(key) == IsKeyPressed(key, ImGuiKeyOwner_Any)
+                // But notice the "bool repeat = true" parameter in old signature 'IsKeyPressed(key, repeat)'
+                // with the new signature becomes 'IsKeyPressed(key, owner, ImGuiInputFlags_Repeat)'
+                ImGui::Text("2nd read: (NOT owner-aware)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key) ? "PRESSED!" : "..");
+
+                ImGui::Text("3rd read: (owner-aware: ImGuiKeyOwner_NoOwner)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, ImGuiKeyOwner_NoOwner) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ? "PRESSED!" : "..");
+
+                ImGuiID another_owner = ImGui::GetID("AnotherItem");
+                ImGui::Text("4nd read: (owner-aware: different owner)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, another_owner) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, another_owner) ? "PRESSED!" : "..");
+
+                ImGui::TreePop();
+            }
+
+            if (ImGui::TreeNode("2. Calling SetKeyOwner()"))
+            {
+                const ImGuiKey key = ImGuiKey_A;
+                const char* key_name = ImGui::GetKeyName(key);
+                ImGui::Text("Press '%s'", key_name);
+
+                ImGui::Text("1st read:");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
+                ImGui::Text("...when pressed, call SetKeyOwner() with an owner ID.");
+                ImGuiID owner_1 = ImGui::GetID("MyItemID");
+                if (ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, owner_1))
+                    ImGui::SetKeyOwner(key, owner_1);
+
+                // Assume this is another piece of code running later.
+                // (same comments as in section 1)
+                ImGui::Text("2nd read: (NOT owner-aware)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key) ? "PRESSED!" : "..");
+
+                ImGui::Text("3rd read: (owner-aware: ImGuiKeyOwner_NoOwner)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, ImGuiKeyOwner_NoOwner) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) ? "PRESSED!" : "..");
 
+                ImGuiID another_owner = ImGui::GetID("AnotherItem");
+                ImGui::Text("4th read: (owner-aware: different owner)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key, another_owner) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, ImGuiInputFlags_Repeat, another_owner) ? "PRESSED!" : "..");
+
+                ImGui::TreePop();
+            }
+
+            // Demonstrate using SetKeyOwner() with ImGuiInputFlags_LockThisFrame / ImGuiInputFlags_LockUntilRelease flags.
+            // - Using an owner id solves all/most cases as long as everyone is "owner-id-aware",
+            //   meaning they call the long form of IsKeyXXX function. This is the preferred way to do things.
+            // - Using ImGuiInputFlags_LockXXXX flags is a way to prevent code that is NOT owner-id-aware from accessing the key.
+            //   Think of it as "eating" a key completely: only same owner ID can access the key/button.
+            if (ImGui::TreeNode("3. Calling SetKeyOwner() with ImGuiInputFlags_LockXXX flags for non-owner-aware code"))
+            {
+                const ImGuiKey key = ImGuiKey_B;
+                const char* key_name = ImGui::GetKeyName(key);
+                ImGui::Text("Press '%s'", key_name);
+                static bool lock_this_frame = false;
+                static bool lock_until_release = false;
+
+                ImGui::Text("1st read:");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
+                ImGui::Text("...when pressed, call SetKeyOwner() with:");
+                ImGui::Checkbox("ImGuiInputFlags_LockThisFrame", &lock_this_frame);
+                ImGui::Checkbox("ImGuiInputFlags_LockUntilRelease", &lock_until_release);
+                if (ImGui::IsKeyPressed(key, false) && (lock_this_frame || lock_until_release))
+                    ImGui::SetKeyOwner(key, 0, (lock_this_frame ? ImGuiInputFlags_LockThisFrame : 0) | (lock_until_release ? ImGuiInputFlags_LockUntilRelease : 0));
+
+                // Assume this is another piece of code running later. The calls are not owner-aware,
+                // due to the lock they won't be able to see the key.
+                ImGui::Text("2nd read: (NOT owner-aware)");
+                ImGui::Text("- IsKeyDown(%s): %s", key_name, ImGui::IsKeyDown(key) ? "DOWN!" : "..");
+                ImGui::Text("- IsKeyPressed(%s): %s", key_name, ImGui::IsKeyPressed(key, false) ? "PRESSED!" : "..");
+                ImGui::TreePop();
+            }
             ImGui::TreePop();
         }