Skip to content

Commit 59a7c74

Browse files
committed
fix: try to fix issue #338
* use custom control to draw badges
1 parent f3406e9 commit 59a7c74

File tree

5 files changed

+214
-37
lines changed

5 files changed

+214
-37
lines changed

src/ViewModels/BranchTreeNode.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@ public bool IsBranch
3636
get => Backend is Models.Branch;
3737
}
3838

39-
public string TrackStatus
40-
{
41-
get => Backend is Models.Branch { IsLocal: true } branch ? branch.TrackStatus.ToString() : string.Empty;
42-
}
43-
4439
public FontWeight NameFontWeight
4540
{
4641
get => Backend is Models.Branch { IsCurrent: true } ? FontWeight.Bold : FontWeight.Regular;

src/Views/BranchTree.axaml

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,13 @@
8383
FontWeight="{Binding NameFontWeight}"/>
8484

8585
<!-- Tracking status -->
86-
<Border Grid.Column="2"
87-
Margin="8,0"
88-
Height="18"
89-
CornerRadius="9"
90-
VerticalAlignment="Center"
91-
Background="{DynamicResource Brush.Badge}"
92-
IsVisible="{Binding TrackStatus, Converter={x:Static StringConverters.IsNotNullOrEmpty}}">
93-
<TextBlock Classes="primary"
94-
FontSize="10"
95-
HorizontalAlignment="Center"
96-
Margin="9,0"
97-
Text="{Binding TrackStatus}"
98-
Foreground="{DynamicResource Brush.BadgeFG}"/>
99-
</Border>
86+
<v:BranchTreeNodeTrackStatusPresenter Grid.Column="2"
87+
Margin="8,0"
88+
VerticalAlignment="Center"
89+
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
90+
FontSize="10"
91+
Foreground="{DynamicResource Brush.BadgeFG}"
92+
Background="{DynamicResource Brush.Badge}"/>
10093

10194
<!-- Filter Toggle Button -->
10295
<ToggleButton Grid.Column="3"

src/Views/BranchTree.axaml.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Globalization;
34

45
using Avalonia;
56
using Avalonia.Collections;
@@ -104,6 +105,99 @@ protected override void OnPointerPressed(PointerPressedEventArgs e)
104105
}
105106
}
106107

