more menu items
This commit is contained in:
		
							parent
							
								
									98434eb11e
								
							
						
					
					
						commit
						3e7c20f303
					
				| @ -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(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user