refactor: rename popover

This commit is contained in:
Vincent Chan 2022-08-30 12:51:59 +08:00
parent 406f185ab7
commit e9535201a4
9 changed files with 94 additions and 49 deletions

View File

@ -1,7 +1,6 @@
import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart'; import 'package:app_flowy/plugins/grid/application/field/field_cell_bloc.dart';
import 'package:app_flowy/plugins/grid/application/field/field_service.dart'; import 'package:app_flowy/plugins/grid/application/field/field_service.dart';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_context.dart'; import 'package:appflowy_popover/popover.dart';
import 'package:appflowy_popover/appflowy_popover.dart';
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart'; import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
@ -15,7 +14,6 @@ import '../../layout/sizes.dart';
import 'field_type_extension.dart'; import 'field_type_extension.dart';
import 'field_cell_action_sheet.dart'; import 'field_cell_action_sheet.dart';
import 'field_editor.dart';
class GridFieldCell extends StatefulWidget { class GridFieldCell extends StatefulWidget {
final GridFieldCellContext cellContext; final GridFieldCellContext cellContext;
@ -26,7 +24,7 @@ class GridFieldCell extends StatefulWidget {
} }
class _GridFieldCellState extends State<GridFieldCell> { class _GridFieldCellState extends State<GridFieldCell> {
final popover = AppFlowyPopoverController(); final popover = PopoverController();
@override @override
Widget build(BuildContext gridCellContext) { Widget build(BuildContext gridCellContext) {
@ -36,7 +34,7 @@ class _GridFieldCellState extends State<GridFieldCell> {
child: BlocBuilder<FieldCellBloc, FieldCellState>( child: BlocBuilder<FieldCellBloc, FieldCellState>(
// buildWhen: (p, c) => p.field != c.field, // buildWhen: (p, c) => p.field != c.field,
builder: (context, state) { builder: (context, state) {
final button = AppFlowyPopover( final button = Popover(
controller: popover, controller: popover,
child: FieldCellButton( child: FieldCellButton(
field: state.field, field: state.field,

View File

@ -11,7 +11,7 @@ import 'package:flowy_infra_ui/widget/spacing.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/popover.dart';
import 'package:app_flowy/generated/locale_keys.g.dart'; import 'package:app_flowy/generated/locale_keys.g.dart';
import '../../layout/sizes.dart'; import '../../layout/sizes.dart';
@ -61,7 +61,7 @@ class _EditFieldButton extends StatefulWidget {
} }
class _EditFieldButtonState extends State<_EditFieldButton> { class _EditFieldButtonState extends State<_EditFieldButton> {
final popover = AppFlowyPopoverController(); final popover = PopoverController();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -70,7 +70,7 @@ class _EditFieldButtonState extends State<_EditFieldButton> {
builder: (context, state) { builder: (context, state) {
return SizedBox( return SizedBox(
height: GridSize.typeOptionItemHeight, height: GridSize.typeOptionItemHeight,
child: AppFlowyPopover( child: Popover(
controller: popover, controller: popover,
targetAnchor: Alignment.topRight, targetAnchor: Alignment.topRight,
followerAnchor: Alignment.topLeft, followerAnchor: Alignment.topLeft,

View File

@ -10,7 +10,7 @@ import 'package:app_flowy/generated/locale_keys.g.dart';
import 'field_name_input.dart'; import 'field_name_input.dart';
import 'field_type_option_editor.dart'; import 'field_type_option_editor.dart';
class FieldEditor extends StatelessWidget with FlowyOverlayDelegate { class FieldEditor extends StatelessWidget {
final String gridId; final String gridId;
final String fieldName; final String fieldName;
@ -49,10 +49,6 @@ class FieldEditor extends StatelessWidget with FlowyOverlayDelegate {
); );
} }
static String identifier() {
return (FieldEditor).toString();
}
@override @override
bool asBarrier() => true; bool asBarrier() => true;
} }

View File

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart'; import 'package:app_flowy/plugins/grid/application/field/type_option/type_option_data_controller.dart';
import 'package:appflowy_popover/popover.dart';
import 'package:dartz/dartz.dart' show Either; import 'package:dartz/dartz.dart' show Either;
import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/image.dart';
import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra/theme.dart';
@ -36,6 +37,7 @@ class FieldTypeOptionEditor extends StatefulWidget {
} }
class _FieldTypeOptionEditorState extends State<FieldTypeOptionEditor> { class _FieldTypeOptionEditorState extends State<FieldTypeOptionEditor> {
final popover = PopoverController();
String? currentOverlayIdentifier; String? currentOverlayIdentifier;
@override @override
@ -68,19 +70,34 @@ class _FieldTypeOptionEditorState extends State<FieldTypeOptionEditor> {
final theme = context.watch<AppTheme>(); final theme = context.watch<AppTheme>();
return SizedBox( return SizedBox(
height: GridSize.typeOptionItemHeight, height: GridSize.typeOptionItemHeight,
child: Popover(
controller: popover,
offset: const Offset(20, 0),
targetAnchor: Alignment.topRight,
followerAnchor: Alignment.topLeft,
popupBuilder: (context) {
final list = FieldTypeList(onSelectField: (newFieldType) {
widget.dataController.switchToField(newFieldType);
});
return OverlayContainer(
constraints: BoxConstraints.loose(const Size(460, 440)),
child: list,
);
},
child: FlowyButton( child: FlowyButton(
text: FlowyText.medium(field.fieldType.title(), fontSize: 12), text: FlowyText.medium(field.fieldType.title(), fontSize: 12),
margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
hoverColor: theme.hover, hoverColor: theme.hover,
onTap: () { onHover: (bool hover) {
final list = FieldTypeList(onSelectField: (newFieldType) { if (hover) {
widget.dataController.switchToField(newFieldType); popover.show();
}); }
_showOverlay(context, list);
}, },
leftIcon: svgWidget(field.fieldType.iconName(), color: theme.iconColor), leftIcon:
svgWidget(field.fieldType.iconName(), color: theme.iconColor),
rightIcon: svgWidget("grid/more", color: theme.iconColor), rightIcon: svgWidget("grid/more", color: theme.iconColor),
), ),
),
); );
} }

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:appflowy_popover/popover.dart';
class PopoverMenu extends StatefulWidget { class PopoverMenu extends StatefulWidget {
@override @override
@ -7,14 +7,14 @@ class PopoverMenu extends StatefulWidget {
} }
class _PopoverMenuState extends State<PopoverMenu> { class _PopoverMenuState extends State<PopoverMenu> {
final AppFlowyPopoverExclusive exclusive = AppFlowyPopoverExclusive(); final PopoverExclusive exclusive = PopoverExclusive();
late AppFlowyPopoverController firstPopover; late PopoverController firstPopover;
late AppFlowyPopoverController secondPopover; late PopoverController secondPopover;
@override @override
void initState() { void initState() {
firstPopover = AppFlowyPopoverController(exclusive: exclusive); firstPopover = PopoverController(exclusive: exclusive);
secondPopover = AppFlowyPopoverController(exclusive: exclusive); secondPopover = PopoverController(exclusive: exclusive);
super.initState(); super.initState();
} }
@ -26,7 +26,7 @@ class _PopoverMenuState extends State<PopoverMenu> {
decoration: const BoxDecoration(color: Colors.yellow), decoration: const BoxDecoration(color: Colors.yellow),
child: ListView(children: [ child: ListView(children: [
const Text("App"), const Text("App"),
AppFlowyPopover( Popover(
controller: firstPopover, controller: firstPopover,
offset: const Offset(10, 0), offset: const Offset(10, 0),
targetAnchor: Alignment.topRight, targetAnchor: Alignment.topRight,
@ -46,7 +46,7 @@ class _PopoverMenuState extends State<PopoverMenu> {
child: const Text("First"), child: const Text("First"),
), ),
), ),
AppFlowyPopover( Popover(
controller: secondPopover, controller: secondPopover,
offset: const Offset(10, 0), offset: const Offset(10, 0),
targetAnchor: Alignment.topRight, targetAnchor: Alignment.topRight,
@ -72,7 +72,7 @@ class _PopoverMenuState extends State<PopoverMenu> {
} }
class ExampleButton extends StatelessWidget { class ExampleButton extends StatelessWidget {
final AppFlowyPopoverController _popover = AppFlowyPopoverController(); final PopoverController _popover = PopoverController();
final String label; final String label;
final Alignment targetAnchor; final Alignment targetAnchor;
@ -89,7 +89,7 @@ class ExampleButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppFlowyPopover( return Popover(
controller: _popover, controller: _popover,
targetAnchor: targetAnchor, targetAnchor: targetAnchor,
followerAnchor: followerAnchor, followerAnchor: followerAnchor,

View File

@ -1,15 +1,16 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class AppFlowyPopoverExclusive { class PopoverExclusive {
AppFlowyPopoverController? controller; PopoverController? controller;
} }
class AppFlowyPopoverController { class PopoverController {
AppFlowyPopoverState? state; PopoverState? state;
AppFlowyPopoverExclusive? exclusive; PopoverExclusive? exclusive;
AppFlowyPopoverController({this.exclusive}); PopoverController({this.exclusive});
close() { close() {
state?.close(); state?.close();
@ -28,16 +29,16 @@ class AppFlowyPopoverController {
} }
} }
class AppFlowyPopover extends StatefulWidget { class Popover extends StatefulWidget {
final Widget child; final Widget child;
final AppFlowyPopoverController? controller; final PopoverController? controller;
final Offset? offset; final Offset? offset;
final Decoration? maskDecoration; final Decoration? maskDecoration;
final Alignment targetAnchor; final Alignment targetAnchor;
final Alignment followerAnchor; final Alignment followerAnchor;
final Widget Function(BuildContext context) popupBuilder; final Widget Function(BuildContext context) popupBuilder;
const AppFlowyPopover({ const Popover({
Key? key, Key? key,
required this.child, required this.child,
required this.popupBuilder, required this.popupBuilder,
@ -49,19 +50,27 @@ class AppFlowyPopover extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<AppFlowyPopover> createState() => AppFlowyPopoverState(); State<Popover> createState() => PopoverState();
} }
class AppFlowyPopoverState extends State<AppFlowyPopover> { class PopoverState extends State<Popover> {
final LayerLink layerLink = LayerLink(); final LayerLink layerLink = LayerLink();
OverlayEntry? _overlayEntry; OverlayEntry? _overlayEntry;
bool hasMask = true; bool hasMask = true;
late TapGestureRecognizer _recognizer;
static AppFlowyPopoverState? _popoverWithMask; static PopoverState? _popoverWithMask;
@override @override
void initState() { void initState() {
widget.controller?.state = this; widget.controller?.state = this;
_recognizer = TapGestureRecognizer();
_recognizer.onTapDown = (details) {
debugPrint("ggg tapdown");
};
_recognizer.onTap = (() {
debugPrint("ggg tap");
});
super.initState(); super.initState();
} }
@ -121,6 +130,12 @@ class AppFlowyPopoverState extends State<AppFlowyPopover> {
super.deactivate(); super.deactivate();
} }
@override
void dispose() {
_recognizer.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CompositedTransformTarget(link: layerLink, child: widget.child); return CompositedTransformTarget(link: layerLink, child: widget.child);

View File

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
class FlowyButton extends StatelessWidget { class FlowyButton extends StatelessWidget {
final Widget text; final Widget text;
final VoidCallback? onTap; final VoidCallback? onTap;
final void Function(bool)? onHover;
final EdgeInsets margin; final EdgeInsets margin;
final Widget? leftIcon; final Widget? leftIcon;
final Widget? rightIcon; final Widget? rightIcon;
@ -15,6 +16,7 @@ class FlowyButton extends StatelessWidget {
Key? key, Key? key,
required this.text, required this.text,
this.onTap, this.onTap,
this.onHover,
this.margin = const EdgeInsets.symmetric(horizontal: 6, vertical: 2), this.margin = const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
this.leftIcon, this.leftIcon,
this.rightIcon, this.rightIcon,
@ -27,7 +29,9 @@ class FlowyButton extends StatelessWidget {
return InkWell( return InkWell(
onTap: onTap, onTap: onTap,
child: FlowyHover( child: FlowyHover(
style: HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor), style:
HoverStyle(borderRadius: BorderRadius.zero, hoverColor: hoverColor),
onHover: onHover,
setSelected: () => isSelected, setSelected: () => isSelected,
builder: (context, onHover) => _render(), builder: (context, onHover) => _render(),
), ),
@ -38,14 +42,16 @@ class FlowyButton extends StatelessWidget {
List<Widget> children = List.empty(growable: true); List<Widget> children = List.empty(growable: true);
if (leftIcon != null) { if (leftIcon != null) {
children.add(SizedBox.fromSize(size: const Size.square(16), child: leftIcon!)); children.add(
SizedBox.fromSize(size: const Size.square(16), child: leftIcon!));
children.add(const HSpace(6)); children.add(const HSpace(6));
} }
children.add(Expanded(child: text)); children.add(Expanded(child: text));
if (rightIcon != null) { if (rightIcon != null) {
children.add(SizedBox.fromSize(size: const Size.square(16), child: rightIcon!)); children.add(
SizedBox.fromSize(size: const Size.square(16), child: rightIcon!));
} }
return Padding( return Padding(
@ -121,7 +127,8 @@ class FlowyTextButton extends StatelessWidget {
visualDensity: VisualDensity.compact, visualDensity: VisualDensity.compact,
hoverElevation: 0, hoverElevation: 0,
highlightElevation: 0, highlightElevation: 0,
shape: RoundedRectangleBorder(borderRadius: radius ?? BorderRadius.circular(2)), shape: RoundedRectangleBorder(
borderRadius: radius ?? BorderRadius.circular(2)),
fillColor: fillColor, fillColor: fillColor,
hoverColor: hoverColor ?? Colors.transparent, hoverColor: hoverColor ?? Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,

View File

@ -9,6 +9,7 @@ class FlowyHover extends StatefulWidget {
final HoverBuilder? builder; final HoverBuilder? builder;
final Widget? child; final Widget? child;
final bool Function()? setSelected; final bool Function()? setSelected;
final void Function(bool)? onHover;
final MouseCursor? cursor; final MouseCursor? cursor;
const FlowyHover( const FlowyHover(
@ -17,6 +18,7 @@ class FlowyHover extends StatefulWidget {
this.child, this.child,
required this.style, required this.style,
this.setSelected, this.setSelected,
this.onHover,
this.cursor}) this.cursor})
: super(key: key); : super(key: key);
@ -32,8 +34,18 @@ class _FlowyHoverState extends State<FlowyHover> {
return MouseRegion( return MouseRegion(
cursor: widget.cursor != null ? widget.cursor! : SystemMouseCursors.click, cursor: widget.cursor != null ? widget.cursor! : SystemMouseCursors.click,
opaque: false, opaque: false,
onEnter: (p) => setState(() => _onHover = true), onEnter: (p) {
onExit: (p) => setState(() => _onHover = false), setState(() => _onHover = true);
if (widget.onHover != null) {
widget.onHover!(true);
}
},
onExit: (p) {
setState(() => _onHover = false);
if (widget.onHover != null) {
widget.onHover!(false);
}
},
child: renderWidget(), child: renderWidget(),
); );
} }