mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[infra_ui][overlay] (WIP) Impl new overlay lifecycle actions
This commit is contained in:
parent
7efbf03030
commit
440d2940c3
@ -1,37 +1,104 @@
|
||||
import 'dart:ui' show window;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'overlay_basis.dart';
|
||||
import 'overlay_layout_delegate.dart';
|
||||
|
||||
class OverlayPannel extends StatelessWidget {
|
||||
class OverlayPannel extends StatefulWidget {
|
||||
const OverlayPannel({
|
||||
Key? key,
|
||||
required this.child,
|
||||
required this.targetRect,
|
||||
required this.anchorRect,
|
||||
this.safeAreaEnabled = true,
|
||||
this.anchorDirection = AnchorDirection.topRight,
|
||||
this.insets = EdgeInsets.zero,
|
||||
this.focusNode,
|
||||
}) : super(key: key);
|
||||
|
||||
final AnchorDirection anchorDirection;
|
||||
final bool safeAreaEnabled;
|
||||
final EdgeInsets insets;
|
||||
final Rect targetRect;
|
||||
final Rect anchorRect;
|
||||
final Widget child;
|
||||
final FocusNode? focusNode;
|
||||
|
||||
@override
|
||||
_OverlayPannelState createState() => _OverlayPannelState();
|
||||
}
|
||||
|
||||
class _OverlayPannelState extends State<OverlayPannel> with WidgetsBindingObserver {
|
||||
FocusNode? _internalNode;
|
||||
FocusNode? get focusNode => widget.focusNode ?? _internalNode;
|
||||
late FocusHighlightMode _focusHighlightMode;
|
||||
bool _hasPrimaryFocus = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.focusNode == null) {
|
||||
_internalNode ??= _createFocusNode();
|
||||
}
|
||||
focusNode!.addListener(_handleFocusChanged);
|
||||
final FocusManager focusManager = WidgetsBinding.instance!.focusManager;
|
||||
_focusHighlightMode = focusManager.highlightMode;
|
||||
focusManager.addHighlightModeListener(_handleFocusHighlightModeChanged);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance!.removeObserver(this);
|
||||
focusNode!.removeListener(_handleFocusChanged);
|
||||
WidgetsBinding.instance!.focusManager.removeHighlightModeListener(_handleFocusHighlightModeChanged);
|
||||
_internalNode?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomSingleChildLayout(
|
||||
delegate: OverlayLayoutDelegate(
|
||||
targetRect: targetRect,
|
||||
anchorRect: anchorRect,
|
||||
safeAreaEnabled: safeAreaEnabled,
|
||||
anchorDirection: anchorDirection,
|
||||
insets: insets,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
return Container();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(OverlayPannel oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (widget.focusNode != oldWidget.focusNode) {
|
||||
oldWidget.focusNode?.removeListener(_handleFocusChanged);
|
||||
if (widget.focusNode == null) {
|
||||
_internalNode ??= _createFocusNode();
|
||||
}
|
||||
_hasPrimaryFocus = focusNode!.hasPrimaryFocus;
|
||||
focusNode!.addListener(_handleFocusChanged);
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Focus & Route
|
||||
|
||||
FocusNode _createFocusNode() {
|
||||
return FocusNode(debugLabel: '${widget.runtimeType}');
|
||||
}
|
||||
|
||||
void _handleFocusChanged() {
|
||||
if (_hasPrimaryFocus != focusNode!.hasPrimaryFocus) {
|
||||
setState(() {
|
||||
_hasPrimaryFocus = focusNode!.hasPrimaryFocus;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _handleFocusHighlightModeChanged(FocusHighlightMode mode) {
|
||||
if (!mounted) {
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_focusHighlightMode = mode;
|
||||
});
|
||||
}
|
||||
|
||||
void _removeOverlayRoute() {
|
||||
// TODO: junlin
|
||||
}
|
||||
|
||||
// MARK: Layout
|
||||
|
||||
Orientation _getOrientation(BuildContext context) {
|
||||
Orientation? result = MediaQuery.maybeOf(context)?.orientation;
|
||||
if (result == null) {
|
||||
// If there's no MediaQuery, then use the window aspect to determine
|
||||
// orientation.
|
||||
final Size size = window.physicalSize;
|
||||
result = size.width > size.height ? Orientation.landscape : Orientation.portrait;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user