FileItem will no longer open more than 1 tab for a file.

Added Ctrl+S shortcut in BaseEditor.
This commit is contained in:
Creeper Lv
2025-12-28 23:23:33 +11:00
parent ac5053a5df
commit 25efa1127f
8 changed files with 136 additions and 39 deletions

View File

@@ -7,5 +7,13 @@
x:Class="Progrart.Controls.BaseEditor"> x:Class="Progrart.Controls.BaseEditor">
<avaloniaedit:TextEditor Name="CodeEditBox" Text="" SyntaxHighlighting="JavaScript" <avaloniaedit:TextEditor Name="CodeEditBox" Text="" SyntaxHighlighting="JavaScript"
ShowLineNumbers="True" ShowLineNumbers="True"
FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace"/> FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace">
<avaloniaedit:TextEditor.ContextMenu>
<ContextMenu>
<MenuItem Name="Copy" Click="Copy_Click"/>
<MenuItem Name="Cut" Click="Cut_Click"/>
<MenuItem Name="Paste" Click="Paste_Click"/>
</ContextMenu>
</avaloniaedit:TextEditor.ContextMenu>
</avaloniaedit:TextEditor>
</UserControl> </UserControl>

View File

@@ -1,37 +1,82 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using AvaloniaEdit;
using AvaloniaEdit.TextMate; using AvaloniaEdit.TextMate;
using System;
using System.Windows.Input;
using TextMateSharp.Grammars; using TextMateSharp.Grammars;
namespace Progrart.Controls; namespace Progrart.Controls;
public partial class BaseEditor : UserControl public partial class BaseEditor : UserControl
{ {
RegistryOptions _registryOptions; RegistryOptions _registryOptions;
TextMate.Installation _textMateInstallation; TextMate.Installation _textMateInstallation;
public string Text public string Text
{ {
get => CodeEditBox.Text; get => CodeEditBox.Text;
set => CodeEditBox.Text = value; set => CodeEditBox.Text = value;
} }
public BaseEditor() public Action? onSaveCmd;
{ public BaseEditor()
InitializeComponent(); {
{ InitializeComponent();
var _textEditor = CodeEditBox; {
_registryOptions = new RegistryOptions(ThemeName.DarkPlus); var _textEditor = CodeEditBox;
_textMateInstallation = _textEditor.InstallTextMate(_registryOptions); _registryOptions = new RegistryOptions(ThemeName.DarkPlus);
_textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id)); _textMateInstallation = _textEditor.InstallTextMate(_registryOptions);
} _textMateInstallation.SetGrammar(_registryOptions.GetScopeByLanguageId(_registryOptions.GetLanguageByExtension(".js").Id));
} }
public void SetGrammerByExtension(string extension_name) var saveBinding = new KeyBinding
{ {
_textMateInstallation.SetGrammar( Gesture = new KeyGesture(Key.S, KeyModifiers.Control),
_registryOptions.GetScopeByLanguageId( Command = new saveCmd() { onSave = Save }
_registryOptions.GetLanguageByExtension(extension_name).Id };
)
);
} 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();
}
} }

View File

@@ -149,18 +149,23 @@ public partial class FileItem : UserControl
else else
if (currentItem is IStorageFile file) if (currentItem is IStorageFile file)
{ {
var btn = EditorProvider.IsOpen(file);
if (EditorProvider.TryGetEditor(extension, out var page)) if (btn is not null)
{ {
if (page is ITabPage editor) EditorProvider.SelectTabPage(btn);
{
if (page is IEditorPage editor_page)
{
editor_page.LoadDocument(file);
}
EditorProvider.OpenEditor(editor);
}
} }
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) async Task LoadAll(IStorageFolder folder)

View File

@@ -1,6 +1,8 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using Progrart.Pages;
namespace Progrart.Controls.TabSystem; namespace Progrart.Controls.TabSystem;
@@ -30,6 +32,17 @@ public partial class TabHost : UserControl
page.BindButton(button); page.BindButton(button);
SelectButton(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) public void SelectButton(TabButton button)
{ {
foreach (var item in TabContainer.Children) foreach (var item in TabContainer.Children)

View File

@@ -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) public void BindButton(TabButton button)
{ {
btn = button; btn = button;

View File

@@ -29,6 +29,14 @@ namespace Progrart.Pages
{ {
ExtensionMapping[type] = id; 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) public static void OpenEditor(ITabPage page)
{ {
currentHost?.AddPage(page); currentHost?.AddPage(page);
@@ -56,6 +64,7 @@ namespace Progrart.Pages
{ {
void LoadDocument(IStorageFile file); void LoadDocument(IStorageFile file);
void Save(); void Save();
bool IsSameFile(IStorageFile file);
void Execute(ExecuteArguments? args = null); void Execute(ExecuteArguments? args = null);
} }
} }

View File

@@ -12,6 +12,7 @@ namespace Progrart.Pages;
public partial class ImageViewPage : UserControl, ITabPage, IEditorPage public partial class ImageViewPage : UserControl, ITabPage, IEditorPage
{ {
IStorageFile? file;
public ImageViewPage() public ImageViewPage()
{ {
InitializeComponent(); InitializeComponent();
@@ -31,15 +32,16 @@ public partial class ImageViewPage : UserControl, ITabPage, IEditorPage
{ {
return false; return false;
} }
public void LoadDocument(IStorageFile file) public void LoadDocument(IStorageFile file)
{ {
this.file = file;
Task.Run(async () => Task.Run(async () =>
{ {
using var fs = await file.OpenReadAsync(); using var fs = await file.OpenReadAsync();
Bitmap bitmap = new Bitmap(fs); Bitmap bitmap = new Bitmap(fs);
Dispatcher.UIThread.Invoke(() => { Dispatcher.UIThread.Invoke(() =>
{
this.ImageViewer.SetImage(bitmap); this.ImageViewer.SetImage(bitmap);
}); });
}); });
@@ -52,4 +54,9 @@ public partial class ImageViewPage : UserControl, ITabPage, IEditorPage
public void SetHost(TabHost host) public void SetHost(TabHost host)
{ {
} }
public bool IsSameFile(IStorageFile file)
{
return (this.file?.Path == file.Path);
}
} }

View File

@@ -21,6 +21,7 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage
public ProgrartEditorPage() public ProgrartEditorPage()
{ {
InitializeComponent(); InitializeComponent();
CodeEditor.onSaveCmd = Save;
} }
public void BindButton(TabButton button) public void BindButton(TabButton button)
@@ -72,7 +73,12 @@ public partial class ProgrartEditorPage : UserControl, ITabPage, IEditorPage
return false; 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; this.file = file;
if (btn is not null) if (btn is not null)