Pārlūkot izejas kodu

文本输入框雏形完善,样式根据Json设置

loki.wu 2 gadi atpakaļ
vecāks
revīzija
1777cc51c7

+ 9 - 0
lib/converts/pt_to_px_converter.dart

@@ -0,0 +1,9 @@
+class PtToPxConverter {
+  //Json 中的PT单位转换为像素单位
+  static double ptToPx(double? value) {
+    if (value == null) {
+      return 10.5 * 4 / 3;
+    }
+    return value * 4 / 3;
+  }
+}

+ 20 - 0
lib/converts/vertical_alignment.dart

@@ -0,0 +1,20 @@
+import 'package:fis_lib_report/report/interfaces/position_layout.dart';
+import 'package:flutter/widgets.dart';
+
+class VerticalAlignmentToAlignVertical {
+  static TextAlignVertical VerticalAlignmentConvert(VerticalLayout? value) {
+    if (value == null) {
+      return TextAlignVertical.center;
+    }
+    switch (value) {
+      case VerticalLayout.Top:
+        return TextAlignVertical.top;
+      case VerticalLayout.Bottom:
+        return TextAlignVertical.bottom;
+      case VerticalLayout.Center:
+        return TextAlignVertical.center;
+      case VerticalLayout.Stretch:
+        return TextAlignVertical.center;
+    }
+  }
+}

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

@@ -0,0 +1,133 @@
+import 'package:fis_lib_report/converts/pt_to_px_converter.dart';
+import 'package:fis_lib_report/converts/vertical_alignment.dart';
+import 'package:fis_lib_report/report/inputText.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class RInputText extends StatefulWidget {
+  final InputText inputText;
+
+  const RInputText({Key? key, required this.inputText}) : super(key: key);
+
+  @override
+  State<StatefulWidget> createState() {
+    return _RInputTextState(inputText: inputText);
+  }
+}
+
+class _RInputTextState extends State<RInputText> {
+  _RInputTextState({required this.inputText});
+  final InputText inputText;
+  final _controller = TextEditingController(text: '');
+  final _focusNode = FocusNode();
+  double? _lineWidth = 136.0;
+  double? _fontSize = 22.0;
+  double? _height = 22.0;
+  bool? _textWrap = false;
+  Color _fontColor = const Color.fromARGB(255, 0, 0, 0);
+  Color _backgroundColor = const Color.fromARGB(255, 255, 255, 255);
+  int? _lineLength = 1;
+  @override
+  initState() {
+    final fontColor = inputText.fontColor;
+    if (fontColor != null) {
+      _fontColor = Color.fromARGB(
+          fontColor.a!, fontColor.r!, fontColor.g!, fontColor.b!);
+    }
+    final backgroundColor = inputText.background;
+    if (backgroundColor != null) {
+      _backgroundColor = Color.fromARGB(backgroundColor.a!, backgroundColor.r!,
+          backgroundColor.g!, backgroundColor.b!);
+    }
+    //TODO(Loki):set FontName in TextField
+    final fontName = inputText.fontName;
+    //TODO(Loki):常规模板暂未设置fontStyles,后续再支持
+    final fontStyles = inputText.fontStyles;
+    _lineLength = inputText.lineLength;
+    _lineWidth = inputText.lineWidth;
+    _textWrap = inputText.textWrap;
+    _fontSize = PtToPxConverter.ptToPx(inputText.fontSize);
+    _height = _fontSize! > 30 ? 36.5 : 22;
+
+    print(_lineLength);
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final _textStyle = TextStyle(
+      fontSize: PtToPxConverter.ptToPx(inputText.fontSize),
+      color: _fontColor,
+    );
+    return Container(
+      width: PtToPxConverter.ptToPx(_lineWidth!),
+      height: _textWrap! ? _height! * 4 : (_height! + 5),
+      padding: EdgeInsets.only(top: _textWrap! ? 10 : 5, right: 5, left: 5),
+      decoration: BoxDecoration(
+        border: Border.all(
+          width: 1,
+          color: Colors.grey,
+        ),
+        color: _backgroundColor,
+      ),
+      alignment: Alignment.center,
+      child: TextField(
+        focusNode: _focusNode,
+        readOnly: inputText.isReadOnly ?? false,
+        cursorHeight: _height!,
+        decoration: InputDecoration.collapsed(
+          hintText: '',
+          hintStyle: TextStyle(
+            fontSize: _fontSize,
+            color: Colors.black54,
+          ),
+          fillColor: _backgroundColor,
+          filled: true,
+        ),
+        textAlignVertical:
+            VerticalAlignmentToAlignVertical.VerticalAlignmentConvert(
+                inputText.verticalAlignment),
+        maxLines: _textWrap! ? 6 : 1,
+        minLines: _textWrap! ? 6 : 1,
+        controller: _controller,
+        textAlign: TextAlign.start,
+        style: _textStyle,
+        onChanged: (v) {
+          if (_lineWidth! <
+              boundingTextSize(_controller.text, _textStyle).width) {
+            setState(() {
+              if (_lineWidth! < 600) {
+                _lineWidth = _lineWidth! + 12;
+              }
+            });
+          } else if (_controller.text.isEmpty) {
+            setState(() {
+              _lineWidth = inputText.lineWidth;
+            });
+          } else if (boundingTextSize(_controller.text, _textStyle).width >
+              inputText.lineWidth!) {
+            setState(() {
+              if (_lineWidth! < 600) {
+                _lineWidth =
+                    boundingTextSize(_controller.text, _textStyle).width;
+              }
+            });
+          }
+        },
+      ),
+    );
+  }
+
+  static Size boundingTextSize(String text, TextStyle style,
+      {int maxLines = 2 ^ 31, double maxWidth = double.infinity}) {
+    if (text == null || text.isEmpty) {
+      return Size.zero;
+    }
+    final TextPainter textPainter = TextPainter(
+        textDirection: TextDirection.ltr,
+        text: TextSpan(text: text, style: style),
+        maxLines: maxLines)
+      ..layout(maxWidth: maxWidth);
+    return textPainter.size;
+  }
+}

