From 930bf72c91d3129ceeda2d18865459e6c34f197e Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 22 Aug 2022 17:58:48 +0800 Subject: [PATCH] optimize ui style Signed-off-by: 21pages --- flutter/lib/common.dart | 15 +- .../lib/desktop/pages/connection_page.dart | 153 ++++++++++++------ .../desktop/pages/connection_tab_page.dart | 61 +++---- .../lib/desktop/pages/desktop_home_page.dart | 67 +++----- .../desktop/pages/file_manager_tab_page.dart | 47 +++--- flutter/lib/desktop/pages/server_page.dart | 22 ++- .../lib/desktop/widgets/tabbar_widget.dart | 13 +- 7 files changed, 218 insertions(+), 160 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 8c4216020..c33e2b291 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -59,6 +59,7 @@ class ColorThemeExtension extends ThemeExtension { required this.text, required this.lightText, required this.lighterText, + required this.placeholder, required this.border, }); @@ -67,6 +68,7 @@ class ColorThemeExtension extends ThemeExtension { final Color? text; final Color? lightText; final Color? lighterText; + final Color? placeholder; final Color? border; static const light = ColorThemeExtension( @@ -75,6 +77,7 @@ class ColorThemeExtension extends ThemeExtension { text: Color(0xFF222222), lightText: Color(0xFF666666), lighterText: Color(0xFF888888), + placeholder: Color(0xFFAAAAAA), border: Color(0xFFCCCCCC), ); @@ -84,6 +87,7 @@ class ColorThemeExtension extends ThemeExtension { text: Color(0xFFFFFFFF), lightText: Color(0xFF999999), lighterText: Color(0xFF777777), + placeholder: Color(0xFF555555), border: Color(0xFF555555), ); @@ -94,6 +98,7 @@ class ColorThemeExtension extends ThemeExtension { Color? text, Color? lightText, Color? lighterText, + Color? placeholder, Color? border}) { return ColorThemeExtension( bg: bg ?? this.bg, @@ -101,6 +106,7 @@ class ColorThemeExtension extends ThemeExtension { text: text ?? this.text, lightText: lightText ?? this.lightText, lighterText: lighterText ?? this.lighterText, + placeholder: placeholder ?? this.placeholder, border: border ?? this.border, ); } @@ -117,6 +123,7 @@ class ColorThemeExtension extends ThemeExtension { text: Color.lerp(text, other.text, t), lightText: Color.lerp(lightText, other.lightText, t), lighterText: Color.lerp(lighterText, other.lighterText, t), + placeholder: Color.lerp(placeholder, other.placeholder, t), border: Color.lerp(border, other.border, t), ); } @@ -136,6 +143,8 @@ class MyTheme { static const Color darkGray = Color(0xFFB9BABC); static const Color cmIdColor = Color(0xFF21790B); static const Color dark = Colors.black87; + static const Color button = Color(0xFF2C8CFF); + static const Color hoverBorder = Color(0xFF999999); static ThemeData lightTheme = ThemeData( brightness: Brightness.light, @@ -144,7 +153,8 @@ class MyTheme { tabBarTheme: TabBarTheme( labelColor: Colors.black87, ), - // backgroundColor: Color(0xFFFFFFFF), + splashColor: Colors.transparent, + highlightColor: Colors.transparent, ).copyWith( extensions: >[ ColorThemeExtension.light, @@ -157,7 +167,8 @@ class MyTheme { tabBarTheme: TabBarTheme( labelColor: Colors.white70, ), - // backgroundColor: Color(0xFF252525) + splashColor: Colors.transparent, + highlightColor: Colors.transparent, ).copyWith( extensions: >[ ColorThemeExtension.dark, diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index c07df87e9..c021217e0 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -65,12 +65,14 @@ class _ConnectionPageState extends State { getUpdateUI(), Row( children: [ - getSearchBarUI(), + getSearchBarUI(context), ], - ).marginOnly(top: 16.0, left: 16.0), + ).marginOnly(top: 22, left: 22), SizedBox(height: 12), Divider( thickness: 1, + indent: 22, + endIndent: 22, ), Expanded( // TODO: move all tab info into _PeerTabbedPage @@ -123,7 +125,7 @@ class _ConnectionPageState extends State { } }), ], - )), + ).marginSymmetric(horizontal: 6)), Divider(), SizedBox(height: 50, child: Obx(() => buildStatus())) .paddingSymmetric(horizontal: 12.0) @@ -178,12 +180,16 @@ class _ConnectionPageState extends State { /// UI for the search bar. /// Search for a peer and connect to it if the id exists. - Widget getSearchBarUI() { + Widget getSearchBarUI(BuildContext context) { + RxBool ftHover = false.obs; + RxBool ftPressed = false.obs; + RxBool connHover = false.obs; + RxBool connPressed = false.obs; var w = Container( - width: 500, - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 24), + width: 320 + 20 * 2, + padding: EdgeInsets.only(left: 20, right: 20, bottom: 22, top: 30), decoration: BoxDecoration( - color: isDarkTheme() ? null : MyTheme.white, + color: MyTheme.color(context).bg, borderRadius: const BorderRadius.all(Radius.circular(13)), ), child: Ink( @@ -197,17 +203,12 @@ class _ConnectionPageState extends State { autocorrect: false, enableSuggestions: false, keyboardType: TextInputType.visiblePassword, - // keyboardType: TextInputType.number, style: TextStyle( fontFamily: 'WorkSans', - fontWeight: FontWeight.bold, - fontSize: 30, - // color: MyTheme.idColor, + fontSize: 22, ), decoration: InputDecoration( labelText: translate('Control Remote Desktop'), - // hintText: 'Enter your remote ID', - // border: InputBorder., border: OutlineInputBorder(borderRadius: BorderRadius.zero), helperStyle: TextStyle( @@ -215,7 +216,7 @@ class _ConnectionPageState extends State { fontSize: 16, ), labelStyle: TextStyle( - fontWeight: FontWeight.w600, + fontWeight: FontWeight.w500, fontSize: 26, letterSpacing: 0.2, ), @@ -230,42 +231,84 @@ class _ConnectionPageState extends State { ], ), Padding( - padding: const EdgeInsets.only(top: 16.0), + padding: const EdgeInsets.only(top: 13.0), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - OutlinedButton( - onPressed: () { - onConnect(isFileTransfer: true); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 8.0, horizontal: 8.0), - child: Text( - translate( - "Transfer File", + Obx(() => InkWell( + onTapDown: (_) => ftPressed.value = true, + onTapUp: (_) => ftPressed.value = false, + onTapCancel: () => ftPressed.value = false, + onHover: (value) => ftHover.value = value, + onTap: () { + onConnect(isFileTransfer: true); + }, + child: Container( + height: 24, + width: 72, + alignment: Alignment.center, + decoration: BoxDecoration( + color: ftPressed.value + ? MyTheme.accent + : Colors.transparent, + border: Border.all( + color: ftPressed.value + ? MyTheme.accent + : ftHover.value + ? MyTheme.hoverBorder + : MyTheme.border, + ), + borderRadius: BorderRadius.circular(5), + ), + child: Text( + translate( + "Transfer File", + ), + style: TextStyle( + fontSize: 12, + color: ftPressed.value + ? MyTheme.color(context).bg + : MyTheme.color(context).text), + ), ), - ), - ), - ), + )), SizedBox( - width: 30, + width: 17, ), - OutlinedButton( - onPressed: onConnect, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 8.0, horizontal: 16.0), - child: Text( - translate( - "Connection", + Obx( + () => InkWell( + onTapDown: (_) => connPressed.value = true, + onTapUp: (_) => connPressed.value = false, + onTapCancel: () => connPressed.value = false, + onHover: (value) => connHover.value = value, + onTap: onConnect, + child: Container( + height: 24, + width: 65, + decoration: BoxDecoration( + color: connPressed.value + ? MyTheme.accent + : MyTheme.button, + border: Border.all( + color: connPressed.value + ? MyTheme.accent + : connHover.value + ? MyTheme.hoverBorder + : MyTheme.button, + ), + borderRadius: BorderRadius.circular(5), + ), + child: Center( + child: Text( + translate( + "Connection", + ), + style: TextStyle( + fontSize: 12, color: MyTheme.color(context).bg), + ), ), - style: TextStyle(color: MyTheme.white), ), ), - style: OutlinedButton.styleFrom( - backgroundColor: Colors.blueAccent, - ), ), ], ), @@ -920,6 +963,7 @@ class _PeerTabbedPage extends StatefulWidget { class _PeerTabbedPageState extends State<_PeerTabbedPage> with SingleTickerProviderStateMixin { late TabController _tabController; + RxInt _tabIndex = 0.obs; @override void initState() { @@ -932,6 +976,7 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> // hard code for now void _handleTabSelection() { if (_tabController.indexIsChanging) { + _tabIndex.value = _tabController.index; switch (_tabController.index) { case 0: bind.mainLoadRecentPeers(); @@ -969,19 +1014,37 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage> return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - _createTabBar(), + _createTabBar(context), _createTabBarView(), ], ); } - Widget _createTabBar() { + Widget _createTabBar(BuildContext context) { return TabBar( isScrollable: true, indicatorSize: TabBarIndicatorSize.label, + indicatorColor: Colors.transparent, + indicatorWeight: 0.1, controller: _tabController, - tabs: super.widget.tabs.map((t) { - return Tab(child: Text(t)); + labelPadding: EdgeInsets.zero, + padding: EdgeInsets.only(left: 16), + tabs: super.widget.tabs.asMap().entries.map((t) { + return Obx(() => Container( + padding: EdgeInsets.symmetric(horizontal: 8, vertical: 6), + decoration: BoxDecoration( + color: + _tabIndex.value == t.key ? MyTheme.color(context).bg : null, + borderRadius: BorderRadius.circular(2), + ), + child: Text( + t.value, + style: TextStyle( + height: 1, + color: _tabIndex.value == t.key + ? MyTheme.color(context).text + : MyTheme.color(context).lightText), + ))); }).toList()); } diff --git a/flutter/lib/desktop/pages/connection_tab_page.dart b/flutter/lib/desktop/pages/connection_tab_page.dart index ece7df5ca..407feddea 100644 --- a/flutter/lib/desktop/pages/connection_tab_page.dart +++ b/flutter/lib/desktop/pages/connection_tab_page.dart @@ -76,34 +76,39 @@ class _ConnectionTabPageState extends State { Widget build(BuildContext context) { return SubWindowDragToResizeArea( windowId: windowId(), - child: Scaffold( - body: Column( - children: [ - Obx(() => Visibility( - visible: _fullscreenID.value.isEmpty, - child: DesktopTabBar( - tabs: tabs, - onTabClose: onRemoveId, - dark: isDarkTheme(), - mainTab: false, - ))), - Expanded(child: Obx(() { - WindowController.fromWindowId(windowId()) - .setFullscreen(_fullscreenID.value.isNotEmpty); - return PageView( - controller: DesktopTabBar.controller.value, - children: tabs - .map((tab) => RemotePage( - key: ValueKey(tab.label), - id: tab.label, - tabBarHeight: _fullscreenID.value.isNotEmpty - ? 0 - : kDesktopRemoteTabBarHeight, - fullscreenID: _fullscreenID, - )) //RemotePage(key: ValueKey(e), id: e)) - .toList()); - })), - ], + child: Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: Column( + children: [ + Obx(() => Visibility( + visible: _fullscreenID.value.isEmpty, + child: DesktopTabBar( + tabs: tabs, + onTabClose: onRemoveId, + dark: isDarkTheme(), + mainTab: false, + ))), + Expanded(child: Obx(() { + WindowController.fromWindowId(windowId()) + .setFullscreen(_fullscreenID.value.isNotEmpty); + return PageView( + controller: DesktopTabBar.controller.value, + children: tabs + .map((tab) => RemotePage( + key: ValueKey(tab.label), + id: tab.label, + tabBarHeight: _fullscreenID.value.isNotEmpty + ? 0 + : kDesktopRemoteTabBarHeight, + fullscreenID: _fullscreenID, + )) //RemotePage(key: ValueKey(e), id: e)) + .toList()); + })), + ], + ), ), ), ); diff --git a/flutter/lib/desktop/pages/desktop_home_page.dart b/flutter/lib/desktop/pages/desktop_home_page.dart index 30fec849b..f85cf5b86 100644 --- a/flutter/lib/desktop/pages/desktop_home_page.dart +++ b/flutter/lib/desktop/pages/desktop_home_page.dart @@ -90,7 +90,7 @@ class _DesktopHomePageState extends State buildIDBoard(BuildContext context) { final model = gFFI.serverModel; return Container( - margin: EdgeInsets.symmetric(horizontal: 16), + margin: EdgeInsets.only(left: 20, right: 16), height: 52, child: Row( crossAxisAlignment: CrossAxisAlignment.baseline, @@ -133,11 +133,12 @@ class _DesktopHomePageState extends State readOnly: true, decoration: InputDecoration( border: InputBorder.none, + contentPadding: EdgeInsets.only(bottom: 8), ), style: TextStyle( fontSize: 22, ), - ).marginOnly(bottom: 5), + ), ), ) ], @@ -240,7 +241,8 @@ class _DesktopHomePageState extends State child: Obx( () => Container( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(90), + // borderRadius: BorderRadius.circular(10), + shape: BoxShape.circle, boxShadow: [ BoxShadow( color: hover.value @@ -268,7 +270,7 @@ class _DesktopHomePageState extends State final model = gFFI.serverModel; RxBool refreshHover = false.obs; return Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 16.0), + margin: EdgeInsets.only(left: 20.0, right: 16, top: 13, bottom: 13), child: Row( crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, @@ -306,6 +308,7 @@ class _DesktopHomePageState extends State readOnly: true, decoration: InputDecoration( border: InputBorder.none, + contentPadding: EdgeInsets.only(bottom: 8), ), style: TextStyle(fontSize: 15), ), @@ -319,7 +322,7 @@ class _DesktopHomePageState extends State ? MyTheme.color(context).text : Color(0xFFDDDDDD), size: 22, - ).marginOnly(right: 5), + ).marginOnly(right: 10, bottom: 8), ), onTap: () => bind.mainUpdateTemporaryPassword(), onHover: (value) => refreshHover.value = value, @@ -337,7 +340,7 @@ class _DesktopHomePageState extends State } }) ], - ).marginOnly(bottom: 20), + ), ], ), ), @@ -423,15 +426,17 @@ class _DesktopHomePageState extends State }, onHover: (value) => editHover.value = value, child: Obx(() => Icon(Icons.edit, - size: 22, - color: editHover.value - ? MyTheme.color(context).text - : Color(0xFFDDDDDD)))); + size: 22, + color: editHover.value + ? MyTheme.color(context).text + : Color(0xFFDDDDDD)) + .marginOnly(bottom: 8))); } buildTip(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + padding: + const EdgeInsets.only(left: 20.0, right: 16, top: 16.0, bottom: 14), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, @@ -441,53 +446,21 @@ class _DesktopHomePageState extends State style: TextStyle(fontWeight: FontWeight.normal, fontSize: 19), ), SizedBox( - height: 8.0, + height: 10.0, ), Text( translate("desk_tip"), overflow: TextOverflow.clip, style: TextStyle( - fontSize: 12, color: MyTheme.color(context).lighterText), + fontSize: 12, + color: MyTheme.color(context).lighterText, + height: 1.25), ) ], ), ); } - buildControlPanel(BuildContext context) { - return Container( - width: 320, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), color: MyTheme.white), - padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - translate("Control Remote Desktop"), - style: TextStyle(fontWeight: FontWeight.normal, fontSize: 19), - ), - Form( - child: Column( - children: [ - TextFormField( - controller: TextEditingController(), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[0-9]")) - ], - style: TextStyle(fontSize: 22, fontWeight: FontWeight.w400), - ) - ], - )) - ], - ), - ); - } - - buildRecentSession(BuildContext context) { - return Center(child: Text("waiting implementation")); - } - @override void onTrayMenuItemClick(MenuItem menuItem) { print("click ${menuItem.key}"); diff --git a/flutter/lib/desktop/pages/file_manager_tab_page.dart b/flutter/lib/desktop/pages/file_manager_tab_page.dart index 7e94724bb..78f0842ad 100644 --- a/flutter/lib/desktop/pages/file_manager_tab_page.dart +++ b/flutter/lib/desktop/pages/file_manager_tab_page.dart @@ -72,28 +72,33 @@ class _FileManagerTabPageState extends State { Widget build(BuildContext context) { return SubWindowDragToResizeArea( windowId: windowId(), - child: Scaffold( - body: Column( - children: [ - DesktopTabBar( - tabs: tabs, - onTabClose: onRemoveId, - dark: isDarkTheme(), - mainTab: false, - ), - Expanded( - child: Obx( - () => PageView( - controller: DesktopTabBar.controller.value, - children: tabs - .map((tab) => FileManagerPage( - key: ValueKey(tab.label), - id: tab - .label)) //RemotePage(key: ValueKey(e), id: e)) - .toList()), + child: Container( + decoration: BoxDecoration( + border: Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: Column( + children: [ + DesktopTabBar( + tabs: tabs, + onTabClose: onRemoveId, + dark: isDarkTheme(), + mainTab: false, ), - ) - ], + Expanded( + child: Obx( + () => PageView( + controller: DesktopTabBar.controller.value, + children: tabs + .map((tab) => FileManagerPage( + key: ValueKey(tab.label), + id: tab + .label)) //RemotePage(key: ValueKey(e), id: e)) + .toList()), + ), + ) + ], + ), ), ), ); diff --git a/flutter/lib/desktop/pages/server_page.dart b/flutter/lib/desktop/pages/server_page.dart index e8f9ec26b..0023158ca 100644 --- a/flutter/lib/desktop/pages/server_page.dart +++ b/flutter/lib/desktop/pages/server_page.dart @@ -33,14 +33,20 @@ class _DesktopServerPageState extends State ChangeNotifierProvider.value(value: gFFI.chatModel), ], child: Consumer( - builder: (context, serverModel, child) => Material( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded(child: ConnectionManager()), - SizedBox.fromSize(size: Size(0, 15.0)), - ], + builder: (context, serverModel, child) => Container( + decoration: BoxDecoration( + border: + Border.all(color: MyTheme.color(context).border!)), + child: Scaffold( + backgroundColor: MyTheme.color(context).bg, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded(child: ConnectionManager()), + SizedBox.fromSize(size: Size(0, 15.0)), + ], + ), ), ), ))); diff --git a/flutter/lib/desktop/widgets/tabbar_widget.dart b/flutter/lib/desktop/widgets/tabbar_widget.dart index 74019c815..530696a48 100644 --- a/flutter/lib/desktop/widgets/tabbar_widget.dart +++ b/flutter/lib/desktop/widgets/tabbar_widget.dart @@ -249,6 +249,7 @@ class WindowActionPanel extends StatelessWidget { }, is_close: false, )), + // TODO: drag makes window restore Offstage( offstage: !showMaximize, child: FutureBuilder(builder: (context, snapshot) { @@ -273,21 +274,15 @@ class WindowActionPanel extends StatelessWidget { if (is_maximized.value) { windowManager.unmaximize(); } else { - WindowController.fromWindowId(windowId!).minimize(); + windowManager.maximize(); } } else { + // TODO: subwindow is maximized but first query result is not maximized. final wc = WindowController.fromWindowId(windowId!); if (is_maximized.value) { wc.unmaximize(); } else { - final wc = WindowController.fromWindowId(windowId!); - wc.isMaximized().then((maximized) { - if (maximized) { - wc.unmaximize(); - } else { - wc.maximize(); - } - }); + wc.maximize(); } } is_maximized.value = !is_maximized.value;