more menu items

This commit is contained in:
rustdesk 2022-02-02 00:46:21 +08:00
parent 98434eb11e
commit 3e7c20f303
2 changed files with 175 additions and 135 deletions

View File

@ -16,6 +16,7 @@ class FfiModel with ChangeNotifier {
var _decoding = false; var _decoding = false;
bool _waitForImage; bool _waitForImage;
bool _initialized = false; bool _initialized = false;
var _inputBlocked = false;
final _permissions = Map<String, bool>(); final _permissions = Map<String, bool>();
bool _secure; bool _secure;
bool _direct; bool _direct;
@ -26,6 +27,11 @@ class FfiModel with ChangeNotifier {
get secure => _secure; get secure => _secure;
get direct => _direct; get direct => _direct;
get pi => _pi; get pi => _pi;
get inputBlocked => _inputBlocked;
set inputBlocked(v) {
_inputBlocked = v;
}
FfiModel() { FfiModel() {
Translator.call = translate; Translator.call = translate;
@ -54,6 +60,7 @@ class FfiModel with ChangeNotifier {
_waitForImage = false; _waitForImage = false;
_secure = null; _secure = null;
_direct = null; _direct = null;
_inputBlocked = false;
clearPermissions(); clearPermissions();
} }
@ -79,6 +86,7 @@ class FfiModel with ChangeNotifier {
} }
void clearPermissions() { void clearPermissions() {
_inputBlocked = false;
_permissions.clear(); _permissions.clear();
} }

View File

@ -266,18 +266,25 @@ class _RemotePageState extends State<RemotePage> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Row(children: [ Row(
children: <Widget>[
IconButton( IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.clear), icon: Icon(Icons.clear),
onPressed: () { onPressed: () {
close(); close();
}, },
), )
] +
(isDesktop
? []
: [
IconButton( IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.keyboard), icon: Icon(Icons.keyboard),
onPressed: openKeyboard), onPressed: openKeyboard)
]) +
<Widget>[
IconButton( IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.tv), icon: Icon(Icons.tv),
@ -285,9 +292,15 @@ class _RemotePageState extends State<RemotePage> {
setState(() => _showEdit = false); setState(() => _showEdit = false);
showOptions(context); showOptions(context);
}, },
), )
] +
(isDesktop
? []
: [
Container( Container(
color: _mouseTools ? Colors.blue[500] : null, color: _mouseTools
? Colors.blue[500]
: null,
child: IconButton( child: IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.mouse), icon: Icon(Icons.mouse),
@ -298,7 +311,9 @@ class _RemotePageState extends State<RemotePage> {
if (_mouseTools) _drag = true; if (_mouseTools) _drag = true;
}); });
}, },
)), ))
]) +
<Widget>[
IconButton( IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.more_vert), icon: Icon(Icons.more_vert),
@ -418,15 +433,12 @@ class _RemotePageState extends State<RemotePage> {
final x = 120.0; final x = 120.0;
final y = size.height; final y = size.height;
final more = <PopupMenuItem<String>>[]; final more = <PopupMenuItem<String>>[];
if (FFI.ffiModel.pi.version.isNotEmpty) { final pi = FFI.ffiModel.pi;
final perms = FFI.ffiModel.permissions;
if (pi.version.isNotEmpty) {
more.add(PopupMenuItem<String>( more.add(PopupMenuItem<String>(
child: Text(translate('Refresh')), value: 'refresh')); child: Text(translate('Refresh')), value: 'refresh'));
} }
if (FFI.ffiModel.permissions['keyboard'] != false &&
FFI.ffiModel.permissions['clipboard'] != false) {
more.add(PopupMenuItem<String>(
child: Text(translate('Paste')), value: 'paste'));
}
more.add(PopupMenuItem<String>( more.add(PopupMenuItem<String>(
child: Row( child: Row(
children: ([ children: ([
@ -441,6 +453,11 @@ class _RemotePageState extends State<RemotePage> {
) )
])), ])),
value: 'enter_os_password')); value: 'enter_os_password'));
if (!isDesktop) {
if (perms['keyboard'] != false && perms['clipboard'] != false) {
more.add(PopupMenuItem<String>(
child: Text(translate('Paste')), value: 'paste'));
}
more.add(PopupMenuItem<String>( more.add(PopupMenuItem<String>(
child: Row( child: Row(
children: ([ children: ([
@ -455,24 +472,38 @@ class _RemotePageState extends State<RemotePage> {
value: 'touch_mode')); value: 'touch_mode'));
more.add(PopupMenuItem<String>( more.add(PopupMenuItem<String>(
child: Text(translate('Reset canvas')), value: 'reset_canvas')); child: Text(translate('Reset canvas')), value: 'reset_canvas'));
}
if (perms['keyboard'] != false) {
if (pi.platform == 'Linux' || pi.sasEnabled) {
more.add(PopupMenuItem<String>(
child: Text(translate('Insert') + ' Ctrl + Alt + Del'),
value: 'cad'));
}
more.add(PopupMenuItem<String>(
child: Text(translate('Insert Lock')), value: 'lock'));
if (pi.platform == 'Windows' &&
FFI.getByName('toggle_option', 'privacy-mode') != 'true') {
more.add(PopupMenuItem<String>(
child: Text(translate(
(FFI.ffiModel.inputBlocked ? 'Unb' : 'B') + 'lock user input')),
value: 'block-input'));
}
}
() async { () async {
var value = await showMenu( var value = await showMenu(
context: context, context: context,
position: RelativeRect.fromLTRB(x, y, x, y), position: RelativeRect.fromLTRB(x, y, x, y),
items: [ items: more,
PopupMenuItem<String>(
child: Text(translate('Insert') + ' Ctrl + Alt + Del'),
value: 'cad'),
PopupMenuItem<String>(
child: Text(translate('Insert Lock')), value: 'lock'),
] +
more,
elevation: 8, elevation: 8,
); );
if (value == 'cad') { if (value == 'cad') {
FFI.setByName('ctrl_alt_del'); FFI.setByName('ctrl_alt_del');
} else if (value == 'lock') { } else if (value == 'lock') {
FFI.setByName('lock_screen'); FFI.setByName('lock_screen');
} else if (value == 'block-input') {
FFI.setByName('toggle_option',
(FFI.ffiModel.inputBlocked ? 'un' : '') + 'block-inpu');
FFI.ffiModel.inputBlocked = !FFI.ffiModel.inputBlocked;
} else if (value == 'refresh') { } else if (value == 'refresh') {
FFI.setByName('refresh'); FFI.setByName('refresh');
} else if (value == 'paste') { } else if (value == 'paste') {
@ -796,9 +827,36 @@ void wrongPasswordDialog(String id, BuildContext context) {
])); ]));
} }
CheckboxListTile getToggle(
void Function(void Function()) setState, option, name) {
return CheckboxListTile(
value: FFI.getByName('toggle_option', option) == 'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', option);
});
},
dense: true,
title: Text(translate(name)));
}
RadioListTile<String> getRadio(String name, String toValue, String curValue,
void Function(String) onChange) {
return RadioListTile<String>(
controlAffinity: ListTileControlAffinity.trailing,
title: Text(translate(name)),
value: toValue,
groupValue: curValue,
onChanged: onChange,
dense: true,
);
}
void showOptions(BuildContext context) { void showOptions(BuildContext context) {
String quality = FFI.getByName('image_quality'); String quality = FFI.getByName('image_quality');
if (quality == '') quality = 'balanced'; if (quality == '') quality = 'balanced';
String viewStyle = FFI.getByName('peer_option', 'view-style');
if (viewStyle == '') viewStyle = 'original';
var displays = <Widget>[]; var displays = <Widget>[];
final pi = FFI.ffiModel.pi; final pi = FFI.ffiModel.pi;
final image = FFI.ffiModel.getConnectionImage(); final image = FFI.ffiModel.getConnectionImage();
@ -835,82 +893,56 @@ void showOptions(BuildContext context) {
if (displays.isNotEmpty) { if (displays.isNotEmpty) {
displays.add(Divider(color: MyTheme.border)); displays.add(Divider(color: MyTheme.border));
} }
final perms = FFI.ffiModel.permissions;
showAlertDialog(context, (setState) { showAlertDialog(context, (setState) {
final more = <Widget>[]; final more = <Widget>[];
if (FFI.ffiModel.permissions['audio'] != false) { if (perms['audio'] != false) {
more.add(CheckboxListTile( more.add(getToggle(setState, 'disable-audio', 'Mute'));
value: FFI.getByName('toggle_option', 'disable-audio') == 'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', 'disable-audio');
});
},
title: Text(translate('Mute'))));
} }
if (FFI.ffiModel.permissions['keyboard'] != false) { if (perms['keyboard'] != false) {
more.add(CheckboxListTile( if (perms['clipboard'] != false)
value: FFI.getByName('toggle_option', 'lock-after-session-end') == more.add(getToggle(setState, 'disable-clipboard', 'Disable clipboard'));
'true', more.add(getToggle(
onChanged: (v) { setState, 'lock-after-session-end', 'Lock after session end'));
setState(() { if (pi.platform == 'Windows') {
FFI.setByName('toggle_option', 'lock-after-session-end'); more.add(getToggle(setState, 'privacy-mode', 'Privacy mode'));
});
},
title: Text(translate('Lock after session end'))));
} }
}
var setQuality = (String value) {
setState(() {
quality = value;
FFI.setByName('image_quality', value);
});
};
var setViewStyle = (String value) {
setState(() {
viewStyle = value;
FFI.setByName(
'peer_option', '{"name": "view-style", "value": "$value"}');
});
};
return Tuple3( return Tuple3(
null, null,
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: displays + children: displays +
<Widget>[ (isDesktop
RadioListTile<String>( ? <Widget>[
controlAffinity: ListTileControlAffinity.trailing, getRadio(
title: Text(translate('Good image quality')), 'Original', 'original', viewStyle, setViewStyle),
value: 'best', getRadio('Shrink', 'shrink', viewStyle, setViewStyle),
groupValue: quality, getRadio('Stretch', 'stretch', viewStyle, setViewStyle),
onChanged: (String value) {
setState(() {
quality = value;
FFI.setByName('image_quality', value);
});
},
),
RadioListTile<String>(
controlAffinity: ListTileControlAffinity.trailing,
title: Text(translate('Balanced')),
value: 'balanced',
groupValue: quality,
onChanged: (String value) {
setState(() {
quality = value;
FFI.setByName('image_quality', value);
});
},
),
RadioListTile<String>(
controlAffinity: ListTileControlAffinity.trailing,
title: Text(translate('Optimize reaction time')),
value: 'low',
groupValue: quality,
onChanged: (String value) {
setState(() {
quality = value;
FFI.setByName('image_quality', value);
});
},
),
Divider(color: MyTheme.border), Divider(color: MyTheme.border),
CheckboxListTile( ]
value: FFI.getByName( : {}) +
'toggle_option', 'show-remote-cursor') == <Widget>[
'true', getRadio('Good image quality', 'best', quality, setQuality),
onChanged: (v) { getRadio('Balanced', 'balanced', quality, setQuality),
setState(() { getRadio(
FFI.setByName('toggle_option', 'show-remote-cursor'); 'Optimize reaction time', 'low', quality, setQuality),
}); Divider(color: MyTheme.border),
}, getToggle(
title: Text(translate('Show remote cursor'))), setState, 'show-remote-cursor', 'Show remote cursor'),
] + ] +
more), more),
null); null);