mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[infra_ui][overlay] Implement overlap behavior and update example proj
This commit is contained in:
parent
39ac4b59be
commit
eb4728e346
@ -20,8 +20,8 @@ class OverlayItem extends DemoItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OverlayDemoAnchorDirection extends ChangeNotifier {
|
class OverlayDemoConfiguration extends ChangeNotifier {
|
||||||
OverlayDemoAnchorDirection(this._anchorDirection);
|
OverlayDemoConfiguration(this._anchorDirection, this._overlapBehaviour);
|
||||||
|
|
||||||
AnchorDirection _anchorDirection;
|
AnchorDirection _anchorDirection;
|
||||||
|
|
||||||
@ -31,6 +31,15 @@ class OverlayDemoAnchorDirection extends ChangeNotifier {
|
|||||||
_anchorDirection = value;
|
_anchorDirection = value;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OverlapBehaviour _overlapBehaviour;
|
||||||
|
|
||||||
|
OverlapBehaviour get overlapBehaviour => _overlapBehaviour;
|
||||||
|
|
||||||
|
set overlapBehaviour(OverlapBehaviour value) {
|
||||||
|
_overlapBehaviour = value;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OverlayScreen extends StatelessWidget {
|
class OverlayScreen extends StatelessWidget {
|
||||||
@ -43,7 +52,7 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
title: const Text('Overlay Demo'),
|
title: const Text('Overlay Demo'),
|
||||||
),
|
),
|
||||||
body: ChangeNotifierProvider(
|
body: ChangeNotifierProvider(
|
||||||
create: (context) => OverlayDemoAnchorDirection(AnchorDirection.rightWithTopAligned),
|
create: (context) => OverlayDemoConfiguration(AnchorDirection.rightWithTopAligned, OverlapBehaviour.stretch),
|
||||||
child: Builder(builder: (providerContext) {
|
child: Builder(builder: (providerContext) {
|
||||||
return Center(
|
return Center(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
@ -80,10 +89,10 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 24.0),
|
const SizedBox(height: 24.0),
|
||||||
DropdownButton<AnchorDirection>(
|
DropdownButton<AnchorDirection>(
|
||||||
value: providerContext.watch<OverlayDemoAnchorDirection>().anchorDirection,
|
value: providerContext.watch<OverlayDemoConfiguration>().anchorDirection,
|
||||||
onChanged: (AnchorDirection? newValue) {
|
onChanged: (AnchorDirection? newValue) {
|
||||||
if (newValue != null) {
|
if (newValue != null) {
|
||||||
providerContext.read<OverlayDemoAnchorDirection>().anchorDirection = newValue;
|
providerContext.read<OverlayDemoConfiguration>().anchorDirection = newValue;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
items: AnchorDirection.values.map((AnchorDirection classType) {
|
items: AnchorDirection.values.map((AnchorDirection classType) {
|
||||||
@ -91,6 +100,18 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24.0),
|
const SizedBox(height: 24.0),
|
||||||
|
DropdownButton<OverlapBehaviour>(
|
||||||
|
value: providerContext.watch<OverlayDemoConfiguration>().overlapBehaviour,
|
||||||
|
onChanged: (OverlapBehaviour? newValue) {
|
||||||
|
if (newValue != null) {
|
||||||
|
providerContext.read<OverlayDemoConfiguration>().overlapBehaviour = newValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
items: OverlapBehaviour.values.map((OverlapBehaviour classType) {
|
||||||
|
return DropdownMenuItem<OverlapBehaviour>(value: classType, child: Text(classType.toString()));
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24.0),
|
||||||
Builder(builder: (buttonContext) {
|
Builder(builder: (buttonContext) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 100,
|
height: 100,
|
||||||
@ -98,7 +119,7 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
widget: SizedBox(
|
widget: SizedBox(
|
||||||
width: 100,
|
width: 300,
|
||||||
height: 50,
|
height: 50,
|
||||||
child: Card(
|
child: Card(
|
||||||
color: Colors.grey[200],
|
color: Colors.grey[200],
|
||||||
@ -112,7 +133,8 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
identifier: 'overlay_anchored_card',
|
identifier: 'overlay_anchored_card',
|
||||||
delegate: null,
|
delegate: null,
|
||||||
anchorContext: buttonContext,
|
anchorContext: buttonContext,
|
||||||
anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
|
anchorDirection: providerContext.read<OverlayDemoConfiguration>().anchorDirection,
|
||||||
|
overlapBehaviour: providerContext.read<OverlayDemoConfiguration>().overlapBehaviour,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const Text('Show Anchored Overlay'),
|
child: const Text('Show Anchored Overlay'),
|
||||||
@ -140,7 +162,8 @@ class OverlayScreen extends StatelessWidget {
|
|||||||
delegate: null,
|
delegate: null,
|
||||||
anchorPosition: Offset(0, windowSize.height - 200),
|
anchorPosition: Offset(0, windowSize.height - 200),
|
||||||
anchorSize: Size.zero,
|
anchorSize: Size.zero,
|
||||||
anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
|
anchorDirection: providerContext.read<OverlayDemoConfiguration>().anchorDirection,
|
||||||
|
overlapBehaviour: providerContext.read<OverlayDemoConfiguration>().overlapBehaviour,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: const Text('Show Positioned Overlay'),
|
child: const Text('Show Positioned Overlay'),
|
||||||
|
@ -28,8 +28,7 @@ enum AnchorDirection {
|
|||||||
custom,
|
custom,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: junlin - support overlap behaviour
|
/// The behaviour of overlay when overlap with anchor widget
|
||||||
/// [Unsupported] The behaviour of overlay when overlap with anchor widget
|
|
||||||
enum OverlapBehaviour {
|
enum OverlapBehaviour {
|
||||||
/// Maintain overlay size, which may cover the anchor widget.
|
/// Maintain overlay size, which may cover the anchor widget.
|
||||||
none,
|
none,
|
||||||
@ -144,6 +143,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
required Size anchorSize,
|
required Size anchorSize,
|
||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
|
OverlapBehaviour? overlapBehaviour,
|
||||||
}) {
|
}) {
|
||||||
_showOverlay(
|
_showOverlay(
|
||||||
widget: widget,
|
widget: widget,
|
||||||
@ -153,6 +153,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
anchorPosition: anchorPosition,
|
anchorPosition: anchorPosition,
|
||||||
anchorSize: anchorSize,
|
anchorSize: anchorSize,
|
||||||
anchorDirection: anchorDirection,
|
anchorDirection: anchorDirection,
|
||||||
|
overlapBehaviour: overlapBehaviour,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +163,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
required BuildContext anchorContext,
|
required BuildContext anchorContext,
|
||||||
AnchorDirection? anchorDirection,
|
AnchorDirection? anchorDirection,
|
||||||
FlowyOverlayDelegate? delegate,
|
FlowyOverlayDelegate? delegate,
|
||||||
|
OverlapBehaviour? overlapBehaviour,
|
||||||
}) {
|
}) {
|
||||||
_showOverlay(
|
_showOverlay(
|
||||||
widget: widget,
|
widget: widget,
|
||||||
@ -170,6 +172,7 @@ class FlowyOverlayState extends State<FlowyOverlay> {
|
|||||||
delegate: delegate,
|
delegate: delegate,
|
||||||
anchorContext: anchorContext,
|
anchorContext: anchorContext,
|
||||||
anchorDirection: anchorDirection,
|
anchorDirection: anchorDirection,
|
||||||
|
overlapBehaviour: overlapBehaviour,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,8 +29,93 @@ class OverlayLayoutDelegate extends SingleChildLayoutDelegate {
|
|||||||
case OverlapBehaviour.none:
|
case OverlapBehaviour.none:
|
||||||
return constraints.loosen();
|
return constraints.loosen();
|
||||||
case OverlapBehaviour.stretch:
|
case OverlapBehaviour.stretch:
|
||||||
// TODO: junlin - resize when overlapBehaviour == .stretch
|
BoxConstraints childConstraints;
|
||||||
return constraints.loosen();
|
switch (anchorDirection) {
|
||||||
|
case AnchorDirection.topLeft:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
anchorRect.top,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.topRight:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth - anchorRect.right,
|
||||||
|
anchorRect.top,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomLeft:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomRight:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth - anchorRect.right,
|
||||||
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithTopAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth - anchorRect.right,
|
||||||
|
constraints.maxHeight - anchorRect.top,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithCenterAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth - anchorRect.right,
|
||||||
|
constraints.maxHeight,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithBottomAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth - anchorRect.right,
|
||||||
|
anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithLeftAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithCenterAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
constraints.maxWidth,
|
||||||
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithRightAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.right,
|
||||||
|
constraints.maxHeight - anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithTopAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
constraints.maxHeight - anchorRect.top,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithCenterAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
constraints.maxHeight,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithBottomAligned:
|
||||||
|
childConstraints = BoxConstraints.loose(Size(
|
||||||
|
anchorRect.left,
|
||||||
|
anchorRect.bottom,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
case AnchorDirection.custom:
|
||||||
|
childConstraints = constraints.loosen();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
return childConstraints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user