From 9cb5ef69c01a642d6bf2b4e53927a014a5c1c11f Mon Sep 17 00:00:00 2001 From: Adil Hanney Date: Wed, 15 Feb 2023 04:04:21 +0000 Subject: [PATCH] Add `axis` parameter to `ArrowIndicatedButtonList` --- lib/src/widgets/toolbar.dart | 5 +- .../toolbar/arrow_indicated_button_list.dart | 80 +++++++++++++------ 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/lib/src/widgets/toolbar.dart b/lib/src/widgets/toolbar.dart index 5955b5b8..22d01ff3 100644 --- a/lib/src/widgets/toolbar.dart +++ b/lib/src/widgets/toolbar.dart @@ -551,7 +551,10 @@ class QuillToolbar extends StatelessWidget implements PreferredSizeWidget { width: axis == Axis.vertical ? toolbarSize : null, ), color: color ?? Theme.of(context).canvasColor, - child: ArrowIndicatedButtonList(buttons: children), + child: ArrowIndicatedButtonList( + axis: axis, + buttons: children, + ), ), ); } diff --git a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart index 1c6917a1..94e500ff 100644 --- a/lib/src/widgets/toolbar/arrow_indicated_button_list.dart +++ b/lib/src/widgets/toolbar/arrow_indicated_button_list.dart @@ -7,9 +7,13 @@ import 'package:flutter/material.dart'; /// The arrow indicators are automatically hidden if the list is not /// scrollable in the direction of the respective arrow. class ArrowIndicatedButtonList extends StatefulWidget { - const ArrowIndicatedButtonList({required this.buttons, Key? key}) - : super(key: key); + const ArrowIndicatedButtonList({ + required this.axis, + required this.buttons, + Key? key, + }) : super(key: key); + final Axis axis; final List buttons; @override @@ -20,8 +24,8 @@ class ArrowIndicatedButtonList extends StatefulWidget { class _ArrowIndicatedButtonListState extends State with WidgetsBindingObserver { final ScrollController _controller = ScrollController(); - bool _showLeftArrow = false; - bool _showRightArrow = false; + bool _showBackwardArrow = false; + bool _showForwardArrow = false; @override void initState() { @@ -40,13 +44,19 @@ class _ArrowIndicatedButtonListState extends State @override Widget build(BuildContext context) { - return Row( - children: [ - _buildLeftArrow(), - _buildScrollableList(), - _buildRightColor(), - ], - ); + final children = [ + _buildBackwardArrow(), + _buildScrollableList(), + _buildForwardArrow(), + ]; + + return widget.axis == Axis.horizontal + ? Row( + children: children, + ) + : Column( + children: children, + ); } @override @@ -63,20 +73,29 @@ class _ArrowIndicatedButtonListState extends State if (!mounted) return; setState(() { - _showLeftArrow = + _showBackwardArrow = _controller.position.minScrollExtent != _controller.position.pixels; - _showRightArrow = + _showForwardArrow = _controller.position.maxScrollExtent != _controller.position.pixels; }); } - Widget _buildLeftArrow() { + Widget _buildBackwardArrow() { + IconData? icon; + if (_showBackwardArrow) { + if (widget.axis == Axis.horizontal) { + icon = Icons.arrow_left; + } else { + icon = Icons.arrow_drop_up; + } + } + return SizedBox( width: 8, child: Transform.translate( // Move the icon a few pixels to center it offset: const Offset(-5, 0), - child: _showLeftArrow ? const Icon(Icons.arrow_left, size: 18) : null, + child: icon != null ? Icon(icon, size: 18) : null, ), ); } @@ -87,18 +106,24 @@ class _ArrowIndicatedButtonListState extends State // Remove the glowing effect, as we already have the arrow indicators behavior: _NoGlowBehavior(), // The CustomScrollView is necessary so that the children are not - // stretched to the height of the toolbar, https://bit.ly/3uC3bjI + // stretched to the height of the toolbar: + // https://stackoverflow.com/a/65998731/7091839 child: CustomScrollView( - scrollDirection: Axis.horizontal, + scrollDirection: widget.axis, controller: _controller, physics: const ClampingScrollPhysics(), slivers: [ SliverFillRemaining( hasScrollBody: false, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: widget.buttons, - ), + child: widget.axis == Axis.horizontal + ? Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: widget.buttons, + ) + : Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: widget.buttons, + ), ) ], ), @@ -106,13 +131,22 @@ class _ArrowIndicatedButtonListState extends State ); } - Widget _buildRightColor() { + Widget _buildForwardArrow() { + IconData? icon; + if (_showForwardArrow) { + if (widget.axis == Axis.horizontal) { + icon = Icons.arrow_right; + } else { + icon = Icons.arrow_drop_down; + } + } + return SizedBox( width: 8, child: Transform.translate( // Move the icon a few pixels to center it offset: const Offset(-5, 0), - child: _showRightArrow ? const Icon(Icons.arrow_right, size: 18) : null, + child: icon != null ? Icon(icon, size: 18) : null, ), ); }