mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-26 05:27:01 +00:00
Internals: Added FocusItem(). Made activation explicit/opt-in via ImGuiNavMoveFlags_Activate. Rename ActivateItem() to ActivateItemByID().
This commit is contained in:
parent
61ebb37843
commit
31f11cf304
59
imgui.cpp
59
imgui.cpp
@ -7530,13 +7530,6 @@ void ImGui::SetWindowFontScale(float scale)
|
|||||||
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
|
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::ActivateItem(ImGuiID id)
|
|
||||||
{
|
|
||||||
ImGuiContext& g = *GImGui;
|
|
||||||
g.NavNextActivateId = id;
|
|
||||||
g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui::PushFocusScope(ImGuiID id)
|
void ImGui::PushFocusScope(ImGuiID id)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
@ -7552,13 +7545,40 @@ void ImGui::PopFocusScope()
|
|||||||
g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back() : 0;
|
g.CurrentFocusScopeId = g.FocusScopeStack.Size ? g.FocusScopeStack.back() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Focus = move navigation cursor, set scrolling, set focus window.
|
||||||
|
void ImGui::FocusItem()
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
IMGUI_DEBUG_LOG_FOCUS("FocusItem(0x%08x) in window \"%s\"\n", g.LastItemData.ID, window->Name);
|
||||||
|
if (g.DragDropActive || g.MovingWindow != NULL) // FIXME: Opt-in flags for this?
|
||||||
|
{
|
||||||
|
IMGUI_DEBUG_LOG_FOCUS("FocusItem() ignored while DragDropActive!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi; // No activation/selection
|
||||||
|
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
||||||
|
SetNavWindow(window);
|
||||||
|
NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags);
|
||||||
|
NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui::ActivateItemByID(ImGuiID id)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
g.NavNextActivateId = id;
|
||||||
|
g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
||||||
|
}
|
||||||
|
|
||||||
// Note: this will likely be called ActivateItem() once we rework our Focus/Activation system!
|
// Note: this will likely be called ActivateItem() once we rework our Focus/Activation system!
|
||||||
|
// But ActivateItem() should function without altering scroll/focus?
|
||||||
void ImGui::SetKeyboardFocusHere(int offset)
|
void ImGui::SetKeyboardFocusHere(int offset)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
IM_ASSERT(offset >= -1); // -1 is allowed but not below
|
IM_ASSERT(offset >= -1); // -1 is allowed but not below
|
||||||
IMGUI_DEBUG_LOG_ACTIVEID("SetKeyboardFocusHere(%d) in window \"%s\"\n", offset, window->Name);
|
IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere(%d) in window \"%s\"\n", offset, window->Name);
|
||||||
|
|
||||||
// It makes sense in the vast majority of cases to never interrupt a drag and drop.
|
// It makes sense in the vast majority of cases to never interrupt a drag and drop.
|
||||||
// When we refactor this function into ActivateItem() we may want to make this an option.
|
// When we refactor this function into ActivateItem() we may want to make this an option.
|
||||||
@ -7566,14 +7586,15 @@ void ImGui::SetKeyboardFocusHere(int offset)
|
|||||||
// is also automatically dropped in the event g.ActiveId is stolen.
|
// is also automatically dropped in the event g.ActiveId is stolen.
|
||||||
if (g.DragDropActive || g.MovingWindow != NULL)
|
if (g.DragDropActive || g.MovingWindow != NULL)
|
||||||
{
|
{
|
||||||
IMGUI_DEBUG_LOG_ACTIVEID("SetKeyboardFocusHere() ignored while DragDropActive!\n");
|
IMGUI_DEBUG_LOG_FOCUS("SetKeyboardFocusHere() ignored while DragDropActive!\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetNavWindow(window);
|
SetNavWindow(window);
|
||||||
|
|
||||||
|
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi;
|
||||||
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
||||||
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
{
|
{
|
||||||
NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal);
|
NavMoveRequestResolveWithLastItem(&g.NavMoveResultLocal);
|
||||||
@ -11555,9 +11576,10 @@ void ImGui::NavUpdateCreateTabbingRequest()
|
|||||||
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1;
|
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1;
|
||||||
else
|
else
|
||||||
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1;
|
g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1;
|
||||||
|
ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate;
|
||||||
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
|
||||||
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
|
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
|
||||||
NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
NavMoveRequestSubmit(ImGuiDir_None, clip_dir, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
|
||||||
g.NavTabbingCounter = -1;
|
g.NavTabbingCounter = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11623,7 +11645,7 @@ void ImGui::NavMoveRequestApplyResult()
|
|||||||
}
|
}
|
||||||
if (g.ActiveId != result->ID)
|
if (g.ActiveId != result->ID)
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
if (g.NavId != result->ID)
|
if (g.NavId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_Activate) != 0)
|
||||||
{
|
{
|
||||||
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
|
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
|
||||||
g.NavJustMovedToId = result->ID;
|
g.NavJustMovedToId = result->ID;
|
||||||
@ -11644,19 +11666,18 @@ void ImGui::NavMoveRequestApplyResult()
|
|||||||
g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer] = preferred_scoring_pos_rel;
|
g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer] = preferred_scoring_pos_rel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tabbing: Activates Inputable or Focus non-Inputable
|
// Tabbing: Activates Inputable, otherwise only Focus
|
||||||
if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable))
|
if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0)
|
||||||
{
|
g.NavMoveFlags &= ~ImGuiNavMoveFlags_Activate;
|
||||||
g.NavNextActivateId = result->ID;
|
|
||||||
g.NavNextActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
|
|
||||||
g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate
|
// Activate
|
||||||
if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate)
|
if (g.NavMoveFlags & ImGuiNavMoveFlags_Activate)
|
||||||
{
|
{
|
||||||
g.NavNextActivateId = result->ID;
|
g.NavNextActivateId = result->ID;
|
||||||
g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
g.NavNextActivateFlags = ImGuiActivateFlags_None;
|
||||||
|
g.NavMoveFlags |= ImGuiNavMoveFlags_DontSetNavHighlight;
|
||||||
|
if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing)
|
||||||
|
g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable nav highlight
|
// Enable nav highlight
|
||||||
|
@ -1479,9 +1479,9 @@ enum ImGuiNavMoveFlags_
|
|||||||
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
|
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
|
||||||
ImGuiNavMoveFlags_Forwarded = 1 << 7,
|
ImGuiNavMoveFlags_Forwarded = 1 << 7,
|
||||||
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
|
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
|
||||||
ImGuiNavMoveFlags_FocusApi = 1 << 9,
|
ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details)
|
||||||
ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
|
ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
|
||||||
ImGuiNavMoveFlags_Activate = 1 << 11,
|
ImGuiNavMoveFlags_Activate = 1 << 11, // Activate/select target item.
|
||||||
ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 12, // Do not alter the visible state of keyboard vs mouse nav highlight
|
ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 12, // Do not alter the visible state of keyboard vs mouse nav highlight
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2912,10 +2912,15 @@ namespace ImGui
|
|||||||
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
|
||||||
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
|
IMGUI_API void NavClearPreferredPosForAxis(ImGuiAxis axis);
|
||||||
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
|
IMGUI_API void NavUpdateCurrentWindowIsScrollPushableX();
|
||||||
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 void SetNavWindow(ImGuiWindow* window);
|
IMGUI_API void SetNavWindow(ImGuiWindow* window);
|
||||||
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
|
||||||
|
|
||||||
|
// Focus/Activation
|
||||||
|
// This should be part of a larger set of API: FocusItem(offset = -1), FocusItemByID(id), ActivateItem(offset = -1), ActivateItemByID(id) etc. which are
|
||||||
|
// much harder to design and implement than expected. I have a couple of private branches on this matter but it's not simple. For now implementing the easy ones.
|
||||||
|
IMGUI_API void FocusItem(); // Focus last item (no selection/activation).
|
||||||
|
IMGUI_API void ActivateItemByID(ImGuiID id); // Activate an item by ID (button, checkbox, tree node etc.). Activation is queued and processed on the next frame when the item is encountered again.
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
|
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
|
||||||
inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; }
|
inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; }
|
||||||
|
Loading…
Reference in New Issue
Block a user