flutter_desktop: remote menubar remove submenu
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
f42c6ffeaf
commit
4d914e9a01
@ -97,15 +97,18 @@ class MenuConfig {
|
||||
}
|
||||
|
||||
abstract class MenuEntryBase<T> {
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf);
|
||||
List<mod_menu.PopupMenuEntry<T>> build(BuildContext context, MenuConfig conf);
|
||||
}
|
||||
|
||||
class MenuEntryDivider<T> extends MenuEntryBase<T> {
|
||||
@override
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf) {
|
||||
return mod_menu.PopupMenuDivider(
|
||||
height: conf.dividerHeight,
|
||||
);
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return [
|
||||
mod_menu.PopupMenuDivider(
|
||||
height: conf.dividerHeight,
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,6 +116,85 @@ typedef RadioOptionsGetter = List<Tuple2<String, String>> Function();
|
||||
typedef RadioCurOptionGetter = Future<String> Function();
|
||||
typedef RadioOptionSetter = Future<void> Function(String);
|
||||
|
||||
class MenuEntryRadioUtils<T> {}
|
||||
|
||||
class MenuEntryRadios<T> extends MenuEntryBase<T> {
|
||||
final String text;
|
||||
final RadioOptionsGetter optionsGetter;
|
||||
final RadioCurOptionGetter curOptionGetter;
|
||||
final RadioOptionSetter optionSetter;
|
||||
final RxString _curOption = "".obs;
|
||||
|
||||
MenuEntryRadios(
|
||||
{required this.text,
|
||||
required this.optionsGetter,
|
||||
required this.curOptionGetter,
|
||||
required this.optionSetter}) {
|
||||
() async {
|
||||
_curOption.value = await curOptionGetter();
|
||||
}();
|
||||
}
|
||||
|
||||
List<Tuple2<String, String>> get options => optionsGetter();
|
||||
RxString get curOption => _curOption;
|
||||
setOption(String option) async {
|
||||
await optionSetter(option);
|
||||
final opt = await curOptionGetter();
|
||||
if (_curOption.value != opt) {
|
||||
_curOption.value = opt;
|
||||
}
|
||||
}
|
||||
|
||||
mod_menu.PopupMenuEntry<T> _buildMenuItem(
|
||||
BuildContext context, MenuConfig conf, Tuple2<String, String> opt) {
|
||||
return mod_menu.PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
child: TextButton(
|
||||
child: Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
opt.item1,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: SizedBox(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
child: Obx(() => opt.item2 == curOption.value
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: conf.commonColor,
|
||||
)
|
||||
: const SizedBox.shrink())),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
if (opt.item2 != curOption.value) {
|
||||
setOption(opt.item2);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return options.map((opt) => _buildMenuItem(context, conf, opt)).toList();
|
||||
}
|
||||
}
|
||||
|
||||
class MenuEntrySubRadios<T> extends MenuEntryBase<T> {
|
||||
final String text;
|
||||
final RadioOptionsGetter optionsGetter;
|
||||
@ -151,23 +233,26 @@ class MenuEntrySubRadios<T> extends MenuEntryBase<T> {
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
child: Obx(() => opt.item2 == curOption.value
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: conf.commonColor,
|
||||
)
|
||||
: const SizedBox.shrink())),
|
||||
const SizedBox(width: MenuConfig.midPadding),
|
||||
Text(
|
||||
opt.item1,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
)
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: SizedBox(
|
||||
width: 20.0,
|
||||
height: 20.0,
|
||||
child: Obx(() => opt.item2 == curOption.value
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: conf.commonColor,
|
||||
)
|
||||
: const SizedBox.shrink())),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -181,31 +266,34 @@ class MenuEntrySubRadios<T> extends MenuEntryBase<T> {
|
||||
}
|
||||
|
||||
@override
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf) {
|
||||
return PopupMenuChildrenItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
itemBuilder: (BuildContext context) =>
|
||||
options.map((opt) => _buildSecondMenu(context, conf, opt)).toList(),
|
||||
child: Row(children: [
|
||||
const SizedBox(width: MenuConfig.midPadding),
|
||||
Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: conf.commonColor,
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return [
|
||||
PopupMenuChildrenItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
itemBuilder: (BuildContext context) =>
|
||||
options.map((opt) => _buildSecondMenu(context, conf, opt)).toList(),
|
||||
child: Row(children: [
|
||||
const SizedBox(width: MenuConfig.midPadding),
|
||||
Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
),
|
||||
))
|
||||
]),
|
||||
);
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: conf.commonColor,
|
||||
),
|
||||
))
|
||||
]),
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,35 +309,38 @@ abstract class MenuEntrySwitchBase<T> extends MenuEntryBase<T> {
|
||||
Future<void> setOption(bool option);
|
||||
|
||||
@override
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf) {
|
||||
return mod_menu.PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
child: Obx(
|
||||
() => SwitchListTile(
|
||||
value: curOption.value,
|
||||
onChanged: (v) {
|
||||
setOption(v);
|
||||
},
|
||||
title: Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
)),
|
||||
dense: true,
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return [
|
||||
mod_menu.PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
child: Obx(
|
||||
() => SwitchListTile(
|
||||
value: curOption.value,
|
||||
onChanged: (v) {
|
||||
setOption(v);
|
||||
},
|
||||
title: Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
)),
|
||||
dense: true,
|
||||
visualDensity: const VisualDensity(
|
||||
horizontal: VisualDensity.minimumDensity,
|
||||
vertical: VisualDensity.minimumDensity,
|
||||
),
|
||||
contentPadding: const EdgeInsets.only(left: 8.0),
|
||||
),
|
||||
contentPadding: const EdgeInsets.only(left: 8.0),
|
||||
),
|
||||
),
|
||||
);
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,32 +398,37 @@ class MenuEntrySubMenu<T> extends MenuEntryBase<T> {
|
||||
});
|
||||
|
||||
@override
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf) {
|
||||
return PopupMenuChildrenItem(
|
||||
height: conf.height,
|
||||
padding: EdgeInsets.zero,
|
||||
position: mod_menu.PopupMenuPosition.overSide,
|
||||
itemBuilder: (BuildContext context) =>
|
||||
entries.map((entry) => entry.build(context, conf)).toList(),
|
||||
child: Row(children: [
|
||||
const SizedBox(width: MenuConfig.midPadding),
|
||||
Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
),
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: conf.commonColor,
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return [
|
||||
PopupMenuChildrenItem(
|
||||
height: conf.height,
|
||||
padding: EdgeInsets.zero,
|
||||
position: mod_menu.PopupMenuPosition.overSide,
|
||||
itemBuilder: (BuildContext context) => entries
|
||||
.map((entry) => entry.build(context, conf))
|
||||
.expand((i) => i)
|
||||
.toList(),
|
||||
child: Row(children: [
|
||||
const SizedBox(width: MenuConfig.midPadding),
|
||||
Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
),
|
||||
))
|
||||
]),
|
||||
);
|
||||
Expanded(
|
||||
child: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Icon(
|
||||
Icons.keyboard_arrow_right,
|
||||
color: conf.commonColor,
|
||||
),
|
||||
))
|
||||
]),
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,24 +442,27 @@ class MenuEntryButton<T> extends MenuEntryBase<T> {
|
||||
});
|
||||
|
||||
@override
|
||||
mod_menu.PopupMenuEntry<T> build(BuildContext context, MenuConfig conf) {
|
||||
return mod_menu.PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
child: TextButton(
|
||||
child: Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: childBuilder(
|
||||
const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
)),
|
||||
onPressed: () {
|
||||
proc();
|
||||
},
|
||||
),
|
||||
);
|
||||
List<mod_menu.PopupMenuEntry<T>> build(
|
||||
BuildContext context, MenuConfig conf) {
|
||||
return [
|
||||
mod_menu.PopupMenuItem(
|
||||
padding: EdgeInsets.zero,
|
||||
height: conf.height,
|
||||
child: TextButton(
|
||||
child: Container(
|
||||
alignment: AlignmentDirectional.centerStart,
|
||||
constraints: BoxConstraints(minHeight: conf.height),
|
||||
child: childBuilder(
|
||||
const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: MenuConfig.fontSize,
|
||||
fontWeight: FontWeight.normal),
|
||||
)),
|
||||
onPressed: () {
|
||||
proc();
|
||||
},
|
||||
),
|
||||
)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -236,6 +236,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
height: _MenubarTheme.height,
|
||||
dividerHeight: _MenubarTheme.dividerHeight,
|
||||
)))
|
||||
.expand((i) => i)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
@ -258,6 +259,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
height: _MenubarTheme.height,
|
||||
dividerHeight: _MenubarTheme.dividerHeight,
|
||||
)))
|
||||
.expand((i) => i)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
@ -401,7 +403,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
|
||||
List<MenuEntryBase<String>> _getDisplayMenu() {
|
||||
final displayMenu = [
|
||||
MenuEntrySubRadios<String>(
|
||||
MenuEntryRadios<String>(
|
||||
text: translate('Ratio'),
|
||||
optionsGetter: () => [
|
||||
Tuple2<String, String>(translate('Original'), 'original'),
|
||||
@ -418,7 +420,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
id: widget.id, name: "view-style", value: v);
|
||||
widget.ffi.canvasModel.updateViewStyle();
|
||||
}),
|
||||
MenuEntrySubRadios<String>(
|
||||
MenuEntryDivider<String>(),
|
||||
MenuEntryRadios<String>(
|
||||
text: translate('Scroll Style'),
|
||||
optionsGetter: () => [
|
||||
Tuple2<String, String>(translate('ScrollAuto'), 'scrollauto'),
|
||||
@ -434,7 +437,8 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
id: widget.id, name: "scroll-style", value: v);
|
||||
widget.ffi.canvasModel.updateScrollStyle();
|
||||
}),
|
||||
MenuEntrySubRadios<String>(
|
||||
MenuEntryDivider<String>(),
|
||||
MenuEntryRadios<String>(
|
||||
text: translate('Image Quality'),
|
||||
optionsGetter: () => [
|
||||
Tuple2<String, String>(translate('Good image quality'), 'best'),
|
||||
@ -451,6 +455,7 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
|
||||
optionSetter: (String v) async {
|
||||
await bind.sessionSetImageQuality(id: widget.id, value: v);
|
||||
}),
|
||||
MenuEntryDivider<String>(),
|
||||
MenuEntrySwitch<String>(
|
||||
text: translate('Show remote cursor'),
|
||||
getter: () async {
|
||||
|
@ -40,10 +40,7 @@ dependencies:
|
||||
url_launcher: ^6.0.9
|
||||
shared_preferences: ^2.0.6
|
||||
toggle_switch: ^1.4.0
|
||||
dash_chat_2:
|
||||
git:
|
||||
url: https://github.com/fufesou/Dash-Chat-2
|
||||
ref: feat_maxWidth
|
||||
dash_chat_2: ^0.0.14
|
||||
draggable_float_widget: ^0.0.2
|
||||
settings_ui: ^2.0.2
|
||||
flutter_breadcrumb: ^1.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user