Summary
The two debug tool windows — InputDebugPanel and Disk2DebugPanel — independently re-implement a large amount of common window/dialog scaffolding. Factor the shared behavior into a common base class (proposed name DxDialog — see naming note) and derive both panels from it.
Both currently implement IChromedPanelContent and are hosted in a ChromedPanelWindow via composition (m_window). They duplicate, near-verbatim:
- Keyboard focus management — a parallel
*FocusStop enum, an m_focusStops tab-order vector rebuilt on every focus change, plus matching switches in ApplyFocus/HandleKey and hand-written SetFocusToStop(...) calls in every mouse handler. (Tracked separately below.)
- ListView scrollbar mouse wiring — arrow/thumb/track hit-testing, thumb-drag begin/update/end,
SetCapture/ReleaseCapture plumbing in OnLButtonDown/OnMouseMove/OnLButtonUp.
- Tooltip viewport clamping —
SetViewportSize on layout recompute.
- Row layout / spacing constants —
kRowVGap96, header gaps, etc.
- Sticky-tail autoscroll — keep newest row visible only when already scrolled to the bottom.
- Window title plumbing —
SetTitle on the chrome titlebar.
Goal
Extract a common base (DxDialog) that owns the ChromedPanelWindow, focus ring, scrollbar/mouse routing for a hosted ListView, tooltip clamping, and title handling. The two debug panels become thin subclasses that only declare their own widgets and event semantics.
Sub-task: rework focus management
As part of (or alongside) this, replace the enum-and-three-switches focus model with a focus manager over a vector<IFocusable*> tab ring:
- Each focusable widget implements a small common interface (
Blur(), HandleKey(), OnLButtonDown()/hit-test, and an IsFocusable() predicate for conditional stops like the joystick/paddle checkboxes).
- Focus becomes an index into the vector; Tab and clicks just move the index, and the manager blurs the outgoing widget and focuses the incoming one.
- Separate
Dropdown::Blur() (lose keyboard focus) from closing the popup. They are currently the same call (SetFocused(false) also sets m_open = false), which caused the dropdown-commit bug worked around with a !IsOpen() guard. Decoupling these removes the workaround.
Naming note
DxDialog is a reasonable name, though these are non-modal chromed tool windows rather than modal dialogs — ChromedDialog, DxToolWindow, or DxPanelContent are alternatives. Pick whatever reads best against the existing ChromedPanelWindow / IChromedPanelContent vocabulary.
Not urgent
The current code is functional; this is a maintainability refactor. Land it on its own branch so the diff is reviewable in isolation.
Summary
The two debug tool windows —
InputDebugPanelandDisk2DebugPanel— independently re-implement a large amount of common window/dialog scaffolding. Factor the shared behavior into a common base class (proposed nameDxDialog— see naming note) and derive both panels from it.Both currently implement
IChromedPanelContentand are hosted in aChromedPanelWindowvia composition (m_window). They duplicate, near-verbatim:*FocusStopenum, anm_focusStopstab-order vector rebuilt on every focus change, plus matching switches inApplyFocus/HandleKeyand hand-writtenSetFocusToStop(...)calls in every mouse handler. (Tracked separately below.)SetCapture/ReleaseCaptureplumbing inOnLButtonDown/OnMouseMove/OnLButtonUp.SetViewportSizeon layout recompute.kRowVGap96, header gaps, etc.SetTitleon the chrome titlebar.Goal
Extract a common base (
DxDialog) that owns theChromedPanelWindow, focus ring, scrollbar/mouse routing for a hostedListView, tooltip clamping, and title handling. The two debug panels become thin subclasses that only declare their own widgets and event semantics.Sub-task: rework focus management
As part of (or alongside) this, replace the enum-and-three-switches focus model with a focus manager over a
vector<IFocusable*>tab ring:Blur(),HandleKey(),OnLButtonDown()/hit-test, and anIsFocusable()predicate for conditional stops like the joystick/paddle checkboxes).Dropdown::Blur()(lose keyboard focus) from closing the popup. They are currently the same call (SetFocused(false)also setsm_open = false), which caused the dropdown-commit bug worked around with a!IsOpen()guard. Decoupling these removes the workaround.Naming note
DxDialogis a reasonable name, though these are non-modal chromed tool windows rather than modal dialogs —ChromedDialog,DxToolWindow, orDxPanelContentare alternatives. Pick whatever reads best against the existingChromedPanelWindow/IChromedPanelContentvocabulary.Not urgent
The current code is functional; this is a maintainability refactor. Land it on its own branch so the diff is reviewable in isolation.