fix: Load icon successfully

This commit is contained in:
walterlv 2024-04-08 16:05:37 +08:00
parent f66c6c14a2
commit 0426e24c6e
5 changed files with 106 additions and 49 deletions

View file

@ -5,14 +5,14 @@ using System.IO;
namespace SourceGit.Models
{
public class ExternalTerminal
public record ExternalTerminal
{
public string Name { get; set; } = string.Empty;
public string Icon { get; set; } = string.Empty;
public string Executable { get; set; } = string.Empty;
public string OpenCmdArgs { get; set; } = string.Empty;
public string Name { get; init; } = string.Empty;
public string Icon { get; init; } = string.Empty;
public string Executable { get; init; } = string.Empty;
public string OpenCmdArgs { get; init; } = string.Empty;
public void Open(string repo)
public virtual void Open(string repo)
{
Process.Start(new ProcessStartInfo()
{
@ -34,31 +34,33 @@ namespace SourceGit.Models
public void WindowsGitBash(Func<string> platform_finder)
{
TryAdd("Git Bash", "git-bash.png", "bash", "\"{0}\"", platform_finder);
TryAdd("Git Bash", "git-bash.png", "bash", "", platform_finder);
}
public void Gnome(Func<string> platform_finder)
{
TryAdd("gnome-terminal", "gnome.png", "/usr/bin/gnome-terminal", "--working-directory=\"{0}\"", platform_finder);
TryAdd("gnome-terminal", "gnome.png", "gnome", "--working-directory=\"{0}\"", platform_finder);
}
public void Konsole(Func<string> platform_finder)
{
TryAdd("gnome-terminal", "konsole.png", "/usr/bin/konsole", "--workdir \"{0}\"", platform_finder);
TryAdd("konsole", "konsole.png", "konsole", "--workdir \"{0}\"", platform_finder);
}
public void osaScript(Func<string> platform_finder)
public void AppleScript(ExternalTerminal terminal)
{
TryAdd("AppleScript", "osascript.png", "/usr/bin/osascript",
"""
on run argv
tell application "Terminal"
do script "cd '{0}'"
activate
end tell
end run
""",
platform_finder);
var path = terminal.Executable;
if (string.IsNullOrEmpty(path) || !File.Exists(path))
{
return;
}
Terminals.Add(terminal with
{
Name = "AppleScript",
Icon = "osascript.png",
});
}
public void PowerShell(Func<string> platform_finder)
@ -73,7 +75,7 @@ namespace SourceGit.Models
public void Xfce4(Func<string> platform_finder)
{
TryAdd("gnome-terminal", "xfce4.png", "/usr/bin/xfce4-terminal", "--working-directory=\"{0}\"", platform_finder);
TryAdd("xfce4", "xfce4.png", "xfce4", "--working-directory=\"{0}\"", platform_finder);
}
private void TryAdd(string name, string icon, string cmd, string args, Func<string> finder)

View file

@ -31,7 +31,7 @@ namespace SourceGit.Native
public List<Models.ExternalTerminal> FindExternalTerminals()
{
var finder = new Models.ExternalTerminalFinder();
finder.osaScript(() => "/usr/bin/osascript");
finder.AppleScript(new AppleScriptTerminal());
return finder.Terminals;
}
@ -64,25 +64,39 @@ namespace SourceGit.Native
public void OpenTerminal(string workdir)
{
var dir = string.IsNullOrEmpty(workdir) ? "~" : workdir;
var builder = new StringBuilder();
builder.AppendLine("on run argv");
builder.AppendLine(" tell application \"Terminal\"");
builder.AppendLine($" do script \"cd '{dir}'\"");
builder.AppendLine(" activate");
builder.AppendLine(" end tell");
builder.AppendLine("end run");
var tmp = Path.GetTempFileName();
File.WriteAllText(tmp, builder.ToString());
var proc = Process.Start("/usr/bin/osascript", $"\"{tmp}\"");
proc.Exited += (o, e) => File.Delete(tmp);
new AppleScriptTerminal().Open(workdir);
}
public void OpenWithDefaultEditor(string file)
{
Process.Start("open", file);
}
private sealed record AppleScriptTerminal : Models.ExternalTerminal
{
public AppleScriptTerminal()
{
Executable = "/usr/bin/osascript";
OpenCmdArgs = "";
}
public override void Open(string repo)
{
var dir = string.IsNullOrEmpty(repo) ? "~" : repo;
var tmp = Path.GetTempFileName();
File.WriteAllText(tmp,
$"""
on run argv
tell application "Terminal"
do script "cd '{dir}'"
activate
end tell
end run
""");
var proc = Process.Start("/usr/bin/osascript", $"\"{tmp}\"");
proc.Exited += (o, e) => File.Delete(tmp);
}
}
}
}

View file

@ -346,8 +346,10 @@ namespace SourceGit.ViewModels
foreach (var terminal in terminals)
{
var dupTerminal = terminal;
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalTerminalIcons/{dupTerminal.Icon}", UriKind.RelativeOrAbsolute));
var item = new ExternalMenuItem(App.Text("Repository.OpenIn", dupTerminal.Name), new Bitmap(icon), () => dupTerminal.Open(_fullpath));
var item = new ExternalMenuItem(
App.Text("Repository.OpenIn", dupTerminal.Name),
$"ExternalTerminalIcons/{dupTerminal.Icon}",
() => dupTerminal.Open(_fullpath));
items.Add(item);
}
@ -370,8 +372,10 @@ namespace SourceGit.ViewModels
foreach (var editor in editors)
{
var dupEditor = editor;
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/ExternalToolIcons/{dupEditor.Icon}", UriKind.RelativeOrAbsolute));
var item = new ExternalMenuItem(App.Text("Repository.OpenIn", dupEditor.Name), new Bitmap(icon), () => dupEditor.Open(_fullpath));
var item = new ExternalMenuItem(
App.Text("Repository.OpenIn", dupEditor.Name),
$"ExternalToolIcons/{dupEditor.Icon}",
() => dupEditor.Open(_fullpath));
items.Add(item);
}
@ -1424,14 +1428,14 @@ namespace SourceGit.ViewModels
public ExternalMenuItem(string header)
{
Header = header;
Icon = null;
IconKey = null;
Command = null;
}
public ExternalMenuItem(string header, Bitmap icon, Action click)
public ExternalMenuItem(string header, string iconKey, Action click)
{
Header = header;
Icon = icon;
IconKey = iconKey;
Command = new RelayCommand(click);
}
@ -1443,7 +1447,7 @@ namespace SourceGit.ViewModels
/// <summary>
/// The resource key of the icon.
/// </summary>
public Bitmap? Icon { get; init; }
public string? IconKey { get; init; }
/// <summary>
/// The command when the user click the menu item.
@ -1453,6 +1457,6 @@ namespace SourceGit.ViewModels
/// <summary>
/// <see langword="true"/> if the menu item is enabled; otherwise, <see langword="false"/>.
/// </summary>
public bool IsEnabled { get; init; }
public bool IsEnabled { get; init; } = true;
}
}

View file

@ -11,12 +11,23 @@
x:DataType="vm:Repository">
<UserControl.Resources>
<MenuFlyout x:Key="TerminalShellsMenuFlyout" Placement="Bottom">
</MenuFlyout>
<MenuFlyout x:Key="ExternalToolsMenuFlyout" Placement="Bottom">
</MenuFlyout>
<v:ExternalIconKeyToImageConverter x:Key="IconKeyToImageConverter" />
<MenuFlyout x:Key="TerminalShellsMenuFlyout" Placement="BottomEdgeAlignedLeft"
ItemsSource="{Binding ExternalTerminals, Mode=OneTime}" />
<MenuFlyout x:Key="ExternalToolsMenuFlyout" Placement="BottomEdgeAlignedLeft"
ItemsSource="{Binding ExternalEditors, Mode=OneTime}" />
</UserControl.Resources>
<UserControl.DataTemplates>
<DataTemplate x:DataType="vm:ExternalMenuItem">
<MenuItem Header="{Binding Header, Mode=OneTime}"
Icon="{Binding IconKey, Mode=OneTime, Converter={StaticResource IconKeyToImageConverter}}"
Command="{Binding Command, Mode=OneTime}"
IsEnabled="{Binding IsEnabled, Mode=OneTime}">
</MenuItem>
</DataTemplate>
</UserControl.DataTemplates>
<Grid RowDefinitions="36,*" Background="{DynamicResource Brush.Window}">
<!-- Toolbar -->
<Border Grid.Row="0" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" Background="{DynamicResource Brush.ToolBar}">

View file

@ -1,11 +1,15 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data.Converters;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace SourceGit.Views
{
@ -301,4 +305,26 @@ namespace SourceGit.Views
}
}
}
public sealed class ExternalIconKeyToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string iconKey && !string.IsNullOrWhiteSpace(iconKey))
{
var icon = AssetLoader.Open(new Uri($"avares://SourceGit/Resources/{iconKey}", UriKind.RelativeOrAbsolute));
return new Image
{
Width = 16, Height = 16, Source = new Bitmap(icon),
};
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}