From 1440d263760cc597614902da05176b1b722e98ed Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 10 Aug 2022 16:40:04 +0800 Subject: [PATCH] tabbar: material style Signed-off-by: 21pages --- .../lib/desktop/widgets/tabbar_widget.dart | 313 +++++++----------- 1 file changed, 119 insertions(+), 194 deletions(-) diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index 2eafeed85..420267b44 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -35,53 +35,53 @@ class DesktopTabBar extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - color: _theme.bgColor, height: _kTabBarHeight, - child: Row( - children: [ - Flexible( - child: Obx(() => TabBar( - indicatorColor: _theme.tabindicatorColor, - indicatorSize: TabBarIndicatorSize.tab, - indicatorWeight: 1, - labelPadding: - const EdgeInsets.symmetric(vertical: 0, horizontal: 0), - indicatorPadding: EdgeInsets.zero, - isScrollable: true, - physics: BouncingScrollPhysics(), - controller: controller.value, - tabs: tabs - .asMap() - .entries - .map((e) => _Tab( - index: e.key, - text: e.value, - icon: tabIcon, - selected: selected.value, - onClose: () { - onTabClose(e.value); - if (e.key <= selected.value) { - selected.value = max(0, selected.value - 1); - } - controller.value.animateTo(selected.value, - duration: Duration.zero); - }, - onSelected: () { - selected.value = e.key; - controller.value - .animateTo(e.key, duration: Duration.zero); - }, - theme: _theme, - )) - .toList())), - ), - Padding( - padding: EdgeInsets.only(left: 10), - child: _AddButton( - theme: _theme, + child: Scaffold( + backgroundColor: _theme.bgColor, + body: Row( + children: [ + Flexible( + child: Obx(() => TabBar( + indicator: BoxDecoration(), + indicatorColor: Colors.transparent, + labelPadding: + const EdgeInsets.symmetric(vertical: 0, horizontal: 0), + isScrollable: true, + physics: BouncingScrollPhysics(), + controller: controller.value, + tabs: tabs + .asMap() + .entries + .map((e) => _Tab( + index: e.key, + text: e.value, + icon: tabIcon, + selected: selected.value, + onClose: () { + onTabClose(e.value); + if (e.key <= selected.value) { + selected.value = max(0, selected.value - 1); + } + controller.value.animateTo(selected.value, + duration: Duration.zero); + }, + onSelected: () { + selected.value = e.key; + controller.value + .animateTo(e.key, duration: Duration.zero); + }, + theme: _theme, + )) + .toList())), ), - ), - ], + Padding( + padding: EdgeInsets.only(left: 10), + child: _AddButton( + theme: _theme, + ), + ), + ], + ), ), ); } @@ -112,73 +112,63 @@ class _Tab extends StatelessWidget { Widget build(BuildContext context) { bool is_selected = index == selected; bool show_divider = index != selected - 1 && index != selected; - return Obx( - (() => _Hoverable( - onHover: (hover) => _hover.value = hover, - onTapUp: () => onSelected(), - child: Container( - width: _kTabFixedWidth, - decoration: BoxDecoration( - color: is_selected - ? theme.tabSelectedColor - : _hover.value - ? theme.tabHoverColor - : theme.tabUnselectedColor, - ), - child: Row( - children: [ - Expanded( - child: Tab( - key: this.key, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric(horizontal: 5), - child: Icon( - icon, - size: _kIconSize, - color: theme.tabIconColor, - ), - ), - Expanded( - child: Text( - text, - style: TextStyle( - color: is_selected - ? theme.selectedTextColor - : theme.unSelectedTextColor), - ), - ), - _CloseButton( - tabHovered: _hover.value, - tabSelected: is_selected, - onClose: () => onClose(), - theme: theme, - ), - ])), - ), - Offstage( - offstage: !show_divider, - child: VerticalDivider( - width: 1, - indent: _kDividerIndent, - endIndent: _kDividerIndent, - color: theme.dividerColor, - thickness: 1, - ), - ) - ], - ), + return Ink( + width: _kTabFixedWidth, + color: is_selected ? theme.tabSelectedColor : null, + child: InkWell( + onHover: (hover) => _hover.value = hover, + onTap: () => onSelected(), + child: Row( + children: [ + Expanded( + child: Tab( + key: this.key, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 5), + child: Icon( + icon, + size: _kIconSize, + color: theme.tabIconColor, + ), + ), + Expanded( + child: Text( + text, + style: TextStyle( + color: is_selected + ? theme.selectedTextColor + : theme.unSelectedTextColor), + ), + ), + Obx((() => _CloseButton( + tabHovered: _hover.value, + tabSelected: is_selected, + onClose: () => onClose(), + theme: theme, + ))), + ])), ), - )), + Offstage( + offstage: !show_divider, + child: VerticalDivider( + width: 1, + indent: _kDividerIndent, + endIndent: _kDividerIndent, + color: theme.dividerColor, + thickness: 1, + ), + ) + ], + ), + ), ); } } class _AddButton extends StatelessWidget { - final RxBool _hover = false.obs; - final RxBool _pressed = false.obs; late final _Theme theme; _AddButton({ @@ -188,27 +178,18 @@ class _AddButton extends StatelessWidget { @override Widget build(BuildContext context) { - return _Hoverable( - onHover: (hover) => _hover.value = hover, - onPressed: (pressed) => _pressed.value = pressed, - onTapUp: () => - rustDeskWinManager.call(WindowType.Main, "main_window_on_top", ""), - child: Obx((() => Container( - height: _kTabBarHeight, - decoration: ShapeDecoration( - shape: const CircleBorder(), - color: _pressed.value - ? theme.iconPressedBgColor - : _hover.value - ? theme.iconHoverBgColor - : Colors.transparent, - ), - child: Icon( - Icons.add_sharp, - color: theme.unSelectedIconColor, - size: _kAddIconSize, - ), - ))), + return Ink( + height: _kTabBarHeight, + child: InkWell( + customBorder: const CircleBorder(), + onTap: () => + rustDeskWinManager.call(WindowType.Main, "main_window_on_top", ""), + child: Icon( + Icons.add_sharp, + size: _kAddIconSize, + color: theme.unSelectedIconColor, + ), + ), ); } } @@ -217,8 +198,6 @@ class _CloseButton extends StatelessWidget { final bool tabHovered; final bool tabSelected; final Function onClose; - final RxBool _hover = false.obs; - final RxBool _pressed = false.obs; late final _Theme theme; _CloseButton({ @@ -237,104 +216,50 @@ class _CloseButton extends StatelessWidget { width: _kIconSize, child: Offstage( offstage: !tabHovered, - child: Obx((() => _Hoverable( - onHover: (hover) => _hover.value = hover, - onPressed: (pressed) => _pressed.value = pressed, - onTapUp: () => onClose(), - child: Container( - color: _pressed.value - ? theme.iconPressedBgColor - : _hover.value - ? theme.iconHoverBgColor - : Colors.transparent, - child: Icon( - Icons.close, - size: _kIconSize, - color: tabSelected - ? theme.selectedIconColor - : theme.unSelectedIconColor, - )), - ))), + child: InkWell( + customBorder: RoundedRectangleBorder(), + onTap: () => onClose(), + child: Icon( + Icons.close, + size: _kIconSize, + color: tabSelected + ? theme.selectedIconColor + : theme.unSelectedIconColor, + ), + ), ))); } } -class _Hoverable extends StatelessWidget { - final Widget child; - final Function(bool hover) onHover; - final Function(bool pressed)? onPressed; - final Function()? onTapUp; - - const _Hoverable( - {Key? key, - required this.child, - required this.onHover, - this.onPressed, - this.onTapUp}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (_) => onHover(true), - onExit: (_) => onHover(false), - child: onPressed == null && onTapUp == null - ? child - : GestureDetector( - onTapDown: (details) => onPressed?.call(true), - onTapUp: (details) { - onPressed?.call(false); - onTapUp?.call(); - }, - child: child, - )); - } -} - class _Theme { late Color bgColor; - late Color tabUnselectedColor; - late Color tabHoverColor; late Color tabSelectedColor; late Color tabIconColor; - late Color tabindicatorColor; late Color selectedTextColor; late Color unSelectedTextColor; late Color selectedIconColor; late Color unSelectedIconColor; - late Color iconHoverBgColor; - late Color iconPressedBgColor; late Color dividerColor; _Theme.light() { bgColor = Color.fromARGB(255, 253, 253, 253); - tabUnselectedColor = Color.fromARGB(255, 253, 253, 253); - tabHoverColor = Color.fromARGB(255, 245, 245, 245); tabSelectedColor = MyTheme.grayBg; tabIconColor = MyTheme.accent50; - tabindicatorColor = MyTheme.grayBg; selectedTextColor = Color.fromARGB(255, 26, 26, 26); unSelectedTextColor = Color.fromARGB(255, 96, 96, 96); selectedIconColor = Color.fromARGB(255, 26, 26, 26); unSelectedIconColor = Color.fromARGB(255, 96, 96, 96); - iconHoverBgColor = Color.fromARGB(255, 224, 224, 224); - iconPressedBgColor = Color.fromARGB(255, 215, 215, 215); dividerColor = Color.fromARGB(255, 238, 238, 238); } _Theme.dark() { bgColor = Color.fromARGB(255, 50, 50, 50); - tabUnselectedColor = Color.fromARGB(255, 50, 50, 50); - tabHoverColor = Color.fromARGB(255, 59, 59, 59); tabSelectedColor = MyTheme.canvasColor; tabIconColor = Color.fromARGB(255, 84, 197, 248); - tabindicatorColor = MyTheme.canvasColor; selectedTextColor = Color.fromARGB(255, 255, 255, 255); unSelectedTextColor = Color.fromARGB(255, 207, 207, 207); selectedIconColor = Color.fromARGB(255, 215, 215, 215); unSelectedIconColor = Color.fromARGB(255, 255, 255, 255); - iconHoverBgColor = Color.fromARGB(255, 67, 67, 67); - iconPressedBgColor = Color.fromARGB(255, 73, 73, 73); dividerColor = Color.fromARGB(255, 64, 64, 64); } }