Merge pull request #2445 from Hixie/overlay
Clarify the "needs an Overlay" assert.
This commit is contained in:
commit
d55e5a698a
@ -182,6 +182,7 @@ class _DropDownRoute<T> extends PopupRoute<_DropDownRouteResult<T>> {
|
|||||||
|
|
||||||
ModalPosition getPosition(BuildContext context) {
|
ModalPosition getPosition(BuildContext context) {
|
||||||
RenderBox overlayBox = Overlay.of(context).context.findRenderObject();
|
RenderBox overlayBox = Overlay.of(context).context.findRenderObject();
|
||||||
|
assert(overlayBox != null); // can't be null; routes get inserted by Navigator which has its own Overlay
|
||||||
Size overlaySize = overlayBox.size;
|
Size overlaySize = overlayBox.size;
|
||||||
RelativeRect menuRect = new RelativeRect.fromSize(rect, overlaySize);
|
RelativeRect menuRect = new RelativeRect.fromSize(rect, overlaySize);
|
||||||
return new ModalPosition(
|
return new ModalPosition(
|
||||||
|
@ -46,6 +46,7 @@ class Tooltip extends StatefulComponent {
|
|||||||
assert(preferBelow != null);
|
assert(preferBelow != null);
|
||||||
assert(fadeDuration != null);
|
assert(fadeDuration != null);
|
||||||
assert(showDuration != null);
|
assert(showDuration != null);
|
||||||
|
assert(child != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String message;
|
final String message;
|
||||||
@ -150,7 +151,7 @@ class _TooltipState extends State<Tooltip> {
|
|||||||
preferBelow: config.preferBelow
|
preferBelow: config.preferBelow
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
Overlay.of(context).insert(_entry);
|
Overlay.of(context, debugRequiredFor: config).insert(_entry);
|
||||||
}
|
}
|
||||||
_timer?.cancel();
|
_timer?.cancel();
|
||||||
if (_controller.status != AnimationStatus.completed) {
|
if (_controller.status != AnimationStatus.completed) {
|
||||||
@ -175,7 +176,7 @@ class _TooltipState extends State<Tooltip> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
assert(Overlay.of(context) != null);
|
assert(Overlay.of(context, debugRequiredFor: config) != null);
|
||||||
return new GestureDetector(
|
return new GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onLongPress: showTooltip,
|
onLongPress: showTooltip,
|
||||||
|
@ -234,7 +234,7 @@ class _DraggableState<T> extends State<DraggableBase<T>> {
|
|||||||
_activeCount += 1;
|
_activeCount += 1;
|
||||||
});
|
});
|
||||||
return new _DragAvatar<T>(
|
return new _DragAvatar<T>(
|
||||||
overlay: Overlay.of(context),
|
overlay: Overlay.of(context, debugRequiredFor: config),
|
||||||
data: config.data,
|
data: config.data,
|
||||||
initialPosition: position,
|
initialPosition: position,
|
||||||
dragStartPoint: dragStartPoint,
|
dragStartPoint: dragStartPoint,
|
||||||
@ -249,6 +249,7 @@ class _DraggableState<T> extends State<DraggableBase<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
assert(Overlay.of(context, debugRequiredFor: config) != null);
|
||||||
final bool canDrag = config.maxSimultaneousDrags == null ||
|
final bool canDrag = config.maxSimultaneousDrags == null ||
|
||||||
_activeCount < config.maxSimultaneousDrags;
|
_activeCount < config.maxSimultaneousDrags;
|
||||||
final bool showChild = _activeCount == 0 || config.childWhenDragging == null;
|
final bool showChild = _activeCount == 0 || config.childWhenDragging == null;
|
||||||
|
@ -137,6 +137,9 @@ class Mimic extends StatelessComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A widget that can be copied by a [Mimic].
|
/// A widget that can be copied by a [Mimic].
|
||||||
|
///
|
||||||
|
/// This widget's State, [MimicableState], contains an API for initiating the
|
||||||
|
/// mimic operation.
|
||||||
class Mimicable extends StatefulComponent {
|
class Mimicable extends StatefulComponent {
|
||||||
Mimicable({ Key key, this.child }) : super(key: key);
|
Mimicable({ Key key, this.child }) : super(key: key);
|
||||||
|
|
||||||
@ -193,8 +196,7 @@ class MimicableState extends State<Mimicable> {
|
|||||||
/// had when the mimicking process started and (2) the child will be
|
/// had when the mimicking process started and (2) the child will be
|
||||||
/// placed in the enclosing overlay.
|
/// placed in the enclosing overlay.
|
||||||
MimicOverlayEntry liftToOverlay() {
|
MimicOverlayEntry liftToOverlay() {
|
||||||
OverlayState overlay = Overlay.of(context);
|
OverlayState overlay = Overlay.of(context, debugRequiredFor: config);
|
||||||
assert(overlay != null); // You need an overlay to lift into.
|
|
||||||
MimicOverlayEntry entry = new MimicOverlayEntry._(startMimic());
|
MimicOverlayEntry entry = new MimicOverlayEntry._(startMimic());
|
||||||
overlay.insert(entry._overlayEntry);
|
overlay.insert(entry._overlayEntry);
|
||||||
return entry;
|
return entry;
|
||||||
|
@ -71,7 +71,32 @@ class Overlay extends StatefulComponent {
|
|||||||
final List<OverlayEntry> initialEntries;
|
final List<OverlayEntry> initialEntries;
|
||||||
|
|
||||||
/// The state from the closest instance of this class that encloses the given context.
|
/// The state from the closest instance of this class that encloses the given context.
|
||||||
static OverlayState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<OverlayState>());
|
///
|
||||||
|
/// In checked mode, if the [debugRequiredFor] argument is provided then this
|
||||||
|
/// function will assert that an overlay was found and will throw an exception
|
||||||
|
/// if not. The exception attempts to explain that the calling [Widget] (the
|
||||||
|
/// one given by the [debugRequiredFor] argument) needs an [Overlay] to be
|
||||||
|
/// present to function.
|
||||||
|
static OverlayState of(BuildContext context, { Widget debugRequiredFor }) {
|
||||||
|
OverlayState result = context.ancestorStateOfType(const TypeMatcher<OverlayState>());
|
||||||
|
assert(() {
|
||||||
|
if (debugRequiredFor != null && result == null) {
|
||||||
|
String additional = context.widget != debugRequiredFor
|
||||||
|
? '\nThe context from which that widget was searching for an overlay was:\n $context'
|
||||||
|
: '';
|
||||||
|
throw new WidgetError(
|
||||||
|
'No Overlay widget found.\n'
|
||||||
|
'${debugRequiredFor.runtimeType} widgets require an Overlay widget ancestor for correct operation.\n'
|
||||||
|
'The most common way to add an Overlay to an application is to include a MaterialApp or Navigator widget in the runApp() call.\n'
|
||||||
|
'The specific widget that failed to find an overlay was:\n'
|
||||||
|
' $debugRequiredFor'
|
||||||
|
'$additional'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
OverlayState createState() => new OverlayState();
|
OverlayState createState() => new OverlayState();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user