Skip to content

Conversation

@vanlooverenkoen
Copy link
Contributor

Added a configurable padding for the CupertinoSegmentedControl. The default of 16 will still be used if no padding was set.

#25989

@goderbauer goderbauer added f: cupertino flutter/packages/flutter/cupertino repository framework flutter/packages/flutter repository. See also f: labels. labels Apr 9, 2019
@LongCatIsLooong
Copy link
Contributor

Hi @vanlooverenkoen, thanks for your contribution! Could you add some tests for the changes you made?

@vanlooverenkoen
Copy link
Contributor Author

I have added 2 tests

  • 1 to make sure the default padding is shown
  • 1 to make sure the custom padding is shown.

@vanlooverenkoen
Copy link
Contributor Author

@LongCatIsLooong, is there something else I should do to get this PR merged?

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

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

Sorry for taking so long.

/// Defaults to the selectedColor at 20% opacity if null.
final Color pressedColor;

/// The [children], if any, are placed inside this padding.
Copy link
Contributor

Choose a reason for hiding this comment

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

It's guaranteed a segmented control will have more than 1 child.

}) : assert(children != null),
assert(children.length >= 2),

),
);

expect(find.byType(Padding), findsOneWidget);
Copy link
Contributor

Choose a reason for hiding this comment

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

Inspecting Padding directly to see if the parameter is set correctly seems a bit implementation dependent, IMO it's better to verify the expected behavior.

I'd prefer to verify that the bounding Rect of child widgets is indeed inset by padding amount, i.e. verify the top left corner of "Child 1" is Offset(16, 0) to the top left corner of CupertinoSegmentedControl<int> etc..

Copy link
Contributor Author

@vanlooverenkoen vanlooverenkoen May 26, 2019

Choose a reason for hiding this comment

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

How should I implement this test? coordinates_test.dart is what I am looking at at this point.

    final RenderBox boxA = tester.renderObject(find.byKey(keyChild1));
    expect(boxA.globalToLocal(Offset.zero), equals(const Offset(0.0, 286.0)));

How can I check what the position is between 2 widgets?

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong Jun 3, 2019

Choose a reason for hiding this comment

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

The WidgetTester class offers methods to get the key coordinates of a widget, e.g. getBottomLeft.
A good example would be this test:

testWidgets('Widgets are centered within segments', (WidgetTester tester) async {
final Map<int, Widget> children = <int, Widget>{};
children[0] = const Text('Child 1');
children[1] = const Text('Child 2');
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 200.0,
height: 200.0,
child: CupertinoSegmentedControl<int>(
children: children,
onValueChanged: (int newValue) { },
),
),
),
),
);
// Widgets are centered taking into account 16px of horizontal padding
expect(tester.getCenter(find.text('Child 1')), const Offset(58.0, 100.0));
expect(tester.getCenter(find.text('Child 2')), const Offset(142.0, 100.0));
});

Copy link
Contributor

Choose a reason for hiding this comment

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

e.g.

  testWidgets('Padding works', (WidgetTester tester) async {
    const Key key = Key('Container');

    final Map<int, Widget> children = <int, Widget>{};
    children[0] = const SizedBox(
      height: double.infinity,
      child: Text('Child 1'),
    ) ;
    children[1] = const SizedBox(
      height: double.infinity,
      child: Text('Child 2'),
    ) ;

    Future<void> verifyPadding({ EdgeInsets padding }) async {
      final EdgeInsets effectivePadding = padding ?? const EdgeInsets.symmetric(horizontal: 16);
      final Rect segmentedControlRect = tester.getRect(find.byKey(key));
      expect(
        tester.getTopLeft(find.byWidget(children[0])),
        segmentedControlRect.topLeft.translate(
          effectivePadding.topLeft.dx,
          effectivePadding.topLeft.dy,
        )
      );
      expect(
        tester.getBottomLeft(find.byWidget(children[0])),
        segmentedControlRect.bottomLeft.translate(
          effectivePadding.bottomLeft.dx,
          effectivePadding.bottomLeft.dy,
        ),
      );

      expect(
        tester.getTopRight(find.byWidget(children[1])),
        segmentedControlRect.topRight.translate(
          effectivePadding.topRight.dx,
          effectivePadding.topRight.dy,
        ),
      );
      expect(
        tester.getBottomRight(find.byWidget(children[1])),
        segmentedControlRect.bottomRight.translate(
          effectivePadding.bottomRight.dx,
          effectivePadding.bottomRight.dy,
        ),
      );
    }

    await tester.pumpWidget(
      boilerplate(
        child: CupertinoSegmentedControl<int>(
          key: key,
          children: children,
          onValueChanged: (int newValue) { },
        ),
      )
    );

    // Default padding works.
    await verifyPadding();

    // Switch to Child 2 padding should remain the same.
    await tester.tap(find.text('Child 2'));
    await tester.pumpAndSettle();

    await verifyPadding();

    await tester.pumpWidget(
      boilerplate(
        child: CupertinoSegmentedControl<int>(
          key: key,
          padding: const EdgeInsets.fromLTRB(1, 3, 5, 7),
          children: children,
          onValueChanged: (int newValue) { },
        ),
      )
    );

    // Custom padding works.
    await verifyPadding(padding: const EdgeInsets.fromLTRB(1, 3, 5, 7));

    // Switch back to Child 1 padding should remain the same.
    await tester.tap(find.text('Child 1'));
    await tester.pumpAndSettle();

    await verifyPadding(padding: const EdgeInsets.fromLTRB(1, 3, 5, 7));
  });

),
);

