mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-06 04:58:47 +02:00
Removed io.NavInputs[] and ImGuiNavInput enum. Kept inline redirection code. (#4921, #4858, #787, #1599, #323)
This commit is contained in:
269
imgui.cpp
269
imgui.cpp
@ -132,7 +132,7 @@ CODE
|
||||
- ESCAPE to revert text to its original value.
|
||||
- Controls are automatically adjusted for OSX to match standard OSX text editing operations.
|
||||
- General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard.
|
||||
- General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://dearimgui.org/controls_sheets
|
||||
- General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. Download controller mapping PNG/PSD at http://dearimgui.org/controls_sheets
|
||||
|
||||
|
||||
PROGRAMMER GUIDE
|
||||
@ -345,12 +345,10 @@ CODE
|
||||
USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
|
||||
------------------------------------------
|
||||
- The gamepad/keyboard navigation is fairly functional and keeps being improved.
|
||||
- Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PS4, Switch, XB1) without a mouse!
|
||||
- You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787
|
||||
- Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PlayStation, Switch, Xbox) without a mouse!
|
||||
- The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable.
|
||||
- Keyboard:
|
||||
- Application: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable.
|
||||
- Internally: NewFrame() will automatically fill io.NavInputs[] based on backend's io.AddKeyEvent() calls.
|
||||
- When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard),
|
||||
the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from:
|
||||
- io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set.
|
||||
@ -362,8 +360,7 @@ CODE
|
||||
- Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + call io.AddKeyEvent/AddKeyAnalogEvent() with ImGuiKey_Gamepad_XXX keys.
|
||||
For analog values (0.0f to 1.0f), backend is responsible to handling a dead-zone and rescaling inputs accordingly.
|
||||
Backend code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.).
|
||||
- Internally: NewFrame() will automatically fill io.NavInputs[] based on backend's io.AddKeyEvent() + io.AddKeyAnalogEvent() calls.
|
||||
- BEFORE 1.87, BACKENDS USED TO WRITE DIRECTLY TO io.NavInputs[]. This is going to be obsoleted in the future. Please call io functions instead!
|
||||
- BEFORE 1.87, BACKENDS USED TO WRITE TO io.NavInputs[]. This is now obsolete. Please call io functions instead!
|
||||
- You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://dearimgui.org/controls_sheets
|
||||
- If you need to share inputs between your game and the Dear ImGui interface, the easiest approach is to go all-or-nothing,
|
||||
with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved.
|
||||
@ -387,6 +384,12 @@ CODE
|
||||
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||||
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||||
|
||||
- 2022/07/08 (1.88) - inputs: removed io.NavInputs[] and ImGuiNavInput enum (following 1.87 changes).
|
||||
- Official backends from 1.87+ -> no issue.
|
||||
- Official backends from 1.60 to 1.86 -> will build and convert gamepad inputs, unless IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Need updating!
|
||||
- Custom backends not writing to io.NavInputs[] -> no issue.
|
||||
- Custom backends writing to io.NavInputs[] -> will build and convert gamepad inputs, unless IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Need fixing!
|
||||
- TL;DR: Backends should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values instead of filling io.NavInput[].
|
||||
- 2022/06/15 (1.88) - renamed IMGUI_DISABLE_METRICS_WINDOW to IMGUI_DISABLE_DEBUG_TOOLS for correctness. kept support for old define (will obsolete).
|
||||
- 2022/05/03 (1.88) - backends: osx: removed ImGui_ImplOSX_HandleEvent() from backend API in favor of backend automatically handling event capture. All ImGui_ImplOSX_HandleEvent() calls should be removed as they are now unnecessary.
|
||||
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
|
||||
@ -1171,7 +1174,6 @@ ImGuiIO::ImGuiIO()
|
||||
MouseDragThreshold = 6.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
|
||||
for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f;
|
||||
AppAcceptingEvents = true;
|
||||
BackendUsingLegacyKeyArrays = (ImS8)-1;
|
||||
BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong
|
||||
@ -1262,8 +1264,6 @@ void ImGuiIO::ClearInputKeys()
|
||||
}
|
||||
KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
|
||||
KeyMods = ImGuiModFlags_None;
|
||||
for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
|
||||
NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
|
||||
}
|
||||
|
||||
// Queue a new key down/up event.
|
||||
@ -3425,8 +3425,10 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||
// (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet)
|
||||
g.ActiveIdUsingMouseWheel = false;
|
||||
g.ActiveIdUsingNavDirMask = 0x00;
|
||||
g.ActiveIdUsingNavInputMask = 0x00;
|
||||
g.ActiveIdUsingKeyInputMask.ClearAllBits();
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
g.ActiveIdUsingNavInputMask = 0x00;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGui::ClearActiveID()
|
||||
@ -4005,6 +4007,31 @@ static void ImGui::UpdateKeyboardInputs()
|
||||
io.KeysData[ImGuiKey_ModSuper].Down = io.KeySuper;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
||||
if (io.BackendUsingLegacyNavInputArray && nav_gamepad_active)
|
||||
{
|
||||
#define MAP_LEGACY_NAV_INPUT_TO_KEY1(_KEY, _NAV1) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f); io.KeysData[_KEY].AnalogValue = io.NavInputs[_NAV1]; } while (0)
|
||||
#define MAP_LEGACY_NAV_INPUT_TO_KEY2(_KEY, _NAV1, _NAV2) do { io.KeysData[_KEY].Down = (io.NavInputs[_NAV1] > 0.0f) || (io.NavInputs[_NAV2] > 0.0f); io.KeysData[_KEY].AnalogValue = ImMax(io.NavInputs[_NAV1], io.NavInputs[_NAV2]); } while (0)
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, ImGuiNavInput_TweakSlow);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY2(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, ImGuiNavInput_TweakFast);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp);
|
||||
MAP_LEGACY_NAV_INPUT_TO_KEY1(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown);
|
||||
#undef NAV_MAP_KEY
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
|
||||
@ -4384,7 +4411,6 @@ void ImGui::NewFrame()
|
||||
if (g.ActiveId == 0)
|
||||
{
|
||||
g.ActiveIdUsingNavDirMask = 0x00;
|
||||
g.ActiveIdUsingNavInputMask = 0x00;
|
||||
g.ActiveIdUsingKeyInputMask.ClearAllBits();
|
||||
}
|
||||
|
||||
@ -4902,7 +4928,6 @@ void ImGui::EndFrame()
|
||||
// Clear Input data for next frame
|
||||
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
|
||||
g.IO.InputQueueCharacters.resize(0);
|
||||
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
|
||||
|
||||
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
|
||||
}
|
||||
@ -5175,7 +5200,6 @@ void ImGui::SetActiveIdUsingNavAndKeys()
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(g.ActiveId != 0);
|
||||
g.ActiveIdUsingNavDirMask = ~(ImU32)0;
|
||||
g.ActiveIdUsingNavInputMask = ~(ImU32)0;
|
||||
g.ActiveIdUsingKeyInputMask.SetAllBits();
|
||||
NavMoveRequestCancel();
|
||||
}
|
||||
@ -5719,9 +5743,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
|
||||
{
|
||||
ImVec2 nav_resize_dir;
|
||||
if (g.NavInputSource == ImGuiInputSource_Keyboard && g.IO.KeyShift)
|
||||
nav_resize_dir = ImVec2((float)IsKeyDown(ImGuiKey_RightArrow) - (float)IsKeyDown(ImGuiKey_LeftArrow), (float)IsKeyDown(ImGuiKey_DownArrow) - (float)IsKeyDown(ImGuiKey_UpArrow));
|
||||
nav_resize_dir = GetKeyVector2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow);
|
||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||
nav_resize_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiNavReadMode_Down);
|
||||
nav_resize_dir = GetKeyVector2d(ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown);
|
||||
if (nav_resize_dir.x != 0.0f || nav_resize_dir.y != 0.0f)
|
||||
{
|
||||
const float NAV_RESIZE_SPEED = 600.0f;
|
||||
@ -6609,7 +6633,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
/*
|
||||
//if (g.NavWindow == window && g.ActiveId == 0)
|
||||
if (g.ActiveId == window->MoveId)
|
||||
if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C))
|
||||
if (g.IO.KeyCtrl && IsKeyPressed(ImGuiKey_C))
|
||||
LogToClipboard();
|
||||
*/
|
||||
|
||||
@ -7668,6 +7692,19 @@ int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, flo
|
||||
return count;
|
||||
}
|
||||
|
||||
void ImGui::GetTypematicRepeatRate(ImGuiInputReadFlags flags, float* repeat_delay, float* repeat_rate)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
switch (flags & ImGuiInputReadFlags_RepeatRateMask_)
|
||||
{
|
||||
case ImGuiInputReadFlags_RepeatRateNavMove: *repeat_delay = g.IO.KeyRepeatDelay * 0.72f; *repeat_rate = g.IO.KeyRepeatRate * 0.80f; return;
|
||||
case ImGuiInputReadFlags_RepeatRateNavTweak: *repeat_delay = g.IO.KeyRepeatDelay * 0.72f; *repeat_rate = g.IO.KeyRepeatRate * 0.30f; return;
|
||||
case ImGuiInputReadFlags_RepeatRateDefault: default: *repeat_delay = g.IO.KeyRepeatDelay * 1.00f; *repeat_rate = g.IO.KeyRepeatRate * 1.00f; return;
|
||||
}
|
||||
}
|
||||
|
||||
// Return value representing the number of presses in the last time period, for the given repeat rate
|
||||
// (most often returns 0 or 1. The result is generally only >1 when RepeatRate is smaller than DeltaTime, aka large DeltaTime or fast RepeatRate)
|
||||
int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_rate)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -7676,6 +7713,14 @@ int ImGui::GetKeyPressedAmount(ImGuiKey key, float repeat_delay, float repeat_ra
|
||||
return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate);
|
||||
}
|
||||
|
||||
// Return 2D vector representing the combination of four cardinal direction, with analog value support (for e.g. ImGuiKey_GamepadLStick* values).
|
||||
ImVec2 ImGui::GetKeyVector2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down)
|
||||
{
|
||||
return ImVec2(
|
||||
GetKeyData(key_right)->AnalogValue - GetKeyData(key_left)->AnalogValue,
|
||||
GetKeyData(key_down)->AnalogValue - GetKeyData(key_up)->AnalogValue);
|
||||
}
|
||||
|
||||
// Note that Dear ImGui doesn't know the meaning/semantic of ImGuiKey from 0..511: they are legacy native keycodes.
|
||||
// Consider transitioning from 'IsKeyDown(MY_ENGINE_KEY_A)' (<1.87) to IsKeyDown(ImGuiKey_A) (>= 1.87)
|
||||
bool ImGui::IsKeyDown(ImGuiKey key)
|
||||
@ -7688,12 +7733,26 @@ bool ImGui::IsKeyDown(ImGuiKey key)
|
||||
|
||||
bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
return IsKeyPressedEx(key, repeat ? ImGuiInputReadFlags_Repeat : ImGuiInputReadFlags_None);
|
||||
}
|
||||
|
||||
// Important: unlike legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat.
|
||||
// [Internal] 2022/07: Do not call this directly! It is a temporary entry point which we will soon replace with an overload for IsKeyPressed() when we introduce key ownership.
|
||||
bool ImGui::IsKeyPressedEx(ImGuiKey key, ImGuiInputReadFlags flags)
|
||||
{
|
||||
const ImGuiKeyData* key_data = GetKeyData(key);
|
||||
const float t = key_data->DownDuration;
|
||||
if (t < 0.0f)
|
||||
return false;
|
||||
const bool pressed = (t == 0.0f) || (repeat && t > g.IO.KeyRepeatDelay && GetKeyPressedAmount(key, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0);
|
||||
|
||||
bool pressed = (t == 0.0f);
|
||||
if (!pressed && ((flags & ImGuiInputReadFlags_Repeat) != 0))
|
||||
{
|
||||
float repeat_delay, repeat_rate;
|
||||
GetTypematicRepeatRate(flags, &repeat_delay, &repeat_rate);
|
||||
pressed = (t > repeat_delay) && GetKeyPressedAmount(key, repeat_delay, repeat_rate) > 0;
|
||||
}
|
||||
|
||||
if (!pressed)
|
||||
return false;
|
||||
return true;
|
||||
@ -10119,55 +10178,27 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
|
||||
}
|
||||
}
|
||||
|
||||
const char* ImGui::GetNavInputName(ImGuiNavInput n)
|
||||
{
|
||||
static const char* names[] =
|
||||
{
|
||||
"Activate", "Cancel", "Input", "Menu", "DpadLeft", "DpadRight", "DpadUp", "DpadDown", "LStickLeft", "LStickRight", "LStickUp", "LStickDown",
|
||||
"FocusPrev", "FocusNext", "TweakSlow", "TweakFast", "KeyLeft", "KeyRight", "KeyUp", "KeyDown"
|
||||
};
|
||||
IM_ASSERT(IM_ARRAYSIZE(names) == ImGuiNavInput_COUNT);
|
||||
IM_ASSERT(n >= 0 && n < ImGuiNavInput_COUNT);
|
||||
return names[n];
|
||||
}
|
||||
|
||||
float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiNavReadMode mode)
|
||||
float ImGui::GetNavTweakPressedAmount(ImGuiAxis axis)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiIO& io = g.IO;
|
||||
if (mode == ImGuiNavReadMode_Down) // Instant, read analog input (0.0f..1.0f, as provided by user)
|
||||
return io.NavInputs[n];
|
||||
const float t = io.NavInputsDownDuration[n];
|
||||
if (t < 0.0f)
|
||||
return 0.0f;
|
||||
switch (mode)
|
||||
{
|
||||
case ImGuiNavReadMode_Repeat:
|
||||
return (float)CalcTypematicRepeatAmount(t - io.DeltaTime, t, io.KeyRepeatDelay * 0.72f, io.KeyRepeatRate * 0.80f);
|
||||
case ImGuiNavReadMode_RepeatSlow:
|
||||
return (float)CalcTypematicRepeatAmount(t - io.DeltaTime, t, io.KeyRepeatDelay * 1.25f, io.KeyRepeatRate * 2.00f);
|
||||
case ImGuiNavReadMode_RepeatFast:
|
||||
return (float)CalcTypematicRepeatAmount(t - io.DeltaTime, t, io.KeyRepeatDelay * 0.72f, io.KeyRepeatRate * 0.30f);
|
||||
default:
|
||||
IM_ASSERT(0);
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
float repeat_delay, repeat_rate;
|
||||
GetTypematicRepeatRate(ImGuiInputReadFlags_RepeatRateNavTweak, &repeat_delay, &repeat_rate);
|
||||
|
||||
ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiNavReadMode mode, float slow_factor, float fast_factor)
|
||||
{
|
||||
ImVec2 delta(0.0f, 0.0f);
|
||||
if (dir_sources & ImGuiNavDirSourceFlags_Keyboard) // Number of presses during the frame, according to repeat rate
|
||||
delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode) - GetNavInputAmount(ImGuiNavInput_KeyLeft_, mode), GetNavInputAmount(ImGuiNavInput_KeyDown_, mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_, mode));
|
||||
if (dir_sources & ImGuiNavDirSourceFlags_PadDPad)
|
||||
delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode) - GetNavInputAmount(ImGuiNavInput_DpadLeft, mode), GetNavInputAmount(ImGuiNavInput_DpadDown, mode) - GetNavInputAmount(ImGuiNavInput_DpadUp, mode));
|
||||
if (dir_sources & ImGuiNavDirSourceFlags_PadLStick)
|
||||
delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode));
|
||||
if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow))
|
||||
delta *= slow_factor;
|
||||
if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast))
|
||||
delta *= fast_factor;
|
||||
return delta;
|
||||
ImGuiKey key_less, key_more;
|
||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
key_less = (axis == ImGuiAxis_X) ? ImGuiKey_GamepadDpadLeft : ImGuiKey_GamepadDpadUp;
|
||||
key_more = (axis == ImGuiAxis_X) ? ImGuiKey_GamepadDpadRight : ImGuiKey_GamepadDpadDown;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_less = (axis == ImGuiAxis_X) ? ImGuiKey_LeftArrow : ImGuiKey_UpArrow;
|
||||
key_more = (axis == ImGuiAxis_X) ? ImGuiKey_RightArrow : ImGuiKey_DownArrow;
|
||||
}
|
||||
float amount = (float)GetKeyPressedAmount(key_more, repeat_delay, repeat_rate) - (float)GetKeyPressedAmount(key_less, repeat_delay, repeat_rate);
|
||||
if (amount != 0.0f && IsKeyDown(key_less) && IsKeyDown(key_more)) // Cancel when opposite directions are held, regardless of repeat phase
|
||||
amount = 0.0f;
|
||||
return amount;
|
||||
}
|
||||
|
||||
static void ImGui::NavUpdate()
|
||||
@ -10178,54 +10209,20 @@ static void ImGui::NavUpdate()
|
||||
io.WantSetMousePos = false;
|
||||
//if (g.NavScoringDebugCount > 0) IMGUI_DEBUG_LOG_NAV("[nav] NavScoringDebugCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.NavScoringDebugCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
|
||||
|
||||
// Update Gamepad->Nav inputs mapping
|
||||
// Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard)
|
||||
// Set input source based on which keys are last pressed (as some features differs when used with Gamepad vs Keyboard)
|
||||
// FIXME-NAV: Now that keys are separated maybe we can get rid of NavInputSource?
|
||||
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
|
||||
if (nav_gamepad_active && g.IO.BackendUsingLegacyNavInputArray == false)
|
||||
{
|
||||
for (int n = 0; n < ImGuiNavInput_COUNT; n++)
|
||||
IM_ASSERT(io.NavInputs[n] == 0.0f && "Backend needs to either only use io.AddKeyEvent()/io.AddKeyAnalogEvent(), either only fill legacy io.NavInputs[]. Not both!");
|
||||
#define NAV_MAP_KEY(_KEY, _NAV_INPUT, _ACTIVATE_NAV) do { io.NavInputs[_NAV_INPUT] = io.KeysData[_KEY - ImGuiKey_KeysData_OFFSET].AnalogValue; if (_ACTIVATE_NAV && io.NavInputs[_NAV_INPUT] > 0.0f) { g.NavInputSource = ImGuiInputSource_Gamepad; } } while (0)
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadFaceDown, ImGuiNavInput_Activate, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadFaceRight, ImGuiNavInput_Cancel, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadFaceLeft, ImGuiNavInput_Menu, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadFaceUp, ImGuiNavInput_Input, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadDpadLeft, ImGuiNavInput_DpadLeft, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadDpadRight, ImGuiNavInput_DpadRight, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadDpadUp, ImGuiNavInput_DpadUp, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadDpadDown, ImGuiNavInput_DpadDown, true);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadL1, ImGuiNavInput_FocusPrev, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadR1, ImGuiNavInput_FocusNext, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadL1, ImGuiNavInput_TweakSlow, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadR1, ImGuiNavInput_TweakFast, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadLStickLeft, ImGuiNavInput_LStickLeft, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadLStickRight, ImGuiNavInput_LStickRight, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadLStickUp, ImGuiNavInput_LStickUp, false);
|
||||
NAV_MAP_KEY(ImGuiKey_GamepadLStickDown, ImGuiNavInput_LStickDown, false);
|
||||
#undef NAV_MAP_KEY
|
||||
}
|
||||
|
||||
// Update Keyboard->Nav inputs mapping
|
||||
const ImGuiKey nav_gamepad_keys_to_change_source[] = { ImGuiKey_GamepadFaceRight, ImGuiKey_GamepadFaceLeft, ImGuiKey_GamepadFaceUp, ImGuiKey_GamepadFaceDown, ImGuiKey_GamepadDpadRight, ImGuiKey_GamepadDpadLeft, ImGuiKey_GamepadDpadUp, ImGuiKey_GamepadDpadDown };
|
||||
if (nav_gamepad_active)
|
||||
for (ImGuiKey key : nav_gamepad_keys_to_change_source)
|
||||
if (IsKeyDown(key))
|
||||
g.NavInputSource = ImGuiInputSource_Gamepad;
|
||||
const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
|
||||
const ImGuiKey nav_keyboard_keys_to_change_source[] = { ImGuiKey_Space, ImGuiKey_Enter, ImGuiKey_Escape, ImGuiKey_RightArrow, ImGuiKey_LeftArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow };
|
||||
if (nav_keyboard_active)
|
||||
{
|
||||
#define NAV_MAP_KEY(_KEY, _NAV_INPUT) do { if (IsKeyDown(_KEY)) { io.NavInputs[_NAV_INPUT] = 1.0f; g.NavInputSource = ImGuiInputSource_Keyboard; } } while (0)
|
||||
NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate );
|
||||
NAV_MAP_KEY(ImGuiKey_Enter, ImGuiNavInput_Input );
|
||||
NAV_MAP_KEY(ImGuiKey_Escape, ImGuiNavInput_Cancel );
|
||||
NAV_MAP_KEY(ImGuiKey_LeftArrow, ImGuiNavInput_KeyLeft_ );
|
||||
NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_);
|
||||
NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ );
|
||||
NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ );
|
||||
if (io.KeyCtrl)
|
||||
io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
|
||||
if (io.KeyShift)
|
||||
io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
|
||||
#undef NAV_MAP_KEY
|
||||
}
|
||||
memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
|
||||
for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++)
|
||||
io.NavInputsDownDuration[i] = (io.NavInputs[i] > 0.0f) ? (io.NavInputsDownDuration[i] < 0.0f ? 0.0f : io.NavInputsDownDuration[i] + io.DeltaTime) : -1.0f;
|
||||
for (ImGuiKey key : nav_keyboard_keys_to_change_source)
|
||||
if (IsKeyDown(key))
|
||||
g.NavInputSource = ImGuiInputSource_Keyboard;
|
||||
|
||||
// Process navigation init request (select first/default focus)
|
||||
if (g.NavInitResultId != 0)
|
||||
@ -10270,10 +10267,10 @@ static void ImGui::NavUpdate()
|
||||
g.NavActivateFlags = ImGuiActivateFlags_None;
|
||||
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
||||
{
|
||||
bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
|
||||
bool input_down = IsNavInputDown(ImGuiNavInput_Input);
|
||||
bool activate_pressed = activate_down && IsNavInputPressed(ImGuiNavInput_Activate);
|
||||
bool input_pressed = input_down && IsNavInputPressed(ImGuiNavInput_Input);
|
||||
const bool activate_down = IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_NavGamepadActivate);
|
||||
const bool activate_pressed = activate_down && (IsKeyPressed(ImGuiKey_Space, false) || IsKeyPressed(ImGuiKey_NavGamepadActivate, false));
|
||||
const bool input_down = IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadInput);
|
||||
const bool input_pressed = input_down && (IsKeyPressed(ImGuiKey_Enter, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false));
|
||||
if (g.ActiveId == 0 && activate_pressed)
|
||||
{
|
||||
g.NavActivateId = g.NavId;
|
||||
@ -10330,11 +10327,12 @@ static void ImGui::NavUpdate()
|
||||
|
||||
// *Normal* Manual scroll with NavScrollXXX keys
|
||||
// Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds.
|
||||
ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiNavReadMode_Down, 1.0f / 10.0f, 10.0f);
|
||||
const ImVec2 scroll_dir = GetKeyVector2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown);
|
||||
const float tweak_factor = IsKeyDown(ImGuiKey_NavGamepadTweakSlow) ? 1.0f / 10.0f : IsKeyDown(ImGuiKey_NavGamepadTweakFast) ? 10.0f : 1.0f;
|
||||
if (scroll_dir.x != 0.0f && window->ScrollbarX)
|
||||
SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed));
|
||||
SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed * tweak_factor));
|
||||
if (scroll_dir.y != 0.0f)
|
||||
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
|
||||
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed * tweak_factor));
|
||||
}
|
||||
|
||||
// Always prioritize mouse highlight if navigation is disabled
|
||||
@ -10403,11 +10401,11 @@ void ImGui::NavUpdateCreateMoveRequest()
|
||||
g.NavMoveScrollFlags = ImGuiScrollFlags_None;
|
||||
if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs))
|
||||
{
|
||||
const ImGuiNavReadMode read_mode = ImGuiNavReadMode_Repeat;
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; }
|
||||
const ImGuiInputReadFlags repeat_mode = ImGuiInputReadFlags_Repeat | ImGuiInputReadFlags_RepeatRateNavMove;
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsKeyPressedEx(ImGuiKey_GamepadDpadLeft, repeat_mode) || IsKeyPressedEx(ImGuiKey_LeftArrow, repeat_mode))) { g.NavMoveDir = ImGuiDir_Left; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsKeyPressedEx(ImGuiKey_GamepadDpadRight, repeat_mode) || IsKeyPressedEx(ImGuiKey_RightArrow, repeat_mode))) { g.NavMoveDir = ImGuiDir_Right; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsKeyPressedEx(ImGuiKey_GamepadDpadUp, repeat_mode) || IsKeyPressedEx(ImGuiKey_UpArrow, repeat_mode))) { g.NavMoveDir = ImGuiDir_Up; }
|
||||
if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsKeyPressedEx(ImGuiKey_GamepadDpadDown, repeat_mode) || IsKeyPressedEx(ImGuiKey_DownArrow, repeat_mode))) { g.NavMoveDir = ImGuiDir_Down; }
|
||||
}
|
||||
g.NavMoveClipDir = g.NavMoveDir;
|
||||
g.NavScoringNoClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||
@ -10613,13 +10611,22 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
static void ImGui::NavUpdateCancelRequest()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!IsNavInputPressed(ImGuiNavInput_Cancel))
|
||||
if (!IsKeyPressed(ImGuiKey_Escape, false) && !IsKeyPressed(ImGuiKey_NavGamepadCancel, false))
|
||||
return;
|
||||
|
||||
IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||
// If your custom widget code used: { g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel); }
|
||||
// Since IMGUI_VERSION_NUM >= 18804 it should be: { SetActiveIdUsingKey(ImGuiKey_Escape); SetActiveIdUsingKey(ImGuiKey_NavGamepadCancel); }
|
||||
if (g.ActiveIdUsingNavInputMask & (1 << ImGuiNavInput_Cancel))
|
||||
SetActiveIdUsingKey(ImGuiKey_Escape);
|
||||
if (g.ActiveIdUsingNavInputMask & ~(1 << ImGuiNavInput_Cancel))
|
||||
IM_ASSERT(0); // Other values unsupported
|
||||
#endif
|
||||
|
||||
IMGUI_DEBUG_LOG_NAV("[nav] NavUpdateCancelRequest()\n");
|
||||
if (g.ActiveId != 0)
|
||||
{
|
||||
if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel))
|
||||
if (!IsActiveIdUsingKey(ImGuiKey_Escape) && !IsActiveIdUsingKey(ImGuiKey_NavGamepadCancel))
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (g.NavLayer != ImGuiNavLayer_Main)
|
||||
@ -10865,8 +10872,8 @@ static void ImGui::NavUpdateWindowing()
|
||||
}
|
||||
|
||||
// Start CTRL+Tab or Square+L/R window selection
|
||||
const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_Menu);
|
||||
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressed(ImGuiKey_Tab);
|
||||
const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsKeyPressed(ImGuiKey_NavGamepadMenu, false);
|
||||
const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && io.KeyCtrl && IsKeyPressed(ImGuiKey_Tab, false);
|
||||
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
|
||||
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
|
||||
{
|
||||
@ -10885,7 +10892,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f));
|
||||
|
||||
// Select window to focus
|
||||
const int focus_change_dir = (int)IsNavInputTest(ImGuiNavInput_FocusPrev, ImGuiNavReadMode_RepeatSlow) - (int)IsNavInputTest(ImGuiNavInput_FocusNext, ImGuiNavReadMode_RepeatSlow);
|
||||
const int focus_change_dir = (int)IsKeyPressed(ImGuiKey_GamepadL1) - (int)IsKeyPressed(ImGuiKey_GamepadR1);
|
||||
if (focus_change_dir != 0)
|
||||
{
|
||||
NavUpdateWindowingHighlightWindow(focus_change_dir);
|
||||
@ -10893,7 +10900,7 @@ static void ImGui::NavUpdateWindowing()
|
||||
}
|
||||
|
||||
// Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered top-most)
|
||||
if (!IsNavInputDown(ImGuiNavInput_Menu))
|
||||
if (!IsKeyDown(ImGuiKey_NavGamepadMenu))
|
||||
{
|
||||
g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore.
|
||||
if (g.NavWindowingToggleLayer && g.NavWindow)
|
||||
@ -10946,9 +10953,9 @@ static void ImGui::NavUpdateWindowing()
|
||||
{
|
||||
ImVec2 nav_move_dir;
|
||||
if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
|
||||
nav_move_dir = ImVec2((float)IsKeyDown(ImGuiKey_RightArrow) - (float)IsKeyDown(ImGuiKey_LeftArrow), (float)IsKeyDown(ImGuiKey_DownArrow) - (float)IsKeyDown(ImGuiKey_UpArrow));
|
||||
nav_move_dir = GetKeyVector2d(ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_UpArrow, ImGuiKey_DownArrow);
|
||||
if (g.NavInputSource == ImGuiInputSource_Gamepad)
|
||||
nav_move_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiNavReadMode_Down);
|
||||
nav_move_dir = GetKeyVector2d(ImGuiKey_GamepadLStickLeft, ImGuiKey_GamepadLStickRight, ImGuiKey_GamepadLStickUp, ImGuiKey_GamepadLStickDown);
|
||||
if (nav_move_dir.x != 0.0f || nav_move_dir.y != 0.0f)
|
||||
{
|
||||
const float NAV_MOVE_SPEED = 800.0f;
|
||||
@ -12667,7 +12674,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
int active_id_using_key_input_count = 0;
|
||||
for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_NamedKey_END; n++)
|
||||
active_id_using_key_input_count += g.ActiveIdUsingKeyInputMask[n] ? 1 : 0;
|
||||
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, NavInputMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, g.ActiveIdUsingNavInputMask, active_id_using_key_input_count);
|
||||
Text("ActiveIdUsing: Wheel: %d, NavDirMask: %X, KeyInputMask: %d key(s)", g.ActiveIdUsingMouseWheel, g.ActiveIdUsingNavDirMask, active_id_using_key_input_count);
|
||||
Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Not displaying g.HoveredId as it is update mid-frame
|
||||
Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize);
|
||||
Unindent();
|
||||
|
Reference in New Issue
Block a user