Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support PasswordBox on Skia #6768

Merged
merged 2 commits into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Object = GLib.Object;
using Point = Windows.Foundation.Point;
using Scale = Pango.Scale;
using System.Diagnostics;

namespace Uno.UI.Runtime.Skia.GTK.Extensions.UI.Xaml.Controls
{
Expand All @@ -38,7 +39,7 @@ public TextBoxViewExtension(TextBoxView owner, GtkWindow window)
private Fixed GetWindowTextInputLayer()
{
// now we have the GtkEventBox
var overlay = (Overlay)((EventBox) _window.Child).Child;
var overlay = (Overlay)((EventBox)_window.Child).Child;
return overlay.Children.OfType<Fixed>().First();
}

Expand All @@ -53,7 +54,7 @@ public void StartEntry()

_contentElement = textBox.ContentElement;

EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn);
EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn, isPassword: textBox is PasswordBox);
var textInputLayer = GetWindowTextInputLayer();
textInputLayer.Put(_currentInputWidget!, 0, 0);

Expand Down Expand Up @@ -107,7 +108,7 @@ public void UpdateNativeView()
return;
}

EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn);
EnsureWidgetForAcceptsReturn(textBox.AcceptsReturn, isPassword: textBox is PasswordBox);

var fontDescription = new FontDescription
{
Expand Down Expand Up @@ -170,24 +171,29 @@ private void UpdateEntryProperties(Entry entry, TextBox textBox)
{
entry.IsEditable = !textBox.IsReadOnly;
entry.MaxLength = textBox.MaxLength;

}

private void EnsureWidgetForAcceptsReturn(bool acceptsReturn)
private void EnsureWidgetForAcceptsReturn(bool acceptsReturn, bool isPassword)
{
// On UWP, A PasswordBox doesn't have AcceptsReturn property.
// The property exists on Uno because PasswordBox incorrectly inherits TextBox.
// If we have PasswordBox, ignore AcceptsReturnValue and always use Gtk.Entry
acceptsReturn = acceptsReturn && !isPassword;

var isIncompatibleInputType =
(acceptsReturn && !(_currentInputWidget is TextView)) ||
(!acceptsReturn && !(_currentInputWidget is Entry));
if (isIncompatibleInputType)
{
var inputText = GetInputText();
_currentInputWidget = CreateInputWidget(acceptsReturn);
_currentInputWidget = CreateInputWidget(acceptsReturn, isPassword);
SetWidgetText(inputText ?? string.Empty);
}
}

private Widget CreateInputWidget(bool acceptsReturn)
private Widget CreateInputWidget(bool acceptsReturn, bool isPassword)
{
Debug.Assert(!acceptsReturn || !isPassword);
Widget widget;
if (acceptsReturn)
{
Expand All @@ -199,6 +205,12 @@ private Widget CreateInputWidget(bool acceptsReturn)
else
{
var entry = new Entry();
if (isPassword)
{
entry.InputPurpose = InputPurpose.Password;
entry.Visibility = false;
}

entry.Changed += WidgetTextChanged;
_textChangedDisposable.Disposable = Disposable.Create(() => entry.Changed -= WidgetTextChanged);
widget = entry;
Expand Down Expand Up @@ -261,5 +273,15 @@ private void ContentElementSizeChanged(object sender, Windows.UI.Xaml.SizeChange
UpdateSize();
UpdatePosition();
}

public void SetIsPassword(bool isPassword)
{
if (_currentInputWidget is Entry entry)
{
entry.Visibility = !isPassword;
// InputPurpose doesn't have any visual effects.
entry.InputPurpose = InputPurpose.Password;
davidjohnoliver marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,5 +183,9 @@ private void ContentElementSizeChanged(object sender, Windows.UI.Xaml.SizeChange
UpdatePosition();
}

public void SetIsPassword(bool isPassword)
{
// No support for now.
}
}
}
14 changes: 14 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/PasswordBox/PasswordBox.skia.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Windows.UI.Xaml.Controls
{
public partial class PasswordBox
{
partial void SetPasswordScope(bool shouldHideText)
{
SetIsPassword(shouldHideText);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ internal interface ITextBoxViewExtension
void UpdatePosition();

void SetTextNative(string text);
}

void SetIsPassword(bool isPassword);
}
}
2 changes: 2 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBox.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ private void UpdateTextBoxView()
}

partial void OnFocusStateChangedPartial(FocusState focusState) => _textBoxView?.OnFocusStateChanged(focusState);

protected void SetIsPassword(bool isPassword) => _textBoxView?.SetIsPassword(isPassword);
}
}
4 changes: 3 additions & 1 deletion src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.skia.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public TextBox? TextBox

internal void SetTextNative(string text)
{
DisplayBlock.Text = text;
DisplayBlock.Text = new string('•', text.Length);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem should probably be here. I'll take a look to confirm and fix. Sorry for introducing such a regression :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries, happens to everybody. :)

For my part, I somehow did not even notice this line when I reviewed the PR.

_textBoxExtension?.SetTextNative(text);
}

Expand All @@ -65,6 +65,8 @@ internal void OnFocusStateChanged(FocusState focusState)
}
}

internal void SetIsPassword(bool isPassword) => _textBoxExtension?.SetIsPassword(isPassword);

internal void UpdateTextFromNative(string newText)
{
var textBox = _textBox?.GetTarget();
Expand Down