diff --git a/lib/src/widgets/raw_editor.dart b/lib/src/widgets/raw_editor.dart index 0caba63e..ce9540ab 100644 --- a/lib/src/widgets/raw_editor.dart +++ b/lib/src/widgets/raw_editor.dart @@ -254,11 +254,8 @@ class RawEditorState extends EditorState /// by changing its attribute according to [value]. void _handleCheckboxTap(int offset, bool value) { if (!widget.readOnly) { - if (value) { - widget.controller.formatText(offset, 0, Attribute.checked); - } else { - widget.controller.formatText(offset, 0, Attribute.unchecked); - } + widget.controller.formatText( + offset, 0, value ? Attribute.checked : Attribute.unchecked); } } diff --git a/lib/src/widgets/style_widgets/checkbox_point.dart b/lib/src/widgets/style_widgets/checkbox_point.dart new file mode 100644 index 00000000..1f97097d --- /dev/null +++ b/lib/src/widgets/style_widgets/checkbox_point.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; + +class CheckboxPoint extends StatefulWidget { + const CheckboxPoint({ + required this.size, + required this.value, + required this.enabled, + required this.onChanged, + Key? key, + }) : super(key: key); + + final double size; + final bool value; + final bool enabled; + final ValueChanged onChanged; + + @override + _CheckboxPointState createState() => _CheckboxPointState(); +} + +class _CheckboxPointState extends State { + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final fillColor = widget.value + ? (widget.enabled + ? theme.colorScheme.primary + : theme.colorScheme.onSurface.withOpacity(0.5)) + : theme.colorScheme.surface; + final borderColor = widget.value + ? (widget.enabled + ? theme.colorScheme.primary + : theme.colorScheme.onSurface.withOpacity(0)) + : (widget.enabled + ? theme.colorScheme.onSurface.withOpacity(0.5) + : theme.colorScheme.onSurface.withOpacity(0.3)); + return Center( + child: SizedBox( + width: widget.size, + height: widget.size, + child: Material( + color: fillColor, + shape: RoundedRectangleBorder( + side: BorderSide( + color: borderColor, + ), + borderRadius: BorderRadius.circular(2), + ), + child: InkWell( + onTap: + widget.enabled ? () => widget.onChanged(!widget.value) : null, + child: widget.value + ? Icon(Icons.check, + size: widget.size, color: theme.colorScheme.onPrimary) + : null, + ), + ), + ), + ); + } +} diff --git a/lib/src/widgets/text_block.dart b/lib/src/widgets/text_block.dart index 33b1c351..aed6ed77 100644 --- a/lib/src/widgets/text_block.dart +++ b/lib/src/widgets/text_block.dart @@ -11,6 +11,7 @@ import 'cursor.dart'; import 'default_styles.dart'; import 'delegate.dart'; import 'editor.dart'; +import 'style_widgets/checkbox_point.dart'; import 'text_line.dart'; import 'text_selection.dart'; @@ -168,25 +169,20 @@ class EditableTextBlock extends StatelessWidget { } if (attrs[Attribute.list.key] == Attribute.checked) { - return QuillCheckbox( - key: UniqueKey(), - style: defaultStyles!.leading!.style, - width: 32, - isChecked: true, - offset: block.offset + line.offset, - onTap: onCheckboxTap, - uiBuilder: defaultStyles.lists!.checkboxUIBuilder, + return CheckboxPoint( + size: 14, + value: true, + enabled: !readOnly, + onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), ); } if (attrs[Attribute.list.key] == Attribute.unchecked) { - return QuillCheckbox( - key: UniqueKey(), - style: defaultStyles!.leading!.style, - width: 32, - offset: block.offset + line.offset, - onTap: onCheckboxTap, - uiBuilder: defaultStyles.lists!.checkboxUIBuilder, + return CheckboxPoint( + size: 14, + value: false, + enabled: !readOnly, + onChanged: (checked) => onCheckboxTap(line.documentOffset, checked), ); } diff --git a/lib/src/widgets/text_line.dart b/lib/src/widgets/text_line.dart index d75daffd..a9e2dbc5 100644 --- a/lib/src/widgets/text_line.dart +++ b/lib/src/widgets/text_line.dart @@ -967,6 +967,17 @@ class RenderEditableTextLine extends RenderEditableBox { @override bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { + if (_leading != null) { + final childParentData = _leading!.parentData as BoxParentData; + final isHit = result.addWithPaintOffset( + offset: childParentData.offset, + position: position, + hitTest: (result, transformed) { + assert(transformed == position - childParentData.offset); + return _leading!.hitTest(result, position: transformed); + }); + if (isHit) return true; + } if (_body == null) return false; final parentData = _body!.parentData as BoxParentData; return result.addWithPaintOffset(