Added option to modify SelectHeaderStyleButton options and changed Attribute to const (#889)

pull/895/head
Lucas Henrique Polazzo 3 years ago committed by GitHub
parent 1b8a6513bb
commit fc3b326b14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 136
      lib/src/models/documents/attribute.dart
  2. 10
      lib/src/translations/toolbar.i18n.dart
  3. 60
      lib/src/widgets/toolbar/select_header_style_button.dart

@ -10,7 +10,7 @@ enum AttributeScope {
} }
class Attribute<T> { class Attribute<T> {
Attribute(this.key, this.scope, this.value); const Attribute(this.key, this.scope, this.value);
/// Unique key of this attribute. /// Unique key of this attribute.
final String key; final String key;
@ -44,53 +44,53 @@ class Attribute<T> {
Attribute.script.key: Attribute.script, Attribute.script.key: Attribute.script,
}); });
static final BoldAttribute bold = BoldAttribute(); static const BoldAttribute bold = BoldAttribute();
static final ItalicAttribute italic = ItalicAttribute(); static const ItalicAttribute italic = ItalicAttribute();
static final SmallAttribute small = SmallAttribute(); static const SmallAttribute small = SmallAttribute();
static final UnderlineAttribute underline = UnderlineAttribute(); static const UnderlineAttribute underline = UnderlineAttribute();
static final StrikeThroughAttribute strikeThrough = StrikeThroughAttribute(); static const StrikeThroughAttribute strikeThrough = StrikeThroughAttribute();
static final InlineCodeAttribute inlineCode = InlineCodeAttribute(); static const InlineCodeAttribute inlineCode = InlineCodeAttribute();
static final FontAttribute font = FontAttribute(null); static const FontAttribute font = FontAttribute(null);
static final SizeAttribute size = SizeAttribute(null); static const SizeAttribute size = SizeAttribute(null);
static final LinkAttribute link = LinkAttribute(null); static const LinkAttribute link = LinkAttribute(null);
static final ColorAttribute color = ColorAttribute(null); static const ColorAttribute color = ColorAttribute(null);
static final BackgroundAttribute background = BackgroundAttribute(null); static const BackgroundAttribute background = BackgroundAttribute(null);
static final PlaceholderAttribute placeholder = PlaceholderAttribute(); static const PlaceholderAttribute placeholder = PlaceholderAttribute();
static final HeaderAttribute header = HeaderAttribute(); static const HeaderAttribute header = HeaderAttribute();
static final IndentAttribute indent = IndentAttribute(); static const IndentAttribute indent = IndentAttribute();
static final AlignAttribute align = AlignAttribute(null); static const AlignAttribute align = AlignAttribute(null);
static final ListAttribute list = ListAttribute(null); static const ListAttribute list = ListAttribute(null);
static final CodeBlockAttribute codeBlock = CodeBlockAttribute(); static const CodeBlockAttribute codeBlock = CodeBlockAttribute();
static final BlockQuoteAttribute blockQuote = BlockQuoteAttribute(); static const BlockQuoteAttribute blockQuote = BlockQuoteAttribute();
static final DirectionAttribute direction = DirectionAttribute(null); static const DirectionAttribute direction = DirectionAttribute(null);
static final WidthAttribute width = WidthAttribute(null); static const WidthAttribute width = WidthAttribute(null);
static final HeightAttribute height = HeightAttribute(null); static const HeightAttribute height = HeightAttribute(null);
static final StyleAttribute style = StyleAttribute(null); static const StyleAttribute style = StyleAttribute(null);
static final TokenAttribute token = TokenAttribute(''); static const TokenAttribute token = TokenAttribute('');
static final ScriptAttribute script = ScriptAttribute(''); static const ScriptAttribute script = ScriptAttribute('');
static const String mobileWidth = 'mobileWidth'; static const String mobileWidth = 'mobileWidth';
@ -138,47 +138,47 @@ class Attribute<T> {
Attribute.blockQuote.key, Attribute.blockQuote.key,
}); });
static Attribute<int?> get h1 => HeaderAttribute(level: 1); static const Attribute<int?> h1 = HeaderAttribute(level: 1);
static Attribute<int?> get h2 => HeaderAttribute(level: 2); static const Attribute<int?> h2 = HeaderAttribute(level: 2);
static Attribute<int?> get h3 => HeaderAttribute(level: 3); static const Attribute<int?> h3 = HeaderAttribute(level: 3);
// "attributes":{"align":"left"} // "attributes":{"align":"left"}
static Attribute<String?> get leftAlignment => AlignAttribute('left'); static const Attribute<String?> leftAlignment = AlignAttribute('left');
// "attributes":{"align":"center"} // "attributes":{"align":"center"}
static Attribute<String?> get centerAlignment => AlignAttribute('center'); static const Attribute<String?> centerAlignment = AlignAttribute('center');
// "attributes":{"align":"right"} // "attributes":{"align":"right"}
static Attribute<String?> get rightAlignment => AlignAttribute('right'); static const Attribute<String?> rightAlignment = AlignAttribute('right');
// "attributes":{"align":"justify"} // "attributes":{"align":"justify"}
static Attribute<String?> get justifyAlignment => AlignAttribute('justify'); static const Attribute<String?> justifyAlignment = AlignAttribute('justify');
// "attributes":{"list":"bullet"} // "attributes":{"list":"bullet"}
static Attribute<String?> get ul => ListAttribute('bullet'); static const Attribute<String?> ul = ListAttribute('bullet');
// "attributes":{"list":"ordered"} // "attributes":{"list":"ordered"}
static Attribute<String?> get ol => ListAttribute('ordered'); static const Attribute<String?> ol = ListAttribute('ordered');
// "attributes":{"list":"checked"} // "attributes":{"list":"checked"}
static Attribute<String?> get checked => ListAttribute('checked'); static const Attribute<String?> checked = ListAttribute('checked');
// "attributes":{"list":"unchecked"} // "attributes":{"list":"unchecked"}
static Attribute<String?> get unchecked => ListAttribute('unchecked'); static const Attribute<String?> unchecked = ListAttribute('unchecked');
// "attributes":{"direction":"rtl"} // "attributes":{"direction":"rtl"}
static Attribute<String?> get rtl => DirectionAttribute('rtl'); static const Attribute<String?> rtl = DirectionAttribute('rtl');
// "attributes":{"indent":1"} // "attributes":{"indent":1"}
static Attribute<int?> get indentL1 => IndentAttribute(level: 1); static const Attribute<int?> indentL1 = IndentAttribute(level: 1);
// "attributes":{"indent":2"} // "attributes":{"indent":2"}
static Attribute<int?> get indentL2 => IndentAttribute(level: 2); static const Attribute<int?> indentL2 = IndentAttribute(level: 2);
// "attributes":{"indent":3"} // "attributes":{"indent":3"}
static Attribute<int?> get indentL3 => IndentAttribute(level: 3); static const Attribute<int?> indentL3 = IndentAttribute(level: 3);
static Attribute<int?> getIndentLevel(int? level) { static Attribute<int?> getIndentLevel(int? level) {
if (level == 1) { if (level == 1) {
@ -244,101 +244,109 @@ class Attribute<T> {
} }
class BoldAttribute extends Attribute<bool> { class BoldAttribute extends Attribute<bool> {
BoldAttribute() : super('bold', AttributeScope.INLINE, true); const BoldAttribute() : super('bold', AttributeScope.INLINE, true);
} }
class ItalicAttribute extends Attribute<bool> { class ItalicAttribute extends Attribute<bool> {
ItalicAttribute() : super('italic', AttributeScope.INLINE, true); const ItalicAttribute() : super('italic', AttributeScope.INLINE, true);
} }
class SmallAttribute extends Attribute<bool> { class SmallAttribute extends Attribute<bool> {
SmallAttribute() : super('small', AttributeScope.INLINE, true); const SmallAttribute() : super('small', AttributeScope.INLINE, true);
} }
class UnderlineAttribute extends Attribute<bool> { class UnderlineAttribute extends Attribute<bool> {
UnderlineAttribute() : super('underline', AttributeScope.INLINE, true); const UnderlineAttribute() : super('underline', AttributeScope.INLINE, true);
} }
class StrikeThroughAttribute extends Attribute<bool> { class StrikeThroughAttribute extends Attribute<bool> {
StrikeThroughAttribute() : super('strike', AttributeScope.INLINE, true); const StrikeThroughAttribute() : super('strike', AttributeScope.INLINE, true);
} }
class InlineCodeAttribute extends Attribute<bool> { class InlineCodeAttribute extends Attribute<bool> {
InlineCodeAttribute() : super('code', AttributeScope.INLINE, true); const InlineCodeAttribute() : super('code', AttributeScope.INLINE, true);
} }
class FontAttribute extends Attribute<String?> { class FontAttribute extends Attribute<String?> {
FontAttribute(String? val) : super('font', AttributeScope.INLINE, val); const FontAttribute(String? val) : super('font', AttributeScope.INLINE, val);
} }
class SizeAttribute extends Attribute<String?> { class SizeAttribute extends Attribute<String?> {
SizeAttribute(String? val) : super('size', AttributeScope.INLINE, val); const SizeAttribute(String? val) : super('size', AttributeScope.INLINE, val);
} }
class LinkAttribute extends Attribute<String?> { class LinkAttribute extends Attribute<String?> {
LinkAttribute(String? val) : super('link', AttributeScope.INLINE, val); const LinkAttribute(String? val) : super('link', AttributeScope.INLINE, val);
} }
class ColorAttribute extends Attribute<String?> { class ColorAttribute extends Attribute<String?> {
ColorAttribute(String? val) : super('color', AttributeScope.INLINE, val); const ColorAttribute(String? val)
: super('color', AttributeScope.INLINE, val);
} }
class BackgroundAttribute extends Attribute<String?> { class BackgroundAttribute extends Attribute<String?> {
BackgroundAttribute(String? val) const BackgroundAttribute(String? val)
: super('background', AttributeScope.INLINE, val); : super('background', AttributeScope.INLINE, val);
} }
/// This is custom attribute for hint /// This is custom attribute for hint
class PlaceholderAttribute extends Attribute<bool> { class PlaceholderAttribute extends Attribute<bool> {
PlaceholderAttribute() : super('placeholder', AttributeScope.INLINE, true); const PlaceholderAttribute()
: super('placeholder', AttributeScope.INLINE, true);
} }
class HeaderAttribute extends Attribute<int?> { class HeaderAttribute extends Attribute<int?> {
HeaderAttribute({int? level}) : super('header', AttributeScope.BLOCK, level); const HeaderAttribute({int? level})
: super('header', AttributeScope.BLOCK, level);
} }
class IndentAttribute extends Attribute<int?> { class IndentAttribute extends Attribute<int?> {
IndentAttribute({int? level}) : super('indent', AttributeScope.BLOCK, level); const IndentAttribute({int? level})
: super('indent', AttributeScope.BLOCK, level);
} }
class AlignAttribute extends Attribute<String?> { class AlignAttribute extends Attribute<String?> {
AlignAttribute(String? val) : super('align', AttributeScope.BLOCK, val); const AlignAttribute(String? val) : super('align', AttributeScope.BLOCK, val);
} }
class ListAttribute extends Attribute<String?> { class ListAttribute extends Attribute<String?> {
ListAttribute(String? val) : super('list', AttributeScope.BLOCK, val); const ListAttribute(String? val) : super('list', AttributeScope.BLOCK, val);
} }
class CodeBlockAttribute extends Attribute<bool> { class CodeBlockAttribute extends Attribute<bool> {
CodeBlockAttribute() : super('code-block', AttributeScope.BLOCK, true); const CodeBlockAttribute() : super('code-block', AttributeScope.BLOCK, true);
} }
class BlockQuoteAttribute extends Attribute<bool> { class BlockQuoteAttribute extends Attribute<bool> {
BlockQuoteAttribute() : super('blockquote', AttributeScope.BLOCK, true); const BlockQuoteAttribute() : super('blockquote', AttributeScope.BLOCK, true);
} }
class DirectionAttribute extends Attribute<String?> { class DirectionAttribute extends Attribute<String?> {
DirectionAttribute(String? val) const DirectionAttribute(String? val)
: super('direction', AttributeScope.BLOCK, val); : super('direction', AttributeScope.BLOCK, val);
} }
class WidthAttribute extends Attribute<String?> { class WidthAttribute extends Attribute<String?> {
WidthAttribute(String? val) : super('width', AttributeScope.IGNORE, val); const WidthAttribute(String? val)
: super('width', AttributeScope.IGNORE, val);
} }
class HeightAttribute extends Attribute<String?> { class HeightAttribute extends Attribute<String?> {
HeightAttribute(String? val) : super('height', AttributeScope.IGNORE, val); const HeightAttribute(String? val)
: super('height', AttributeScope.IGNORE, val);
} }
class StyleAttribute extends Attribute<String?> { class StyleAttribute extends Attribute<String?> {
StyleAttribute(String? val) : super('style', AttributeScope.IGNORE, val); const StyleAttribute(String? val)
: super('style', AttributeScope.IGNORE, val);
} }
class TokenAttribute extends Attribute<String> { class TokenAttribute extends Attribute<String> {
TokenAttribute(String val) : super('token', AttributeScope.IGNORE, val); const TokenAttribute(String val) : super('token', AttributeScope.IGNORE, val);
} }
// `script` is supposed to be inline attribute but it is not supported yet // `script` is supposed to be inline attribute but it is not supported yet
class ScriptAttribute extends Attribute<String> { class ScriptAttribute extends Attribute<String> {
ScriptAttribute(String val) : super('script', AttributeScope.IGNORE, val); const ScriptAttribute(String val)
: super('script', AttributeScope.IGNORE, val);
} }

@ -337,11 +337,11 @@ extension Localization on String {
'Width': 'Largura', 'Width': 'Largura',
'Height': 'Altura', 'Height': 'Altura',
'Size': 'Tamanho', 'Size': 'Tamanho',
'Small': 'Small', 'Small': 'Pequeno',
'Large': 'Large', 'Large': 'Grande',
'Huge': 'Huge', 'Huge': 'Gigante',
'Clear': 'Clear', 'Clear': 'Limpar',
'Font': 'Font', 'Font': 'Fonte',
}, },
'pl': { 'pl': {
'Paste a link': 'Wklej link', 'Paste a link': 'Wklej link',

@ -12,13 +12,19 @@ class SelectHeaderStyleButton extends StatefulWidget {
required this.controller, required this.controller,
this.iconSize = kDefaultIconSize, this.iconSize = kDefaultIconSize,
this.iconTheme, this.iconTheme,
this.attributes = const [
Attribute.header,
Attribute.h1,
Attribute.h2,
Attribute.h3,
],
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
final QuillController controller; final QuillController controller;
final double iconSize; final double iconSize;
final QuillIconTheme? iconTheme; final QuillIconTheme? iconTheme;
final List<Attribute> attributes;
@override @override
_SelectHeaderStyleButtonState createState() => _SelectHeaderStyleButtonState createState() =>
@ -26,35 +32,32 @@ class SelectHeaderStyleButton extends StatefulWidget {
} }
class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> { class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
Attribute? _value; Attribute? _selectedAttribute;
Style get _selectionStyle => widget.controller.getSelectionStyle(); Style get _selectionStyle => widget.controller.getSelectionStyle();
final _valueToText = <Attribute, String>{
Attribute.header: 'N',
Attribute.h1: 'H1',
Attribute.h2: 'H2',
Attribute.h3: 'H3',
};
@override @override
void initState() { void initState() {
super.initState(); super.initState();
setState(() { setState(() {
_value = _getHeaderValue(); _selectedAttribute = _getHeaderValue();
}); });
widget.controller.addListener(_didChangeEditingValue); widget.controller.addListener(_didChangeEditingValue);
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final _valueToText = <Attribute, String>{ assert(
Attribute.header: 'N', widget.attributes.every((element) => _valueToText.keys.contains(element)),
Attribute.h1: 'H1', 'All attributes must be one of them: header, h1, h2 or h3',
Attribute.h2: 'H2', );
Attribute.h3: 'H3',
};
final _valueAttribute = <Attribute>[
Attribute.header,
Attribute.h1,
Attribute.h2,
Attribute.h3
];
final _valueString = <String>['N', 'H1', 'H2', 'H3'];
final theme = Theme.of(context); final theme = Theme.of(context);
final style = TextStyle( final style = TextStyle(
@ -64,7 +67,8 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: List.generate(4, (index) { children: widget.attributes.map((attribute) {
final isSelected = _selectedAttribute == attribute;
return Padding( return Padding(
// ignore: prefer_const_constructors // ignore: prefer_const_constructors
padding: EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0), padding: EdgeInsets.symmetric(horizontal: !kIsWeb ? 1.0 : 5.0),
@ -81,17 +85,21 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
widget.iconTheme?.borderRadius ?? 2)), widget.iconTheme?.borderRadius ?? 2)),
fillColor: _valueToText[_value] == _valueString[index] fillColor: isSelected
? (widget.iconTheme?.iconSelectedFillColor ?? ? (widget.iconTheme?.iconSelectedFillColor ??
theme.toggleableActiveColor) theme.toggleableActiveColor)
: (widget.iconTheme?.iconUnselectedFillColor ?? : (widget.iconTheme?.iconUnselectedFillColor ??
theme.canvasColor), theme.canvasColor),
onPressed: () => onPressed: () {
widget.controller.formatSelection(_valueAttribute[index]), final _attribute = _selectedAttribute == attribute
? Attribute.header
: attribute;
widget.controller.formatSelection(_attribute);
},
child: Text( child: Text(
_valueString[index], _valueToText[attribute] ?? '',
style: style.copyWith( style: style.copyWith(
color: _valueToText[_value] == _valueString[index] color: isSelected
? (widget.iconTheme?.iconSelectedColor ?? ? (widget.iconTheme?.iconSelectedColor ??
theme.primaryIconTheme.color) theme.primaryIconTheme.color)
: (widget.iconTheme?.iconUnselectedColor ?? : (widget.iconTheme?.iconUnselectedColor ??
@ -101,13 +109,13 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
), ),
), ),
); );
}), }).toList(),
); );
} }
void _didChangeEditingValue() { void _didChangeEditingValue() {
setState(() { setState(() {
_value = _getHeaderValue(); _selectedAttribute = _getHeaderValue();
}); });
} }
@ -127,7 +135,7 @@ class _SelectHeaderStyleButtonState extends State<SelectHeaderStyleButton> {
if (oldWidget.controller != widget.controller) { if (oldWidget.controller != widget.controller) {
oldWidget.controller.removeListener(_didChangeEditingValue); oldWidget.controller.removeListener(_didChangeEditingValue);
widget.controller.addListener(_didChangeEditingValue); widget.controller.addListener(_didChangeEditingValue);
_value = _getHeaderValue(); _selectedAttribute = _getHeaderValue();
} }
} }

Loading…
Cancel
Save