Skip to content

Introduce separate HitTestResults for Box and Sliver#31894

Merged
goderbauer merged 7 commits intoflutter:masterfrom
goderbauer:seperatehittestresult
May 9, 2019
Merged

Introduce separate HitTestResults for Box and Sliver#31894
goderbauer merged 7 commits intoflutter:masterfrom
goderbauer:seperatehittestresult

Conversation

@goderbauer
Copy link
Member

@goderbauer goderbauer commented May 1, 2019

Description

Introduces a BoxHitTestResult for RenderBox subtypes and SliverHitTestResult for RenderSliver subtypes. These replace the generic HitTestResult for those subtypes and allow us to implement Sliver and Box specific hit test helpers in those new classes (see #31222 for context).

Related Issues

#29916

Tests

It's mostly a refactoring of existing functionality. Added tests for the newly introduced BoxHitTestResult and SliverHitTestResult.

Checklist

Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes ([x]). This will ensure a smooth and quick review process.

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I signed the CLA.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.
  • The analyzer (flutter analyze --flutter-repo) does not report any problems on my PR.
  • I am willing to follow-up on review comments in a timely manner.

Breaking Change

Does your PR require Flutter developers to manually update their apps to accommodate your change?

@goderbauer goderbauer force-pushed the seperatehittestresult branch from 4278889 to 2ce18be Compare May 1, 2019 14:07
@goderbauer goderbauer added the framework flutter/packages/flutter repository. See also f: labels. label May 1, 2019
@Hixie
Copy link
Contributor

Hixie commented May 2, 2019

sector too?

@Hixie
Copy link
Contributor

Hixie commented May 2, 2019

approach seems good to me

@goderbauer
Copy link
Member Author

I added an implementation for RenderSector.

@goderbauer goderbauer marked this pull request as ready for review May 2, 2019 09:33
@goderbauer
Copy link
Member Author

goderbauer commented May 2, 2019

@Hixie Would you be up for giving this one a full review then? My plan would be to submit this PR first as a first step and then rebase #31222 on top of it to keep the PR sizes manageable.

@Hixie
Copy link
Contributor

Hixie commented May 3, 2019

LGTM

please watch the performance benchmarks after this lands

}
}

/// The result of performing a hit test on [RenderSector]s.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate in the docs on what this class adds? Specifically, looking at it in isolation, it doesn't add any properties or methods over a HitTestResult, so it makes me wonder what it's used for.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is correct that SectorHitTestResult currently does not provide any additional functionality over HitTestResult because RenderSector is an incomplete example implementation of an alternative to RenderBox. Once we have something like RenderSectorTransform (which, changes the origin of its child to be different from the parent) we'd add methods here to implement the origin changing for hit testing. I've added added a TODO for this to the class.

super(target);

@override
RenderSector get target => super.target;
Copy link
Contributor

Choose a reason for hiding this comment

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

Worth redefining HitTestEntry to be HitTestEntry<T extends HitTestTarget> and making this class be SectorHitTestEntry extends HitTestEntry<RenderSector>?

Copy link
Member Author

Choose a reason for hiding this comment

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

That probably would have been a good idea when HitTestEntry was first written. This is now just copying what the existing BoxHitTestEntry and SliverHitTestEntry is doing. Changing this now would be another breaking change. This one I find really hard to justify since it doesn't provide any user value. I'll leave it as is for now.

///
/// The [radius] and [theta] argument must not be null.
SectorHitTestEntry(RenderSector target, { @required this.radius, @required this.theta })
: assert(radius != null),
Copy link
Contributor

Choose a reason for hiding this comment

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

assert(radius > 0), assert(theta > 0)?

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 believe negative values for these are fine.

/// [target].
final double radius;

/// The theta component of the hit test position in the local coordinates of
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on what the theta component is or provide breadcrumbs to more info about hit testing that explains the concepts of radius and theta?

Copy link
Member Author

Choose a reason for hiding this comment

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

Radius and theta are concepts of a polar coordinate system, which is implemented by RenderSector as an alternative to RenderBox, which implements a cartesian coordinate system. It is just an example (see the directory) and as such poorly documented. (These are in fact the first doc comments in the file...). Both concepts are not really specific to hit testing. I added a general comment to the file.

/// [SliverHitTestResult] for hit testing on [RenderSliver] children.
BoxHitTestResult.wrap(HitTestResult result) : super.wrap(result);

/// Transforms `position` to the local coordinate system of a child before
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels weird that this does the hit testing -- and that this class is now both the result and an object that performs hit testing.

It almost feels like we need a level of indirection here, with a notion of a HitTester object (that may have a transformation applied to it) to which the render box delegates.

But take with comment with a huge grain of salt, since it's a drive-by code review from someone who knows these innards much less than you do 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

This does not perform the hit testing. It only transforms the coordinates to the coordinate space of the child, records the necessary transform and then executes the provided callback, which is supposed to implement the actual hit testing on the child. I updated the doc comment to make this clear.

@goderbauer goderbauer merged commit 1621baa into flutter:master May 9, 2019
@goderbauer goderbauer deleted the seperatehittestresult branch May 9, 2019 08:00
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants