Skip to content

Commit

Permalink
Merge pull request #28 from ItsTheSky/features/projects
Browse files Browse the repository at this point in the history
Better projects
  • Loading branch information
ItsTheSky committed Feb 5, 2024
2 parents af69352 + a695d17 commit 4b74713
Show file tree
Hide file tree
Showing 16 changed files with 744 additions and 62 deletions.
1 change: 1 addition & 0 deletions Installer/SkEditorInstaller.wixproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<Content Include="Assets\Warning.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.6" />
<PackageReference Include="WixToolset.UI.wixext" Version="4.0.3" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions SkEditor/Assets/Icons.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,10 @@
<ui:SymbolIconSource x:Key="RefreshIcon" Symbol="Refresh"/>
<ui:SymbolIconSource x:Key="ImportantIcon" Symbol="Important"/>
<ui:SymbolIconSource x:Key="EditIcon" Symbol="Edit"/>
<ui:SymbolIconSource x:Key="NewFile" Symbol="New"/>
<ui:SymbolIconSource x:Key="NewFolder" Symbol="NewFolder"/>
<ui:SymbolIconSource x:Key="OpenFolder" Symbol="OpenLocal"/>
<ui:SymbolIconSource x:Key="Delete" Symbol="Delete"/>
<ui:SymbolIconSource x:Key="Rename" Symbol="Rename"/>

</ResourceDictionary>
78 changes: 75 additions & 3 deletions SkEditor/Controls/Sidebar/ExplorerSidebarPanel.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:ar="clr-namespace:SkEditor.Utilities.Projects"
xmlns:elements="clr-namespace:SkEditor.Utilities.Projects.Elements"
xmlns:visualBasic="clr-namespace:Microsoft.VisualBasic;assembly=Microsoft.VisualBasic.Core"
x:Class="SkEditor.Controls.Sidebar.ExplorerSidebarPanel">

<UserControl.Styles>
Expand All @@ -26,12 +29,81 @@
</Transitions>
</Border.Transitions>

<Grid RowDefinitions="auto,auto,*">
<Grid RowDefinitions="auto,auto,auto,*">
<TextBlock Grid.Row="0" Text="Explorer" FontWeight="DemiBold" Margin="20,10,20,10"/>
<Separator Grid.Row="1" Margin="0,0,0,10"/>
<TreeView Grid.Row="2" Name="FileTreeView">

<Border Name="LoadingPanel" Grid.Row="2" IsVisible="False" Margin="10">
<StackPanel Spacing="10">
<TextBlock Name="LoadingText" TextAlignment="Center">Loading XX files ...</TextBlock>
<ProgressBar Name="LoadingBar" Margin="5 0"></ProgressBar>
<Separator />
</StackPanel>
</Border>
<TreeView Grid.Row="3" Name="FileTreeView">
<TreeView.Styles>
<Style Selector="TreeViewItem">
<Setter Property="IsExpanded" x:DataType="elements:StorageElement" Value="{Binding IsExpanded, Mode=TwoWay}"/>
</Style>
</TreeView.Styles>
<TreeView.ItemTemplate>
<TreeDataTemplate x:DataType="elements:StorageElement" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Spacing="10" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent">
<Interaction.Behaviors>
<EventTriggerBehavior EventName="DoubleTapped">
<EventTriggerBehavior.Actions>
<InvokeCommandAction Command="{Binding DoubleClickCommand}" />
</EventTriggerBehavior.Actions>
</EventTriggerBehavior>
</Interaction.Behaviors>

<ui:IconSourceElement HorizontalAlignment="Left" VerticalAlignment="Center" IsVisible="{Binding IsFile}" IconSource="{Binding Icon}" Width="24" Height="24" />
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Center" Text="{Binding Name}"/>

<StackPanel.ContextFlyout>
<MenuFlyout>
<MenuItem IsVisible="{Binding !IsFile}" Header="New File" Command="{Binding CreateNewFileCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="New" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>
<MenuItem IsVisible="{Binding !IsFile}" Header="New Folder" Command="{Binding CreateNewFolderCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="NewFolder" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>

<Separator IsVisible="{Binding !IsFile}" />

<MenuItem Header="Copy Path" Command="{Binding CopyPathCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="Copy" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>

<MenuItem Header="Copy Absolute Path" Command="{Binding CopyAbsolutePathCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="Copy" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>

<Separator />

