feature: supports custom fonts (#30)

This commit is contained in:
leo 2024-03-21 18:02:06 +08:00
parent 0e49ad181a
commit 83aa373079
14 changed files with 181 additions and 15 deletions

View file

@ -2,6 +2,7 @@
using System.Globalization; using System.Globalization;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Media;
using Avalonia.Styling; using Avalonia.Styling;
namespace SourceGit.Converters namespace SourceGit.Converters
@ -69,5 +70,29 @@ namespace SourceGit.Converters
public static FuncValueConverter<string, string> ToShortSHA = public static FuncValueConverter<string, string> ToShortSHA =
new FuncValueConverter<string, string>(v => v.Length > 10 ? v.Substring(0, 10) : v); new FuncValueConverter<string, string>(v => v.Length > 10 ? v.Substring(0, 10) : v);
public class ToFontFamilyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var name = value as string;
if (string.IsNullOrEmpty(name))
{
return FontManager.Current.DefaultFontFamily;
}
else
{
return new FontFamily(name);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var fontFamily = value as FontFamily;
return fontFamily == null ? string.Empty : fontFamily.ToString();
}
}
public static ToFontFamilyConverter ToFontFamily = new ToFontFamilyConverter();
} }
} }

View file

@ -2256,6 +2256,15 @@ namespace SourceGit.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Default FontFamily.
/// </summary>
public static string Text_Preference_General_DefaultFont {
get {
return ResourceManager.GetString("Text.Preference.General.DefaultFont", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Language. /// Looks up a localized string similar to Language.
/// </summary> /// </summary>
@ -2274,6 +2283,15 @@ namespace SourceGit.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Monospace FontFamily.
/// </summary>
public static string Text_Preference_General_MonospaceFont {
get {
return ResourceManager.GetString("Text.Preference.General.MonospaceFont", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Restore windows. /// Looks up a localized string similar to Restore windows.
/// </summary> /// </summary>

View file

@ -1290,4 +1290,10 @@
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve"> <data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>Syntax Highlighting</value> <value>Syntax Highlighting</value>
</data> </data>
<data name="Text.Preference.General.DefaultFont" xml:space="preserve">
<value>Default FontFamily</value>
</data>
<data name="Text.Preference.General.MonospaceFont" xml:space="preserve">
<value>Monospace FontFamily</value>
</data>
</root> </root>

View file

@ -1290,4 +1290,10 @@
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve"> <data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>Syntax Highlighting</value> <value>Syntax Highlighting</value>
</data> </data>
<data name="Text.Preference.General.DefaultFont" xml:space="preserve">
<value>Default FontFamily</value>
</data>
<data name="Text.Preference.General.MonospaceFont" xml:space="preserve">
<value>Monospace FontFamily</value>
</data>
</root> </root>

View file

@ -1290,4 +1290,10 @@
<data name="Text.Diff.SyntaxHighlight" xml:space="preserve"> <data name="Text.Diff.SyntaxHighlight" xml:space="preserve">
<value>语法高亮</value> <value>语法高亮</value>
</data> </data>
<data name="Text.Preference.General.DefaultFont" xml:space="preserve">
<value>缺省字体</value>
</data>
<data name="Text.Preference.General.MonospaceFont" xml:space="preserve">
<value>等宽字体</value>
</data>
</root> </root>

View file

@ -1,5 +1,7 @@
<Styles xmlns="https://github.com/avaloniaui" <Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:SourceGit.ViewModels"
xmlns:c="using:SourceGit.Converters"
xmlns:ae="using:AvaloniaEdit" xmlns:ae="using:AvaloniaEdit"
xmlns:aes="using:AvaloniaEdit.Search"> xmlns:aes="using:AvaloniaEdit.Search">
<Design.PreviewWith> <Design.PreviewWith>
@ -13,6 +15,10 @@
</Style.Resources> </Style.Resources>
</Style> </Style>
<Style Selector="ContentPresenter">
<Setter Property="FontFamily" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=DefaultFont, Converter={x:Static c:StringConverters.ToFontFamily}}"/>
</Style>
<Style Selector="Path"> <Style Selector="Path">
<Setter Property="Fill" Value="{DynamicResource Brush.FG1}"/> <Setter Property="Fill" Value="{DynamicResource Brush.FG1}"/>
<Setter Property="Stretch" Value="Uniform"/> <Setter Property="Stretch" Value="Uniform"/>
@ -64,7 +70,7 @@
<Setter Property="FontStyle" Value="Italic"/> <Setter Property="FontStyle" Value="Italic"/>
</Style> </Style>
<Style Selector="TextBlock.monospace"> <Style Selector="TextBlock.monospace">
<Setter Property="FontFamily" Value="fonts:SourceGit#JetBrains Mono"/> <Setter Property="FontFamily" Value="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"/>
</Style> </Style>
<Style Selector="TextBlock.group_header_label"> <Style Selector="TextBlock.group_header_label">
<Setter Property="Foreground" Value="{DynamicResource Brush.FG2}"/> <Setter Property="Foreground" Value="{DynamicResource Brush.FG2}"/>

View file

@ -71,6 +71,18 @@ namespace SourceGit.ViewModels
} }
} }
public string DefaultFont
{
get => _defaultFont;
set => SetProperty(ref _defaultFont, value);
}
public string MonospaceFont
{
get => _monospaceFont;
set => SetProperty(ref _monospaceFont, value);
}
public string AvatarServer public string AvatarServer
{ {
get => Models.AvatarManager.SelectedServer; get => Models.AvatarManager.SelectedServer;
@ -352,6 +364,9 @@ namespace SourceGit.ViewModels
private string _locale = "en_US"; private string _locale = "en_US";
private string _theme = "Default"; private string _theme = "Default";
private string _defaultFont = string.Empty;
private string _monospaceFont = "fonts:SourceGit#JetBrains Mono";
private int _maxHistoryCommits = 20000; private int _maxHistoryCommits = 20000;
private bool _restoreTabs = false; private bool _restoreTabs = false;
private bool _useFixedTabWidth = true; private bool _useFixedTabWidth = true;

View file

@ -72,7 +72,7 @@
BorderThickness="1" BorderThickness="1"
Background="{DynamicResource Brush.Contents}" Background="{DynamicResource Brush.Contents}"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
FontFamily="fonts:SourceGit#JetBrains Mono" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"
FontSize="12" FontSize="12"
BlameData="{Binding Data}"/> BlameData="{Binding Data}"/>

View file

@ -43,7 +43,7 @@
<Grid RowDefinitions="24,Auto,Auto,Auto" ColumnDefinitions="96,*"> <Grid RowDefinitions="24,Auto,Auto,Auto" ColumnDefinitions="96,*">
<!-- SHA --> <!-- SHA -->
<TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" /> <TextBlock Grid.Row="0" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.SHA}" />
<SelectableTextBlock Grid.Row="0" Grid.Column="1" Text="{Binding SHA}" Margin="12,0,0,0" FontSize="12" VerticalAlignment="Center" FontFamily="fonts:SourceGit#JetBrains Mono"/> <SelectableTextBlock Grid.Row="0" Grid.Column="1" Text="{Binding SHA}" Margin="12,0,0,0" FontSize="12" VerticalAlignment="Center" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"/>
<!-- PARENTS --> <!-- PARENTS -->
<TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Parents}" IsVisible="{Binding Parents.Count, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"/> <TextBlock Grid.Row="1" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Parents}" IsVisible="{Binding Parents.Count, Converter={x:Static c:IntConverters.IsGreaterThanZero}}"/>
@ -95,7 +95,7 @@
<!-- Messages --> <!-- Messages -->
<TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" /> <TextBlock Grid.Row="3" Grid.Column="0" Classes="info_label" Text="{DynamicResource Text.CommitDetail.Info.Message}" VerticalAlignment="Top" Margin="0,4,0,0" />
<ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,0,0" MaxHeight="100" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <ScrollViewer Grid.Row="3" Grid.Column="1" Margin="12,5,0,0" MaxHeight="100" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<SelectableTextBlock Text="{Binding FullMessage}" FontSize="12" FontFamily="fonts:SourceGit#JetBrains Mono" TextWrapping="Wrap"/> <SelectableTextBlock Text="{Binding FullMessage}" FontSize="12" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}" TextWrapping="Wrap"/>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>

View file

@ -67,7 +67,7 @@
<TabItem.Header> <TabItem.Header>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/> <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
</TabItem.Header> </TabItem.Header>
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="Auto,*"> <Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" <TextBlock Grid.Row="0" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.Locale}" Text="{DynamicResource Text.Preference.General.Locale}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
@ -113,10 +113,48 @@
</ComboBox> </ComboBox>
<TextBlock Grid.Row="3" Grid.Column="0" <TextBlock Grid.Row="3" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.DefaultFont}"
HorizontalAlignment="Right"
Margin="0,0,16,0"/>
<ComboBox Grid.Row="3" Grid.Column="1"
MinHeight="28"
Padding="8,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding #me.InstalledFonts}"
SelectedItem="{Binding DefaultFont, Converter={x:Static c:StringConverters.ToFontFamily}, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="FontFamily">
<Border Height="24">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontFamily="{Binding}"/>
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="4" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.MonospaceFont}"
HorizontalAlignment="Right"
Margin="0,0,16,0"/>
<ComboBox Grid.Row="4" Grid.Column="1"
MinHeight="28"
Padding="8,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding #me.InstalledMonospaceFonts}"
SelectedItem="{Binding MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="FontFamily">
<Border Height="24">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" FontFamily="{Binding}"/>
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="5" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}" Text="{DynamicResource Text.Preference.General.MaxHistoryCommits}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<Grid Grid.Row="3" Grid.Column="1" ColumnDefinitions="*,64"> <Grid Grid.Row="5" Grid.Column="1" ColumnDefinitions="*,64">
<Slider Grid.Column="0" <Slider Grid.Column="0"
Minimum="20000" Maximum="100000" Minimum="20000" Maximum="100000"
TickPlacement="BottomRight" TickFrequency="5000" TickPlacement="BottomRight" TickFrequency="5000"
@ -140,11 +178,11 @@
Text="{Binding MaxHistoryCommits}"/> Text="{Binding MaxHistoryCommits}"/>
</Grid> </Grid>
<CheckBox Grid.Row="4" Grid.Column="1" <CheckBox Grid.Row="6" Grid.Column="1"
Content="{DynamicResource Text.Preference.General.RestoreTabs}" Content="{DynamicResource Text.Preference.General.RestoreTabs}"
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/> IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
<CheckBox Grid.Row="5" Grid.Column="1" <CheckBox Grid.Row="7" Grid.Column="1"
Height="32" Height="32"
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}" Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/> IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>

