mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-04-24 14:47:13 -04:00
[infra_ui][overlar] Implement edge aligned anchor mode and update example project
This commit is contained in:
parent
dffb56d1a9
commit
5c4df3c6f2
2 changed files with 185 additions and 89 deletions
|
@ -43,96 +43,111 @@ class OverlayScreen extends StatelessWidget {
|
||||||
title: const Text('Overlay Demo'),
|
title: const Text('Overlay Demo'),
|
||||||
),
|
),
|
||||||
body: ChangeNotifierProvider(
|
body: ChangeNotifierProvider(
|
||||||
create: (context) => OverlayDemoAnchorDirection(AnchorDirection.topLeft),
|
create: (context) => OverlayDemoAnchorDirection(AnchorDirection.rightWithTopAligned),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (providerContext) {
|
||||||
return Column(
|
return Center(
|
||||||
children: [
|
child: ConstrainedBox(
|
||||||
DropdownButton<AnchorDirection>(
|
constraints: const BoxConstraints.tightFor(width: 500),
|
||||||
value: context.watch<OverlayDemoAnchorDirection>().anchorDirection,
|
child: Column(
|
||||||
onChanged: (AnchorDirection? newValue) {
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
if (newValue != null) {
|
children: [
|
||||||
context.read<OverlayDemoAnchorDirection>().anchorDirection = newValue;
|
const SizedBox(height: 48.0),
|
||||||
}
|
ElevatedButton(
|
||||||
},
|
onPressed: () {
|
||||||
items: AnchorDirection.values.map((AnchorDirection classType) {
|
final windowSize = MediaQuery.of(context).size;
|
||||||
return DropdownMenuItem<AnchorDirection>(value: classType, child: Text(classType.toString()));
|
FlowyOverlay.of(context).insertCustom(
|
||||||
}).toList(),
|
widget: Positioned(
|
||||||
),
|
left: windowSize.width / 2.0 - 100,
|
||||||
Flexible(
|
top: 200,
|
||||||
child: Padding(
|
child: SizedBox(
|
||||||
padding: const EdgeInsets.all(16.0),
|
width: 200,
|
||||||
child: Container(
|
height: 100,
|
||||||
height: 300.0,
|
child: Card(
|
||||||
decoration: BoxDecoration(
|
color: Colors.green[200],
|
||||||
borderRadius: BorderRadius.circular(15.0),
|
child: GestureDetector(
|
||||||
color: Colors.grey[200],
|
// ignore: avoid_print
|
||||||
),
|
onTapDown: (_) => print('Hello Flutter'),
|
||||||
),
|
child: const Center(child: FlutterLogo(size: 100)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
FlowyOverlay.of(context).insertCustom(
|
|
||||||
widget: const FlutterLogo(
|
|
||||||
size: 200,
|
|
||||||
),
|
|
||||||
identifier: 'overlay_flutter_logo',
|
|
||||||
delegate: null,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: const Text('Show Overlay'),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 12.0),
|
|
||||||
Builder(builder: (buttonContext) {
|
|
||||||
return ElevatedButton(
|
|
||||||
onPressed: () {
|
|
||||||
FlowyOverlay.of(context).insertWithAnchor(
|
|
||||||
widget: SizedBox(
|
|
||||||
width: 200,
|
|
||||||
height: 100,
|
|
||||||
child: Card(
|
|
||||||
color: Colors.grey[200],
|
|
||||||
child: GestureDetector(
|
|
||||||
onTapDown: (_) => print('Hello Flutter'),
|
|
||||||
child: const Center(child: FlutterLogo(size: 100)),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
identifier: 'overlay_flutter_logo',
|
||||||
identifier: 'overlay_card',
|
delegate: null,
|
||||||
delegate: null,
|
);
|
||||||
anchorContext: buttonContext,
|
},
|
||||||
anchorDirection: context.read<OverlayDemoAnchorDirection>().anchorDirection,
|
child: const Text('Show Overlay'),
|
||||||
);
|
),
|
||||||
},
|
const SizedBox(height: 24.0),
|
||||||
child: const Text('Show Anchored Overlay'),
|
DropdownButton<AnchorDirection>(
|
||||||
);
|
value: providerContext.watch<OverlayDemoAnchorDirection>().anchorDirection,
|
||||||
}),
|
onChanged: (AnchorDirection? newValue) {
|
||||||
const SizedBox(height: 12.0),
|
if (newValue != null) {
|
||||||
ElevatedButton(
|
providerContext.read<OverlayDemoAnchorDirection>().anchorDirection = newValue;
|
||||||
onPressed: () {
|
}
|
||||||
final windowSize = MediaQuery.of(context).size;
|
},
|
||||||
FlowyOverlay.of(context).insertWithRect(
|
items: AnchorDirection.values.map((AnchorDirection classType) {
|
||||||
widget: SizedBox(
|
return DropdownMenuItem<AnchorDirection>(value: classType, child: Text(classType.toString()));
|
||||||
width: 200,
|
}).toList(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24.0),
|
||||||
|
Builder(builder: (buttonContext) {
|
||||||
|
return SizedBox(
|
||||||
height: 100,
|
height: 100,
|
||||||
child: Card(
|
child: ElevatedButton(
|
||||||
color: Colors.orange[200],
|
onPressed: () {
|
||||||
child: GestureDetector(
|
FlowyOverlay.of(context).insertWithAnchor(
|
||||||
onTapDown: (_) => print('Hello Flutter'),
|
widget: SizedBox(
|
||||||
child: const Center(child: FlutterLogo(size: 100)),
|
width: 100,
|
||||||
),
|
height: 50,
|
||||||
|
child: Card(
|
||||||
|
color: Colors.grey[200],
|
||||||
|
child: GestureDetector(
|
||||||
|
// ignore: avoid_print
|
||||||
|
onTapDown: (_) => print('Hello Flutter'),
|
||||||
|
child: const Center(child: FlutterLogo(size: 50)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
identifier: 'overlay_anchored_card',
|
||||||
|
delegate: null,
|
||||||
|
anchorContext: buttonContext,
|
||||||
|
anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('Show Anchored Overlay'),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
identifier: 'overlay_card',
|
}),
|
||||||
delegate: null,
|
const SizedBox(height: 24.0),
|
||||||
anchorPosition: Offset(0, windowSize.height - 200),
|
ElevatedButton(
|
||||||
anchorSize: Size.zero,
|
onPressed: () {
|
||||||
anchorDirection: context.read<OverlayDemoAnchorDirection>().anchorDirection,
|
final windowSize = MediaQuery.of(context).size;
|
||||||
);
|
FlowyOverlay.of(context).insertWithRect(
|
||||||
},
|
widget: SizedBox(
|
||||||
child: const Text('Show Positioned Overlay'),
|
width: 200,
|
||||||
|
height: 100,
|
||||||
|
child: Card(
|
||||||
|
color: Colors.orange[200],
|
||||||
|
child: GestureDetector(
|
||||||
|
// ignore: avoid_print
|
||||||
|
onTapDown: (_) => print('Hello Flutter'),
|
||||||
|
child: const Center(child: FlutterLogo(size: 100)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
identifier: 'overlay_positioned_card',
|
||||||
|
delegate: null,
|
||||||
|
anchorPosition: Offset(0, windowSize.height - 200),
|
||||||
|
anchorSize: Size.zero,
|
||||||
|
anchorDirection: providerContext.read<OverlayDemoAnchorDirection>().anchorDirection,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: const Text('Show Positioned Overlay'),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|
|
@ -39,16 +39,97 @@ class OverlayLayoutDelegate extends SingleChildLayoutDelegate {
|
||||||
Offset position;
|
Offset position;
|
||||||
switch (anchorDirection) {
|
switch (anchorDirection) {
|
||||||
case AnchorDirection.topLeft:
|
case AnchorDirection.topLeft:
|
||||||
position = Offset(anchorRect.left - childSize.width, anchorRect.top - childSize.height);
|
position = Offset(
|
||||||
|
anchorRect.left - childSize.width,
|
||||||
|
anchorRect.top - childSize.height,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case AnchorDirection.topRight:
|
case AnchorDirection.topRight:
|
||||||
position = Offset(anchorRect.right, anchorRect.top - childSize.height);
|
position = Offset(
|
||||||
|
anchorRect.right,
|
||||||
|
anchorRect.top - childSize.height,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case AnchorDirection.bottomLeft:
|
case AnchorDirection.bottomLeft:
|
||||||
position = Offset(anchorRect.left - childSize.width, anchorRect.bottom);
|
position = Offset(
|
||||||
|
anchorRect.left - childSize.width,
|
||||||
|
anchorRect.bottom,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case AnchorDirection.bottomRight:
|
case AnchorDirection.bottomRight:
|
||||||
position = Offset(anchorRect.right, anchorRect.bottom);
|
position = Offset(
|
||||||
|
anchorRect.right,
|
||||||
|
anchorRect.bottom,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.topWithLeftAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left,
|
||||||
|
anchorRect.top - childSize.height,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.topWithCenterAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left + anchorRect.width / 2.0 - childSize.width / 2.0,
|
||||||
|
anchorRect.top - childSize.height,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.topWithRightAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.right - childSize.width,
|
||||||
|
anchorRect.top - childSize.height,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithTopAligned:
|
||||||
|
position = Offset(anchorRect.right, anchorRect.top);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithCenterAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.right,
|
||||||
|
anchorRect.top + anchorRect.height / 2.0 - childSize.height / 2.0,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.rightWithBottomAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.right,
|
||||||
|
anchorRect.bottom - childSize.height,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithLeftAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left,
|
||||||
|
anchorRect.bottom,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithCenterAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left + anchorRect.width / 2.0 - childSize.width / 2.0,
|
||||||
|
anchorRect.bottom,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.bottomWithRightAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.right - childSize.width,
|
||||||
|
anchorRect.bottom,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithTopAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left - childSize.width,
|
||||||
|
anchorRect.top,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithCenterAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left - childSize.width,
|
||||||
|
anchorRect.top + anchorRect.height / 2.0 - childSize.height / 2.0,
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case AnchorDirection.leftWithBottomAligned:
|
||||||
|
position = Offset(
|
||||||
|
anchorRect.left - childSize.width,
|
||||||
|
anchorRect.bottom - childSize.height,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw UnimplementedError();
|
throw UnimplementedError();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue