feat(input): #24 Phase K.2 - auto-enter player mode at login + MMB mouse-look + DebugPanel free-fly + Tab to chat-input focus
Five changes:
1. PlayerModeAutoEntry — testable guard class that fires once after
EnterWorld + WorldSession.State.InWorld + player entity present +
PlayerController.State == InWorld. GameWindow arms the entry
after EnterWorld; per-frame Tick checks all four guards and
invokes the same fly-to-player transition the Tab handler runs.
User-initiated fly toggle (DebugPanel button) Cancel()s pending
entry. Skip in offline mode (no ACDREAM_LIVE) — Holtburg orbit
stays default for testing.
2. MouseLookState + KeyBindings.RetailDefaults() binds MMB Hold to
InputAction.CameraInstantMouseLook. GameWindow subscribes:
- Press: hide cursor, capture position, _mouseLookActive = true.
- Release: restore cursor, deactivate.
- WantCaptureMouse=true while held → suspend (release cursor).
- MouseMove while active: combined drive — chase camera yaw +
character heading move together (retail's signature mouse-look
behavior). Camera Y still pitches camera-only.
3. DebugPanel "Toggle Free-Fly Mode" button via DebugVM.ToggleFlyMode
action delegate — replaces the F-key as the primary discovery
path for free-fly. Gated on DevToolsEnabled.
4. ChatPanel.FocusInput() one-shot + IPanelRenderer.SetKeyboardFocusHere
primitive. GameWindow's ToggleChatEntry (Tab) subscriber calls
_chatPanel.FocusInput() so Tab moves focus to the chat input
field. Replaces the K.1c TODO stub.
5. WantCaptureMouse gating reinforcement on surviving mouse handlers
(no new code; verified intact from K.1b).
21 new tests (8 PlayerModeAutoEntry, 10 MouseLookState, 3 ChatPanel
focus). 1183 total green. 0 warnings, 0 errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
da189103b8
commit
af74eac0c2
12 changed files with 972 additions and 66 deletions
|
|
@ -42,6 +42,14 @@ public sealed class ChatPanel : IPanel
|
|||
// entries without yanking the user's manual scroll.
|
||||
private int _lastRenderedCount;
|
||||
|
||||
// Phase K.2: one-shot focus request for the chat input. Set by
|
||||
// FocusInput() (driven by Tab → ToggleChatEntry); the next Render
|
||||
// call emits SetKeyboardFocusHere immediately before the input
|
||||
// field and clears the flag. Without the one-shot semantics, the
|
||||
// panel would steal focus on every frame and the user could never
|
||||
// click into another widget.
|
||||
private bool _focusRequested;
|
||||
|
||||
public ChatPanel(ChatVM vm)
|
||||
{
|
||||
_vm = vm ?? throw new ArgumentNullException(nameof(vm));
|
||||
|
|
@ -56,6 +64,15 @@ public sealed class ChatPanel : IPanel
|
|||
/// <inheritdoc />
|
||||
public bool IsVisible { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Phase K.2: request keyboard focus for the chat input on the
|
||||
/// NEXT <see cref="Render"/>. One-shot — fires once and resets,
|
||||
/// so callers (e.g. <c>GameWindow</c>'s Tab handler subscribing to
|
||||
/// <c>ToggleChatEntry</c>) can drive it on a single key press
|
||||
/// without trapping the user permanently in the input field.
|
||||
/// </summary>
|
||||
public void FocusInput() => _focusRequested = true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Render(PanelContext ctx, IPanelRenderer renderer)
|
||||
{
|
||||
|
|
@ -115,6 +132,15 @@ public sealed class ChatPanel : IPanel
|
|||
// Phase I.4: input field. Backend implementation clears _input
|
||||
// on submit per the IPanelRenderer contract.
|
||||
renderer.Separator();
|
||||
// Phase K.2: honor a pending FocusInput() request — emit
|
||||
// SetKeyboardFocusHere immediately before the input widget so
|
||||
// ImGui (or the future custom backend) applies it to that
|
||||
// field. One-shot: clear the flag after firing.
|
||||
if (_focusRequested)
|
||||
{
|
||||
renderer.SetKeyboardFocusHere();
|
||||
_focusRequested = false;
|
||||
}
|
||||
if (renderer.InputTextSubmit("##chatinput", ref _input, InputBufferMaxLen, out var submitted)
|
||||
&& submitted is not null)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue