Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Enable BoxDecoration for DefaultTextBlockStyle of header Attribute #2438

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- `decoration` property in `DefaultTextBlockStyle` for the `header` attribute to customize headers with borders, background colors, and other styles using `BoxDecoration` [#2429](https://github.com/singerdmx/flutter-quill/pull/2429).

## [11.0.0-dev.21] - 2025-01-21

### Added
Expand Down
32 changes: 29 additions & 3 deletions lib/src/editor/raw_editor/raw_editor_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,8 @@ class QuillRawEditorState extends EditorState
prevNodeOl = attrs[Attribute.list.key] == Attribute.ol;
final nodeTextDirection = getDirectionOfNode(node, _textDirection);
if (node is Line) {
final editableTextLine = _getEditableTextLineFromNode(node, context);
final editableTextLine =
_getEditableTextLineFromNode(node, context, attrs);
result.add(Directionality(
textDirection: nodeTextDirection, child: editableTextLine));
} else if (node is Block) {
Expand Down Expand Up @@ -638,7 +639,7 @@ class QuillRawEditorState extends EditorState
}

EditableTextLine _getEditableTextLineFromNode(
Line node, BuildContext context) {
Line node, BuildContext context, Map<String, Attribute<dynamic>> attrs) {
final textLine = TextLine(
line: node,
textDirection: _textDirection,
Expand Down Expand Up @@ -666,7 +667,8 @@ class QuillRawEditorState extends EditorState
_hasFocus,
MediaQuery.devicePixelRatioOf(context),
_cursorCont,
_styles!.inlineCode!);
_styles!.inlineCode!,
_getDecoration(node, _styles, attrs));
return editableTextLine;
}

Expand Down Expand Up @@ -770,6 +772,30 @@ class QuillRawEditorState extends EditorState
return VerticalSpacing.zero;
}

BoxDecoration? _getDecoration(Node node, DefaultStyles? defaultStyles,
Map<String, Attribute<dynamic>> attrs) {
if (attrs.containsKey(Attribute.header.key)) {
final level = attrs[Attribute.header.key]!.value;
switch (level) {
case 1:
return defaultStyles!.h1!.decoration;
case 2:
return defaultStyles!.h2!.decoration;
case 3:
return defaultStyles!.h3!.decoration;
case 4:
return defaultStyles!.h4!.decoration;
case 5:
return defaultStyles!.h5!.decoration;
case 6:
return defaultStyles!.h6!.decoration;
default:
throw ArgumentError('Invalid level $level');
}
}
return null;
}

