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/controller.dart';
export 'src/widgets/default_styles.dart'; export 'src/widgets/default_styles.dart';
export 'src/widgets/editor.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/link.dart' show LinkActionPickerDelegate, LinkMenuAction;
export 'src/widgets/style_widgets/style_widgets.dart'; export 'src/widgets/style_widgets/style_widgets.dart';
export 'src/widgets/toolbar.dart'; export 'src/widgets/toolbar.dart';

@ -3,11 +3,23 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../flutter_quill.dart'; import '../../flutter_quill.dart';
import '../models/documents/nodes/line.dart';
import 'text_selection.dart'; import 'text_selection.dart';
typedef EmbedBuilder = Widget Function(BuildContext context, typedef EmbedBuilder = Widget Function(BuildContext context,
QuillController controller, Embed node, bool readOnly); 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); typedef CustomStyleBuilder = TextStyle Function(Attribute attribute);
/// Delegate interface for the [EditorTextSelectionGestureDetectorBuilder]. /// Delegate interface for the [EditorTextSelectionGestureDetectorBuilder].

@ -20,6 +20,7 @@ import 'default_styles.dart';
import 'delegate.dart'; import 'delegate.dart';
import 'embeds/default_embed_builder.dart'; import 'embeds/default_embed_builder.dart';
import 'float_cursor.dart'; import 'float_cursor.dart';
import 'leading/default_leading_builder.dart';
import 'link.dart'; import 'link.dart';
import 'raw_editor.dart'; import 'raw_editor.dart';
import 'text_selection.dart'; import 'text_selection.dart';
@ -168,6 +169,7 @@ class QuillEditor extends StatefulWidget {
this.onSingleLongTapMoveUpdate, this.onSingleLongTapMoveUpdate,
this.onSingleLongTapEnd, this.onSingleLongTapEnd,
this.embedBuilder = defaultEmbedBuilder, this.embedBuilder = defaultEmbedBuilder,
this.leadingBuilder = defaultLeadingBuilder,
this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, this.linkActionPickerDelegate = defaultLinkActionPickerDelegate,
this.customStyleBuilder, this.customStyleBuilder,
this.locale, this.locale,
@ -339,6 +341,7 @@ class QuillEditor extends StatefulWidget {
onSingleLongTapEnd; onSingleLongTapEnd;
final EmbedBuilder embedBuilder; final EmbedBuilder embedBuilder;
final LeadingBuilder leadingBuilder;
final CustomStyleBuilder? customStyleBuilder; final CustomStyleBuilder? customStyleBuilder;
/// The locale to use for the editor toolbar, defaults to system locale /// The locale to use for the editor toolbar, defaults to system locale
@ -453,6 +456,7 @@ class QuillEditorState extends State<QuillEditor>
enableInteractiveSelection: widget.enableInteractiveSelection, enableInteractiveSelection: widget.enableInteractiveSelection,
scrollPhysics: widget.scrollPhysics, scrollPhysics: widget.scrollPhysics,
embedBuilder: widget.embedBuilder, embedBuilder: widget.embedBuilder,
leadingBuilder: widget.leadingBuilder,
linkActionPickerDelegate: widget.linkActionPickerDelegate, linkActionPickerDelegate: widget.linkActionPickerDelegate,
customStyleBuilder: widget.customStyleBuilder, customStyleBuilder: widget.customStyleBuilder,
floatingCursorDisabled: widget.floatingCursorDisabled, 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/default_embed_builder.dart';
import 'embeds/image.dart'; import 'embeds/image.dart';
import 'keyboard_listener.dart'; import 'keyboard_listener.dart';
import 'leading/default_leading_builder.dart';
import 'link.dart'; import 'link.dart';
import 'proxy.dart'; import 'proxy.dart';
import 'quill_single_child_scroll_view.dart'; import 'quill_single_child_scroll_view.dart';
@ -72,6 +73,7 @@ class RawEditor extends StatefulWidget {
this.enableInteractiveSelection = true, this.enableInteractiveSelection = true,
this.scrollPhysics, this.scrollPhysics,
this.embedBuilder = defaultEmbedBuilder, this.embedBuilder = defaultEmbedBuilder,
this.leadingBuilder = defaultLeadingBuilder,
this.linkActionPickerDelegate = defaultLinkActionPickerDelegate, this.linkActionPickerDelegate = defaultLinkActionPickerDelegate,
this.customStyleBuilder, this.customStyleBuilder,
this.floatingCursorDisabled = false}) this.floatingCursorDisabled = false})
@ -223,6 +225,9 @@ class RawEditor extends StatefulWidget {
/// Builder function for embeddable objects. /// Builder function for embeddable objects.
final EmbedBuilder embedBuilder; final EmbedBuilder embedBuilder;
/// Builder function for leading objects.
final LeadingBuilder leadingBuilder;
final LinkActionPickerDelegate linkActionPickerDelegate; final LinkActionPickerDelegate linkActionPickerDelegate;
final CustomStyleBuilder? customStyleBuilder; final CustomStyleBuilder? customStyleBuilder;
final bool floatingCursorDisabled; final bool floatingCursorDisabled;
@ -456,6 +461,7 @@ class RawEditorState extends EditorState
? const EdgeInsets.all(16) ? const EdgeInsets.all(16)
: null, : null,
embedBuilder: widget.embedBuilder, embedBuilder: widget.embedBuilder,
leadingBuilder: widget.leadingBuilder,
linkActionPicker: _linkActionPicker, linkActionPicker: _linkActionPicker,
onLaunchUrl: widget.onLaunchUrl, onLaunchUrl: widget.onLaunchUrl,
cursorCont: _cursorCont, cursorCont: _cursorCont,

@ -59,6 +59,7 @@ class EditableTextBlock extends StatelessWidget {
required this.hasFocus, required this.hasFocus,
required this.contentPadding, required this.contentPadding,
required this.embedBuilder, required this.embedBuilder,
required this.leadingBuilder,
required this.linkActionPicker, required this.linkActionPicker,
required this.cursorCont, required this.cursorCont,
required this.indentLevelCounts, required this.indentLevelCounts,
@ -80,12 +81,13 @@ class EditableTextBlock extends StatelessWidget {
final bool hasFocus; final bool hasFocus;
final EdgeInsets? contentPadding; final EdgeInsets? contentPadding;
final EmbedBuilder embedBuilder; final EmbedBuilder embedBuilder;
final LeadingBuilder leadingBuilder;
final LinkActionPicker linkActionPicker; final LinkActionPicker linkActionPicker;
final ValueChanged<String>? onLaunchUrl; final ValueChanged<String>? onLaunchUrl;
final CustomStyleBuilder? customStyleBuilder; final CustomStyleBuilder? customStyleBuilder;
final CursorCont cursorCont; final CursorCont cursorCont;
final Map<int, int> indentLevelCounts; final Map<int, int> indentLevelCounts;
final Function(int, bool) onCheckboxTap; final CheckboxTapCallback onCheckboxTap;
final bool readOnly; final bool readOnly;
@override @override
@ -126,7 +128,15 @@ class EditableTextBlock extends StatelessWidget {
index++; index++;
final editableTextLine = EditableTextLine( final editableTextLine = EditableTextLine(
line, line,
_buildLeading(context, line, index, indentLevelCounts, count), leadingBuilder(
context,
line,
index,
indentLevelCounts,
count,
onCheckboxTap,
readOnly,
),
TextLine( TextLine(
line: line, line: line,
textDirection: textDirection, textDirection: textDirection,
@ -154,66 +164,6 @@ class EditableTextBlock extends StatelessWidget {
return children.toList(growable: false); 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() { double _getIndentWidth() {
final attrs = block.style.attributes; final attrs = block.style.attributes;

Loading…
Cancel
Save