<MenuItem Header="Open in Explorer" Command="{Binding OpenInExplorerCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="OpenFolder" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>
<MenuItem Header="Rename" Command="{Binding RenameCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="Rename" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>
<MenuItem Header="Delete" Command="{Binding DeleteCommand}">
<MenuItem.Icon><ui:SymbolIcon Symbol="Delete" FontSize="20"></ui:SymbolIcon></MenuItem.Icon>
</MenuItem>
</MenuFlyout>
</StackPanel.ContextFlyout>
</StackPanel>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<StackPanel Name="NoFolderMessage" VerticalAlignment="Center" Grid.Row="3" Margin="5" Spacing="10">
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap">You don't have any folders opened yet. Keep in mind they are in beta!</TextBlock>
<Button Click="OpenFolder" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" Spacing="5" VerticalAlignment="Center">
<ui:SymbolIcon Symbol="OpenFolder" FontSize="18"></ui:SymbolIcon>
<TextBlock>Open Folder</TextBlock>
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Border>
</UserControl>
11 changes: 8 additions & 3 deletions SkEditor/Controls/Sidebar/ExplorerSidebarPanel.axaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.Controls;
using Avalonia.Interactivity;
using FluentAvalonia.UI.Controls;
using SkEditor.Utilities;
using SkEditor.Utilities.Projects;

namespace SkEditor.Controls.Sidebar;

Expand All @@ -21,4 +21,9 @@ public class ExplorerPanel : SidebarPanel

public readonly ExplorerSidebarPanel Panel = new ();
}

private void OpenFolder(object? sender, RoutedEventArgs e)
{
ProjectOpener.OpenProject();
}
}
28 changes: 27 additions & 1 deletion SkEditor/Languages/English.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
<system:String x:Key="WindowTitleCommandGenerator">Generate command</system:String>
<system:String x:Key="WindowTitleItemSelector">Select item</system:String>
<system:String x:Key="WindowTitleMarketplace">Marketplace</system:String>
<system:String x:Key="WindowTitleElementRename">Rename</system:String>
<system:String x:Key="WindowTitleElementCreate">Create</system:String>

<!-- Menu Headers -->
<system:String x:Key="MenuHeaderFile">File</system:String>
Expand Down Expand Up @@ -46,11 +48,19 @@
<system:String x:Key="MenuHeaderGenerateGUI">GUI</system:String>
<system:String x:Key="MenuHeaderGenerateCommand">Command</system:String>
<system:String x:Key="MenuHeaderRefactor">Refactor</system:String>

<!-- Other Menu -->
<system:String x:Key="MenuHeaderMarketplace">Marketplace</system:String>
<system:String x:Key="MenuHeaderRefreshSyntax">Refresh syntax</system:String>

<!-- Project Menu -->
<system:String x:Key="MenuHeaderOpenInExplorer">Open in explorer</system:String>
<system:String x:Key="MenuHeaderCopyPath">Copy relative path</system:String>
<system:String x:Key="MenuHeaderCopyAbsolutePath">Copy absolute path</system:String>
<system:String x:Key="MenuHeaderRename">Rename</system:String>
<system:String x:Key="MenuHeaderNewFile">New file</system:String>
<system:String x:Key="MenuHeaderNewFolder">New folder</system:String>

<!-- Buttons -->
<system:String x:Key="ApplyButton">Apply</system:String>
<system:String x:Key="ConfirmButton">Confirm</system:String>
Expand Down Expand Up @@ -98,6 +108,21 @@
<system:String x:Key="RefactorWindowSpacesToTabs">Convert spaces to tabs</system:String>
<system:String x:Key="RefactorWindowRefactorBoxName">Renaming '{0}' into ...</system:String>


<!-- Projects -->
<system:String x:Key="ProjectExplorerTitle">Explorer</system:String>
<system:String x:Key="ProjectExplorerInfoText">Projects are still in beta and bugs may occur!</system:String>
<system:String x:Key="ProjectExplorerInfoButton">Open Folder</system:String>
<system:String x:Key="ProjectRenameText">Renaming into ...</system:String>
<system:String x:Key="ProjectRenameErrorNameEmpty">Name cannot be empty.</system:String>
<system:String x:Key="ProjectRenameErrorParentNull">Parent cannot be null.</system:String>
<system:String x:Key="ProjectRenameErrorNameExists">A file or folder with this name already exists.</system:String>
<system:String x:Key="ProjectRenameErrorSameName">The new name is the same as the old name.</system:String>
<system:String x:Key="ProjectCreateErrorNameExists">A file or folder with this name already exists.</system:String>
<system:String x:Key="ProjectCreateFileName">File Name</system:String>
<system:String x:Key="ProjectCreateFolderName">Folder Name</system:String>
<system:String x:Key="ProjectCreateTemplate">Template</system:String>

<!-- File Association Selection Window -->
<system:String x:Key="FileAssociationSelectionWindowTitle">Select file association</system:String>
<system:String x:Key="FileAssociationSelectionWindowInfo">There's multiple provider for this file type. Please select one.</system:String>
Expand All @@ -106,6 +131,7 @@
<system:String x:Key="FileAssociationSelectionWindowRememberMyChoice">Remember my choice</system:String>
<system:String x:Key="FileAssociationSelectionWindowConfirm">Confirm</system:String>


