Эх сурвалжийг харах

图片选择器功能实现 & UI数据可绑定reportInfo

loki.wu 2 жил өмнө
parent
commit
698b7940a2

+ 31 - 0
lib/converts/event_type.dart

@@ -0,0 +1,31 @@
+typedef FEventCallback<T> = void Function(Object sender, T e);
+
+class FEventHandler<T> {
+  List<FEventCallback<T>>? _callbacks;
+
+  void emit(Object sender, T e) {
+    if (_callbacks != null && _callbacks!.isNotEmpty) {
+      for (final callback in _callbacks!) {
+        callback.call(sender, e);
+      }
+    }
+  }
+
+  void addListener(FEventCallback<T> callback) {
+    _callbacks ??= [];
+    _callbacks!.add(callback);
+  }
+
+  void removeListener(FEventCallback<T> callback) {
+    if (_callbacks == null) return;
+
+    if (_callbacks!.contains(callback)) {
+      _callbacks!.remove(callback);
+    }
+  }
+
+  void dispose() {
+    _callbacks?.clear();
+    _callbacks = null;
+  }
+}

+ 8 - 6
lib/main.dart

@@ -85,10 +85,10 @@ class _MyHomePageState extends State<MyHomePage> {
             alignment: Alignment.center,
             height: _height,
             width: _width,
-            child: Column(
-              mainAxisAlignment: MainAxisAlignment.center,
-              crossAxisAlignment: CrossAxisAlignment.center,
-              mainAxisSize: MainAxisSize.min,
+            child: ListView(
+              // mainAxisAlignment: MainAxisAlignment.center,
+              // crossAxisAlignment: CrossAxisAlignment.center,
+              // mainAxisSize: MainAxisSize.min,
               children: [
                 ..._header.map((head) {
                   return BlockElementPage(element: head);
@@ -103,7 +103,7 @@ class _MyHomePageState extends State<MyHomePage> {
               ],
             ),
           ),
-          const SizedBox(width: 20),
+          const SizedBox(width: 40),
           Container(
               decoration: _buildDecoration(),
               padding: _padding,
@@ -116,7 +116,9 @@ class _MyHomePageState extends State<MyHomePage> {
                     return MouseRegion(
                       cursor: SystemMouseCursors.click,
                       child: GestureDetector(
-                        onTap: () {},
+                        onTap: () {
+                          ReportInfo.instance.getSelectedInputImage(element);
+                        },
                         child: Container(
                           margin: const EdgeInsets.all(15),
                           child: VidImageView.network(element),

+ 2 - 4
lib/pages/block_element_page.dart

@@ -37,15 +37,13 @@ class _BlockElementState extends State<BlockElementPage> {
   Widget build(BuildContext context) {
     if (_type != null && _type!.name == ElementType.rtTable!.name) {
       RTTable t = widget.element as RTTable;
-      return Container(
-        alignment: Alignment.center,
-        child: RTTablePage(element: t),
-      );
+      return RTTablePage(element: t);
     } else if (_type != null && _type!.name == ElementType.paragraph!.name) {
       final paragraph = widget.element as Paragraph;
       return ParagraphPage(paragraph: paragraph);
     } else if (_type != null && _type!.name == ElementType.imageList!.name) {
       final inputImageList = widget.element as InputImageList;
+
       return RInputImageList(inputImageList);
     }
     return Container(

+ 56 - 3
lib/pages/components/input_imageList.dart

@@ -1,7 +1,10 @@
 import 'package:fis_lib_report/converts/margin_convert.dart';
 import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
+import 'package:fis_lib_report/pages/components/vid_image.dart';
 import 'package:fis_lib_report/pages/helpler.dart';
 import 'package:fis_lib_report/report/inputImageList.dart';
+import 'package:fis_lib_report/report_info/input_image_list_info.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 
@@ -17,14 +20,34 @@ class RInputImageList extends StatefulWidget {
 
 class _RInputImageListState extends State<RInputImageList> {
   final InputImageList inputImageList;
+  InputImageListInfo? inputImageListInfo;
   _RInputImageListState(this.inputImageList);
   Color _borderColor = Colors.grey;
   bool _isSelected = false;
   bool _hasImageBorder = false;
+  final List<String> _images = [];
+  double _height = 0.0;
+
+  Widget _child = const Text('请点击此处后选择右侧图片');
 
   @override
   initState() {
     _hasImageBorder = inputImageList.hasImageBorder!;
+    _height = PtToPxConverter.ptToPx(inputImageList.imageHeight) + 6;
+    final element = ReportInfo.instance.getBlockElement(inputImageList);
+    if (element != null) {
+      inputImageListInfo = element as InputImageListInfo;
+      inputImageListInfo!.onSelect!.addListener((sender, e) {
+        setState(() {
+          if (_images.contains(e)) {
+            _images.remove(e);
+          } else {
+            _images.add(e);
+          }
+          _child = _getChild();
+        });
+      });
+    }
     super.initState();
   }
 
@@ -39,17 +62,20 @@ class _RInputImageListState extends State<RInputImageList> {
               _borderColor = Colors.grey;
               _isSelected = false;
               _hasImageBorder = false;
+              inputImageListInfo!.isSelected = false;
             });
           } else {
             setState(() {
-              _borderColor = Color.fromARGB(255, 64, 159, 248);
+              _borderColor = const Color.fromARGB(255, 64, 159, 248);
               _isSelected = true;
               _hasImageBorder = true;
+              inputImageListInfo!.isSelected = true;
             });
           }
         },
         child: Container(
-          height: PtToPxConverter.ptToPx(inputImageList.imageHeight),
+          padding: const EdgeInsets.all(3),
+          height: _height,
           width: PtToPxConverter.ptToPx(
               inputImageList.imageWidth! * inputImageList.column!),
           alignment: Alignment.center,
@@ -62,9 +88,36 @@ class _RInputImageListState extends State<RInputImageList> {
                     )
                   : null,
               color: Colors.transparent),
-          child: const Text('请点击此处后选择右侧图片'),
+          child: _child,
         ),
       ),
     );
   }
+
+  Widget _getChild() {
+    if (_images.isNotEmpty) {
+      final rowCount = (_images.length / 2).ceil();
+      _height =
+          rowCount * (PtToPxConverter.ptToPx(inputImageList.imageHeight!) + 3) +
+              6;
+      return GridView.builder(
+        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+          crossAxisCount: inputImageList.column!,
+          crossAxisSpacing: 5,
+          mainAxisSpacing: 5,
+          childAspectRatio:
+              inputImageList.imageWidth! / inputImageList.imageHeight!,
+        ),
+        itemCount: _images.length,
+        itemBuilder: (BuildContext context, int index) {
+          return VidImageView.network(
+            _images[index],
+            fit: BoxFit.fill,
+            width: PtToPxConverter.ptToPx(inputImageList.imageWidth!) - 20,
+          );
+        },
+      );
+    }
+    return const Text('请点击此处后选择右侧图片');
+  }
 }

+ 9 - 0
lib/pages/components/input_text.dart

@@ -2,6 +2,9 @@ import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
 import 'package:fis_lib_report/converts/text_size_converter.dart';
 import 'package:fis_lib_report/converts/alignment_convert.dart';
 import 'package:fis_lib_report/report/inputText.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/input_text_info.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
 import 'package:flutter/material.dart';
 
 class RInputText extends StatefulWidget {
@@ -28,9 +31,12 @@ class _RInputTextState extends State<RInputText> {
   Color _backgroundColor = const Color.fromARGB(255, 255, 255, 255);
   int? _lineLength = 1;
   TextStyle? _textStyle;
+  InputTextInfo? _inputTextInfo;
 
   @override
   initState() {
+    final inputTextInfo = ReportInfo.instance.getElementInfo(inputText);
+    _inputTextInfo = inputTextInfo as InputTextInfo;
     if (inputText.isReadOnly!) {
       _controller.text = 'test';
     }
@@ -108,6 +114,9 @@ class _RInputTextState extends State<RInputText> {
 
   //onchange 事件
   void _onInputChanged(TextStyle _textStyle, String value) {
+    if (_inputTextInfo != null) {
+      _inputTextInfo!.text = value;
+    }
     final width = TextSizeConvert.getTextSize(value, _textStyle).width;
     // ignore: todo
     //TODO(LOki):此处需要区分不同的输入框

+ 13 - 2
lib/pages/components/multi_selected.dart

@@ -5,6 +5,8 @@ import 'package:fis_lib_report/report/inputText.dart';
 import 'package:fis_lib_report/report/multiSelected.dart';
 import 'package:fis_lib_report/report/rt_color.dart';
 import 'package:fis_lib_report/report/singleSelected.dart';
+import 'package:fis_lib_report/report_info/multi_selected_info.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
 import 'package:flutter/material.dart';
 import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:fis_lib_report/report/inputText.dart';
@@ -22,14 +24,20 @@ class RMultiSelected extends StatefulWidget {
 class _RRMultiSelectedState extends State<RMultiSelected> {
   MultiSelected multiSelected;
   _RRMultiSelectedState(this.multiSelected);
-  String _value = '';
+  final String _value = '';
   String? _selectedItemView = '';
   List<String>? _items = [];
-  List<String>? _selectedItems = [];
+  final List<String>? _selectedItems = [];
   double _width = 0.0;
+  MulitiSelectedInfo? _mulitiSelectedInfo;
+
   TextStyle _textStyle = TextStyle();
   @override
   initState() {
+    final selectInfo = ReportInfo.instance.getElementInfo(multiSelected);
+    if (selectInfo != null) {
+      _mulitiSelectedInfo = selectInfo as MulitiSelectedInfo;
+    }
     if (multiSelected.items!.isNotEmpty) {
       _items = multiSelected.items;
     }
@@ -103,6 +111,9 @@ class _RRMultiSelectedState extends State<RMultiSelected> {
                 // _width = width - 25;
               }
             });
+            if (_mulitiSelectedInfo != null) {
+              _mulitiSelectedInfo!.selectedItems = _selectedItems;
+            }
           },
           isSelected: _selectedItems!.contains(e),
         ),

+ 11 - 1
lib/pages/components/single_select.dart

@@ -1,5 +1,7 @@
 import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
 import 'package:fis_lib_report/report/singleSelected.dart';
+import 'package:fis_lib_report/report_info/report_info.dart';
+import 'package:fis_lib_report/report_info/single_selected_info.dart';
 import 'package:flutter/material.dart';
 import 'package:dropdown_button2/dropdown_button2.dart';
 import 'package:fis_ui/simple/select.dart';
@@ -18,9 +20,13 @@ class _RSingleSelectState extends State<RSingleSelected> {
   _RSingleSelectState(this.singleSelected);
   String _value = '';
   List<String>? _items = [];
-
+  SingleSelectedInfo? _singleSelectedInfo;
   @override
   initState() {
+    final selectInfo = ReportInfo.instance.getElementInfo(singleSelected);
+    if (selectInfo != null) {
+      _singleSelectedInfo = selectInfo as SingleSelectedInfo;
+    }
     if (singleSelected.items!.isNotEmpty) {
       _items = singleSelected.items;
     }
@@ -71,6 +77,10 @@ class _RSingleSelectState extends State<RSingleSelected> {
             setState(() {
               _value = v!;
             });
+            if (_singleSelectedInfo != null) {
+              _singleSelectedInfo!.selectedItem = v;
+              ReportInfo.instance;
+            }
           },
         ),
       ),

+ 0 - 1
lib/pages/paragraph_page.dart

@@ -62,7 +62,6 @@ class _ParagraphState extends State<ParagraphPage> {
           ..._elements!.map((element) {
             if (element.elementType!.name == ElementType.inputText!.name) {
               InputText inputText = element as InputText;
-
               return RInputText(inputText: inputText);
             } else if (element.elementType!.name ==
                 ElementType.staticText!.name) {

+ 1 - 15
lib/report_info/block_element_info.dart → lib/report_info/block_element_info_interface.dart

@@ -9,20 +9,6 @@ import 'package:fis_lib_report/report_info/input_image_list_info.dart';
 import 'package:fis_lib_report/report_info/paragraph_info.dart';
 import 'package:fis_lib_report/report_info/rt_table_info.dart';
 
-class BlockElementInfo {
+abstract class IBlockElementInfo implements ElementInfo {
   List<ElementInfo>? elementInfos = [];
-
-  BlockElementInfo.fromElement(IElement element) {
-    final _type = element.elementType!;
-    if (_type.name == ElementType.rtTable!.name) {
-      final table = element as RTTable;
-      elementInfos!.add(RTTableInfo.fromElement(table));
-    } else if (_type.name == ElementType.paragraph!.name) {
-      final paragraph = element as Paragraph;
-      elementInfos!.add(ParagraphInfo.fromElement(paragraph));
-    } else {
-      final inputImageList = element as InputImageList;
-      elementInfos!.add(InputImageListInfo.fromElement(inputImageList));
-    }
-  }
 }

+ 14 - 2
lib/report_info/input_image_list_info.dart

@@ -1,22 +1,34 @@
+import 'package:fis_lib_report/converts/event_type.dart';
 import 'package:fis_lib_report/report/element.dart';
 import 'package:fis_lib_report/report/inputImageList.dart';
 import 'package:fis_lib_report/report/interfaces/block_element.dart';
 import 'package:fis_lib_report/report/interfaces/element.dart';
 import 'package:fis_lib_report/report/interfaces/inputImageList.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
 import 'package:fis_lib_report/report_info/element_info.dart';
 
-class InputImageListInfo extends ElementInfo {
+class InputImageListInfo extends ElementInfo implements IBlockElementInfo {
   int? column;
 
   bool? hasGap;
 
   bool? isReadOnly;
 
+  bool? isSelected;
+
+  FEventHandler<String>? onSelect = FEventHandler();
+
   InputImageListInfo.fromElement(InputImageList inputImageList)
       : super.fromElement(inputImageList) {
     column = inputImageList.column;
     hasGap = inputImageList.hasGap;
     isReadOnly = inputImageList.isReadOnly;
   }
+
+  @override
+  List<ElementInfo>? elementInfos;
+
+  void addImage(String imageUrl) {
+    onSelect!.emit(this, imageUrl);
+  }
 }

+ 2 - 3
lib/report_info/paragraph_info.dart

@@ -1,12 +1,11 @@
 import 'package:fis_lib_report/report/dateTimeElement.dart';
 import 'package:fis_lib_report/report/element_type.dart';
 import 'package:fis_lib_report/report/inputText.dart';
-import 'package:fis_lib_report/report/line.dart';
 import 'package:fis_lib_report/report/multiSelected.dart';
 import 'package:fis_lib_report/report/paragraph.dart';
 import 'package:fis_lib_report/report/singleSelected.dart';
 import 'package:fis_lib_report/report/staticText.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
 import 'package:fis_lib_report/report_info/date_time_info.dart';
 import 'package:fis_lib_report/report_info/element_info.dart';
 import 'package:fis_lib_report/report_info/input_text_info.dart';
@@ -14,7 +13,7 @@ import 'package:fis_lib_report/report_info/multi_selected_info.dart';
 import 'package:fis_lib_report/report_info/single_selected_info.dart';
 import 'package:fis_lib_report/report_info/static_text_info.dart';
 
-class ParagraphInfo extends ElementInfo implements BlockElementInfo {
+class ParagraphInfo extends ElementInfo implements IBlockElementInfo {
   double? lineSpace;
 
   @override

+ 138 - 7
lib/report_info/report_info.dart

@@ -1,12 +1,23 @@
 import 'package:fis_lib_report/report/element_tag.dart';
+import 'package:fis_lib_report/report/element_type.dart';
+import 'package:fis_lib_report/report/inputImageList.dart';
+import 'package:fis_lib_report/report/inputText.dart';
+import 'package:fis_lib_report/report/interfaces/block_element.dart';
+import 'package:fis_lib_report/report/interfaces/element.dart';
+import 'package:fis_lib_report/report/paragraph.dart';
 import 'package:fis_lib_report/report/report_template_document.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report/rt_table.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
+import 'package:fis_lib_report/report_info/input_image_list_info.dart';
+import 'package:fis_lib_report/report_info/paragraph_info.dart';
+import 'package:fis_lib_report/report_info/rt_table_info.dart';
 
 class ReportInfo {
   static ReportInfo? _reportInfo;
-  List<BlockElementInfo> blocks = [];
-  List<BlockElementInfo> headers = [];
-  List<BlockElementInfo> footers = [];
+  List<IBlockElementInfo> blocks = [];
+  List<IBlockElementInfo> headers = [];
+  List<IBlockElementInfo> footers = [];
 
   /// Gets the author of the report template.
   String? author;
@@ -44,16 +55,136 @@ class ReportInfo {
       version = reportTemplate.version;
       id = reportTemplate.id;
       for (var element in reportTemplate.header!) {
-        headers.add(BlockElementInfo.fromElement(element));
+        headers.add(_initBlockElement(element));
       }
       for (var element in reportTemplate.blocks!) {
-        blocks.add(BlockElementInfo.fromElement(element));
+        blocks.add(_initBlockElement(element));
       }
       for (var element in reportTemplate.footer!) {
-        footers.add(BlockElementInfo.fromElement(element));
+        footers.add(_initBlockElement(element));
       }
     } catch (e) {
       print(e);
     }
   }
+
+  IBlockElementInfo? getBlockElement(IBlockElement block) {
+    final id = block.id;
+    for (var element in headers) {
+      if (element.id == id) {
+        return element;
+      }
+    }
+    for (var element in blocks) {
+      if (element.id == id) {
+        return element;
+      }
+    }
+    for (var element in footers) {
+      if (element.id == id) {
+        return element;
+      }
+    }
+  }
+
+  IBlockElementInfo _initBlockElement(IBlockElement element) {
+    final _type = element.elementType!;
+    if (_type.name == ElementType.rtTable!.name) {
+      final table = element as RTTable;
+      return RTTableInfo.fromElement(table);
+    } else if (_type.name == ElementType.paragraph!.name) {
+      final paragraph = element as Paragraph;
+      return ParagraphInfo.fromElement(paragraph);
+    } else {
+      final inputImageList = element as InputImageList;
+      return InputImageListInfo.fromElement(inputImageList);
+    }
+  }
+
+  void getSelectedInputImage(String imageUrl) {
+    for (var element in headers) {
+      if (_checkImageisSelected(element)) {
+        final inputImage = element as InputImageListInfo;
+        inputImage.addImage(imageUrl);
+      }
+    }
+    for (var element in blocks) {
+      if (_checkImageisSelected(element)) {
+        final inputImage = element as InputImageListInfo;
+        inputImage.addImage(imageUrl);
+      }
+    }
+    for (var element in footers) {
+      if (_checkImageisSelected(element)) {
+        final inputImage = element as InputImageListInfo;
+        inputImage.addImage(imageUrl);
+      }
+    }
+  }
+
+  ElementInfo? getElementInfo(IElement element) {
+    try {
+      for (var e in headers) {
+        final elementInfo = _getBaseElementInfo(e, element);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+      for (var e in blocks) {
+        final elementInfo = _getBaseElementInfo(e, element);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+      for (var e in footers) {
+        final elementInfo = _getBaseElementInfo(e, element);
+        if (elementInfo != null) {
+          return elementInfo;
+        }
+      }
+    } catch (e) {
+      print(e);
+    }
+    return null;
+  }
+
+  bool _checkImageisSelected(IBlockElementInfo block) {
+    if (block is InputImageListInfo) {
+      final inputImage = block;
+      if (inputImage.isSelected!) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  ElementInfo? _getBaseElementInfo(IBlockElementInfo block, IElement element) {
+    ElementInfo? result;
+    final type = block.elementType;
+    if (type!.name == ElementType.paragraph!.name) {
+      final paragraph = block as ParagraphInfo;
+      for (var el in paragraph.elementInfos!) {
+        if (el.id == element.id) {
+          result = el;
+          break;
+        }
+      }
+    }
+    if (result == null) {
+      if (type.name == ElementType.rtTable!.name) {
+        final table = block as RTTableInfo;
+        final cells = table.cells!;
+        for (var cell in cells.values) {
+          for (var b in cell.blocks!) {
+            final info = _getBaseElementInfo(b, element);
+            if (info != null) {
+              result = info;
+              break;
+            }
+          }
+        }
+      }
+    }
+    return result;
+  }
 }

+ 2 - 3
lib/report_info/rt_cell_info.dart

@@ -1,13 +1,12 @@
 import 'package:fis_lib_report/report/element_type.dart';
 import 'package:fis_lib_report/report/interfaces/cell.dart';
 import 'package:fis_lib_report/report/paragraph.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
 import 'package:fis_lib_report/report_info/element_info.dart';
 import 'package:fis_lib_report/report_info/paragraph_info.dart';
 
 class RTCellInfo extends ElementInfo {
-  @override
-  List<BlockElementInfo>? blocks = [];
+  List<IBlockElementInfo>? blocks = [];
 
   RTCellInfo.fromElement(ICell value) : super.fromElement(value) {
     for (var element in value.blocks!) {

+ 1 - 1
lib/report_info/rt_grid.dart

@@ -4,7 +4,7 @@ import 'package:fis_lib_report/report/interfaces/cell.dart';
 import 'package:fis_lib_report/report/interfaces/grid.dart';
 import 'package:fis_lib_report/report/interfaces/report_element.dart';
 import 'package:fis_lib_report/report/rt_table.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
 import 'package:fis_lib_report/report_info/element_info.dart';
 import 'package:fis_lib_report/report_info/rt_cell_info.dart';
 

+ 6 - 2
lib/report_info/rt_table_info.dart

@@ -1,10 +1,11 @@
 import 'package:fis_lib_report/report/element_type.dart';
 import 'package:fis_lib_report/report/interfaces/report_element.dart';
 import 'package:fis_lib_report/report/rt_table.dart';
-import 'package:fis_lib_report/report_info/block_element_info.dart';
+import 'package:fis_lib_report/report_info/block_element_info_interface.dart';
+import 'package:fis_lib_report/report_info/element_info.dart';
 import 'package:fis_lib_report/report_info/rt_grid.dart';
 
-class RTTableInfo extends RTGridInfo {
+class RTTableInfo extends RTGridInfo implements IBlockElementInfo {
   bool? autoHide;
   bool? isAverageColumnWidth;
   bool? allowBreakAcrossPages;
@@ -14,4 +15,7 @@ class RTTableInfo extends RTGridInfo {
     isAverageColumnWidth = table.isAverageColumnWidth;
     allowBreakAcrossPages = table.allowBreakAcrossPages;
   }
+
+  @override
+  List<ElementInfo>? elementInfos;
 }

+ 1 - 0
pubspec.yaml

@@ -51,6 +51,7 @@ dependency_overrides:
       url: http://git.ius.plus:88/Project-Wing/flutter_vid
       ref: 173b68819c
 
+
 dev_dependencies:
   flutter_test:
     sdk: flutter