Skip to content

Commit 4ecf3b8

Browse files
authored
Merge pull request #7352 from Youssef1313/issues/7172
fix: Fix TextBox.Foreground on Skia
2 parents ce58125 + c8f4b47 commit 4ecf3b8

File tree

5 files changed

+183
-14
lines changed

5 files changed

+183
-14
lines changed

src/Uno.UI.Runtime.Skia.Gtk/UI/Xaml/Controls/TextBoxViewExtension.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Point = Windows.Foundation.Point;
1616
using Scale = Pango.Scale;
1717
using System.Diagnostics;
18+
using Windows.UI.Xaml.Media;
1819

1920
namespace Uno.UI.Runtime.Skia.GTK.Extensions.UI.Xaml.Controls
2021
{
@@ -338,5 +339,19 @@ public int GetSelectionLength()
338339

339340
return 0;
340341
}
342+
343+
public void SetForeground(Windows.UI.Xaml.Media.Brush brush)
344+
{
345+
if (brush is SolidColorBrush scb)
346+
{
347+
_currentInputWidget?.OverrideColor(StateFlags.Normal, new Gdk.RGBA
348+
{
349+
Red = scb.ColorWithOpacity.R,
350+
Green = scb.ColorWithOpacity.G,
351+
Blue = scb.ColorWithOpacity.B,
352+
Alpha = scb.ColorWithOpacity.A
353+
});
354+
}
355+
}
341356
}
342357
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#nullable enable
2+
3+
using System.Linq;
4+
using System.Diagnostics;
5+
6+
namespace Uno.UI.Runtime.Skia.WPF.Extensions.UI.Xaml.Controls
7+
{
8+
internal static class Extensions
9+
{
10+
public static System.Windows.Media.Brush? ToWpfBrush(this Windows.UI.Xaml.Media.Brush brush)
11+
{
12+
if (brush is Windows.UI.Xaml.Media.SolidColorBrush solidBrush)
13+
{
14+
return new System.Windows.Media.SolidColorBrush(solidBrush.Color.ToWpfColor()) { Opacity = solidBrush.Opacity };
15+
}
16+
else if (brush is Windows.UI.Xaml.Media.LinearGradientBrush gradientBrush)
17+
{
18+
return new System.Windows.Media.LinearGradientBrush(gradientBrush.GradientStops.ToWpfGradientStopCollection(), gradientBrush.StartPoint.ToWpfPoint(), gradientBrush.EndPoint.ToWpfPoint())
19+
{
20+
MappingMode = gradientBrush.MappingMode.ToWpfBrushMappingMode(),
21+
Transform = gradientBrush.Transform.ToWpfTransform(),
22+
RelativeTransform = gradientBrush.RelativeTransform.ToWpfTransform(),
23+
};
24+
}
25+
else if (brush is Windows.UI.Xaml.Media.ImageBrush imageBrush)
26+
{
27+
return new System.Windows.Media.ImageBrush(imageBrush.ImageSource.ToWpfImageSource())
28+
{
29+
AlignmentX = imageBrush.AlignmentX.ToWpfAlignmentX(),
30+
AlignmentY = imageBrush.AlignmentY.ToWpfAlignmentY(),
31+
Opacity = imageBrush.Opacity,
32+
Stretch = imageBrush.Stretch.ToWpfStretch(),
33+
Transform = imageBrush.Transform.ToWpfTransform(),
34+
RelativeTransform = imageBrush.RelativeTransform.ToWpfTransform(),
35+
};
36+
}
37+
38+
// TODO: Support more brushes.
39+
return null;
40+
}
41+
42+
private static System.Windows.Media.Color ToWpfColor(this Windows.UI.Color color)
43+
=> System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
44+
45+
private static System.Windows.Point ToWpfPoint(this Windows.Foundation.Point point)
46+
=> new System.Windows.Point(point.X, point.Y);
47+
48+
private static System.Windows.Media.GradientStopCollection ToWpfGradientStopCollection(this Windows.UI.Xaml.Media.GradientStopCollection gradientStops)
49+
=> new System.Windows.Media.GradientStopCollection(gradientStops.Select(stop => stop.ToWpfGradientStop()));
50+
51+
private static System.Windows.Media.GradientStop ToWpfGradientStop(this Windows.UI.Xaml.Media.GradientStop gradientStop)
52+
=> new System.Windows.Media.GradientStop(gradientStop.Color.ToWpfColor(), gradientStop.Offset);
53+
54+
private static System.Windows.Media.ImageSource? ToWpfImageSource(this Windows.UI.Xaml.Media.ImageSource imageSource)
55+
{
56+
if (imageSource is Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapSource)
57+
{
58+
new System.Windows.Media.Imaging.BitmapImage(bitmapSource.UriSource);
59+
}
60+
61+
// TODO: Support more image sources.
62+
return null;
63+
}
64+
65+
private static System.Windows.Media.AlignmentX ToWpfAlignmentX(this Windows.UI.Xaml.Media.AlignmentX alignment)
66+
{
67+
Debug.Assert((int)System.Windows.Media.AlignmentX.Left == (int)Windows.UI.Xaml.Media.AlignmentX.Left);
68+
Debug.Assert((int)System.Windows.Media.AlignmentX.Right == (int)Windows.UI.Xaml.Media.AlignmentX.Right);
69+
Debug.Assert((int)System.Windows.Media.AlignmentX.Center == (int)Windows.UI.Xaml.Media.AlignmentX.Center);
70+
return (System.Windows.Media.AlignmentX)alignment;
71+
}
72+
73+
private static System.Windows.Media.AlignmentY ToWpfAlignmentY(this Windows.UI.Xaml.Media.AlignmentY alignment)
74+
{
75+
Debug.Assert((int)System.Windows.Media.AlignmentY.Top == (int)Windows.UI.Xaml.Media.AlignmentY.Top);
76+
Debug.Assert((int)System.Windows.Media.AlignmentY.Center == (int)Windows.UI.Xaml.Media.AlignmentY.Center);
77+
Debug.Assert((int)System.Windows.Media.AlignmentY.Bottom == (int)Windows.UI.Xaml.Media.AlignmentY.Bottom);
78+
return (System.Windows.Media.AlignmentY)alignment;
79+
}
80+
81+
private static System.Windows.Media.Stretch ToWpfStretch(this Windows.UI.Xaml.Media.Stretch stretch)
82+
{
83+
Debug.Assert((int)System.Windows.Media.Stretch.None == (int)Windows.UI.Xaml.Media.Stretch.None);
84+
Debug.Assert((int)System.Windows.Media.Stretch.Fill == (int)Windows.UI.Xaml.Media.Stretch.Fill);
85+
Debug.Assert((int)System.Windows.Media.Stretch.Uniform == (int)Windows.UI.Xaml.Media.Stretch.Uniform);
86+
Debug.Assert((int)System.Windows.Media.Stretch.UniformToFill == (int)Windows.UI.Xaml.Media.Stretch.UniformToFill);
87+
return (System.Windows.Media.Stretch)stretch;
88+
}
89+
90+
private static System.Windows.Media.Transform ToWpfTransform(this Windows.UI.Xaml.Media.Transform transform)
91+
{
92+
if (transform is Windows.UI.Xaml.Media.MatrixTransform matrixTransform)
93+
{
94+
return new System.Windows.Media.MatrixTransform(
95+
m11: matrixTransform.Matrix.M11,
96+
m12: matrixTransform.Matrix.M12,
97+
m21: matrixTransform.Matrix.M21,
98+
m22: matrixTransform.Matrix.M22,
99+
offsetX: matrixTransform.Matrix.OffsetX,
100+
offsetY: matrixTransform.Matrix.OffsetY);
101+
}
102+
else if (transform is Windows.UI.Xaml.Media.RotateTransform rotateTransform)
103+
{
104+
return new System.Windows.Media.RotateTransform(
105+
angle: rotateTransform.Angle,
106+
centerX: rotateTransform.CenterX,
107+
centerY: rotateTransform.CenterY);
108+
}
109+
else if (transform is Windows.UI.Xaml.Media.ScaleTransform scaleTransform)
110+
{
111+
return new System.Windows.Media.ScaleTransform(
112+
scaleX: scaleTransform.ScaleX,
113+
scaleY: scaleTransform.ScaleY,
114+
centerX: scaleTransform.CenterX,
115+
centerY: scaleTransform.CenterY);
116+
}
117+
else if (transform is Windows.UI.Xaml.Media.SkewTransform skewTransform)
118+
{
119+
return new System.Windows.Media.SkewTransform(
120+
angleX: skewTransform.AngleX,
121+
angleY: skewTransform.AngleY,
122+
centerX: skewTransform.CenterX,
123+
centerY: skewTransform.CenterY);
124+
}
125+
else if (transform is Windows.UI.Xaml.Media.TransformGroup transformGroup)
126+
{
127+
return new System.Windows.Media.TransformGroup()
128+
{
129+
Children = new System.Windows.Media.TransformCollection(transformGroup.Children.Select(g => g.ToWpfTransform()))
130+
};
131+
}
132+
else if (transform is Windows.UI.Xaml.Media.TranslateTransform translateTransform)
133+
{
134+
return new System.Windows.Media.TranslateTransform(translateTransform.X, translateTransform.Y);
135+
}
136+
137+
return null;
138+
}
139+
140+
private static System.Windows.Media.BrushMappingMode ToWpfBrushMappingMode(this Windows.UI.Xaml.Media.BrushMappingMode mappingMode)
141+
{
142+
Debug.Assert((int)System.Windows.Media.BrushMappingMode.Absolute == (int)Windows.UI.Xaml.Media.BrushMappingMode.Absolute);
143+
Debug.Assert((int)System.Windows.Media.BrushMappingMode.RelativeToBoundingBox == (int)Windows.UI.Xaml.Media.BrushMappingMode.RelativeToBoundingBox);
144+
145+
return (System.Windows.Media.BrushMappingMode)mappingMode;
146+
}
147+
}
148+
}

