Skip to content

Commit

Permalink
Merge pull request #7352 from Youssef1313/issues/7172
Browse files Browse the repository at this point in the history
fix: Fix TextBox.Foreground on Skia
  • Loading branch information
jeromelaban authored Nov 23, 2021
2 parents ce58125 + c8f4b47 commit 4ecf3b8
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Point = Windows.Foundation.Point;
using Scale = Pango.Scale;
using System.Diagnostics;
using Windows.UI.Xaml.Media;

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

return 0;
}

public void SetForeground(Windows.UI.Xaml.Media.Brush brush)
{
if (brush is SolidColorBrush scb)
{
_currentInputWidget?.OverrideColor(StateFlags.Normal, new Gdk.RGBA
{
Red = scb.ColorWithOpacity.R,
Green = scb.ColorWithOpacity.G,
Blue = scb.ColorWithOpacity.B,
Alpha = scb.ColorWithOpacity.A
});
}
}
}
}
148 changes: 148 additions & 0 deletions src/Uno.UI.Runtime.Skia.Wpf/Extensions/UI/Xaml/Controls/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#nullable enable

using System.Linq;
using System.Diagnostics;

namespace Uno.UI.Runtime.Skia.WPF.Extensions.UI.Xaml.Controls
{
internal static class Extensions
{
public static System.Windows.Media.Brush? ToWpfBrush(this Windows.UI.Xaml.Media.Brush brush)
{
if (brush is Windows.UI.Xaml.Media.SolidColorBrush solidBrush)
{
return new System.Windows.Media.SolidColorBrush(solidBrush.Color.ToWpfColor()) { Opacity = solidBrush.Opacity };
}
else if (brush is Windows.UI.Xaml.Media.LinearGradientBrush gradientBrush)
{
return new System.Windows.Media.LinearGradientBrush(gradientBrush.GradientStops.ToWpfGradientStopCollection(), gradientBrush.StartPoint.ToWpfPoint(), gradientBrush.EndPoint.ToWpfPoint())
{
MappingMode = gradientBrush.MappingMode.ToWpfBrushMappingMode(),
Transform = gradientBrush.Transform.ToWpfTransform(),
RelativeTransform = gradientBrush.RelativeTransform.ToWpfTransform(),
};
}
else if (brush is Windows.UI.Xaml.Media.ImageBrush imageBrush)
{
return new System.Windows.Media.ImageBrush(imageBrush.ImageSource.ToWpfImageSource())
{
AlignmentX = imageBrush.AlignmentX.ToWpfAlignmentX(),
AlignmentY = imageBrush.AlignmentY.ToWpfAlignmentY(),
Opacity = imageBrush.Opacity,
Stretch = imageBrush.Stretch.ToWpfStretch(),
Transform = imageBrush.Transform.ToWpfTransform(),
RelativeTransform = imageBrush.RelativeTransform.ToWpfTransform(),
};
}

// TODO: Support more brushes.
return null;
}

private static System.Windows.Media.Color ToWpfColor(this Windows.UI.Color color)
=> System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);

private static System.Windows.Point ToWpfPoint(this Windows.Foundation.Point point)
=> new System.Windows.Point(point.X, point.Y);

private static System.Windows.Media.GradientStopCollection ToWpfGradientStopCollection(this Windows.UI.Xaml.Media.GradientStopCollection gradientStops)
=> new System.Windows.Media.GradientStopCollection(gradientStops.Select(stop => stop.ToWpfGradientStop()));

private static System.Windows.Media.GradientStop ToWpfGradientStop(this Windows.UI.Xaml.Media.GradientStop gradientStop)
=> new System.Windows.Media.GradientStop(gradientStop.Color.ToWpfColor(), gradientStop.Offset);

private static System.Windows.Media.ImageSource? ToWpfImageSource(this Windows.UI.Xaml.Media.ImageSource imageSource)
{
if (imageSource is Windows.UI.Xaml.Media.Imaging.BitmapImage bitmapSource)
{
new System.Windows.Media.Imaging.BitmapImage(bitmapSource.UriSource);
}

// TODO: Support more image sources.
return null;
}

private static System.Windows.Media.AlignmentX ToWpfAlignmentX(this Windows.UI.Xaml.Media.AlignmentX alignment)
{
Debug.Assert((int)System.Windows.Media.AlignmentX.Left == (int)Windows.UI.Xaml.Media.AlignmentX.Left);
Debug.Assert((int)System.Windows.Media.AlignmentX.Right == (int)Windows.UI.Xaml.Media.AlignmentX.Right);
Debug.Assert((int)System.Windows.Media.AlignmentX.Center == (int)Windows.UI.Xaml.Media.AlignmentX.Center);
return (System.Windows.Media.AlignmentX)alignment;
}

private static System.Windows.Media.AlignmentY ToWpfAlignmentY(this Windows.UI.Xaml.Media.AlignmentY alignment)
{
Debug.Assert((int)System.Windows.Media.AlignmentY.Top == (int)Windows.UI.Xaml.Media.AlignmentY.Top);
Debug.Assert((int)System.Windows.Media.AlignmentY.Center == (int)Windows.UI.Xaml.Media.AlignmentY.Center);
Debug.Assert((int)System.Windows.Media.AlignmentY.Bottom == (int)Windows.UI.Xaml.Media.AlignmentY.Bottom);
return (System.Windows.Media.AlignmentY)alignment;
}

private static System.Windows.Media.Stretch ToWpfStretch(this Windows.UI.Xaml.Media.Stretch stretch)
{
Debug.Assert((int)System.Windows.Media.Stretch.None == (int)Windows.UI.Xaml.Media.Stretch.None);
Debug.Assert((int)System.Windows.Media.Stretch.Fill == (int)Windows.UI.Xaml.Media.Stretch.Fill);
Debug.Assert((int)System.Windows.Media.Stretch.Uniform == (int)Windows.UI.Xaml.Media.Stretch.Uniform);
Debug.Assert((int)System.Windows.Media.Stretch.UniformToFill == (int)Windows.UI.Xaml.Media.Stretch.UniformToFill);
return (System.Windows.Media.Stretch)stretch;
}

private static System.Windows.Media.Transform ToWpfTransform(this Windows.UI.Xaml.Media.Transform transform)
{
if (transform is Windows.UI.Xaml.Media.MatrixTransform matrixTransform)
{
return new System.Windows.Media.MatrixTransform(
m11: matrixTransform.Matrix.M11,
m12: matrixTransform.Matrix.M12,
m21: matrixTransform.Matrix.M21,
m22: matrixTransform.Matrix.M22,
offsetX: matrixTransform.Matrix.OffsetX,
offsetY: matrixTransform.Matrix.OffsetY);
}
else if (transform is Windows.UI.Xaml.Media.RotateTransform rotateTransform)
{
return new System.Windows.Media.RotateTransform(
angle: rotateTransform.Angle,
centerX: rotateTransform.CenterX,
centerY: rotateTransform.CenterY);
}
else if (transform is Windows.UI.Xaml.Media.ScaleTransform scaleTransform)
{
return new System.Windows.Media.ScaleTransform(
scaleX: scaleTransform.ScaleX,
scaleY: scaleTransform.ScaleY,
centerX: scaleTransform.CenterX,
centerY: scaleTransform.CenterY);
}
else if (transform is Windows.UI.Xaml.Media.SkewTransform skewTransform)
{
return new System.Windows.Media.SkewTransform(
angleX: skewTransform.AngleX,
angleY: skewTransform.AngleY,
centerX: skewTransform.CenterX,
centerY: skewTransform.CenterY);
}
else if (transform is Windows.UI.Xaml.Media.TransformGroup transformGroup)
{
return new System.Windows.Media.TransformGroup()
{
Children = new System.Windows.Media.TransformCollection(transformGroup.Children.Select(g => g.ToWpfTransform()))
};
}
else if (transform is Windows.UI.Xaml.Media.TranslateTransform translateTransform)
{
return new System.Windows.Media.TranslateTransform(translateTransform.X, translateTransform.Y);
}

return null;
}

private static System.Windows.Media.BrushMappingMode ToWpfBrushMappingMode(this Windows.UI.Xaml.Media.BrushMappingMode mappingMode)
{
Debug.Assert((int)System.Windows.Media.BrushMappingMode.Absolute == (int)Windows.UI.Xaml.Media.BrushMappingMode.Absolute);
Debug.Assert((int)System.Windows.Media.BrushMappingMode.RelativeToBoundingBox == (int)Windows.UI.Xaml.Media.BrushMappingMode.RelativeToBoundingBox);

return (System.Windows.Media.BrushMappingMode)mappingMode;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Windows.UI.Xaml.Controls;
using Uno.Disposables;
using Uno.UI.Runtime.Skia.WPF.Controls;
using Uno.UI.Skia.Platform;
using Uno.UI.Xaml.Controls.Extensions;
using Point = Windows.Foundation.Point;
using SolidColorBrush = Windows.UI.Xaml.Media.SolidColorBrush;
using WpfCanvas = System.Windows.Controls.Canvas;
using WpfTextBox = System.Windows.Controls.TextBox;

namespace Uno.UI.Runtime.Skia.WPF.Extensions.UI.Xaml.Controls
{
Expand Down Expand Up @@ -101,12 +97,7 @@ public void UpdateNativeView()
_currentInputWidget.TextWrapping = textBox.AcceptsReturn ? TextWrapping.Wrap : TextWrapping.NoWrap;
_currentInputWidget.MaxLength = textBox.MaxLength;
_currentInputWidget.IsReadOnly = textBox.IsReadOnly;

if (textBox.Foreground is SolidColorBrush colorBrush)
{
var unoColor = colorBrush.Color;
_currentInputWidget.Foreground = new System.Windows.Media.SolidColorBrush(Color.FromArgb(unoColor.A, unoColor.R, unoColor.G, unoColor.B));
}
_currentInputWidget.Foreground = textBox.Foreground.ToWpfBrush();
}

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

public int GetSelectionLength() => _currentInputWidget?.SelectionLength ?? 0;

public void SetForeground(Windows.UI.Xaml.Media.Brush brush)
{
if (_currentInputWidget != null)
{
_currentInputWidget.Foreground = brush.ToWpfBrush();
}
}
}
}
3 changes: 3 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/ITextBoxExtension.skia.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Windows.Foundation;
using Windows.UI.Xaml.Media;

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

int GetSelectionLength();

void SetForeground(Brush brush);
}
}
12 changes: 8 additions & 4 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Windows.UI.Xaml.Controls
{
internal class TextBoxView
{
private readonly ITextBoxViewExtension _textBoxExtension;
private readonly ITextBoxViewExtension? _textBoxExtension;

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

internal void Select(int start, int length)
{
_textBoxExtension.Select(start, length);
_textBoxExtension?.Select(start, length);
}

internal void OnForegroundChanged(Brush brush) => DisplayBlock.Foreground = brush;
internal void OnForegroundChanged(Brush brush)
{
DisplayBlock.Foreground = brush;
_textBoxExtension?.SetForeground(brush);
}

internal void OnFocusStateChanged(FocusState focusState)
{
Expand Down

0 comments on commit 4ecf3b8

Please sign in to comment.