void _didChangeTextEditingValueListener() {
_didChangeTextEditingValue(controller.ignoreFocusOnTextChange);
}
Expand Down
66 changes: 33 additions & 33 deletions lib/src/editor/widgets/text/text_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -174,39 +174,39 @@ class EditableTextBlock extends StatelessWidget {
for (final line in Iterable.castFrom<dynamic, Line>(block.children)) {
index++;
final editableTextLine = EditableTextLine(
line,
_buildLeading(
context: context,
line: line,
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
),
TextLine(
line: line,
textDirection: textDirection,
embedBuilder: embedBuilder,
customStyleBuilder: customStyleBuilder,
styles: styles!,
readOnly: readOnly,
controller: controller,
linkActionPicker: linkActionPicker,
onLaunchUrl: onLaunchUrl,
customLinkPrefixes: customLinkPrefixes,
customRecognizerBuilder: customRecognizerBuilder,
composingRange: composingRange,
),
indentWidthBuilder(block, context, count, numberPointWidthBuilder),
_getSpacingForLine(line, index, count, defaultStyles),
textDirection,
textSelection,
color,
enableInteractiveSelection,
hasFocus,
MediaQuery.devicePixelRatioOf(context),
cursorCont,
styles!.inlineCode!,
);
line,
_buildLeading(
context: context,
line: line,
index: index,
indentLevelCounts: indentLevelCounts,
count: count,
Comment on lines +177 to +183
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you minimize the changes and remove any formatting or changes that not related to this functionality, reverting the changes to the example and sample data json, mainly because we want a cleaner commit history that's organized and also to avoid any possible regressions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EchoEllet
thank you for your review.

I have fixed

4eb8652

),
TextLine(
line: line,
textDirection: textDirection,
embedBuilder: embedBuilder,
customStyleBuilder: customStyleBuilder,
styles: styles!,
readOnly: readOnly,
controller: controller,
linkActionPicker: linkActionPicker,
onLaunchUrl: onLaunchUrl,
customLinkPrefixes: customLinkPrefixes,
customRecognizerBuilder: customRecognizerBuilder,
composingRange: composingRange,
),
indentWidthBuilder(block, context, count, numberPointWidthBuilder),
_getSpacingForLine(line, index, count, defaultStyles),
textDirection,
textSelection,
color,
enableInteractiveSelection,
hasFocus,
MediaQuery.devicePixelRatioOf(context),
cursorCont,
styles!.inlineCode!,
null);
final nodeTextDirection = getDirectionOfNode(line, textDirection);
children.add(
Directionality(
Expand Down
25 changes: 23 additions & 2 deletions lib/src/editor/widgets/text/text_line.dart
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,7 @@ class EditableTextLine extends RenderObjectWidget {
this.devicePixelRatio,
this.cursorCont,
this.inlineCodeStyle,
this.decoration,
{super.key});

final Line line;
Expand All @@ -701,6 +702,7 @@ class EditableTextLine extends RenderObjectWidget {
final double devicePixelRatio;
final CursorCont cursorCont;
final InlineCodeStyle inlineCodeStyle;
final BoxDecoration? decoration;

@override
RenderObjectElement createElement() {
Expand All @@ -719,7 +721,8 @@ class EditableTextLine extends RenderObjectWidget {
_getPadding(),
color,
cursorCont,
inlineCodeStyle);
inlineCodeStyle,
decoration);
}

@override
Expand All @@ -735,7 +738,8 @@ class EditableTextLine extends RenderObjectWidget {
..hasFocus = hasFocus
..setDevicePixelRatio(devicePixelRatio)
..setCursorCont(cursorCont)
..setInlineCodeStyle(inlineCodeStyle);
..setInlineCodeStyle(inlineCodeStyle)
..setDecoration(decoration);
}

EdgeInsetsGeometry _getPadding() {
Expand All @@ -762,6 +766,7 @@ class RenderEditableTextLine extends RenderEditableBox {
this.color,
this.cursorCont,
this.inlineCodeStyle,
this.decoration,
);

RenderBox? _leading;
Expand All @@ -780,6 +785,7 @@ class RenderEditableTextLine extends RenderEditableBox {
List<TextBox>? _selectedRects;
late Rect _caretPrototype;
InlineCodeStyle inlineCodeStyle;
BoxDecoration? decoration;
final Map<TextLineSlot, RenderBox> children = <TextLineSlot, RenderBox>{};

Iterable<RenderBox> get _children sync* {
Expand Down Expand Up @@ -895,6 +901,12 @@ class RenderEditableTextLine extends RenderEditableBox {
markNeedsLayout();
}

void setDecoration(BoxDecoration? newDecoration) {
if (decoration == newDecoration) return;
decoration = newDecoration;
markNeedsPaint();
}

// Start selection implementation

bool containsTextSelection() {
Expand Down Expand Up @@ -1284,6 +1296,15 @@ class RenderEditableTextLine extends RenderEditableBox {
);
}
}
final boxDecoration = decoration;
if (boxDecoration != null) {
final paintRect = offset & size;
boxDecoration.createBoxPainter().paint(
context.canvas,
paintRect.topLeft,
ImageConfiguration(size: paintRect.size),
);
}

if (_body != null) {
final parentData = _body!.parentData as BoxParentData;
Expand Down
Loading