Unverified Commit 21bc9f1b authored by matthew-carroll's avatar matthew-carroll Committed by GitHub

iOS Dialog blur, brightness, and layout (#18381)

Rewrote CupertinoAlertDialog to look nearly identical to an alert dialog in iOS. This includes considerations for blur, translucent white background color, button sizing, gap dividers between buttons, and text scaling layout behavior. (#18381)
parent 25ba90aa
...@@ -83,11 +83,11 @@ class BoxDecoration extends Decoration { ...@@ -83,11 +83,11 @@ class BoxDecoration extends Decoration {
this.backgroundBlendMode, this.backgroundBlendMode,
this.shape = BoxShape.rectangle, this.shape = BoxShape.rectangle,
}) : assert(shape != null), }) : assert(shape != null),
// TODO(mattcarroll): Use "backgroundBlendMode == null" when Dart #31140 is in. // TODO(mattcarroll): Use "backgroundBlendMode == null" when https://github.com/dart-lang/sdk/issues/31140 is in.
assert( assert(
identical(backgroundBlendMode, null) || color != null || gradient != null, identical(backgroundBlendMode, null) || color != null || gradient != null,
'backgroundBlendMode applies to BoxDecoration\'s background color or' 'backgroundBlendMode applies to BoxDecoration\'s background color or '
'gradient, but no color or gradient were provided.' 'gradient, but no color or gradient were provided.'
); );
@override @override
...@@ -146,10 +146,10 @@ class BoxDecoration extends Decoration { ...@@ -146,10 +146,10 @@ class BoxDecoration extends Decoration {
/// The blend mode applied to the [color] or [gradient] background of the box. /// The blend mode applied to the [color] or [gradient] background of the box.
/// ///
/// If no [backgroundBlendMode] is provided, then the default painting blend /// If no [backgroundBlendMode] is provided then the default painting blend
/// mode is used. /// mode is used.
/// ///
/// If no [color] or [gradient] is provided, then blend mode has no impact. /// If no [color] or [gradient] is provided then the blend mode has no impact.
final BlendMode backgroundBlendMode; final BlendMode backgroundBlendMode;
/// The shape to fill the background [color], [gradient], and [image] into and /// The shape to fill the background [color], [gradient], and [image] into and
......
...@@ -273,6 +273,17 @@ abstract class WidgetController { ...@@ -273,6 +273,17 @@ abstract class WidgetController {
}); });
} }
/// Dispatch a pointer down at the center of the given widget, assuming it is
/// exposed.
///
/// If the center of the widget is not exposed, this might send events to
/// another object.
Future<TestGesture> press(Finder finder, { int pointer }) {
return TestAsyncUtils.guard<TestGesture>(() {
return startGesture(getCenter(finder), pointer: pointer);
});
}
/// Dispatch a pointer down / pointer up sequence (with a delay of /// Dispatch a pointer down / pointer up sequence (with a delay of
/// [kLongPressTimeout] + [kPressTimeout] between the two events) at the /// [kLongPressTimeout] + [kPressTimeout] between the two events) at the
/// center of the given widget, assuming it is exposed. /// center of the given widget, assuming it is exposed.
......
...@@ -57,7 +57,7 @@ class TestAsyncUtils { ...@@ -57,7 +57,7 @@ class TestAsyncUtils {
/// this one before this one has finished will throw an exception. /// this one before this one has finished will throw an exception.
/// ///
/// This method first calls [guardSync]. /// This method first calls [guardSync].
static Future<Null> guard(Future<Null> body()) { static Future<T> guard<T>(Future<T> body()) {
guardSync(); guardSync();
final Zone zone = Zone.current.fork( final Zone zone = Zone.current.fork(
zoneValues: <dynamic, dynamic>{ zoneValues: <dynamic, dynamic>{
...@@ -66,8 +66,9 @@ class TestAsyncUtils { ...@@ -66,8 +66,9 @@ class TestAsyncUtils {
); );
final _AsyncScope scope = new _AsyncScope(StackTrace.current, zone); final _AsyncScope scope = new _AsyncScope(StackTrace.current, zone);
_scopeStack.add(scope); _scopeStack.add(scope);
final Future<Null> result = scope.zone.run(body); final Future<T> result = scope.zone.run<Future<T>>(body);
Future<Null> completionHandler(dynamic error, StackTrace stack) { T resultValue; // This is set when the body of work completes with a result value.
Future<T> completionHandler(dynamic error, StackTrace stack) {
assert(_scopeStack.isNotEmpty); assert(_scopeStack.isNotEmpty);
assert(_scopeStack.contains(scope)); assert(_scopeStack.contains(scope));
bool leaked = false; bool leaked = false;
...@@ -102,11 +103,12 @@ class TestAsyncUtils { ...@@ -102,11 +103,12 @@ class TestAsyncUtils {
throw new FlutterError(message.toString().trimRight()); throw new FlutterError(message.toString().trimRight());
} }
if (error != null) if (error != null)
return new Future<Null>.error(error, stack); return new Future<T>.error(error, stack);
return new Future<Null>.value(null); return new Future<T>.value(resultValue);
} }
return result.then<Null>( return result.then<T>(
(Null value) { (T value) {
resultValue = value;
return completionHandler(null, null); return completionHandler(null, null);
}, },
onError: completionHandler onError: completionHandler
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment