diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f283a4..c5955c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,26 @@ ## 1.0.0-rc.2 -- Add `AdwComboRow`, `AdwAvatar` -- Improve Headerbar and Header Button -- Update Sidebar theming to look more closer to libadwaita one +**BREAKING** +- `AdwHeaderBarMinimal` is now `AdwHeaderBar.minimal` +- The `start` and `end` parameter of `AdwHeaderBar` are now `List` instead of `Widget` +- `AdwTextButton` is now `AdwButton.flat` +- The `height` and `expanded` properties of ViewSwitcher are now deprecated + +**Other Changes** +- Add `AdwComboRow`, `AdwAvatar`, `AdwButton`(`.pill`, `.circular`, `.flat`) +- Improve Header Button +- Update Sidebar Theming +- Update View Switcher theming - Remove Scroll errors from example app by improving `AdwClamp` -- Deprecate `AdwHeaderBarMinimal`, Now use `AdwHeaderBar.minimal` ## 1.0.0-rc.1 - Added the following widgets: - - `AdwScaffold` - - `AdwTextField` - - `AdwTextButton` - - `AdwViewStack` - - `WindowResizeListener` + - `AdwScaffold` + - `AdwTextField` + - `AdwTextButton` + - `AdwViewStack` + - `WindowResizeListener` - Fix Window buttons null error - Update Example - Update `AdwActionRow` & `AdwStackSidebar` @@ -27,8 +34,8 @@ - Add `AdwPreferenceGroup` and `AdwActionRow` from libadwaita. - Add `AdwStackSidebar` which is basically `GtkStackSidebar` - `AdwHeaderBar` parameter's - - Replace leading with start - - Replace trailing with end - - Replace center with title + - Replace leading with start + - Replace trailing with end + - Replace center with title For older Changelog visit: https://pub.dev/packages/gtk/changelog diff --git a/example/lib/flap/flap_home_page.dart b/example/lib/flap/flap_home_page.dart index 160a57c..d3b01bf 100644 --- a/example/lib/flap/flap_home_page.dart +++ b/example/lib/flap/flap_home_page.dart @@ -52,21 +52,19 @@ class _FlapHomePageState extends State { AdwHeaderBar.bitsdojo( appWindow: appWindow, windowDecor: windowDecor, - start: Row( - children: [ - Builder(builder: (context) { - return AdwHeaderButton( - icon: const Icon(Icons.view_sidebar, size: 15), - isActive: _flapController.isOpen, - onPressed: () => _flapController.toggle(), - ); - }), - AdwHeaderButton( - icon: const Icon(Icons.nightlight_round, size: 15), - onPressed: changeTheme, - ), - ], - ), + start: [ + Builder(builder: (context) { + return AdwHeaderButton( + icon: const Icon(Icons.view_sidebar, size: 15), + isActive: _flapController.isOpen, + onPressed: () => _flapController.toggle(), + ); + }), + AdwHeaderButton( + icon: const Icon(Icons.nightlight_round, size: 15), + onPressed: changeTheme, + ), + ], title: const Text("AdwFlap Demo"), ), Expanded( diff --git a/example/lib/home_page.dart b/example/lib/home_page.dart index 8914810..449ec49 100644 --- a/example/lib/home_page.dart +++ b/example/lib/home_page.dart @@ -57,47 +57,43 @@ class _MyHomePageState extends State { AdwHeaderBar.bitsdojo( appWindow: appWindow, windowDecor: windowDecor, - start: Row( - children: [ - Builder( - builder: (context) { - return AdwHeaderButton( - icon: const Icon(Icons.view_sidebar, size: 15), - isActive: _flapController.isOpen, - onPressed: () { - _flapController.toggle(); - }, - ); - }, - ), - AdwHeaderButton( - icon: const Icon(Icons.nightlight_round, size: 15), - onPressed: changeTheme, - ), - ], - ), + start: [ + Builder( + builder: (context) { + return AdwHeaderButton( + icon: const Icon(Icons.view_sidebar, size: 15), + isActive: _flapController.isOpen, + onPressed: () { + _flapController.toggle(); + }, + ); + }, + ), + AdwHeaderButton( + icon: const Icon(Icons.nightlight_round, size: 15), + onPressed: changeTheme, + ), + ], title: const Text("Libadwaita Demo"), - end: Row( - children: [ - AdwPopupMenu( - body: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - onTap: () { - counter.value = 0; - Navigator.of(context).pop(); - }, - title: const Text( - 'Reset Counter', - style: TextStyle(fontSize: 15), - ), + end: [ + AdwPopupMenu( + body: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + onTap: () { + counter.value = 0; + Navigator.of(context).pop(); + }, + title: const Text( + 'Reset Counter', + style: TextStyle(fontSize: 15), ), - ], - ), + ), + ], ), - ], - ), + ), + ], ), Expanded( child: AdwScaffold( diff --git a/example/pubspec.lock b/example/pubspec.lock index 24e75fd..fd11db7 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -172,6 +172,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" meta: dependency: transitive description: @@ -302,7 +309,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" typed_data: dependency: transitive description: diff --git a/lib/src/widgets/adw/header_bar.dart b/lib/src/widgets/adw/header_bar.dart index f1ca0e0..d927802 100644 --- a/lib/src/widgets/adw/header_bar.dart +++ b/lib/src/widgets/adw/header_bar.dart @@ -7,13 +7,13 @@ import 'package:libadwaita/libadwaita.dart'; class AdwHeaderBar extends StatefulWidget { /// The leading widget for the headerbar - final Widget start; + final List start; /// The center widget for the headerbar final Widget title; /// The trailing widget for the headerbar - final Widget end; + final List end; final Widget? minimizeBtn; @@ -49,9 +49,9 @@ class AdwHeaderBar extends StatefulWidget { dynamic themeType, this.onDoubleTap, this.onHeaderDrag, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -85,9 +85,9 @@ class AdwHeaderBar extends StatefulWidget { Key? key, this.onDoubleTap, this.onHeaderDrag, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -108,9 +108,9 @@ class AdwHeaderBar extends StatefulWidget { /// The appWindow object from bitsdojo_window package required appWindow, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -141,9 +141,9 @@ class AdwHeaderBar extends StatefulWidget { /// The appWindow object from bitsdojo_window package required appWindow, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -169,9 +169,9 @@ class AdwHeaderBar extends StatefulWidget { /// The Window.of(context) object from nativeshell package required window, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -194,9 +194,9 @@ class AdwHeaderBar extends StatefulWidget { /// The Window.of(context) object from nativeshell package required window, - this.start = const SizedBox(), + this.start = const [], this.title = const SizedBox(), - this.end = const SizedBox(), + this.end = const [], this.padding = const EdgeInsets.only(left: 3, right: 5), this.titlebarSpace = 4, this.height = 51, @@ -292,14 +292,22 @@ class _AdwHeaderBarState extends State { SizedBox(width: widget.titlebarSpace), for (var i in sep[0].split(',')) if (windowButtons[i] != null) windowButtons[i]!, - widget.start, + ...widget.start.map( + (e) => Padding( + padding: const EdgeInsets.only(right: 5), + child: e), + ), ], ), middle: widget.title, trailing: Row( mainAxisSize: MainAxisSize.min, children: [ - widget.end, + ...widget.end.map( + (e) => Padding( + padding: const EdgeInsets.only(left: 5), + child: e), + ), if (hasWindowControls && sep[1].split(',').isNotEmpty) SizedBox(width: widget.titlebarSpace), diff --git a/lib/src/widgets/adw/new/scaffold.dart b/lib/src/widgets/adw/new/scaffold.dart index b6d0ff1..2c8f458 100644 --- a/lib/src/widgets/adw/new/scaffold.dart +++ b/lib/src/widgets/adw/new/scaffold.dart @@ -10,13 +10,17 @@ class AdwScaffold extends StatefulWidget { /// Remove this when ViewSwitcher becomes adaptive final Widget? bottomNavigationBar; - const AdwScaffold({ + AdwScaffold({ Key? key, required this.body, this.flapController, - this.drawer, + Widget? drawer, this.bottomNavigationBar, - }) : super(key: key); + }) : + + /// Use less width to match libadwaita + drawer = drawer != null ? SizedBox(width: 200, child: drawer) : null, + super(key: key); @override _AdwScaffoldState createState() => _AdwScaffoldState(); diff --git a/lib/src/widgets/adw/view_switcher.dart b/lib/src/widgets/adw/view_switcher.dart index 508ee45..d9fa671 100644 --- a/lib/src/widgets/adw/view_switcher.dart +++ b/lib/src/widgets/adw/view_switcher.dart @@ -4,9 +4,8 @@ import 'package:flutter/material.dart'; class AdwViewSwitcher extends StatelessWidget { final List tabs; final ValueChanged onViewChanged; - final ViewSwitcherStyle style; + final ViewSwitcherStyle? style; final int currentIndex; - final bool expanded; final double height; const AdwViewSwitcher({ @@ -14,44 +13,41 @@ class AdwViewSwitcher extends StatelessWidget { required this.tabs, required this.onViewChanged, required this.currentIndex, - this.style = ViewSwitcherStyle.desktop, - this.height = 55, - bool? expanded, - }) : expanded = - expanded ?? (style == ViewSwitcherStyle.desktop ? false : true), - assert(tabs.length >= 2), + this.style, + @Deprecated('This parameter is no longer in use') + this.height = 55, + @Deprecated( + 'This field is now ignored. ' + 'This feature was deprecated after v1.0.0-rc.2', + ) + bool? expanded, + }) : assert(tabs.length >= 2), super(key: key); @override Widget build(BuildContext context) { - return Row( - mainAxisSize: MainAxisSize.min, - children: [ - for (final tab in tabs.asMap().entries) - () { - var ctab = InkWell( - onTap: - currentIndex != tab.key ? () => onViewChanged(tab.key) : null, - child: Container( - height: height, - decoration: BoxDecoration( - color: tab.key == currentIndex - ? Theme.of(context) - .appBarTheme - .backgroundColor - ?.darken(0.05) - : Colors.transparent, - ), - child: AdwViewSwitcherTab( - data: tab.value, - isSelected: tab.key == currentIndex, - style: style, - ), - ), - ); - return expanded ? Expanded(child: ctab) : ctab; - }() - ], + return LayoutBuilder( + builder: (context, constraints) { + final newStyle = style ?? + (constraints.maxWidth > 600 + ? ViewSwitcherStyle.desktop + : ViewSwitcherStyle.mobile); + + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + for (final tab in tabs.asMap().entries) + AdwViewSwitcherTab( + data: tab.value, + style: newStyle, + isSelected: tab.key == currentIndex, + onSelected: currentIndex != tab.key + ? () => onViewChanged(tab.key) + : null, + ) + ], + ); + }, ); } } diff --git a/lib/src/widgets/adw/view_switcher_tab.dart b/lib/src/widgets/adw/view_switcher_tab.dart index 1500294..3b00a30 100644 --- a/lib/src/widgets/adw/view_switcher_tab.dart +++ b/lib/src/widgets/adw/view_switcher_tab.dart @@ -5,59 +5,72 @@ class AdwViewSwitcherTab extends StatelessWidget { final ViewSwitcherData data; final ViewSwitcherStyle style; final bool isSelected; + final VoidCallback? onSelected; const AdwViewSwitcherTab({ Key? key, required this.data, - required this.isSelected, required this.style, + this.isSelected = false, + this.onSelected, }) : super(key: key); @override Widget build(BuildContext context) { - final icon = Icon( - data.icon, - size: 18, - ); + final isDesktop = style == ViewSwitcherStyle.desktop; - return style == ViewSwitcherStyle.desktop - ? Padding( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - child: Row( - children: [ - if (data.icon != null) icon, - if (data.icon != null && data.title != null) - const SizedBox(width: 8), - if (data.title != null) - Text( - data.title!, - style: Theme.of(context).textTheme.bodyText2?.copyWith( - fontWeight: - isSelected ? FontWeight.bold : FontWeight.normal, - ), - ), - ], + return AdwButton.flat( + constraints: isDesktop + ? const BoxConstraints(minWidth: 120, minHeight: 34, maxHeight: 36) + : const BoxConstraints(minWidth: 75), + margin: + isDesktop ? const EdgeInsets.fromLTRB(0, 6, 3, 6) : EdgeInsets.zero, + onPressed: onSelected, + isActive: isSelected, + textStyle: TextStyle( + fontSize: isDesktop ? null : 11, + ), + borderRadius: isDesktop + ? const BorderRadius.all(Radius.circular(6.0)) + : BorderRadius.zero, + child: _AdwViewSwitcherTabLayout( + isRow: isDesktop, + children: [ + if (data.icon != null) + Icon( + data.icon, + size: 18, ), + if (data.icon != null && data.title != null) + const SizedBox(width: 8, height: 2), + if (data.title != null) Text(data.title!), + ], + ), + ); + } +} + +class _AdwViewSwitcherTabLayout extends StatelessWidget { + final List children; + final bool isRow; + + const _AdwViewSwitcherTabLayout({ + Key? key, + required this.isRow, + required this.children, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return isRow + ? Row( + mainAxisAlignment: MainAxisAlignment.center, + children: children, ) - : Padding( - padding: const EdgeInsets.symmetric(horizontal: 21.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (data.icon != null) icon, - if (data.icon != null && data.title != null) - const SizedBox(height: 2), - if (data.title != null) - Text( - data.title!, - style: Theme.of(context).textTheme.bodyText2?.copyWith( - fontSize: 12, - fontWeight: - isSelected ? FontWeight.bold : FontWeight.normal, - ), - ), - ], - ), + : Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: children, ); } }