[Phase L2-6] 검색 결과 그룹핑 (앱/폴더/파일/단축키)
AxCopilot.SDK/IActionHandler.cs: - LauncherItem 레코드에 Group? 선택 매개변수 추가 (기존 호출 코드 무변경) Core/CommandResolver.cs: - Fuzzy 검색 결과에 Group 태깅: 앱/폴더/단축키/파일 ViewModels/LauncherViewModel.cs: - ICollectionView GroupedResults 프로퍼티 추가 - CollectionViewSource + PropertyGroupDescription(nameof(LauncherItem.Group)) 초기화 Views/LauncherWindow.xaml: - ItemsSource: Results → GroupedResults 변경 - ListView.GroupStyle 추가: 그룹 이름 헤더(10px, SemiBold, 흐린 보조 텍스트) - GroupItem ContainerStyle로 헤더+아이템 수직 배치 - Group=null 항목은 NullToCollapsedConverter로 헤더 숨김 빌드: 경고 0, 오류 0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,8 @@ public record LauncherItem(
|
||||
string? IconPath, // null이면 기본 아이콘 사용
|
||||
object? Data, // ExecuteAsync에 전달되는 임의 데이터
|
||||
string? ActionUrl = null, // Enter 시 열릴 URL (선택)
|
||||
string? Symbol = null // Segoe MDL2 Assets 유니코드 심볼 (null이면 타입 기반 자동 결정)
|
||||
string? Symbol = null, // Segoe MDL2 Assets 유니코드 심볼 (null이면 타입 기반 자동 결정)
|
||||
string? Group = null // 검색 결과 그룹 레이블 (null이면 그룹 없음)
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -104,6 +104,13 @@ public class CommandResolver
|
||||
_ => Symbols.Plugin
|
||||
},
|
||||
_ => Symbols.File
|
||||
},
|
||||
Group: r.Entry.Type switch
|
||||
{
|
||||
IndexEntryType.App => "앱",
|
||||
IndexEntryType.Folder => "폴더",
|
||||
IndexEntryType.Alias => "단축키",
|
||||
_ => "파일"
|
||||
}
|
||||
)),
|
||||
item => (item.Data as IndexEntry)?.Path
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Media;
|
||||
using AxCopilot.Core;
|
||||
using AxCopilot.Models;
|
||||
@@ -41,6 +42,12 @@ public partial class LauncherViewModel : INotifyPropertyChanged
|
||||
/// </summary>
|
||||
public BulkObservableCollection<LauncherItem> Results { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 그룹핑이 적용된 결과 뷰. prefix 없는 일반 검색에서 앱/폴더/파일/단축키 섹션 구분 표시.
|
||||
/// Group == null 항목은 별도 그룹 헤더 없이 표시됩니다.
|
||||
/// </summary>
|
||||
public ICollectionView GroupedResults { get; }
|
||||
|
||||
// ─── 기본 프로퍼티 ────────────────────────────────────────────────────────
|
||||
|
||||
public string InputText
|
||||
@@ -243,6 +250,11 @@ public partial class LauncherViewModel : INotifyPropertyChanged
|
||||
{
|
||||
_resolver = resolver;
|
||||
_settings = settings;
|
||||
|
||||
// 그룹핑 뷰 초기화 (UI 스레드에서 생성 보장)
|
||||
GroupedResults = CollectionViewSource.GetDefaultView(Results);
|
||||
GroupedResults.GroupDescriptions.Add(
|
||||
new PropertyGroupDescription(nameof(LauncherItem.Group)));
|
||||
}
|
||||
|
||||
// ─── 런처 표시 시 초기화 ──────────────────────────────────────────────────
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
WindowStartupLocation="Manual"
|
||||
Loaded="Window_Loaded"
|
||||
Deactivated="Window_Deactivated"
|
||||
IsVisibleChanged="Window_IsVisibleChanged"
|
||||
PreviewKeyDown="Window_PreviewKeyDown"
|
||||
KeyDown="Window_KeyDown">
|
||||
|
||||
@@ -488,7 +489,7 @@
|
||||
<!-- ─── 결과 리스트 ─── -->
|
||||
<ListView x:Name="ResultList"
|
||||
Grid.Row="4"
|
||||
ItemsSource="{Binding Results}"
|
||||
ItemsSource="{Binding GroupedResults}"
|
||||
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
|
||||
Background="Transparent"
|
||||
BorderThickness="0"
|
||||
@@ -507,6 +508,40 @@
|
||||
<Style TargetType="ScrollBar" BasedOn="{StaticResource SlimScrollBar}"/>
|
||||
</ListView.Resources>
|
||||
|
||||
<!-- 그룹 헤더: Group이 null/empty이면 헤더 숨김 -->
|
||||
<ListView.GroupStyle>
|
||||
<GroupStyle>
|
||||
<GroupStyle.HeaderTemplate>
|
||||
<DataTemplate>
|
||||
<Border Padding="8,4,8,2"
|
||||
Margin="0,4,0,0">
|
||||
<TextBlock Text="{Binding Name}"
|
||||
FontFamily="Segoe UI, Malgun Gothic"
|
||||
FontSize="10"
|
||||
FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource SecondaryText}"
|
||||
Opacity="0.7"
|
||||
Visibility="{Binding Name, Converter={StaticResource NullToCollapsedConverter}}"/>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</GroupStyle.HeaderTemplate>
|
||||
<GroupStyle.ContainerStyle>
|
||||
<Style TargetType="GroupItem">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="GroupItem">
|
||||
<StackPanel>
|
||||
<ContentPresenter/>
|
||||
<ItemsPresenter/>
|
||||
</StackPanel>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</GroupStyle.ContainerStyle>
|
||||
</GroupStyle>
|
||||
</ListView.GroupStyle>
|
||||
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
|
||||
Reference in New Issue
Block a user