+ 3 - 22
lib/pages/paragraph_page.dart

@@ -1,3 +1,4 @@
+import 'package:fis_lib_report/pages/components/input_text.dart';
 import 'package:fis_lib_report/pages/components/multi_select.dart';
 import 'package:fis_lib_report/pages/helpler.dart';
 import 'package:fis_lib_report/report/dateTimeElement.dart';
@@ -24,7 +25,6 @@ class ParagraphPage extends StatefulWidget {
 }
 
 class _ParagraphState extends State<ParagraphPage> {
-  final _controller = TextEditingController();
   List<IElement>? _elements = [];
   int _itemCount = 0;
 
@@ -50,27 +50,8 @@ class _ParagraphState extends State<ParagraphPage> {
         ..._elements!.map((element) {
           if (element.elementType!.name == ElementType.inputText!.name) {
             InputText inputText = element as InputText;
-            return Container(
-              color: Colors.white,
-              width: inputText.lineWidth! * 1.5,
-              height: inputText.lineWidth! / 3.5,
-              child: TextField(
-                decoration: const InputDecoration(
-                  isCollapsed: true,
-                  contentPadding:
-                      EdgeInsets.symmetric(vertical: 5, horizontal: 5),
-                  hintText: '',
-                  border: OutlineInputBorder(
-                    borderRadius: BorderRadius.all(Radius.circular(4.0)),
-                  ),
-                ),
-                maxLines: 6,
-                controller: _controller,
-                textAlign: TextAlign.start,
-                style: const TextStyle(
-                  fontSize: 18,
-                ),
-              ),
+            return RInputText(
+              inputText: inputText,
             );
           } else if (element.elementType!.name ==
               ElementType.staticText!.name) {

+ 1 - 2
lib/pages/rt_table.dart

@@ -41,7 +41,6 @@ class _RTTableState extends State<RTTablePage> {
   @override
   Widget build(BuildContext context) {
     return SizedBox(
-      height: _row! * 40,
       child: (_column == null || _column == 0 || _values!.isEmpty)
           ? const SizedBox()
           : GridView.builder(
@@ -50,7 +49,7 @@ class _RTTableState extends State<RTTablePage> {
               itemCount: _values!.length,
               gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                 crossAxisCount: _column!,
-                childAspectRatio: _column == 3 ? 6.6 : 24,
+                childAspectRatio: _column == 3 ? 6.6 : 18.5,
               ),
               itemBuilder: (BuildContext context, int index) {
                 final cell = _values![index];

+ 2 - 0
lib/report/text_element.dart

@@ -10,6 +10,8 @@ abstract class TextElement extends InlineElement implements ITextElement {
   RTColor? background;
   int? lineLength;
   double? lineWidth;
+
+  ///是否自动换行
   bool? textWrap;
 
   TextElement.fromJson(Map<String, dynamic> json) : super.fromJson(json) {