diff --git a/Progrart/App.axaml.cs b/Progrart/App.axaml.cs index f2bfb1d..e54faf3 100644 --- a/Progrart/App.axaml.cs +++ b/Progrart/App.axaml.cs @@ -5,13 +5,17 @@ using Avalonia.Data.Core.Plugins; using Avalonia.Markup.Xaml; using Avalonia.Platform.Storage; using Microsoft.Extensions.Configuration; +using Newtonsoft.Json; +using Progrart.Core; using Progrart.Core.ProjectSystem; using Progrart.Core.Settings; using Progrart.Icons; using Progrart.Pages; using Progrart.Views; using System; +using System.IO; using System.Linq; +using System.Threading.Tasks; namespace Progrart; @@ -30,14 +34,27 @@ public partial class App : Application { AvaloniaXamlLoader.Load(this); } + public async Task LoadProject(IStorageFile item) + { + + using var stream = await (item).OpenReadAsync(); + using var reader = new StreamReader(stream); + var txt = await reader.ReadToEndAsync(); + App.LoadedProject = JsonConvert.DeserializeObject(txt); + } public override void OnFrameworkInitializationCompleted() { IconProvider.Register(new DefaultIconProvider()); - EditorProvider.Register("text", "Default Text Editor", typeof(EditorPage)); - EditorProvider.Register("image", "Default Image Viewer", typeof(ImageViewPage)); - EditorProvider.Register("progrart", "Default Progrart Editor", typeof(ProgrartEditorPage)); - EditorProvider.Register("project", "Progrart Project Editor", typeof(ProjectEditor)); - EditorProvider.Register("console", "Console", typeof(Pages.Console)); + EditorProvider.Register("text", new EditorFileHandler("Default Text Editor")); + EditorProvider.Register("image", new EditorFileHandler("Default Image Viewer")); + EditorProvider.Register("progrart", new EditorFileHandler("Default Progrart Editor")); + EditorProvider.Register("as_project", new FileHandler("Load Project",async (item) => + { + await LoadProject(item); + ProjectLoadHandler?.Invoke(); + })); + EditorProvider.Register("project_editor", new EditorFileHandler("Progrart Project Editor")); + EditorProvider.Register("console", new EditorFileHandler("Console")); EditorProvider.BindFileType("cs", "text"); EditorProvider.BindFileType("c", "text"); EditorProvider.BindFileType("cpp", "text"); @@ -49,11 +66,14 @@ public partial class App : Application EditorProvider.BindFileType("json", "text"); EditorProvider.BindFileType("sh", "text"); EditorProvider.BindFileType("progrart", "progrart"); + EditorProvider.BindFileType("progrart", "text"); EditorProvider.BindFileType("bashrc", "text"); EditorProvider.BindFileType("png", "image"); EditorProvider.BindFileType("bmp", "image"); EditorProvider.BindFileType("jpg", "image"); - EditorProvider.BindFileType("progrart-project", "project"); + EditorProvider.BindFileType("progrart-project", "as_project"); + EditorProvider.BindFileType("progrart-project", "project_editor"); + EditorProvider.BindFileType("progrart-project", "text"); EditorProvider.BindFileType("wd", "console"); if (!OperatingSystem.IsBrowser()) { diff --git a/Progrart/Controls/BaseEditor.axaml b/Progrart/Controls/BaseEditor.axaml index 27d0980..ea5772f 100644 --- a/Progrart/Controls/BaseEditor.axaml +++ b/Progrart/Controls/BaseEditor.axaml @@ -10,11 +10,37 @@ FontFamily="{StaticResource SarasaMonoSlabCLFont}"> - - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + diff --git a/Progrart/Controls/BaseEditor.axaml.cs b/Progrart/Controls/BaseEditor.axaml.cs index 5ca6b76..03fe5c3 100644 --- a/Progrart/Controls/BaseEditor.axaml.cs +++ b/Progrart/Controls/BaseEditor.axaml.cs @@ -33,13 +33,13 @@ public partial class BaseEditor : UserControl InitializeComponent(); var uri = new Uri("avares://Progrart/Assets/Styles/JavaScript.xml"); - if (AssetLoader.Exists(uri)) - { - using Stream stream = AssetLoader.Open(uri); - using XmlReader reader = XmlReader.Create(stream); - var xshd = HighlightingLoader.LoadXshd(reader); - CodeEditBox.SyntaxHighlighting = HighlightingLoader.Load(xshd, HighlightingManager.Instance); - } + if (AssetLoader.Exists(uri)) + { + using Stream stream = AssetLoader.Open(uri); + using XmlReader reader = XmlReader.Create(stream); + var xshd = HighlightingLoader.LoadXshd(reader); + CodeEditBox.SyntaxHighlighting = HighlightingLoader.Load(xshd, HighlightingManager.Instance); + } if (!OperatingSystem.IsBrowser()) { { @@ -68,11 +68,19 @@ public partial class BaseEditor : UserControl { return; } - _textMateInstallation?.SetGrammar( - _registryOptions?.GetScopeByLanguageId( - _registryOptions.GetLanguageByExtension(extension_name).Id - ) - ); + if (extension_name == ".progrart") extension_name = ".js"; + if (extension_name == ".progrart-project") extension_name = ".json"; + try + { + _textMateInstallation?.SetGrammar( + _registryOptions?.GetScopeByLanguageId( + _registryOptions.GetLanguageByExtension(extension_name).Id + ) + ); + } + catch (Exception) + { + } } diff --git a/Progrart/Controls/FileItem.axaml b/Progrart/Controls/FileItem.axaml index a4c477b..fd5b21d 100644 --- a/Progrart/Controls/FileItem.axaml +++ b/Progrart/Controls/FileItem.axaml @@ -10,7 +10,21 @@ - + + + + + + + + + + + + + + + diff --git a/Progrart/Controls/FileItem.axaml.cs b/Progrart/Controls/FileItem.axaml.cs index cb36597..0bebd8d 100644 --- a/Progrart/Controls/FileItem.axaml.cs +++ b/Progrart/Controls/FileItem.axaml.cs @@ -32,6 +32,7 @@ public partial class FileItem : UserControl FolderIcon.IsVisible = true; GenericFileIcon.IsVisible = false; IconContainer.IsVisible = false; + OpenWithMenu.IsVisible = false; } else if (storageItem is IStorageFile file) { @@ -48,17 +49,27 @@ public partial class FileItem : UserControl GenericFileIcon.IsVisible = false; IconContainer.Children.Add(icon); } + foreach (var item in EditorProvider.GetHandlerCollection(extension)) + { + MenuItem mItem = new() { Header = item.Name }; + mItem.Click += async (a, b) => + { + if (item.OpenAction is not null) + await item.OpenAction(file); + }; + OpenWithMenu.Items.Add(mItem); + } } IconContainer.IsVisible = true; } NameBlock.Text = storageItem.Name; MainButton.DoubleTapped += async (_, _) => { - OpenItem(); + await OpenItem(); }; OpenFileMenuItem.Click += async (a, b) => { - OpenItem(); + await OpenItem(); }; CreateFolderItem.Click += async (a, b) => { @@ -133,7 +144,7 @@ public partial class FileItem : UserControl await DialogHost.Show(content); }; } - void OpenItem() + public async Task OpenItem() { if (currentItem is IStorageFolder folder) @@ -146,7 +157,7 @@ public partial class FileItem : UserControl else { isOpen = true; - Task.Run(async () => + await Task.Run(async () => { await LoadAll(folder); }); @@ -161,23 +172,25 @@ public partial class FileItem : UserControl EditorProvider.SelectTabPage(btn); } else - if (EditorProvider.TryGetEditor(extension, out var page)) + if (EditorProvider.TryGetHandler(extension, out var page)) { - if (page is ITabPage editor) - { - try - { - if (page is IEditorPage editor_page) - { - editor_page.LoadDocument(file); - } - EditorProvider.OpenEditor(editor); - } - catch (System.Exception e) - { - Trace.WriteLine(e); - } - } + if (page.OpenAction is not null) + await page.OpenAction(file); + //if (page is ITabPage editor) + //{ + // try + // { + // if (page is IEditorPage editor_page) + // { + // editor_page.LoadDocument(file); + // } + // EditorProvider.OpenEditor(editor); + // } + // catch (System.Exception e) + // { + // Trace.WriteLine(e); + // } + //} } } } diff --git a/Progrart/Controls/TabSystem/TabButton.axaml.cs b/Progrart/Controls/TabSystem/TabButton.axaml.cs index 9240ae7..45aca55 100644 --- a/Progrart/Controls/TabSystem/TabButton.axaml.cs +++ b/Progrart/Controls/TabSystem/TabButton.axaml.cs @@ -8,8 +8,8 @@ public partial class TabButton : UserControl { public string? Title { get => MainButton.Content as string; set => MainButton.Content = value; } public string? TooltipText { get => ToolTip.GetTip(MainButton) as string; set => ToolTip.SetTip(MainButton, value); } - public ITabPage? page=null; - public TabHost? Host=null; + public ITabPage? page = null; + public TabHost? Host = null; public TabButton() { InitializeComponent(); @@ -36,6 +36,12 @@ public partial class TabButton : UserControl Host.RemoveButton(this); }; } + public bool IsVisibleInHost() + { + if (page is Control pageControl) + return pageControl.IsVisible; + return false; + } public void SetSelectState(bool v) { if (page is Control pageControl) diff --git a/Progrart/Controls/TabSystem/TabHost.axaml.cs b/Progrart/Controls/TabSystem/TabHost.axaml.cs index b088357..6b21cf7 100644 --- a/Progrart/Controls/TabSystem/TabHost.axaml.cs +++ b/Progrart/Controls/TabSystem/TabHost.axaml.cs @@ -63,10 +63,47 @@ public partial class TabHost : UserControl itemBtn.SetSelectState(item == button); } } + public void SelectButton(int index) + { + for (int i = 0; i < TabContainer.Children.Count; i++) + { + Control? item = TabContainer.Children[i]; + if (item is TabButton itemBtn) + itemBtn.SetSelectState(i == index); + } + } + private int GetOpenIndex() + { + for (int i = 0; i < TabContainer.Children.Count; i++) + { + Control item = TabContainer.Children[i]; + if (item is TabButton itemBtn) + { + if (itemBtn.IsVisibleInHost()) return i; + } + } + return -1; + } public void RemoveButton(TabButton button) { + var index = TabContainer.Children.IndexOf(button); + int v = GetOpenIndex(); TabContainer.Children.Remove(button); if (button.page is Control pageControl) PageContainer.Children.Remove(pageControl); + + if (index == v) + { + if (index - 1 > 0) + SelectButton(index - 1); + else + { + SelectButton(1); + } + } + if (v == -1) + { + SelectButton(0); + } } } \ No newline at end of file diff --git a/Progrart/Core/FileHandler.cs b/Progrart/Core/FileHandler.cs new file mode 100644 index 0000000..3f16ce2 --- /dev/null +++ b/Progrart/Core/FileHandler.cs @@ -0,0 +1,36 @@ +using Avalonia.Platform.Storage; +using Progrart.Controls.TabSystem; +using Progrart.Pages; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace Progrart.Core +{ + public class FileHandler + { + public string Name = ""; + public Func? OpenAction = null; + + public FileHandler(string name, Func? openAction) + { + Name = name; + OpenAction = openAction; + } + } + public class EditorFileHandler : FileHandler where T : IEditorPage, ITabPage + { + public EditorFileHandler(string name) : base(name, async (item) => + { + if (item is IStorageFile file) + { + var page = (T)Activator.CreateInstance(typeof(T))!; + page.LoadDocument(file); + EditorProvider.OpenEditor(page); + } + }) + { + } + } +} diff --git a/Progrart/Pages/EditorProvider.cs b/Progrart/Pages/EditorProvider.cs index a0a0f52..b1aae54 100644 --- a/Progrart/Pages/EditorProvider.cs +++ b/Progrart/Pages/EditorProvider.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,22 +14,28 @@ namespace Progrart.Pages { static public class EditorProvider { - static Dictionary Names = new(); - static Dictionary ExtensionMapping = new(); - static Dictionary EditorTypes = new(); + static Dictionary handlers = 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) + public static void Register(string id, FileHandler handler) { - Names[id] = name; - EditorTypes[id] = t; + handlers[id] = handler; } public static void BindFileType(string type, string id) { - ExtensionMapping[type] = id; + if (ExtensionMapping.TryGetValue(type, out var list)) + { + list.Add(id); + } + else + { + ExtensionMapping[type] = [id]; + } } public static TabButton? IsOpen(IStorageFile file) { @@ -42,24 +49,33 @@ namespace Progrart.Pages { currentHost?.AddPage(page); } - public static bool TryGetEditor(string extension, [MaybeNullWhen(false)] out Control editorPage) + + public static bool TryGetHandler(string extension, [MaybeNullWhen(false)] out FileHandler handler) { if (ExtensionMapping.TryGetValue(extension.ToLower(), out var id)) { - if (EditorTypes.TryGetValue(id, out var editorType)) + if (handlers.TryGetValue(id.First(), out var editorType)) { - var obj = Activator.CreateInstance(editorType); - if (obj is Control control) - { - editorPage = control; - return true; - } + handler = editorType; + return true; } } - editorPage = null; + handler = null; return false; } + public static List GetHandlerCollection(string extension) + { + List handlersList = new(); + if (ExtensionMapping.TryGetValue(extension.ToLower(), out var id)) + { + foreach (var item in id) + { + handlersList.Add(handlers[item]); + } + } + return handlersList; + } } public interface IEditorPage { diff --git a/Progrart/Views/MainView.axaml.cs b/Progrart/Views/MainView.axaml.cs index bbaa7d3..a4c60ac 100644 --- a/Progrart/Views/MainView.axaml.cs +++ b/Progrart/Views/MainView.axaml.cs @@ -109,7 +109,8 @@ public partial class MainView : UserControl FileContainer.Children.Clear(); var folder = folders[0]; App.CurrentOpenFolder = folder; - FileContainer.Children.Add(new FileItem(folder)); + FileItem item1 = new(folder); + FileContainer.Children.Add(item1); await foreach (var item in folder.GetItemsAsync()) { if (item.Name.ToLower().EndsWith(".progrart-project", StringComparison.OrdinalIgnoreCase)) @@ -122,6 +123,7 @@ public partial class MainView : UserControl break; } } + await item1.OpenItem(); } }; FileExplorerCloseButton.Click += (_, _) =>