From 76caa0d64492f85ab2418f36c1388d739cc418bc Mon Sep 17 00:00:00 2001 From: Creeper Lv Date: Thu, 18 Dec 2025 01:28:15 +1100 Subject: [PATCH] Implemented editor providers. --- Progrart/App.axaml.cs | 13 +++++- Progrart/Controls/FileItem.axaml | 2 +- Progrart/Controls/FileItem.axaml.cs | 50 ++++++++++++++++----- Progrart/Controls/TabSystem/ITabPage.cs | 2 - Progrart/Pages/EditorPage.axaml | 4 +- Progrart/Pages/EditorPage.axaml.cs | 22 ++++++++- Progrart/Pages/EditorProvider.cs | 60 +++++++++++++++++++++++++ Progrart/Views/MainView.axaml.cs | 2 +- 8 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 Progrart/Pages/EditorProvider.cs diff --git a/Progrart/App.axaml.cs b/Progrart/App.axaml.cs index de2c3d5..78d5660 100644 --- a/Progrart/App.axaml.cs +++ b/Progrart/App.axaml.cs @@ -6,6 +6,7 @@ using System.Linq; using Avalonia.Markup.Xaml; using Progrart.Views; using Progrart.Icons; +using Progrart.Pages; namespace Progrart; @@ -19,12 +20,22 @@ public partial class App : Application public override void OnFrameworkInitializationCompleted() { + IconProvider.Register(new DefaultIconProvider()); + EditorProvider.Register("text", "Default Text Editor", typeof(EditorPage)); + EditorProvider.BindFileType("cs", "text"); + EditorProvider.BindFileType("c", "text"); + EditorProvider.BindFileType("cpp", "text"); + EditorProvider.BindFileType("h", "text"); + EditorProvider.BindFileType("hpp", "text"); + EditorProvider.BindFileType("txt", "text"); + EditorProvider.BindFileType("cpp", "text"); + EditorProvider.BindFileType("json", "text"); + EditorProvider.BindFileType("sh", "text"); if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { // Avoid duplicate validations from both Avalonia and the CommunityToolkit. // More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins isDesktop = true; - IconProvider.Register(new DefaultIconProvider()); DisableAvaloniaDataAnnotationValidation(); desktop.MainWindow = new MainWindow(); } diff --git a/Progrart/Controls/FileItem.axaml b/Progrart/Controls/FileItem.axaml index 2bf510b..396d05f 100644 --- a/Progrart/Controls/FileItem.axaml +++ b/Progrart/Controls/FileItem.axaml @@ -10,7 +10,7 @@ - + diff --git a/Progrart/Controls/FileItem.axaml.cs b/Progrart/Controls/FileItem.axaml.cs index 6c3134a..dfad962 100644 --- a/Progrart/Controls/FileItem.axaml.cs +++ b/Progrart/Controls/FileItem.axaml.cs @@ -2,7 +2,9 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; using Avalonia.Platform.Storage; +using Progrart.Controls.TabSystem; using Progrart.Icons; +using Progrart.Pages; using System.Threading.Tasks; namespace Progrart.Controls; @@ -11,6 +13,7 @@ public partial class FileItem : UserControl { IStorageItem currentItem; bool isOpen = false; + string extension = ""; public FileItem(IStorageItem storageItem) { InitializeComponent(); @@ -29,7 +32,7 @@ public partial class FileItem : UserControl var dotIndex = file.Name.LastIndexOf('.'); if (dotIndex >= 0) { - var extension = file.Name[(dotIndex + 1)..]; + extension = file.Name[(dotIndex + 1)..]; if (IconProvider.TryGetIcon(extension, out var icon)) { GenericFileIcon.IsVisible = false; @@ -41,20 +44,45 @@ public partial class FileItem : UserControl NameBlock.Text = storageItem.Name; MainButton.DoubleTapped += async (_, _) => { - if (currentItem is IStorageFolder folder) + await OpenItem(); + }; + OpenFileMenuItem.Click += async (a, b) => + { + await OpenItem(); + }; + } + async Task OpenItem() + { + + if (currentItem is IStorageFolder folder) + { + if (isOpen) { - if (isOpen) + RemoveAll(); + isOpen = false; + } + else + { + isOpen = true; + await LoadAll(folder); + } + } + else + if (currentItem is IStorageFile file) + { + + if (EditorProvider.TryGetEditor(extension, out var page)) { - RemoveAll(); - isOpen = false; - } - else - { - isOpen = true; - await LoadAll(folder); + 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/ITabPage.cs b/Progrart/Controls/TabSystem/ITabPage.cs index 2599e9e..e446965 100644 --- a/Progrart/Controls/TabSystem/ITabPage.cs +++ b/Progrart/Controls/TabSystem/ITabPage.cs @@ -9,7 +9,5 @@ namespace Progrart.Controls.TabSystem void SetHost(TabHost host); void BindButton(TabButton button); bool IsModified(); - void Save(); - void Execute(); } } diff --git a/Progrart/Pages/EditorPage.axaml b/Progrart/Pages/EditorPage.axaml index e5e7302..b80c512 100644 --- a/Progrart/Pages/EditorPage.axaml +++ b/Progrart/Pages/EditorPage.axaml @@ -5,7 +5,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="Progrart.Pages.EditorPage"> - + FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace"/> diff --git a/Progrart/Pages/EditorPage.axaml.cs b/Progrart/Pages/EditorPage.axaml.cs index 221375b..da04416 100644 --- a/Progrart/Pages/EditorPage.axaml.cs +++ b/Progrart/Pages/EditorPage.axaml.cs @@ -1,11 +1,15 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; +using Avalonia.Platform.Storage; +using Avalonia.Threading; using Progrart.Controls.TabSystem; +using System.IO; +using System.Threading.Tasks; namespace Progrart.Pages; -public partial class EditorPage : UserControl, ITabPage +public partial class EditorPage : UserControl, ITabPage, IEditorPage { public EditorPage() { @@ -14,7 +18,7 @@ public partial class EditorPage : UserControl, ITabPage public void BindButton(TabButton button) { - button.Title="Editor Page"; + button.Title = "Editor Page"; } public void Execute() @@ -26,6 +30,20 @@ public partial class EditorPage : UserControl, ITabPage return false; } + public void LoadDocument(IStorageFile file) + { + Task.Run(async () => + { + using var stream = await file.OpenReadAsync(); + using StreamReader sr = new StreamReader(stream); + var text = sr.ReadToEnd(); + Dispatcher.UIThread.Invoke(() => + { + CodeEditBox.Text = text; + }); + }); + } + public void Save() { } diff --git a/Progrart/Pages/EditorProvider.cs b/Progrart/Pages/EditorProvider.cs new file mode 100644 index 0000000..b5fcc5b --- /dev/null +++ b/Progrart/Pages/EditorProvider.cs @@ -0,0 +1,60 @@ +using Avalonia.Controls; +using Avalonia.Platform.Storage; +using Progrart.Controls.TabSystem; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +namespace Progrart.Pages +{ + static public class EditorProvider + { + static Dictionary Names = new(); + static Dictionary ExtensionMapping = new(); + static Dictionary EditorTypes = new(); + static TabHost? currentHost = null; + public static void setHost(TabHost host) + { + currentHost = host; + } + public static void Register(string id, string name, Type t) + { + Names[id] = name; + EditorTypes[id] = t; + } + public static void BindFileType(string type, string id) + { + ExtensionMapping[type] = id; + } + public static void OpenEditor(ITabPage page) + { + currentHost?.AddPage(page); + } + public static bool TryGetEditor(string extension, [MaybeNullWhen(false)] out Control editorPage) + { + if (ExtensionMapping.TryGetValue(extension.ToLower(), out var id)) + { + + if (EditorTypes.TryGetValue(id, out var editorType)) + { + var obj = Activator.CreateInstance(editorType); + if (obj is Control control) + { + editorPage = control; + return true; + } + } + } + editorPage = null; + return false; + } + } + public interface IEditorPage + { + void LoadDocument(IStorageFile file); + void Save(); + void Execute(); + } +} \ No newline at end of file diff --git a/Progrart/Views/MainView.axaml.cs b/Progrart/Views/MainView.axaml.cs index e4af9c8..bc2e123 100644 --- a/Progrart/Views/MainView.axaml.cs +++ b/Progrart/Views/MainView.axaml.cs @@ -30,7 +30,7 @@ public partial class MainView : UserControl } }; Trace.Listeners.Add(new ConsoleLogger()); - + EditorProvider.setHost(MainTabHost); BottomPanelToggle.IsCheckedChanged += (a, b) => { bool v = BottomPanelToggle.IsChecked == true;