using System; using System.CodeDom.Compiler; using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Markup; using System.Windows.Media; using AxCopilot.Services; namespace AxCopilot.Views; public class ShortcutHelpWindow : Window, IComponentConnector { private record ShortcutRow(string Key, string Description, string Icon = "\ue72d", string Color = "#4B5EFC"); private const int WM_NCLBUTTONDOWN = 161; private const int HTBOTTOMRIGHT = 17; internal ItemsControl NavigationItems; internal ItemsControl FileActionItems; internal ItemsControl ViewItems; internal ItemsControl RunItems; internal ItemsControl PrefixItems; internal CheckBox ThemeColorChk; private bool _contentLoaded; [DllImport("user32.dll")] private static extern void ReleaseCapture(); [DllImport("user32.dll")] private static extern nint SendMessage(nint hWnd, int msg, nint wParam, nint lParam); public ShortcutHelpWindow() { InitializeComponent(); base.Loaded += delegate { SettingsService settingsService = (Application.Current as App)?.SettingsService; if (settingsService != null) { ThemeColorChk.IsChecked = settingsService.Settings.Launcher.ShortcutHelpUseThemeColor; } BuildItems(); }; } private void BuildItems() { bool valueOrDefault = ThemeColorChk.IsChecked == true; ShortcutRow[] rows = new ShortcutRow[6] { new ShortcutRow("↑ / ↓", "결과 목록 위/아래로 이동", "\ue74a"), new ShortcutRow("PageUp / PageDown", "목록 5칸 빠른 이동", "\ue74a"), new ShortcutRow("Home / End", "목록 처음 항목 / 마지막 항목으로 점프", "\ue74a"), new ShortcutRow("Tab", "선택 항목 제목을 입력창에 자동 완성", "\ue748", "#7B68EE"), new ShortcutRow("→", "파일/앱 선택 시 액션 모드(복사·실행 등) 진입", "\ue76c", "#107C10"), new ShortcutRow("Escape", "액션 모드면 일반 모드로 복귀, 아니면 AX Commander 닫기", "\ue711", "#C50F1F") }; ShortcutRow[] rows2 = new ShortcutRow[10] { new ShortcutRow("Enter", "선택 항목 실행 (파일 열기·명령 실행·URL 열기 등)", "\ue768", "#107C10"), new ShortcutRow("Ctrl+Enter", "선택 파일·앱을 관리자(UAC 상승) 권한으로 실행", "\ue7ef", "#C50F1F"), new ShortcutRow("Alt+Enter", "선택 항목의 Windows 속성 대화 상자 열기", "\ue7ee", "#8B2FC9"), new ShortcutRow("Ctrl+C", "선택 항목의 파일 이름(확장자 제외)을 클립보드에 복사", "\ue8c8", "#0078D4"), new ShortcutRow("Ctrl+Shift+C", "선택 항목의 전체 경로를 클립보드에 복사", "\ue8c8", "#0078D4"), new ShortcutRow("Ctrl+Shift+E", "파일 탐색기를 열고 선택 항목 위치를 하이라이트", "\ue8da", "#107C10"), new ShortcutRow("Ctrl+T", "선택 항목 폴더 경로에서 터미널(wt/cmd) 열기", "\ue756", "#323130"), new ShortcutRow("Ctrl+P", "선택 항목을 즐겨찾기에 추가 (이미 있으면 제거)", "\ue734", "#D97706"), new ShortcutRow("F2", "선택 파일·폴더의 이름 변경 모드로 전환", "\ue70f", "#6B2C91"), new ShortcutRow("Delete", "선택 항목을 최근 목록에서 제거 (확인 후 실행)", "\ue74d", "#C50F1F") }; ShortcutRow[] rows3 = new ShortcutRow[6] { new ShortcutRow("Ctrl+B", "즐겨찾기 목록 보기 (다시 누르면 닫기, 토글)", "\ue735", "#D97706"), new ShortcutRow("Ctrl+R", "최근 실행 목록 보기 (다시 누르면 닫기, 토글)", "\ue81c", "#0078D4"), new ShortcutRow("Ctrl+H", "클립보드 히스토리 목록 보기", "\ue77f", "#8B2FC9"), new ShortcutRow("Ctrl+D", "다운로드 폴더 경로 바로 열기", "\ue8b7", "#107C10"), new ShortcutRow("Ctrl+F", "입력 초기화 후 파일 검색 모드로 포커스 이동", "\ue71e"), new ShortcutRow("F1", "헬프 화면 열기 (help 입력과 동일)", "\ue897") }; ShortcutRow[] rows4 = new ShortcutRow[7] { new ShortcutRow("Ctrl+1 ~ Ctrl+9", "표시 중인 N번째 결과를 즉시 실행 (번호 배지와 연동)", "\ue8c4", "#107C10"), new ShortcutRow("Ctrl+L", "입력창 전체 초기화", "\ue711", "#9999BB"), new ShortcutRow("Ctrl+W", "AX Commander 창 즉시 닫기", "\ue711", "#9999BB"), new ShortcutRow("Ctrl+K", "이 단축키 참조 창 열기", "\ue8fd"), new ShortcutRow("Ctrl+,", "설정 창 열기", "\ue713"), new ShortcutRow("F5", "파일 인덱스 즉시 재구축", "\ue72c", "#107C10"), new ShortcutRow("Shift+Enter", "Large Type / 병합 실행 / 캡처 모드: 지연 캡처(3/5/10초) 타이머", "\ue8a7", "#7B68EE") }; ShortcutRow[] rows5 = new ShortcutRow[9] { new ShortcutRow("cd [경로/별칭]", "지정한 경로 또는 등록된 폴더 별칭을 탐색기로 열기", "\ue8da", "#107C10"), new ShortcutRow("~ [이름]", "워크스페이스 저장(save)/복원(restore)/목록(list)", "\ue8b7", "#C50F1F"), new ShortcutRow("# [검색어]", "클립보드 히스토리 검색·붙여넣기", "\ue77f", "#8B2FC9"), new ShortcutRow("fav [검색어]", "즐겨찾기 목록 검색 및 열기. add/del 로 관리", "\ue735", "#D97706"), new ShortcutRow("recent [검색어]", "최근 실행 항목 검색", "\ue81c", "#0078D4"), new ShortcutRow("cap [모드]", "화면 캡처 (region/window/scroll/screen) · Shift+Enter: 지연 캡처", "\ue722", "#C09010"), new ShortcutRow("help [검색어]", "도움말 및 기능 목록 검색", "\ue897"), new ShortcutRow("/ [명령]", "시스템 명령 (lock/sleep/restart/shutdown 등)", "\ue7e8", "#C50F1F"), new ShortcutRow("! [질문]", "AX Agent — Ollama/vLLM/Gemini/Claude", "\ue8bd", "#8B2FC9") }; NavigationItems.Items.Clear(); FileActionItems.Items.Clear(); ViewItems.Items.Clear(); RunItems.Items.Clear(); PrefixItems.Items.Clear(); Populate(NavigationItems, rows, valueOrDefault); Populate(FileActionItems, rows2, valueOrDefault); Populate(ViewItems, rows3, valueOrDefault); Populate(RunItems, rows4, valueOrDefault); Populate(PrefixItems, rows5, valueOrDefault); } private static void Populate(ItemsControl control, ShortcutRow[] rows, bool useThemeColor) { Brush foreground = (Application.Current.TryFindResource("PrimaryText") as Brush) ?? new SolidColorBrush(Color.FromRgb(51, 51, 85)); Brush background = (Application.Current.TryFindResource("ItemBackground") as Brush) ?? new SolidColorBrush(Color.FromRgb(238, 238, byte.MaxValue)); string text = ((Application.Current.TryFindResource("AccentColor") is SolidColorBrush solidColorBrush) ? $"#{solidColorBrush.Color.R:X2}{solidColorBrush.Color.G:X2}{solidColorBrush.Color.B:X2}" : "#4B5EFC"); foreach (ShortcutRow shortcutRow in rows) { string text2 = (useThemeColor ? text : shortcutRow.Color); Grid grid = new Grid { Margin = new Thickness(0.0, 0.0, 0.0, 3.0) }; grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(28.0) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(148.0) }); grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Star) }); Border border = new Border { Width = 22.0, Height = 22.0, CornerRadius = new CornerRadius(5.0), Background = ParseBrush(text2 + "22"), VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Center }; border.Child = new TextBlock { Text = shortcutRow.Icon, FontFamily = new FontFamily("Segoe MDL2 Assets"), FontSize = 10.0, Foreground = ParseBrush(text2), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }; Grid.SetColumn(border, 0); grid.Children.Add(border); Border border2 = new Border { Background = background, CornerRadius = new CornerRadius(5.0), Padding = new Thickness(7.0, 3.0, 7.0, 3.0), Margin = new Thickness(4.0, 1.0, 8.0, 1.0), VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Left }; border2.Child = new TextBlock { Text = shortcutRow.Key, FontFamily = new FontFamily("Consolas, Courier New"), FontSize = 11.0, Foreground = foreground, VerticalAlignment = VerticalAlignment.Center }; Grid.SetColumn(border2, 1); grid.Children.Add(border2); TextBlock element = new TextBlock { Text = shortcutRow.Description, FontSize = 11.5, Foreground = foreground, VerticalAlignment = VerticalAlignment.Center, TextWrapping = TextWrapping.Wrap, LineHeight = 16.0 }; Grid.SetColumn(element, 2); grid.Children.Add(element); control.Items.Add(grid); } } private static SolidColorBrush ParseBrush(string hex) { try { return new SolidColorBrush((Color)ColorConverter.ConvertFromString(hex)); } catch { return new SolidColorBrush(Colors.Transparent); } } private void ThemeColorChk_Changed(object sender, RoutedEventArgs e) { SettingsService settingsService = (Application.Current as App)?.SettingsService; if (settingsService != null) { settingsService.Settings.Launcher.ShortcutHelpUseThemeColor = ThemeColorChk.IsChecked == true; settingsService.Save(); } BuildItems(); } private void ResizeGrip_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (e.ButtonState == MouseButtonState.Pressed) { ReleaseCapture(); SendMessage(new WindowInteropHelper(this).Handle, 161, 17, IntPtr.Zero); } } private void Close_Click(object sender, RoutedEventArgs e) { Close(); } private void Window_KeyDown(object sender, KeyEventArgs e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if ((int)e.Key == 13) { Close(); } } private void Window_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left && e.LeftButton == MouseButtonState.Pressed) { try { DragMove(); } catch { } } } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "10.0.5.0")] public void InitializeComponent() { if (!_contentLoaded) { _contentLoaded = true; Uri resourceLocator = new Uri("/AxCopilot;component/views/shortcuthelpwindow.xaml", UriKind.Relative); Application.LoadComponent(this, resourceLocator); } } [DebuggerNonUserCode] [GeneratedCode("PresentationBuildTasks", "10.0.5.0")] [EditorBrowsable(EditorBrowsableState.Never)] void IComponentConnector.Connect(int connectionId, object target) { switch (connectionId) { case 1: ((ShortcutHelpWindow)target).KeyDown += Window_KeyDown; ((ShortcutHelpWindow)target).MouseDown += Window_MouseDown; break; case 2: ((Button)target).Click += Close_Click; break; case 3: NavigationItems = (ItemsControl)target; break; case 4: FileActionItems = (ItemsControl)target; break; case 5: ViewItems = (ItemsControl)target; break; case 6: RunItems = (ItemsControl)target; break; case 7: PrefixItems = (ItemsControl)target; break; case 8: ((Border)target).MouseLeftButtonDown += ResizeGrip_MouseLeftButtonDown; break; case 9: ThemeColorChk = (CheckBox)target; ThemeColorChk.Checked += ThemeColorChk_Changed; ThemeColorChk.Unchecked += ThemeColorChk_Changed; break; case 10: ((Button)target).Click += Close_Click; break; default: _contentLoaded = true; break; } } }