-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add TextField triple tap/click gestures #119046
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
Add TextField triple tap/click gestures #119046
Conversation
1b4d81e to
f4615e1
Compare
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.
Perhaps remove the doc comment reference to [int] as it's a generic type? Can follow the style of TextBoundary (or even CharacterBoundary which only has class level doc comments...).
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 guess these magic numbers could be avoided with constants (also needed in isLineTerminator).
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.
Same as above on constants.
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.
Looking at TextPainter, the list of what's considered a newline is different: no 0xD on its own, plus 0x2028/0x2029.
static bool _isNewline(int codePoint) {
switch (codePoint) {
case 0x000A:
case 0x0085:
case 0x000B:
case 0x000C:
case 0x2028:
case 0x2029:
return true;
default:
return false;
}
}
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.
Hmm I got the list from here https://www.unicode.org/standard/reports/tr13/tr13-5.html. I added 0x2028 and 0x2029 I had left out.
|
@tgucio sorry this wasn't ready for review. This depends on another PR so some files are not related to this one. Appreciate the feedback nonetheless :) |
|
@Renzo-Olivares this is a very welcome PR so I thought I'd share review comments early but it looks like I missed the "Draft" status :). |
e17f147 to
962fb81
Compare
0a2a3f6 to
123f26a
Compare
|
This is ready for an initial review with a caveat: I'm still addressing an edge case where the |
justinmc
left a comment
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.
LGTM with nits 👍
The main thing is just a TODO that I commented on, not sure if you plan to do that in this PR or a new one.
It's really great that this PR is so straightforward with the addition of your paragraph boundary work and refactoring. Before that it was such a mess trying to support triple tap!
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.
Why do iOS and Mac fall through to the same behavior as Windows if the comments above seem to describe their behavior differently?
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.
To me it looked like iOS/macOS/Windows increased their tap count infinitely but they handled taps past 3 differently.
iOS and macOS don't handle anything past a third tap. The selection is retained at the paragraph that was selected on the triple tap.
Windows alternates between double click and triple click when going past the third tap. Alternating between selecting the word or paragraph at the position.
Let me know if I can clarify this further.
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 think it's ok as-is. I looked through the code to see how consecutiveTapCount is used and it makes sense that these all return null but later have different behavior.
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 think it makes more sense now after introducing an effectiveConsecutiveTapCount.
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.
Ah I guess some tests that previously tapped very soon after a double tap might behave differently now. We should watch out for this breaking Google tests or anything else. Though it looks like Google tests are currently passing 👍
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.
Yeah, how it worked previously is that the double tap timer on TextSelectionGestureDetector would reset the count to 0 after every double tap for every platform. So some test behavior changed a bit, but google tests look good so far.
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.
Is your plan to do this in another PR?
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 hoping that I can fix it in this one. But if the fix becomes overly complex then I'll probably make it into another PR.
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.
Just wanted to draw attention to this again in case you forgot about it.
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.
It's a bummer that we have to duplicate all of these tests for Cupertino and Material, but I guess they won't work on EditableText because of the code changes in text_selection.dart.
Someday we need to make it easier to share these kinds of tests!
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.
Agreed, it would definitely help with velocity if we only had to write these tests once.
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.
It's nice that this test still works (with minor changes) and makes a lot of sense with the addition of triple tap.
bc68b75 to
004fbf0
Compare
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.
nit: maybe it's easier to write the if clauses, if the local variable is for "effective tap count".
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.
or maybe move the logic to the static method you created later in this file that turns the raw tap count to the effective tap count.
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.
Sorry i'm not sure I follow, can you elaborate? The static method I created later in the file is meant to tell the gesture recognizer what its ceiling is for the consecutive tap count before it resets it to 0.
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.
is it possible to repurpose _getDefaultMaxConsecutiveTap so it takes the raw consecutive tap count and returns the "effective" tap count? For instance for windows the conversion would look like input < 2 ? input : 2 + input % 2 and for other platforms it's max(input, 3).
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.
In this scenario if we are repurposing _getDefaultMaxConsecutiveTap are we then setting the ceiling for consecutive tap count on the recognizer to null for all platforms?
In that case I think we can do this.
static int _getEffectiveConsecutiveTapCount(int rawCount) {
switch(defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
return rawCount <= 3 ? rawCount : 0 + (rawCount % 3 == 0 ? 3 : rawCount % 3);
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return math.min(rawCount, 3);
case TargetPlatform.windows:
return rawCount < 2 ? rawCount : 2 + rawCount % 2;
}
}Definitely makes the if cases much better! Thanks for the code and suggestion!
9bdc1f8 to
345f154
Compare
justinmc
left a comment
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.
LGTM 👍
This PR adds the following triple tap/click gestures to select text in a TextField to match the native platform behavior.
Fixes #63576
///).