108+
public class BranchTreeNodeTrackStatusPresenter : Control
109+
{
110+
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
111+
TextBlock.FontFamilyProperty.AddOwner<BranchTreeNodeTrackStatusPresenter>();
112+
113+
public FontFamily FontFamily
114+
{
115+
get => GetValue(FontFamilyProperty);
116+
set => SetValue(FontFamilyProperty, value);
117+
}
118+
119+
public static readonly StyledProperty<double> FontSizeProperty =
120+
TextBlock.FontSizeProperty.AddOwner<BranchTreeNodeTrackStatusPresenter>();
121+
122+
public double FontSize
123+
{
124+
get => GetValue(FontSizeProperty);
125+
set => SetValue(FontSizeProperty, value);
126+
}
127+
128+
public static readonly StyledProperty<IBrush> ForegroundProperty =
129+
AvaloniaProperty.Register<BranchTreeNodeTrackStatusPresenter, IBrush>(nameof(Foreground), Brushes.White);
130+
131+
public IBrush Foreground
132+
{
133+
get => GetValue(ForegroundProperty);
134+
set => SetValue(ForegroundProperty, value);
135+
}
136+
137+
public static readonly StyledProperty<IBrush> BackgroundProperty =
138+
AvaloniaProperty.Register<BranchTreeNodeTrackStatusPresenter, IBrush>(nameof(Background), Brushes.White);
139+
140+
public IBrush Background
141+
{
142+
get => GetValue(BackgroundProperty);
143+
set => SetValue(BackgroundProperty, value);
144+
}
145+
146+
static BranchTreeNodeTrackStatusPresenter()
147+
{
148+
AffectsMeasure<BranchTreeNodeTrackStatusPresenter>(
149+
FontSizeProperty,
150+
FontFamilyProperty,
151+
ForegroundProperty);
152+
153+
AffectsRender<BranchTreeNodeTrackStatusPresenter>(
154+
ForegroundProperty,
155+
BackgroundProperty);
156+
}
157+
158+
public override void Render(DrawingContext context)
159+
{
160+
base.Render(context);
161+
162+
if (_label != null)
163+
{
164+
context.DrawRectangle(Background, null, new RoundedRect(new Rect(0, 0, _label.Width + 18, 18), new CornerRadius(9)));
165+
context.DrawText(_label, new Point(9, 9 - _label.Height * 0.5));
166+
}
167+
}
168+
169+
protected override void OnDataContextChanged(EventArgs e)
170+
{
171+
base.OnDataContextChanged(e);
172+
InvalidateMeasure();
173+
InvalidateVisual();
174+
}
175+
176+
protected override Size MeasureOverride(Size availableSize)
177+
{
178+
_label = null;
179+
180+
if (DataContext is ViewModels.BranchTreeNode { Backend: Models.Branch branch })
181+
{
182+
var status = branch.TrackStatus.ToString();
183+
if (!string.IsNullOrEmpty(status))
184+
{
185+
_label = new FormattedText(
186+
status,
187+
CultureInfo.CurrentCulture,
188+
FlowDirection.LeftToRight,
189+
new Typeface(FontFamily),
190+
FontSize,
191+
Foreground);
192+
}
193+
}
194+
195+
return _label != null ? new Size(_label.Width + 18, 18) : new Size(0, 0);
196+
}
197+
198+
private FormattedText _label = null;
199+
}
200+
107201
public partial class BranchTree : UserControl
108202
{
109203
public static readonly StyledProperty<List<ViewModels.BranchTreeNode>> NodesProperty =

src/Views/Repository.axaml

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,31 +91,29 @@
9191
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
9292
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Changes}"/>
9393
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.WorkingCopy}"/>
94-
<Border Grid.Column="2"
95-
Margin="6,0"
96-
Height="18"
97-
CornerRadius="9"
98-
VerticalAlignment="Center"
99-
Background="{DynamicResource Brush.Badge}"
100-
IsVisible="{Binding LocalChangesCount, Converter={x:Static c:IntConverters.IsGreaterThanZero}}">
101-
<TextBlock Classes="primary" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding LocalChangesCount}" Foreground="{DynamicResource Brush.BadgeFG}"/>
102-
</Border>
94+
<v:CounterPresenter Grid.Column="2"
95+
Margin="6,0"
96+
VerticalAlignment="Center"
97+
Count="{Binding LocalChangesCount}"
98+
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
99+
FontSize="10"
100+
Foreground="{DynamicResource Brush.BadgeFG}"
101+
Background="{DynamicResource Brush.Badge}"/>
103102
</Grid>
104103
</ListBoxItem>
105104

106105
<ListBoxItem>
107106
<Grid Classes="view_mode" ColumnDefinitions="32,*,Auto">
108107
<Path Grid.Column="0" Width="12" Height="12" Data="{StaticResource Icons.Stashes}"/>
109108
<TextBlock Grid.Column="1" Classes="primary" Text="{DynamicResource Text.Stashes}"/>
110-
<Border Grid.Column="2"
111-
Margin="6,0"
112-
Height="18"
113-
CornerRadius="9"
114-
VerticalAlignment="Center"
115-
Background="{DynamicResource Brush.Badge}"
116-
IsVisible="{Binding StashesCount, Converter={x:Static c:IntConverters.IsGreaterThanZero}}">
117-
<TextBlock Classes="primary" FontSize="10" HorizontalAlignment="Center" Margin="9,0" Text="{Binding StashesCount}" Foreground="{DynamicResource Brush.BadgeFG}"/>
118-
</Border>
109+
<v:CounterPresenter Grid.Column="2"
110+
Margin="6,0"
111+
VerticalAlignment="Center"
112+
Count="{Binding StashesCount}"
113+
FontFamily="{Binding Source={x:Static vm:Preference.Instance}, Path=MonospaceFont}"
114+
FontSize="10"
115+
Foreground="{DynamicResource Brush.BadgeFG}"
116+
Background="{DynamicResource Brush.Badge}"/>
119117
</Grid>
120118
</ListBoxItem>
121119
</ListBox>

