Added leadingBuilder for improved customization.

pull/684/head
Aloïs Deniel 3 years ago
parent 5772b51d86
commit c936decb0c
  1. 1
      lib/flutter_quill.dart
  2. 12
      lib/src/widgets/delegate.dart
  3. 4
      lib/src/widgets/editor.dart
  4. 72
      lib/src/widgets/leading/default_leading_builder.dart
  5. 6
      lib/src/widgets/raw_editor.dart
  6. 74
      lib/src/widgets/text_block.dart

@ -11,6 +11,7 @@ export 'src/models/themes/quill_icon_theme.dart';
export 'src/widgets/controller.dart';
export 'src/widgets/default_styles.dart';
export 'src/widgets/editor.dart';
export 'src/widgets/leading/default_leading_builder.dart';
export 'src/widgets/link.dart' show LinkActionPickerDelegate, LinkMenuAction;
export 'src/widgets/style_widgets/style_widgets.dart';
export 'src/widgets/toolbar.dart';

@ -3,11 +3,23 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import '../../flutter_quill.dart';
import '../models/documents/nodes/line.dart';
import 'text_selection.dart';
typedef EmbedBuilder = Widget Function(BuildContext context,
QuillController controller, Embed node, bool readOnly);
typedef LeadingBuilder = Widget? Function(
BuildContext context,
Line line,
int index,
Map<int, int> indentLevelCounts,
int count,
CheckboxTapCallback onCheckboxTap,
bool readOnly);
typedef CheckboxTapCallback = void Function(int index, bool checked);
typedef CustomStyleBuilder = TextStyle Function(Attribute attribute);
/// Delegate interface for the [EditorTextSelectionGestureDetectorBuilder].

