Explorar el Código

add color attribute

lucky1213 hace 4 años
padre
commit
31427306d2

+ 29
- 5
packages/notus/lib/src/document/attributes.dart Ver fichero

@@ -75,6 +75,8 @@ class NotusAttribute<T> implements NotusAttributeBuilder<T> {
75 75
   static final Map<String, NotusAttributeBuilder> _registry = {
76 76
     NotusAttribute.bold.key: NotusAttribute.bold,
77 77
     NotusAttribute.line.key: NotusAttribute.line,
78
+    NotusAttribute.color.key: NotusAttribute.color,
79
+    NotusAttribute.highlight.key: NotusAttribute.highlight,
78 80
     NotusAttribute.italic.key: NotusAttribute.italic,
79 81
     NotusAttribute.link.key: NotusAttribute.link,
80 82
     NotusAttribute.heading.key: NotusAttribute.heading,
@@ -97,11 +99,11 @@ class NotusAttribute<T> implements NotusAttributeBuilder<T> {
97 99
   // Line attributes
98 100
   static const line = LineAttributeBuilder._();
99 101
 
100
-  /// Alias for [NotusAttribute.line.underline].
101
-  static NotusAttribute<String> get underline => line.underline;
102
+  // SearchHighLight attributes
103
+  static const highlight = _HighlightAttribute();
102 104
 
103
-  /// Alias for [NotusAttribute.line.deleteline].
104
-  static NotusAttribute<String> get deleteline => line.deleteline;
105
+  // Color attributes
106
+  static const color = ColorAttributeBuilder._();
105 107
 
106 108
   /// Heading style attribute.
107 109
   // ignore: const_eval_throws_exception
@@ -375,6 +377,28 @@ class LineAttributeBuilder extends NotusAttributeBuilder<String> {
375 377
   NotusAttribute<String> get deleteline => NotusAttribute<String>._(key, scope, 'deleteline');
376 378
 }
377 379
 
380
+/// Builder for highlight attribute values.
381
+///
382
+/// There is no need to use this class directly, consider using
383
+/// [NotusAttribute.highlight] instead.
384
+class _HighlightAttribute extends NotusAttribute<bool> {
385
+  const _HighlightAttribute() : super._('highlight', NotusAttributeScope.inline, true);
386
+}
387
+
388
+/// Builder for color attribute values.
389
+///
390
+/// There is no need to use this class directly, consider using
391
+/// [NotusAttribute.color] instead.
392
+class ColorAttributeBuilder extends NotusAttributeBuilder<String> {
393
+  static const _kColor = 'color';
394
+  const ColorAttributeBuilder._()
395
+      : super._(_kColor, NotusAttributeScope.inline);
396
+
397
+  /// Creates a Highlight attribute with specified Highlight [value].
398
+  NotusAttribute<String> fromString(String value) =>
399
+      NotusAttribute<String>._(key, scope, value);
400
+}
401
+
378 402
 /// Builder for heading attribute styles.
379 403
 ///
380 404
 /// There is no need to use this class directly, consider using
@@ -438,7 +462,7 @@ class EmbedAttributeBuilder
438 462
 
439 463
   NotusAttribute<Map<String, dynamic>> image(String source) =>
440 464
       EmbedAttribute.image(source);
441
-
465
+  
442 466
   @override
443 467
   NotusAttribute<Map<String, dynamic>> get unset => EmbedAttribute._(null);
444 468
 

+ 1
- 1
packages/zefyr/example/android/build.gradle Ver fichero

@@ -5,7 +5,7 @@ buildscript {
5 5
     }
6 6
 
7 7
     dependencies {
8
-        classpath 'com.android.tools.build:gradle:3.1.2'
8
+        classpath 'com.android.tools.build:gradle:3.5.0'
9 9
     }
10 10
 }
11 11
 

+ 2
- 0
packages/zefyr/example/android/gradle.properties Ver fichero

@@ -1,2 +1,4 @@
1 1
 org.gradle.jvmargs=-Xmx1536M
2 2
 android.enableR8=true
3
+android.enableJetifier=true
4
+android.useAndroidX=true

+ 1
- 1
packages/zefyr/example/android/gradle/wrapper/gradle-wrapper.properties Ver fichero

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
3 3
 distributionPath=wrapper/dists
4 4
 zipStoreBase=GRADLE_USER_HOME
5 5
 zipStorePath=wrapper/dists
6
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

+ 45
- 27
packages/zefyr/example/lib/src/full_page.dart Ver fichero

@@ -30,17 +30,13 @@ class FullPageEditorScreen extends StatefulWidget {
30 30
   _FullPageEditorScreenState createState() => _FullPageEditorScreenState();
31 31
 }
32 32
 
33
-final doc =
34
-    r'[{"insert":"Zefyr", "attributes":{"line": "underline"}},{"insert":"\n"}]';
35
-    
36
-    
37
-    // ,{"insert":"\n","attributes":{"heading":1}},{"insert":"Soft and gentle rich text editing for Flutter applications.","attributes":{"i":true}},{"insert":"\n"},{"insert":"​","attributes":{"embed":{"type":"image","source":"asset://images/breeze.jpg"}}},{"insert":"\n"},{"insert":"Photo by Hiroyuki Takeda.","attributes":{"i":true}},{"insert":"\nZefyr is currently in "},{"insert":"early preview","attributes":{"b":true}},{"insert":". If you have a feature request or found a bug, please file it at the "},{"insert":"issue tracker","attributes":{"a":"https://github.com/memspace/zefyr/issues"}},{"insert":'
38
-    // r'".\nDocumentation"},{"insert":"\n","attributes":{"heading":3}},{"insert":"Quick Start","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/quick_start.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Data Format and Document Model","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/data_and_document.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Style Attributes","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/attr'
39
-    // r'ibutes.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Heuristic Rules","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/heuristics.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"FAQ","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/faq.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Clean and modern look"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Zefyr’s rich text editor is built with simplicity and fle'
40
-    // r'xibility in mind. It provides clean interface for distraction-free editing. Think Medium.com-like experience.\nMarkdown inspired semantics"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Ever needed to have a heading line inside of a quote block, like this:\nI’m a Markdown heading"},{"insert":"\n","attributes":{"block":"quote","heading":3}},{"insert":"And I’m a regular paragraph"},{"insert":"\n","attributes":{"block":"quote"}},{"insert":"Code blocks"},{"insert":"\n","attributes":{"headin'
41
-    // r'g":2}},{"insert":"Of course:\nimport ‘package:flutter/material.dart’;"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"import ‘package:zefyr/zefyr.dart’;"},{"insert":"\n\n","attributes":{"block":"code"}},{"insert":"void main() {"},{"insert":"\n","attributes":{"block":"code"}},{"insert":" runApp(MyZefyrApp());"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"}"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"\n\n\n"}]';
42
-
43 33
 Delta getDelta() {
34
+  final doc =
35
+    r'[{"insert":"Zefyr", "attributes": {"color": "#595959", "highlight": true}},{"insert":"\n","attributes":{"heading":1}},{"insert":"Soft and gentle rich text editing for Flutter applications.","attributes":{"i":true}},{"insert":"\n"},{"insert":"​","attributes":{"embed":{"type":"image","source":"asset://images/breeze.jpg"}}},{"insert":"\n"},{"insert":"Photo by Hiroyuki Takeda.","attributes":{"i":true}},{"insert":"\nZefyr is currently in "},{"insert":"early preview","attributes":{"b":true}},{"insert":". If you have a feature request or found a bug, please file it at the "},{"insert":"issue tracker","attributes":{"a":"https://github.com/memspace/zefyr/issues"}},{"insert":'
36
+    r'".\nDocumentation"},{"insert":"\n","attributes":{"heading":3}},{"insert":"Quick Start","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/quick_start.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Data Format and Document Model","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/data_and_document.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Style Attributes","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/attr'
37
+    r'ibutes.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Heuristic Rules","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/heuristics.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"FAQ","attributes":{"a":"https://github.com/memspace/zefyr/blob/master/doc/faq.md"}},{"insert":"\n","attributes":{"block":"ul"}},{"insert":"Clean and modern look"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Zefyr’s rich text editor is built with simplicity and fle'
38
+    r'xibility in mind. It provides clean interface for distraction-free editing. Think Medium.com-like experience.\nMarkdown inspired semantics"},{"insert":"\n","attributes":{"heading":2}},{"insert":"Ever needed to have a heading line inside of a quote block, like this:\nI’m a Markdown heading"},{"insert":"\n","attributes":{"block":"quote","heading":3}},{"insert":"And I’m a regular paragraph"},{"insert":"\n","attributes":{"block":"quote"}},{"insert":"Code blocks"},{"insert":"\n","attributes":{"headin'
39
+    r'g":2}},{"insert":"Of course:\nimport ‘package:flutter/material.dart’;"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"import ‘package:zefyr/zefyr.dart’;"},{"insert":"\n\n","attributes":{"block":"code"}},{"insert":"void main() {"},{"insert":"\n","attributes":{"block":"code"}},{"insert":" runApp(MyZefyrApp());"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"}"},{"insert":"\n","attributes":{"block":"code"}},{"insert":"\n\n\n"}]';
44 40
   return Delta.fromJson(json.decode(doc) as List);
45 41
 }
46 42
 
@@ -70,6 +66,8 @@ class _FullPageEditorScreenState extends State<FullPageEditorScreen> {
70 66
 
71 67
   @override
72 68
   Widget build(BuildContext context) {
69
+    Runes input = new Runes(
70
+        '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d} 哇哈哈哈哈!!!');
73 71
     final done = _editing
74 72
         ? IconButton(onPressed: _stopEditing, icon: Icon(Icons.save))
75 73
         : IconButton(onPressed: _startEditing, icon: Icon(Icons.edit));
@@ -85,25 +83,45 @@ class _FullPageEditorScreenState extends State<FullPageEditorScreen> {
85 83
           )
86 84
         ],
87 85
       ),
88
-      body: ZefyrScaffold(
89
-        child: ZefyrTheme(
90
-          data: ZefyrThemeData(
91
-            // attributeTheme: AttributeTheme(
92
-            //   link: TextStyle(
93
-            //     color: Colors.red,
94
-            //   ),
95
-            // ),
86
+      body: Column(
87
+        children: <Widget>[
88
+          Container(
89
+            child: RichText(
90
+                text: TextSpan(children: [
91
+              TextSpan(text: 'Flutter is', style: TextStyle(color: Colors.black)),
92
+              WidgetSpan(
93
+                child: SizedBox(
94
+                  height: 20,
95
+                  width: 20,
96
+                    child: Image.network(
97
+                        'http://links-emoticons.oss-cn-hangzhou.aliyuncs.com/v3/e100@2x.gif'),),
98
+              ),
99
+              TextSpan(text: '123123', style: TextStyle(color: Colors.black)),
100
+            ])),
96 101
           ),
97
-          child: ZefyrEditor(
98
-            autofocus: false,
99
-            controller: _controller,
100
-            focusNode: _focusNode,
101
-            mode: ZefyrMode.edit,
102
-            imageDelegate: CustomImageDelegate(),
103
-            linkDelegate: CustomLinkDelegate(),
104
-            keyboardAppearance: _darkTheme ? Brightness.dark : Brightness.light,
102
+          Expanded(
103
+            child: ZefyrScaffold(
104
+              child: ZefyrTheme(
105
+                data: ZefyrThemeData(
106
+                  // attributeTheme: AttributeTheme(
107
+                  //   link: TextStyle(
108
+                  //     color: Colors.red,
109
+                  //   ),
110
+                  // ),
111
+                ),
112
+                child: ZefyrEditor(
113
+                  autofocus: false,
114
+                  controller: _controller,
115
+                  focusNode: _focusNode,
116
+                  mode: ZefyrMode.edit,
117
+                  imageDelegate: CustomImageDelegate(),
118
+                  linkDelegate: CustomLinkDelegate(),
119
+                  keyboardAppearance: _darkTheme ? Brightness.dark : Brightness.light,
120
+                ),
121
+              ),
122
+            ),
105 123
           ),
106
-        ),
124
+        ],
107 125
       ),
108 126
     );
109 127
     if (_darkTheme) {

+ 1
- 0
packages/zefyr/example/lib/src/images.dart Ver fichero

@@ -44,6 +44,7 @@ class CustomImageDelegate implements ZefyrImageDelegate<ImageSource> {
44 44
   @override
45 45
   Future<String> picked(file, isFullImage) async {
46 46
     print(isFullImage);
47
+    // await Future.delayed(Duration(seconds: 2));
47 48
     //File file = await asset.file;
48 49
     return file.uri.toString();
49 50
     // Im.Image image = Im.decodeImage(file.readAsBytesSync());

BIN
packages/zefyr/lib/fonts/zefyrfont.ttf Ver fichero


+ 52
- 14
packages/zefyr/lib/src/widgets/__theme.dart Ver fichero

@@ -160,10 +160,22 @@ class HeadingTheme {
160 160
   /// Style theme for level 3 headings.
161 161
   final StyleTheme level3;
162 162
 
163
+  /// Style theme for level 4 headings.
164
+  final StyleTheme level4;
165
+
166
+  /// Style theme for level 5 headings.
167
+  final StyleTheme level5;
168
+
169
+  /// Style theme for level 6 headings.
170
+  final StyleTheme level6;
171
+
163 172
   HeadingTheme({
164 173
     @required this.level1,
165 174
     @required this.level2,
166 175
     @required this.level3,
176
+    @required this.level4,
177
+    @required this.level5,
178
+    @required this.level6,
167 179
   });
168 180
 
169 181
   /// Creates fallback theme for headings.
@@ -172,30 +184,56 @@ class HeadingTheme {
172 184
     return HeadingTheme(
173 185
       level1: StyleTheme(
174 186
         textStyle: defaultStyle.style.copyWith(
175
-          fontSize: 34.0,
176
-          color: defaultStyle.style.color.withOpacity(0.70),
177
-          height: 1.15,
178
-          fontWeight: FontWeight.w300,
187
+          fontSize: 24.0,
188
+          color: defaultStyle.style.color,
189
+          height: 1.5,
190
+          fontWeight: FontWeight.w500,
179 191
         ),
180
-        padding: EdgeInsets.only(top: 16.0, bottom: 0.0),
192
+        padding: EdgeInsets.only(top: 16.0),
181 193
       ),
182 194
       level2: StyleTheme(
183 195
         textStyle: TextStyle(
184
-          fontSize: 24.0,
185
-          color: defaultStyle.style.color.withOpacity(0.70),
186
-          height: 1.15,
187
-          fontWeight: FontWeight.normal,
196
+          fontSize: 20.0,
197
+          height: 1.5,
198
+          fontWeight: FontWeight.w500,
188 199
         ),
189
-        padding: EdgeInsets.only(bottom: 0.0, top: 8.0),
200
+        padding: EdgeInsets.only(top: 8.0),
190 201
       ),
191 202
       level3: StyleTheme(
192 203
         textStyle: TextStyle(
193
-          fontSize: 20.0,
194
-          color: defaultStyle.style.color.withOpacity(0.70),
195
-          height: 1.25,
204
+          fontSize: 18.0,
205
+          color: defaultStyle.style.color,
206
+          height: 1.5,
207
+          fontWeight: FontWeight.w500,
208
+        ),
209
+        padding: EdgeInsets.only(top: 8.0),
210
+      ),
211
+      level4: StyleTheme(
212
+        textStyle: TextStyle(
213
+          fontSize: 16.0,
214
+          color: defaultStyle.style.color,
215
+          height: 1.5,
216
+          fontWeight: FontWeight.w500,
217
+        ),
218
+        padding: EdgeInsets.only(top: 4.0),
219
+      ),
220
+      level5: StyleTheme(
221
+        textStyle: TextStyle(
222
+          fontSize: 14.0,
223
+          color: defaultStyle.style.color,
224
+          height: 1.5,
225
+          fontWeight: FontWeight.w500,
226
+        ),
227
+        padding: EdgeInsets.only(top: 4.0),
228
+      ),
229
+      level6: StyleTheme(
230
+        textStyle: TextStyle(
231
+          fontSize: 12.0,
232
+          color: defaultStyle.style.color,
233
+          height: 1.5,
196 234
           fontWeight: FontWeight.w500,
197 235
         ),
198
-        padding: EdgeInsets.only(bottom: 0.0, top: 8.0),
236
+        padding: EdgeInsets.only(top: 4.0),
199 237
       ),
200 238
     );
201 239
   }

+ 192
- 132
packages/zefyr/lib/src/widgets/buttons.dart Ver fichero

@@ -118,16 +118,16 @@ class ZefyrButton extends StatelessWidget {
118 118
 
119 119
   Color _getColor(ZefyrScope editor, ToolbarTheme theme) {
120 120
     if (kToolbarButtonIcons.contains(action)) {
121
-      return editor.toolbarAction == action ? theme.toggleColor : theme.surfaceColor;
121
+      return editor.toolbarAction == action
122
+          ? theme.toggleColor
123
+          : theme.surfaceColor;
122 124
     } else {
123 125
       if (isAttributeAction) {
124 126
         final attribute = kZefyrToolbarAttributeActions[action];
125 127
         final isToggled = (attribute is NotusAttribute)
126 128
             ? editor.selectionStyle.containsSame(attribute)
127 129
             : editor.selectionStyle.contains(attribute);
128
-        return isToggled
129
-            ? theme.toggleColor
130
-            : theme.iconColor;
130
+        return isToggled ? theme.toggleColor : theme.iconColor;
131 131
       }
132 132
       return null;
133 133
     }
@@ -262,7 +262,7 @@ class RawZefyrButton extends StatelessWidget {
262 262
 
263 263
     // Widget button = Row(
264 264
     //   children: <Widget>[
265
-        
265
+
266 266
     //     // if (action == ZefyrToolbarAction.showKeyboard || action == ZefyrToolbarAction.hideKeyboard || action == ZefyrToolbarAction.link)
267 267
     //     // Container(
268 268
     //     //   width: 1,
@@ -328,9 +328,18 @@ class _HeadingButtonState extends State<HeadingButton> {
328 328
     );
329 329
   }
330 330
 
331
+  bool hasColor(NotusStyle style, String color) {
332
+    if (style.contains(NotusAttribute.color)) {
333
+      var _style = style.get(NotusAttribute.color);
334
+      return _style.value.toLowerCase() == color.toLowerCase();
335
+    }
336
+    return false;
337
+  }
338
+
331 339
   Widget buildOverlay(BuildContext context) {
332 340
     final theme = ZefyrTheme.of(context).toolbarTheme;
333 341
     final toolbar = ZefyrToolbar.of(context);
342
+
334 343
     final headingButtons = <Widget>[
335 344
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel1),
336 345
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel2),
@@ -354,112 +363,110 @@ class _HeadingButtonState extends State<HeadingButton> {
354 363
       toolbar.buildButton(context, ZefyrToolbarAction.horizontalRule),
355 364
       toolbar.buildButton(context, ZefyrToolbarAction.code),
356 365
     ];
366
+    final textColors = [
367
+      ZefyrTheme.of(context).defaultLineTheme.textStyle.color, ...List.of(kTextColors),
368
+    ];
369
+
357 370
     return Material(
358 371
       color: theme.color,
359 372
       child: Container(
360 373
         decoration: BoxDecoration(
361 374
           border: Border(top: BorderSide(color: theme.dividerColor, width: 1)),
362 375
         ),
363
-        child: Column(
364
-          children: [
365
-            Container(
366
-              padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
367
-              child: Column(
368
-                children: [
369
-                  _buildButtonsView(headingButtons),
370
-                  _buildButtonsView(textButtons),
371
-                  _buildButtonsView(listButtons),
372
-                  _buildButtonsView(otherButtons),
373
-                ],
374
-              ),
375
-            ),
376
-            Container(
377
-              decoration: BoxDecoration(
378
-                border: Border(
379
-                    top: BorderSide(color: theme.dividerColor, width: 1)),
376
+        child: SingleChildScrollView(
377
+          physics: ClampingScrollPhysics(),
378
+          child: Column(
379
+            children: [
380
+              Container(
381
+                padding: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
382
+                child: Column(
383
+                  children: [
384
+                    _buildButtonsView(headingButtons),
385
+                    _buildButtonsView(textButtons),
386
+                    _buildButtonsView(listButtons),
387
+                    _buildButtonsView(otherButtons),
388
+                  ],
389
+                ),
380 390
               ),
381
-              padding: EdgeInsets.symmetric(vertical: 16),
382
-              margin: EdgeInsets.symmetric(horizontal: 16),
383
-              child: Row(
384
-                children: <Widget>[
385
-                  Padding(
386
-                    padding: EdgeInsets.only(right: 12),
387
-                    child: Text(
388
-                      '文字色',
389
-                      style: Theme.of(context).textTheme.caption.copyWith(
390
-                            color: Theme.of(context).colorScheme.onSurface,
391
-                            fontSize: 14,
392
-                            fontWeight: FontWeight.w500,
393
-                          ),
394
-                    ),
395
-                  ),
396
-                  Expanded(
397
-                    child: Container(
398
-                      height: 20,
399
-                      child: ListView(
400
-                        scrollDirection: Axis.horizontal,
401
-                        children: [
402
-                          Container(
403
-                            padding: EdgeInsets.all(1),
404
-                            decoration: ShapeDecoration(
405
-                              shape: CircleBorder(
406
-                                side: BorderSide(
407
-                                    width: 1, color: theme.toggleColor),
408
-                              ),
409
-                            ),
410
-                            margin: EdgeInsets.symmetric(horizontal: 8),
411
-                            child: Container(
412
-                              width: 16,
413
-                              height: 16,
414
-                              decoration: ShapeDecoration(
415
-                                color: Color(0xFFE02020),
416
-                                shape: CircleBorder(),
417
-                              ),
418
-                            ),
419
-                          ),
420
-                          Container(
421
-                            padding: EdgeInsets.all(1),
422
-                            decoration: ShapeDecoration(
423
-                              shape: CircleBorder(
424
-                                side: BorderSide.none,
425
-                              ),
426
-                            ),
427
-                            margin: EdgeInsets.symmetric(horizontal: 8),
428
-                            child: Container(
429
-                              width: 16,
430
-                              height: 16,
431
-                              decoration: ShapeDecoration(
432
-                                color: Color(0xFFFA6400),
433
-                                shape: CircleBorder(),
434
-                              ),
435
-                            ),
436
-                          ),
437
-                          Container(
438
-                            padding: EdgeInsets.all(1),
439
-                            decoration: ShapeDecoration(
440
-                              shape: CircleBorder(
441
-                                side: BorderSide.none,
442
-                              ),
391
+              Container(
392
+                decoration: BoxDecoration(
393
+                  border: Border(
394
+                      top: BorderSide(color: theme.dividerColor, width: 1)),
395
+                ),
396
+                padding: EdgeInsets.symmetric(vertical: 16),
397
+                margin: EdgeInsets.symmetric(horizontal: 16),
398
+                child: Row(
399
+                  children: <Widget>[
400
+                    Padding(
401
+                      padding: EdgeInsets.only(right: 12),
402
+                      child: Text(
403
+                        '文字色',
404
+                        style: Theme.of(context).textTheme.caption.copyWith(
405
+                              color: Theme.of(context).colorScheme.onSurface,
406
+                              fontSize: 14,
407
+                              fontWeight: FontWeight.w500,
443 408
                             ),
444
-                            margin: EdgeInsets.symmetric(horizontal: 8),
445
-                            child: Container(
446
-                              width: 16,
447
-                              height: 16,
448
-                              decoration: ShapeDecoration(
449
-                                color: Color(0xFF0091FF),
450
-                                shape: CircleBorder(),
409
+                      ),
410
+                    ),
411
+                    Expanded(
412
+                      child: Container(
413
+                        height: 20,
414
+                        child: ListView(
415
+                          scrollDirection: Axis.horizontal,
416
+                          children: textColors.map((color) {
417
+                            var hex = color.value.toRadixString(16).substring(2, 8);
418
+                            var has = false;
419
+                            if (!toolbar.editor.selectionStyle.contains(NotusAttribute.color)) {
420
+                              if (color == ZefyrTheme.of(context).defaultLineTheme.textStyle.color) {
421
+                                has = true;
422
+                              }
423
+                            } else {
424
+                              has = hasColor(toolbar.editor.selectionStyle, '#$hex');
425
+                            }
426
+                            // var key = kTextColors[index].value;
427
+                            return GestureDetector(
428
+                              behavior: HitTestBehavior.translucent,
429
+                              onTap: () {
430
+                                toolbar.editor.formatSelection(NotusAttribute.color.fromString('#$hex'));
431
+                              },
432
+                              child: Container(
433
+                                padding: EdgeInsets.all(1),
434
+                                width: 20,
435
+                                height: 20,
436
+                                decoration: ShapeDecoration(
437
+                                  shape: CircleBorder(
438
+                                    side: has ? BorderSide(
439
+                                      width: 1,
440
+                                      color: theme.toggleColor,
441
+                                    ) : BorderSide.none,
442
+                                  ),
443
+                                ),
444
+                                margin: EdgeInsets.symmetric(horizontal: 8),
445
+                                child: Container(
446
+                                  // width: 16,
447
+                                  // height: 16,
448
+                                  decoration: ShapeDecoration(
449
+                                    color: color,
450
+                                    shape: CircleBorder(
451
+                                      side: color == Color(0xFFFFFFFF) && !has ? BorderSide(
452
+                                        width: 1,
453
+                                        color: theme.dividerColor,
454
+                                      ) : BorderSide.none,
455
+                                    ),
456
+                                  ),
457
+                                ),
451 458
                               ),
452
-                            ),
453
-                          ),
454
-                        ],
455
-                        physics: ClampingScrollPhysics(),
459
+                            );
460
+                          }).toList(),
461
+                          physics: ClampingScrollPhysics(),
462
+                        ),
456 463
                       ),
457 464
                     ),
458
-                  ),
459
-                ],
465
+                  ],
466
+                ),
460 467
               ),
461
-            ),
462
-          ],
468
+            ],
469
+          ),
463 470
         ),
464 471
       ),
465 472
     );
@@ -470,6 +477,45 @@ class _HeadingButtonState extends State<HeadingButton> {
470 477
   }
471 478
 }
472 479
 
480
+// class TextColorButton extends StatelessWidget {
481
+
482
+//   const TextColorButton({Key key, String color, ZefyrThemeData theme}) : super(key: key);
483
+
484
+//   @override
485
+//   Widget build(BuildContext context) {
486
+//     return GestureDetector(
487
+//       behavior: HitTestBehavior.translucent,
488
+//       onTap: () {
489
+//         // onTap(color);
490
+//         // toolbar.editor.formatSelection(NotusAttribute.color.fromString('#000000'));
491
+//       },
492
+//       child: Container(
493
+//         padding: EdgeInsets.all(1),
494
+//         decoration: ShapeDecoration(
495
+//           shape: CircleBorder(
496
+//             side: BorderSide(
497
+//               width: 1,
498
+//               color: theme,
499
+//             ),
500
+//           ),
501
+//         ),
502
+//         margin: EdgeInsets.symmetric(horizontal: 8),
503
+//         child: Container(
504
+//           width: 16,
505
+//           height: 16,
506
+//           decoration: ShapeDecoration(
507
+//             color: ZefyrTheme.of(context)
508
+//                 .defaultLineTheme
509
+//                 .textStyle
510
+//                 .color,
511
+//             shape: CircleBorder(),
512
+//           ),
513
+//         ),
514
+//       ),
515
+//     );
516
+//   }
517
+// }
518
+
473 519
 /// Controls image attribute.
474 520
 ///
475 521
 /// When pressed, this button displays overlay toolbar with three
@@ -576,7 +622,10 @@ class _ImageButtonState extends State<ImageButton> {
576 622
                                 shape: RoundedRectangleBorder(),
577 623
                                 color: Color(0xFFF6F6F6),
578 624
                                 onPressed: () {
579
-                                  toolbar.editor.keepOverlay = true;
625
+                                  final editor =
626
+                                      ZefyrToolbar.of(context).editor;
627
+                                  // var _selection = toolbar.editor.selection;
628
+                                  editor.closeKeyboard(true);
580 629
                                   PhotoPicker.pickAsset(
581 630
                                     context: context,
582 631
                                     rowCount: 4,
@@ -588,9 +637,6 @@ class _ImageButtonState extends State<ImageButton> {
588 637
                                     photoPathList: null,
589 638
                                   ).then((PickedEntity entity) async {
590 639
                                     if (entity.asset.isNotEmpty) {
591
-                                      toolbar.closeOverlay();
592
-                                      final editor =
593
-                                          ZefyrToolbar.of(context).editor;
594 640
                                       for (var asset in entity.asset) {
595 641
                                         var file = await asset.originFile;
596 642
                                         final image = await editor.imageDelegate
@@ -599,6 +645,7 @@ class _ImageButtonState extends State<ImageButton> {
599 645
                                           editor.formatSelection(NotusAttribute
600 646
                                               .embed
601 647
                                               .image(image));
648
+                                          editor.closeKeyboard();
602 649
                                         }
603 650
                                       }
604 651
                                     }
@@ -642,18 +689,19 @@ class _ImageButtonState extends State<ImageButton> {
642 689
                           initialData: PickedEntity(),
643 690
                           builder: (context, snapshot) {
644 691
                             return PhotoPicker.buildGallery(
645
-                                context: context,
646
-                                padding: 4,
647
-                                thumbSize: 300,
648
-                                itemRadio: 0.5,
649
-                                provider: I18nProvider.chinese,
650
-                                sortDelegate: SortDelegate.common,
651
-                                pickType: PickType.onlyImage,
652
-                                photoPathList: null,
653
-                                isFullImage: snapshot.data.isFullImage,
654
-                                onSelected: (PickedEntity entity) {
655
-                                  pickedChangeController.add(entity);
656
-                                });
692
+                              context: context,
693
+                              padding: 4,
694
+                              thumbSize: 300,
695
+                              itemRadio: 0.5,
696
+                              provider: I18nProvider.chinese,
697
+                              sortDelegate: SortDelegate.common,
698
+                              pickType: PickType.onlyImage,
699
+                              photoPathList: null,
700
+                              isFullImage: snapshot.data.isFullImage,
701
+                              onSelected: (PickedEntity entity) {
702
+                                pickedChangeController.add(entity);
703
+                              },
704
+                            );
657 705
                           },
658 706
                         ),
659 707
                       ),
@@ -724,15 +772,19 @@ class _ImageButtonState extends State<ImageButton> {
724 772
                         onPressed: snapshot.data.asset.isNotEmpty
725 773
                             ? () async {
726 774
                                 pickedChangeController.add(PickedEntity());
727
-                                toolbar.closeOverlay();
775
+                                // toolbar.closeOverlay();
776
+                                toolbar.editor.closeKeyboard(true);
728 777
                                 for (var asset in snapshot.data.asset) {
729 778
                                   var file = await asset.originFile;
730 779
                                   final image = await toolbar
731 780
                                       .editor.imageDelegate
732 781
                                       .picked(file, snapshot.data.isFullImage);
733 782
                                   if (image != null) {
783
+                                    // toolbar.editor.toolbarAction = null;
784
+                                    // toolbar.editor.keepOverlay = true;
734 785
                                     toolbar.editor.formatSelection(
735 786
                                         NotusAttribute.embed.image(image));
787
+                                    toolbar.editor.closeKeyboard();
736 788
                                   }
737 789
                                 }
738 790
                               }
@@ -826,27 +878,35 @@ class _LinkButtonState extends State<LinkButton> {
826 878
   OverlayEntry _overlayEntry;
827 879
 
828 880
   Future<void> showOverlay() async {
829
-    final toolbar = ZefyrToolbar.of(context);
830
-    var _selection = toolbar.editor.selection;
881
+    final editor = ZefyrToolbar.of(context).editor;
882
+    editor.closeKeyboard(true);
883
+    var _selection = editor.selection;
831 884
     var value = ZefyrLinkEntity();
832
-    if (hasLink(toolbar.editor.selectionStyle)) {
833
-      value = value.copyWith(url: toolbar.editor.selectionStyle.value(NotusAttribute.link));
885
+    if (hasLink(editor.selectionStyle)) {
886
+      value =
887
+          value.copyWith(url: editor.selectionStyle.value(NotusAttribute.link));
834 888
     }
835 889
     // 已选中
836
-    if(!toolbar.editor.selection.isCollapsed) {
837
-      var text = toolbar.editor.controller.document.toPlainText().substring(toolbar.editor.selection.start, toolbar.editor.selection.end);
890
+    if (!editor.selection.isCollapsed) {
891
+      var text = editor.controller.document
892
+          .toPlainText()
893
+          .substring(editor.selection.start, editor.selection.end);
838 894
       value = value.copyWith(text: text);
839
-    };
840
-    var result = await toolbar.editor.linkDelegate.fillLink(context, value);
841
-    
895
+    }
896
+    ;
897
+    var result = await editor.linkDelegate.fillLink(context, value);
898
+
842 899
     if (result != null) {
843
-      toolbar.editor.updateSelection(_selection, source: ChangeSource.local);
844
-      _selection = toolbar.editor.selection;
845
-      toolbar.editor.controller.replaceText(_selection.start, _selection.end - _selection.start, result.text, selection: _selection.copyWith(
846
-        baseOffset: _selection.start,
847
-        extentOffset: _selection.start + result.text.length,
848
-      ));
849
-      toolbar.editor.formatSelection(NotusAttribute.link.fromString(result.url));
900
+      // toolbar.editor.updateSelection(_selection, source: ChangeSource.local);
901
+      // _selection = toolbar.editor.selection;
902
+      editor.controller.replaceText(
903
+          _selection.start, _selection.end - _selection.start, result.text,
904
+          selection: _selection.copyWith(
905
+            baseOffset: _selection.start,
906
+            extentOffset: _selection.start + result.text.length,
907
+          ));
908
+      editor.formatSelection(NotusAttribute.link.fromString(result.url));
909
+      editor.closeKeyboard();
850 910
     }
851 911
   }
852 912
 

+ 17
- 0
packages/zefyr/lib/src/widgets/common.dart Ver fichero

@@ -154,6 +154,23 @@ class _ZefyrLineState extends State<ZefyrLine> {
154 154
     if (style.contains(NotusAttribute.link)) {
155 155
       result = result.merge(theme.attributeTheme.link);
156 156
     }
157
+    if (style.contains(NotusAttribute.highlight)) {
158
+      result = result.merge(TextStyle(
159
+        backgroundColor: Color(0xFFFFAF64).withOpacity(0.5),
160
+      ));
161
+    }
162
+    if (style.contains(NotusAttribute.color)) {
163
+      final hexStringToColor = (String hex) {
164
+        hex = hex.replaceFirst('#', '');
165
+        hex = hex.length == 6 ? 'ff' + hex : hex;
166
+        var val = int.parse(hex, radix: 16);
167
+        return Color(val);
168
+      };
169
+      final color = hexStringToColor(style.value<String>(NotusAttribute.color));
170
+      result = result.merge(TextStyle(
171
+        color: color,
172
+      ));
173
+    }
157 174
     return result;
158 175
   }
159 176
 

+ 4
- 1
packages/zefyr/lib/src/widgets/controller.dart Ver fichero

@@ -168,7 +168,10 @@ class ZefyrController extends ChangeNotifier {
168 168
 
169 169
     if (length == 0 &&
170 170
         (attribute.key == NotusAttribute.bold.key ||
171
-            attribute.key == NotusAttribute.italic.key)) {
171
+            attribute.key == NotusAttribute.italic.key || 
172
+            attribute.key == NotusAttribute.highlight.key || 
173
+            attribute.key == NotusAttribute.color.key || 
174
+            attribute.key == NotusAttribute.line.key)) {
172 175
       // Add the attribute to our toggledStyle. It will be used later upon insertion.
173 176
       _toggledStyles = toggledStyles.put(attribute);
174 177
     }

+ 8
- 8
packages/zefyr/lib/src/widgets/iconfont.dart Ver fichero

@@ -74,13 +74,13 @@ class ZefyrFont {
74 74
   static const IconData note_more_favorite =
75 75
       IconData(0xe6fe, fontFamily: _family, fontPackage: _fontPackage);
76 76
   static const IconData note_more_move = IconData(0xe6ff, fontFamily: _family, fontPackage: _fontPackage);
77
-  static const IconData note_editor_text_h =
77
+  static const IconData note_editor_text_h1 =
78 78
       IconData(0xe6e4, fontFamily: _family, fontPackage: _fontPackage);
79 79
   static const IconData note_editor_text_code =
80 80
       IconData(0xe6e5, fontFamily: _family, fontPackage: _fontPackage);
81 81
   static const IconData note_editor_text_bold =
82 82
       IconData(0xe6e6, fontFamily: _family, fontPackage: _fontPackage);
83
-  static const IconData note_editor_text_h1 =
83
+  static const IconData note_editor_text_h2 =
84 84
       IconData(0xe6e7, fontFamily: _family, fontPackage: _fontPackage);
85 85
   static const IconData note_editor_text_center =
86 86
       IconData(0xe6e8, fontFamily: _family, fontPackage: _fontPackage);
@@ -88,16 +88,16 @@ class ZefyrFont {
88 88
       IconData(0xe6e9, fontFamily: _family, fontPackage: _fontPackage);
89 89
   static const IconData note_editor_text_left =
90 90
       IconData(0xe6ea, fontFamily: _family, fontPackage: _fontPackage);
91
-  static const IconData note_editor_text_h2 =
92
-      IconData(0xe6eb, fontFamily: _family, fontPackage: _fontPackage);
93 91
   static const IconData note_editor_text_h3 =
92
+      IconData(0xe6eb, fontFamily: _family, fontPackage: _fontPackage);
93
+  static const IconData note_editor_text_h4 =
94 94
       IconData(0xe6ec, fontFamily: _family, fontPackage: _fontPackage);
95 95
   static const IconData note_editor_text_right =
96 96
       IconData(0xe6ed, fontFamily: _family, fontPackage: _fontPackage);
97 97
   static const IconData note_editor_text_hr =
98 98
       IconData(0xe6ee, fontFamily: _family, fontPackage: _fontPackage);
99
-  static const IconData note_editor_text_h4 =
100
-      IconData(0xe6ef, fontFamily: _family, fontPackage: _fontPackage);
99
+  static const IconData note_editor_text_h5 =
100
+      IconData(0xe6f4, fontFamily: _family, fontPackage: _fontPackage);
101 101
   static const IconData note_editor_text_underline =
102 102
       IconData(0xe6f0, fontFamily: _family, fontPackage: _fontPackage);
103 103
   static const IconData note_editor_text_ul =
@@ -106,8 +106,8 @@ class ZefyrFont {
106 106
       IconData(0xe6f2, fontFamily: _family, fontPackage: _fontPackage);
107 107
   static const IconData note_editor_text_in =
108 108
       IconData(0xe6f3, fontFamily: _family, fontPackage: _fontPackage);
109
-  static const IconData note_editor_text_h5 =
110
-      IconData(0xe6f4, fontFamily: _family, fontPackage: _fontPackage);
109
+  static const IconData note_editor_text_h6 =
110
+      IconData(0xe6ef, fontFamily: _family, fontPackage: _fontPackage);
111 111
   static const IconData note_editor_text_para =
112 112
       IconData(0xe6f5, fontFamily: _family, fontPackage: _fontPackage);
113 113
   static const IconData note_editor_text_ol =

+ 4
- 1
packages/zefyr/lib/src/widgets/scope.dart Ver fichero

@@ -257,9 +257,12 @@ class ZefyrScope extends ChangeNotifier {
257 257
     _focusScope.requestFocus(_focusNode);
258 258
   }
259 259
 
260
-  void closeKeyboard() {
260
+  void closeKeyboard([bool force = false]) {
261 261
     assert(isEditable);
262 262
     assert(!_disposed);
263
+    if (force) {
264
+      _keepOverlay = false;
265
+    }
263 266
     _focusNode.unfocus();
264 267
     //tapHandle = null;
265 268
   }

+ 33
- 27
packages/zefyr/lib/src/widgets/theme.dart Ver fichero

@@ -77,6 +77,7 @@ class ZefyrThemeData {
77 77
       textStyle: defaultStyle.style.copyWith(
78 78
         fontSize: 16.0,
79 79
         height: 1.3,
80
+        color: Color(0xFF595959),
80 81
       ),
81 82
       padding: EdgeInsets.symmetric(vertical: 8.0),
82 83
     );
@@ -366,8 +367,8 @@ class AttributeTheme {
366 367
 
367 368
     return AttributeTheme(
368 369
       bold: TextStyle(fontWeight: FontWeight.bold),
369
-      underline: defaultLineTheme.textStyle.copyWith(decoration: TextDecoration.underline),
370
-      deleteline: defaultLineTheme.textStyle.copyWith(decoration: TextDecoration.lineThrough),
370
+      underline: TextStyle(decoration: TextDecoration.underline),
371
+      deleteline: TextStyle(decoration: TextDecoration.lineThrough),
371 372
       italic: TextStyle(fontStyle: FontStyle.italic),
372 373
       link: TextStyle(
373 374
         decoration: TextDecoration.underline,
@@ -375,54 +376,54 @@ class AttributeTheme {
375 376
       ),
376 377
       heading1: LineTheme(
377 378
         textStyle: defaultLineTheme.textStyle.copyWith(
378
-          fontSize: 38.0,
379
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
380
-          height: 1.15,
381
-          fontWeight: FontWeight.w300,
379
+          fontSize: 24.0,
380
+          color: defaultLineTheme.textStyle.color,
381
+          height: 1.5,
382
+          fontWeight: FontWeight.w500,
382 383
         ),
383 384
         padding: EdgeInsets.only(top: 16.0),
384 385
       ),
385 386
       heading2: LineTheme(
386 387
         textStyle: defaultLineTheme.textStyle.copyWith(
387
-          fontSize: 34.0,
388
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
389
-          height: 1.15,
390
-          fontWeight: FontWeight.normal,
388
+          fontSize: 20.0,
389
+          color: defaultLineTheme.textStyle.color,
390
+          height: 1.5,
391
+          fontWeight: FontWeight.w500,
391 392
         ),
392
-        padding: EdgeInsets.only(top: 16.0),
393
+        padding: EdgeInsets.only(top: 8.0),
393 394
       ),
394 395
       heading3: LineTheme(
395 396
         textStyle: defaultLineTheme.textStyle.copyWith(
396
-          fontSize: 30.0,
397
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
398
-          height: 1.15,
397
+          fontSize: 18.0,
398
+          color: defaultLineTheme.textStyle.color,
399
+          height: 1.5,
399 400
           fontWeight: FontWeight.w500,
400 401
         ),
401
-        padding: EdgeInsets.only(top: 16.0),
402
+        padding: EdgeInsets.only(top: 8.0),
402 403
       ),
403 404
       heading4: LineTheme(
404 405
         textStyle: defaultLineTheme.textStyle.copyWith(
405
-          fontSize: 26.0,
406
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
407
-          height: 1.15,
406
+          fontSize: 16.0,
407
+          color: defaultLineTheme.textStyle.color,
408
+          height: 1.5,
408 409
           fontWeight: FontWeight.w500,
409 410
         ),
410
-        padding: EdgeInsets.only(top: 12.0),
411
+        padding: EdgeInsets.only(top: 4.0),
411 412
       ),
412 413
       heading5: LineTheme(
413 414
         textStyle: defaultLineTheme.textStyle.copyWith(
414
-          fontSize: 22.0,
415
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
416
-          height: 1.15,
415
+          fontSize: 14.0,
416
+          color: defaultLineTheme.textStyle.color,
417
+          height: 1.5,
417 418
           fontWeight: FontWeight.w500,
418 419
         ),
419
-        padding: EdgeInsets.only(top: 8.0),
420
+        padding: EdgeInsets.only(top: 4.0),
420 421
       ),
421 422
       heading6: LineTheme(
422 423
         textStyle: defaultLineTheme.textStyle.copyWith(
423
-          fontSize: 18.0,
424
-          color: defaultLineTheme.textStyle.color.withOpacity(0.7),
425
-          height: 1.15,
424
+          fontSize: 12.0,
425
+          color: defaultLineTheme.textStyle.color,
426
+          height: 1.5,
426 427
           fontWeight: FontWeight.w500,
427 428
         ),
428 429
         padding: EdgeInsets.only(top: 4.0),
@@ -461,6 +462,7 @@ class AttributeTheme {
461 462
   AttributeTheme copyWith({
462 463
     TextStyle bold,
463 464
     TextStyle underline,
465
+    TextStyle deleteline,
464 466
     TextStyle italic,
465 467
     TextStyle link,
466 468
     LineTheme heading1,
@@ -477,6 +479,7 @@ class AttributeTheme {
477 479
     return AttributeTheme(
478 480
       bold: bold ?? this.bold,
479 481
       underline: underline ?? this.underline,
482
+      deleteline: deleteline ?? this.deleteline,
480 483
       italic: italic ?? this.italic,
481 484
       link: link ?? this.link,
482 485
       heading1: heading1 ?? this.heading1,
@@ -499,6 +502,7 @@ class AttributeTheme {
499 502
     return copyWith(
500 503
       bold: bold?.merge(other.bold) ?? other.bold,
501 504
       underline: underline?.merge(other.underline) ?? other.underline,
505
+      deleteline: underline?.merge(other.deleteline) ?? other.deleteline,
502 506
       italic: italic?.merge(other.italic) ?? other.italic,
503 507
       link: link?.merge(other.link) ?? other.link,
504 508
       heading1: heading1?.merge(other.heading1) ?? other.heading1,
@@ -520,6 +524,7 @@ class AttributeTheme {
520 524
     final AttributeTheme otherTheme = other;
521 525
     return (otherTheme.bold == bold) &&
522 526
         (otherTheme.underline == underline) &&
527
+        (otherTheme.deleteline == deleteline) &&
523 528
         (otherTheme.italic == italic) &&
524 529
         (otherTheme.link == link) &&
525 530
         (otherTheme.heading1 == heading1) &&
@@ -539,6 +544,7 @@ class AttributeTheme {
539 544
     return hashList([
540 545
       bold,
541 546
       underline,
547
+      deleteline,
542 548
       italic,
543 549
       link,
544 550
       heading1,
@@ -586,7 +592,7 @@ class ToolbarTheme {
586 592
       iconFillColor: theme.brightness == Brightness.light ? Color(0xFFF2F2F2) : Color(0xFF1F1F1F),
587 593
       iconColor: Color(0xFF595959),
588 594
       disabledIconColor: theme.brightness == Brightness.light ? Color(0xFFBFBFBF) : Color(0xFF363636),
589
-      dividerColor: theme.brightness == Brightness.light ? Color(0xFFF2F2F2) : Color(0xFF3B3B3B),
595
+      dividerColor: theme.brightness == Brightness.light ? Color(0x0D1C202B) : Color(0xFF3B3B3B),
590 596
     );
591 597
   }
592 598
 

+ 22
- 8
packages/zefyr/lib/src/widgets/toolbar.dart Ver fichero

@@ -22,6 +22,7 @@ enum ZefyrToolbarAction {
22 22
   link,
23 23
   unlink,
24 24
   emoji,
25
+  color,
25 26
   undo,
26 27
   redo,
27 28
   save,
@@ -51,10 +52,11 @@ enum ZefyrToolbarAction {
51 52
 
52 53
 final kZefyrToolbarAttributeActions = <ZefyrToolbarAction, NotusAttributeKey>{
53 54
   ZefyrToolbarAction.bold: NotusAttribute.bold,
54
-  ZefyrToolbarAction.underline: NotusAttribute.underline,
55
-  ZefyrToolbarAction.deleteline: NotusAttribute.deleteline,
55
+  ZefyrToolbarAction.underline: NotusAttribute.line.underline,
56
+  ZefyrToolbarAction.deleteline: NotusAttribute.line.deleteline,
56 57
   ZefyrToolbarAction.italic: NotusAttribute.italic,
57 58
   ZefyrToolbarAction.link: NotusAttribute.link,
59
+  ZefyrToolbarAction.color: NotusAttribute.color,
58 60
   // ZefyrToolbarAction.text: NotusAttribute.heading,
59 61
   ZefyrToolbarAction.heading: NotusAttribute.heading,
60 62
   ZefyrToolbarAction.headingLevel1: NotusAttribute.heading.level1,
@@ -92,12 +94,12 @@ const kDefaultButtonIcons = {
92 94
   ZefyrToolbarAction.unlink: Icons.link_off,
93 95
   ZefyrToolbarAction.clipboardCopy: Icons.content_copy,
94 96
   ZefyrToolbarAction.openInBrowser: Icons.open_in_new,
95
-  ZefyrToolbarAction.headingLevel1: ZefyrFont.note_editor_text_h,
96
-  ZefyrToolbarAction.headingLevel2: ZefyrFont.note_editor_text_h1,
97
-  ZefyrToolbarAction.headingLevel3: ZefyrFont.note_editor_text_h2,
98
-  ZefyrToolbarAction.headingLevel4: ZefyrFont.note_editor_text_h3,
99
-  ZefyrToolbarAction.headingLevel5: ZefyrFont.note_editor_text_h4,
100
-  ZefyrToolbarAction.headingLevel6: ZefyrFont.note_editor_text_h5,
97
+  ZefyrToolbarAction.headingLevel1: ZefyrFont.note_editor_text_h1,
98
+  ZefyrToolbarAction.headingLevel2: ZefyrFont.note_editor_text_h2,
99
+  ZefyrToolbarAction.headingLevel3: ZefyrFont.note_editor_text_h3,
100
+  ZefyrToolbarAction.headingLevel4: ZefyrFont.note_editor_text_h4,
101
+  ZefyrToolbarAction.headingLevel5: ZefyrFont.note_editor_text_h5,
102
+  ZefyrToolbarAction.headingLevel6: ZefyrFont.note_editor_text_h6,
101 103
   ZefyrToolbarAction.text: ZefyrFont.note_editor_text,
102 104
   ZefyrToolbarAction.code: ZefyrFont.note_editor_text_code,
103 105
   ZefyrToolbarAction.horizontalRule: ZefyrFont.note_editor_text_hr,
@@ -122,6 +124,18 @@ final kToolbarDivider = Container(
122 124
   margin: EdgeInsets.symmetric(horizontal: 10),
123 125
 );
124 126
 
127
+const kTextColors = [
128
+  Color(0xFFFA6400),
129
+  Color(0xFFF7B500),
130
+  Color(0xFF6DD400),
131
+  Color(0xFF44D7B6),
132
+  Color(0xFF32C5FF),
133
+  Color(0xFF0091FF),
134
+  Color(0xFF6236FF),
135
+  Color(0xFF000000),
136
+  Color(0xFFFFFFFF),
137
+];
138
+
125 139
 /// Allows customizing appearance of [ZefyrToolbar].
126 140
 abstract class ZefyrToolbarDelegate {
127 141
   /// Builds toolbar button for specified [action].