Nav: clarified/renamed NavInputId as NavAcivateInputId, added flags shared by both.

(this commit should have no visible side effect but is designed to introduce the followup commit refactoring SetKeyboardFocusHere into using a Nav request)
This commit is contained in:
ocornut 2021-09-06 19:15:20 +02:00
parent 755bf985d2
commit d9b427cce0
4 changed files with 50 additions and 16 deletions

View File

@ -3106,7 +3106,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
if (id) if (id)
{ {
g.ActiveIdIsAlive = id; g.ActiveIdIsAlive = id;
g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse;
} }
// Clear declaration of inputs claimed by the widget // Clear declaration of inputs claimed by the widget
@ -7063,6 +7063,7 @@ void ImGui::ActivateItem(ImGuiID id)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
g.NavNextActivateId = id; g.NavNextActivateId = id;
g.NavNextActivateFlags = ImGuiActivateFlags_None;
} }
void ImGui::PushFocusScope(ImGuiID id) void ImGui::PushFocusScope(ImGuiID id)
@ -9232,19 +9233,28 @@ static void ImGui::NavUpdate()
NavUpdateCancelRequest(); NavUpdateCancelRequest();
// Process manual activation request // Process manual activation request
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0; g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavActivateInputId = 0;
g.NavActivateFlags = ImGuiActivateFlags_None;
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
{ {
bool activate_down = IsNavInputDown(ImGuiNavInput_Activate); bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
bool input_down = IsNavInputDown(ImGuiNavInput_Input);
bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed); bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed);
bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed);
if (g.ActiveId == 0 && activate_pressed) if (g.ActiveId == 0 && activate_pressed)
{
g.NavActivateId = g.NavId; g.NavActivateId = g.NavId;
g.NavActivateFlags = ImGuiActivateFlags_PreferTweak;
}
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && input_pressed)
{
g.NavActivateInputId = g.NavId;
g.NavActivateFlags = ImGuiActivateFlags_PreferInput;
}
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down) if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down)
g.NavActivateDownId = g.NavId; g.NavActivateDownId = g.NavId;
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed) if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed)
g.NavActivatePressedId = g.NavId; g.NavActivatePressedId = g.NavId;
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed))
g.NavInputId = g.NavId;
} }
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
g.NavDisableHighlight = true; g.NavDisableHighlight = true;
@ -9254,7 +9264,13 @@ static void ImGui::NavUpdate()
// Process programmatic activation request // Process programmatic activation request
// FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others) // FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
if (g.NavNextActivateId != 0) if (g.NavNextActivateId != 0)
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; {
if (g.NavNextActivateFlags & ImGuiActivateFlags_PreferInput)
g.NavActivateInputId = g.NavNextActivateId;
else
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavNextActivateId;
g.NavActivateFlags = g.NavNextActivateFlags;
}
g.NavNextActivateId = 0; g.NavNextActivateId = 0;
// Process move requests // Process move requests
@ -11393,7 +11409,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer);
Text("NavInputSource: %s", input_source_names[g.NavInputSource]); Text("NavInputSource: %s", input_source_names[g.NavInputSource]);
Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId);
Text("NavActivateFlags: %04X", g.NavActivateFlags);
Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId); Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId);
Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL"); Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL");

View File