View file

@ -1,15 +1,30 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
namespace SourceGit.Views namespace SourceGit.Views
{ {
public partial class Preference : Window public partial class Preference : Window
{ {
public List<FontFamily> InstalledFonts
{
get;
private set;
}
public List<FontFamily> InstalledMonospaceFonts
{
get;
private set;
}
public string DefaultUser public string DefaultUser
{ {
get; get;
@ -51,6 +66,37 @@ namespace SourceGit.Views
var pref = ViewModels.Preference.Instance; var pref = ViewModels.Preference.Instance;
DataContext = pref; DataContext = pref;
InstalledFonts = new List<FontFamily>();
InstalledFonts.Add(new FontFamily("fonts:SourceGit#JetBrains Mono"));
InstalledFonts.AddRange(FontManager.Current.SystemFonts);
InstalledFonts.Remove(FontManager.Current.DefaultFontFamily);
InstalledFonts.Add(FontManager.Current.DefaultFontFamily);
InstalledMonospaceFonts = new List<FontFamily>();
InstalledMonospaceFonts.Add(new FontFamily("fonts:SourceGit#JetBrains Mono"));
foreach (var font in FontManager.Current.SystemFonts)
{
var typeface = new Typeface(font);
var testI = new FormattedText(
"i",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
12,
Brushes.White);
var testW = new FormattedText(
"W",
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
12,
Brushes.White);
if (testI.Width == testW.Width)
{
InstalledMonospaceFonts.Add(font);
}
}
var ver = string.Empty; var ver = string.Empty;
if (pref.IsGitConfigured) if (pref.IsGitConfigured)
{ {

View file

@ -89,7 +89,7 @@
</DataTemplate> </DataTemplate>
<DataTemplate DataType="m:RevisionTextFile"> <DataTemplate DataType="m:RevisionTextFile">
<v:RevisionTextFileView FontFamily="fonts:SourceGit#JetBrains Mono" FontSize="12" Background="{DynamicResource Brush.Contents}"/> <v:RevisionTextFileView FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}" FontSize="12" Background="{DynamicResource Brush.Contents}"/>
</DataTemplate> </DataTemplate>
<DataTemplate DataType="m:RevisionLFSObject"> <DataTemplate DataType="m:RevisionLFSObject">

View file

@ -17,7 +17,7 @@
BorderThickness="0" BorderThickness="0"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
SecondaryFG="{DynamicResource Brush.FG2}" SecondaryFG="{DynamicResource Brush.FG2}"
FontFamily="fonts:SourceGit#JetBrains Mono" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"
FontSize="12" FontSize="12"
DiffData="{Binding}" DiffData="{Binding}"
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}" SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
@ -36,7 +36,7 @@
BorderThickness="0" BorderThickness="0"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
SecondaryFG="{DynamicResource Brush.FG2}" SecondaryFG="{DynamicResource Brush.FG2}"
FontFamily="fonts:SourceGit#JetBrains Mono" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"
FontSize="12" FontSize="12"
DiffData="{Binding}"/> DiffData="{Binding}"/>
@ -52,7 +52,7 @@
BorderThickness="0" BorderThickness="0"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
SecondaryFG="{DynamicResource Brush.FG2}" SecondaryFG="{DynamicResource Brush.FG2}"
FontFamily="fonts:SourceGit#JetBrains Mono" FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont, Converter={x:Static c:StringConverters.ToFontFamily}}"
FontSize="12" FontSize="12"
DiffData="{Binding}"/> DiffData="{Binding}"/>
</Grid> </Grid>

View file

@ -160,7 +160,7 @@ namespace SourceGit.Views
public LineStyleTransformer(CombinedTextDiffPresenter editor) public LineStyleTransformer(CombinedTextDiffPresenter editor)
{ {
_editor = editor; _editor = editor;
_indicatorTypeface = new Typeface("fonts:SourceGit#JetBrains Mono", FontStyle.Italic); _indicatorTypeface = new Typeface(editor.FontFamily, FontStyle.Italic);
} }
protected override void ColorizeLine(DocumentLine line) protected override void ColorizeLine(DocumentLine line)
@ -520,7 +520,7 @@ namespace SourceGit.Views
public LineStyleTransformer(SingleSideTextDiffPresenter editor) public LineStyleTransformer(SingleSideTextDiffPresenter editor)
{ {
_editor = editor; _editor = editor;
_indicatorTypeface = new Typeface("fonts:SourceGit#JetBrains Mono", FontStyle.Italic); _indicatorTypeface = new Typeface(editor.FontFamily, FontStyle.Italic);
} }
protected override void ColorizeLine(DocumentLine line) protected override void ColorizeLine(DocumentLine line)