@ -20,6 +20,7 @@ import 'default_styles.dart';
import 'delegate.dart';
import 'embeds/default_embed_builder.dart';
import 'float_cursor.dart';
import 'leading/default_leading_builder.dart';
import 'link.dart';
import 'raw_editor.dart';
import 'text_selection.dart';
@ -168,6 +169,7 @@ class QuillEditor extends StatefulWidget {
this.onSingleLongTapMoveUpdate,
this.onSingleLongTapEnd,
this.embedBuilder = defaultEmbedBuilder,
this.leadingBuilder = defaultLeadingBuilder,
this.linkActionPickerDelegate = defaultLinkActionPickerDelegate,
this.customStyleBuilder,
this.locale,
@ -339,6 +341,7 @@ class QuillEditor extends StatefulWidget {
onSingleLongTapEnd;
final EmbedBuilder embedBuilder;
final LeadingBuilder leadingBuilder;
final CustomStyleBuilder? customStyleBuilder;
/// The locale to use for the editor toolbar, defaults to system locale
@ -453,6 +456,7 @@ class QuillEditorState extends State<QuillEditor>
enableInteractiveSelection: widget.enableInteractiveSelection,
scrollPhysics: widget.scrollPhysics,
embedBuilder: widget.embedBuilder,
leadingBuilder: widget.leadingBuilder,
linkActionPickerDelegate: widget.linkActionPickerDelegate,
customStyleBuilder: widget.customStyleBuilder,
floatingCursorDisabled: widget.floatingCursorDisabled,

@ -0,0 +1,72 @@
import 'package:flutter/widgets.dart';
import '../../models/documents/attribute.dart';
import '../../models/documents/nodes/line.dart' as line;
import '../default_styles.dart';
import '../delegate.dart';
import '../style_widgets/style_widgets.dart';
Widget? defaultLeadingBuilder(
BuildContext context,
line.Line line,
int index,
Map<int, int> indentLevelCounts,
int count,
CheckboxTapCallback onCheckboxTap,
bool readOnly) {
final defaultStyles = QuillStyles.getStyles(context, false);
final attrs = line.style.attributes;
if (attrs[Attribute.list.key] == Attribute.ol) {
return QuillNumberPoint(
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles!.leading!.style,
attrs: attrs,
width: 32,
padding: 8,
);
}
if (attrs[Attribute.list.key] == Attribute.ul) {
return QuillBulletPoint(
style:
defaultStyles!.leading!.style.copyWith(fontWeight: FontWeight.bold),
width: 32,
);
}
if (attrs[Attribute.list.key] == Attribute.checked) {
return CheckboxPoint(
size: 14,
value: true,
enabled: !readOnly,
onChanged: (checked) => onCheckboxTap(line.documentOffset, checked),
uiBuilder: defaultStyles?.lists?.checkboxUIBuilder,
);
}
if (attrs[Attribute.list.key] == Attribute.unchecked) {
return CheckboxPoint(
size: 14,
value: false,
enabled: !readOnly,
onChanged: (checked) => onCheckboxTap(line.documentOffset, checked),
uiBuilder: defaultStyles?.lists?.checkboxUIBuilder,
);
}
if (attrs.containsKey(Attribute.codeBlock.key)) {
return QuillNumberPoint(
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles!.code!.style
.copyWith(color: defaultStyles.code!.style.color!.withOpacity(0.4)),
width: 32,
attrs: attrs,
padding: 16,
withDot: false,
);
}
return null;
}

@ -29,6 +29,7 @@ import 'editor.dart';
import 'embeds/default_embed_builder.dart';
import 'embeds/image.dart';
import 'keyboard_listener.dart';
import 'leading/default_leading_builder.dart';
import 'link.dart';
import 'proxy.dart';
import 'quill_single_child_scroll_view.dart';
@ -72,6 +73,7 @@ class RawEditor extends StatefulWidget {
this.enableInteractiveSelection = true,
this.scrollPhysics,
this.embedBuilder = defaultEmbedBuilder,
this.leadingBuilder = defaultLeadingBuilder,
this.linkActionPickerDelegate = defaultLinkActionPickerDelegate,
this.customStyleBuilder,
this.floatingCursorDisabled = false})
@ -223,6 +225,9 @@ class RawEditor extends StatefulWidget {
/// Builder function for embeddable objects.
final EmbedBuilder embedBuilder;
/// Builder function for leading objects.
final LeadingBuilder leadingBuilder;
final LinkActionPickerDelegate linkActionPickerDelegate;
final CustomStyleBuilder? customStyleBuilder;
final bool floatingCursorDisabled;
@ -456,6 +461,7 @@ class RawEditorState extends EditorState
? const EdgeInsets.all(16)
: null,
embedBuilder: widget.embedBuilder,
leadingBuilder: widget.leadingBuilder,
linkActionPicker: _linkActionPicker,
onLaunchUrl: widget.onLaunchUrl,
cursorCont: _cursorCont,

@ -59,6 +59,7 @@ class EditableTextBlock extends StatelessWidget {
required this.hasFocus,
required this.contentPadding,
required this.embedBuilder,
required this.leadingBuilder,
required this.linkActionPicker,
required this.cursorCont,
required this.indentLevelCounts,
@ -80,12 +81,13 @@ class EditableTextBlock extends StatelessWidget {
final bool hasFocus;
final EdgeInsets? contentPadding;
final EmbedBuilder embedBuilder;
final LeadingBuilder leadingBuilder;
final LinkActionPicker linkActionPicker;
final ValueChanged<String>? onLaunchUrl;
final CustomStyleBuilder? customStyleBuilder;
final CursorCont cursorCont;
final Map<int, int> indentLevelCounts;
final Function(int, bool) onCheckboxTap;
final CheckboxTapCallback onCheckboxTap;
final bool readOnly;
@override
@ -126,7 +128,15 @@ class EditableTextBlock extends StatelessWidget {
index++;
final editableTextLine = EditableTextLine(
line,
_buildLeading(context, line, index, indentLevelCounts, count),
leadingBuilder(
context,
line,
index,
indentLevelCounts,
count,
onCheckboxTap,
readOnly,
),
TextLine(
line: line,
textDirection: textDirection,
@ -154,66 +164,6 @@ class EditableTextBlock extends StatelessWidget {
return children.toList(growable: false);
}
Widget? _buildLeading(BuildContext context, Line line, int index,
Map<int, int> indentLevelCounts, int count) {
final defaultStyles = QuillStyles.getStyles(context, false);
final attrs = line.style.attributes;
if (attrs[Attribute.list.key] == Attribute.ol) {
return QuillNumberPoint(
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles!.leading!.style,
attrs: attrs,
width: 32,
padding: 8,
);
}
if (attrs[Attribute.list.key] == Attribute.ul) {
return QuillBulletPoint(
style:
defaultStyles!.leading!.style.copyWith(fontWeight: FontWeight.bold),
width: 32,
);
}
if (attrs[Attribute.list.key] == Attribute.checked) {
return CheckboxPoint(
size: 14,
value: true,
enabled: !readOnly,
onChanged: (checked) => onCheckboxTap(line.documentOffset, checked),
uiBuilder: defaultStyles?.lists?.checkboxUIBuilder,
);
}
if (attrs[Attribute.list.key] == Attribute.unchecked) {
return CheckboxPoint(
size: 14,
value: false,
enabled: !readOnly,
onChanged: (checked) => onCheckboxTap(line.documentOffset, checked),
uiBuilder: defaultStyles?.lists?.checkboxUIBuilder,
);
}
if (attrs.containsKey(Attribute.codeBlock.key)) {
return QuillNumberPoint(
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
style: defaultStyles!.code!.style
.copyWith(color: defaultStyles.code!.style.color!.withOpacity(0.4)),
width: 32,
attrs: attrs,
padding: 16,
withDot: false,
);
}
return null;
}
double _getIndentWidth() {
final attrs = block.style.attributes;

Loading…
Cancel
Save