Implemented editor providers.

This commit is contained in:
Creeper Lv
2025-12-18 01:28:15 +11:00
parent daa2a74e71
commit 76caa0d644
8 changed files with 135 additions and 20 deletions

View File

@@ -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();
}

View File

@@ -10,7 +10,7 @@
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="_Open"/>
<MenuItem Header="_Open" Name="OpenFileMenuItem"/>
<MenuItem Header="_Delete"/>
</ContextMenu>
</Button.ContextMenu>

View File

@@ -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)
{

View File

@@ -9,7 +9,5 @@ namespace Progrart.Controls.TabSystem
void SetHost(TabHost host);
void BindButton(TabButton button);
bool IsModified();
void Save();
void Execute();
}
}

View File

@@ -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">
<avaloniaedit:TextEditor Name="CodePane" Text="" SyntaxHighlighting="JavaScript"
<avaloniaedit:TextEditor Name="CodeEditBox" Text="" SyntaxHighlighting="JavaScript"
ShowLineNumbers="True"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"/>
FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace"/>
</UserControl>

View File

@@ -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()
{
}

View File

@@ -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<string, string> Names = new();
static Dictionary<string, string> ExtensionMapping = new();
static Dictionary<string, Type> 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();
}
}

View File

@@ -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;