-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Implement Text Selection handles in TextBox for touch input #13107
Conversation
You can test this PR using the following package version. |
Shouldn't this be done with adorners? They are specifically designed for cases like this. I'm a little uncomfortable with how this was implemented with new canvas controls overlaying everything else. It doesn't seem to match XAML ideas. The graphical design looks good though and this feature is a big plus for mobile! |
Adorners currently can't be used in the any layer above the AdornerLayer, which includes OverlayLayer. It also has a composition bug, #10409 . |
Why would the selection handles need to appear over the overlay layer? In Android they do the following:
Someone can check iOS as well but simply copying Android would allow Adorner usage.
There a few other issues for adorners as well: #10701 and #11232. However, those bugs should not drive a "hacky" solution for a core feature. The correct path is to fix adorners. We don't want a temporary solution that will stick around in the code base for years I think? |
A few more comments:
|
I know of 1 popular avalonia control toolkit that uses the overlay layler for managed dialogs, ie content dialogs. These dialogs can host text boxes. And the overlay layer is above the adorner layer. |
@robloo Android uses popups for their copy-paste menu. These are windows on their own, similar to desktop |
Ok, even if they are 'windows' rather than an overlay my point stands about z-index. The selection handles are underneath them as shown below. If it works for Android I have to think it would work for Avalonia.... however
Yea, true, the adorner layer would still have to render above the overlay layer so the selection handles could appear in all cases like this. I was hoping this could be avoided but it can't - overlay hosted controls need selection handles too in some cases. This also might be a little bit new territory since UWP didn't have adorners. Perhaps that's why they don't fully work in composition renderer now. Perhaps the solution is to:
TL;DR: I still think adorners should be used. They were designed exactly for things like this. |
3 and 4 are on my list of things to do for touch. 1 and 2 will need @kekekeks input. I think OverlayLayer was added after Adorners, so it was placed above so as not to break stuff. |
You can test this PR using the following package version. |
@robloo Added mobile themed context flyouts for textbox |
You can test this PR using the following package version. |
@@ -1470,7 +1459,7 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) | |||
var text = Text; | |||
var clickInfo = e.GetCurrentPoint(this); | |||
|
|||
if (text != null && clickInfo.Properties.IsLeftButtonPressed && | |||
if (text != null && (e.Pointer.Type == PointerType.Mouse || e.ClickCount >= 2) && clickInfo.Properties.IsLeftButtonPressed && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the new condition does, but it seems incompatible with the code inside the if
branch: isTouch && e.ClickCount == 1
below can now never be true
Edit: this prevents setting the caret manually with touch without the handles once you have a selection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolving this as dragging the caret itself doesn't work (see my comment below).
I completely agree with this statement. We're adding a public layer here to work around adorners issues, but they're really made for this case. Even when adorners get fixed, the current solution might have to stay, which really isn't ideal. Apart from that, this PR is a great and much needed improvement for mobile! |
4ee9b16
to
b2f9393
Compare
You can test this PR using the following package version. |
4f98c74
to
64f947c
Compare
Ok, I didn't account for that. There may be issues with scrolling, but I'll try to alleviate it. |
9078671
to
060502a
Compare
This behavior would need #13351 first, so will update after that's merged. |
060502a
to
fdbba7e
Compare
@MrJul Should be good now. could you try again? |
Awesome work again! Finally, what was decided about adorners? Will this be adjusted later when adorners work in overlays and the bugs are fixed? |
Several issues after testing on a real Android device:
|
Hopefully, yes. |
Selection mode is entered by either tapping the text to set the handle, then tapping the handle, or holding on the text. Drag selection for touch has been removed due to how it interferes with gestures. |
What does the pull request do?
Implements text selection handles in textbox that allow changing text selection by dragging. This is activated by non-mouse input, i.e. touch and pen. This provides similar text selection behavior to what users are familiar with on android and iOS.
Recording.2023-10-02.122506.mp4
In addition, the textbox context menu has been simplified and optimized for mobile.
Recording.2023-10-09.091959.mp4
Though what I've planned for this pr is all in, it's still subject to change, so comments on implementation details and recommendations are welcome.
What is the current behavior?
Currently, text can only be be selected by dragging the caret along the text. This makes it very inaccurate on touch devices, and text selection is easily reset by accidental touches.
What is the updated/expected behavior with this PR?
How was the solution implemented (if it's not obvious)?
SelectionHandles must be drawn over all other controls, and though visibility of the handles is affected by the current text cursor, it shouldn't be clipped. As such, a new visual layer with a higher z-index is used to host the handles. This has the side effect of selection handles drawing over hosted popups, which are drawn in the OverlayLayer. It's possible to add text controls to the OverlayLayer, as such, that layer is not suitable to host selection handles.
Checklist
Breaking changes
This is a behavioral breaking change.
Obsoletions / Deprecations
Fixed issues