Implemented an image viewer.

This commit is contained in:
Creeper Lv
2025-12-21 22:45:07 +11:00
parent 40f35ddf63
commit b47fe42a0b
13 changed files with 167 additions and 10 deletions

View File

@@ -20,6 +20,7 @@
<PackageVersion Include="Jint" Version="4.4.2" />
<PackageVersion Include="Microsoft.Maui.Graphics" Version="10.0.11" />
<PackageVersion Include="Microsoft.Maui.Graphics.Skia" Version="10.0.11" />
<PackageVersion Include="PanAndZoom" Version="11.3.6" />
<PackageVersion Include="SkiaSharp.NativeAssets.WebAssembly" Version="3.116.1" />
<PackageVersion Include="Xamarin.AndroidX.Core.SplashScreen" Version="1.0.1.15" />
</ItemGroup>

View File

@@ -22,15 +22,22 @@ public partial class App : Application
{
IconProvider.Register(new DefaultIconProvider());
EditorProvider.Register("text", "Default Text Editor", typeof(EditorPage));
EditorProvider.Register("image", "Default Image Viewer", typeof(ImageViewPage));
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("ini", "text");
EditorProvider.BindFileType("cpp", "text");
EditorProvider.BindFileType("json", "text");
EditorProvider.BindFileType("sh", "text");
EditorProvider.BindFileType("progrart", "text");
EditorProvider.BindFileType("bashrc", "text");
EditorProvider.BindFileType("png", "image");
EditorProvider.BindFileType("bmp", "image");
EditorProvider.BindFileType("jpg", "image");
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.

View File

@@ -0,0 +1,18 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:paz="using:Avalonia.Controls.PanAndZoom"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Controls.ImageViewer">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<paz:ZoomBorder Name="ZoomBorder" Stretch="Uniform" ZoomSpeed="1.2"
Background="Transparent" ClipToBounds="True" Focusable="True"
EnableGestures="True" EnablePan="True" EnableZoom="True"
EnableConstrains="True"
EnableGestureTranslation="True" EnableGestureZoom="True"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Image Name="ImagePresenter"></Image>
</paz:ZoomBorder>
</ScrollViewer>
</UserControl>

View File

@@ -0,0 +1,21 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging;
namespace Progrart.Controls;
public partial class ImageViewer : UserControl
{
public ImageViewer()
{
InitializeComponent();
}
public void SetImage(Bitmap image)
{
ImagePresenter.Source = image;
ImagePresenter.Width = image.Size.Width;
ImagePresenter.Height = image.Size.Height;
}
}

View File

@@ -34,6 +34,22 @@ namespace Progrart.Icons
icon = _icon;
return true;
}
case "ini":
{
PathIcon _icon = new PathIcon();
_icon.Data = PathGeometry.Parse("F1 M 6 3.799999 C 5.44 3.799999 4.966666 3.993334 4.58 4.379999 C 4.193333 4.766666 4 5.24 4 5.799999 L 4 9.999999 C 4.32 9.92 4.653333 9.866667 5 9.839999 L 5 5.799999 C 5 5.533333 5.099999 5.299999 5.3 5.1 C 5.5 4.9 5.733333 4.799999 6 4.799999 L 10 4.799999 L 10 8.28 C 10 8.706667 10.146666 9.066667 10.44 9.36 C 10.733334 9.653334 11.093333 9.799999 11.52 9.799999 L 15 9.799999 L 15 17.799999 C 14.999999 18.066666 14.9 18.299999 14.7 18.5 C 14.5 18.699999 14.266666 18.799999 14 18.799999 L 9.76 18.799999 C 9.44 19.173332 9.079999 19.506666 8.679999 19.799999 L 14 19.799999 C 14.559999 19.799999 15.033333 19.606667 15.42 19.219999 C 15.806666 18.833332 16 18.360001 16 17.799999 L 16 9.2 C 16 8.8 15.853333 8.453333 15.559999 8.16 L 11.639999 4.24 C 11.346666 3.946667 11 3.799999 10.599999 3.799999 Z M 14.799999 8.799999 L 11.52 8.799999 C 11.36 8.799999 11.233333 8.753333 11.139999 8.66 C 11.046666 8.566667 11 8.453333 11 8.32 L 11 5 Z M 3.08 12.24 C 3.213333 12.773333 3.14 13.286667 2.86 13.78 C 2.58 14.273333 2.173333 14.586666 1.64 14.719999 L 1.16 14.839999 C 1.133333 15.186666 1.146667 15.52 1.2 15.839999 L 1.52 15.92 C 2.08 16.053333 2.506666 16.373333 2.8 16.879999 C 3.093333 17.386665 3.16 17.906666 3 18.439999 L 2.88 18.879999 C 3.12 19.093332 3.386667 19.266666 3.68 19.4 L 4.04 19.039999 C 4.413333 18.639999 4.893333 18.439999 5.48 18.439999 C 6.066666 18.439999 6.546666 18.639999 6.92 19.039999 L 7.28 19.4 C 7.573333 19.266666 7.839999 19.106667 8.08 18.92 L 7.92 18.359999 C 7.786666 17.826666 7.859999 17.313332 8.139999 16.82 C 8.419999 16.326666 8.826666 16.013332 9.36 15.879999 L 9.84 15.759999 C 9.866667 15.413333 9.853333 15.08 9.8 14.759999 L 9.48 14.679999 C 8.919999 14.546666 8.493333 14.226666 8.2 13.719999 C 7.906666 13.213333 7.839999 12.693333 8 12.16 L 8.12 11.719999 C 7.879999 11.506666 7.613333 11.333334 7.32 11.2 L 6.96 11.559999 C 6.586666 11.96 6.106666 12.16 5.52 12.16 C 4.933333 12.16 4.453333 11.96 4.08 11.559999 L 3.72 11.2 C 3.426666 11.333334 3.16 11.493334 2.92 11.679999 Z M 5.48 16.279999 C 5.213333 16.279999 4.98 16.186666 4.78 16 C 4.58 15.813334 4.48 15.58 4.48 15.299999 C 4.48 15.02 4.58 14.786666 4.78 14.599999 C 4.98 14.413333 5.22 14.313334 5.5 14.299999 C 5.78 14.286667 6.013333 14.379999 6.2 14.58 C 6.386666 14.779999 6.48 15.02 6.48 15.299999 C 6.48 15.58 6.386666 15.813334 6.2 16 C 6.013333 16.186666 5.773333 16.279999 5.48 16.279999 Z ");
icon = _icon;
return true;
}
case "png":
case "jpg":
case "bmp":
{
PathIcon _icon = new PathIcon();
_icon.Data = PathGeometry.Parse("F1 M 14 9.28 C 14 9.706667 13.853333 10.066667 13.559999 10.36 C 13.266666 10.653333 12.913333 10.799999 12.5 10.799999 C 12.086666 10.799999 11.733333 10.653333 11.44 10.36 C 11.146667 10.066667 11 9.713333 11 9.299999 C 11 8.886666 11.146667 8.533333 11.44 8.24 C 11.733333 7.946667 12.086666 7.799999 12.5 7.799999 C 12.913333 7.799999 13.266666 7.946667 13.559999 8.24 C 13.853333 8.533333 14 8.893333 14 9.32 Z M 13 9.28 C 13 9.146667 12.953333 9.033334 12.86 8.94 C 12.766665 8.846666 12.646666 8.799999 12.5 8.799999 C 12.353333 8.799999 12.233332 8.846666 12.139999 8.94 C 12.046666 9.033334 12 9.153334 12 9.299999 C 12 9.446667 12.046666 9.566668 12.139999 9.66 C 12.233332 9.753333 12.353333 9.799999 12.5 9.799999 C 12.646666 9.799999 12.766665 9.753333 12.86 9.66 C 12.953333 9.566668 13 9.453334 13 9.32 Z M 3 7.799999 C 3 6.973333 3.293333 6.266667 3.88 5.68 C 4.466666 5.093334 5.173333 4.799999 6 4.799999 L 14 4.799999 C 14.826666 4.799999 15.533332 5.093334 16.119999 5.68 C 16.706665 6.266667 17 6.973333 17 7.799999 L 17 15.799999 C 17 16.626667 16.706665 17.333332 16.119999 17.92 C 15.533332 18.506666 14.826666 18.799999 14 18.799999 L 6 18.799999 C 5.173333 18.799999 4.466666 18.506666 3.88 17.92 C 3.293333 17.333332 3 16.626667 3 15.799999 Z M 6 5.799999 C 5.44 5.799999 4.966666 5.993333 4.58 6.379999 C 4.193333 6.766666 4 7.24 4 7.799999 L 4 15.799999 C 4 16.173332 4.093333 16.52 4.28 16.84 L 8.96 12.24 C 9.253332 11.946667 9.599999 11.799999 10 11.799999 C 10.4 11.799999 10.746666 11.946667 11.04 12.24 L 15.719999 16.799999 C 15.906666 16.506666 16 16.173332 16 15.799999 L 16 7.799999 C 16 7.24 15.806666 6.766666 15.42 6.379999 C 15.033333 5.993333 14.559999 5.799999 14 5.799999 Z M 6 17.799999 L 14 17.799999 C 14.373333 17.799999 14.706666 17.706665 15 17.52 L 10.36 12.959999 C 10.253332 12.853333 10.133333 12.799999 10 12.799999 C 9.866667 12.799999 9.746666 12.853333 9.639999 12.959999 L 5 17.52 C 5.293333 17.706665 5.626667 17.799999 6 17.799999 Z ");
icon = _icon;
return true;
}
default:
break;
}

View File

@@ -8,6 +8,9 @@
<StackPanel>
<TextBlock FontSize="36" TextAlignment="Center" Margin="0,50">Progrart</TextBlock>
<TextBlock FontSize="18" TextAlignment="Center">Version: 0.0.0.0-preview</TextBlock>
<TextBlock FontSize="24" TextAlignment="Center" Margin="0,25">Third-Party Libs</TextBlock>
<TextBlock FontSize="17" TextAlignment="Center">Avalonia - github.com/avaloniaui</TextBlock>
<TextBlock FontSize="17" TextAlignment="Center">PanAndZoom - GitHub - wieslawsoltes/PanAndZoom</TextBlock>
</StackPanel>
</ScrollViewer>
</UserControl>

View File

@@ -30,7 +30,7 @@ public partial class EditorPage : UserControl, ITabPage, IEditorPage
}
}
public void Execute()
public void Execute(ExecuteArguments? args = null)
{
}

View File

@@ -55,6 +55,6 @@ namespace Progrart.Pages
{
void LoadDocument(IStorageFile file);
void Save();
void Execute();
void Execute(ExecuteArguments? args = null);
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Progrart.Pages
{
public class ExecuteArguments
{
public Dictionary<string, string> data = new Dictionary<string, string>();
}
}

View File

@@ -0,0 +1,9 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:controls="using:Progrart.Controls"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.Pages.ImageViewPage">
<controls:ImageViewer Name="ImageViewer"/>
</UserControl>

View File

@@ -0,0 +1,54 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Media.Imaging;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using Progrart.Controls.TabSystem;
using System.Threading.Tasks;
namespace Progrart.Pages;
public partial class ImageViewPage : UserControl, ITabPage, IEditorPage
{
public ImageViewPage()
{
InitializeComponent();
}
TabButton? TabButton = null;
public void BindButton(TabButton button)
{
TabButton = button;
TabButton.Title = "Image";
}
public void Execute(ExecuteArguments? args = null)
{
}
public bool IsModified()
{
return false;
}
public void LoadDocument(IStorageFile file)
{
Task.Run(async () =>
{
using var fs = await file.OpenReadAsync();
Bitmap bitmap = new Bitmap(fs);
Dispatcher.UIThread.Invoke(() => {
this.ImageViewer.SetImage(bitmap);
});
});
}
public void Save()
{
}
public void SetHost(TabHost host)
{
}
}

View File

@@ -1,8 +1,26 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:avaloniaedit="https://github.com/avaloniaui/avaloniaedit"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Progrart.ProgrartEditorPage">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<avaloniaedit:TextEditor Name="CodeEditBox" Text="" SyntaxHighlighting="JavaScript"
ShowLineNumbers="True"
FontFamily="Sarasa Mono Slab CL,Cascadia Code,Consolas,Menlo,Monospace"/>
<Grid Name="VerticalSplitterVisualElement">
<Border Width="2" Background="#8888"></Border>
</Grid>
<GridSplitter Grid.Column="1"/>
<Grid Name="PreviewHolder">
</Grid>
</Grid>
</UserControl>

View File

@@ -20,6 +20,7 @@
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="PanAndZoom" />
<!--<PackageReference Include="Devolutions.AvaloniaTheme.DevExpress" />
<PackageReference Include="Devolutions.AvaloniaTheme.MacOS" />-->
</ItemGroup>