style: border-less window style on Linux platform.

This commit is contained in:
leo 2024-03-14 18:23:36 +08:00
parent f4b396596b
commit 035300a612
23 changed files with 752 additions and 427 deletions

View file

@ -26,6 +26,8 @@ Opensouce Git GUI client.
* Revision Diffs * Revision Diffs
* GitFlow support * GitFlow support
> **Linux** only tested on `Ubuntu 22.04` on `X11`.
## How to use ## How to use
**To use this tool, you need to install Git first.** **To use this tool, you need to install Git first.**
@ -43,7 +45,6 @@ For **macOS** users:
For **Linux** users: For **Linux** users:
* `xdg-open` must be installed to support open native file manager. * `xdg-open` must be installed to support open native file manager.
* Only tested on `Ubuntu 22.04`.
## Screen Shots ## Screen Shots

View file

@ -50,7 +50,7 @@ namespace SourceGit {
manager.AddFontCollection(monospace); manager.AddFontCollection(monospace);
}); });
Native.OS.SetupFonts(builder); Native.OS.SetupApp(builder);
return builder; return builder;
} }

View file

@ -2,13 +2,15 @@
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Media; using Avalonia.Media;
using Avalonia; using Avalonia;
using System.Runtime.InteropServices; using System;
namespace SourceGit.Converters { namespace SourceGit.Converters {
public static class WindowStateConverters { public static class WindowStateConverters {
public static FuncValueConverter<WindowState, Thickness> ToContentMargin = public static FuncValueConverter<WindowState, Thickness> ToContentMargin =
new FuncValueConverter<WindowState, Thickness>(state => { new FuncValueConverter<WindowState, Thickness>(state => {
if (state == WindowState.Maximized && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (OperatingSystem.IsWindows() && state == WindowState.Maximized) {
return new Thickness(6);
} else if (OperatingSystem.IsLinux() && state != WindowState.Maximized) {
return new Thickness(6); return new Thickness(6);
} else { } else {
return new Thickness(0); return new Thickness(0);
@ -17,7 +19,7 @@ namespace SourceGit.Converters {
public static FuncValueConverter<WindowState, GridLength> ToTitleBarHeight = public static FuncValueConverter<WindowState, GridLength> ToTitleBarHeight =
new FuncValueConverter<WindowState, GridLength>(state => { new FuncValueConverter<WindowState, GridLength>(state => {
if (state == WindowState.Maximized && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { if (state == WindowState.Maximized) {
return new GridLength(30); return new GridLength(30);
} else { } else {
return new GridLength(38); return new GridLength(38);

View file

@ -6,7 +6,7 @@ using System.Runtime.Versioning;
namespace SourceGit.Native { namespace SourceGit.Native {
[SupportedOSPlatform("linux")] [SupportedOSPlatform("linux")]
internal class Linux : OS.IBackend { internal class Linux : OS.IBackend {
public void SetupFonts(AppBuilder builder) { public void SetupApp(AppBuilder builder) {
#if USE_FONT_INTER #if USE_FONT_INTER
builder.WithInterFont(); builder.WithInterFont();
#endif #endif

View file

@ -8,7 +8,7 @@ using System.Text;
namespace SourceGit.Native { namespace SourceGit.Native {
[SupportedOSPlatform("macOS")] [SupportedOSPlatform("macOS")]
internal class MacOS : OS.IBackend { internal class MacOS : OS.IBackend {
public void SetupFonts(AppBuilder builder) { public void SetupApp(AppBuilder builder) {
builder.With(new FontManagerOptions() { builder.With(new FontManagerOptions() {
DefaultFamilyName = "PingFang SC", DefaultFamilyName = "PingFang SC",
FontFallbacks = [ FontFallbacks = [

View file

@ -5,7 +5,7 @@ using System.Diagnostics;
namespace SourceGit.Native { namespace SourceGit.Native {
public static class OS { public static class OS {
public interface IBackend { public interface IBackend {
void SetupFonts(AppBuilder builder); void SetupApp(AppBuilder builder);
string FindGitExecutable(); string FindGitExecutable();
string FindVSCode(); string FindVSCode();
@ -41,8 +41,8 @@ namespace SourceGit.Native {
} }
} }
public static void SetupFonts(AppBuilder builder) { public static void SetupApp(AppBuilder builder) {
_backend?.SetupFonts(builder); _backend?.SetupApp(builder);
} }
public static string FindGitExecutable() { public static string FindGitExecutable() {

View file

@ -13,7 +13,7 @@ namespace SourceGit.Native {
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = false)] [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = false)]
private static extern bool PathFindOnPath([In, Out] StringBuilder pszFile, [In] string[] ppszOtherDirs); private static extern bool PathFindOnPath([In, Out] StringBuilder pszFile, [In] string[] ppszOtherDirs);
public void SetupFonts(AppBuilder builder) { public void SetupApp(AppBuilder builder) {
builder.With(new FontManagerOptions() { builder.With(new FontManagerOptions() {
DefaultFamilyName = "Microsoft YaHei UI", DefaultFamilyName = "Microsoft YaHei UI",
FontFallbacks = [ FontFallbacks = [

View file

@ -9,24 +9,32 @@
x:DataType="v:About" x:DataType="v:About"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.About}" Title="{DynamicResource Text.About}"
Background="{DynamicResource Brush.Window}" Background="Transparent"
SizeToContent="WidthAndHeight" SizeToContent="WidthAndHeight"
CanResize="False" CanResize="False"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}"> <!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0" <Path Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
Margin="10,0,0,0" Margin="10,0,0,0"
Data="{StaticResource Icons.Info}" Data="{StaticResource Icons.Info}"
IsVisible="{OnPlatform False, Windows=True}"/> IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}"> <Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow"> <Button Classes="caption_button_macos" Click="CloseWindow">
@ -46,12 +54,12 @@
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="caption_button" Classes="caption_button"
Click="CloseWindow" Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}"> IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/> <Path Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
</Grid> </Grid>
<Grid Grid.Row="1" ColumnDefinitions="Auto,*"> <Grid Grid.Row="1" ColumnDefinitions="Auto,*" Background="{DynamicResource Brush.Window}">
<Image Grid.Column="0" <Image Grid.Column="0"
Width="200" Height="200" Width="200" Height="200"
Margin="8,0" Margin="8,0"

View file

@ -17,6 +17,10 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) { private void CloseWindow(object sender, RoutedEventArgs e) {
Close(); Close();
} }

View file

@ -10,25 +10,32 @@
x:DataType="vm:AssumeUnchangedManager" x:DataType="vm:AssumeUnchangedManager"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.AssumeUnchanged}" Title="{DynamicResource Text.AssumeUnchanged}"
Background="{DynamicResource Brush.Window}" Background="Transparent"
Width="600" Height="400" Width="600" Height="400"
CanResize="False" CanResize="False"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar --> <!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0" <Path Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
Margin="10,0,0,0" Margin="10,0,0,0"
Data="{StaticResource Icons.File.Ignore}" Data="{StaticResource Icons.File.Ignore}"
IsVisible="{OnPlatform False, Windows=True}"/> IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}"> <Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow"> <Button Classes="caption_button_macos" Click="CloseWindow">
@ -48,61 +55,61 @@
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="caption_button" Classes="caption_button"
Click="CloseWindow" Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}"> IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/> <Path Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
</Grid> </Grid>
<!-- Unchanged Files --> <!-- Unchanged Files -->
<DataGrid Grid.Row="1" <Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
Margin="8" <DataGrid Margin="8"
Background="{DynamicResource Brush.Contents}" Background="{DynamicResource Brush.Contents}"
ItemsSource="{Binding Files}" ItemsSource="{Binding Files}"
SelectionMode="Single" SelectionMode="Single"
CanUserReorderColumns="False" CanUserReorderColumns="False"
CanUserResizeColumns="False" CanUserResizeColumns="False"
CanUserSortColumns="False" CanUserSortColumns="False"
IsReadOnly="True" IsReadOnly="True"
HeadersVisibility="None" HeadersVisibility="None"
Focusable="False" Focusable="False"
RowHeight="26" RowHeight="26"
BorderThickness="1" BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border2}" BorderBrush="{DynamicResource Brush.Border2}"
HorizontalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"> VerticalScrollBarVisibility="Auto">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTemplateColumn Width="*"> <DataGridTemplateColumn Width="*">
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/> <Path Width="14" Height="14" Margin="8,0,4,0" Data="{StaticResource Icons.File}"/>
<TextBlock Text="{Binding}" Margin="4,0"/> <TextBlock Text="{Binding}" Margin="4,0"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
<DataGridTemplateColumn> <DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate> <DataGridTemplateColumn.CellTemplate>
<DataTemplate> <DataTemplate>
<Button Classes="icon_button" <Button Classes="icon_button"
Command="{Binding $parent[v:AssumeUnchangedManager].DataContext.(vm:AssumeUnchangedManager).Remove}" Command="{Binding $parent[v:AssumeUnchangedManager].DataContext.(vm:AssumeUnchangedManager).Remove}"
CommandParameter="{Binding}"> CommandParameter="{Binding}">
<Path Width="14" Height="14" Data="{StaticResource Icons.Clear}"/> <Path Width="14" Height="14" Data="{StaticResource Icons.Clear}"/>
</Button> </Button>
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> </DataGridTemplateColumn>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
<!-- Empty --> <!-- Empty -->
<StackPanel Grid.Row="2" <StackPanel Orientation="Vertical"
Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding Files.Count, Converter={x:Static c:IntConverters.IsZero}}">
IsVisible="{Binding Files.Count, Converter={x:Static c:IntConverters.IsZero}}"> <Path Width="48" Height="48" Data="{StaticResource Icons.Empty}" Fill="{DynamicResource Brush.FG2}"/>
<Path Width="48" Height="48" Data="{StaticResource Icons.Empty}" Fill="{DynamicResource Brush.FG2}"/> <TextBlock Margin="0,16,0,0" Text="{DynamicResource Text.AssumeUnchanged.Empty}" Foreground="{DynamicResource Brush.FG2}"/>
<TextBlock Margin="0,16,0,0" Text="{DynamicResource Text.AssumeUnchanged.Empty}" Foreground="{DynamicResource Brush.FG2}"/> </StackPanel>
</StackPanel> </Grid>
</Grid> </Grid>
</Window> </Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
namespace SourceGit.Views { namespace SourceGit.Views {
@ -7,6 +8,10 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) { private void CloseWindow(object sender, RoutedEventArgs e) {
Close(); Close();
} }

View file

@ -12,25 +12,32 @@
x:DataType="vm:Blame" x:DataType="vm:Blame"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Blame}" Title="{DynamicResource Text.Blame}"
Background="Transparent"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
BorderThickness="1"
BorderBrush="{DynamicResource Brush.Border0}"
Background="{DynamicResource Brush.Window}"
MinWidth="1280" MinHeight="720" MinWidth="1280" MinHeight="720"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}"> <Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="30"/> <RowDefinition Height="30"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto"> <Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<!-- Bottom border --> <!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="5" <Border Grid.Column="0" Grid.ColumnSpan="5"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border2}"
IsHitTestVisible="False"/> DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) --> <!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}"> <Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}">
@ -40,19 +47,20 @@
<!-- Icon --> <!-- Icon -->
<Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Data="{StaticResource Icons.Blame}"/> <Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Data="{StaticResource Icons.Blame}"/>
<!-- Title (Hide on Linux) --> <!-- Title -->
<TextBlock Grid.Column="2" Margin="8,0,0,0" Text="{DynamicResource Text.Blame}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center" IsVisible="{OnPlatform True, Linux=False}"/> <TextBlock Grid.Column="2" Margin="8,0,0,0" Text="{DynamicResource Text.Blame}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Blame information --> <!-- Blame information -->
<TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding Title}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/> <TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding Title}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Caption Buttons (Windows) --> <!-- Caption Buttons (Windows/Linux) -->
<Border Grid.Column="4" IsVisible="{OnPlatform False, Windows=True}"> <Border Grid.Column="4" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons/> <v:CaptionButtons/>
</Border> </Border>
</Grid> </Grid>
<Grid Grid.Row="1"> <!-- Body -->
<Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
<!-- Blame View --> <!-- Blame View -->
<v:BlameTextEditor HorizontalScrollBarVisibility="Auto" <v:BlameTextEditor HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
@ -78,5 +86,64 @@
Data="{StaticResource Icons.Loading}" Data="{StaticResource Icons.Loading}"
IsVisible="{Binding Data, Converter={x:Static ObjectConverters.IsNull}}"/> IsVisible="{Binding Data, Converter={x:Static ObjectConverters.IsNull}}"/>
</Grid> </Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid> </Grid>
</Window> </Window>

View file

@ -308,6 +308,27 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) {
if (WindowState == WindowState.Maximized) {
WindowState = WindowState.Normal;
} else {
WindowState = WindowState.Maximized;
}
e.Handled = true;
}
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
protected override void OnClosed(EventArgs e) { protected override void OnClosed(EventArgs e) {
base.OnClosed(e); base.OnClosed(e);
GC.Collect(); GC.Collect();

View file

@ -12,24 +12,31 @@
x:Name="me" x:Name="me"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.FileHistory}" Title="{DynamicResource Text.FileHistory}"
Background="Transparent"
MinWidth="1280" MinHeight="720" MinWidth="1280" MinHeight="720"
BorderThickness="1" ExtendClientAreaToDecorationsHint="True"
BorderBrush="{DynamicResource Brush.Border0}" ExtendClientAreaChromeHints="NoChrome"
Background="{DynamicResource Brush.Window}" SystemDecorations="{OnPlatform Full, Linux=None}">
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}">
<Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}"> <Grid Margin="{Binding #me.WindowState, Converter={x:Static c:WindowStateConverters.ToContentMargin}}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="30"/> <RowDefinition Height="30"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto"> <Grid Grid.Row="0" ColumnDefinitions="Auto,Auto,Auto,*,Auto">
<!-- Bottom border --> <!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="5" <Border Grid.Column="0" Grid.ColumnSpan="5"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) --> <!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}"> <Border Grid.Column="0" IsVisible="{OnPlatform False, macOS=True}">
@ -39,19 +46,20 @@
<!-- Icon --> <!-- Icon -->
<Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Stretch="Uniform" Data="{StaticResource Icons.Histories}"/> <Path Grid.Column="1" Margin="8,0,0,0" Width="12" Height="12" Stretch="Uniform" Data="{StaticResource Icons.Histories}"/>
<!-- Title (Hide on Linux) --> <!-- Title -->
<TextBlock Grid.Column="2" Margin="4,0,0,0" Text="{DynamicResource Text.FileHistory}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center" IsVisible="{OnPlatform True, Linux=False}"/> <TextBlock Grid.Column="2" Margin="4,0,0,0" Text="{DynamicResource Text.FileHistory}" FontWeight="Bold" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Target File --> <!-- Target File -->
<TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding File}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/> <TextBlock Grid.Column="3" Margin="8,0,0,0" Text="{Binding File}" FontSize="11" FontStyle="Italic" IsHitTestVisible="False" VerticalAlignment="Center"/>
<!-- Caption Buttons (Windows) --> <!-- Caption Buttons (Windows/Linux) -->
<Border Grid.Column="4" IsVisible="{OnPlatform False, Windows=true}"> <Border Grid.Column="4" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons/> <v:CaptionButtons/>
</Border> </Border>
</Grid> </Grid>
<Grid Grid.Row="1"> <!-- Body -->
<Grid Grid.Row="1" Background="{DynamicResource Brush.Window}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="300" MinWidth="300" MaxWidth="600"/> <ColumnDefinition Width="300" MinWidth="300" MaxWidth="600"/>
<ColumnDefinition Width="1"/> <ColumnDefinition Width="1"/>
@ -109,5 +117,64 @@
</ContentControl> </ContentControl>
</Grid> </Grid>
</Grid> </Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid> </Grid>
</Window> </Window>

View file

@ -7,6 +7,27 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void MaximizeOrRestoreWindow(object sender, TappedEventArgs e) {
if (WindowState == WindowState.Maximized) {
WindowState = WindowState.Normal;
} else {
WindowState = WindowState.Maximized;
}
e.Handled = true;
}
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void OnPressedSHA(object sender, PointerPressedEventArgs e) { private void OnPressedSHA(object sender, PointerPressedEventArgs e) {
if (sender is TextBlock block) { if (sender is TextBlock block) {
var histories = DataContext as ViewModels.FileHistories; var histories = DataContext as ViewModels.FileHistories;

View file

@ -7,24 +7,32 @@
x:Class="SourceGit.Views.Hotkeys" x:Class="SourceGit.Views.Hotkeys"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Hotkeys}" Title="{DynamicResource Text.Hotkeys}"
Background="{DynamicResource Brush.Window}" Background="Transparent"
SizeToContent="WidthAndHeight" SizeToContent="WidthAndHeight"
CanResize="False" CanResize="False"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}"> <!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0" <Path Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
Margin="10,0,0,0" Margin="10,0,0,0"
Data="{StaticResource Icons.Hotkeys}" Data="{StaticResource Icons.Hotkeys}"
IsVisible="{OnPlatform False, Windows=True}"/> IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}"> <Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow"> <Button Classes="caption_button_macos" Click="CloseWindow">
@ -44,74 +52,77 @@
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="caption_button" Classes="caption_button"
Click="CloseWindow" Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}"> IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/> <Path Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
</Grid> </Grid>
<StackPanel Grid.Row="1" Orientation="Vertical" Margin="16,8,16,16"> <!-- Body -->
<TextBlock Text="{DynamicResource Text.Hotkeys.Global}" <Border Grid.Row="1" Background="{DynamicResource Brush.Window}">
Foreground="{DynamicResource Brush.FG2}" <StackPanel Orientation="Vertical" Margin="16,8,16,16">
FontWeight="Bold" <TextBlock Text="{DynamicResource Text.Hotkeys.Global}"
FontSize="13" Foreground="{DynamicResource Brush.FG2}"
Margin="0,0,0,8"/> FontWeight="Bold"
FontSize="13"
Margin="0,0,0,8"/>
<Grid RowDefinitions="20,20,20,20" ColumnDefinitions="Auto,*"> <Grid RowDefinitions="20,20,20,20" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+T"/> <TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+T"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.NewTab}" /> <TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.NewTab}" />
<TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Ctrl+W" /> <TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Ctrl+W" />
<TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CloseTab}" /> <TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CloseTab}" />
<TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="Ctrl+Tab"/> <TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="Ctrl+Tab"/>
<TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.GotoNextTab}" /> <TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.GotoNextTab}" />
<TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="ESC"/> <TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="ESC"/>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CancelPopup}" /> <TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Global.CancelPopup}" />
</Grid> </Grid>
<TextBlock Text="{DynamicResource Text.Hotkeys.Repo}" <TextBlock Text="{DynamicResource Text.Hotkeys.Repo}"
Foreground="{DynamicResource Brush.FG2}" Foreground="{DynamicResource Brush.FG2}"
FontWeight="Bold" FontWeight="Bold"
FontSize="13" FontSize="13"
Margin="0,8"/> Margin="0,8"/>
<Grid RowDefinitions="20,20,20,20,20" ColumnDefinitions="Auto,*"> <Grid RowDefinitions="20,20,20,20,20" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/> <TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ToggleSearch}" /> <TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ToggleSearch}" />
<TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Ctrl+1"/> <TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Ctrl+1"/>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewHistories}" /> <TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewHistories}" />
<TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="Ctrl+2"/> <TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="Ctrl+2"/>
<TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewChanges}" /> <TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewChanges}" />
<TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="Ctrl+3"/> <TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="Ctrl+3"/>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewStashes}" /> <TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.ViewStashes}" />
<TextBlock Grid.Row="4" Grid.Column="0" Classes="monospace bold" Text="SPACE"/> <TextBlock Grid.Row="4" Grid.Column="0" Classes="monospace bold" Text="SPACE"/>
<TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.StageOrUnstageSelected}" /> <TextBlock Grid.Row="4" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.Repo.StageOrUnstageSelected}" />
</Grid> </Grid>
<TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}" <TextBlock Text="{DynamicResource Text.Hotkeys.TextEditor}"
Foreground="{DynamicResource Brush.FG2}" Foreground="{DynamicResource Brush.FG2}"
FontWeight="Bold" FontWeight="Bold"
FontSize="13" FontSize="13"
Margin="0,8"/> Margin="0,8"/>
<Grid RowDefinitions="20,20,20,20" ColumnDefinitions="Auto,*"> <Grid RowDefinitions="20,20,20,20" ColumnDefinitions="Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/> <TextBlock Grid.Row="0" Grid.Column="0" Classes="monospace bold" Text="Ctrl+F"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.Search}" /> <TextBlock Grid.Row="0" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.Search}" />
<TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Shift+F3"/> <TextBlock Grid.Row="1" Grid.Column="0" Classes="monospace bold" Text="Shift+F3"/>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.GotoPrevMatch}" /> <TextBlock Grid.Row="1" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.GotoPrevMatch}" />
<TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="F3"/> <TextBlock Grid.Row="2" Grid.Column="0" Classes="monospace bold" Text="F3"/>
<TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.GotoNextMatch}" /> <TextBlock Grid.Row="2" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.GotoNextMatch}" />
<TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="ESC"/> <TextBlock Grid.Row="3" Grid.Column="0" Classes="monospace bold" Text="ESC"/>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.CloseSearch}" /> <TextBlock Grid.Row="3" Grid.Column="1" Margin="16,0,0,0" Text="{DynamicResource Text.Hotkeys.TextEditor.CloseSearch}" />
</Grid> </Grid>
</StackPanel> </StackPanel>
</Border>
</Grid> </Grid>
</Window> </Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
namespace SourceGit.Views { namespace SourceGit.Views {
@ -7,6 +8,10 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) { private void CloseWindow(object sender, RoutedEventArgs e) {
Close(); Close();
} }

View file

@ -12,13 +12,12 @@
x:Name="me" x:Name="me"
Icon="/App.ico" Icon="/App.ico"
Title="SourceGit" Title="SourceGit"
BorderThickness="1" Background="Transparent"
BorderBrush="{DynamicResource Brush.Border0}"
Background="{DynamicResource Brush.Window}"
MinWidth="1280" MinHeight="720" MinWidth="1280" MinHeight="720"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Window.Resources> <Window.Resources>
<SolidColorBrush x:Key="SystemControlErrorTextForegroundBrush" Color="Red"/> <SolidColorBrush x:Key="SystemControlErrorTextForegroundBrush" Color="Red"/>
</Window.Resources> </Window.Resources>
@ -29,12 +28,20 @@
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- Custom TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto">
<!-- Bottom border --> <!-- Bottom border -->
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> DoubleTapped="MaximizeOrRestoreWindow"
PointerPressed="BeginMoveWindow"/>
<!-- Caption Buttons (macOS) --> <!-- Caption Buttons (macOS) -->
<Border Grid.Column="0" VerticalAlignment="Stretch" Margin="2,0,8,3" IsVisible="{OnPlatform False, macOS=True}"> <Border Grid.Column="0" VerticalAlignment="Stretch" Margin="2,0,8,3" IsVisible="{OnPlatform False, macOS=True}">
@ -233,8 +240,8 @@
</Button> </Button>
</StackPanel> </StackPanel>
<!-- Caption Buttons (Windows)--> <!-- Caption Buttons (Windows/Linux)-->
<Border Grid.Column="2" Margin="32,0,0,0" IsVisible="{OnPlatform False, Windows=True}"> <Border Grid.Column="2" Margin="32,0,0,0" IsVisible="{OnPlatform True, macOS=False}">
<v:CaptionButtons Height="30" VerticalAlignment="Top"/> <v:CaptionButtons Height="30" VerticalAlignment="Top"/>
</Border> </Border>
</Grid> </Grid>
@ -364,5 +371,64 @@
</ItemsControl> </ItemsControl>
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
<!-- Custom window sizer for Linux -->
<Grid Grid.Row="0" Grid.RowSpan="2" IsVisible="{OnPlatform False, Linux=True}">
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top"
Cursor="TopLeftCorner"
Tag="{x:Static WindowEdge.NorthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Top"
Cursor="TopSide"
Tag="{x:Static WindowEdge.North}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Top"
Cursor="TopRightCorner"
Tag="{x:Static WindowEdge.NorthEast}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Stretch"
Cursor="LeftSide"
Tag="{x:Static WindowEdge.West}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Margin="0,4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Stretch"
Cursor="RightSide"
Tag="{x:Static WindowEdge.East}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Bottom"
Cursor="BottomLeftCorner"
Tag="{x:Static WindowEdge.SouthWest}"
PointerPressed="CustomResizeWindow"/>
<Border Height="4" Margin="4,0"
Background="Transparent"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom"
Cursor="BottomSide"
Tag="{x:Static WindowEdge.South}"
PointerPressed="CustomResizeWindow"/>
<Border Width="4" Height="4"
Background="Transparent"
HorizontalAlignment="Right" VerticalAlignment="Bottom"
Cursor="BottomRightCorner"
Tag="{x:Static WindowEdge.SouthEast}"
PointerPressed="CustomResizeWindow"/>
</Grid>
</Grid> </Grid>
</Window> </Window>

View file

@ -126,6 +126,14 @@ namespace SourceGit.Views {
e.Handled = true; e.Handled = true;
} }
private void CustomResizeWindow(object sender, PointerPressedEventArgs e) {
if (sender is Border border) {
if (border.Tag is WindowEdge edge) {
BeginResizeDrag(edge, e);
}
}
}
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) { private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e); BeginMoveDrag(e);
} }

View file

@ -13,24 +13,32 @@
x:Name="me" x:Name="me"
Icon="/App.ico" Icon="/App.ico"
Title="{DynamicResource Text.Preference}" Title="{DynamicResource Text.Preference}"
Background="{DynamicResource Brush.Window}" Background="Transparent"
Width="600" SizeToContent="Height" Width="600" SizeToContent="Height"
CanResize="False" CanResize="False"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,Auto"> <Grid RowDefinitions="Auto,Auto">
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}"> <!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- TitleBar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
IsHitTestVisible="False"/> PointerPressed="BeginMoveWindow"/>
<Path Grid.Column="0" <Path Grid.Column="0"
Width="14" Height="14" Width="14" Height="14"
Data="{StaticResource Icons.Settings2}" Data="{StaticResource Icons.Settings2}"
Margin="10,0,0,0" Margin="10,0,0,0"
IsVisible="{OnPlatform False, Windows=True}"/> IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}"> <Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow"> <Button Classes="caption_button_macos" Click="CloseWindow">
@ -47,286 +55,289 @@
HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False"/> IsHitTestVisible="False"/>
<Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform False, Windows=True}"> <Button Grid.Column="2" Classes="caption_button" Click="CloseWindow" IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/> <Path Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
</Grid> </Grid>
<TabControl Grid.Row="1"> <!-- Body -->
<TabItem> <Border Grid.Row="1" Background="{DynamicResource Brush.Window}">
<TabItem.Header> <TabControl>
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/> <TabItem>
</TabItem.Header> <TabItem.Header>
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="Auto,*"> <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.General}"/>
<TextBlock Grid.Row="0" Grid.Column="0" </TabItem.Header>
Text="{DynamicResource Text.Preference.General.Locale}" <Grid Margin="8" RowDefinitions="32,32,32,32,32,32" ColumnDefinitions="Auto,*">
HorizontalAlignment="Right" <TextBlock Grid.Row="0" Grid.Column="0"
Margin="0,0,16,0"/> Text="{DynamicResource Text.Preference.General.Locale}"
<ComboBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right"
MinHeight="28" Margin="0,0,16,0"/>
Padding="8,0" <ComboBox Grid.Row="0" Grid.Column="1"
HorizontalAlignment="Stretch" MinHeight="28"
ItemsSource="{Binding Source={x:Static m:Locale.Supported}}" Padding="8,0"
DisplayMemberBinding="{Binding Name, x:DataType=m:Locale}" HorizontalAlignment="Stretch"
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/> ItemsSource="{Binding Source={x:Static m:Locale.Supported}}"
DisplayMemberBinding="{Binding Name, x:DataType=m:Locale}"
SelectedItem="{Binding Locale, Mode=TwoWay, Converter={x:Static c:StringConverters.ToLocale}}"/>
<TextBlock Grid.Row="1" Grid.Column="0" <TextBlock Grid.Row="1" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.AvatarServer}" Text="{DynamicResource Text.Preference.General.AvatarServer}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<ComboBox Grid.Row="1" Grid.Column="1" <ComboBox Grid.Row="1" Grid.Column="1"
MinHeight="28" MinHeight="28"
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
SelectedItem="{Binding AvatarServer, Mode=TwoWay}"> SelectedItem="{Binding AvatarServer, Mode=TwoWay}">
<ComboBox.Items> <ComboBox.Items>
<sys:String>https://www.gravatar.com/avatar/</sys:String> <sys:String>https://www.gravatar.com/avatar/</sys:String>
<sys:String>https://cravatar.cn/avatar/</sys:String> <sys:String>https://cravatar.cn/avatar/</sys:String>
</ComboBox.Items> </ComboBox.Items>
</ComboBox> </ComboBox>
<TextBlock Grid.Row="2" Grid.Column="0" <TextBlock Grid.Row="2" Grid.Column="0"
Text="{DynamicResource Text.Preference.General.Theme}" Text="{DynamicResource Text.Preference.General.Theme}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<ComboBox Grid.Row="2" Grid.Column="1" <ComboBox Grid.Row="2" Grid.Column="1"
MinHeight="28" MinHeight="28"
Padding="8,0" Padding="8,0"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
DisplayMemberBinding="{Binding Key, x:DataType=ThemeVariant}" DisplayMemberBinding="{Binding Key, x:DataType=ThemeVariant}"
SelectedItem="{Binding Theme, Mode=TwoWay, Converter={x:Static c:StringConverters.ToTheme}}"> SelectedItem="{Binding Theme, Mode=TwoWay, Converter={x:Static c:StringConverters.ToTheme}}">
<ComboBox.Items> <ComboBox.Items>
<ThemeVariant>Default</ThemeVariant> <ThemeVariant>Default</ThemeVariant>
<ThemeVariant>Dark</ThemeVariant> <ThemeVariant>Dark</ThemeVariant>
<ThemeVariant>Light</ThemeVariant> <ThemeVariant>Light</ThemeVariant>
</ComboBox.Items> </ComboBox.Items>
</ComboBox> </ComboBox>
<TextBlock Grid.Row="3" Grid.Column="0" <TextBlock Grid.Row="3" 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="3" 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"
IsSnapToTickEnabled="True" IsSnapToTickEnabled="True"
VerticalAlignment="Center" VerticalAlignment="Center"
Foreground="{DynamicResource Brush.Border1}" Foreground="{DynamicResource Brush.Border1}"
Value="{Binding MaxHistoryCommits, Mode=TwoWay}"> Value="{Binding MaxHistoryCommits, Mode=TwoWay}">
<Slider.Resources> <Slider.Resources>
<Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness> <Thickness x:Key="SliderTopHeaderMargin">0,0,0,4</Thickness>
<GridLength x:Key="SliderPreContentMargin">0</GridLength> <GridLength x:Key="SliderPreContentMargin">0</GridLength>
<GridLength x:Key="SliderPostContentMargin">0</GridLength> <GridLength x:Key="SliderPostContentMargin">0</GridLength>
<CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius> <CornerRadius x:Key="SliderThumbCornerRadius">8</CornerRadius>
<x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double> <x:Double x:Key="SliderHorizontalThumbWidth">16</x:Double>
<x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double> <x:Double x:Key="SliderHorizontalThumbHeight">16</x:Double>
</Slider.Resources> </Slider.Resources>
</Slider> </Slider>
<TextBlock Grid.Column="1" <TextBlock Grid.Column="1"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
Text="{Binding MaxHistoryCommits}"/> Text="{Binding MaxHistoryCommits}"/>
</Grid>
<CheckBox Grid.Row="4" Grid.Column="1"
Content="{DynamicResource Text.Preference.General.RestoreTabs}"
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/>
<CheckBox Grid.Row="5" Grid.Column="1"
Height="32"
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/>
</Grid> </Grid>
</TabItem>
<CheckBox Grid.Row="4" Grid.Column="1" <TabItem>
Content="{DynamicResource Text.Preference.General.RestoreTabs}" <TabItem.Header>
IsChecked="{Binding RestoreTabs, Mode=TwoWay}"/> <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.Git}"/>
</TabItem.Header>
<CheckBox Grid.Row="5" Grid.Column="1" <Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*">
Height="32" <TextBlock Grid.Row="0" Grid.Column="0"
Content="{DynamicResource Text.Preference.General.UseFixedTabWidth}" Text="{DynamicResource Text.Preference.Git.Path}"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=UseFixedTabWidth, Mode=TwoWay}"/> HorizontalAlignment="Right"
</Grid> Margin="0,0,16,0"/>
</TabItem> <TextBox Grid.Row="0" Grid.Column="1"
Height="28"
CornerRadius="3"
Text="{Binding GitInstallPath, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGitExecutable">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<TabItem> <TextBlock Grid.Row="1" Grid.Column="0"
<TabItem.Header> Text="{DynamicResource Text.Preference.Git.Version}"
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.Git}"/> HorizontalAlignment="Right"
</TabItem.Header> Margin="0,0,16,0"/>
<TextBlock Grid.Row="1" Grid.Column="1"
x:Name="txtVersion"/>
<Grid Margin="8" RowDefinitions="32,32,32,32,32,32,32" ColumnDefinitions="Auto,*"> <TextBlock Grid.Row="2" Grid.Column="0"
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Text.Preference.Git.DefaultCloneDir}"
Text="{DynamicResource Text.Preference.Git.Path}" HorizontalAlignment="Right"
HorizontalAlignment="Right" Margin="0,0,16,0"/>
Margin="0,0,16,0"/> <TextBox Grid.Row="2" Grid.Column="1"
<TextBox Grid.Row="0" Grid.Column="1" Height="28"
Height="28" CornerRadius="3"
CornerRadius="3" Text="{Binding GitDefaultCloneDir, Mode=TwoWay}">
Text="{Binding GitInstallPath, Mode=TwoWay}"> <TextBox.InnerRightContent>
<TextBox.InnerRightContent> <Button Classes="icon_button" Width="30" Height="30" Click="SelectDefaultCloneDir">
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGitExecutable"> <Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/> </Button>
</Button> </TextBox.InnerRightContent>
</TextBox.InnerRightContent> </TextBox>
</TextBox>
<TextBlock Grid.Row="1" Grid.Column="0" <TextBlock Grid.Row="3" Grid.Column="0"
Text="{DynamicResource Text.Preference.Git.Version}" Text="{DynamicResource Text.Preference.Git.User}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<TextBlock Grid.Row="1" Grid.Column="1" <TextBox Grid.Row="3" Grid.Column="1"
x:Name="txtVersion"/> Height="28"
CornerRadius="3"
Text="{Binding #me.DefaultUser, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.Git.User.Placeholder}"/>
<TextBlock Grid.Row="2" Grid.Column="0" <TextBlock Grid.Row="4" Grid.Column="0"
Text="{DynamicResource Text.Preference.Git.DefaultCloneDir}" Text="{DynamicResource Text.Preference.Git.Email}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<TextBox Grid.Row="2" Grid.Column="1" <TextBox Grid.Row="4" Grid.Column="1"
Height="28" Height="28"
CornerRadius="3" CornerRadius="3"
Text="{Binding GitDefaultCloneDir, Mode=TwoWay}"> Text="{Binding #me.DefaultEmail, Mode=TwoWay}"
<TextBox.InnerRightContent> Watermark="{DynamicResource Text.Preference.Git.Email.Placeholder}"/>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectDefaultCloneDir">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<TextBlock Grid.Row="3" Grid.Column="0" <TextBlock Grid.Row="5" Grid.Column="0"
Text="{DynamicResource Text.Preference.Git.User}" Text="{DynamicResource Text.Preference.Git.CRLF}"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,0,16,0"/> Margin="0,0,16,0"/>
<TextBox Grid.Row="3" Grid.Column="1" <ComboBox Grid.Row="5" Grid.Column="1"
Height="28" MinHeight="28"
CornerRadius="3" Padding="8,0"
Text="{Binding #me.DefaultUser, Mode=TwoWay}" HorizontalAlignment="Stretch"
Watermark="{DynamicResource Text.Preference.Git.User.Placeholder}"/> ItemsSource="{Binding Source={x:Static m:CRLFMode.Supported}}"
SelectedItem="{Binding #me.CRLFMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:CRLFMode}">
<Grid ColumnDefinitions="64,*">
<TextBlock Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Grid.Column="1" Text="{Binding Desc}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Right"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="4" Grid.Column="0" <CheckBox Grid.Row="6" Grid.Column="1"
Text="{DynamicResource Text.Preference.Git.Email}" Content="{DynamicResource Text.Preference.Git.AutoFetch}"
HorizontalAlignment="Right" IsChecked="{Binding GitAutoFetch, Mode=TwoWay}"/>
Margin="0,0,16,0"/> </Grid>
<TextBox Grid.Row="4" Grid.Column="1" </TabItem>
Height="28"
CornerRadius="3"
Text="{Binding #me.DefaultEmail, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.Git.Email.Placeholder}"/>
<TextBlock Grid.Row="5" Grid.Column="0" <TabItem>
Text="{DynamicResource Text.Preference.Git.CRLF}" <TabItem.Header>
HorizontalAlignment="Right" <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.GPG}"/>
Margin="0,0,16,0"/> </TabItem.Header>
<ComboBox Grid.Row="5" Grid.Column="1"
MinHeight="28"
Padding="8,0"
HorizontalAlignment="Stretch"
ItemsSource="{Binding Source={x:Static m:CRLFMode.Supported}}"
SelectedItem="{Binding #me.CRLFMode, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate x:DataType="{x:Type m:CRLFMode}">
<Grid ColumnDefinitions="64,*">
<TextBlock Grid.Column="0" Text="{Binding Name}"/>
<TextBlock Grid.Column="1" Text="{Binding Desc}" Foreground="{DynamicResource Brush.FG2}" HorizontalAlignment="Right"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<CheckBox Grid.Row="6" Grid.Column="1" <Grid Margin="8" RowDefinitions="32,32,32" ColumnDefinitions="Auto,*">
Content="{DynamicResource Text.Preference.Git.AutoFetch}" <TextBlock Grid.Row="0" Grid.Column="0"
IsChecked="{Binding GitAutoFetch, Mode=TwoWay}"/> Text="{DynamicResource Text.Preference.GPG.Enabled}"
</Grid> HorizontalAlignment="Right"
</TabItem> Margin="0,0,16,0"/>
<CheckBox Grid.Row="0" Grid.Column="1"
IsChecked="{Binding #me.EnableGPGSigning, Mode=TwoWay}"/>
<TabItem> <TextBlock Grid.Row="1" Grid.Column="0"
<TabItem.Header> Text="{DynamicResource Text.Preference.GPG.Path}"
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.GPG}"/> HorizontalAlignment="Right"
</TabItem.Header> Margin="0,0,16,0"/>
<TextBox Grid.Row="1" Grid.Column="1"
x:Name="txtGPGExecutable"
Height="28"
CornerRadius="3"
Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<Grid Margin="8" RowDefinitions="32,32,32" ColumnDefinitions="Auto,*"> <TextBlock Grid.Row="2" Grid.Column="0"
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Text.Preference.GPG.UserKey}"
Text="{DynamicResource Text.Preference.GPG.Enabled}" HorizontalAlignment="Right"
HorizontalAlignment="Right" Margin="0,0,16,0"/>
Margin="0,0,16,0"/> <TextBox Grid.Row="2" Grid.Column="1"
<CheckBox Grid.Row="0" Grid.Column="1" Height="28"
IsChecked="{Binding #me.EnableGPGSigning, Mode=TwoWay}"/> CornerRadius="3"
Text="{Binding #me.GPGUserKey, Mode=TwoWay}"
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"/>
</Grid>
</TabItem>
<TextBlock Grid.Row="1" Grid.Column="0" <TabItem>
Text="{DynamicResource Text.Preference.GPG.Path}" <TabItem.Header>
HorizontalAlignment="Right" <TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.Merger}"/>
Margin="0,0,16,0"/> </TabItem.Header>
<TextBox Grid.Row="1" Grid.Column="1"
x:Name="txtGPGExecutable"
Height="28"
CornerRadius="3"
Text="{Binding #me.GPGExecutableFile, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectGPGExecutable">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<TextBlock Grid.Row="2" Grid.Column="0" <Grid Margin="8" RowDefinitions="32,32,Auto,Auto" ColumnDefinitions="Auto,*">
Text="{DynamicResource Text.Preference.GPG.UserKey}" <TextBlock Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Right" Text="{DynamicResource Text.Preference.Merger.Type}"
Margin="0,0,16,0"/> HorizontalAlignment="Right"
<TextBox Grid.Row="2" Grid.Column="1" Margin="0,0,16,0"/>
Height="28" <ComboBox Grid.Row="0" Grid.Column="1"
CornerRadius="3" MinHeight="28"
Text="{Binding #me.GPGUserKey, Mode=TwoWay}" Padding="8,0"
Watermark="{DynamicResource Text.Preference.GPG.UserKey.Placeholder}"/> HorizontalAlignment="Stretch"
</Grid> ItemsSource="{Binding Source={x:Static m:ExternalMergeTools.Supported}}"
</TabItem> DisplayMemberBinding="{Binding Name, x:DataType=m:ExternalMergeTools}"
SelectedIndex="{Binding ExternalMergeToolType, Mode=TwoWay}"/>
<TabItem> <TextBlock Grid.Row="1" Grid.Column="0"
<TabItem.Header> Text="{DynamicResource Text.Preference.Merger.Path}"
<TextBlock Classes="tab_header" Text="{DynamicResource Text.Preference.Merger}"/> HorizontalAlignment="Right"
</TabItem.Header> Margin="0,0,16,0"/>
<TextBox Grid.Row="1" Grid.Column="1"
Height="28"
CornerRadius="3"
Text="{Binding ExternalMergeToolPath, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectExternalMergeTool">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<Grid Margin="8" RowDefinitions="32,32,Auto,Auto" ColumnDefinitions="Auto,*"> <TextBlock Grid.Row="2" Grid.Column="0"
<TextBlock Grid.Row="0" Grid.Column="0" Text="{DynamicResource Text.Preference.Merger.CustomMergeCmd}"
Text="{DynamicResource Text.Preference.Merger.Type}" HorizontalAlignment="Right" VerticalAlignment="Center"
HorizontalAlignment="Right" Margin="0,0,16,0"
Margin="0,0,16,0"/> IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
<ComboBox Grid.Row="0" Grid.Column="1" <TextBox Grid.Row="2" Grid.Column="1"
MinHeight="28" Height="28" Margin="0,2"
Padding="8,0" CornerRadius="3"
HorizontalAlignment="Stretch" Text="{Binding ExternalMergeToolCmd, Mode=TwoWay}"
ItemsSource="{Binding Source={x:Static m:ExternalMergeTools.Supported}}"
DisplayMemberBinding="{Binding Name, x:DataType=m:ExternalMergeTools}"
SelectedIndex="{Binding ExternalMergeToolType, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Grid.Column="0"
Text="{DynamicResource Text.Preference.Merger.Path}"
HorizontalAlignment="Right"
Margin="0,0,16,0"/>
<TextBox Grid.Row="1" Grid.Column="1"
Height="28"
CornerRadius="3"
Text="{Binding ExternalMergeToolPath, Mode=TwoWay}">
<TextBox.InnerRightContent>
<Button Classes="icon_button" Width="30" Height="30" Click="SelectExternalMergeTool">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</TextBox.InnerRightContent>
</TextBox>
<TextBlock Grid.Row="2" Grid.Column="0"
Text="{DynamicResource Text.Preference.Merger.CustomMergeCmd}"
HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,16,0"
IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/> IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
<TextBox Grid.Row="2" Grid.Column="1"
Height="28" Margin="0,2"
CornerRadius="3"
Text="{Binding ExternalMergeToolCmd, Mode=TwoWay}"
IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
<TextBlock Grid.Row="3" Grid.Column="0" <TextBlock Grid.Row="3" Grid.Column="0"
Text="{DynamicResource Text.Preference.Merger.CustomDiffCmd}" Text="{DynamicResource Text.Preference.Merger.CustomDiffCmd}"
HorizontalAlignment="Right" VerticalAlignment="Center" HorizontalAlignment="Right" VerticalAlignment="Center"
Margin="0,0,16,0" Margin="0,0,16,0"
IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
<TextBox Grid.Row="3" Grid.Column="1"
Height="28" Margin="0,2"
CornerRadius="3"
Text="{Binding ExternalMergeToolDiffCmd, Mode=TwoWay}"
IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/> IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
<TextBox Grid.Row="3" Grid.Column="1" </Grid>
Height="28" Margin="0,2" </TabItem>
CornerRadius="3" </TabControl>
Text="{Binding ExternalMergeToolDiffCmd, Mode=TwoWay}" </Border>
IsVisible="{Binding ExternalMergeToolType, Converter={x:Static c:IntConverters.IsZero}}"/>
</Grid>
</TabItem>
</TabControl>
</Grid> </Grid>
</Window> </Window>

