Add ability to set up horizontal spacing for block style (#2051)

Co-authored-by: dimkanovikov <Dmitriy.S.Novikov@rt.ru>
pull/2057/head
Dimka 9 months ago committed by GitHub
parent 58ee571c9d
commit fd69f614bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      example/lib/screens/quill/my_quill_editor.dart
  2. 1
      lib/flutter_quill.dart
  3. 12
      lib/src/common/structs/horizontal_spacing.dart
  4. 54
      lib/src/editor/raw_editor/raw_editor_state.dart
  5. 35
      lib/src/editor/widgets/default_styles.dart
  6. 25
      lib/src/editor/widgets/text/text_block.dart
  7. 7
      lib/src/editor/widgets/text/text_line.dart

@ -51,6 +51,7 @@ class MyQuillEditor extends StatelessWidget {
height: 1.15, height: 1.15,
fontWeight: FontWeight.w300, fontWeight: FontWeight.w300,
), ),
const HorizontalSpacing(0, 0),
const VerticalSpacing(16, 0), const VerticalSpacing(16, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,

@ -1,5 +1,6 @@
library flutter_quill; library flutter_quill;
export 'src/common/structs/horizontal_spacing.dart';
export 'src/common/structs/image_url.dart'; export 'src/common/structs/image_url.dart';
export 'src/common/structs/offset_value.dart'; export 'src/common/structs/offset_value.dart';
export 'src/common/structs/optional_size.dart'; export 'src/common/structs/optional_size.dart';

@ -0,0 +1,12 @@
import 'package:flutter/foundation.dart' show immutable;
@immutable
class HorizontalSpacing {
const HorizontalSpacing(
this.left,
this.right,
);
final double left;
final double right;
}

@ -20,6 +20,7 @@ import 'package:flutter/services.dart'
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart' import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'
show KeyboardVisibilityController; show KeyboardVisibilityController;
import '../../common/structs/horizontal_spacing.dart';
import '../../common/structs/offset_value.dart'; import '../../common/structs/offset_value.dart';
import '../../common/structs/vertical_spacing.dart'; import '../../common/structs/vertical_spacing.dart';
import '../../common/utils/cast.dart'; import '../../common/utils/cast.dart';
@ -1011,6 +1012,7 @@ class QuillRawEditorState extends EditorState
controller: controller, controller: controller,
textDirection: getDirectionOfNode(node), textDirection: getDirectionOfNode(node),
scrollBottomInset: widget.configurations.scrollBottomInset, scrollBottomInset: widget.configurations.scrollBottomInset,
horizontalSpacing: _getHorizontalSpacingForBlock(node, _styles),
verticalSpacing: _getVerticalSpacingForBlock(node, _styles), verticalSpacing: _getVerticalSpacingForBlock(node, _styles),
textSelection: controller.selection, textSelection: controller.selection,
color: widget.configurations.selectionColor, color: widget.configurations.selectionColor,
@ -1069,7 +1071,7 @@ class QuillRawEditorState extends EditorState
node, node,
null, null,
textLine, textLine,
0, _getHorizontalSpacingForLine(node, _styles),
_getVerticalSpacingForLine(node, _styles), _getVerticalSpacingForLine(node, _styles),
_textDirection, _textDirection,
controller.selection, controller.selection,
@ -1081,6 +1083,39 @@ class QuillRawEditorState extends EditorState
return editableTextLine; return editableTextLine;
} }
HorizontalSpacing _getHorizontalSpacingForLine(
Line line,
DefaultStyles? defaultStyles,
) {
final attrs = line.style.attributes;
if (attrs.containsKey(Attribute.header.key)) {
int level;
if (attrs[Attribute.header.key]!.value is double) {
level = attrs[Attribute.header.key]!.value.toInt();
} else {
level = attrs[Attribute.header.key]!.value;
}
switch (level) {
case 1:
return defaultStyles!.h1!.horizontalSpacing;
case 2:
return defaultStyles!.h2!.horizontalSpacing;
case 3:
return defaultStyles!.h3!.horizontalSpacing;
case 4:
return defaultStyles!.h4!.horizontalSpacing;
case 5:
return defaultStyles!.h5!.horizontalSpacing;
case 6:
return defaultStyles!.h6!.horizontalSpacing;
default:
throw ArgumentError('Invalid level $level');
}
}
return defaultStyles!.paragraph!.horizontalSpacing;
}
VerticalSpacing _getVerticalSpacingForLine( VerticalSpacing _getVerticalSpacingForLine(
Line line, Line line,
DefaultStyles? defaultStyles, DefaultStyles? defaultStyles,
@ -1114,6 +1149,23 @@ class QuillRawEditorState extends EditorState
return defaultStyles!.paragraph!.verticalSpacing; return defaultStyles!.paragraph!.verticalSpacing;
} }
HorizontalSpacing _getHorizontalSpacingForBlock(
Block node, DefaultStyles? defaultStyles) {
final attrs = node.style.attributes;
if (attrs.containsKey(Attribute.blockQuote.key)) {
return defaultStyles!.quote!.horizontalSpacing;
} else if (attrs.containsKey(Attribute.codeBlock.key)) {
return defaultStyles!.code!.horizontalSpacing;
} else if (attrs.containsKey(Attribute.indent.key)) {
return defaultStyles!.indent!.horizontalSpacing;
} else if (attrs.containsKey(Attribute.list.key)) {
return defaultStyles!.lists!.horizontalSpacing;
} else if (attrs.containsKey(Attribute.align.key)) {
return defaultStyles!.align!.horizontalSpacing;
}
return const HorizontalSpacing(0, 0);
}
VerticalSpacing _getVerticalSpacingForBlock( VerticalSpacing _getVerticalSpacingForBlock(
Block node, DefaultStyles? defaultStyles) { Block node, DefaultStyles? defaultStyles) {
final attrs = node.style.attributes; final attrs = node.style.attributes;

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../common/structs/horizontal_spacing.dart';
import '../../common/structs/vertical_spacing.dart'; import '../../common/structs/vertical_spacing.dart';
import '../../common/utils/platform.dart'; import '../../common/utils/platform.dart';
import '../../document/attribute.dart'; import '../../document/attribute.dart';
@ -36,6 +37,7 @@ class QuillStyles extends InheritedWidget {
class DefaultTextBlockStyle { class DefaultTextBlockStyle {
const DefaultTextBlockStyle( const DefaultTextBlockStyle(
this.style, this.style,
this.horizontalSpacing,
this.verticalSpacing, this.verticalSpacing,
this.lineSpacing, this.lineSpacing,
this.decoration, this.decoration,
@ -44,6 +46,9 @@ class DefaultTextBlockStyle {
/// Base text style for a text block. /// Base text style for a text block.
final TextStyle style; final TextStyle style;
/// Horizontal spacing around a text block.
final HorizontalSpacing horizontalSpacing;
/// Vertical spacing around a text block. /// Vertical spacing around a text block.
final VerticalSpacing verticalSpacing; final VerticalSpacing verticalSpacing;
@ -151,6 +156,7 @@ class InlineCodeStyle {
class DefaultListBlockStyle extends DefaultTextBlockStyle { class DefaultListBlockStyle extends DefaultTextBlockStyle {
const DefaultListBlockStyle( const DefaultListBlockStyle(
super.style, super.style,
super.horizontalSpacing,
super.verticalSpacing, super.verticalSpacing,
super.lineSpacing, super.lineSpacing,
super.decoration, super.decoration,
@ -238,7 +244,8 @@ class DefaultStyles {
height: 1.15, height: 1.15,
decoration: TextDecoration.none, decoration: TextDecoration.none,
); );
const baseSpacing = VerticalSpacing(6, 0); const baseHorizontalSpacing = HorizontalSpacing(0, 0);
const baseVerticalSpacing = VerticalSpacing(6, 0);
String fontFamily; String fontFamily;
if (isAppleOS(platform: themeData.platform, supportWeb: true)) { if (isAppleOS(platform: themeData.platform, supportWeb: true)) {
fontFamily = 'Menlo'; fontFamily = 'Menlo';
@ -262,6 +269,7 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(16, 0), const VerticalSpacing(16, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null), null),
@ -274,6 +282,7 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(8, 0), const VerticalSpacing(8, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null), null),
@ -286,6 +295,7 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(8, 0), const VerticalSpacing(8, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
@ -299,6 +309,7 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(6, 0), const VerticalSpacing(6, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
@ -312,6 +323,7 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(6, 0), const VerticalSpacing(6, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
@ -325,36 +337,42 @@ class DefaultStyles {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
decoration: TextDecoration.none, decoration: TextDecoration.none,
), ),
baseHorizontalSpacing,
const VerticalSpacing(4, 0), const VerticalSpacing(4, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
lineHeightNormal: DefaultTextBlockStyle( lineHeightNormal: DefaultTextBlockStyle(
baseStyle.copyWith(height: 1.15), baseStyle.copyWith(height: 1.15),
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
lineHeightTight: DefaultTextBlockStyle( lineHeightTight: DefaultTextBlockStyle(
baseStyle.copyWith(height: 1.30), baseStyle.copyWith(height: 1.30),
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
lineHeightOneAndHalf: DefaultTextBlockStyle( lineHeightOneAndHalf: DefaultTextBlockStyle(
baseStyle.copyWith(height: 1.55), baseStyle.copyWith(height: 1.55),
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
lineHeightDouble: DefaultTextBlockStyle( lineHeightDouble: DefaultTextBlockStyle(
baseStyle.copyWith(height: 2), baseStyle.copyWith(height: 2),
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
paragraph: DefaultTextBlockStyle( paragraph: DefaultTextBlockStyle(
baseStyle, baseStyle,
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
@ -403,19 +421,22 @@ class DefaultStyles {
height: 1.5, height: 1.5,
color: Colors.grey.withOpacity(0.6), color: Colors.grey.withOpacity(0.6),
), ),
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null), null),
lists: DefaultListBlockStyle( lists: DefaultListBlockStyle(
baseStyle, baseStyle,
baseSpacing, baseHorizontalSpacing,
baseVerticalSpacing,
const VerticalSpacing(0, 6), const VerticalSpacing(0, 6),
null, null,
null, null,
), ),
quote: DefaultTextBlockStyle( quote: DefaultTextBlockStyle(
TextStyle(color: baseStyle.color!.withOpacity(0.6)), TextStyle(color: baseStyle.color!.withOpacity(0.6)),
baseSpacing, baseHorizontalSpacing,
baseVerticalSpacing,
const VerticalSpacing(6, 2), const VerticalSpacing(6, 2),
BoxDecoration( BoxDecoration(
border: Border( border: Border(
@ -430,7 +451,8 @@ class DefaultStyles {
fontSize: 13, fontSize: 13,
height: 1.15, height: 1.15,
), ),
baseSpacing, baseHorizontalSpacing,
baseVerticalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
BoxDecoration( BoxDecoration(
color: Colors.grey.shade50, color: Colors.grey.shade50,
@ -438,18 +460,21 @@ class DefaultStyles {
)), )),
indent: DefaultTextBlockStyle( indent: DefaultTextBlockStyle(
baseStyle, baseStyle,
baseSpacing, baseHorizontalSpacing,
baseVerticalSpacing,
const VerticalSpacing(0, 6), const VerticalSpacing(0, 6),
null, null,
), ),
align: DefaultTextBlockStyle( align: DefaultTextBlockStyle(
baseStyle, baseStyle,
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,
), ),
leading: DefaultTextBlockStyle( leading: DefaultTextBlockStyle(
baseStyle, baseStyle,
baseHorizontalSpacing,
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
const VerticalSpacing(0, 0), const VerticalSpacing(0, 0),
null, null,

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import '../../../common/structs/horizontal_spacing.dart';
import '../../../common/structs/vertical_spacing.dart'; import '../../../common/structs/vertical_spacing.dart';
import '../../../common/utils/font.dart'; import '../../../common/utils/font.dart';
import '../../../controller/quill_controller.dart'; import '../../../controller/quill_controller.dart';
@ -61,6 +62,7 @@ class EditableTextBlock extends StatelessWidget {
required this.controller, required this.controller,
required this.textDirection, required this.textDirection,
required this.scrollBottomInset, required this.scrollBottomInset,
required this.horizontalSpacing,
required this.verticalSpacing, required this.verticalSpacing,
required this.textSelection, required this.textSelection,
required this.color, required this.color,
@ -86,6 +88,7 @@ class EditableTextBlock extends StatelessWidget {
final QuillController controller; final QuillController controller;
final TextDirection textDirection; final TextDirection textDirection;
final double scrollBottomInset; final double scrollBottomInset;
final HorizontalSpacing horizontalSpacing;
final VerticalSpacing verticalSpacing; final VerticalSpacing verticalSpacing;
final TextSelection textSelection; final TextSelection textSelection;
final Color color; final Color color;
@ -113,7 +116,8 @@ class EditableTextBlock extends StatelessWidget {
return _EditableBlock( return _EditableBlock(
block: block, block: block,
textDirection: textDirection, textDirection: textDirection,
padding: verticalSpacing, horizontalSpacing: horizontalSpacing,
verticalSpacing: verticalSpacing,
scrollBottomInset: scrollBottomInset, scrollBottomInset: scrollBottomInset,
decoration: decoration:
_getDecorationForBlock(block, defaultStyles) ?? const BoxDecoration(), _getDecorationForBlock(block, defaultStyles) ?? const BoxDecoration(),
@ -304,7 +308,7 @@ class EditableTextBlock extends StatelessWidget {
return null; return null;
} }
double _getIndentWidth(BuildContext context, int count) { HorizontalSpacing _getIndentWidth(BuildContext context, int count) {
final defaultStyles = QuillStyles.getStyles(context, false)!; final defaultStyles = QuillStyles.getStyles(context, false)!;
final fontSize = defaultStyles.paragraph?.style.fontSize ?? 16; final fontSize = defaultStyles.paragraph?.style.fontSize ?? 16;
final attrs = block.style.attributes; final attrs = block.style.attributes;
@ -316,7 +320,7 @@ class EditableTextBlock extends StatelessWidget {
} }
if (attrs.containsKey(Attribute.blockQuote.key)) { if (attrs.containsKey(Attribute.blockQuote.key)) {
return fontSize + extraIndent; return HorizontalSpacing(fontSize + extraIndent, 0);
} }
var baseIndent = 0.0; var baseIndent = 0.0;
@ -330,7 +334,7 @@ class EditableTextBlock extends StatelessWidget {
} }
} }
return baseIndent + extraIndent; return HorizontalSpacing(baseIndent + extraIndent, 0);
} }
VerticalSpacing _getSpacingForLine( VerticalSpacing _getSpacingForLine(
@ -715,7 +719,8 @@ class _EditableBlock extends MultiChildRenderObjectWidget {
const _EditableBlock( const _EditableBlock(
{required this.block, {required this.block,
required this.textDirection, required this.textDirection,
required this.padding, required this.horizontalSpacing,
required this.verticalSpacing,
required this.scrollBottomInset, required this.scrollBottomInset,
required this.decoration, required this.decoration,
required this.contentPadding, required this.contentPadding,
@ -723,13 +728,17 @@ class _EditableBlock extends MultiChildRenderObjectWidget {
final Block block; final Block block;
final TextDirection textDirection; final TextDirection textDirection;
final VerticalSpacing padding; final HorizontalSpacing horizontalSpacing;
final VerticalSpacing verticalSpacing;
final double scrollBottomInset; final double scrollBottomInset;
final Decoration decoration; final Decoration decoration;
final EdgeInsets? contentPadding; final EdgeInsets? contentPadding;
EdgeInsets get _padding => EdgeInsets get _padding => EdgeInsets.only(
EdgeInsets.only(top: padding.top, bottom: padding.bottom); left: horizontalSpacing.left,
right: horizontalSpacing.right,
top: verticalSpacing.top,
bottom: verticalSpacing.bottom);
EdgeInsets get _contentPadding => contentPadding ?? EdgeInsets.zero; EdgeInsets get _contentPadding => contentPadding ?? EdgeInsets.zero;

@ -602,7 +602,7 @@ class EditableTextLine extends RenderObjectWidget {
this.line, this.line,
this.leading, this.leading,
this.body, this.body,
this.indentWidth, this.horizontalSpacing,
this.verticalSpacing, this.verticalSpacing,
this.textDirection, this.textDirection,
this.textSelection, this.textSelection,
@ -616,7 +616,7 @@ class EditableTextLine extends RenderObjectWidget {
final Line line; final Line line;
final Widget? leading; final Widget? leading;
final Widget body; final Widget body;
final double indentWidth; final HorizontalSpacing horizontalSpacing;
final VerticalSpacing verticalSpacing; final VerticalSpacing verticalSpacing;
final TextDirection textDirection; final TextDirection textDirection;
final TextSelection textSelection; final TextSelection textSelection;
@ -666,7 +666,8 @@ class EditableTextLine extends RenderObjectWidget {
EdgeInsetsGeometry _getPadding() { EdgeInsetsGeometry _getPadding() {
return EdgeInsetsDirectional.only( return EdgeInsetsDirectional.only(
start: indentWidth, start: horizontalSpacing.left,
end: horizontalSpacing.right,
top: verticalSpacing.top, top: verticalSpacing.top,
bottom: verticalSpacing.bottom); bottom: verticalSpacing.bottom);
} }

Loading…
Cancel
Save