From fdba64e748c1c2a78cb6f0927b9b46a156bf5f9c Mon Sep 17 00:00:00 2001 From: debuggerx Date: Sun, 26 Sep 2021 20:47:01 +0800 Subject: [PATCH] feat: responsive layout. --- app/lib/constants/constants.dart | 18 ++++++++++++++ app/lib/main.dart | 1 + app/lib/pages/content.dart | 42 ++++++++++++++++++++++---------- app/lib/pages/gesture_editor.dart | 50 +++++++++++++++++++++++++++++++++++---- app/lib/pages/local_manager.dart | 17 ++++++------- app/lib/pages/market.dart | 44 +++++++++++++++++++++++++++++++++- app/lib/utils/helper.dart | 48 +++++++++++++++++++++++++++++++++++++ app/lib/utils/init_linux.dart | 3 ++- 8 files changed, 197 insertions(+), 26 deletions(-) create mode 100644 app/lib/constants/constants.dart diff --git a/app/lib/constants/constants.dart b/app/lib/constants/constants.dart new file mode 100644 index 0000000..30e9c29 --- /dev/null +++ b/app/lib/constants/constants.dart @@ -0,0 +1,18 @@ +import 'package:flutter/cupertino.dart'; + +const double localManagerPanelWidth = 200; + +const double marketPanelWidth = 200; + +const shortDuration = const Duration(milliseconds: 100); + +const mediumDuration = const Duration(milliseconds: 300); + +const longDuration = const Duration(milliseconds: 500); + +const minWindowSize = const Size(800, 600); + +enum PanelType { + local_manager, + market, +} \ No newline at end of file diff --git a/app/lib/main.dart b/app/lib/main.dart index 702852e..0e634e1 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -54,6 +54,7 @@ class MyApp extends StatelessWidget { localizationsDelegates: context.localizationDelegates, supportedLocales: context.supportedLocales, locale: context.locale, + debugShowCheckedModeBanner: false, home: AnimatedCrossFade( crossFadeState: isDarkMode != null ? CrossFadeState.showSecond : CrossFadeState.showFirst, alignment: Alignment.center, diff --git a/app/lib/pages/content.dart b/app/lib/pages/content.dart index 6eb14ac..daa897f 100644 --- a/app/lib/pages/content.dart +++ b/app/lib/pages/content.dart @@ -4,6 +4,7 @@ import 'package:dde_gesture_manager/pages/local_manager.dart'; import 'package:dde_gesture_manager/pages/market.dart'; import 'package:flutter/material.dart'; import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:dde_gesture_manager/utils/helper.dart'; class Content extends StatefulWidget { const Content({Key? key}) : super(key: key); @@ -13,21 +14,38 @@ class Content extends StatefulWidget { } class _ContentState extends State { + double? preWindowWidth; + @override Widget build(BuildContext context) { - return ChangeNotifierProvider( + var windowWidth = MediaQuery.of(context).size.width; + var preferredPanelsStatus = H.getPreferredPanelsStatus(windowWidth); + var widthChanged = preWindowWidth != null && preWindowWidth != windowWidth; + var widget = ChangeNotifierProvider( create: (context) => ContentLayoutProvider() - ..localManagerOpened = true - ..marketOpened = true, - builder: (context, child) => Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - LocalManager(), - GestureEditor(), - Market(), - ], - ), + ..localManagerOpened = preferredPanelsStatus.localManagerPanelOpened + ..marketOpened = preferredPanelsStatus.marketPanelOpened, + builder: (context, child) { + if (widthChanged && mounted) { + Future.microtask( + () => context.read().setProps( + localManagerOpened: preferredPanelsStatus.localManagerPanelOpened, + marketOpened: preferredPanelsStatus.marketPanelOpened, + ), + ); + } + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + LocalManager(), + GestureEditor(), + Market(), + ], + ); + }, ); + preWindowWidth = windowWidth; + return widget; } } diff --git a/app/lib/pages/gesture_editor.dart b/app/lib/pages/gesture_editor.dart index ac8691c..54407a8 100644 --- a/app/lib/pages/gesture_editor.dart +++ b/app/lib/pages/gesture_editor.dart @@ -1,14 +1,56 @@ +import 'package:dde_gesture_manager/constants/constants.dart'; +import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:dde_gesture_manager/utils/helper.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:dde_gesture_manager/extensions.dart'; class GestureEditor extends StatelessWidget { const GestureEditor({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Container( - color: Colors.black45, - child: Column( - children: [], + var layoutProvider = context.watch(); + return Flexible( + child: Container( + color: Colors.black45, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Visibility( + visible: layoutProvider.localManagerOpened == false, + child: IconButton( + onPressed: () => H.openPanel(context, PanelType.local_manager), + icon: Icon( + CupertinoIcons.square_list, + ), + ), + ), + Visibility( + visible: layoutProvider.marketOpened == false, + child: IconButton( + onPressed: () => H.openPanel(context, PanelType.market), + icon: Icon( + CupertinoIcons.cart, + ), + ), + ), + ], + ), + Container( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("<编辑器区域"), + Text("编辑器区域>"), + ], + ), + ), + ], + ), ), ); } diff --git a/app/lib/pages/local_manager.dart b/app/lib/pages/local_manager.dart index ac02a8c..c5ced46 100644 --- a/app/lib/pages/local_manager.dart +++ b/app/lib/pages/local_manager.dart @@ -3,6 +3,7 @@ import 'package:flutter/animation.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:dde_gesture_manager/extensions.dart'; +import 'package:dde_gesture_manager/constants/constants.dart'; class LocalManager extends StatelessWidget { const LocalManager({ @@ -12,18 +13,18 @@ class LocalManager extends StatelessWidget { @override Widget build(BuildContext context) { var isOpen = context.watch().localManagerOpened == true; - isOpen.sout(); return AnimatedContainer( - duration: Duration(milliseconds: 300), + duration: mediumDuration, curve: Curves.easeInOut, - width: isOpen ? 200 : 36, + width: isOpen ? localManagerPanelWidth : 0, child: OverflowBox( alignment: Alignment.centerRight, - maxWidth: 200, - minWidth: 200, + maxWidth: localManagerPanelWidth, + minWidth: localManagerPanelWidth, child: Material( - color: context.t.backgroundColor, - elevation: 20, + // color: context.t.backgroundColor, + color: Colors.deepPurple, + elevation: isOpen ? 20 : 0, child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -41,7 +42,7 @@ class LocalManager extends StatelessWidget { IconButton( onPressed: () => context.read().setProps(localManagerOpened: !isOpen), icon: Icon( - isOpen ? CupertinoIcons.chevron_left_2 : CupertinoIcons.chevron_right_2, + CupertinoIcons.chevron_left_2, ), ), ], diff --git a/app/lib/pages/market.dart b/app/lib/pages/market.dart index 11ad12e..061e3b5 100644 --- a/app/lib/pages/market.dart +++ b/app/lib/pages/market.dart @@ -1,4 +1,8 @@ +import 'package:dde_gesture_manager/constants/constants.dart'; +import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:dde_gesture_manager/extensions.dart'; class Market extends StatelessWidget { const Market({ @@ -7,6 +11,44 @@ class Market extends StatelessWidget { @override Widget build(BuildContext context) { - return Container(); + var isOpen = context.watch().marketOpened == true; + return AnimatedContainer( + duration: mediumDuration, + curve: Curves.easeInOut, + width: isOpen ? marketPanelWidth : 0, + child: OverflowBox( + alignment: Alignment.centerLeft, + maxWidth: marketPanelWidth, + minWidth: marketPanelWidth, + child: Material( + color: Colors.deepPurpleAccent, + elevation: isOpen ? 20 : 0, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton( + onPressed: () => context.read().setProps(marketOpened: !isOpen), + icon: Icon( + CupertinoIcons.chevron_right_2, + ), + ), + Flexible( + child: Center( + child: Text( + "配置市场", + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + ], + ), + ), + ), + ); } } diff --git a/app/lib/utils/helper.dart b/app/lib/utils/helper.dart index f306e6a..0e67a88 100644 --- a/app/lib/utils/helper.dart +++ b/app/lib/utils/helper.dart @@ -1,4 +1,8 @@ +import 'package:dde_gesture_manager/models/content_layout.provider.dart'; +import 'package:flutter/cupertino.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:dde_gesture_manager/constants/constants.dart'; +import 'package:dde_gesture_manager/extensions.dart'; class H { H._(); @@ -14,4 +18,48 @@ class H { initSharedPreference() async { _sp = await SharedPreferences.getInstance(); } + + static void openPanel(BuildContext context, PanelType panelType) { + var windowWidth = MediaQuery.of(context).size.width; + if (windowWidth < minWindowSize.width + localManagerPanelWidth + marketPanelWidth) { + context.read().setProps( + localManagerOpened: panelType == PanelType.local_manager, + marketOpened: panelType == PanelType.market, + ); + } else { + switch (panelType) { + case PanelType.local_manager: + return context.read().setProps(localManagerOpened: true); + case PanelType.market: + return context.read().setProps(marketOpened: true); + } + } + } + + static PreferredPanelsStatus getPreferredPanelsStatus(double windowWidth) { + var preferredPanelsStatus = PreferredPanelsStatus(localManagerPanelOpened: true, marketPanelOpened: true); + if (windowWidth > minWindowSize.width + localManagerPanelWidth + marketPanelWidth) + return preferredPanelsStatus; + else if (windowWidth < minWindowSize.width + localManagerPanelWidth) + return preferredPanelsStatus + ..marketPanelOpened = false + ..localManagerPanelOpened = false; + else + return preferredPanelsStatus..marketPanelOpened = false; + } +} + +class PreferredPanelsStatus { + bool localManagerPanelOpened; + bool marketPanelOpened; + + PreferredPanelsStatus({ + required this.localManagerPanelOpened, + required this.marketPanelOpened, + }); + + @override + String toString() { + return 'PreferredPanelsStatus{localManagerPanelOpened: $localManagerPanelOpened, marketPanelOpened: $marketPanelOpened}'; + } } diff --git a/app/lib/utils/init_linux.dart b/app/lib/utils/init_linux.dart index e11a845..ca8faa7 100644 --- a/app/lib/utils/init_linux.dart +++ b/app/lib/utils/init_linux.dart @@ -1,3 +1,4 @@ +import 'package:dde_gesture_manager/constants/constants.dart'; import 'package:dde_gesture_manager/constants/sp_keys.dart'; import 'package:dde_gesture_manager/constants/supported_locales.dart'; import 'package:dde_gesture_manager/extensions.dart'; @@ -40,7 +41,7 @@ Future initConfigs() async { var userLanguageIndex = H().sp.getInt(SPKeys.userLanguage) ?? 0; var locale = supportedLocales[userLanguageIndex]; windowManager.setTitle(CodegenLoader.mapLocales[locale.toString()]?[LocaleKeys.app_name]); - windowManager.setMinimumSize(const Size(800, 600)); + windowManager.setMinimumSize(minWindowSize); } var windowManager = WindowManager.instance;