diff --git a/imgui.cpp b/imgui.cpp index 6a466f5..7c76018 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2837,6 +2837,11 @@ IM_ASSERT(g.NavActivateDownId == g.NavActivateId); g.NavMoveRequest = false; + // Process explicit activation request + if (g.NavNextActivateId != 0) + g.NavActivateId = g.NavActivateDownId = g.NavInputId = g.NavNextActivateId; + g.NavNextActivateId = 0; + // Initiate directional inputs request const int allowed_dir_flags = (g.ActiveId == 0) ? ~0 : g.ActiveIdAllowNavDirFlags; if (g.NavMoveRequestForwardStep == 0) @@ -6379,6 +6384,18 @@ SetScrollFromPosY(target_y, center_y_ratio); } +void ImGui::ActivateItem(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; +} + +ImGuiID ImGui::GetItemID() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DC.LastItemId; +} + void ImGui::SetKeyboardFocusHere(int offset) { IM_ASSERT(offset >= -1); // -1 is allowed but not below diff --git a/imgui.cpp b/imgui.cpp index 6a466f5..7c76018 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2837,6 +2837,11 @@ IM_ASSERT(g.NavActivateDownId == g.NavActivateId); g.NavMoveRequest = false; + // Process explicit activation request + if (g.NavNextActivateId != 0) + g.NavActivateId = g.NavActivateDownId = g.NavInputId = g.NavNextActivateId; + g.NavNextActivateId = 0; + // Initiate directional inputs request const int allowed_dir_flags = (g.ActiveId == 0) ? ~0 : g.ActiveIdAllowNavDirFlags; if (g.NavMoveRequestForwardStep == 0) @@ -6379,6 +6384,18 @@ SetScrollFromPosY(target_y, center_y_ratio); } +void ImGui::ActivateItem(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; +} + +ImGuiID ImGui::GetItemID() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DC.LastItemId; +} + void ImGui::SetKeyboardFocusHere(int offset) { IM_ASSERT(offset >= -1); // -1 is allowed but not below diff --git a/imgui.h b/imgui.h index 8e47249..c360175 100644 --- a/imgui.h +++ b/imgui.h @@ -177,7 +177,6 @@ IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); @@ -416,6 +415,11 @@ // Styles IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + // Focus, Activation + IMGUI_API void ActivateItem(ImGuiID id); // remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. + IMGUI_API ImGuiID GetItemID(); // get id of previous item, generally ~GetID(label) + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. + // Utilities IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? or we are currently using Nav and the item is focused. IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this diff --git a/imgui.cpp b/imgui.cpp index 6a466f5..7c76018 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2837,6 +2837,11 @@ IM_ASSERT(g.NavActivateDownId == g.NavActivateId); g.NavMoveRequest = false; + // Process explicit activation request + if (g.NavNextActivateId != 0) + g.NavActivateId = g.NavActivateDownId = g.NavInputId = g.NavNextActivateId; + g.NavNextActivateId = 0; + // Initiate directional inputs request const int allowed_dir_flags = (g.ActiveId == 0) ? ~0 : g.ActiveIdAllowNavDirFlags; if (g.NavMoveRequestForwardStep == 0) @@ -6379,6 +6384,18 @@ SetScrollFromPosY(target_y, center_y_ratio); } +void ImGui::ActivateItem(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; +} + +ImGuiID ImGui::GetItemID() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DC.LastItemId; +} + void ImGui::SetKeyboardFocusHere(int offset) { IM_ASSERT(offset >= -1); // -1 is allowed but not below diff --git a/imgui.h b/imgui.h index 8e47249..c360175 100644 --- a/imgui.h +++ b/imgui.h @@ -177,7 +177,6 @@ IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); @@ -416,6 +415,11 @@ // Styles IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + // Focus, Activation + IMGUI_API void ActivateItem(ImGuiID id); // remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. + IMGUI_API ImGuiID GetItemID(); // get id of previous item, generally ~GetID(label) + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. + // Utilities IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? or we are currently using Nav and the item is focused. IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 22adf89..c058fa1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1754,6 +1754,11 @@ if (ImGui::IsItemActive()) has_focus = 3; ImGui::PopAllowKeyboardFocus(); + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item static float f3[3] = { 0.0f, 0.0f, 0.0f }; int focus_ahead = -1; @@ -1763,14 +1768,26 @@ if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); - if (has_focus) - ImGui::Text("Item with focus: %d", has_focus); - else - ImGui::Text("Item with focus: "); - ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); ImGui::TreePop(); } +#if 0 + if (ImGui::TreeNode("Remote Activation")) + { + static char label[256]; + ImGui::InputText("Label", label, IM_ARRAYSIZE(label)); + ImGui::PopID(); // We don't yet have an easy way compute ID at other levels of the ID stack so we pop it manually for now (e.g. we'd like something like GetID("../label")) + ImGuiID id = ImGui::GetID(label); + ImGui::PushID("Remote Activation"); + if (ImGui::SmallButton("Activate")) + ImGui::ActivateItem(id); + ImGui::SameLine(); + ImGui::Text("ID = 0x%08X", id); + ImGui::TreePop(); + } +#endif + if (ImGui::TreeNode("Dragging")) { ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); diff --git a/imgui.cpp b/imgui.cpp index 6a466f5..7c76018 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2837,6 +2837,11 @@ IM_ASSERT(g.NavActivateDownId == g.NavActivateId); g.NavMoveRequest = false; + // Process explicit activation request + if (g.NavNextActivateId != 0) + g.NavActivateId = g.NavActivateDownId = g.NavInputId = g.NavNextActivateId; + g.NavNextActivateId = 0; + // Initiate directional inputs request const int allowed_dir_flags = (g.ActiveId == 0) ? ~0 : g.ActiveIdAllowNavDirFlags; if (g.NavMoveRequestForwardStep == 0) @@ -6379,6 +6384,18 @@ SetScrollFromPosY(target_y, center_y_ratio); } +void ImGui::ActivateItem(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; +} + +ImGuiID ImGui::GetItemID() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow->DC.LastItemId; +} + void ImGui::SetKeyboardFocusHere(int offset) { IM_ASSERT(offset >= -1); // -1 is allowed but not below diff --git a/imgui.h b/imgui.h index 8e47249..c360175 100644 --- a/imgui.h +++ b/imgui.h @@ -177,7 +177,6 @@ IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) IMGUI_API ImGuiStorage* GetStateStorage(); @@ -416,6 +415,11 @@ // Styles IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); + // Focus, Activation + IMGUI_API void ActivateItem(ImGuiID id); // remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. + IMGUI_API ImGuiID GetItemID(); // get id of previous item, generally ~GetID(label) + IMGUI_API void SetKeyboardFocusHere(int offset = 0); // FIXME-NAVIGATION // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. + // Utilities IMGUI_API bool IsItemHovered(); // is the last item hovered by mouse (and usable)? or we are currently using Nav and the item is focused. IMGUI_API bool IsItemRectHovered(); // is the last item hovered by mouse? even if another item is active or window is blocked by popup while we are hovering this diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 22adf89..c058fa1 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1754,6 +1754,11 @@ if (ImGui::IsItemActive()) has_focus = 3; ImGui::PopAllowKeyboardFocus(); + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); + // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item static float f3[3] = { 0.0f, 0.0f, 0.0f }; int focus_ahead = -1; @@ -1763,14 +1768,26 @@ if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); - if (has_focus) - ImGui::Text("Item with focus: %d", has_focus); - else - ImGui::Text("Item with focus: "); - ImGui::TextWrapped("Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); ImGui::TreePop(); } +#if 0 + if (ImGui::TreeNode("Remote Activation")) + { + static char label[256]; + ImGui::InputText("Label", label, IM_ARRAYSIZE(label)); + ImGui::PopID(); // We don't yet have an easy way compute ID at other levels of the ID stack so we pop it manually for now (e.g. we'd like something like GetID("../label")) + ImGuiID id = ImGui::GetID(label); + ImGui::PushID("Remote Activation"); + if (ImGui::SmallButton("Activate")) + ImGui::ActivateItem(id); + ImGui::SameLine(); + ImGui::Text("ID = 0x%08X", id); + ImGui::TreePop(); + } +#endif + if (ImGui::TreeNode("Dragging")) { ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); diff --git a/imgui_internal.h b/imgui_internal.h index 318520d..e9660a2 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -469,6 +469,7 @@ ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_PadInput) ? NavId : 0, etc. ImGuiID NavJustTabbedId; // Just tabbed to this id. ImGuiID NavJustNavigatedId; // Just navigated to this id (result of a successfully MoveRequest) + ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring. ImGuiWindow* NavWindowingTarget; float NavWindowingDisplayAlpha; @@ -584,7 +585,7 @@ NavWindow = NULL; NavId = NavActivateId = NavActivateDownId = NavInputId = 0; - NavJustTabbedId = NavJustNavigatedId = 0; + NavJustTabbedId = NavJustNavigatedId = NavNextActivateId = 0; NavScoringRectScreen = ImRect(); NavWindowingTarget = NULL; NavWindowingDisplayAlpha = 0.0f;