Skip to content

Conversation

@dkwingsmt
Copy link
Contributor

@dkwingsmt dkwingsmt commented May 30, 2024

This PR rewrite CupertinoActionSheet to be based on layout widgets instead of the custom layout code in _CupertinoDialogRenderWidget, making it much easier to understand. It also fixes a layout deviation from SwiftUI, and add a few tests.

_CupertinoDialogRenderWidget is a custom layout widget that contains too much boilerplate code and is hard to understand where is customized. The plan is to replace it with widgets as much as possible. (Since this widget is used by both CupertinoActionSheet and CupertinoAlertDialog, this PR only removes the branches related to isActionSheet).

The need to use custom layout widget probably came from the following difficulties:

  1. The parent needs to know whether an action button is being pressed to correctly render or hide each divider, but the action button is provided by the user as a built widget that also needs to respond to the tap gesture.
  2. The main sheet's column needs to prioritize allocating the space to the content section before allocating the remaining to the actions section, while also leaving the actions section a minimum height. This is not supported by simply Column.
  3. The minimum height of the action section is a non-trivial algorithm.

Luckily, I've found out that all these problems are solvable with widgets.

All existing tests pass.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: cupertino flutter/packages/flutter/cupertino repository labels May 30, 2024
@dkwingsmt dkwingsmt marked this pull request as ready for review May 30, 2024 19:37
@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #149334 at sha 7ecfd84

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label May 30, 2024
@chunhtai chunhtai self-requested a review May 30, 2024 20:16
Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

overall I am on board with this refactor, my comments are mostly in the implementation details

super.dispose();
}

bool hasContent() => widget.title != null || widget.message != null;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybe use getter?

}

/// A button typically used in a [CupertinoActionSheet].
/// The content of a typical button in a [CupertinoActionSheet].
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/// The content of a typical button in a [CupertinoActionSheet].
/// The content of a typical action button in a [CupertinoActionSheet].

final Widget? child;
final bool isCancel;

/// The callback that is called when the button is tapped.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment and variable name don't seem to match

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed it to:

  /// Called when the user taps down or lifts up on the button.
  ///
  /// The boolean value is true if the user is tapping down on the button.

const _CupertinoActionSheetCancelButton({
this.child,
// This widget renders the background (pressed or not) of a button, and sends
// whether the button is pressed to the parent.
Copy link
Contributor

Choose a reason for hiding this comment

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

a bit confused about this doc string, will this even send when the button is not pressed?

const _CupertinoActionSheetCancelButton({
this.child,
// This widget renders the background (pressed or not) of a button, and sends
// whether the button is pressed to the parent.
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe

// This widget renders the background (pressed or not) of a button and calls `onPressStateChange`
// when user tap down or lift up on the button

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I've changed it to

// Renders the background of a button (both the pressed background and the idle
// background) and reports its state to the parent with `onPressStateChange`.

(The exact definition of "the state" is explained in onPressStateChange.) What do you think of it?

// The buttons and the dividers are placed alternately, both keyed by indexes.
// Dividers use this special class so that the two lists of indexes can be told
// apart.
class _DividerKey extends ValueKey<int> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I am curious why this is needed, are you seeing some state lost due if not using this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to add keys to each element of the list. Since there are two list of integers, I can't add, for example, ValueKey<int>(1) to both the second item and the first divider (I've tested that in this case Flutter will report duplicate key error.)

If you mean that we don't need keys, well, I'm not strong on it either. But I was thinking that adding keys to a list of items might improve the performance, or at least is a good practice. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

key in a multichildrenderobject will only matter if you reorder or add or remove child in between update and you want to maintain state, otherwise it is the same as unkeyed, so I will probably not bother adding one for the divider

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, removed!

await tester.pump();

expect(findScrollableActionsSectionRenderBox(tester).size.height, moreOrLessEquals(112.3));
expect(findScrollableActionsSectionRenderBox(tester).size.height, moreOrLessEquals(84.0));
Copy link
Contributor

Choose a reason for hiding this comment

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

why this change?

Copy link
Contributor

Choose a reason for hiding this comment

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

same for other in the file

Copy link
Contributor Author

@dkwingsmt dkwingsmt May 31, 2024

Choose a reason for hiding this comment

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

On a second thought, I think I should revert this change and propose it in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've reverted these changes (and changed the minimum height from 84.0 to 84.3). Now all previous tests pass without any adjustment!

@dkwingsmt
Copy link
Contributor Author

I've addresses all comments and made changes so that all existing tests pass without adjustment.

Copy link
Contributor

@chunhtai chunhtai left a comment

Choose a reason for hiding this comment

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

LGTM

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #149334 at sha 7ad6897

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
@dkwingsmt dkwingsmt changed the title Rewrite CupertinoActionSheet, and fix layout deviation Rewrite CupertinoActionSheet Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
auto-submit bot pushed a commit that referenced this pull request Jun 3, 2024
…e user scrolls far (#149542)

When I implemented #149334, there was a bug that if the actions section is overscrolled for too far (typically due to a fling), the overscroll background might be so long that it overflows the actions section. This PR fixes this bug.
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App f: cupertino flutter/packages/flutter/cupertino repository framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants