Carsten Fregin
Committed by David PHAM-VAN

Add Choice Field

@@ -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 //