diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ab311b3..345ceb9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [2.0.0-beta.7] +✨ New ✨ +* You can now call `MacosTypography.of(context)` as a shorthand for retrieving the typography used in your `MacosTheme`. + +🔄 Updated 🔄 +* `MacosAlertDialog` now defines `primaryButton` and `secondaryButton` to be of type `PushButton`. +* `MacosAlertDialog` now requires that `primaryButton` and `secondaryButton` to have `controlSize`s of `ControlSize.large`. +* `MacosAlertDialog` docs now suggest that `appIcon` should be of size 64x64. + ## [2.0.0-beta.6] 🔄 Updated 🔄 * `MacosCheckbox` appearance more closely matches its native counterpart. diff --git a/README.md b/README.md index cf586f34..b9a911d1 100644 --- a/README.md +++ b/README.md @@ -703,9 +703,7 @@ Usage: showMacosAlertDialog( context: context, builder: (_) => MacosAlertDialog( - appIcon: FlutterLogo( - size: 56, - ), + appIcon: FlutterLogo(size: 64), title: Text( 'Alert Dialog with Primary Action', style: MacosTheme.of(context).typography.headline, @@ -713,10 +711,10 @@ showMacosAlertDialog( message: Text( 'This is an alert dialog with a primary action and no secondary action', textAlign: TextAlign.center, - style: MacosTheme.of(context).typography.headline, + style: MacosTypography.of(context).headline, ), primaryButton: PushButton( - buttonSize: ButtonSize.large, + controlSize: ControlSize.large, child: Text('Primary'), onPressed: () {}, ), diff --git a/example/lib/main.dart b/example/lib/main.dart index cba22164..3b7d2ed2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,6 +3,7 @@ import 'package:example/pages/colors_page.dart'; import 'package:example/pages/dialogs_page.dart'; import 'package:example/pages/fields_page.dart'; import 'package:example/pages/indicators_page.dart'; +import 'package:example/pages/resizable_pane_page.dart'; import 'package:example/pages/selectors_page.dart'; import 'package:example/pages/sliver_toolbar_page.dart'; import 'package:example/pages/tabview_page.dart'; @@ -55,33 +56,21 @@ class WidgetGallery extends StatefulWidget { } class _WidgetGalleryState extends State { - double ratingValue = 0; - double sliderValue = 0; - bool value = false; - int pageIndex = 0; late final searchFieldController = TextEditingController(); final List pageBuilders = [ - (bool isVisible) => CupertinoTabView( - builder: (_) => const ButtonsPage(), - ), - (bool isVisible) => const IndicatorsPage(), - (bool isVisible) => const FieldsPage(), - (bool isVisible) => const ColorsPage(), - (bool isVisible) => const Center( - child: MacosIcon( - CupertinoIcons.add, - ), - ), - (bool isVisible) => const DialogsPage(), - (bool isVisible) => const ToolbarPage(), - (bool isVisible) => SliverToolbarPage( - isVisible: isVisible, - ), - (bool isVisible) => const TabViewPage(), - (bool isVisible) => const SelectorsPage(), + (_) => CupertinoTabView(builder: (_) => const ButtonsPage()), + (_) => const IndicatorsPage(), + (_) => const FieldsPage(), + (_) => const ColorsPage(), + (_) => const DialogsPage(), + (_) => const ToolbarPage(), + (isVisible) => SliverToolbarPage(isVisible: isVisible), + (_) => const TabViewPage(), + (_) => const ResizablePanePage(), + (_) => const SelectorsPage(), ]; @override @@ -152,7 +141,7 @@ class _WidgetGalleryState extends State { break; case 'Dialogs and Sheets': setState(() { - pageIndex = 5; + pageIndex = 4; searchFieldController.clear(); }); break; @@ -162,12 +151,18 @@ class _WidgetGalleryState extends State { searchFieldController.clear(); }); break; - case 'Selectors': + case 'ResizablePane': setState(() { pageIndex = 7; searchFieldController.clear(); }); break; + case 'Selectors': + setState(() { + pageIndex = 8; + searchFieldController.clear(); + }); + break; default: searchFieldController.clear(); } @@ -179,6 +174,7 @@ class _WidgetGalleryState extends State { SearchResultItem('Colors'), SearchResultItem('Dialogs and Sheets'), SearchResultItem('Toolbar'), + SearchResultItem('ResizablePane'), SearchResultItem('Selectors'), ], ), @@ -189,17 +185,14 @@ class _WidgetGalleryState extends State { onChanged: (i) => setState(() => pageIndex = i), scrollController: scrollController, itemSize: SidebarItemSize.large, - items: [ - const SidebarItem( - // leading: MacosIcon(CupertinoIcons.square_on_circle), + items: const [ + SidebarItem( leading: MacosImageIcon( - AssetImage( - 'assets/sf_symbols/button_programmable_2x.png', - ), + AssetImage('assets/sf_symbols/button_programmable_2x.png'), ), label: Text('Buttons'), ), - const SidebarItem( + SidebarItem( leading: MacosImageIcon( AssetImage( 'assets/sf_symbols/lines_measurement_horizontal_2x.png', @@ -207,7 +200,7 @@ class _WidgetGalleryState extends State { ), label: Text('Indicators'), ), - const SidebarItem( + SidebarItem( leading: MacosImageIcon( AssetImage( 'assets/sf_symbols/character_cursor_ibeam_2x.png', @@ -216,36 +209,16 @@ class _WidgetGalleryState extends State { label: Text('Fields'), ), SidebarItem( - leading: const MacosIcon(CupertinoIcons.folder), - label: const Text('Disclosure'), - trailing: Text( - '2', - style: TextStyle( - color: MacosTheme.brightnessOf(context) == Brightness.dark - ? MacosColors.tertiaryLabelColor.darkColor - : MacosColors.tertiaryLabelColor, - ), + leading: MacosImageIcon( + AssetImage('assets/sf_symbols/rectangle_3_group_2x.png'), ), - disclosureItems: [ - const SidebarItem( - leading: MacosImageIcon( - AssetImage( - 'assets/sf_symbols/rectangle_3_group_2x.png', - ), - ), - label: Text('Colors'), - ), - const SidebarItem( - leading: MacosIcon(CupertinoIcons.infinite), - label: Text('Item 3'), - ), - ], + label: Text('Colors'), ), - const SidebarItem( + SidebarItem( leading: MacosIcon(CupertinoIcons.square_on_square), label: Text('Dialogs & Sheets'), ), - const SidebarItem( + SidebarItem( leading: MacosImageIcon( AssetImage( 'assets/sf_symbols/macwindow.on.rectangle_2x.png', @@ -269,13 +242,16 @@ class _WidgetGalleryState extends State { leading: MacosIcon(CupertinoIcons.uiwindow_split_2x1), label: Text('TabView'), ), + SidebarItem( + leading: MacosIcon(CupertinoIcons.rectangle_split_3x1), + label: Text('ResizablePane'), + ), ], ), - const SidebarItem( + SidebarItem( leading: MacosImageIcon( AssetImage( - 'assets/sf_symbols/filemenu_and_selection_2x.png', - ), + 'assets/sf_symbols/filemenu_and_selection_2x.png'), ), label: Text('Selectors'), ), diff --git a/example/lib/pages/buttons_page.dart b/example/lib/pages/buttons_page.dart index 7c480ce9..d26501c3 100644 --- a/example/lib/pages/buttons_page.dart +++ b/example/lib/pages/buttons_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; import 'package:macos_ui/macos_ui.dart'; import 'package:provider/provider.dart'; @@ -59,779 +60,715 @@ class _ButtonsPageState extends State { ], ), children: [ - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: ResizableSide.right, - builder: (_, __) { - return const Center( - child: Text('Resizable Pane'), - ); - }, - ), ContentArea( builder: (context, scrollController) { - return Column( - children: [ - Flexible( - fit: FlexFit.loose, - child: SingleChildScrollView( - controller: scrollController, - padding: const EdgeInsets.all(20), - child: Column( - children: [ - const Text('MacosBackButton'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosBackButton( - onPressed: () => debugPrint('click'), - fillColor: Colors.transparent, - ), - const SizedBox(width: 16.0), - MacosBackButton( - onPressed: () => debugPrint('click'), - ), - ], - ), - const SizedBox(height: 20), - const Text('MacosDisclosureButton'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosDisclosureButton( - isPressed: isDisclosureButtonPressed, - onPressed: () { - debugPrint('click'); - setState(() { - isDisclosureButtonPressed = - !isDisclosureButtonPressed; - }); - }), - ], - ), - const SizedBox(height: 20), - const Text('MacosIconButton'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosIconButton( - icon: const MacosIcon( - CupertinoIcons.star_fill, - ), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(7), - onPressed: () {}, - ), - const SizedBox(width: 8), - const MacosIconButton( - icon: MacosIcon( - CupertinoIcons.plus_app, - ), - shape: BoxShape.circle, - //onPressed: () {}, - ), - const SizedBox(width: 8), - MacosIconButton( - icon: const MacosIcon( - CupertinoIcons.minus_square, - ), - backgroundColor: Colors.transparent, - onPressed: () {}, - ), - ], - ), - const SizedBox(height: 20), - const Text('Primary PushButton'), - const SizedBox(height: 8), - Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - PushButton( - controlSize: ControlSize.mini, - child: const Text('Mini'), - onPressed: () { - MacosWindowScope.of(context) - .toggleSidebar(); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.small, - child: const Text('Small'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.regular, - child: const Text('Regular'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.large, - child: const Text('Large'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - ], - ), - ], - ), - const SizedBox(height: 8), - const Text('Secondary PushButton'), - const SizedBox(height: 8), - Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - PushButton( - controlSize: ControlSize.mini, - secondary: true, - child: const Text('Mini'), - onPressed: () { - MacosWindowScope.of(context) - .toggleSidebar(); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.small, - secondary: true, - child: const Text('Small'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.regular, - secondary: true, - child: const Text('Regular'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - const SizedBox(width: 8), - PushButton( - controlSize: ControlSize.large, - secondary: true, - child: const Text('Large'), - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) { - return MacosScaffold( - toolBar: const ToolBar( - title: Text('New page'), - ), - children: [ - ContentArea( - builder: (context, _) { - return Center( - child: PushButton( - controlSize: - ControlSize.regular, - child: - const Text('Go Back'), - onPressed: () { - Navigator.of(context) - .maybePop(); - }, - ), - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 700, - resizableSide: - ResizableSide.left, - builder: (_, __) { - return const Center( - child: - Text('Resizable Pane'), - ); - }, - ), - ], - ); - }, - ), - ); - }, - ), - ], - ), - ], - ), - const SizedBox(height: 8), - const Text('Disabled Primary PushButton'), - const SizedBox(height: 8), - const Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - PushButton( - controlSize: ControlSize.mini, - child: Text('Mini'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.small, - child: Text('Small'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.regular, - child: Text('Regular'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.large, - child: Text('Large'), - ), - ], - ), - ], - ), - const SizedBox(height: 8), - const Text('Disabled Secondary PushButton'), - const SizedBox(height: 8), - const Column( - mainAxisSize: MainAxisSize.min, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - PushButton( - controlSize: ControlSize.mini, - secondary: true, - child: Text('Mini'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.small, - secondary: true, - child: Text('Small'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.regular, - secondary: true, - child: Text('Regular'), - ), - SizedBox(width: 8), - PushButton( - controlSize: ControlSize.large, - secondary: true, - child: Text('Large'), - ), - ], - ), - ], - ), - const SizedBox(height: 20), - const Text('MacosSwitch'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosSwitch( - value: switchValue, - size: ControlSize.mini, - onChanged: (value) { - setState(() => switchValue = value); + return SingleChildScrollView( + controller: scrollController, + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const WidgetTextTitle1(widgetName: 'PushButton'), + Divider(color: MacosTheme.of(context).dividerColor), + Text( + 'Primary', + style: MacosTypography.of(context).title2, + ), + Row( + children: [ + PushButton( + controlSize: ControlSize.mini, + child: const Text('Mini'), + onPressed: () { + MacosWindowScope.of(context).toggleSidebar(); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.small, + child: const Text('Small'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], + ); }, ), - const SizedBox(width: 16.0), - MacosSwitch( - value: switchValue, - size: ControlSize.small, - onChanged: (value) { - setState(() => switchValue = value); + ); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.regular, + child: const Text('Regular'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], + ); }, ), - const SizedBox(width: 16.0), - MacosSwitch( - value: switchValue, - onChanged: (value) { - setState(() => switchValue = value); + ); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.large, + child: const Text('Large'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], + ); }, ), - ], - ), - const SizedBox(height: 20), - const Text('MacosPulldownButton'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosPulldownButton( - title: 'PDF', - items: [ - MacosPulldownMenuItem( - title: const Text('Open in Preview'), - onTap: () => - debugPrint('Opening in preview...'), - ), - MacosPulldownMenuItem( - title: const Text('Save as PDF...'), - onTap: () => debugPrint('Saving as PDF...'), - ), - MacosPulldownMenuItem( - enabled: false, - title: const Text('Save as Postscript'), - onTap: () => - debugPrint('Saving as Postscript...'), - ), - const MacosPulldownMenuDivider(), - MacosPulldownMenuItem( - enabled: false, - title: const Text('Save to iCloud Drive'), - onTap: () => - debugPrint('Saving to iCloud...'), - ), - MacosPulldownMenuItem( - enabled: false, - title: const Text('Save to Web Receipts'), - onTap: () => - debugPrint('Saving to Web Receipts...'), - ), - MacosPulldownMenuItem( - title: const Text('Send in Mail...'), - onTap: () => - debugPrint('Sending via Mail...'), - ), - const MacosPulldownMenuDivider(), - MacosPulldownMenuItem( - title: const Text('Edit Menu...'), - onTap: () => debugPrint('Editing menu...'), - ), - ], - ), - const SizedBox(width: 20), - const MacosPulldownButton( - title: 'PDF', - disabledTitle: 'Disabled', - items: [], - ), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosPulldownButton( - icon: CupertinoIcons.ellipsis_circle, - items: [ - MacosPulldownMenuItem( - title: const Text('New Folder'), - onTap: () => - debugPrint('Creating new folder...'), - ), - MacosPulldownMenuItem( - title: const Text('Open'), - onTap: () => debugPrint('Opening...'), - ), - MacosPulldownMenuItem( - title: const Text('Open with...'), - onTap: () => debugPrint('Opening with...'), - ), - MacosPulldownMenuItem( - title: const Text('Import from iPhone...'), - onTap: () => debugPrint('Importing...'), - ), - const MacosPulldownMenuDivider(), - MacosPulldownMenuItem( - enabled: false, - title: const Text('Remove'), - onTap: () => debugPrint('Deleting...'), - ), - MacosPulldownMenuItem( - title: const Text('Move to Bin'), - onTap: () => debugPrint('Moving to Bin...'), - ), - const MacosPulldownMenuDivider(), - MacosPulldownMenuItem( - title: const Text('Tags...'), - onTap: () => debugPrint('Tags...'), - ), - ], - ), - const SizedBox(width: 20), - const MacosPulldownButton( - icon: CupertinoIcons.square_grid_3x2, - items: [], - ), - ], - ), - const SizedBox(height: 20), - const Text('MacosPopupButton'), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - MacosPopupButton( - value: popupValue, - onChanged: (String? newValue) { - setState(() => popupValue = newValue!); - }, - items: [ - 'One', - 'Two', - 'Three', - 'Four' - ].map>((String value) { - return MacosPopupMenuItem( - value: value, - child: Text(value), + ); + }, + ), + ], + ), + const SizedBox(height: 16), + Text( + 'Disabled Primary', + style: MacosTypography.of(context).title2, + ), + const Row( + children: [ + PushButton( + controlSize: ControlSize.mini, + child: Text('Mini'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.small, + child: Text('Small'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.regular, + child: Text('Regular'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.large, + child: Text('Large'), + ), + ], + ), + const SizedBox(height: 16), + Text( + 'Secondary', + style: MacosTypography.of(context).title2, + ), + Row( + children: [ + PushButton( + controlSize: ControlSize.mini, + secondary: true, + child: const Text('Mini'), + onPressed: () { + MacosWindowScope.of(context).toggleSidebar(); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.small, + secondary: true, + child: const Text('Small'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], ); - }).toList(), - ), - const SizedBox(width: 20), - MacosPopupButton( - disabledHint: const Text('Disabled'), - onChanged: null, - items: null, - ), - ], - ), - const SizedBox(height: 20), - MacosPopupButton( - value: languagePopupValue, - onChanged: (String? newValue) { - setState(() => languagePopupValue = newValue!); - }, - items: languages - .map>((String value) { - return MacosPopupMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - ), - const SizedBox(height: 20), - MacosCheckbox( - value: switchValue, - onChanged: (value) { - setState(() => switchValue = value); - }, - ), - const SizedBox(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('System Theme'), - const SizedBox(width: 8), - MacosRadioButton( - groupValue: context.watch().mode, - value: ThemeMode.system, - onChanged: (value) { - context.read().mode = value!; }, ), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('Light Theme'), - const SizedBox(width: 24), - MacosRadioButton( - groupValue: context.watch().mode, - value: ThemeMode.light, - onChanged: (value) { - context.read().mode = value!; + ); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.regular, + secondary: true, + child: const Text('Regular'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], + ); }, ), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('Dark Theme'), - const SizedBox(width: 26), - MacosRadioButton( - groupValue: context.watch().mode, - value: ThemeMode.dark, - onChanged: (value) { - context.read().mode = value!; + ); + }, + ), + const SizedBox(width: 8), + PushButton( + controlSize: ControlSize.large, + secondary: true, + child: const Text('Large'), + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) { + return MacosScaffold( + toolBar: const ToolBar( + title: Text('New page'), + ), + children: [ + ContentArea( + builder: (context, _) { + return Center( + child: PushButton( + controlSize: ControlSize.regular, + child: const Text('Go Back'), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Resizable Pane'), + ); + }, + ), + ], + ); }, ), - ], + ); + }, + ), + ], + ), + const SizedBox(height: 16), + Text( + 'Disabled Secondary', + style: MacosTypography.of(context).title2, + ), + const Row( + children: [ + PushButton( + controlSize: ControlSize.mini, + secondary: true, + child: Text('Mini'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.small, + secondary: true, + child: Text('Small'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.regular, + secondary: true, + child: Text('Regular'), + ), + SizedBox(width: 8), + PushButton( + controlSize: ControlSize.large, + secondary: true, + child: Text('Large'), + ), + ], + ), + const SizedBox(height: 16), + Text( + 'Icon Buttons', + style: MacosTypography.of(context).title1, + ), + Divider(color: MacosTheme.of(context).dividerColor), + const WidgetTextTitle2(widgetName: 'MacosBackButton'), + const SizedBox(height: 8), + Row( + children: [ + MacosBackButton( + onPressed: () => debugPrint('click'), + fillColor: Colors.transparent, + ), + const SizedBox(width: 16.0), + MacosBackButton( + onPressed: () => debugPrint('click'), + ), + ], + ), + const SizedBox(height: 20), + const WidgetTextTitle2(widgetName: 'MacosDisclosureButton'), + const SizedBox(height: 8), + Row( + children: [ + MacosDisclosureButton( + isPressed: isDisclosureButtonPressed, + onPressed: () { + debugPrint('click'); + setState(() { + isDisclosureButtonPressed = + !isDisclosureButtonPressed; + }); + }, + ), + ], + ), + const SizedBox(height: 20), + const WidgetTextTitle2(widgetName: 'MacosIconButton'), + const SizedBox(height: 8), + Row( + children: [ + MacosIconButton( + icon: const MacosIcon( + CupertinoIcons.star_fill, ), - const SizedBox(height: 20), - const Text('MacosSegmentedControl'), - const SizedBox(height: 8), - MacosSegmentedControl( - controller: _tabController, - tabs: [ - MacosTab( - label: 'Tab 1', - active: _tabController.index == 0, - ), - MacosTab( - label: 'Tab 2', - active: _tabController.index == 1, - ), - MacosTab( - label: 'Tab 3', - active: _tabController.index == 2, - ), - ], + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(7), + onPressed: () {}, + ), + const SizedBox(width: 8), + const MacosIconButton( + icon: MacosIcon( + CupertinoIcons.plus_app, ), - ], - ), + shape: BoxShape.circle, + //onPressed: () {}, + ), + const SizedBox(width: 8), + MacosIconButton( + icon: const MacosIcon( + CupertinoIcons.minus_square, + ), + backgroundColor: Colors.transparent, + onPressed: () {}, + ), + ], ), - ), - ResizablePane( - minSize: 50, - startSize: 200, - //windowBreakpoint: 600, - builder: (_, __) { - return const Center( - child: Text('Resizable Pane'), - ); - }, - resizableSide: ResizableSide.top, - ) - ], - ); - }, - ), - ResizablePane( - minSize: 180, - startSize: 200, - windowBreakpoint: 800, - resizableSide: ResizableSide.left, - builder: (_, __) { - return const Center( - child: Text('Resizable Pane'), + const SizedBox(height: 20), + Text( + 'Switches, Checkboxes, & Radios', + style: MacosTypography.of(context).title1, + ), + Divider(color: MacosTheme.of(context).dividerColor), + const WidgetTextTitle2(widgetName: 'MacosSwitch'), + const SizedBox(height: 8), + Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + const Text('Mini'), + const SizedBox(width: 8), + MacosSwitch( + value: switchValue, + size: ControlSize.mini, + onChanged: (value) { + setState(() => switchValue = value); + }, + ), + ], + ), + const SizedBox(height: 8.0), + Row( + children: [ + const Text('Small'), + const SizedBox(width: 8), + MacosSwitch( + value: switchValue, + size: ControlSize.small, + onChanged: (value) { + setState(() => switchValue = value); + }, + ), + ], + ), + const SizedBox(height: 8.0), + Row( + children: [ + const Text('Regular'), + const SizedBox(width: 8), + MacosSwitch( + value: switchValue, + onChanged: (value) { + setState(() => switchValue = value); + }, + ), + ], + ), + ], + ), + const SizedBox(height: 16), + const WidgetTextTitle2(widgetName: 'MacosCheckbox'), + const SizedBox(height: 8), + MacosCheckbox( + value: switchValue, + onChanged: (value) { + setState(() => switchValue = value); + }, + ), + const SizedBox(height: 16), + const WidgetTextTitle2(widgetName: 'MacosRadioButton'), + const SizedBox(height: 8), + Row( + children: [ + const Text('System Theme'), + const SizedBox(width: 8), + MacosRadioButton( + groupValue: context.watch().mode, + value: ThemeMode.system, + onChanged: (value) { + context.read().mode = value!; + }, + ), + ], + ), + const SizedBox(height: 8), + Row( + children: [ + const Text('Light Theme'), + const SizedBox(width: 24), + MacosRadioButton( + groupValue: context.watch().mode, + value: ThemeMode.light, + onChanged: (value) { + context.read().mode = value!; + }, + ), + ], + ), + const SizedBox(height: 8), + Row( + children: [ + const Text('Dark Theme'), + const SizedBox(width: 26), + MacosRadioButton( + groupValue: context.watch().mode, + value: ThemeMode.dark, + onChanged: (value) { + context.read().mode = value!; + }, + ), + ], + ), + const SizedBox(height: 20), + Text( + 'Pulldown & Popup Buttons', + style: MacosTypography.of(context).title1, + ), + Divider(color: MacosTheme.of(context).dividerColor), + const WidgetTextTitle2(widgetName: 'MacosPulldownButton'), + const SizedBox(height: 8), + Row( + children: [ + MacosPulldownButton( + title: 'PDF', + items: [ + MacosPulldownMenuItem( + title: const Text('Open in Preview'), + onTap: () => debugPrint('Opening in preview...'), + ), + MacosPulldownMenuItem( + title: const Text('Save as PDF...'), + onTap: () => debugPrint('Saving as PDF...'), + ), + MacosPulldownMenuItem( + enabled: false, + title: const Text('Save as Postscript'), + onTap: () => debugPrint('Saving as Postscript...'), + ), + const MacosPulldownMenuDivider(), + MacosPulldownMenuItem( + enabled: false, + title: const Text('Save to iCloud Drive'), + onTap: () => debugPrint('Saving to iCloud...'), + ), + MacosPulldownMenuItem( + enabled: false, + title: const Text('Save to Web Receipts'), + onTap: () => + debugPrint('Saving to Web Receipts...'), + ), + MacosPulldownMenuItem( + title: const Text('Send in Mail...'), + onTap: () => debugPrint('Sending via Mail...'), + ), + const MacosPulldownMenuDivider(), + MacosPulldownMenuItem( + title: const Text('Edit Menu...'), + onTap: () => debugPrint('Editing menu...'), + ), + ], + ), + const SizedBox(width: 20), + const MacosPulldownButton( + title: 'PDF', + disabledTitle: 'Disabled', + items: [], + ), + ], + ), + const SizedBox(height: 8), + Row( + children: [ + MacosPulldownButton( + icon: CupertinoIcons.ellipsis_circle, + items: [ + MacosPulldownMenuItem( + title: const Text('New Folder'), + onTap: () => debugPrint('Creating new folder...'), + ), + MacosPulldownMenuItem( + title: const Text('Open'), + onTap: () => debugPrint('Opening...'), + ), + MacosPulldownMenuItem( + title: const Text('Open with...'), + onTap: () => debugPrint('Opening with...'), + ), + MacosPulldownMenuItem( + title: const Text('Import from iPhone...'), + onTap: () => debugPrint('Importing...'), + ), + const MacosPulldownMenuDivider(), + MacosPulldownMenuItem( + enabled: false, + title: const Text('Remove'), + onTap: () => debugPrint('Deleting...'), + ), + MacosPulldownMenuItem( + title: const Text('Move to Bin'), + onTap: () => debugPrint('Moving to Bin...'), + ), + const MacosPulldownMenuDivider(), + MacosPulldownMenuItem( + title: const Text('Tags...'), + onTap: () => debugPrint('Tags...'), + ), + ], + ), + const SizedBox(width: 20), + const MacosPulldownButton( + icon: CupertinoIcons.square_grid_3x2, + items: [], + ), + ], + ), + const SizedBox(height: 20), + const WidgetTextTitle2(widgetName: 'MacosPopupButton'), + const SizedBox(height: 8), + Row( + children: [ + MacosPopupButton( + value: popupValue, + onChanged: (String? newValue) { + setState(() => popupValue = newValue!); + }, + items: ['One', 'Two', 'Three', 'Four'] + .map>((String value) { + return MacosPopupMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), + const SizedBox(width: 20), + MacosPopupButton( + disabledHint: const Text('Disabled'), + onChanged: null, + items: null, + ), + ], + ), + const SizedBox(height: 20), + MacosPopupButton( + value: languagePopupValue, + onChanged: (String? newValue) { + setState(() => languagePopupValue = newValue!); + }, + items: languages + .map>((String value) { + return MacosPopupMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + ), + const SizedBox(height: 20), + const WidgetTextTitle1(widgetName: 'MacosSegmentedControl'), + Divider(color: MacosTheme.of(context).dividerColor), + const SizedBox(height: 8), + MacosSegmentedControl( + controller: _tabController, + tabs: [ + MacosTab( + label: 'Tab 1', + active: _tabController.index == 0, + ), + MacosTab( + label: 'Tab 2', + active: _tabController.index == 1, + ), + MacosTab( + label: 'Tab 3', + active: _tabController.index == 2, + ), + ], + ), + ], + ), ); }, ), @@ -876,3 +813,57 @@ const languages = [ 'Romanian', 'Dutch' ]; + +class WidgetTextTitle1 extends StatelessWidget { + const WidgetTextTitle1({super.key, required this.widgetName}); + + final String widgetName; + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: BoxDecoration( + color: MacosColors.systemGrayColor.withOpacity(0.5), + borderRadius: BorderRadius.circular(4.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 6.0, + ), + child: Text( + widgetName, + style: MacosTypography.of(context) + .title1 + .copyWith(fontFamily: GoogleFonts.jetBrainsMono().fontFamily), + ), + ), + ); + } +} + +class WidgetTextTitle2 extends StatelessWidget { + const WidgetTextTitle2({super.key, required this.widgetName}); + + final String widgetName; + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: BoxDecoration( + color: MacosColors.systemGrayColor.withOpacity(0.5), + borderRadius: BorderRadius.circular(4.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 6.0, + ), + child: Text( + widgetName, + style: MacosTypography.of(context) + .title2 + .copyWith(fontFamily: GoogleFonts.jetBrainsMono().fontFamily), + ), + ), + ); + } +} diff --git a/example/lib/pages/colors_page.dart b/example/lib/pages/colors_page.dart index 7a9df4fe..6eb3eac8 100644 --- a/example/lib/pages/colors_page.dart +++ b/example/lib/pages/colors_page.dart @@ -15,16 +15,27 @@ class _ColorsPageState extends State { toolBar: ToolBar( title: const Text('Colors'), titleWidth: 150.0, - actions: [ - ToolBarIconButton( - label: 'Toggle Sidebar', - icon: const MacosIcon( + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, ), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), - showLabel: false, ), - ], + ), ), children: [ ContentArea( diff --git a/example/lib/pages/dialogs_page.dart b/example/lib/pages/dialogs_page.dart index 9046b61c..1fea4908 100644 --- a/example/lib/pages/dialogs_page.dart +++ b/example/lib/pages/dialogs_page.dart @@ -2,6 +2,9 @@ import 'package:macos_ui/macos_ui.dart'; // ignore: implementation_imports import 'package:macos_ui/src/library.dart'; +const dialogMessage = + 'Description text about this alert is shown here, explaining to users what the options underneath are about and what to do.'; + class DialogsPage extends StatefulWidget { const DialogsPage({super.key}); @@ -16,16 +19,27 @@ class _DialogsPageState extends State { toolBar: ToolBar( title: const Text('Dialogs and Sheets'), titleWidth: 150.0, - actions: [ - ToolBarIconButton( - label: 'Toggle Sidebar', - icon: const MacosIcon( + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, ), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), - showLabel: false, ), - ], + ), ), children: [ ContentArea( @@ -41,20 +55,14 @@ class _DialogsPageState extends State { onPressed: () => showMacosAlertDialog( context: context, builder: (context) => MacosAlertDialog( - appIcon: const FlutterLogo( - size: 56, - ), - title: const Text( - 'Alert Dialog with Primary Action', - ), - message: const Text( - 'This is an alert dialog with a primary action and no secondary action', - ), + appIcon: const FlutterLogo(size: 64), + title: const Text('Title'), + message: const Text(dialogMessage), //horizontalActions: false, primaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, onPressed: Navigator.of(context).pop, - child: const Text('Primary'), + child: const Text('Label'), ), ), ), @@ -66,27 +74,23 @@ class _DialogsPageState extends State { onPressed: () => showMacosAlertDialog( context: context, builder: (context) => MacosAlertDialog( - appIcon: const FlutterLogo( - size: 56, - ), - title: const Text( - 'Alert Dialog with Secondary Action', - ), + appIcon: const FlutterLogo(size: 64), + title: const Text('Title'), message: const Text( - 'This is an alert dialog with primary action and secondary action laid out horizontally', + dialogMessage, textAlign: TextAlign.center, ), //horizontalActions: false, primaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, onPressed: Navigator.of(context).pop, - child: const Text('Primary'), + child: const Text('Label'), ), secondaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, secondary: true, onPressed: Navigator.of(context).pop, - child: const Text('Secondary'), + child: const Text('Label'), ), ), ), @@ -98,27 +102,23 @@ class _DialogsPageState extends State { onPressed: () => showMacosAlertDialog( context: context, builder: (context) => MacosAlertDialog( - appIcon: const FlutterLogo( - size: 56, - ), - title: const Text( - 'Alert Dialog with Secondary Action', - ), + appIcon: const FlutterLogo(size: 64), + title: const Text('Title'), message: const Text( - 'This is an alert dialog with primary action and secondary action laid out vertically', + dialogMessage, textAlign: TextAlign.center, ), horizontalActions: false, primaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, onPressed: Navigator.of(context).pop, - child: const Text('Primary'), + child: const Text('Label'), ), secondaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, secondary: true, onPressed: Navigator.of(context).pop, - child: const Text('Secondary'), + child: const Text('Label'), ), ), ), @@ -130,25 +130,20 @@ class _DialogsPageState extends State { onPressed: () => showMacosAlertDialog( context: context, builder: (context) => MacosAlertDialog( - appIcon: const FlutterLogo( - size: 56, - ), - title: const Text( - 'Alert Dialog with Secondary Action', - ), + appIcon: const FlutterLogo(size: 64), + title: const Text('Title'), message: const Text( - 'This is an alert dialog with primary action and secondary ' - 'action laid out vertically. It also contains a "suppress" option.', + dialogMessage, textAlign: TextAlign.center, ), horizontalActions: false, primaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, onPressed: Navigator.of(context).pop, child: const Text('Primary'), ), secondaryButton: PushButton( - controlSize: ControlSize.regular, + controlSize: ControlSize.large, secondary: true, onPressed: Navigator.of(context).pop, child: const Text('Secondary'), diff --git a/example/lib/pages/fields_page.dart b/example/lib/pages/fields_page.dart index 00b2aa81..ff5ae256 100644 --- a/example/lib/pages/fields_page.dart +++ b/example/lib/pages/fields_page.dart @@ -15,16 +15,27 @@ class _FieldsPageState extends State { toolBar: ToolBar( title: const Text('Fields'), titleWidth: 150.0, - actions: [ - ToolBarIconButton( - label: 'Toggle Sidebar', - icon: const MacosIcon( + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, ), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), - showLabel: false, ), - ], + ), ), children: [ ContentArea( diff --git a/example/lib/pages/indicators_page.dart b/example/lib/pages/indicators_page.dart index 1dd4caf5..55347f10 100644 --- a/example/lib/pages/indicators_page.dart +++ b/example/lib/pages/indicators_page.dart @@ -20,16 +20,27 @@ class _IndicatorsPageState extends State { toolBar: ToolBar( title: const Text('Indicators'), titleWidth: 150.0, - actions: [ - ToolBarIconButton( - label: 'Toggle Sidebar', - icon: const MacosIcon( + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, ), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), - showLabel: false, ), - ], + ), ), children: [ ContentArea( diff --git a/example/lib/pages/resizable_pane_page.dart b/example/lib/pages/resizable_pane_page.dart new file mode 100644 index 00000000..b850a0c3 --- /dev/null +++ b/example/lib/pages/resizable_pane_page.dart @@ -0,0 +1,90 @@ +import 'package:flutter/cupertino.dart'; +import 'package:macos_ui/macos_ui.dart'; + +class ResizablePanePage extends StatefulWidget { + const ResizablePanePage({super.key}); + + @override + State createState() => _ResizablePanePageState(); +} + +class _ResizablePanePageState extends State { + @override + Widget build(BuildContext context) { + return MacosScaffold( + toolBar: ToolBar( + title: const Text('Resizable Pane'), + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( + CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, + ), + onPressed: () => MacosWindowScope.of(context).toggleSidebar(), + ), + ), + ), + children: [ + ResizablePane( + minSize: 180, + startSize: 200, + windowBreakpoint: 700, + resizableSide: ResizableSide.right, + builder: (_, __) { + return const Center( + child: Text('Left Resizable Pane'), + ); + }, + ), + ContentArea( + builder: (_, __) { + return Column( + children: [ + const Flexible( + fit: FlexFit.loose, + child: Center( + child: Text('Content Area'), + ), + ), + ResizablePane( + minSize: 50, + startSize: 200, + //windowBreakpoint: 600, + builder: (_, __) { + return const Center( + child: Text('Bottom Resizable Pane'), + ); + }, + resizableSide: ResizableSide.top, + ), + ], + ); + }, + ), + ResizablePane( + minSize: 180, + startSize: 200, + // windowBreakpoint: 800, + resizableSide: ResizableSide.left, + builder: (_, __) { + return const Center( + child: Text('Right Resizable Pane'), + ); + }, + ), + ], + ); + } +} diff --git a/example/lib/pages/selectors_page.dart b/example/lib/pages/selectors_page.dart index 8256a33e..9c9a8364 100644 --- a/example/lib/pages/selectors_page.dart +++ b/example/lib/pages/selectors_page.dart @@ -15,16 +15,27 @@ class _SelectorsPageState extends State { toolBar: ToolBar( title: const Text('Selectors'), titleWidth: 150.0, - actions: [ - ToolBarIconButton( - label: 'Toggle Sidebar', - icon: const MacosIcon( + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, ), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), - showLabel: false, ), - ], + ), ), children: [ ContentArea( diff --git a/example/lib/pages/tabview_page.dart b/example/lib/pages/tabview_page.dart index 64d4d8ff..5e224429 100644 --- a/example/lib/pages/tabview_page.dart +++ b/example/lib/pages/tabview_page.dart @@ -17,8 +17,29 @@ class _TabViewPageState extends State { @override Widget build(BuildContext context) { return MacosScaffold( - toolBar: const ToolBar( - title: Text('TabView'), + toolBar: ToolBar( + title: const Text('TabView'), + leading: MacosTooltip( + message: 'Toggle Sidebar', + useMousePosition: false, + child: MacosIconButton( + icon: MacosIcon( + CupertinoIcons.sidebar_left, + color: MacosTheme.brightnessOf(context).resolve( + const Color.fromRGBO(0, 0, 0, 0.5), + const Color.fromRGBO(255, 255, 255, 0.5), + ), + size: 20.0, + ), + boxConstraints: const BoxConstraints( + minHeight: 20, + minWidth: 20, + maxWidth: 48, + maxHeight: 38, + ), + onPressed: () => MacosWindowScope.of(context).toggleSidebar(), + ), + ), ), children: [ ContentArea( diff --git a/example/macos/Flutter/GeneratedPluginRegistrant.swift b/example/macos/Flutter/GeneratedPluginRegistrant.swift index b06f1179..15deecb4 100644 --- a/example/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,8 +7,10 @@ import Foundation import macos_ui import macos_window_utils +import path_provider_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin")) MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) } diff --git a/example/macos/Podfile.lock b/example/macos/Podfile.lock index 42b5eb53..97b47e1b 100644 --- a/example/macos/Podfile.lock +++ b/example/macos/Podfile.lock @@ -4,11 +4,15 @@ PODS: - FlutterMacOS - macos_window_utils (1.0.0): - FlutterMacOS + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - macos_ui (from `Flutter/ephemeral/.symlinks/plugins/macos_ui/macos`) - macos_window_utils (from `Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) EXTERNAL SOURCES: FlutterMacOS: @@ -17,11 +21,14 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/macos_ui/macos macos_window_utils: :path: Flutter/ephemeral/.symlinks/plugins/macos_window_utils/macos + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 macos_ui: 6229a8922cd97bafb7d9636c8eb8dfb0744183ca macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663 + path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 PODFILE CHECKSUM: ff0a9a3ce75ee73f200ca7e2f47745698c917ef9 diff --git a/example/macos/Runner/DebugProfile.entitlements b/example/macos/Runner/DebugProfile.entitlements index dddb8a30..c946719a 100644 --- a/example/macos/Runner/DebugProfile.entitlements +++ b/example/macos/Runner/DebugProfile.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.server + com.apple.security.network.client + diff --git a/example/pubspec.lock b/example/pubspec.lock index 2b2ea121..3f05abc6 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -41,6 +41,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" cupertino_icons: dependency: "direct main" description: @@ -57,6 +65,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + url: "https://pub.dev" + source: hosted + version: "2.0.2" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" flutter: dependency: "direct main" description: flutter @@ -66,15 +90,39 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + google_fonts: + dependency: "direct main" + description: + name: google_fonts + sha256: e20ff62b158b96f392bfc8afe29dee1503c94fbea2cbe8186fd59b756b8ae982 + url: "https://pub.dev" + source: hosted + version: "5.1.0" + http: + dependency: transitive + description: + name: http + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" js: dependency: transitive description: @@ -97,7 +145,7 @@ packages: path: ".." relative: true source: path - version: "2.0.0-beta.6" + version: "2.0.0-beta.7" macos_window_utils: dependency: transitive description: @@ -146,6 +194,78 @@ packages: url: "https://pub.dev" source: hosted version: "1.8.3" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" + url: "https://pub.dev" + source: hosted + version: "2.0.15" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + url: "https://pub.dev" + source: hosted + version: "2.0.27" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" + url: "https://pub.dev" + source: hosted + version: "2.2.3" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 + url: "https://pub.dev" + source: hosted + version: "2.1.11" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" + url: "https://pub.dev" + source: hosted + version: "2.1.7" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" provider: dependency: "direct main" description: @@ -207,6 +327,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" vector_math: dependency: transitive description: @@ -215,6 +343,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + win32: + dependency: transitive + description: + name: win32 + sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee + url: "https://pub.dev" + source: hosted + version: "5.0.5" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + url: "https://pub.dev" + source: hosted + version: "1.0.0" sdks: dart: ">=3.0.0 <4.0.0" flutter: ">=3.10.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e68c5535..79564134 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: '>=2.17.0 <3.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: flutter: @@ -13,12 +13,13 @@ dependencies: cupertino_icons: ^1.0.5 macos_ui: path: .. - provider: ^6.0.3 + provider: ^6.0.5 + google_fonts: ^5.1.0 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^2.0.1 + flutter_lints: ^2.0.2 flutter: assets: diff --git a/lib/src/dialogs/macos_alert_dialog.dart b/lib/src/dialogs/macos_alert_dialog.dart index 057f04df..0dab2588 100644 --- a/lib/src/dialogs/macos_alert_dialog.dart +++ b/lib/src/dialogs/macos_alert_dialog.dart @@ -3,6 +3,10 @@ import 'package:macos_ui/macos_ui.dart'; import 'package:macos_ui/src/library.dart'; const _kDialogBorderRadius = BorderRadius.all(Radius.circular(12.0)); +const _kDefaultDialogConstraints = BoxConstraints( + minWidth: 260, + maxWidth: 260, +); /// A macOS-style AlertDialog. /// @@ -17,14 +21,12 @@ const _kDialogBorderRadius = BorderRadius.all(Radius.circular(12.0)); /// appIcon: FlutterLogo( /// size: 56, /// ), -/// title: Text( -/// 'Alert Dialog with Primary Action', -/// ), +/// title: Text('Alert Dialog with Primary Action'), /// message: Text( /// 'This is an alert dialog with a primary action and no secondary action', /// ), /// primaryButton: PushButton( -/// buttonSize: ButtonSize.large, +/// controlSize: ControlSize.large, /// child: Text('Primary'), /// onPressed: Navigator.of(context).pop, /// ), @@ -46,7 +48,7 @@ class MacosAlertDialog extends StatelessWidget { /// This should be your application's icon. /// - /// The size of this widget should be 56x56. + /// The size of this widget should be 64x64. final Widget appIcon; /// The title for the dialog. @@ -61,13 +63,13 @@ class MacosAlertDialog extends StatelessWidget { /// The primary action a user can take. /// - /// Typically a [PushButton]. - final Widget primaryButton; + /// Must a [PushButton] with a [ControlSize] of `large`. + final PushButton primaryButton; /// The secondary action a user can take. /// - /// Typically a [PushButton]. - final Widget? secondaryButton; + /// Must a [PushButton] with a [ControlSize] of `large`. + final PushButton? secondaryButton; /// Determines whether to lay out [primaryButton] and [secondaryButton] /// horizontally or vertically. @@ -116,6 +118,11 @@ class MacosAlertDialog extends StatelessWidget { @override Widget build(BuildContext context) { assert(debugCheckHasMacosTheme(context)); + assert(primaryButton.controlSize == ControlSize.large); + if (secondaryButton != null) { + assert(secondaryButton is PushButton); + assert(secondaryButton!.controlSize == ControlSize.large); + } final brightness = MacosTheme.brightnessOf(context); final outerBorderColor = brightness.resolve( @@ -153,39 +160,35 @@ class MacosAlertDialog extends StatelessWidget { borderRadius: _kDialogBorderRadius, ), child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 260, - ), + constraints: _kDefaultDialogConstraints, child: Column( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox(height: 28), + const SizedBox(height: 20), ConstrainedBox( constraints: const BoxConstraints( - maxHeight: 56, - maxWidth: 56, + maxHeight: 64, + maxWidth: 64, ), child: appIcon, ), - const SizedBox(height: 28), + const SizedBox(height: 16), DefaultTextStyle( style: MacosTheme.of(context).typography.headline, textAlign: TextAlign.center, child: title, ), - const SizedBox(height: 16), + const SizedBox(height: 10), DefaultTextStyle( textAlign: TextAlign.center, style: MacosTheme.of(context).typography.headline, child: message, ), - const SizedBox(height: 18), + const SizedBox(height: 16), if (secondaryButton == null) ...[ Row( children: [ - Expanded( - child: primaryButton, - ), + Expanded(child: primaryButton), ], ), ] else ...[ @@ -193,9 +196,7 @@ class MacosAlertDialog extends StatelessWidget { Row( children: [ if (secondaryButton != null) ...[ - Expanded( - child: secondaryButton!, - ), + Expanded(child: secondaryButton!), const SizedBox(width: 8.0), ], Expanded( diff --git a/lib/src/theme/typography.dart b/lib/src/theme/typography.dart index d3efbeaf..c5a9eefd 100644 --- a/lib/src/theme/typography.dart +++ b/lib/src/theme/typography.dart @@ -1,5 +1,6 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; +import 'package:macos_ui/src/theme/macos_theme.dart'; const _kDefaultFontFamily = '.AppleSystemUIFont'; @@ -230,6 +231,11 @@ class MacosTypography with Diagnosticable { ); } + static MacosTypography of(BuildContext context) { + final theme = MacosTheme.of(context); + return theme.typography; + } + @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); diff --git a/pubspec.yaml b/pubspec.yaml index 33d64578..5ce15348 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: macos_ui description: Flutter widgets and themes implementing the current macOS design language. -version: 2.0.0-beta.6 +version: 2.0.0-beta.7 homepage: "https://macosui.dev" repository: "https://github.com/GroovinChip/macos_ui"