refactor tabbar: Homepage adaptation
1. remove redundant MaterialApp in GetMaterialApp 2. unified background color Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
parent
1440d26376
commit
c799fb1857
@ -2,3 +2,5 @@ const double kDesktopRemoteTabBarHeight = 48.0;
|
|||||||
const String kAppTypeMain = "main";
|
const String kAppTypeMain = "main";
|
||||||
const String kAppTypeDesktopRemote = "remote";
|
const String kAppTypeDesktopRemote = "remote";
|
||||||
const String kAppTypeDesktopFileTransfer = "file transfer";
|
const String kAppTypeDesktopFileTransfer = "file transfer";
|
||||||
|
const String kTabLabelHomePage = "Home";
|
||||||
|
const String kTabLabelSettingPage = "Settings";
|
||||||
|
@ -57,7 +57,6 @@ class _ConnectionPageState extends State<ConnectionPage> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(color: isDarkTheme() ? null : MyTheme.grayBg),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
@ -84,11 +84,14 @@ class _ConnectionTabPageState extends State<ConnectionTabPage>
|
|||||||
children: [
|
children: [
|
||||||
Obx(() => DesktopTabBar(
|
Obx(() => DesktopTabBar(
|
||||||
controller: tabController,
|
controller: tabController,
|
||||||
tabs: connectionIds.toList(),
|
tabs: connectionIds
|
||||||
|
.map((e) =>
|
||||||
|
TabInfo(label: e, icon: Icons.desktop_windows_sharp))
|
||||||
|
.toList(),
|
||||||
onTabClose: onRemoveId,
|
onTabClose: onRemoveId,
|
||||||
tabIcon: Icons.desktop_windows_sharp,
|
|
||||||
selected: _selected,
|
selected: _selected,
|
||||||
dark: isDarkTheme(),
|
dark: isDarkTheme(),
|
||||||
|
mainTab: false,
|
||||||
)),
|
)),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Obx(() => TabBarView(
|
child: Obx(() => TabBarView(
|
||||||
|
@ -6,7 +6,6 @@ import 'package:flutter/material.dart' hide MenuItem;
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hbb/common.dart';
|
import 'package:flutter_hbb/common.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
|
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
|
||||||
import 'package:flutter_hbb/desktop/widgets/titlebar_widget.dart';
|
|
||||||
import 'package:flutter_hbb/models/platform_model.dart';
|
import 'package:flutter_hbb/models/platform_model.dart';
|
||||||
import 'package:flutter_hbb/models/server_model.dart';
|
import 'package:flutter_hbb/models/server_model.dart';
|
||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
||||||
@ -46,38 +45,17 @@ class _DesktopHomePageState extends State<DesktopHomePage>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Row(
|
||||||
body: Column(
|
children: [
|
||||||
children: [
|
Flexible(
|
||||||
DesktopTitleBar(
|
child: buildServerInfo(context),
|
||||||
child: Center(
|
flex: 1,
|
||||||
child: Text(
|
),
|
||||||
"RustDesk",
|
Flexible(
|
||||||
style: TextStyle(
|
child: buildServerBoard(context),
|
||||||
color: Colors.white,
|
flex: 4,
|
||||||
fontSize: 20,
|
),
|
||||||
fontWeight: FontWeight.bold),
|
],
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Container(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
child: buildServerInfo(context),
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
Flexible(
|
|
||||||
child: buildServerBoard(context),
|
|
||||||
flex: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
flutter/lib/desktop/pages/desktop_setting_page.dart
Normal file
15
flutter/lib/desktop/pages/desktop_setting_page.dart
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
class DesktopSettingPage extends StatefulWidget {
|
||||||
|
DesktopSettingPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DesktopSettingPage> createState() => _DesktopSettingPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopSettingPageState extends State<DesktopSettingPage> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text("Settings");
|
||||||
|
}
|
||||||
|
}
|
88
flutter/lib/desktop/pages/desktop_tab_page.dart
Normal file
88
flutter/lib/desktop/pages/desktop_tab_page.dart
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hbb/common.dart';
|
||||||
|
import 'package:flutter_hbb/consts.dart';
|
||||||
|
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
|
||||||
|
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
|
||||||
|
import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class DesktopTabPage extends StatefulWidget {
|
||||||
|
const DesktopTabPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DesktopTabPage> createState() => _DesktopTabPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DesktopTabPageState extends State<DesktopTabPage>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late Rx<TabController> tabController;
|
||||||
|
late RxList<TabInfo> tabs;
|
||||||
|
static final Rx<int> _selected = 0.obs;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
tabs = RxList.from([
|
||||||
|
TabInfo(label: kTabLabelHomePage, icon: Icons.home_sharp, closable: false)
|
||||||
|
], growable: true);
|
||||||
|
tabController =
|
||||||
|
TabController(length: tabs.length, vsync: this, initialIndex: 0).obs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Obx((() => DesktopTabBar(
|
||||||
|
controller: tabController,
|
||||||
|
tabs: tabs.toList(),
|
||||||
|
onTabClose: onTabClose,
|
||||||
|
selected: _selected,
|
||||||
|
dark: isDarkTheme(),
|
||||||
|
mainTab: true,
|
||||||
|
onMenu: onTabbarMenu,
|
||||||
|
))),
|
||||||
|
Obx((() => Expanded(
|
||||||
|
child: TabBarView(
|
||||||
|
controller: tabController.value,
|
||||||
|
children: tabs.map((tab) {
|
||||||
|
switch (tab.label) {
|
||||||
|
case kTabLabelHomePage:
|
||||||
|
return DesktopHomePage(key: ValueKey(tab.label));
|
||||||
|
case kTabLabelSettingPage:
|
||||||
|
return DesktopSettingPage(key: ValueKey(tab.label));
|
||||||
|
default:
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
}).toList()),
|
||||||
|
))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTabClose(String label) {
|
||||||
|
tabs.removeWhere((tab) => tab.label == label);
|
||||||
|
tabController.value = TabController(
|
||||||
|
length: tabs.length,
|
||||||
|
vsync: this,
|
||||||
|
initialIndex: max(0, tabs.length - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void onTabbarMenu() {
|
||||||
|
int index = tabs.indexWhere((tab) => tab.label == kTabLabelSettingPage);
|
||||||
|
if (index >= 0) {
|
||||||
|
tabController.value.animateTo(index, duration: Duration.zero);
|
||||||
|
_selected.value = index;
|
||||||
|
} else {
|
||||||
|
tabs.add(TabInfo(label: kTabLabelSettingPage, icon: Icons.settings));
|
||||||
|
tabController.value = TabController(
|
||||||
|
length: tabs.length, vsync: this, initialIndex: tabs.length - 1);
|
||||||
|
tabController.value.animateTo(tabs.length - 1, duration: Duration.zero);
|
||||||
|
_selected.value = tabs.length - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -73,7 +73,6 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
backgroundColor: isDarkTheme() ? MyTheme.dark : MyTheme.grayBg,
|
|
||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
Flexible(flex: 3, child: body(isLocal: true)),
|
Flexible(flex: 3, child: body(isLocal: true)),
|
||||||
|
@ -82,11 +82,13 @@ class _FileManagerTabPageState extends State<FileManagerTabPage>
|
|||||||
Obx(
|
Obx(
|
||||||
() => DesktopTabBar(
|
() => DesktopTabBar(
|
||||||
controller: tabController,
|
controller: tabController,
|
||||||
tabs: connectionIds.toList(),
|
tabs: connectionIds
|
||||||
|
.map((e) => TabInfo(label: e, icon: Icons.file_copy_sharp))
|
||||||
|
.toList(),
|
||||||
onTabClose: onRemoveId,
|
onTabClose: onRemoveId,
|
||||||
tabIcon: Icons.file_copy_sharp,
|
|
||||||
selected: _selected,
|
selected: _selected,
|
||||||
dark: isDarkTheme(),
|
dark: isDarkTheme(),
|
||||||
|
mainTab: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
@ -263,7 +263,6 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
OverlayEntry(builder: (context) {
|
OverlayEntry(builder: (context) {
|
||||||
_ffi.chatModel.setOverlayState(Overlay.of(context));
|
_ffi.chatModel.setOverlayState(Overlay.of(context));
|
||||||
return Container(
|
return Container(
|
||||||
color: Colors.black,
|
|
||||||
child: getRawPointerAndKeyBody(getBodyForDesktop(keyboard)));
|
child: getRawPointerAndKeyBody(getBodyForDesktop(keyboard)));
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
@ -500,25 +499,20 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
|
|
||||||
Widget getBodyForDesktop(bool keyboard) {
|
Widget getBodyForDesktop(bool keyboard) {
|
||||||
var paints = <Widget>[
|
var paints = <Widget>[
|
||||||
MouseRegion(
|
MouseRegion(onEnter: (evt) {
|
||||||
onEnter: (evt) {
|
bind.hostStopSystemKeyPropagate(stopped: false);
|
||||||
bind.hostStopSystemKeyPropagate(stopped: false);
|
}, onExit: (evt) {
|
||||||
},
|
bind.hostStopSystemKeyPropagate(stopped: true);
|
||||||
onExit: (evt) {
|
}, child: Container(
|
||||||
bind.hostStopSystemKeyPropagate(stopped: true);
|
child: LayoutBuilder(builder: (context, constraints) {
|
||||||
},
|
Future.delayed(Duration.zero, () {
|
||||||
child: Container(
|
Provider.of<CanvasModel>(context, listen: false).updateViewStyle();
|
||||||
color: MyTheme.canvasColor,
|
});
|
||||||
child: LayoutBuilder(builder: (context, constraints) {
|
return ImagePaint(
|
||||||
Future.delayed(Duration.zero, () {
|
id: widget.id,
|
||||||
Provider.of<CanvasModel>(context, listen: false)
|
);
|
||||||
.updateViewStyle();
|
}),
|
||||||
});
|
))
|
||||||
return ImagePaint(
|
|
||||||
id: widget.id,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
))
|
|
||||||
];
|
];
|
||||||
final cursor = bind.getSessionToggleOptionSync(
|
final cursor = bind.getSessionToggleOptionSync(
|
||||||
id: widget.id, arg: 'show-remote-cursor');
|
id: widget.id, arg: 'show-remote-cursor');
|
||||||
|
@ -20,27 +20,11 @@ class DesktopFileTransferScreen extends StatelessWidget {
|
|||||||
ChangeNotifierProvider.value(value: gFFI.cursorModel),
|
ChangeNotifierProvider.value(value: gFFI.cursorModel),
|
||||||
ChangeNotifierProvider.value(value: gFFI.canvasModel),
|
ChangeNotifierProvider.value(value: gFFI.canvasModel),
|
||||||
],
|
],
|
||||||
child: MaterialApp(
|
child: Scaffold(
|
||||||
navigatorKey: globalKey,
|
body: FileManagerTabPage(
|
||||||
debugShowCheckedModeBanner: false,
|
params: params,
|
||||||
title: 'RustDesk - File Transfer',
|
),
|
||||||
theme: ThemeData(
|
),
|
||||||
primarySwatch: Colors.blue,
|
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
|
||||||
),
|
|
||||||
home: FileManagerTabPage(
|
|
||||||
params: params,
|
|
||||||
),
|
|
||||||
navigatorObservers: [
|
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
|
||||||
FlutterSmartDialog.observer
|
|
||||||
],
|
|
||||||
builder: FlutterSmartDialog.init(
|
|
||||||
builder: isAndroid
|
|
||||||
? (_, child) => AccessibilityListener(
|
|
||||||
child: child,
|
|
||||||
)
|
|
||||||
: null)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,33 +13,16 @@ class DesktopRemoteScreen extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
ChangeNotifierProvider.value(value: gFFI.ffiModel),
|
ChangeNotifierProvider.value(value: gFFI.ffiModel),
|
||||||
ChangeNotifierProvider.value(value: gFFI.imageModel),
|
ChangeNotifierProvider.value(value: gFFI.imageModel),
|
||||||
ChangeNotifierProvider.value(value: gFFI.cursorModel),
|
ChangeNotifierProvider.value(value: gFFI.cursorModel),
|
||||||
ChangeNotifierProvider.value(value: gFFI.canvasModel),
|
ChangeNotifierProvider.value(value: gFFI.canvasModel),
|
||||||
],
|
],
|
||||||
child: MaterialApp(
|
child: Scaffold(
|
||||||
navigatorKey: globalKey,
|
body: ConnectionTabPage(
|
||||||
debugShowCheckedModeBanner: false,
|
|
||||||
title: 'RustDesk - Remote Desktop',
|
|
||||||
theme: ThemeData(
|
|
||||||
primarySwatch: Colors.blue,
|
|
||||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
|
||||||
),
|
|
||||||
home: ConnectionTabPage(
|
|
||||||
params: params,
|
params: params,
|
||||||
),
|
),
|
||||||
navigatorObservers: [
|
));
|
||||||
// FirebaseAnalyticsObserver(analytics: analytics),
|
|
||||||
FlutterSmartDialog.observer
|
|
||||||
],
|
|
||||||
builder: FlutterSmartDialog.init(
|
|
||||||
builder: isAndroid
|
|
||||||
? (_, child) => AccessibilityListener(
|
|
||||||
child: child,
|
|
||||||
)
|
|
||||||
: null)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,76 +12,109 @@ const double _kIconSize = 18;
|
|||||||
const double _kDividerIndent = 10;
|
const double _kDividerIndent = 10;
|
||||||
const double _kAddIconSize = _kTabBarHeight - 15;
|
const double _kAddIconSize = _kTabBarHeight - 15;
|
||||||
|
|
||||||
|
class TabInfo {
|
||||||
|
late final String label;
|
||||||
|
late final IconData icon;
|
||||||
|
late final bool closable;
|
||||||
|
|
||||||
|
TabInfo({required this.label, required this.icon, this.closable = true});
|
||||||
|
}
|
||||||
|
|
||||||
class DesktopTabBar extends StatelessWidget {
|
class DesktopTabBar extends StatelessWidget {
|
||||||
late final Rx<TabController> controller;
|
late final Rx<TabController> controller;
|
||||||
late final List<String> tabs;
|
late final List<TabInfo> tabs;
|
||||||
late final Function(String) onTabClose;
|
late final Function(String) onTabClose;
|
||||||
late final IconData tabIcon;
|
|
||||||
late final Rx<int> selected;
|
late final Rx<int> selected;
|
||||||
late final bool dark;
|
late final bool dark;
|
||||||
late final _Theme _theme;
|
late final _Theme _theme;
|
||||||
|
late final bool mainTab;
|
||||||
|
late final Function()? onMenu;
|
||||||
|
|
||||||
DesktopTabBar(
|
DesktopTabBar({
|
||||||
{Key? key,
|
Key? key,
|
||||||
required this.controller,
|
required this.controller,
|
||||||
required this.tabs,
|
required this.tabs,
|
||||||
required this.onTabClose,
|
required this.onTabClose,
|
||||||
required this.tabIcon,
|
required this.selected,
|
||||||
required this.selected,
|
required this.dark,
|
||||||
required this.dark})
|
required this.mainTab,
|
||||||
: _theme = dark ? _Theme.dark() : _Theme.light(),
|
this.onMenu,
|
||||||
|
}) : _theme = dark ? _Theme.dark() : _Theme.light(),
|
||||||
super(key: key);
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
height: _kTabBarHeight,
|
height: _kTabBarHeight,
|
||||||
child: Scaffold(
|
child: Row(
|
||||||
backgroundColor: _theme.bgColor,
|
children: [
|
||||||
body: Row(
|
Expanded(
|
||||||
children: [
|
child: Row(
|
||||||
Flexible(
|
children: [
|
||||||
child: Obx(() => TabBar(
|
Offstage(
|
||||||
indicator: BoxDecoration(),
|
offstage: !mainTab,
|
||||||
indicatorColor: Colors.transparent,
|
child: Row(children: [
|
||||||
labelPadding:
|
Image.asset('assets/logo.ico'),
|
||||||
const EdgeInsets.symmetric(vertical: 0, horizontal: 0),
|
Text("RustDesk"),
|
||||||
isScrollable: true,
|
]).paddingSymmetric(horizontal: 12, vertical: 5),
|
||||||
physics: BouncingScrollPhysics(),
|
),
|
||||||
controller: controller.value,
|
Flexible(
|
||||||
tabs: tabs
|
child: Obx(() => TabBar(
|
||||||
.asMap()
|
indicator: BoxDecoration(),
|
||||||
.entries
|
indicatorColor: Colors.transparent,
|
||||||
.map((e) => _Tab(
|
labelPadding: const EdgeInsets.symmetric(
|
||||||
index: e.key,
|
vertical: 0, horizontal: 0),
|
||||||
text: e.value,
|
isScrollable: true,
|
||||||
icon: tabIcon,
|
indicatorWeight: 0.1,
|
||||||
selected: selected.value,
|
physics: BouncingScrollPhysics(),
|
||||||
onClose: () {
|
controller: controller.value,
|
||||||
onTabClose(e.value);
|
tabs: tabs.asMap().entries.map((e) {
|
||||||
if (e.key <= selected.value) {
|
int index = e.key;
|
||||||
selected.value = max(0, selected.value - 1);
|
String label = e.value.label;
|
||||||
}
|
|
||||||
controller.value.animateTo(selected.value,
|
return _Tab(
|
||||||
duration: Duration.zero);
|
index: index,
|
||||||
},
|
label: label,
|
||||||
onSelected: () {
|
icon: e.value.icon,
|
||||||
selected.value = e.key;
|
closable: e.value.closable,
|
||||||
controller.value
|
selected: selected.value,
|
||||||
.animateTo(e.key, duration: Duration.zero);
|
onClose: () {
|
||||||
},
|
onTabClose(label);
|
||||||
theme: _theme,
|
if (index <= selected.value) {
|
||||||
))
|
selected.value = max(0, selected.value - 1);
|
||||||
.toList())),
|
}
|
||||||
|
controller.value.animateTo(selected.value,
|
||||||
|
duration: Duration.zero);
|
||||||
|
},
|
||||||
|
onSelected: () {
|
||||||
|
selected.value = index;
|
||||||
|
controller.value
|
||||||
|
.animateTo(index, duration: Duration.zero);
|
||||||
|
},
|
||||||
|
theme: _theme,
|
||||||
|
);
|
||||||
|
}).toList())),
|
||||||
|
),
|
||||||
|
Offstage(
|
||||||
|
offstage: mainTab,
|
||||||
|
child: _AddButton(
|
||||||
|
theme: _theme,
|
||||||
|
).paddingOnly(left: 10),
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
),
|
||||||
padding: EdgeInsets.only(left: 10),
|
Offstage(
|
||||||
child: _AddButton(
|
offstage: onMenu == null,
|
||||||
theme: _theme,
|
child: InkWell(
|
||||||
|
child: Icon(
|
||||||
|
Icons.menu,
|
||||||
|
color: _theme.unSelectedIconColor,
|
||||||
),
|
),
|
||||||
),
|
onTap: () => onMenu?.call(),
|
||||||
],
|
).paddingOnly(right: 10),
|
||||||
),
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -89,8 +122,9 @@ class DesktopTabBar extends StatelessWidget {
|
|||||||
|
|
||||||
class _Tab extends StatelessWidget {
|
class _Tab extends StatelessWidget {
|
||||||
late final int index;
|
late final int index;
|
||||||
late final String text;
|
late final String label;
|
||||||
late final IconData icon;
|
late final IconData icon;
|
||||||
|
late final bool closable;
|
||||||
late final int selected;
|
late final int selected;
|
||||||
late final Function() onClose;
|
late final Function() onClose;
|
||||||
late final Function() onSelected;
|
late final Function() onSelected;
|
||||||
@ -100,8 +134,9 @@ class _Tab extends StatelessWidget {
|
|||||||
_Tab(
|
_Tab(
|
||||||
{Key? key,
|
{Key? key,
|
||||||
required this.index,
|
required this.index,
|
||||||
required this.text,
|
required this.label,
|
||||||
required this.icon,
|
required this.icon,
|
||||||
|
required this.closable,
|
||||||
required this.selected,
|
required this.selected,
|
||||||
required this.onClose,
|
required this.onClose,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
@ -114,7 +149,6 @@ class _Tab extends StatelessWidget {
|
|||||||
bool show_divider = index != selected - 1 && index != selected;
|
bool show_divider = index != selected - 1 && index != selected;
|
||||||
return Ink(
|
return Ink(
|
||||||
width: _kTabFixedWidth,
|
width: _kTabFixedWidth,
|
||||||
color: is_selected ? theme.tabSelectedColor : null,
|
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onHover: (hover) => _hover.value = hover,
|
onHover: (hover) => _hover.value = hover,
|
||||||
onTap: () => onSelected(),
|
onTap: () => onSelected(),
|
||||||
@ -126,17 +160,16 @@ class _Tab extends StatelessWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Icon(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 5),
|
icon,
|
||||||
child: Icon(
|
size: _kIconSize,
|
||||||
icon,
|
color: is_selected
|
||||||
size: _kIconSize,
|
? theme.selectedtabIconColor
|
||||||
color: theme.tabIconColor,
|
: theme.unSelectedtabIconColor,
|
||||||
),
|
).paddingSymmetric(horizontal: 5),
|
||||||
),
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
text,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: is_selected
|
color: is_selected
|
||||||
? theme.selectedTextColor
|
? theme.selectedTextColor
|
||||||
@ -144,7 +177,7 @@ class _Tab extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Obx((() => _CloseButton(
|
Obx((() => _CloseButton(
|
||||||
tabHovered: _hover.value,
|
visiable: _hover.value && closable,
|
||||||
tabSelected: is_selected,
|
tabSelected: is_selected,
|
||||||
onClose: () => onClose(),
|
onClose: () => onClose(),
|
||||||
theme: theme,
|
theme: theme,
|
||||||
@ -195,14 +228,14 @@ class _AddButton extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _CloseButton extends StatelessWidget {
|
class _CloseButton extends StatelessWidget {
|
||||||
final bool tabHovered;
|
final bool visiable;
|
||||||
final bool tabSelected;
|
final bool tabSelected;
|
||||||
final Function onClose;
|
final Function onClose;
|
||||||
late final _Theme theme;
|
late final _Theme theme;
|
||||||
|
|
||||||
_CloseButton({
|
_CloseButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.tabHovered,
|
required this.visiable,
|
||||||
required this.tabSelected,
|
required this.tabSelected,
|
||||||
required this.onClose,
|
required this.onClose,
|
||||||
required this.theme,
|
required this.theme,
|
||||||
@ -210,31 +243,28 @@ class _CloseButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return SizedBox(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 5),
|
width: _kIconSize,
|
||||||
child: SizedBox(
|
child: Offstage(
|
||||||
width: _kIconSize,
|
offstage: !visiable,
|
||||||
child: Offstage(
|
child: InkWell(
|
||||||
offstage: !tabHovered,
|
customBorder: RoundedRectangleBorder(),
|
||||||
child: InkWell(
|
onTap: () => onClose(),
|
||||||
customBorder: RoundedRectangleBorder(),
|
child: Icon(
|
||||||
onTap: () => onClose(),
|
Icons.close,
|
||||||
child: Icon(
|
size: _kIconSize,
|
||||||
Icons.close,
|
color: tabSelected
|
||||||
size: _kIconSize,
|
? theme.selectedIconColor
|
||||||
color: tabSelected
|
: theme.unSelectedIconColor,
|
||||||
? theme.selectedIconColor
|
),
|
||||||
: theme.unSelectedIconColor,
|
),
|
||||||
),
|
)).paddingSymmetric(horizontal: 5);
|
||||||
),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Theme {
|
class _Theme {
|
||||||
late Color bgColor;
|
late Color unSelectedtabIconColor;
|
||||||
late Color tabSelectedColor;
|
late Color selectedtabIconColor;
|
||||||
late Color tabIconColor;
|
|
||||||
late Color selectedTextColor;
|
late Color selectedTextColor;
|
||||||
late Color unSelectedTextColor;
|
late Color unSelectedTextColor;
|
||||||
late Color selectedIconColor;
|
late Color selectedIconColor;
|
||||||
@ -242,9 +272,8 @@ class _Theme {
|
|||||||
late Color dividerColor;
|
late Color dividerColor;
|
||||||
|
|
||||||
_Theme.light() {
|
_Theme.light() {
|
||||||
bgColor = Color.fromARGB(255, 253, 253, 253);
|
unSelectedtabIconColor = Color.fromARGB(255, 162, 203, 241);
|
||||||
tabSelectedColor = MyTheme.grayBg;
|
selectedtabIconColor = MyTheme.accent;
|
||||||
tabIconColor = MyTheme.accent50;
|
|
||||||
selectedTextColor = Color.fromARGB(255, 26, 26, 26);
|
selectedTextColor = Color.fromARGB(255, 26, 26, 26);
|
||||||
unSelectedTextColor = Color.fromARGB(255, 96, 96, 96);
|
unSelectedTextColor = Color.fromARGB(255, 96, 96, 96);
|
||||||
selectedIconColor = Color.fromARGB(255, 26, 26, 26);
|
selectedIconColor = Color.fromARGB(255, 26, 26, 26);
|
||||||
@ -253,9 +282,8 @@ class _Theme {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_Theme.dark() {
|
_Theme.dark() {
|
||||||
bgColor = Color.fromARGB(255, 50, 50, 50);
|
unSelectedtabIconColor = Color.fromARGB(255, 30, 65, 98);
|
||||||
tabSelectedColor = MyTheme.canvasColor;
|
selectedtabIconColor = MyTheme.accent;
|
||||||
tabIconColor = Color.fromARGB(255, 84, 197, 248);
|
|
||||||
selectedTextColor = Color.fromARGB(255, 255, 255, 255);
|
selectedTextColor = Color.fromARGB(255, 255, 255, 255);
|
||||||
unSelectedTextColor = Color.fromARGB(255, 207, 207, 207);
|
unSelectedTextColor = Color.fromARGB(255, 207, 207, 207);
|
||||||
selectedIconColor = Color.fromARGB(255, 215, 215, 215);
|
selectedIconColor = Color.fromARGB(255, 215, 215, 215);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
|
import 'package:flutter_hbb/desktop/pages/desktop_tab_page.dart';
|
||||||
import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart';
|
import 'package:flutter_hbb/desktop/screen/desktop_file_transfer_screen.dart';
|
||||||
import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
|
import 'package:flutter_hbb/desktop/screen/desktop_remote_screen.dart';
|
||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
import 'package:flutter_hbb/utils/multi_window_manager.dart';
|
||||||
@ -86,18 +86,44 @@ void runMainApp(bool startService) async {
|
|||||||
void runRemoteScreen(Map<String, dynamic> argument) async {
|
void runRemoteScreen(Map<String, dynamic> argument) async {
|
||||||
await initEnv(kAppTypeDesktopRemote);
|
await initEnv(kAppTypeDesktopRemote);
|
||||||
runApp(GetMaterialApp(
|
runApp(GetMaterialApp(
|
||||||
|
navigatorKey: globalKey,
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
title: 'RustDesk - Remote Desktop',
|
||||||
theme: getCurrentTheme(),
|
theme: getCurrentTheme(),
|
||||||
home: DesktopRemoteScreen(
|
home: DesktopRemoteScreen(
|
||||||
params: argument,
|
params: argument,
|
||||||
),
|
),
|
||||||
|
navigatorObservers: [
|
||||||
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
|
FlutterSmartDialog.observer
|
||||||
|
],
|
||||||
|
builder: FlutterSmartDialog.init(
|
||||||
|
builder: isAndroid
|
||||||
|
? (_, child) => AccessibilityListener(
|
||||||
|
child: child,
|
||||||
|
)
|
||||||
|
: null),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void runFileTransferScreen(Map<String, dynamic> argument) async {
|
void runFileTransferScreen(Map<String, dynamic> argument) async {
|
||||||
await initEnv(kAppTypeDesktopFileTransfer);
|
await initEnv(kAppTypeDesktopFileTransfer);
|
||||||
runApp(GetMaterialApp(
|
runApp(GetMaterialApp(
|
||||||
|
navigatorKey: globalKey,
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
title: 'RustDesk - File Transfer',
|
||||||
theme: getCurrentTheme(),
|
theme: getCurrentTheme(),
|
||||||
home: DesktopFileTransferScreen(params: argument)));
|
home: DesktopFileTransferScreen(params: argument),
|
||||||
|
navigatorObservers: [
|
||||||
|
// FirebaseAnalyticsObserver(analytics: analytics),
|
||||||
|
FlutterSmartDialog.observer
|
||||||
|
],
|
||||||
|
builder: FlutterSmartDialog.init(
|
||||||
|
builder: isAndroid
|
||||||
|
? (_, child) => AccessibilityListener(
|
||||||
|
child: child,
|
||||||
|
)
|
||||||
|
: null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
class App extends StatelessWidget {
|
class App extends StatelessWidget {
|
||||||
@ -121,7 +147,7 @@ class App extends StatelessWidget {
|
|||||||
title: 'RustDesk',
|
title: 'RustDesk',
|
||||||
theme: getCurrentTheme(),
|
theme: getCurrentTheme(),
|
||||||
home: isDesktop
|
home: isDesktop
|
||||||
? DesktopHomePage()
|
? DesktopTabPage()
|
||||||
: !isAndroid
|
: !isAndroid
|
||||||
? WebHomePage()
|
? WebHomePage()
|
||||||
: HomePage(),
|
: HomePage(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user