<!-- Settings -->
<system:String x:Key="SettingsEnabled">Enabled</system:String>
<system:String x:Key="SettingsDisabled">Disabled</system:String>
Expand Down
1 change: 1 addition & 0 deletions SkEditor/SkEditor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<PackageReference Include="Avalonia.Svg.Skia" Version="11.0.0.10" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.7" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.7" />
<PackageReference Include="Avalonia.Xaml.Behaviors" Version="11.0.6" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />

<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
Expand Down
28 changes: 22 additions & 6 deletions SkEditor/Utilities/Editor/CustomCommandsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,39 @@ public static void OnCommentCommandExecuted(object target)
var document = editor.Document;
var selectionStart = editor.SelectionStart;
var selectionLength = editor.SelectionLength;
var indentation = editor.Options.IndentationString;

var selectedLines = document.Lines
.Where(line => selectionStart <= line.EndOffset && selectionStart + selectionLength >= line.Offset)
.ToList();

bool allLinesCommented = selectedLines.All(line => document.GetText(line).StartsWith("#"));

var modifiedLines = selectedLines.Select(line =>
{
var text = document.GetText(line);
if (allLinesCommented)
if (string.IsNullOrWhiteSpace(text))
return text;
// Find the first non-tabulator character
var strippedLine = text.TrimStart();
var isCommented = text.TrimStart().StartsWith("#");
var indentationAmount = 0;
while (text.StartsWith(indentation))
{
return text.StartsWith('#') ? text[1..] : text;
text = text[indentation.Length..];
indentationAmount++;
}
else
string indentationToInsert = "";
for (int i = 0; i < indentationAmount; i++)
indentationToInsert += indentation;
ApiVault.Get().Log("Indentation 2 insert: " + indentationToInsert + " | Line: '" + text + "'", true);
if (isCommented)
{
return indentationToInsert + strippedLine[1..];
} else
{
return text.StartsWith('#') ? "##" + text[1..] : "#" + text;
return indentationToInsert + "#" + strippedLine;
}
}).ToList();

Expand Down
13 changes: 13 additions & 0 deletions SkEditor/Utilities/Files/Icon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,17 @@ public static void SetIcon(TabViewItem tabViewItem)

tabViewItem.IconSource = iconSource;
}

public static IconSource? GetIcon(string extension)
{
string iconName = IconDictionary.GetValueOrDefault(extension);

if (iconName is not null)
{
Application.Current.TryGetResource(iconName, Avalonia.Styling.ThemeVariant.Default, out object icon);
return icon as PathIconSource;
}

return null;
}
}
88 changes: 88 additions & 0 deletions SkEditor/Utilities/Projects/Elements/File.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.Input;
using SkEditor.API;
using SkEditor.Utilities.Files;

namespace SkEditor.Utilities.Projects.Elements;

public class File : StorageElement
{

public string StorageFilePath { get; set; }

public File(string file, Folder? parent = null)
{
Parent = parent;
StorageFilePath = file;

Name = Path.GetFileName(file);
IsFile = true;

var icon = Files.Icon.GetIcon(Path.GetExtension(file));
if (icon is not null)
Icon = icon;

// Commands
OpenInExplorerCommand = new RelayCommand(OpenInExplorer);
DeleteCommand = new RelayCommand(DeleteFile);
CopyAbsolutePathCommand = new RelayCommand(CopyAbsolutePath);
CopyPathCommand = new RelayCommand(CopyPath);
}

public void OpenInExplorer()
{
Process.Start(new ProcessStartInfo(Parent.StorageFolderPath) { UseShellExecute = true });
}

public void DeleteFile()
{
System.IO.File.Delete(StorageFilePath);
Parent.Children.Remove(this);
}

public override string? ValidateName(string input)
{
if (input == Name)
return Translation.Get("ProjectRenameErrorSameName");

if (Parent is null)
return Translation.Get("ProjectRenameErrorParentNull");

var file = Parent.Children.FirstOrDefault(x => x.Name == input);
if (file is not null)
return Translation.Get("ProjectRenameErrorNameExists");

return null;
}

public override void RenameElement(string newName)
{
var newPath = Path.Combine(Parent.StorageFolderPath, newName);

System.IO.File.Move(StorageFilePath, newPath);
StorageFilePath = newPath;

Name = newName;

RefreshSelf();
}

public override void HandleDoubleClick()
{
FileHandler.OpenFile(StorageFilePath);
}

public void CopyAbsolutePath()
{
ApiVault.Get().GetMainWindow().Clipboard.SetTextAsync(StorageFilePath.Replace("\\", "/"));
}

public void CopyPath()
{
var path = StorageFilePath.Replace(ProjectOpener.ProjectRootFolder.StorageFolderPath, "");
ApiVault.Get().GetMainWindow().Clipboard.SetTextAsync(path.Replace("\\", "/"));
}
}
Loading

0 comments on commit 4b74713

Please sign in to comment.