expect(find.byType(Padding), findsOneWidget);
Copy link
Contributor

Choose a reason for hiding this comment

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

here too

@HansMuller HansMuller changed the title #25989: Added padding. default will still be the 16 horizontal padding Configurable padding for the CupertinoSegmentedControl May 14, 2019
/// The [children], if any, are placed inside this padding.
///
/// Defaults to EdgeInsets.symmetric(horizontal: 16.0)
final EdgeInsets padding;
Copy link
Member

Choose a reason for hiding this comment

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

Let's change this to EdgeInsetsGeometry. Otherwise this is specifying that we use left and right regardless of Directionality.


return Padding(
padding: _kHorizontalItemPadding.resolve(Directionality.of(context)),
padding: widget.padding ?? _kHorizontalItemPadding.resolve(Directionality.of(context)),
Copy link
Member

Choose a reason for hiding this comment

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

Once we change it to an EdgeInsetGeometry, we should remove the .resolve here.

@LongCatIsLooong LongCatIsLooong added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label May 30, 2019
@vanlooverenkoen
Copy link
Contributor Author

@LongCatIsLooong
How should I implement this test? coordinates_test.dart is what I am looking at at this point.

    final RenderBox boxA = tester.renderObject(find.byKey(keyChild1));
    expect(boxA.globalToLocal(Offset.zero), equals(const Offset(0.0, 286.0)));

How can I check what the position is between 2 widgets?

@HansMuller HansMuller removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Jun 4, 2019
@LongCatIsLooong
Copy link
Contributor

@vanlooverenkoen I updated the comment with an example.

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

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

LGTM

/// Defaults to the selectedColor at 20% opacity if null.
final Color pressedColor;

/// The CupertinoSegmentedControl will be placed inside this padding
Copy link
Contributor

Choose a reason for hiding this comment

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

Copied from the docs of _kHorizontalItemPadding

Suggested change
/// The CupertinoSegmentedControl will be placed inside this padding
/// Minimum padding from edges of the segmented control to edges of encompassing
/// widget.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry what I was talking about the padding property in CupertinoSegmentedControl. The padding is part of the CupertinoSegmentedControl widget but it sounded like it is not.

@LongCatIsLooong
Copy link
Contributor

@vanlooverenkoen could you merge the current master branch (from upstream) into this PR? There's something weird happening with the flutter SDK version.

@vanlooverenkoen
Copy link
Contributor Author

@LongCatIsLooong done

@vanlooverenkoen
Copy link
Contributor Author

😑

@vanlooverenkoen
Copy link
Contributor Author

I cannot build anymore :(

Because every version of flutter_goldens from sdk depends on pedantic 1.5.0 and flutter depends on pedantic 1.7.0, flutter_goldens from sdk is forbidden.

So, because flutter depends on flutter_goldens any from sdk, version solving failed.
pub get failed (1)

@LongCatIsLooong
Copy link
Contributor

LongCatIsLooong commented Jun 13, 2019

@vanlooverenkoen sorry for the inconvenience but could you rebase master and squash all your commits into one? Apparently if you merge the latest master into your branch the SDK version is still decided by the commit you branched off from master when you created this feature branch.

@vanlooverenkoen
Copy link
Contributor Author

😑 I do not understand what I am doing wrong

@LongCatIsLooong
Copy link
Contributor

My apologies for the inconvenience 😞, the versioning system in flutter SDK does not handle merge commits by design. Could you do a git rebase upstream/master, to squash all your commits into one, and force push it to this branch? Or if you don't mind I can open a new PR with your changes.

@vanlooverenkoen
Copy link
Contributor Author

@LongCatIsLooong #34555

@vanlooverenkoen vanlooverenkoen deleted the Feature/25989-horizontal-padding-cupertino-segmented-control branch June 17, 2019 07:50
@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

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants