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

View File

@ -266,48 +266,63 @@ class _RemotePageState extends State<RemotePage> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(children: [
IconButton(
color: Colors.white,
icon: Icon(Icons.clear),
onPressed: () {
close();
},
),
IconButton(
color: Colors.white,
icon: Icon(Icons.keyboard),
onPressed: openKeyboard),
IconButton(
color: Colors.white,
icon: Icon(Icons.tv),
onPressed: () {
setState(() => _showEdit = false);
showOptions(context);
},
),
Container(
color: _mouseTools ? Colors.blue[500] : null,
child: IconButton(
color: Colors.white,
icon: Icon(Icons.mouse),
onPressed: () {
setState(() {
_mouseTools = !_mouseTools;
resetTool();
if (_mouseTools) _drag = true;
});
},
)),
IconButton(
color: Colors.white,
icon: Icon(Icons.more_vert),
onPressed: () {
setState(() => _showEdit = false);
showActions(context);
},
),
]),
Row(
children: <Widget>[
IconButton(
color: Colors.white,
icon: Icon(Icons.clear),
onPressed: () {
close();
},
)
] +
(isDesktop
? []
: [
IconButton(
color: Colors.white,
icon: Icon(Icons.keyboard),
onPressed: openKeyboard)
]) +
<Widget>[
IconButton(
color: Colors.white,
icon: Icon(Icons.tv),
onPressed: () {
setState(() => _showEdit = false);
showOptions(context);
},
)
] +
(isDesktop
? []
: [
Container(
color: _mouseTools
? Colors.blue[500]
: null,
child: IconButton(
color: Colors.white,
icon: Icon(Icons.mouse),
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(
color: Colors.white,
icon: Icon(Icons.expand_more),
@ -418,15 +433,12 @@ class _RemotePageState extends State<RemotePage> {
final x = 120.0;
final y = size.height;
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>(
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>(
child: Row(
children: ([
@ -441,38 +453,57 @@ class _RemotePageState extends State<RemotePage> {
)
])),
value: 'enter_os_password'));
more.add(PopupMenuItem<String>(
child: Row(
children: ([
Container(width: 100.0, child: Text(translate('Touch mode'))),
Padding(padding: EdgeInsets.symmetric(horizontal: 16.0)),
Icon(
_touchMode
? Icons.check_box_outlined
: Icons.check_box_outline_blank,
color: MyTheme.accent)
])),
value: 'touch_mode'));
more.add(PopupMenuItem<String>(
child: Text(translate('Reset canvas')), value: 'reset_canvas'));
if (!isDesktop) {
if (perms['keyboard'] != false && perms['clipboard'] != false) {
more.add(PopupMenuItem<String>(
child: Text(translate('Paste')), value: 'paste'));
}
more.add(PopupMenuItem<String>(
child: Row(
children: ([
Container(width: 100.0, child: Text(translate('Touch mode'))),
Padding(padding: EdgeInsets.symmetric(horizontal: 16.0)),
Icon(
_touchMode
? Icons.check_box_outlined
: 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 {
var value = await showMenu(
context: context,
position: RelativeRect.fromLTRB(x, y, x, y),
items: [
PopupMenuItem<String>(
child: Text(translate('Insert') + ' Ctrl + Alt + Del'),
value: 'cad'),
PopupMenuItem<String>(
child: Text(translate('Insert Lock')), value: 'lock'),
] +
more,
items: more,
elevation: 8,
);
if (value == 'cad') {
FFI.setByName('ctrl_alt_del');
} else if (value == 'lock') {
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') {
FFI.setByName('refresh');
} 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) {
String quality = FFI.getByName('image_quality');
if (quality == '') quality = 'balanced';
String viewStyle = FFI.getByName('peer_option', 'view-style');
if (viewStyle == '') viewStyle = 'original';
var displays = <Widget>[];
final pi = FFI.ffiModel.pi;
final image = FFI.ffiModel.getConnectionImage();
@ -835,82 +893,56 @@ void showOptions(BuildContext context) {
if (displays.isNotEmpty) {
displays.add(Divider(color: MyTheme.border));
}
final perms = FFI.ffiModel.permissions;
showAlertDialog(context, (setState) {
final more = <Widget>[];
if (FFI.ffiModel.permissions['audio'] != false) {
more.add(CheckboxListTile(
value: FFI.getByName('toggle_option', 'disable-audio') == 'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', 'disable-audio');
});
},
title: Text(translate('Mute'))));
if (perms['audio'] != false) {
more.add(getToggle(setState, 'disable-audio', 'Mute'));
}
if (FFI.ffiModel.permissions['keyboard'] != false) {
more.add(CheckboxListTile(
value: FFI.getByName('toggle_option', 'lock-after-session-end') ==
'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', 'lock-after-session-end');
});
},
title: Text(translate('Lock after session end'))));
if (perms['keyboard'] != false) {
if (perms['clipboard'] != false)
more.add(getToggle(setState, 'disable-clipboard', 'Disable clipboard'));
more.add(getToggle(
setState, 'lock-after-session-end', 'Lock after session end'));
if (pi.platform == 'Windows') {
more.add(getToggle(setState, 'privacy-mode', 'Privacy mode'));
}
}
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(
null,
Column(
mainAxisSize: MainAxisSize.min,
children: displays +
(isDesktop
? <Widget>[
getRadio(
'Original', 'original', viewStyle, setViewStyle),
getRadio('Shrink', 'shrink', viewStyle, setViewStyle),
getRadio('Stretch', 'stretch', viewStyle, setViewStyle),
Divider(color: MyTheme.border),
]
: {}) +
<Widget>[
RadioListTile<String>(
controlAffinity: ListTileControlAffinity.trailing,
title: Text(translate('Good image quality')),
value: 'best',
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);
});
},
),
getRadio('Good image quality', 'best', quality, setQuality),
getRadio('Balanced', 'balanced', quality, setQuality),
getRadio(
'Optimize reaction time', 'low', quality, setQuality),
Divider(color: MyTheme.border),
CheckboxListTile(
value: FFI.getByName(
'toggle_option', 'show-remote-cursor') ==
'true',
onChanged: (v) {
setState(() {
FFI.setByName('toggle_option', 'show-remote-cursor');
});
},
title: Text(translate('Show remote cursor'))),
getToggle(
setState, 'show-remote-cursor', 'Show remote cursor'),
] +
more),
null);