plugin_framework, ui tmp
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
		
							parent
							
								
									9a08e0bed4
								
							
						
					
					
						commit
						1b303b7b27
					
				| @ -2,6 +2,12 @@ import 'dart:convert'; | |||||||
| 
 | 
 | ||||||
| typedef PluginId = String; | typedef PluginId = String; | ||||||
| 
 | 
 | ||||||
|  | // ui location | ||||||
|  | const String kLocationHostMainDisplayOthers = | ||||||
|  |     'host|main|settings|display|others'; | ||||||
|  | const String kLocationClientRemoteToolbarDisplay = | ||||||
|  |     'client|remote|toolbar|display'; | ||||||
|  | 
 | ||||||
| class MsgFromUi { | class MsgFromUi { | ||||||
|   String remotePeerId; |   String remotePeerId; | ||||||
|   String localPeerId; |   String localPeerId; | ||||||
							
								
								
									
										44
									
								
								flutter/lib/desktop/plugin/model.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								flutter/lib/desktop/plugin/model.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import './common.dart'; | ||||||
|  | import './desc.dart'; | ||||||
|  | 
 | ||||||
|  | final Map<String, LocationModel> locationModels = {}; | ||||||
|  | 
 | ||||||
|  | class PluginModel with ChangeNotifier { | ||||||
|  |   final List<UiType> uiList = []; | ||||||
|  | 
 | ||||||
|  |   void add(UiType ui) { | ||||||
|  |     uiList.add(ui); | ||||||
|  |     notifyListeners(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   bool get isEmpty => uiList.isEmpty; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class LocationModel with ChangeNotifier { | ||||||
|  |   final Map<PluginId, PluginModel> pluginModels = {}; | ||||||
|  | 
 | ||||||
|  |   void add(PluginId id, UiType ui) { | ||||||
|  |     if (pluginModels[id] != null) { | ||||||
|  |       pluginModels[id]!.add(ui); | ||||||
|  |     } else { | ||||||
|  |       var model = PluginModel(); | ||||||
|  |       model.add(ui); | ||||||
|  |       pluginModels[id] = model; | ||||||
|  |       notifyListeners(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   bool get isEmpty => pluginModels.isEmpty; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void addLocationUi(String location, PluginId id, UiType ui) { | ||||||
|  |   locationModels[location]?.add(id, ui); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | LocationModel addLocation(String location) { | ||||||
|  |   if (locationModels[location] == null) { | ||||||
|  |     locationModels[location] = LocationModel(); | ||||||
|  |   } | ||||||
|  |   return locationModels[location]!; | ||||||
|  | } | ||||||
| @ -5,20 +5,18 @@ import 'package:provider/provider.dart'; | |||||||
| import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart'; | import 'package:flutter_hbb/desktop/widgets/remote_toolbar.dart'; | ||||||
| import 'package:flutter_hbb/models/platform_model.dart'; | import 'package:flutter_hbb/models/platform_model.dart'; | ||||||
| 
 | 
 | ||||||
| import '../../../desc.dart'; | import './desc.dart'; | ||||||
| import '../../../model.dart'; | import './model.dart'; | ||||||
| import '../../../common.dart'; | import './common.dart'; | ||||||
| 
 | 
 | ||||||
| class Display extends StatelessWidget { | class LocationItem extends StatelessWidget { | ||||||
|   final PluginId pluginId; |  | ||||||
|   final String peerId; |   final String peerId; | ||||||
|   final FFI ffi; |   final FFI ffi; | ||||||
|   final String location; |   final String location; | ||||||
|   final LocationModel locationModel; |   final LocationModel locationModel; | ||||||
| 
 | 
 | ||||||
|   Display({ |   LocationItem({ | ||||||
|     Key? key, |     Key? key, | ||||||
|     required this.pluginId, |  | ||||||
|     required this.peerId, |     required this.peerId, | ||||||
|     required this.ffi, |     required this.ffi, | ||||||
|     required this.location, |     required this.location, | ||||||
| @ -27,18 +25,71 @@ class Display extends StatelessWidget { | |||||||
| 
 | 
 | ||||||
|   bool get isEmpty => locationModel.isEmpty; |   bool get isEmpty => locationModel.isEmpty; | ||||||
| 
 | 
 | ||||||
|  |   static LocationItem createLocationItem( | ||||||
|  |       String peerId, FFI ffi, String location) { | ||||||
|  |     final model = addLocation(location); | ||||||
|  |     return LocationItem( | ||||||
|  |       peerId: peerId, | ||||||
|  |       ffi: ffi, | ||||||
|  |       location: location, | ||||||
|  |       locationModel: model, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return ChangeNotifierProvider.value( |     return ChangeNotifierProvider.value( | ||||||
|       value: locationModel, |       value: locationModel, | ||||||
|       child: Consumer<LocationModel>(builder: (context, model, child) { |       child: Consumer<LocationModel>(builder: (context, model, child) { | ||||||
|         return Column( |         return Column( | ||||||
|           children: locationModel.uiList.map((ui) => _buildItem(ui)).toList(), |           children: model.pluginModels.entries | ||||||
|  |               .map((entry) => _buildPluginItem(entry.key, entry.value)) | ||||||
|  |               .toList(), | ||||||
|         ); |         ); | ||||||
|       }), |       }), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   Widget _buildPluginItem(PluginId id, PluginModel model) => PluginItem( | ||||||
|  |         pluginId: id, | ||||||
|  |         peerId: peerId, | ||||||
|  |         ffi: ffi, | ||||||
|  |         location: location, | ||||||
|  |         pluginModel: model, | ||||||
|  |       ); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | class PluginItem extends StatelessWidget { | ||||||
|  |   final PluginId pluginId; | ||||||
|  |   final String peerId; | ||||||
|  |   final FFI ffi; | ||||||
|  |   final String location; | ||||||
|  |   final PluginModel pluginModel; | ||||||
|  | 
 | ||||||
|  |   PluginItem({ | ||||||
|  |     Key? key, | ||||||
|  |     required this.pluginId, | ||||||
|  |     required this.peerId, | ||||||
|  |     required this.ffi, | ||||||
|  |     required this.location, | ||||||
|  |     required this.pluginModel, | ||||||
|  |   }) : super(key: key); | ||||||
|  | 
 | ||||||
|  |   bool get isEmpty => pluginModel.isEmpty; | ||||||
|  | 
 | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return ChangeNotifierProvider.value( | ||||||
|  |       value: pluginModel, | ||||||
|  |       child: Consumer<PluginModel>(builder: (context, model, child) { | ||||||
|  |         return Column( | ||||||
|  |           children: model.uiList.map((ui) => _buildItem(ui)).toList(), | ||||||
|  |         ); | ||||||
|  |       }), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // to-do: add plugin icon and tooltip | ||||||
|   Widget _buildItem(UiType ui) { |   Widget _buildItem(UiType ui) { | ||||||
|     switch (ui.runtimeType) { |     switch (ui.runtimeType) { | ||||||
|       case UiButton: |       case UiButton: | ||||||
| @ -80,7 +131,9 @@ class Display extends StatelessWidget { | |||||||
|           ); |           ); | ||||||
|         }(); |         }(); | ||||||
|       }, |       }, | ||||||
|       // to-do: rustdesk translate or plugin translate ? |       trailingIcon: Icon( | ||||||
|  |           IconData(int.parse(ui.icon, radix: 16), fontFamily: 'MaterialIcons')), | ||||||
|  |       // to-do: RustDesk translate or plugin translate ? | ||||||
|       child: Text(ui.text), |       child: Text(ui.text), | ||||||
|       ffi: ffi, |       ffi: ffi, | ||||||
|     ); |     ); | ||||||
| @ -89,6 +142,10 @@ class Display extends StatelessWidget { | |||||||
|   Widget _buildCheckboxMenuButton(UiCheckbox ui) { |   Widget _buildCheckboxMenuButton(UiCheckbox ui) { | ||||||
|     final v = |     final v = | ||||||
|         bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: ui.key); |         bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: ui.key); | ||||||
|  |     if (v == null) { | ||||||
|  |       // session or plugin not found | ||||||
|  |       return Container(); | ||||||
|  |     } | ||||||
|     return CkbMenuButton( |     return CkbMenuButton( | ||||||
|       value: ConfigItem.isTrue(v), |       value: ConfigItem.isTrue(v), | ||||||
|       onChanged: (v) { |       onChanged: (v) { | ||||||
| @ -108,3 +165,11 @@ class Display extends StatelessWidget { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void handleReloading(Map<String, dynamic> evt, String peer) { | ||||||
|  |   if (evt['id'] == null || evt['location'] == null) { | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |   final ui = UiType.fromJson(evt); | ||||||
|  |   addLocationUi(evt['location']!, evt['id']!, ui); | ||||||
|  | } | ||||||
| @ -8,6 +8,8 @@ import 'package:flutter_hbb/models/chat_model.dart'; | |||||||
| import 'package:flutter_hbb/models/state_model.dart'; | import 'package:flutter_hbb/models/state_model.dart'; | ||||||
| import 'package:flutter_hbb/consts.dart'; | import 'package:flutter_hbb/consts.dart'; | ||||||
| import 'package:flutter_hbb/utils/multi_window_manager.dart'; | import 'package:flutter_hbb/utils/multi_window_manager.dart'; | ||||||
|  | import 'package:flutter_hbb/desktop/plugin/widget.dart'; | ||||||
|  | import 'package:flutter_hbb/desktop/plugin/common.dart'; | ||||||
| import 'package:flutter_svg/flutter_svg.dart'; | import 'package:flutter_svg/flutter_svg.dart'; | ||||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||||
| import 'package:provider/provider.dart'; | import 'package:provider/provider.dart'; | ||||||
| @ -655,13 +657,19 @@ class _DisplayMenu extends StatefulWidget { | |||||||
|   final FFI ffi; |   final FFI ffi; | ||||||
|   final MenubarState state; |   final MenubarState state; | ||||||
|   final Function(bool) setFullscreen; |   final Function(bool) setFullscreen; | ||||||
|  |   final LocationItem pluginItem; | ||||||
|   _DisplayMenu( |   _DisplayMenu( | ||||||
|       {Key? key, |       {Key? key, | ||||||
|       required this.id, |       required this.id, | ||||||
|       required this.ffi, |       required this.ffi, | ||||||
|       required this.state, |       required this.state, | ||||||
|       required this.setFullscreen}) |       required this.setFullscreen}) | ||||||
|       : super(key: key); |       : pluginItem = LocationItem.createLocationItem( | ||||||
|  |           id, | ||||||
|  |           ffi, | ||||||
|  |           kLocationClientRemoteToolbarDisplay, | ||||||
|  |         ), | ||||||
|  |         super(key: key); | ||||||
| 
 | 
 | ||||||
|   @override |   @override | ||||||
|   State<_DisplayMenu> createState() => _DisplayMenuState(); |   State<_DisplayMenu> createState() => _DisplayMenuState(); | ||||||
| @ -699,6 +707,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { | |||||||
|           resolutions(), |           resolutions(), | ||||||
|           Divider(), |           Divider(), | ||||||
|           toggles(), |           toggles(), | ||||||
|  |           widget.pluginItem, | ||||||
|         ]); |         ]); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,9 +16,9 @@ import 'package:flutter_hbb/models/peer_tab_model.dart'; | |||||||
| import 'package:flutter_hbb/models/server_model.dart'; | import 'package:flutter_hbb/models/server_model.dart'; | ||||||
| import 'package:flutter_hbb/models/user_model.dart'; | import 'package:flutter_hbb/models/user_model.dart'; | ||||||
| import 'package:flutter_hbb/models/state_model.dart'; | import 'package:flutter_hbb/models/state_model.dart'; | ||||||
| import 'package:flutter_hbb/plugin/event.dart'; | import 'package:flutter_hbb/desktop/plugin/event.dart'; | ||||||
| import 'package:flutter_hbb/plugin/desc.dart'; | import 'package:flutter_hbb/desktop/plugin/desc.dart'; | ||||||
| import 'package:flutter_hbb/plugin/widget.dart'; | import 'package:flutter_hbb/desktop/plugin/widget.dart'; | ||||||
| import 'package:flutter_hbb/common/shared_state.dart'; | import 'package:flutter_hbb/common/shared_state.dart'; | ||||||
| import 'package:tuple/tuple.dart'; | import 'package:tuple/tuple.dart'; | ||||||
| import 'package:image/image.dart' as img2; | import 'package:image/image.dart' as img2; | ||||||
|  | |||||||
| @ -1,30 +0,0 @@ | |||||||
| import 'package:flutter/material.dart'; |  | ||||||
| import './common.dart'; |  | ||||||
| import './desc.dart'; |  | ||||||
| 
 |  | ||||||
| // ui location |  | ||||||
| // host|main|settings|display|others |  | ||||||
| // client|remote|toolbar|display |  | ||||||
| 
 |  | ||||||
| final Map<PluginId, Map<String, LocationModel>> locationModels = {}; |  | ||||||
| 
 |  | ||||||
| class LocationModel with ChangeNotifier { |  | ||||||
|   final List<UiType> uiList = []; |  | ||||||
| 
 |  | ||||||
|   void add(UiType ui) { |  | ||||||
|     uiList.add(ui); |  | ||||||
|     notifyListeners(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   bool get isEmpty => uiList.isEmpty; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void addLocation(PluginId id, String location, UiType ui) { |  | ||||||
|   if (!locationModels.containsKey(id)) { |  | ||||||
|     locationModels[id] = {}; |  | ||||||
|   } |  | ||||||
|   if (!locationModels[id]!.containsKey(location)) { |  | ||||||
|     locationModels[id]![location] = LocationModel(); |  | ||||||
|   } |  | ||||||
|   locationModels[id]![location]!.add(ui); |  | ||||||
| } |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| import 'package:flutter/material.dart'; |  | ||||||
| import './desc.dart'; |  | ||||||
| import './model.dart'; |  | ||||||
| 
 |  | ||||||
| final Map<String, PluginWidget> pluginWidgets = {}; |  | ||||||
| 
 |  | ||||||
| class PluginWidget { |  | ||||||
|   final String id; |  | ||||||
|   final String name; |  | ||||||
|   final String location; |  | ||||||
|   final Widget widget; |  | ||||||
| 
 |  | ||||||
|   PluginWidget({ |  | ||||||
|     required this.id, |  | ||||||
|     required this.name, |  | ||||||
|     required this.location, |  | ||||||
|     required this.widget, |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   // static Widget createButton(UiButton btn) {} |  | ||||||
| 
 |  | ||||||
|   // static Widget createCheckbox(UiCheckbox chk) {} |  | ||||||
| 
 |  | ||||||
|   // // ui location |  | ||||||
|   // // host|main|settings|display|others |  | ||||||
|   // // client|remote|toolbar|display |  | ||||||
|   // static Widget? create(String id, String locatin, UiType ui) { |  | ||||||
|   //   if (ui.button != null) { |  | ||||||
|   //     return createButton(ui.button!); |  | ||||||
|   //   } else if (ui.checkbox != null) { |  | ||||||
|   //     return createCheckbox(ui.checkbox!); |  | ||||||
|   //   } else { |  | ||||||
|   //     return null; |  | ||||||
|   //   } |  | ||||||
|   // } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void handleReloading(Map<String, dynamic> evt, String peer) { |  | ||||||
|   if (evt['id'] == null || evt['location'] == null) { |  | ||||||
|     return; |  | ||||||
|   } |  | ||||||
|   final ui = UiType.fromJson(evt); |  | ||||||
|   addLocation(evt['id']!, evt['location']!, ui); |  | ||||||
| } |  | ||||||
| @ -1406,7 +1406,7 @@ pub fn plugin_event(_id: String, _event: Vec<u8>) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| pub fn plugin_get_session_option(_id: String, _peer: String, _key: String) -> SyncReturn<String> { | pub fn plugin_get_session_option(_id: String, _peer: String, _key: String) -> SyncReturn<Option<String>> { | ||||||
|     #[cfg(feature = "plugin_framework")] |     #[cfg(feature = "plugin_framework")] | ||||||
|     #[cfg(not(any(target_os = "android", target_os = "ios")))] |     #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||||
|     { |     { | ||||||
| @ -1417,7 +1417,9 @@ pub fn plugin_get_session_option(_id: String, _peer: String, _key: String) -> Sy | |||||||
|         target_os = "android", |         target_os = "android", | ||||||
|         target_os = "ios" |         target_os = "ios" | ||||||
|     ))] |     ))] | ||||||
|     return SyncReturn("".to_owned()); |     { | ||||||
|  |         return SyncReturn(None); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| @ -1430,18 +1432,20 @@ pub fn plugin_set_session_option(_id: String, _peer: String, _key: String, _valu | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
| pub fn plugin_get_local_option(_id: String, _key: String) -> SyncReturn<String> { | pub fn plugin_get_local_option(_id: String, _key: String) -> SyncReturn<Option<String>> { | ||||||
|     #[cfg(feature = "plugin_framework")] |     #[cfg(feature = "plugin_framework")] | ||||||
|     #[cfg(not(any(target_os = "android", target_os = "ios")))] |     #[cfg(not(any(target_os = "android", target_os = "ios")))] | ||||||
|     { |     { | ||||||
|         allow_err!(crate::plugin::LocalConfig::get(&_id, &key)); |         return SyncReturn(crate::plugin::LocalConfig::get(&_id, &_key)); | ||||||
|     } |     } | ||||||
|     #[cfg(any(
 |     #[cfg(any(
 | ||||||
|         not(feature = "plugin_framework"), |         not(feature = "plugin_framework"), | ||||||
|         target_os = "android", |         target_os = "android", | ||||||
|         target_os = "ios" |         target_os = "ios" | ||||||
|     ))] |     ))] | ||||||
|     return SyncReturn("".to_owned()); |     { | ||||||
|  |         return SyncReturn(None); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[inline] | #[inline] | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ use std::ffi::{c_char, CStr}; | |||||||
| pub struct UiButton { | pub struct UiButton { | ||||||
|     key: String, |     key: String, | ||||||
|     text: String, |     text: String, | ||||||
|     icon: String, |     icon: String,   // icon can be int in flutter, but string in other ui framework. And it is flexible to use string.
 | ||||||
|     tooltip: String, |     tooltip: String, | ||||||
|     action: String, // The action to be triggered when the button is clicked.
 |     action: String, // The action to be triggered when the button is clicked.
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user