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,48 +266,63 @@ class _RemotePageState extends State<RemotePage> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Row(children: [ Row(
IconButton( children: <Widget>[
color: Colors.white, IconButton(
icon: Icon(Icons.clear), color: Colors.white,
onPressed: () { icon: Icon(Icons.clear),
close(); onPressed: () {
}, close();
), },
IconButton( )
color: Colors.white, ] +
icon: Icon(Icons.keyboard), (isDesktop
onPressed: openKeyboard), ? []
IconButton( : [
color: Colors.white, IconButton(
icon: Icon(Icons.tv), color: Colors.white,
onPressed: () { icon: Icon(Icons.keyboard),
setState(() => _showEdit = false); onPressed: openKeyboard)
showOptions(context); ]) +
}, <Widget>[
), IconButton(
Container( color: Colors.white,
color: _mouseTools ? Colors.blue[500] : null, icon: Icon(Icons.tv),
child: IconButton( onPressed: () {
color: Colors.white, setState(() => _showEdit = false);
icon: Icon(Icons.mouse), showOptions(context);
onPressed: () { },
setState(() { )
_mouseTools = !_mouseTools; ] +
resetTool(); (isDesktop
if (_mouseTools) _drag = true; ? []
}); : [
}, Container(
)), color: _mouseTools
IconButton( ? Colors.blue[500]
color: Colors.white, : null,
icon: Icon(Icons.more_vert), child: IconButton(
onPressed: () { color: Colors.white,
setState(() => _showEdit = false); icon: Icon(Icons.mouse),
showActions(context); onPressed: () {
}, setState(() {
), _mouseTools = !_mouseTools;
]), resetTool();
if (_mouseTools) _drag = true;
});
},
))
]) +
<Widget>[
IconButton(
color: Colors.white,
icon: Icon(Icons.more_vert),
onPressed: () {
setState(() => _showEdit = false);
showActions(context);
},
),
]),
IconButton( IconButton(
color: Colors.white, color: Colors.white,
icon: Icon(Icons.expand_more), icon: Icon(Icons.expand_more),
@ -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,38 +453,57 @@ class _RemotePageState extends State<RemotePage> {
) )
])), ])),
value: 'enter_os_password')); value: 'enter_os_password'));
more.add(PopupMenuItem<String>( if (!isDesktop) {
child: Row( if (perms['keyboard'] != false && perms['clipboard'] != false) {
children: ([ more.add(PopupMenuItem<String>(
Container(width: 100.0, child: Text(translate('Touch mode'))), child: Text(translate('Paste')), value: 'paste'));
Padding(padding: EdgeInsets.symmetric(horizontal: 16.0)), }
Icon( more.add(PopupMenuItem<String>(
_touchMode child: Row(
? Icons.check_box_outlined children: ([
: Icons.check_box_outline_blank, Container(width: 100.0, child: Text(translate('Touch mode'))),
color: MyTheme.accent) Padding(padding: EdgeInsets.symmetric(horizontal: 16.0)),
])), Icon(
value: 'touch_mode')); _touchMode
more.add(PopupMenuItem<String>( ? Icons.check_box_outlined
child: Text(translate('Reset canvas')), value: 'reset_canvas')); : Icons.check_box_outline_blank,
color: MyTheme.accent)
])),
value: 'touch_mode'));
more.add(PopupMenuItem<String>(
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 +
(isDesktop
? <Widget>[
getRadio(
'Original', 'original', viewStyle, setViewStyle),
getRadio('Shrink', 'shrink', viewStyle, setViewStyle),
getRadio('Stretch', 'stretch', viewStyle, setViewStyle),
Divider(color: MyTheme.border),
]
: {}) +
<Widget>[ <Widget>[
RadioListTile<String>( getRadio('Good image quality', 'best', quality, setQuality),
controlAffinity: ListTileControlAffinity.trailing, getRadio('Balanced', 'balanced', quality, setQuality),
title: Text(translate('Good image quality')), getRadio(
value: 'best', 'Optimize reaction time', 'low', quality, setQuality),
groupValue: quality,
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( getToggle(
value: FFI.getByName( setState, 'show-remote-cursor', 'Show remote cursor'),
'toggle_option', 'show-remote-cursor') ==
'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', 'show-remote-cursor');
});
},
title: Text(translate('Show remote cursor'))),
] + ] +
more), more),
null); null);