Browse Source

add color attribute

lucky1213 4 years ago
parent
commit
31427306d2

+ 29
- 5
packages/notus/lib/src/document/attributes.dart View File

75
   static final Map<String, NotusAttributeBuilder> _registry = {
75
   static final Map<String, NotusAttributeBuilder> _registry = {
76
     NotusAttribute.bold.key: NotusAttribute.bold,
76
     NotusAttribute.bold.key: NotusAttribute.bold,
77
     NotusAttribute.line.key: NotusAttribute.line,
77
     NotusAttribute.line.key: NotusAttribute.line,
78
+    NotusAttribute.color.key: NotusAttribute.color,
79
+    NotusAttribute.highlight.key: NotusAttribute.highlight,
78
     NotusAttribute.italic.key: NotusAttribute.italic,
80
     NotusAttribute.italic.key: NotusAttribute.italic,
79
     NotusAttribute.link.key: NotusAttribute.link,
81
     NotusAttribute.link.key: NotusAttribute.link,
80
     NotusAttribute.heading.key: NotusAttribute.heading,
82
     NotusAttribute.heading.key: NotusAttribute.heading,
97
   // Line attributes
99
   // Line attributes
98
   static const line = LineAttributeBuilder._();
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
   /// Heading style attribute.
108
   /// Heading style attribute.
107
   // ignore: const_eval_throws_exception
109
   // ignore: const_eval_throws_exception
375
   NotusAttribute<String> get deleteline => NotusAttribute<String>._(key, scope, 'deleteline');
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
 /// Builder for heading attribute styles.
402
 /// Builder for heading attribute styles.
379
 ///
403
 ///
380
 /// There is no need to use this class directly, consider using
404
 /// There is no need to use this class directly, consider using
438
 
462
 
439
   NotusAttribute<Map<String, dynamic>> image(String source) =>
463
   NotusAttribute<Map<String, dynamic>> image(String source) =>
440
       EmbedAttribute.image(source);
464
       EmbedAttribute.image(source);
441
-
465
+  
442
   @override
466
   @override
443
   NotusAttribute<Map<String, dynamic>> get unset => EmbedAttribute._(null);
467
   NotusAttribute<Map<String, dynamic>> get unset => EmbedAttribute._(null);
444
 
468
 

+ 1
- 1
packages/zefyr/example/android/build.gradle View File

5
     }
5
     }
6
 
6
 
7
     dependencies {
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 View File

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

+ 1
- 1
packages/zefyr/example/android/gradle/wrapper/gradle-wrapper.properties View File

3
 distributionPath=wrapper/dists
3
 distributionPath=wrapper/dists
4
 zipStoreBase=GRADLE_USER_HOME
4
 zipStoreBase=GRADLE_USER_HOME
5
 zipStorePath=wrapper/dists
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 View File

30
   _FullPageEditorScreenState createState() => _FullPageEditorScreenState();
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
 Delta getDelta() {
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
   return Delta.fromJson(json.decode(doc) as List);
40
   return Delta.fromJson(json.decode(doc) as List);
45
 }
41
 }
46
 
42
 
70
 
66
 
71
   @override
67
   @override