src/Uno.UI.Runtime.Skia.Wpf/Extensions/UI/Xaml/Controls/TextBoxViewExtension.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,13 @@
22

33
using System;
44
using System.Windows;
5-
using System.Windows.Media;
6-
using System.Windows.Threading;
75
using Windows.UI.Xaml.Controls;
86
using Uno.Disposables;
97
using Uno.UI.Runtime.Skia.WPF.Controls;
108
using Uno.UI.Skia.Platform;
119
using Uno.UI.Xaml.Controls.Extensions;
1210
using Point = Windows.Foundation.Point;
13-
using SolidColorBrush = Windows.UI.Xaml.Media.SolidColorBrush;
1411
using WpfCanvas = System.Windows.Controls.Canvas;
15-
using WpfTextBox = System.Windows.Controls.TextBox;
1612

1713
namespace Uno.UI.Runtime.Skia.WPF.Extensions.UI.Xaml.Controls
1814
{
@@ -101,12 +97,7 @@ public void UpdateNativeView()
10197
_currentInputWidget.TextWrapping = textBox.AcceptsReturn ? TextWrapping.Wrap : TextWrapping.NoWrap;
10298
_currentInputWidget.MaxLength = textBox.MaxLength;
10399
_currentInputWidget.IsReadOnly = textBox.IsReadOnly;
104-
105-
if (textBox.Foreground is SolidColorBrush colorBrush)
106-
{
107-
var unoColor = colorBrush.Color;
108-
_currentInputWidget.Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(unoColor.A, unoColor.R, unoColor.G, unoColor.B));
109-
}
100+
_currentInputWidget.Foreground = textBox.Foreground.ToWpfBrush();
110101
}
111102