@ -143,6 +143,7 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
@ -1148,6 +1149,14 @@ struct ImGuiPtrOrIndex
// [SECTION] Navigation support // [SECTION] Navigation support
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum ImGuiActivateFlags_
{
ImGuiActivateFlags_None = 0,
ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available.
ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available.
ImGuiActivateFlags_TryToPreserveState = 1 << 2 // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
};
enum ImGuiNavHighlightFlags_ enum ImGuiNavHighlightFlags_
{ {
ImGuiNavHighlightFlags_None = 0, ImGuiNavHighlightFlags_None = 0,
@ -1498,12 +1507,14 @@ struct ImGuiContext
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem() ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem()
ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0
ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0
ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0 ImGuiID NavActivateInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0.
ImGuiActivateFlags NavActivateFlags;
ImGuiID NavJustTabbedId; // Just tabbed to this id. ImGuiID NavJustTabbedId; // Just tabbed to this id.
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
ImGuiKeyModFlags NavJustMovedToKeyMods; ImGuiKeyModFlags NavJustMovedToKeyMods;
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
ImGuiActivateFlags NavNextActivateFlags;
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later.
int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing
@ -1708,8 +1719,9 @@ struct ImGuiContext
CurrentItemFlags = ImGuiItemFlags_None; CurrentItemFlags = ImGuiItemFlags_None;
NavWindow = NULL; NavWindow = NULL;
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0; NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0;
NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
NavJustMovedToKeyMods = ImGuiKeyModFlags_None; NavJustMovedToKeyMods = ImGuiKeyModFlags_None;
NavInputSource = ImGuiInputSource_None; NavInputSource = ImGuiInputSource_None;
NavLayer = ImGuiNavLayer_Main; NavLayer = ImGuiNavLayer_Main;

View File

@ -1479,6 +1479,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
// Ensure frozen columns are ordered in their section. We still allow multiple frozen columns to be reordered. // Ensure frozen columns are ordered in their section. We still allow multiple frozen columns to be reordered.
// FIXME-TABLE: This work for preserving 2143 into 21|43. How about 4321 turning into 21|43? (preserve relative order in each section)
for (int column_n = 0; column_n < table->FreezeColumnsRequest; column_n++) for (int column_n = 0; column_n < table->FreezeColumnsRequest; column_n++)
{ {
int order_n = table->DisplayOrderToIndex[column_n]; int order_n = table->DisplayOrderToIndex[column_n];

View File

@ -273,6 +273,7 @@ void ImGui::TextV(const char* fmt, va_list args)
if (window->SkipItems) if (window->SkipItems)
return; return;
// FIXME-OPT: Handle the %s shortcut?
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText); TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
@ -2405,20 +2406,23 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0; const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]); const bool clicked = (hovered && g.IO.MouseClicked[0]);
const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]); const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavInputId == id) if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{ {
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
FocusWindow(window); FocusWindow(window);
g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavInputId == id)) if (temp_input_allowed)
temp_input_is_active = true; if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id)
temp_input_is_active = true;
} }
// Experimental: simple click (without moving) turns Drag into an InputText // Experimental: simple click (without moving) turns Drag into an InputText
if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active) if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active)
if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR)) if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
{ {
g.NavInputId = id; g.NavActivateId = g.NavActivateInputId = id;
g.NavActivateFlags = ImGuiActivateFlags_PreferInput;
temp_input_is_active = true; temp_input_is_active = true;
} }
} }
@ -3019,13 +3023,13 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
{ {
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0; const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]); const bool clicked = (hovered && g.IO.MouseClicked[0]);
if (focus_requested || clicked || g.NavActivateId == id || g.NavInputId == id) if (focus_requested || clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{ {
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
FocusWindow(window); FocusWindow(window);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavInputId == id)) if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id))
temp_input_is_active = true; temp_input_is_active = true;
} }
} }
@ -3177,7 +3181,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
format = PatchFormatStringFloatToInt(format); format = PatchFormatStringFloatToInt(format);
const bool hovered = ItemHoverable(frame_bb, id); const bool hovered = ItemHoverable(frame_bb, id);
if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id) if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id)
{ {
SetActiveID(id, window); SetActiveID(id, window);
SetFocusID(id, window); SetFocusID(id, window);
@ -4019,7 +4023,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool focus_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0; const bool focus_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
const bool user_clicked = hovered && io.MouseClicked[0]; const bool user_clicked = hovered && io.MouseClicked[0];
const bool user_nav_input_start = (g.ActiveId != id) && ((g.NavInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard)); const bool user_nav_input_start = (g.ActiveId != id) && ((g.NavActivateInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard));
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y); const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);