72
   Widget build(BuildContext context) {
68
   Widget build(BuildContext context) {
69
+    Runes input = new Runes(
70
+        '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d} 哇哈哈哈哈!!!');
73
     final done = _editing
71
     final done = _editing
74
         ? IconButton(onPressed: _stopEditing, icon: Icon(Icons.save))
72
         ? IconButton(onPressed: _stopEditing, icon: Icon(Icons.save))
75
         : IconButton(onPressed: _startEditing, icon: Icon(Icons.edit));
73
         : IconButton(onPressed: _startEditing, icon: Icon(Icons.edit));
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
     if (_darkTheme) {
127
     if (_darkTheme) {

+ 1
- 0
packages/zefyr/example/lib/src/images.dart View File

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

BIN
packages/zefyr/lib/fonts/zefyrfont.ttf View File


+ 52
- 14
packages/zefyr/lib/src/widgets/__theme.dart View File

160
   /// Style theme for level 3 headings.
160
   /// Style theme for level 3 headings.
161
   final StyleTheme level3;
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
   HeadingTheme({
172
   HeadingTheme({
164
     @required this.level1,
173
     @required this.level1,
165
     @required this.level2,
174
     @required this.level2,
166
     @required this.level3,
175
     @required this.level3,
176
+    @required this.level4,
177
+    @required this.level5,
178
+    @required this.level6,
167
   });
179
   });
168
 
180
 
169
   /// Creates fallback theme for headings.
181
   /// Creates fallback theme for headings.
172
     return HeadingTheme(
184
     return HeadingTheme(
173
       level1: StyleTheme(
185
       level1: StyleTheme(
174
         textStyle: defaultStyle.style.copyWith(
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
       level2: StyleTheme(
194
       level2: StyleTheme(
183
         textStyle: TextStyle(
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
       level3: StyleTheme(
202
       level3: StyleTheme(
192
         textStyle: TextStyle(
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
           fontWeight: FontWeight.w500,
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 View File

118
 
118
 
119
   Color _getColor(ZefyrScope editor, ToolbarTheme theme) {
119
   Color _getColor(ZefyrScope editor, ToolbarTheme theme) {
120
     if (kToolbarButtonIcons.contains(action)) {
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
     } else {
124
     } else {
123
       if (isAttributeAction) {
125
       if (isAttributeAction) {
124
         final attribute = kZefyrToolbarAttributeActions[action];
126
         final attribute = kZefyrToolbarAttributeActions[action];
125
         final isToggled = (attribute is NotusAttribute)
127
         final isToggled = (attribute is NotusAttribute)
126
             ? editor.selectionStyle.containsSame(attribute)
128
             ? editor.selectionStyle.containsSame(attribute)
127
             : editor.selectionStyle.contains(attribute);
129
             : editor.selectionStyle.contains(attribute);
128
-        return isToggled
129
-            ? theme.toggleColor
130
-            : theme.iconColor;
130
+        return isToggled ? theme.toggleColor : theme.iconColor;
131
       }
131
       }
132
       return null;
132
       return null;
133
     }
133
     }
262
 
262
 
263
     // Widget button = Row(
263
     // Widget button = Row(
264
     //   children: <Widget>[
264
     //   children: <Widget>[
265
-        
265
+
266
     //     // if (action == ZefyrToolbarAction.showKeyboard || action == ZefyrToolbarAction.hideKeyboard || action == ZefyrToolbarAction.link)
266
     //     // if (action == ZefyrToolbarAction.showKeyboard || action == ZefyrToolbarAction.hideKeyboard || action == ZefyrToolbarAction.link)
267
     //     // Container(
267
     //     // Container(
268
     //     //   width: 1,
268
     //     //   width: 1,
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
   Widget buildOverlay(BuildContext context) {
339
   Widget buildOverlay(BuildContext context) {
332
     final theme = ZefyrTheme.of(context).toolbarTheme;
340
     final theme = ZefyrTheme.of(context).toolbarTheme;
333
     final toolbar = ZefyrToolbar.of(context);
341
     final toolbar = ZefyrToolbar.of(context);
342
+
334
     final headingButtons = <Widget>[
343
     final headingButtons = <Widget>[
335
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel1),
344
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel1),
336
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel2),
345
       toolbar.buildButton(context, ZefyrToolbarAction.headingLevel2),
354
       toolbar.buildButton(context, ZefyrToolbarAction.horizontalRule),
363
       toolbar.buildButton(context, ZefyrToolbarAction.horizontalRule),
355
       toolbar.buildButton(context, ZefyrToolbarAction.code),
364
       toolbar.buildButton(context, ZefyrToolbarAction.code),
356
     ];
365
     ];
366
+    final textColors = [
367
+      ZefyrTheme.of(context).defaultLineTheme.textStyle.color, ...List.of(kTextColors),
368
+    ];
369
+
357
     return Material(
370
     return Material(
358
       color: theme.color,
371
       color: theme.color,
359
       child: Container(
372
       child: Container(
360
         decoration: BoxDecoration(
373
         decoration: BoxDecoration(
361
           border: Border(top: BorderSide(color: theme.dividerColor, width: 1)),
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
   }
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
 /// Controls image attribute.
519
 /// Controls image attribute.
474
 ///
520
 ///
475
 /// When pressed, this button displays overlay toolbar with three
521
 /// When pressed, this button displays overlay toolbar with three
576
                                 shape: RoundedRectangleBorder(),
622
                                 shape: RoundedRectangleBorder(),
577
                                 color: Color(0xFFF6F6F6),
623
                                 color: Color(0xFFF6F6F6),
578
                                 onPressed: () {
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
                                   PhotoPicker.pickAsset(
629
                                   PhotoPicker.pickAsset(
581
                                     context: context,
630
                                     context: context,
582
                                     rowCount: 4,
631
                                     rowCount: 4,
588
                                     photoPathList: null,
637
                                     photoPathList: null,
589
                                   ).then((PickedEntity entity) async {
638
                                   ).then((PickedEntity entity) async {
590
                                     if (entity.asset.isNotEmpty) {
639
                                     if (entity.asset.isNotEmpty) {
591
-                                      toolbar.closeOverlay();
592
-                                      final editor =
593
-                                          ZefyrToolbar.of(context).editor;
594
                                       for (var asset in entity.asset) {
640
                                       for (var asset in entity.asset) {
595
                                         var file = await asset.originFile;
641
                                         var file = await asset.originFile;
596
                                         final image = await editor.imageDelegate
642
                                         final image = await editor.imageDelegate
599
                                           editor.formatSelection(NotusAttribute
645
                                           editor.formatSelection(NotusAttribute
600
                                               .embed
646
                                               .embed
601
                                               .image(image));
647
                                               .image(image));
648
+                                          editor.closeKeyboard();
602
                                         }
649
                                         }
603
                                       }
650
                                       }
604
                                     }
651
                                     }
642
                           initialData: PickedEntity(),
689
                           initialData: PickedEntity(),
643
                           builder: (context, snapshot) {
690
                           builder: (context, snapshot) {
644
                             return PhotoPicker.buildGallery(
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
                         onPressed: snapshot.data.asset.isNotEmpty
772
                         onPressed: snapshot.data.asset.isNotEmpty
725
                             ? () async {
773
                             ? () async {
726
                                 pickedChangeController.add(PickedEntity());
774
                                 pickedChangeController.add(PickedEntity());
727
-                                toolbar.closeOverlay();
775
+                                // toolbar.closeOverlay();
776
+                                toolbar.editor.closeKeyboard(true);
728
                                 for (var asset in snapshot.data.asset) {
777
                                 for (var asset in snapshot.data.asset) {
729
                                   var file = await asset.originFile;
778
                                   var file = await asset.originFile;
730
                                   final image = await toolbar
779
                                   final image = await toolbar
731
                                       .editor.imageDelegate
780
                                       .editor.imageDelegate
732
                                       .picked(file, snapshot.data.isFullImage);
781
                                       .picked(file, snapshot.data.isFullImage);
733
                                   if (image != null) {
782
                                   if (image != null) {
783
+                                    // toolbar.editor.toolbarAction = null;
784
+                                    // toolbar.editor.keepOverlay = true;
734
                                     toolbar.editor.formatSelection(
785
                                     toolbar.editor.formatSelection(
735
                                         NotusAttribute.embed.image(image));
786
                                         NotusAttribute.embed.image(image));
787
+                                    toolbar.editor.closeKeyboard();
736
                                   }
788
                                   }
737
                                 }
789
                                 }
738
                               }
790
                               }
826
   OverlayEntry _overlayEntry;
878
   OverlayEntry _overlayEntry;
827
 
879
 
828
   Future<void> showOverlay() async {
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
     var value = ZefyrLinkEntity();
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
       value = value.copyWith(text: text);
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
     if (result != null) {
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 View File

154
     if (style.contains(NotusAttribute.link)) {
154
     if (style.contains(NotusAttribute.link)) {
155
       result = result.merge(theme.attributeTheme.link);
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
     return result;
174
     return result;
158
   }
175
   }
159
 
176
 

+ 4
- 1
packages/zefyr/lib/src/widgets/controller.dart View File

168
 
168
 
169
     if (length == 0 &&
169
     if (length == 0 &&
170
         (attribute.key == NotusAttribute.bold.key ||
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
       // Add the attribute to our toggledStyle. It will be used later upon insertion.
175
       // Add the attribute to our toggledStyle. It will be used later upon insertion.
173
       _toggledStyles = toggledStyles.put(attribute);
176
       _toggledStyles = toggledStyles.put(attribute);
174
     }
177
     }

+ 8
- 8
packages/zefyr/lib/src/widgets/iconfont.dart View File

74
   static const IconData note_more_favorite =
74
   static const IconData note_more_favorite =
75
       IconData(0xe6fe, fontFamily: _family, fontPackage: _fontPackage);
75
       IconData(0xe6fe, fontFamily: _family, fontPackage: _fontPackage);
76
   static const IconData note_more_move = IconData(0xe6ff, fontFamily: _family, fontPackage: _fontPackage);
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
       IconData(0xe6e4, fontFamily: _family, fontPackage: _fontPackage);
78
       IconData(0xe6e4, fontFamily: _family, fontPackage: _fontPackage);
79
   static const IconData note_editor_text_code =
79
   static const IconData note_editor_text_code =
80
       IconData(0xe6e5, fontFamily: _family, fontPackage: _fontPackage);
80
       IconData(0xe6e5, fontFamily: _family, fontPackage: _fontPackage);
81
   static const IconData note_editor_text_bold =
81
   static const IconData note_editor_text_bold =
82
       IconData(0xe6e6, fontFamily: _family, fontPackage: _fontPackage);
82
       IconData(0xe6e6, fontFamily: _family, fontPackage: _fontPackage);
83
-  static const IconData note_editor_text_h1 =
83
+  static const IconData note_editor_text_h2 =
84
       IconData(0xe6e7, fontFamily: _family, fontPackage: _fontPackage);
84
       IconData(0xe6e7, fontFamily: _family, fontPackage: _fontPackage);
85
   static const IconData note_editor_text_center =
85
   static const IconData note_editor_text_center =
86
       IconData(0xe6e8, fontFamily: _family, fontPackage: _fontPackage);
86
       IconData(0xe6e8, fontFamily: _family, fontPackage: _fontPackage);
88
       IconData(0xe6e9, fontFamily: _family, fontPackage: _fontPackage);
88
       IconData(0xe6e9, fontFamily: _family, fontPackage: _fontPackage);
89
   static const IconData note_editor_text_left =
89
   static const IconData note_editor_text_left =
90
       IconData(0xe6ea, fontFamily: _family, fontPackage: _fontPackage);
90
       IconData(0xe6ea, fontFamily: _family, fontPackage: _fontPackage);
91
-  static const IconData note_editor_text_h2 =
92
-      IconData(0xe6eb, fontFamily: _family, fontPackage: _fontPackage);
93
   static const IconData note_editor_text_h3 =
91
   static const IconData note_editor_text_h3 =
92
+      IconData(0xe6eb, fontFamily: _family, fontPackage: _fontPackage);
93
+  static const IconData note_editor_text_h4 =
94
       IconData(0xe6ec, fontFamily: _family, fontPackage: _fontPackage);
94
       IconData(0xe6ec, fontFamily: _family, fontPackage: _fontPackage);
95
   static const IconData note_editor_text_right =
95
   static const IconData note_editor_text_right =
96
       IconData(0xe6ed, fontFamily: _family, fontPackage: _fontPackage);
96
       IconData(0xe6ed, fontFamily: _family, fontPackage: _fontPackage);
97
   static const IconData note_editor_text_hr =
97
   static const IconData note_editor_text_hr =
98
       IconData(0xe6ee, fontFamily: _family, fontPackage: _fontPackage);
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
   static const IconData note_editor_text_underline =
101
   static const IconData note_editor_text_underline =
102
       IconData(0xe6f0, fontFamily: _family, fontPackage: _fontPackage);
102
       IconData(0xe6f0, fontFamily: _family, fontPackage: _fontPackage);
103
   static const IconData note_editor_text_ul =
103
   static const IconData note_editor_text_ul =
106
       IconData(0xe6f2, fontFamily: _family, fontPackage: _fontPackage);
106
       IconData(0xe6f2, fontFamily: _family, fontPackage: _fontPackage);
107
   static const IconData note_editor_text_in =
107
   static const IconData note_editor_text_in =
108
       IconData(0xe6f3, fontFamily: _family, fontPackage: _fontPackage);
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
   static const IconData note_editor_text_para =
111
   static const IconData note_editor_text_para =
112
       IconData(0xe6f5, fontFamily: _family, fontPackage: _fontPackage);
112
       IconData(0xe6f5, fontFamily: _family, fontPackage: _fontPackage);
113
   static const IconData note_editor_text_ol =
113
   static const IconData note_editor_text_ol =

+ 4
- 1
packages/zefyr/lib/src/widgets/scope.dart View File

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

+ 33
- 27
packages/zefyr/lib/src/widgets/theme.dart View File

77
       textStyle: defaultStyle.style.copyWith(
77
       textStyle: defaultStyle.style.copyWith(
78
         fontSize: 16.0,
78
         fontSize: 16.0,
79
         height: 1.3,
79
         height: 1.3,
80
+        color: Color(0xFF595959),
80
       ),
81
       ),
81
       padding: EdgeInsets.symmetric(vertical: 8.0),
82
       padding: EdgeInsets.symmetric(vertical: 8.0),
82
     );
83
     );
366
 
367
 
367
     return AttributeTheme(
368
     return AttributeTheme(
368
       bold: TextStyle(fontWeight: FontWeight.bold),
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
       italic: TextStyle(fontStyle: FontStyle.italic),
372
       italic: TextStyle(fontStyle: FontStyle.italic),
372
       link: TextStyle(
373
       link: TextStyle(
373
         decoration: TextDecoration.underline,
374
         decoration: TextDecoration.underline,
375
       ),
376
       ),
376
       heading1: LineTheme(
377
       heading1: LineTheme(
377
         textStyle: defaultLineTheme.textStyle.copyWith(
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
         padding: EdgeInsets.only(top: 16.0),
384
         padding: EdgeInsets.only(top: 16.0),
384
       ),
385
       ),
385
       heading2: LineTheme(
386
       heading2: LineTheme(
386
         textStyle: defaultLineTheme.textStyle.copyWith(
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
       heading3: LineTheme(
395
       heading3: LineTheme(
395
         textStyle: defaultLineTheme.textStyle.copyWith(
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
           fontWeight: FontWeight.w500,
400
           fontWeight: FontWeight.w500,
400
         ),
401
         ),
401
-        padding: EdgeInsets.only(top: 16.0),
402
+        padding: EdgeInsets.only(top: 8.0),
402
       ),
403
       ),
403
       heading4: LineTheme(
404
       heading4: LineTheme(
404
         textStyle: defaultLineTheme.textStyle.copyWith(
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
           fontWeight: FontWeight.w500,
409
           fontWeight: FontWeight.w500,
409
         ),
410
         ),
410
-        padding: EdgeInsets.only(top: 12.0),
411
+        padding: EdgeInsets.only(top: 4.0),
411
       ),
412
       ),
412
       heading5: LineTheme(
413
       heading5: LineTheme(
413
         textStyle: defaultLineTheme.textStyle.copyWith(
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
           fontWeight: FontWeight.w500,
418
           fontWeight: FontWeight.w500,
418
         ),
419
         ),
419
-        padding: EdgeInsets.only(top: 8.0),
420
+        padding: EdgeInsets.only(top: 4.0),
420
       ),
421
       ),
421
       heading6: LineTheme(
422
       heading6: LineTheme(
422
         textStyle: defaultLineTheme.textStyle.copyWith(
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
           fontWeight: FontWeight.w500,
427
           fontWeight: FontWeight.w500,
427
         ),
428
         ),
428
         padding: EdgeInsets.only(top: 4.0),
429
         padding: EdgeInsets.only(top: 4.0),
461
   AttributeTheme copyWith({
462
   AttributeTheme copyWith({
462
     TextStyle bold,
463
     TextStyle bold,
463
     TextStyle underline,
464
     TextStyle underline,
465
+    TextStyle deleteline,
464
     TextStyle italic,
466
     TextStyle italic,
465
     TextStyle link,
467
     TextStyle link,
466
     LineTheme heading1,
468
     LineTheme heading1,
477
     return AttributeTheme(
479
     return AttributeTheme(
478
       bold: bold ?? this.bold,
480
       bold: bold ?? this.bold,
479
       underline: underline ?? this.underline,
481
       underline: underline ?? this.underline,
482
+      deleteline: deleteline ?? this.deleteline,
480
       italic: italic ?? this.italic,
483
       italic: italic ?? this.italic,
481
       link: link ?? this.link,
484
       link: link ?? this.link,
482
       heading1: heading1 ?? this.heading1,
485
       heading1: heading1 ?? this.heading1,
499
     return copyWith(
502
     return copyWith(
500
       bold: bold?.merge(other.bold) ?? other.bold,
503
       bold: bold?.merge(other.bold) ?? other.bold,
501
       underline: underline?.merge(other.underline) ?? other.underline,
504
       underline: underline?.merge(other.underline) ?? other.underline,
505
+      deleteline: underline?.merge(other.deleteline) ?? other.deleteline,
502
       italic: italic?.merge(other.italic) ?? other.italic,
506
       italic: italic?.merge(other.italic) ?? other.italic,
503
       link: link?.merge(other.link) ?? other.link,
507
       link: link?.merge(other.link) ?? other.link,
504
       heading1: heading1?.merge(other.heading1) ?? other.heading1,
508
       heading1: heading1?.merge(other.heading1) ?? other.heading1,
520
     final AttributeTheme otherTheme = other;
524
     final AttributeTheme otherTheme = other;
521
     return (otherTheme.bold == bold) &&
525
     return (otherTheme.bold == bold) &&
522
         (otherTheme.underline == underline) &&
526
         (otherTheme.underline == underline) &&
527
+        (otherTheme.deleteline == deleteline) &&
523
         (otherTheme.italic == italic) &&
528
         (otherTheme.italic == italic) &&
524
         (otherTheme.link == link) &&
529
         (otherTheme.link == link) &&
525
         (otherTheme.heading1 == heading1) &&
530
         (otherTheme.heading1 == heading1) &&
539
     return hashList([
544
     return hashList([
540
       bold,
545
       bold,
541
       underline,
546
       underline,
547
+      deleteline,
542
       italic,
548
       italic,
543
       link,
549
       link,
544
       heading1,
550
       heading1,
586
       iconFillColor: theme.brightness == Brightness.light ? Color(0xFFF2F2F2) : Color(0xFF1F1F1F),
592
       iconFillColor: theme.brightness == Brightness.light ? Color(0xFFF2F2F2) : Color(0xFF1F1F1F),
587
       iconColor: Color(0xFF595959),
593
       iconColor: Color(0xFF595959),
588
       disabledIconColor: theme.brightness == Brightness.light ? Color(0xFFBFBFBF) : Color(0xFF363636),
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 View File

22
   link,
22
   link,
23
   unlink,
23
   unlink,
24
   emoji,
24
   emoji,
25
+  color,
25
   undo,
26
   undo,
26
   redo,
27
   redo,
27
   save,
28
   save,
51
 
52
 
52
 final kZefyrToolbarAttributeActions = <ZefyrToolbarAction, NotusAttributeKey>{
53
 final kZefyrToolbarAttributeActions = <ZefyrToolbarAction, NotusAttributeKey>{
53
   ZefyrToolbarAction.bold: NotusAttribute.bold,
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
   ZefyrToolbarAction.italic: NotusAttribute.italic,
57
   ZefyrToolbarAction.italic: NotusAttribute.italic,
57
   ZefyrToolbarAction.link: NotusAttribute.link,
58
   ZefyrToolbarAction.link: NotusAttribute.link,
59
+  ZefyrToolbarAction.color: NotusAttribute.color,
58
   // ZefyrToolbarAction.text: NotusAttribute.heading,
60
   // ZefyrToolbarAction.text: NotusAttribute.heading,
59
   ZefyrToolbarAction.heading: NotusAttribute.heading,
61
   ZefyrToolbarAction.heading: NotusAttribute.heading,
60
   ZefyrToolbarAction.headingLevel1: NotusAttribute.heading.level1,
62
   ZefyrToolbarAction.headingLevel1: NotusAttribute.heading.level1,
92
   ZefyrToolbarAction.unlink: Icons.link_off,
94
   ZefyrToolbarAction.unlink: Icons.link_off,
93
   ZefyrToolbarAction.clipboardCopy: Icons.content_copy,
95
   ZefyrToolbarAction.clipboardCopy: Icons.content_copy,
94
   ZefyrToolbarAction.openInBrowser: Icons.open_in_new,
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
   ZefyrToolbarAction.text: ZefyrFont.note_editor_text,
103
   ZefyrToolbarAction.text: ZefyrFont.note_editor_text,
102
   ZefyrToolbarAction.code: ZefyrFont.note_editor_text_code,
104
   ZefyrToolbarAction.code: ZefyrFont.note_editor_text_code,
103
   ZefyrToolbarAction.horizontalRule: ZefyrFont.note_editor_text_hr,
105
   ZefyrToolbarAction.horizontalRule: ZefyrFont.note_editor_text_hr,
122
   margin: EdgeInsets.symmetric(horizontal: 10),
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
 /// Allows customizing appearance of [ZefyrToolbar].
139
 /// Allows customizing appearance of [ZefyrToolbar].
126
 abstract class ZefyrToolbarDelegate {
140
 abstract class ZefyrToolbarDelegate {
127
   /// Builds toolbar button for specified [action].
141
   /// Builds toolbar button for specified [action].