From 25efa1127fb5d4447342713cc9a6505cb9477239 Mon Sep 17 00:00:00 2001 From: Creeper Lv Date: Sun, 28 Dec 2025 23:23:33 +1100 Subject: [PATCH] FileItem will no longer open more than 1 tab for a file. Added Ctrl+S shortcut in BaseEditor. --- Progrart/Controls/BaseEditor.axaml | 10 ++- Progrart/Controls/BaseEditor.axaml.cs | 95 ++++++++++++++------ Progrart/Controls/FileItem.axaml.cs | 25 +++--- Progrart/Controls/TabSystem/TabHost.axaml.cs | 13 +++ Progrart/Pages/EditorPage.axaml.cs | 4 + Progrart/Pages/EditorProvider.cs | 9 ++ Progrart/Pages/ImageViewPage.axaml.cs | 11 ++- Progrart/Pages/ProgrartEditorPage.axaml.cs | 8 +- 8 files changed, 136 insertions(+), 39 deletions(-) diff --git a/Progrart/Controls/BaseEditor.axaml b/Progrart/Controls/BaseEditor.axaml index 666049a..e0194fe 100644 --- a/Progrart/Controls/BaseEditor.axaml +++ b/Progrart/Controls/BaseEditor.axaml @@ -7,5 +7,13 @@ x:Class="Progrart.Controls.BaseEditor"> + FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace"> + + + + + + + + diff --git a/Progrart/Controls/BaseEditor.axaml.cs b/Progrart/Controls/BaseEditor.axaml.cs index 086b62e..db4cf81 100644 --- a/Progrart/Controls/BaseEditor.axaml.cs +++ b/Progrart/Controls/BaseEditor.axaml.cs @@ -1,37 +1,82 @@ using Avalonia; using Avalonia.Controls; +using Avalonia.Input; using Avalonia.Markup.Xaml; +using AvaloniaEdit; using AvaloniaEdit.TextMate; +using System; +using System.Windows.Input; using TextMateSharp.Grammars; namespace Progrart.Controls; public partial class BaseEditor : UserControl { - RegistryOptions _registryOptions; - TextMate.Installation _textMateInstallation; - public string Text - { - get => CodeEditBox.Text; - set => CodeEditBox.Text = value; - } - public BaseEditor() - { - InitializeComponent(); - { - var _textEditor = CodeEditBox; - _registryOptions = new RegistryOptions(ThemeName.DarkPlus); - _textMateInstallation = _textEditor.InstallTextMate(_registryOptions); - _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id)); - } - } - public void SetGrammerByExtension(string extension_name) - { - _textMateInstallation.SetGrammar( - _registryOptions.GetScopeByLanguageId( - _registryOptions.GetLanguageByExtension(extension_name).Id - ) - ); + RegistryOptions _registryOptions; + TextMate.Installation _textMateInstallation; + public string Text + { + get => CodeEditBox.Text; + set => CodeEditBox.Text = value; + } + public Action? onSaveCmd; + public BaseEditor() + { + InitializeComponent(); + { + var _textEditor = CodeEditBox; + _registryOptions = new RegistryOptions(ThemeName.DarkPlus); + _textMateInstallation = _textEditor.InstallTextMate(_registryOptions); + _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id)); + } + var saveBinding = new KeyBinding + { + Gesture = new KeyGesture(Key.S, KeyModifiers.Control), + Command = new saveCmd() { onSave = Save } + }; - } + CodeEditBox.KeyBindings.Add(saveBinding); + } + void Save() + { + onSaveCmd?.Invoke(); + } + class saveCmd : ICommand + { + public event EventHandler? CanExecuteChanged; + public Action? onSave; + public bool CanExecute(object? parameter) + { + return true; + } + + public void Execute(object? parameter) + { + onSave?.Invoke(); + } + } + public void SetGrammerByExtension(string extension_name) + { + _textMateInstallation.SetGrammar( + _registryOptions.GetScopeByLanguageId( + _registryOptions.GetLanguageByExtension(extension_name).Id + ) + ); + + } + + private void Copy_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Copy(); + } + + private void Paste_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Paste(); + } + + private void Cut_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e) + { + CodeEditBox.Cut(); + } } \ No newline at end of file diff --git a/Progrart/Controls/FileItem.axaml.cs b/Progrart/Controls/FileItem.axaml.cs index b4cc44e..bb4e332 100644 --- a/Progrart/Controls/FileItem.axaml.cs +++ b/Progrart/Controls/FileItem.axaml.cs @@ -149,18 +149,23 @@ public partial class FileItem : UserControl else if (currentItem is IStorageFile file) { - - if (EditorProvider.TryGetEditor(extension, out var page)) + var btn = EditorProvider.IsOpen(file); + if (btn is not null) { - if (page is ITabPage editor) - { - if (page is IEditorPage editor_page) - { - editor_page.LoadDocument(file); - } - EditorProvider.OpenEditor(editor); - } + EditorProvider.SelectTabPage(btn); } + else + if (EditorProvider.TryGetEditor(extension, out var page)) + { + if (page is ITabPage editor) + { + if (page is IEditorPage editor_page) + { + editor_page.LoadDocument(file); + } + EditorProvider.OpenEditor(editor); + } + } } } async Task LoadAll(IStorageFolder folder) diff --git a/Progrart/Controls/TabSystem/TabHost.axaml.cs b/Progrart/Controls/TabSystem/TabHost.axaml.cs index e46dfdc..1c5b016 100644 --- a/Progrart/Controls/TabSystem/TabHost.axaml.cs +++ b/Progrart/Controls/TabSystem/TabHost.axaml.cs @@ -1,6 +1,8 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using Avalonia.Platform.Storage; +using Progrart.Pages; namespace Progrart.Controls.TabSystem; @@ -30,6 +32,17 @@ public partial class TabHost : UserControl page.BindButton(button); SelectButton(button); } + public TabButton? IsOpen(IStorageFile file) + { + + foreach (var item in TabContainer.Children) + { + if (item is TabButton itemBtn) + if (itemBtn.page is IEditorPage page) + if (page.IsSameFile(file)) return itemBtn; + } + return null; + } public void SelectButton(TabButton button) { foreach (var item in TabContainer.Children) diff --git a/Progrart/Pages/EditorPage.axaml.cs b/Progrart/Pages/EditorPage.axaml.cs index 9583e49..71c32bf 100644 --- a/Progrart/Pages/EditorPage.axaml.cs +++ b/Progrart/Pages/EditorPage.axaml.cs @@ -24,6 +24,10 @@ public partial class EditorPage : UserControl, ITabPage, IEditorPage } + public bool IsSameFile(IStorageFile file) + { + return (this.file?.Path == file.Path); + } public void BindButton(TabButton button) { btn = button; diff --git a/Progrart/Pages/EditorProvider.cs b/Progrart/Pages/EditorProvider.cs index 7f3edf8..a6c92ba 100644 --- a/Progrart/Pages/EditorProvider.cs +++ b/Progrart/Pages/EditorProvider.cs @@ -29,6 +29,14 @@ namespace Progrart.Pages { ExtensionMapping[type] = id; } + public static TabButton? IsOpen(IStorageFile file) + { + return currentHost?.IsOpen(file); + } + public static void SelectTabPage(TabButton button) + { + currentHost?.SelectButton(button); + } public static void OpenEditor(ITabPage page) { currentHost?.AddPage(page); @@ -56,6 +64,7 @@ namespace Progrart.Pages { void LoadDocument(IStorageFile file); void Save(); + bool IsSameFile(IStorageFile file); void Execute(ExecuteArguments? args = null); } } \ No newline at end of file diff --git a/Progrart/Pages/ImageViewPage.axaml.cs b/Progrart/Pages/ImageViewPage.axaml.cs index a893ccf..a5426eb 100644 --- a/Progrart/Pages/ImageViewPage.axaml.cs +++ b/Progrart/Pages/ImageViewPage.axaml.cs @@ -12,6 +12,7 @@ namespace Progrart.Pages; public partial class ImageViewPage : UserControl, ITabPage, IEditorPage { + IStorageFile? file; public ImageViewPage() { InitializeComponent(); @@ -31,15 +32,16 @@ public partial class ImageViewPage : UserControl, ITabPage, IEditorPage { return false; } - public void LoadDocument(IStorageFile file) { + this.file = file; Task.Run(async () => { using var fs = await file.OpenReadAsync(); Bitmap bitmap = new Bitmap(fs); - Dispatcher.UIThread.Invoke(() => { + Dispatcher.UIThread.Invoke(() => + { this.ImageViewer.SetImage(bitmap); }); }); @@ -52,4 +54,9 @@ public partial class ImageViewPage : UserControl, ITabPage, IEditorPage public void SetHost(TabHost host) { } + + public bool IsSameFile(IStorageFile file) + { + return (this.file?.Path == file.Path); + } } \ No newline at end of file diff --git a/Progrart/Pages/ProgrartEditorPage.axaml.cs b/Progrart/Pages/ProgrartEditorPage.axaml.cs index a092f1c..430f5fe 100644 --- a/Progrart/Pages/ProgrartEditorPage.axaml.cs +++ b/Progrart/Pages/ProgrartEditorPage.axaml.cs @@ -21,6 +21,7 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage public ProgrartEditorPage() { InitializeComponent(); + CodeEditor.onSaveCmd = Save; } public void BindButton(TabButton button) @@ -72,7 +73,12 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage return false; } - public void LoadDocument(IStorageFile file) + public bool IsSameFile(IStorageFile file) + { + return (this.file?.Path==file.Path); + } + + public void LoadDocument(IStorageFile file) { this.file = file; if (btn is not null)