112103
public void UpdateSize()
@@ -193,5 +184,13 @@ public void SetIsPassword(bool isPassword)
193184
public int GetSelectionStart() => _currentInputWidget?.SelectionStart ?? 0;
194185

195186
public int GetSelectionLength() => _currentInputWidget?.SelectionLength ?? 0;
187+
188+
public void SetForeground(Windows.UI.Xaml.Media.Brush brush)
189+
{
190+
if (_currentInputWidget != null)
191+
{
192+
_currentInputWidget.Foreground = brush.ToWpfBrush();
193+
}
194+
}
196195
}
197196
}

src/Uno.UI/UI/Xaml/Controls/TextBox/ITextBoxExtension.skia.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Windows.Foundation;
2+
using Windows.UI.Xaml.Media;
23

34
namespace Uno.UI.Xaml.Controls.Extensions
45
{
@@ -23,5 +24,7 @@ internal interface ITextBoxViewExtension
2324
int GetSelectionStart();
2425

2526
int GetSelectionLength();
27+
28+
void SetForeground(Brush brush);
2629
}
2730
}

src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.skia.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace Windows.UI.Xaml.Controls
1212
{
1313
internal class TextBoxView
1414
{
15-
private readonly ITextBoxViewExtension _textBoxExtension;
15+
private readonly ITextBoxViewExtension? _textBoxExtension;
1616

1717
private readonly WeakReference<TextBox> _textBox;
1818
private readonly bool _isPasswordBox;
@@ -55,7 +55,7 @@ public TextBox? TextBox
5555
internal void SetTextNative(string text)
5656
{
5757
// TODO: Inheritance hierarchy is wrong in Uno. PasswordBox shouldn't inherit TextBox.
58-
// This needs to be moved to PasswordBox when it's separated from TextBox (likely in Uno 4).
58+
// This needs to be moved to PasswordBox if it's separated from TextBox.
5959
if (_isPasswordBox && !_isPasswordRevealed)
6060
{
6161
// TODO: PasswordChar isn't currently implemented. It should be used here when implemented.
@@ -71,10 +71,14 @@ internal void SetTextNative(string text)
7171

7272
internal void Select(int start, int length)
7373
{
74-
_textBoxExtension.Select(start, length);
74+
_textBoxExtension?.Select(start, length);
7575
}
7676

77-
internal void OnForegroundChanged(Brush brush) => DisplayBlock.Foreground = brush;
77+
internal void OnForegroundChanged(Brush brush)
78+
{
79+
DisplayBlock.Foreground = brush;
80+
_textBoxExtension?.SetForeground(brush);
81+
}
7882

7983
internal void OnFocusStateChanged(FocusState focusState)
8084
{

0 commit comments

Comments
 (0)