src/Views/Repository.axaml.cs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,109 @@
11
using System;
2+
using System.Globalization;
23

34
using Avalonia;
45
using Avalonia.Controls;
56
using Avalonia.Input;
67
using Avalonia.Interactivity;
8+
using Avalonia.Media;
79

810
namespace SourceGit.Views
911
{
12+
public class CounterPresenter : Control
13+
{
14+
public static readonly StyledProperty<int> CountProperty =
15+
AvaloniaProperty.Register<CounterPresenter, int>(nameof(Count), 0);
16+
17+
public int Count
18+
{
19+
get => GetValue(CountProperty);
20+
set => SetValue(CountProperty, value);
21+
}
22+
23+
public static readonly StyledProperty<FontFamily> FontFamilyProperty =
24+
TextBlock.FontFamilyProperty.AddOwner<CounterPresenter>();
25+
26+
public FontFamily FontFamily
27+
{
28+
get => GetValue(FontFamilyProperty);
29+
set => SetValue(FontFamilyProperty, value);
30+
}
31+
32+
public static readonly StyledProperty<double> FontSizeProperty =
33+
TextBlock.FontSizeProperty.AddOwner<CounterPresenter>();
34+
35+
public double FontSize
36+
{
37+
get => GetValue(FontSizeProperty);
38+
set => SetValue(FontSizeProperty, value);
39+
}
40+
41+
public static readonly StyledProperty<IBrush> ForegroundProperty =
42+
AvaloniaProperty.Register<CounterPresenter, IBrush>(nameof(Foreground), Brushes.White);
43+
44+
public IBrush Foreground
45+
{
46+
get => GetValue(ForegroundProperty);
47+
set => SetValue(ForegroundProperty, value);
48+
}
49+
50+
public static readonly StyledProperty<IBrush> BackgroundProperty =
51+
AvaloniaProperty.Register<CounterPresenter, IBrush>(nameof(Background), Brushes.White);
52+
53+
public IBrush Background
54+
{
55+
get => GetValue(BackgroundProperty);
56+
set => SetValue(BackgroundProperty, value);
57+
}
58+
59+
static CounterPresenter()
60+
{
61+
AffectsMeasure<CounterPresenter>(
62+
FontSizeProperty,
63+
FontFamilyProperty,
64+
ForegroundProperty,
65+
CountProperty);
66+
67+
AffectsRender<CounterPresenter>(
68+
ForegroundProperty,
69+
BackgroundProperty,
70+
CountProperty);
71+
}
72+
73+
public override void Render(DrawingContext context)
74+
{
75+
base.Render(context);
76+
77+
if (_label != null)
78+
{
79+
context.DrawRectangle(Background, null, new RoundedRect(new Rect(0, 0, _label.Width + 18, 18), new CornerRadius(9)));
80+
context.DrawText(_label, new Point(9, 9 - _label.Height * 0.5));
81+
}
82+
}
83+
84+
protected override Size MeasureOverride(Size availableSize)
85+
{
86+
if (Count > 0)
87+
{
88+
_label = new FormattedText(
89+
Count.ToString(),
90+
CultureInfo.CurrentCulture,
91+
FlowDirection.LeftToRight,
92+
new Typeface(FontFamily),
93+
FontSize,
94+
Foreground);
95+
}
96+
else
97+
{
98+
_label = null;
99+
}
100+
101+
return _label != null ? new Size(_label.Width + 18, 18) : new Size(0, 0);
102+
}
103+
104+
private FormattedText _label = null;
105+
}
106+
10107
public partial class Repository : UserControl
11108
{
12109
public Repository()

0 commit comments

Comments
 (0)