Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Responsive toolbar (#274) #277

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 114 additions & 5 deletions packages/fleather/lib/src/widgets/editor_toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,50 @@ class _ColorPaletteElement extends StatelessWidget {
}
}

/// Toolbar button which allows to display a dropdown menu with the buttons hidden because of the lack of space.
class OverflowMenuButton extends StatefulWidget {
final List<Widget> menuChildren;

const OverflowMenuButton({super.key, required this.menuChildren});

@override
State<OverflowMenuButton> createState() => _OverflowMenuButtonState();
}

class _OverflowMenuButtonState extends State<OverflowMenuButton> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);

return MenuAnchor(
builder:
(BuildContext context, MenuController controller, Widget? child) {
return FLIconButton(
highlightElevation: 0,
hoverElevation: 0,
size: 32,
icon: Icon(
Icons.more_vert,
size: 18,
color: theme.iconTheme.color,
),
fillColor: theme.canvasColor,
onPressed: () {
if (controller.isOpen) {
controller.close();
} else {
controller.open();
}
},
);
},
anchorTapClosesMenu: true,
menuChildren: widget.menuChildren,
);
}
}

/// Toolbar button which allows to apply heading style to a line of text in
/// Fleather editor.
///
Expand Down Expand Up @@ -1135,6 +1179,7 @@ class FleatherToolbar extends StatefulWidget implements PreferredSizeWidget {
controller: controller,
),
),

Visibility(
visible: !hideUndoRedo,
child: UndoRedoButton.redo(
Expand All @@ -1143,6 +1188,8 @@ class FleatherToolbar extends StatefulWidget implements PreferredSizeWidget {
),

...trailing,

/// ################################################################
]);
}

Expand Down Expand Up @@ -1175,11 +1222,73 @@ class _FleatherToolbarState extends State<FleatherToolbar> {
padding: widget.padding ?? const EdgeInsets.symmetric(horizontal: 8),
constraints:
BoxConstraints.tightFor(height: widget.preferredSize.height),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: widget.children,
),
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
double? availableWidth = constraints.maxWidth;
final overflowMenuChildren = <Widget>[];
final reallyVisibleChildren = <Widget>[];
final allChildren = widget.children;
final visibleChildren = <Widget>[];
for (int i = 0; i < allChildren.length; i++) {
final Widget child = allChildren[i];
if (child is SizedBox) {
continue;
}

if (child is Visibility) {
final Visibility visibilityWidget = child;
if (child.visible) {
visibleChildren.add(visibilityWidget.child);
}
continue;
}
visibleChildren.add(child);
}

for (int i = 0; i < visibleChildren.length; i++) {
final Widget child = visibleChildren[i];
final double? childWidth = child is SizedBox
? child.width
: child is ToggleStyleButton
? 32
: child is VerticalDivider
? child.indent! + child.endIndent!
: 32;
if (availableWidth! - childWidth! >
48 /* 32 is the width of the overflow menu button*/) {
reallyVisibleChildren.add(child);
availableWidth -= childWidth;
} else {
if (child is VerticalDivider) {
overflowMenuChildren.add(/*Horizontal*/ Container(
color: Theme.of(context).canvasColor,
child: Divider(
indent: 2,
endIndent: 2,
color: child.color,
)));
} else {
overflowMenuChildren.add(Container(
constraints: const BoxConstraints.tightFor(width: 48),
child: child,
));
}
}
}
return Row(
children: [
...reallyVisibleChildren,
if (overflowMenuChildren.isNotEmpty)
VerticalDivider(
indent: 16, endIndent: 16, color: Colors.grey.shade400),
if (overflowMenuChildren.isNotEmpty)
OverflowMenuButton(
key: const Key('overflow_menu_button'),
menuChildren: overflowMenuChildren,
),
],
);
},
),
),
),
Expand Down
Loading