mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix position of CupertinoContextMenu within Transform.scale (#97896)
This commit is contained in:
parent
bd2ca58db3
commit
6ddb99e98f
@ -47,10 +47,11 @@ typedef _ContextMenuPreviewBuilderChildless = Widget Function(
|
|||||||
Rect _getRect(GlobalKey globalKey) {
|
Rect _getRect(GlobalKey globalKey) {
|
||||||
assert(globalKey.currentContext != null);
|
assert(globalKey.currentContext != null);
|
||||||
final RenderBox renderBoxContainer = globalKey.currentContext!.findRenderObject()! as RenderBox;
|
final RenderBox renderBoxContainer = globalKey.currentContext!.findRenderObject()! as RenderBox;
|
||||||
final Offset containerOffset = renderBoxContainer.localToGlobal(
|
return Rect.fromPoints(renderBoxContainer.localToGlobal(
|
||||||
renderBoxContainer.paintBounds.topLeft,
|
renderBoxContainer.paintBounds.topLeft,
|
||||||
);
|
), renderBoxContainer.localToGlobal(
|
||||||
return containerOffset & renderBoxContainer.paintBounds.size;
|
renderBoxContainer.paintBounds.bottomRight
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The context menu arranges itself slightly differently based on the location
|
// The context menu arranges itself slightly differently based on the location
|
||||||
|
@ -228,6 +228,62 @@ void main() {
|
|||||||
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
|
kIsWeb ? SystemMouseCursors.click : SystemMouseCursors.basic,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('CupertinoContextMenu is in the correct position when within a Transform.scale', (WidgetTester tester) async {
|
||||||
|
final Widget child = _getChild();
|
||||||
|
await tester.pumpWidget(CupertinoApp(
|
||||||
|
home: CupertinoPageScaffold(
|
||||||
|
child: MediaQuery(
|
||||||
|
data: const MediaQueryData(size: Size(800, 600)),
|
||||||
|
child: Transform.scale(
|
||||||
|
scale: 0.5,
|
||||||
|
child: Align(
|
||||||
|
//alignment: Alignment.bottomRight,
|
||||||
|
child: CupertinoContextMenu(
|
||||||
|
actions: const <CupertinoContextMenuAction>[
|
||||||
|
CupertinoContextMenuAction(
|
||||||
|
child: Text('CupertinoContextMenuAction'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: child
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
expect(find.byWidget(child), findsOneWidget);
|
||||||
|
final Rect childRect = tester.getRect(find.byWidget(child));
|
||||||
|
expect(find.byType(ShaderMask), findsNothing);
|
||||||
|
|
||||||
|
// Start a press on the child.
|
||||||
|
final TestGesture gesture = await tester.startGesture(childRect.center);
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
// The _DecoyChild is showing directly on top of the child.
|
||||||
|
expect(_findDecoyChild(child), findsOneWidget);
|
||||||
|
Rect decoyChildRect = tester.getRect(_findDecoyChild(child));
|
||||||
|
expect(childRect, equals(decoyChildRect));
|
||||||
|
|
||||||
|
expect(find.byType(ShaderMask), findsOneWidget);
|
||||||
|
|
||||||
|
// After a small delay, the _DecoyChild has begun to animate.
|
||||||
|
await tester.pump(const Duration(milliseconds: 100));
|
||||||
|
decoyChildRect = tester.getRect(_findDecoyChild(child));
|
||||||
|
expect(childRect, isNot(equals(decoyChildRect)));
|
||||||
|
|
||||||
|
// Eventually the decoy fully scales by _kOpenSize.
|
||||||
|
await tester.pump(const Duration(milliseconds: 500));
|
||||||
|
decoyChildRect = tester.getRect(_findDecoyChild(child));
|
||||||
|
expect(childRect, isNot(equals(decoyChildRect)));
|
||||||
|
expect(decoyChildRect.width, childRect.width * kOpenScale);
|
||||||
|
|
||||||
|
// Then the CupertinoContextMenu opens.
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
await gesture.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(_findStatic(), findsOneWidget);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('CupertinoContextMenu when open', () {
|
group('CupertinoContextMenu when open', () {
|
||||||
|
@ -473,8 +473,8 @@ void main() {
|
|||||||
Rect.fromLTRB(
|
Rect.fromLTRB(
|
||||||
0,
|
0,
|
||||||
height - titleFontSize - 10,
|
height - titleFontSize - 10,
|
||||||
(width / 1.5).floorToDouble(),
|
(width / 1.5).floorToDouble() * 1.5,
|
||||||
height - 10,
|
height,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -545,8 +545,8 @@ void main() {
|
|||||||
Rect.fromLTRB(
|
Rect.fromLTRB(
|
||||||
0,
|
0,
|
||||||
height - titleFontSize - bottomMargin,
|
height - titleFontSize - bottomMargin,
|
||||||
(collapsedWidth / 3).floorToDouble(),
|
(collapsedWidth / 3).floorToDouble() * 3,
|
||||||
height - bottomMargin,
|
height,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -4321,17 +4321,17 @@ void main() {
|
|||||||
await pumpDecorator(focused: false, empty: false);
|
await pumpDecorator(focused: false, empty: false);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
||||||
expect(getLabelRect(tester).size, equals(const Size(80, 16)));
|
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75));
|
||||||
|
|
||||||
await pumpDecorator(focused: true);
|
await pumpDecorator(focused: true);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
||||||
expect(getLabelRect(tester).size, equals(const Size(80, 16)));
|
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75));
|
||||||
|
|
||||||
await pumpDecorator(focused: true, empty: false);
|
await pumpDecorator(focused: true, empty: false);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
||||||
expect(getLabelRect(tester).size, equals(const Size(80, 16)));
|
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75));
|
||||||
|
|
||||||
await pumpDecorator(focused: false, enabled: false);
|
await pumpDecorator(focused: false, enabled: false);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@ -4341,7 +4341,7 @@ void main() {
|
|||||||
await pumpDecorator(focused: false, empty: false, enabled: false);
|
await pumpDecorator(focused: false, empty: false, enabled: false);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
||||||
expect(getLabelRect(tester).size, equals(const Size(80, 16)));
|
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75));
|
||||||
|
|
||||||
// Focused and disabled happens with NavigationMode.directional.
|
// Focused and disabled happens with NavigationMode.directional.
|
||||||
await pumpDecorator(focused: true, enabled: false);
|
await pumpDecorator(focused: true, enabled: false);
|
||||||
@ -4352,7 +4352,7 @@ void main() {
|
|||||||
await pumpDecorator(focused: true, empty: false, enabled: false);
|
await pumpDecorator(focused: true, empty: false, enabled: false);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
expect(getLabelRect(tester).topLeft, equals(const Offset(12, -5.5)));
|
||||||
expect(getLabelRect(tester).size, equals(const Size(80, 16)));
|
expect(getLabelRect(tester).size, equals(const Size(80, 16) * 0.75));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('InputDecorationTheme.toString()', (WidgetTester tester) async {
|
testWidgets('InputDecorationTheme.toString()', (WidgetTester tester) async {
|
||||||
|
@ -1138,7 +1138,7 @@ abstract class WidgetController {
|
|||||||
|
|
||||||
/// Returns the rect of the given widget. This is only valid once
|
/// Returns the rect of the given widget. This is only valid once
|
||||||
/// the widget's render object has been laid out at least once.
|
/// the widget's render object has been laid out at least once.
|
||||||
Rect getRect(Finder finder) => getTopLeft(finder) & getSize(finder);
|
Rect getRect(Finder finder) => Rect.fromPoints(getTopLeft(finder), getBottomRight(finder));
|
||||||
|
|
||||||
/// Attempts to find the [SemanticsNode] of first result from `finder`.
|
/// Attempts to find the [SemanticsNode] of first result from `finder`.
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user