diff --git a/Directory.Packages.props b/Directory.Packages.props
index 844c9e7..fb997d6 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -15,11 +15,12 @@
-
-
+
+
\ No newline at end of file
diff --git a/Progrart.Browser/Progrart.Browser.csproj b/Progrart.Browser/Progrart.Browser.csproj
index b6c7274..5e25c81 100644
--- a/Progrart.Browser/Progrart.Browser.csproj
+++ b/Progrart.Browser/Progrart.Browser.csproj
@@ -3,11 +3,13 @@
net10.0-browser
Exe
true
+ true
enable
+
diff --git a/Progrart.iOS/Info.plist b/Progrart.iOS/Info.plist
index 6aeb579..a1ba03a 100644
--- a/Progrart.iOS/Info.plist
+++ b/Progrart.iOS/Info.plist
@@ -5,7 +5,7 @@
CFBundleDisplayName
Progrart
CFBundleIdentifier
- io.creeperlv.CINT
+ io.creeperlv.Progrart
CFBundleShortVersionString
1.0
CFBundleVersion
diff --git a/Progrart/App.axaml.cs b/Progrart/App.axaml.cs
index aa33770..de2c3d5 100644
--- a/Progrart/App.axaml.cs
+++ b/Progrart/App.axaml.cs
@@ -5,6 +5,7 @@ using Avalonia.Data.Core.Plugins;
using System.Linq;
using Avalonia.Markup.Xaml;
using Progrart.Views;
+using Progrart.Icons;
namespace Progrart;
@@ -23,7 +24,7 @@ public partial class App : Application
// 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 bd5f382..2bf510b 100644
--- a/Progrart/Controls/FileItem.axaml
+++ b/Progrart/Controls/FileItem.axaml
@@ -3,22 +3,35 @@
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.Controls.FileItem">
+ x:Class="Progrart.Controls.FileItem" HorizontalAlignment="Stretch">
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Progrart/Controls/FileItem.axaml.cs b/Progrart/Controls/FileItem.axaml.cs
index 26db25d..6c3134a 100644
--- a/Progrart/Controls/FileItem.axaml.cs
+++ b/Progrart/Controls/FileItem.axaml.cs
@@ -1,13 +1,70 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
+using Avalonia.Platform.Storage;
+using Progrart.Icons;
+using System.Threading.Tasks;
namespace Progrart.Controls;
public partial class FileItem : UserControl
{
- public FileItem()
- {
- InitializeComponent();
- }
+ IStorageItem currentItem;
+ bool isOpen = false;
+ public FileItem(IStorageItem storageItem)
+ {
+ InitializeComponent();
+ currentItem = storageItem;
+ if (storageItem is IStorageFolder folder)
+ {
+ FolderIcon.IsVisible = true;
+ GenericFileIcon.IsVisible = false;
+ IconContainer.IsVisible = false;
+ }
+ else if (storageItem is IStorageFile file)
+ {
+ FolderIcon.IsVisible = false;
+ GenericFileIcon.IsVisible = true;
+ IconContainer.Children.Clear();
+ var dotIndex = file.Name.LastIndexOf('.');
+ if (dotIndex >= 0)
+ {
+ var extension = file.Name[(dotIndex + 1)..];
+ if (IconProvider.TryGetIcon(extension, out var icon))
+ {
+ GenericFileIcon.IsVisible = false;
+ IconContainer.Children.Add(icon);
+ }
+ }
+ IconContainer.IsVisible = true;
+ }
+ NameBlock.Text = storageItem.Name;
+ MainButton.DoubleTapped += async (_, _) =>
+ {
+ if (currentItem is IStorageFolder folder)
+ {
+ if (isOpen)
+ {
+ RemoveAll();
+ isOpen = false;
+ }
+ else
+ {
+ isOpen = true;
+ await LoadAll(folder);
+ }
+ }
+ };
+ }
+ async Task LoadAll(IStorageFolder folder)
+ {
+ await foreach (var item in folder.GetItemsAsync())
+ {
+ ItemContainer.Children.Add(new FileItem(item));
+ }
+ }
+ void RemoveAll()
+ {
+ ItemContainer.Children.Clear();
+ }
}
\ No newline at end of file
diff --git a/Progrart/Controls/TabSystem/TabHost.axaml.cs b/Progrart/Controls/TabSystem/TabHost.axaml.cs
index 9868d2f..5ceac6a 100644
--- a/Progrart/Controls/TabSystem/TabHost.axaml.cs
+++ b/Progrart/Controls/TabSystem/TabHost.axaml.cs
@@ -16,6 +16,7 @@ public partial class TabHost : UserControl
this.TabContainer.Children.Add(button);
if (page is Control pageControl)
PageContainer.Children.Add(pageControl);
+ page.BindButton(button);
SelectButton(button);
}
public void SelectButton(TabButton button)
diff --git a/Progrart/Icons/DefaultIconProvider.cs b/Progrart/Icons/DefaultIconProvider.cs
new file mode 100644
index 0000000..3727f6b
--- /dev/null
+++ b/Progrart/Icons/DefaultIconProvider.cs
@@ -0,0 +1,44 @@
+using Avalonia.Controls;
+using Avalonia.Media;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Progrart.Icons
+{
+ public class DefaultIconProvider : IIconProvider
+ {
+ public bool TryGetIcon(string name, [MaybeNullWhen(false)] out Control icon)
+ {
+ switch (name)
+ {
+ case "c":
+ case "c++":
+ case "cpp":
+ case "cxx":
+ case "cs":
+ case "h":
+ case "h++":
+ case "hpp":
+ case "hxx":
+ {
+ PathIcon _icon = new PathIcon();
+ _icon.Data = PathGeometry.Parse("F1 M 12.96 5.48 C 13.013332 5.346666 13.013332 5.219999 12.96 5.1 C 12.906666 4.98 12.813333 4.893333 12.679999 4.84 C 12.546665 4.786667 12.419999 4.786667 12.3 4.84 C 12.179999 4.893333 12.093332 4.986668 12.04 5.119999 L 7.04 18.119999 C 6.96 18.306665 6.98 18.473333 7.1 18.619999 C 7.22 18.766666 7.38 18.826666 7.58 18.799999 C 7.779999 18.773333 7.906666 18.666666 7.96 18.48 Z M 5.84 7.919999 C 5.946666 8 6 8.113334 6 8.259999 C 6 8.406667 5.96 8.533333 5.88 8.639999 L 3.16 11.799999 L 5.88 14.959999 C 5.96 15.066667 5.993333 15.186666 5.98 15.32 C 5.966666 15.453333 5.906666 15.566667 5.8 15.66 C 5.693333 15.753333 5.573333 15.793333 5.44 15.779999 C 5.306666 15.766666 5.2 15.719999 5.12 15.639999 L 2.12 12.12 C 2.04 12.039999 2 11.933332 2 11.799999 C 2 11.666666 2.04 11.559999 2.12 11.48 L 5.12 7.959999 C 5.2 7.853333 5.313333 7.799999 5.46 7.799999 C 5.606667 7.799999 5.733333 7.839999 5.84 7.919999 Z M 14.16 16.16 C 14.053333 16.08 14 15.973333 14 15.839999 C 14 15.706667 14.04 15.586666 14.12 15.48 L 16.84 12.28 L 14.12 9.12 C 14.04 9.013333 14 8.893333 14 8.759999 C 14 8.626667 14.053333 8.513333 14.16 8.419999 C 14.266666 8.326667 14.393333 8.286667 14.54 8.299999 C 14.686666 8.313334 14.799999 8.373333 14.88 8.48 L 17.879999 11.959999 C 17.959999 12.066667 18 12.18 18 12.299999 C 18 12.42 17.959999 12.533333 17.879999 12.639999 L 14.88 16.119999 C 14.799999 16.226665 14.686666 16.286667 14.54 16.299999 C 14.393333 16.313332 14.266666 16.279999 14.16 16.199999 Z ");
+ icon = _icon;
+ return true;
+ }
+ case "sh":
+ case "bash":
+ case "ps1":
+ {
+ PathIcon _icon = new PathIcon();
+ _icon.Data = PathGeometry.Parse("F1 M 5.64 10.959999 C 5.746666 10.853333 5.866666 10.799999 6 10.799999 C 6.133333 10.799999 6.253333 10.853333 6.36 10.959999 L 8.36 12.959999 C 8.466666 13.039999 8.52 13.153333 8.52 13.299999 C 8.52 13.446667 8.466666 13.559999 8.36 13.639999 L 6.36 15.639999 C 6.253333 15.746666 6.133333 15.799999 6 15.799999 C 5.866666 15.799999 5.746666 15.753333 5.64 15.66 C 5.533333 15.566667 5.48 15.446667 5.48 15.299999 C 5.48 15.153333 5.533333 15.04 5.64 14.959999 L 7.28 13.28 L 5.64 11.639999 C 5.533333 11.559999 5.48 11.446667 5.48 11.299999 C 5.48 11.153334 5.533333 11.04 5.64 10.959999 Z M 14.52 14.799999 L 9.52 14.799999 C 9.359999 14.799999 9.233333 14.846666 9.139999 14.94 C 9.046666 15.033333 9 15.153333 9 15.299999 C 9 15.446667 9.046666 15.566667 9.139999 15.66 C 9.233333 15.753333 9.346666 15.799999 9.48 15.799999 L 14.52 15.799999 C 14.653333 15.799999 14.766666 15.753333 14.86 15.66 C 14.953333 15.566667 14.999999 15.446667 15 15.299999 C 14.999999 15.153333 14.953333 15.033333 14.86 14.94 C 14.766666 14.846666 14.653333 14.799999 14.52 14.799999 Z M 3 7.28 C 3 6.613334 3.246666 6.033334 3.74 5.539999 C 4.233333 5.046665 4.813333 4.799999 5.48 4.799999 L 14.48 4.799999 C 15.173332 4.799999 15.766665 5.046665 16.26 5.539999 C 16.753334 6.033334 17 6.626667 17 7.32 L 17 16.279999 C 17 16.973333 16.753334 17.566666 16.26 18.059999 C 15.766665 18.553333 15.173332 18.799999 14.48 18.799999 L 5.48 18.799999 C 4.813333 18.799999 4.233333 18.553333 3.74 18.059999 C 3.246666 17.566666 3 16.973333 3 16.279999 Z M 16 7.799999 L 16 7.28 C 16 6.88 15.853333 6.533334 15.559999 6.24 C 15.266665 5.946667 14.906666 5.799999 14.48 5.799999 L 5.48 5.799999 C 5.08 5.799999 4.733334 5.946667 4.44 6.24 C 4.146667 6.533334 4 6.893333 4 7.32 L 4 7.799999 Z M 4 8.799999 L 4 16.279999 C 4 16.706665 4.146667 17.066666 4.44 17.359999 C 4.733334 17.653332 5.08 17.799999 5.48 17.799999 L 14.48 17.799999 C 14.906666 17.799999 15.266665 17.653332 15.559999 17.359999 C 15.853333 17.066666 16 16.706665 16 16.279999 L 16 8.799999 Z ");
+ icon = _icon;
+ return true;
+ }
+ default:
+ break;
+ }
+ icon = null;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Progrart/Icons/IIconProvider.cs b/Progrart/Icons/IIconProvider.cs
new file mode 100644
index 0000000..82bf3ee
--- /dev/null
+++ b/Progrart/Icons/IIconProvider.cs
@@ -0,0 +1,10 @@
+using Avalonia.Controls;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Progrart.Icons
+{
+ public interface IIconProvider
+ {
+ bool TryGetIcon(string name, [MaybeNullWhen(false)] out Control icon);
+ }
+}
\ No newline at end of file
diff --git a/Progrart/Icons/IconProvider.cs b/Progrart/Icons/IconProvider.cs
new file mode 100644
index 0000000..255c8d7
--- /dev/null
+++ b/Progrart/Icons/IconProvider.cs
@@ -0,0 +1,24 @@
+using Avalonia.Controls;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Progrart.Icons
+{
+ public static class IconProvider
+ {
+ static List providers = new List();
+ public static void Register(IIconProvider provider)
+ {
+ providers.Add(provider);
+ }
+ public static bool TryGetIcon(string name, [MaybeNullWhen(false)] out Control icon)
+ {
+ foreach (var provider in providers)
+ {
+ if (provider.TryGetIcon(name, out icon)) return true;
+ }
+ icon = null;
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Progrart/Progrart.csproj b/Progrart/Progrart.csproj
index a33ae6a..25b156a 100644
--- a/Progrart/Progrart.csproj
+++ b/Progrart/Progrart.csproj
@@ -20,8 +20,8 @@
None
All
-
-
+
diff --git a/Progrart/Views/MainView.axaml b/Progrart/Views/MainView.axaml
index 42a558e..1d483b7 100644
--- a/Progrart/Views/MainView.axaml
+++ b/Progrart/Views/MainView.axaml
@@ -24,8 +24,8 @@
-
-
@@ -65,9 +65,11 @@
- File Explorer
-
-
+
+ File Explorer
+
+
+
@@ -82,8 +84,8 @@
-
-
+
+
@@ -104,7 +106,7 @@
-
+
All
@@ -123,24 +125,25 @@
-
+
-
-
+
- Output
+
+
+ Output
+
diff --git a/Progrart/Views/MainView.axaml.cs b/Progrart/Views/MainView.axaml.cs
index 7b4647f..e4af9c8 100644
--- a/Progrart/Views/MainView.axaml.cs
+++ b/Progrart/Views/MainView.axaml.cs
@@ -1,4 +1,6 @@
using Avalonia.Controls;
+using Avalonia.Platform.Storage;
+using Progrart.Controls;
using Progrart.Core.JSExecution;
using Progrart.Pages;
using System;
@@ -31,10 +33,19 @@ public partial class MainView : UserControl
BottomPanelToggle.IsCheckedChanged += (a, b) =>
{
- BottomPanel.IsVisible = BottomPanelToggle.IsChecked == true;
- SplitterVisual.IsVisible = BottomPanelToggle.IsChecked == true;
- Splitter.IsVisible = BottomPanelToggle.IsChecked == true;
+ bool v = BottomPanelToggle.IsChecked == true;
+ BottomPanel.IsVisible = v;
+ SplitterVisual.IsVisible = v;
+ Splitter.IsVisible = v;
ContentGrid.RowDefinitions[2].Height = GridLength.Auto;
+ if (v)
+ {
+ ContentGrid.RowDefinitions[2].MinHeight = 48;
+ }
+ else
+ {
+ ContentGrid.RowDefinitions[2].MinHeight = 0;
+ }
};
LeftPanelToggle.IsCheckedChanged += (a, b) =>
@@ -53,6 +64,34 @@ public partial class MainView : UserControl
{
MainTabHost.AddPage(new AboutPage());
};
+ OpenProjectMenuItem.Click += async (_, _) =>
+ {
+ var topLevel = TopLevel.GetTopLevel(this);
+
+ if (topLevel == null) return;
+
+ // Open the folder picker
+ var folders = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
+ {
+ Title = "Select Folder",
+ AllowMultiple = false
+ });
+
+ if (folders.Count >= 1)
+ {
+ // Get the first selected folder path
+ // Note: TryGetLocalPath() returns null if the file isn't on a local disk (e.g., cloud storage)
+ var folderPath = folders[0].TryGetLocalPath();
+ var folder = folders[0];
+ FileContainer.Children.Add(new FileItem(folder));
+ if (folderPath != null)
+ {
+ // Do something with the path
+ System.Diagnostics.Debug.WriteLine($"Picked: {folderPath}");
+ }
+ }
+ };
+ LeftPanelToggle.IsChecked = true;
}
public void Write(string message)
{