슬래시 팝업 UX 개선: 스크롤/선택 이동 재렌더링 제거
Some checks failed
Release Gate / gate (push) Has been cancelled

- ChatWindow slash 이동 경로를 RenderSlashPage 기반에서 선택 하이라이트 갱신 기반으로 전환

- 휠/방향키/Home/End 이동 시 UpdateSlashSelectionVisualState + EnsureSlashSelectionVisible 호출로 통일

- 항목 hover 시에도 동일 선택 상태 동기화 경로를 사용해 체감 일관성 개선

- README.md, docs/DEVELOPMENT.md에 2026-04-04 14:01(KST) 기준 이력 반영

- 검증: dotnet build 0경고/0오류, 관련 필터 테스트 84건 통과
This commit is contained in:
2026-04-04 14:02:30 +09:00
parent 0bb37d9390
commit 157332df52
3 changed files with 52 additions and 14 deletions

View File

@@ -5315,7 +5315,6 @@ public partial class ChatWindow : Window
var skillAvailable = skillDef?.IsAvailable ?? true;
var absoluteIndex = i;
var isSelected = absoluteIndex == _slashPalette.SelectedIndex;
var hoverBrushItem = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.LightGray;
var itemBg = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
@@ -5325,8 +5324,8 @@ public partial class ChatWindow : Window
var item = new Border
{
Background = isSelected ? hoverBrushItem : itemBg,
BorderBrush = isSelected ? accent : borderBrush,
Background = Brushes.Transparent,
BorderBrush = borderBrush,
BorderThickness = new Thickness(1),
CornerRadius = new CornerRadius(10),
Padding = new Thickness(10, 7, 10, 7),
@@ -5440,14 +5439,9 @@ public partial class ChatWindow : Window
item.MouseEnter += (_, _) =>
{
_slashPalette.SelectedIndex = absoluteIndex;
item.Background = hoverBrushItem;
item.BorderBrush = accent;
};
item.MouseLeave += (_, _) =>
{
item.Background = absoluteIndex == _slashPalette.SelectedIndex ? hoverBrushItem : itemBg;
item.BorderBrush = absoluteIndex == _slashPalette.SelectedIndex ? accent : borderBrush;
UpdateSlashSelectionVisualState();
};
item.MouseLeave += (_, _) => UpdateSlashSelectionVisualState();
item.MouseLeftButtonDown += (_, _) =>
{
_slashPalette.SelectedIndex = absoluteIndex;
@@ -5499,6 +5493,7 @@ public partial class ChatWindow : Window
SlashPopupFooter.Text = $"Enter 실행 · ↑↓/PgUp/PgDn 이동 · Home/End · Esc 닫기 · 표시 {visibleCommandCount + visibleSkillCount}/{total}";
}
UpdateSlashSelectionVisualState();
EnsureSlashSelectionVisible();
}
@@ -5546,7 +5541,8 @@ public partial class ChatWindow : Window
for (var i = 0; i < steps; i++)
MoveSlashSelection(direction);
RenderSlashPage();
UpdateSlashSelectionVisualState();
EnsureSlashSelectionVisible();
}
/// <summary>키보드로 선택된 슬래시 아이템을 실행합니다.</summary>
@@ -5591,6 +5587,28 @@ public partial class ChatWindow : Window
SlashScrollViewer.ScrollToVerticalOffset(SlashScrollViewer.VerticalOffset + (bounds.Bottom - SlashScrollViewer.ViewportHeight) + 8);
}
private void UpdateSlashSelectionVisualState()
{
if (_slashVisibleItemByAbsoluteIndex.Count == 0)
return;
var selectedIndex = _slashPalette.SelectedIndex;
var itemBg = TryFindResource("ItemBackground") as Brush ?? Brushes.Transparent;
var hoverBrushItem = TryFindResource("ItemHoverBackground") as Brush ?? Brushes.LightGray;
var borderBrush = TryFindResource("BorderColor") as Brush ?? Brushes.Gray;
var accent = TryFindResource("AccentColor") as Brush ?? Brushes.Blue;
foreach (var (absoluteIndex, element) in _slashVisibleItemByAbsoluteIndex)
{
if (element is not Border border)
continue;
var selected = absoluteIndex == selectedIndex;
border.Background = selected ? hoverBrushItem : itemBg;
border.BorderBrush = selected ? accent : borderBrush;
}
}
/// <summary>슬래시 명령어 즐겨찾기를 토글하고 설정을 저장합니다.</summary>
private void ToggleSlashFavorite(string cmd)
{
@@ -10881,14 +10899,16 @@ public partial class ChatWindow : Window
{
var visible = GetVisibleSlashOrderedIndices();
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[0] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
RenderSlashPage();
UpdateSlashSelectionVisualState();
EnsureSlashSelectionVisible();
e.Handled = true;
}
else if (e.Key == Key.End)
{
var visible = GetVisibleSlashOrderedIndices();
_slashPalette.SelectedIndex = visible.Count > 0 ? visible[^1] : GetFirstVisibleSlashIndex(_slashPalette.Matches);
RenderSlashPage();
UpdateSlashSelectionVisualState();
EnsureSlashSelectionVisible();
e.Handled = true;
}
else if (e.Key == Key.Enter && _slashPalette.SelectedIndex >= 0)