Showing
5 changed files
with
120 additions
and
0 deletions
| @@ -9,6 +9,7 @@ | @@ -9,6 +9,7 @@ | ||
| 9 | - Update Image dependency | 9 | - Update Image dependency |
| 10 | - Fix lints | 10 | - Fix lints |
| 11 | - Add options to customise border in Dataset widget [838] | 11 | - Add options to customise border in Dataset widget [838] |
| 12 | +- Add Choice Field [Carsten Fregin] | ||
| 12 | 13 | ||
| 13 | ## 3.8.4 | 14 | ## 3.8.4 |
| 14 | 15 |
| @@ -31,6 +31,73 @@ import 'object.dart'; | @@ -31,6 +31,73 @@ import 'object.dart'; | ||
| 31 | import 'object_dict.dart'; | 31 | import 'object_dict.dart'; |
| 32 | import 'page.dart'; | 32 | import 'page.dart'; |
| 33 | 33 | ||
| 34 | +class PdfChoiceField extends PdfAnnotWidget { | ||
| 35 | + PdfChoiceField({ | ||
| 36 | + required PdfRect rect, | ||
| 37 | + required this.textColor, | ||
| 38 | + required this.font, | ||
| 39 | + required this.fontSize, | ||
| 40 | + required this.items, | ||
| 41 | + String? fieldName, | ||
| 42 | + this.value, | ||
| 43 | + this.defaultValue, | ||
| 44 | + }) : super( | ||
| 45 | + rect: rect, | ||
| 46 | + fieldType: '/Ch', | ||
| 47 | + fieldName: fieldName, | ||
| 48 | + ); | ||
| 49 | + | ||
| 50 | + final List<String> items; | ||
| 51 | + final PdfColor textColor; | ||
| 52 | + final String? value; | ||
| 53 | + final String? defaultValue; | ||
| 54 | + final Set<PdfFieldFlags>? fieldFlags = { | ||
| 55 | + PdfFieldFlags.combo, | ||
| 56 | + }; | ||
| 57 | + final PdfFont font; | ||
| 58 | + | ||
| 59 | + final double fontSize; | ||
| 60 | + @override | ||
| 61 | + void build(PdfPage page, PdfObject object, PdfDict params) { | ||
| 62 | + super.build(page, object, params); | ||
| 63 | + // What is /F? | ||
| 64 | + //params['/F'] = const PdfNum(4); | ||
| 65 | + params['/Ff'] = PdfNum(fieldFlagsValue); | ||
| 66 | + params['/Opt'] = | ||
| 67 | + PdfArray<PdfString>(items.map((e) => PdfString.fromString(e)).toList()); | ||
| 68 | + | ||
| 69 | + if (defaultValue != null) { | ||
| 70 | + params['/DV'] = PdfString.fromString(defaultValue!); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + if (value != null) { | ||
| 74 | + params['/V'] = PdfString.fromString(value!); | ||
| 75 | + } else { | ||
| 76 | + params['/V'] = const PdfNull(); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + final buf = PdfStream(); | ||
| 80 | + final g = PdfGraphics(page, buf); | ||
| 81 | + g.setFillColor(textColor); | ||
| 82 | + g.setFont(font, fontSize); | ||
| 83 | + | ||
| 84 | + params['/DA'] = PdfSecString.fromStream(object, buf); | ||
| 85 | + | ||
| 86 | + // What is /TU? Tooltip? | ||
| 87 | + //params['/TU'] = PdfString.fromString('Select from list'); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + int get fieldFlagsValue { | ||
| 91 | + if (fieldFlags == null || fieldFlags!.isEmpty) { | ||
| 92 | + return 0; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + return fieldFlags! | ||
| 96 | + .map<int>((PdfFieldFlags e) => 1 << e.index) | ||
| 97 | + .reduce((int a, int b) => a | b); | ||
| 98 | + } | ||
| 99 | +} | ||
| 100 | + | ||
| 34 | class PdfAnnot extends PdfObjectDict { | 101 | class PdfAnnot extends PdfObjectDict { |
| 35 | PdfAnnot(this.pdfPage, this.annot) | 102 | PdfAnnot(this.pdfPage, this.annot) |
| 36 | : super(pdfPage.pdfDocument, type: '/Annot') { | 103 | : super(pdfPage.pdfDocument, type: '/Annot') { |
| @@ -31,6 +31,46 @@ import 'text_style.dart'; | @@ -31,6 +31,46 @@ import 'text_style.dart'; | ||
| 31 | import 'theme.dart'; | 31 | import 'theme.dart'; |
| 32 | import 'widget.dart'; | 32 | import 'widget.dart'; |
| 33 | 33 | ||
| 34 | +class ChoiceField extends StatelessWidget { | ||
| 35 | + ChoiceField({ | ||
| 36 | + this.width = 120, | ||
| 37 | + this.height = 13, | ||
| 38 | + this.textStyle, | ||
| 39 | + required this.name, | ||
| 40 | + required this.items, | ||
| 41 | + this.value, | ||
| 42 | + }); | ||
| 43 | + final String name; | ||
| 44 | + final TextStyle? textStyle; | ||
| 45 | + final double width; | ||
| 46 | + final double height; | ||
| 47 | + final List<String> items; | ||
| 48 | + final String? value; | ||
| 49 | + | ||
| 50 | + @override | ||
| 51 | + void paint(Context context) { | ||
| 52 | + super.paint(context); | ||
| 53 | + final _textStyle = Theme.of(context).defaultTextStyle.merge(textStyle); | ||
| 54 | + final pdfRect = context.localToGlobal(box!); | ||
| 55 | + | ||
| 56 | + final bf = PdfChoiceField( | ||
| 57 | + textColor: _textStyle.color!, | ||
| 58 | + fieldName: name, | ||
| 59 | + value: value, | ||
| 60 | + font: _textStyle.font!.getFont(context), | ||
| 61 | + fontSize: _textStyle.fontSize!, | ||
| 62 | + items: items, | ||
| 63 | + rect: pdfRect, | ||
| 64 | + ); | ||
| 65 | + PdfAnnot(context.page, bf); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + @override | ||
| 69 | + Widget build(Context context) { | ||
| 70 | + return SizedBox(width: width, height: height); | ||
| 71 | + } | ||
| 72 | +} | ||
| 73 | + | ||
| 34 | class Checkbox extends SingleChildWidget { | 74 | class Checkbox extends SingleChildWidget { |
| 35 | Checkbox({ | 75 | Checkbox({ |
| 36 | required this.value, | 76 | required this.value, |
| @@ -98,6 +98,17 @@ void main() { | @@ -98,6 +98,17 @@ void main() { | ||
| 98 | Decorated(child: TextField(name: 'Address')), | 98 | Decorated(child: TextField(name: 'Address')), |
| 99 | // | 99 | // |
| 100 | SizedBox(width: double.infinity, height: 10), | 100 | SizedBox(width: double.infinity, height: 10), |
| 101 | + Label(label: 'ChoiceField:', width: 100), | ||
| 102 | + Decorated( | ||
| 103 | + child: ChoiceField(name: 'Test Choice', items: [ | ||
| 104 | + 'One', | ||
| 105 | + 'Two', | ||
| 106 | + 'Blue', | ||
| 107 | + 'Yellow', | ||
| 108 | + 'Test äöüß', | ||
| 109 | + ])), | ||
| 110 | + // | ||
| 111 | + SizedBox(width: double.infinity, height: 10), | ||
| 101 | // | 112 | // |
| 102 | Label(label: 'Postcode:', width: 100), | 113 | Label(label: 'Postcode:', width: 100), |
| 103 | Decorated( | 114 | Decorated( |
| @@ -114,6 +125,7 @@ void main() { | @@ -114,6 +125,7 @@ void main() { | ||
| 114 | name: 'Country', | 125 | name: 'Country', |
| 115 | color: PdfColors.blue, | 126 | color: PdfColors.blue, |
| 116 | )), | 127 | )), |
| 128 | + | ||
| 117 | // | 129 | // |
| 118 | SizedBox(width: double.infinity, height: 10), | 130 | SizedBox(width: double.infinity, height: 10), |
| 119 | // | 131 | // |
No preview for this file type
-
Please register or login to post a comment