View file

@ -1,4 +1,5 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using System; using System;
@ -58,6 +59,10 @@ namespace SourceGit.Views {
txtVersion.Text = ver; txtVersion.Text = ver;
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) { private void CloseWindow(object sender, RoutedEventArgs e) {
var cmd = new Commands.Config(null); var cmd = new Commands.Config(null);

View file

@ -9,15 +9,27 @@
x:Class="SourceGit.Views.Statistics" x:Class="SourceGit.Views.Statistics"
x:DataType="vm:Statistics" x:DataType="vm:Statistics"
Title="{DynamicResource Text.Statistics}" Title="{DynamicResource Text.Statistics}"
Background="{DynamicResource Brush.Window}" Background="Transparent"
Width="800" Height="450" Width="800" Height="450"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
CanResize="False" CanResize="False"
ExtendClientAreaToDecorationsHint="{OnPlatform True, Linux=False}" ExtendClientAreaToDecorationsHint="True"
ExtendClientAreaChromeHints="{OnPlatform NoChrome, Linux=Default}"> ExtendClientAreaChromeHints="NoChrome"
SystemDecorations="{OnPlatform Full, Linux=None}">
<Grid RowDefinitions="Auto,Auto,*"> <Grid RowDefinitions="Auto,Auto,*">
<!-- Custom window shadow for Linux -->
<Border Grid.Row="0" Grid.RowSpan="3"
Background="{DynamicResource Brush.Window}"
Effect="drop-shadow(0 0 6 #A0000000)"
IsVisible="{OnPlatform False, Linux=True}"/>
<!-- Window BG -->
<Border Grid.Row="1" Grid.RowSpan="2"
Background="{DynamicResource Brush.Window}"
IsVisible="{OnPlatform True, Linux=False}"/>
<!-- Title bar --> <!-- Title bar -->
<Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30" IsVisible="{OnPlatform True, Linux=False}"> <Grid Grid.Row="0" ColumnDefinitions="Auto,*,Auto" Height="30">
<Border Grid.Column="0" Grid.ColumnSpan="3" <Border Grid.Column="0" Grid.ColumnSpan="3"
Background="{DynamicResource Brush.TitleBar}" Background="{DynamicResource Brush.TitleBar}"
BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource Brush.Border0}"
@ -27,7 +39,7 @@
Width="14" Height="14" Width="14" Height="14"
Margin="10,0,0,0" Margin="10,0,0,0"
Data="{StaticResource Icons.Statistics}" Data="{StaticResource Icons.Statistics}"
IsVisible="{OnPlatform False, Windows=True}"/> IsVisible="{OnPlatform True, macOS=False}"/>
<Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}"> <Grid Grid.Column="0" Classes="caption_button_box" Margin="2,4,0,0" IsVisible="{OnPlatform False, macOS=True}">
<Button Classes="caption_button_macos" Click="CloseWindow"> <Button Classes="caption_button_macos" Click="CloseWindow">
@ -47,7 +59,7 @@
<Button Grid.Column="2" <Button Grid.Column="2"
Classes="caption_button" Classes="caption_button"
Click="CloseWindow" Click="CloseWindow"
IsVisible="{OnPlatform False, Windows=True}"> IsVisible="{OnPlatform True, macOS=False}">
<Path Data="{StaticResource Icons.Window.Close}"/> <Path Data="{StaticResource Icons.Window.Close}"/>
</Button> </Button>
</Grid> </Grid>

View file

@ -191,6 +191,10 @@ namespace SourceGit.Views {
InitializeComponent(); InitializeComponent();
} }
private void BeginMoveWindow(object sender, PointerPressedEventArgs e) {
BeginMoveDrag(e);
}
private void CloseWindow(object sender, RoutedEventArgs e) { private void CloseWindow(object sender, RoutedEventArgs e) {
Close(); Close();
} }