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