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

[widget audit] TextInput, PasswordInput #1944

Merged
merged 39 commits into from
May 29, 2023

Conversation

freakboy3742
Copy link
Member

@freakboy3742 freakboy3742 commented May 18, 2023

Audit of both TextInput and PasswordInput (since they're essentially the same widget).

Extends #1938, as there's a lot of shared functionality in the probe.

  • There are some backwards incompatible changes in the API of individual Validators. Since it's a fairly niche feature, that wasn't previously documented (although there was example code), I didn't think it was worth a full backwards compatibility path.

  • Modifies the implementation of validation on macOS so that it doesn't require modal dialogs

  • Adds confirmation handling on macOS

  • Adds an implementation of focus handling, confirmation handling and validation on iOS.

Fixes #1290.
Fixes #1315.

Audit checklist

  • Core tests ported to pytest
  • Core tests at 100% coverage
  • Core docstrings complete, and in Sphinx format
  • Documentation complete and consistently formatted
  • cocoa backend at 100% coverage
  • winforms backend at 100% coverage
  • gtk backend at 100% coverage
  • iOS backend at 100% coverage
  • android backend at 100% coverage
  • Widget support table updated
  • Widget Issue backlog reviewed

@freakboy3742 freakboy3742 marked this pull request as draft May 18, 2023 06:02
@freakboy3742
Copy link
Member Author

#1290 and #1315 should be fixed by this PR.

@mhsmith mhsmith changed the title [widget audit] toga.TextField, toga.PasswordField [widget audit] TextInput, PasswordInput May 24, 2023
@freakboy3742 freakboy3742 marked this pull request as ready for review May 25, 2023 22:32
Comment on lines +52 to +54
{ directory = "feature", name = "Features", showcontent = true },
{ directory = "bugfix", name = "Bugfixes", showcontent = true },
{ directory = "removal", name = "Backward Incompatible Changes", showcontent = true },
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't backward incompatible changes come first?

Copy link
Member Author

Choose a reason for hiding this comment

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

I guess my take would be that you talk about the awesome new stuff before you scare people with the things that have changed :-)

As a comparable example - Django's release notes list major features, minor features, then backwards incompatibilities.

docs/reference/api/resources/validators.rst Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
Comment on lines 175 to 176
def validate(self) -> bool:
"""Validate the current value of the widget.
Copy link
Member

Choose a reason for hiding this comment

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

Since validation happens automatically on both programmatic and user-generated changes, is there any reason for this method to be public?

Copy link
Member Author

Choose a reason for hiding this comment

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

No particular reason for it to be public (other than, at this point, backwards compatibility). At the very least, it's worth flagging in docs that end-users shouldn't ever need to call this method; but I wouldn't be opposed to making it an internal method (with the appropriate backwards compatibility note).

core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
core/src/toga/validators.py Outdated Show resolved Hide resolved
Comment on lines -124 to -125
def winforms_double_click(self, sender, event):
self.native.SelectAll()
Copy link
Member

Choose a reason for hiding this comment

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

I don't know why this was here: double-clicking on Windows is supposed to select one word, not the entire box.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah - I can't explain this one either.

Comment on lines -106 to -107
def winforms_validated(self, sender, event):
self.interface.validate()
Copy link
Member

Choose a reason for hiding this comment

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

I can't work out what the Validated event handler was supposed to do, but everything seems to work fine without it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Winforms provides explicit event hooks to perform validation independent of focus and text change; I think the intention is that you can prevent a widget from losing focus if it's not currently valid. However, we're not blocking focus in that way, so I guess we can just piggyback on the change event.

Comment on lines +60 to +62
def assert_height(self, min_height, max_height):
# Height isn't configurable in this native widget.
assert 12 <= self.height <= 22
Copy link
Member

Choose a reason for hiding this comment

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

The native TextBox seems to ignore its height allocation and always stay the same height. Does this happen with any other widgets? I think I remember us talking about it, but I can't find any similar implementations of this method.

Copy link
Member Author

Choose a reason for hiding this comment

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

There's some similar behavior with Button. Buttons don't expand to fill the available vertical space unless they're explicitly set to a given height.

There's also some similar (but inconsistent) behavior with Switch. On most platforms, the switch "graphic" is a fixed height, regardless of the containing box; however, GTK and iOS both violate this, and render the switch with a weird aspect ratio.

In this case, I'm happy to call this a platform eccentricity and document it.

Copy link
Member

@mhsmith mhsmith left a comment

Choose a reason for hiding this comment

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

@freakboy3742: All platforms now have 100% coverage, and a fully-working textinput example. Please review my last few commits, and merge the PR if you're happy.

@freakboy3742
Copy link
Member Author

@mhsmith One minor tweak (avoiding the use of ObjC invocations for validation), but otherwise this all looks good to me.

@freakboy3742 freakboy3742 merged commit 488b417 into beeware:main May 29, 2023
@freakboy3742 freakboy3742 deleted the audit-textview branch May 29, 2023 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants