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; | ||||
| 
 | ||||
| // ui location | ||||
| const String kLocationHostMainDisplayOthers = | ||||
|     'host|main|settings|display|others'; | ||||
| const String kLocationClientRemoteToolbarDisplay = | ||||
|     'client|remote|toolbar|display'; | ||||
| 
 | ||||
| class MsgFromUi { | ||||
|   String remotePeerId; | ||||
|   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/models/platform_model.dart'; | ||||
| 
 | ||||
| import '../../../desc.dart'; | ||||
| import '../../../model.dart'; | ||||
| import '../../../common.dart'; | ||||
| import './desc.dart'; | ||||
| import './model.dart'; | ||||
| import './common.dart'; | ||||
| 
 | ||||
| class Display extends StatelessWidget { | ||||
|   final PluginId pluginId; | ||||
| class LocationItem extends StatelessWidget { | ||||
|   final String peerId; | ||||
|   final FFI ffi; | ||||
|   final String location; | ||||
|   final LocationModel locationModel; | ||||
| 
 | ||||
|   Display({ | ||||
|   LocationItem({ | ||||
|     Key? key, | ||||
|     required this.pluginId, | ||||
|     required this.peerId, | ||||
|     required this.ffi, | ||||
|     required this.location, | ||||
| @ -27,18 +25,71 @@ class Display extends StatelessWidget { | ||||
| 
 | ||||
|   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 | ||||
|   Widget build(BuildContext context) { | ||||
|     return ChangeNotifierProvider.value( | ||||
|       value: locationModel, | ||||
|       child: Consumer<LocationModel>(builder: (context, model, child) { | ||||
|         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) { | ||||
|     switch (ui.runtimeType) { | ||||
|       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), | ||||
|       ffi: ffi, | ||||
|     ); | ||||
| @ -89,6 +142,10 @@ class Display extends StatelessWidget { | ||||
|   Widget _buildCheckboxMenuButton(UiCheckbox ui) { | ||||
|     final v = | ||||
|         bind.pluginGetSessionOption(id: pluginId, peer: peerId, key: ui.key); | ||||
|     if (v == null) { | ||||
|       // session or plugin not found | ||||
|       return Container(); | ||||
|     } | ||||
|     return CkbMenuButton( | ||||
|       value: ConfigItem.isTrue(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/consts.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:get/get.dart'; | ||||
| import 'package:provider/provider.dart'; | ||||
| @ -655,13 +657,19 @@ class _DisplayMenu extends StatefulWidget { | ||||
|   final FFI ffi; | ||||
|   final MenubarState state; | ||||
|   final Function(bool) setFullscreen; | ||||
|   final LocationItem pluginItem; | ||||
|   _DisplayMenu( | ||||
|       {Key? key, | ||||
|       required this.id, | ||||
|       required this.ffi, | ||||
|       required this.state, | ||||
|       required this.setFullscreen}) | ||||
|       : super(key: key); | ||||
|       : pluginItem = LocationItem.createLocationItem( | ||||
|           id, | ||||
|           ffi, | ||||
|           kLocationClientRemoteToolbarDisplay, | ||||
|         ), | ||||
|         super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   State<_DisplayMenu> createState() => _DisplayMenuState(); | ||||
| @ -699,6 +707,7 @@ class _DisplayMenuState extends State<_DisplayMenu> { | ||||
|           resolutions(), | ||||
|           Divider(), | ||||
|           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/user_model.dart'; | ||||
| import 'package:flutter_hbb/models/state_model.dart'; | ||||
| import 'package:flutter_hbb/plugin/event.dart'; | ||||
| import 'package:flutter_hbb/plugin/desc.dart'; | ||||
| import 'package:flutter_hbb/plugin/widget.dart'; | ||||
| import 'package:flutter_hbb/desktop/plugin/event.dart'; | ||||
| import 'package:flutter_hbb/desktop/plugin/desc.dart'; | ||||
| import 'package:flutter_hbb/desktop/plugin/widget.dart'; | ||||
| import 'package:flutter_hbb/common/shared_state.dart'; | ||||
| import 'package:tuple/tuple.dart'; | ||||
| 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] | ||||
| 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(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 = "ios" | ||||
|     ))] | ||||
|     return SyncReturn("".to_owned()); | ||||
|     { | ||||
|         return SyncReturn(None); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[inline] | ||||
| @ -1430,18 +1432,20 @@ pub fn plugin_set_session_option(_id: String, _peer: String, _key: String, _valu | ||||
| } | ||||
| 
 | ||||
| #[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(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(
 | ||||
|         not(feature = "plugin_framework"), | ||||
|         target_os = "android", | ||||
|         target_os = "ios" | ||||
|     ))] | ||||
|     return SyncReturn("".to_owned()); | ||||
|     { | ||||
|         return SyncReturn(None); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[inline] | ||||
|  | ||||
| @ -8,7 +8,7 @@ use std::ffi::{c_char, CStr}; | ||||
| pub struct UiButton { | ||||
|     key: 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, | ||||
|     action: String, // The action to be triggered when the button is clicked.
 | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user