Unverified Commit a35e7aae authored by Andrei Diaconu's avatar Andrei Diaconu Committed by GitHub

Add display features to MediaQuery (#92906)

parent 1c4128c7
......@@ -105,7 +105,8 @@ class MediaQueryData {
this.disableAnimations = false,
this.boldText = false,
this.navigationMode = NavigationMode.traditional,
this.gestureSettings = const DeviceGestureSettings(touchSlop: kTouchSlop)
this.gestureSettings = const DeviceGestureSettings(touchSlop: kTouchSlop),
this.displayFeatures = const <ui.DisplayFeature>[],
}) : assert(size != null),
assert(devicePixelRatio != null),
assert(textScaleFactor != null),
......@@ -121,7 +122,8 @@ class MediaQueryData {
assert(disableAnimations != null),
assert(boldText != null),
assert(navigationMode != null),
assert(gestureSettings != null);
assert(gestureSettings != null),
assert(displayFeatures != null);
/// Creates data for a media query based on the given window.
///
......@@ -146,7 +148,8 @@ class MediaQueryData {
highContrast = window.accessibilityFeatures.highContrast,
alwaysUse24HourFormat = window.alwaysUse24HourFormat,
navigationMode = NavigationMode.traditional,
gestureSettings = DeviceGestureSettings.fromWindow(window);
gestureSettings = DeviceGestureSettings.fromWindow(window),
displayFeatures = window.displayFeatures;
/// The size of the media in logical pixels (e.g, the size of the screen).
///
......@@ -351,6 +354,17 @@ class MediaQueryData {
/// gesture behavior over the framework constants.
final DeviceGestureSettings gestureSettings;
/// {@macro dart.ui.ViewConfiguration.displayFeatures}
///
/// See also:
///
/// * [dart:ui.DisplayFeatureType], which lists the different types of
/// display features and explains the differences between them.
/// * [dart:ui.DisplayFeatureState], which lists the possible states for
/// folding features ([dart:ui.DisplayFeatureType.fold] and
/// [dart:ui.DisplayFeatureType.hinge]).
final List<ui.DisplayFeature> displayFeatures;
/// The orientation of the media (e.g., whether the device is in landscape or
/// portrait mode).
Orientation get orientation {
......@@ -376,6 +390,7 @@ class MediaQueryData {
bool? boldText,
NavigationMode? navigationMode,
DeviceGestureSettings? gestureSettings,
List<ui.DisplayFeature>? displayFeatures,
}) {
return MediaQueryData(
size: size ?? this.size,
......@@ -394,6 +409,7 @@ class MediaQueryData {
boldText: boldText ?? this.boldText,
navigationMode: navigationMode ?? this.navigationMode,
gestureSettings: gestureSettings ?? this.gestureSettings,
displayFeatures: displayFeatures ?? this.displayFeatures,
);
}
......@@ -445,6 +461,7 @@ class MediaQueryData {
accessibleNavigation: accessibleNavigation,
boldText: boldText,
gestureSettings: gestureSettings,
displayFeatures: displayFeatures,
);
}
......@@ -494,6 +511,7 @@ class MediaQueryData {
accessibleNavigation: accessibleNavigation,
boldText: boldText,
gestureSettings: gestureSettings,
displayFeatures: displayFeatures,
);
}
......@@ -543,6 +561,7 @@ class MediaQueryData {
accessibleNavigation: accessibleNavigation,
boldText: boldText,
gestureSettings: gestureSettings,
displayFeatures: displayFeatures,
);
}
......@@ -565,7 +584,8 @@ class MediaQueryData {
&& other.accessibleNavigation == accessibleNavigation
&& other.boldText == boldText
&& other.navigationMode == navigationMode
&& other.gestureSettings == gestureSettings;
&& other.gestureSettings == gestureSettings
&& listEquals(other.displayFeatures, displayFeatures);
}
@override
......@@ -586,6 +606,7 @@ class MediaQueryData {
boldText,
navigationMode,
gestureSettings,
hashList(displayFeatures),
);
}
......@@ -607,6 +628,7 @@ class MediaQueryData {
'boldText: $boldText',
'navigationMode: ${navigationMode.name}',
'gestureSettings: $gestureSettings',
'displayFeatures: $displayFeatures',
];
return '${objectRuntimeType(this, 'MediaQueryData')}(${properties.join(', ')})';
}
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' show Brightness;
import 'dart:ui' show Brightness, DisplayFeature, DisplayFeatureState, DisplayFeatureType;
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
......@@ -112,6 +112,7 @@ void main() {
expect(data.highContrast, false);
expect(data.platformBrightness, Brightness.light);
expect(data.gestureSettings.touchSlop, null);
expect(data.displayFeatures, isEmpty);
});
testWidgets('MediaQueryData.copyWith defaults to source', (WidgetTester tester) async {
......@@ -132,6 +133,7 @@ void main() {
expect(copied.highContrast, data.highContrast);
expect(copied.platformBrightness, data.platformBrightness);
expect(copied.gestureSettings, data.gestureSettings);
expect(copied.displayFeatures, data.displayFeatures);
});
testWidgets('MediaQuery.copyWith copies specified values', (WidgetTester tester) async {
......@@ -145,6 +147,13 @@ void main() {
const EdgeInsets customViewInsets = EdgeInsets.all(1.67262);
const EdgeInsets customSystemGestureInsets = EdgeInsets.all(1.5556);
const DeviceGestureSettings gestureSettings = DeviceGestureSettings(touchSlop: 8.0);
const List<DisplayFeature> customDisplayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
final MediaQueryData data = MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
final MediaQueryData copied = data.copyWith(
......@@ -163,6 +172,7 @@ void main() {
highContrast: true,
platformBrightness: Brightness.dark,
gestureSettings: gestureSettings,
displayFeatures: customDisplayFeatures,
);
expect(copied.size, customSize);
expect(copied.devicePixelRatio, customDevicePixelRatio);
......@@ -179,6 +189,7 @@ void main() {
expect(copied.highContrast, true);
expect(copied.platformBrightness, Brightness.dark);
expect(copied.gestureSettings, gestureSettings);
expect(copied.displayFeatures, customDisplayFeatures);
});
testWidgets('MediaQuery.removePadding removes specified padding', (WidgetTester tester) async {
......@@ -188,6 +199,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -205,6 +223,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -238,6 +257,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.removePadding only removes specified padding', (WidgetTester tester) async {
......@@ -247,6 +267,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -264,6 +291,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -294,6 +322,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.removeViewInsets removes specified viewInsets', (WidgetTester tester) async {
......@@ -303,6 +332,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -320,6 +356,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -353,6 +390,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.removeViewInsets removes only specified viewInsets', (WidgetTester tester) async {
......@@ -362,6 +400,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -379,6 +424,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -409,6 +455,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.removeViewPadding removes specified viewPadding', (WidgetTester tester) async {
......@@ -418,6 +465,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -435,6 +489,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -468,6 +523,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.removeViewPadding removes only specified viewPadding', (WidgetTester tester) async {
......@@ -477,6 +533,13 @@ void main() {
const EdgeInsets padding = EdgeInsets.only(top: 5.0, right: 6.0, left: 7.0, bottom: 8.0);
const EdgeInsets viewPadding = EdgeInsets.only(top: 6.0, right: 8.0, left: 10.0, bottom: 12.0);
const EdgeInsets viewInsets = EdgeInsets.only(top: 1.0, right: 2.0, left: 3.0, bottom: 4.0);
const List<DisplayFeature> displayFeatures = <DisplayFeature>[
DisplayFeature(
bounds: Rect.zero,
type: DisplayFeatureType.cutout,
state: DisplayFeatureState.unknown,
),
];
late MediaQueryData unpadded;
await tester.pumpWidget(
......@@ -494,6 +557,7 @@ void main() {
disableAnimations: true,
boldText: true,
highContrast: true,
displayFeatures: displayFeatures,
),
child: Builder(
builder: (BuildContext context) {
......@@ -524,6 +588,7 @@ void main() {
expect(unpadded.disableAnimations, true);
expect(unpadded.boldText, true);
expect(unpadded.highContrast, true);
expect(unpadded.displayFeatures, displayFeatures);
});
testWidgets('MediaQuery.textScaleFactorOf', (WidgetTester tester) async {
......
......@@ -134,6 +134,20 @@ class TestWindow implements ui.SingletonFlutterWindow {
onMetricsChanged?.call();
}
@override
List<ui.DisplayFeature> get displayFeatures => _displayFeaturesTestValue ?? _window.displayFeatures;
List<ui.DisplayFeature>? _displayFeaturesTestValue;
/// Hides the real displayFeatures and reports the given [displayFeaturesTestValue] instead.
set displayFeaturesTestValue(List<ui.DisplayFeature> displayFeaturesTestValue) { // ignore: avoid_setters_without_getters
_displayFeaturesTestValue = displayFeaturesTestValue;
onMetricsChanged?.call();
}
/// Deletes any existing test padding and returns to using the real padding.
void clearDisplayFeaturesTestValue() {
_displayFeaturesTestValue = null;
onMetricsChanged?.call();
}
@override
ui.WindowPadding get systemGestureInsets => _systemGestureInsetsTestValue ?? _window.systemGestureInsets;
ui.WindowPadding? _systemGestureInsetsTestValue;
......@@ -427,6 +441,7 @@ class TestWindow implements ui.SingletonFlutterWindow {
clearLocaleTestValue();
clearLocalesTestValue();
clearPaddingTestValue();
clearDisplayFeaturesTestValue();
clearPhysicalSizeTestValue();
clearSemanticsEnabledTestValue();
clearTextScaleFactorTestValue();
......
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