mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: implement bold text in toolbar service
This commit is contained in:
parent
5ecfc4ff2e
commit
ba78f0073d
@ -178,7 +178,7 @@ class TextNode extends Node {
|
||||
}) : _delta = delta;
|
||||
|
||||
TextNode.empty()
|
||||
: _delta = Delta([TextInsert('')]),
|
||||
: _delta = Delta([TextInsert(' ')]),
|
||||
super(
|
||||
type: 'text',
|
||||
children: LinkedList(),
|
||||
|
@ -1,43 +1,35 @@
|
||||
import 'package:flowy_editor/editor_state.dart';
|
||||
import 'package:flowy_editor/infra/flowy_svg.dart';
|
||||
import 'package:flowy_editor/render/rich_text/rich_text_style.dart';
|
||||
import 'package:flowy_editor/service/default_text_operations/format_rich_text_style.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef ToolbarEventHandler = void Function(
|
||||
EditorState editorState, String eventName);
|
||||
typedef ToolbarEventHandler = void Function(EditorState editorState);
|
||||
|
||||
typedef ToolbarEventHandlers = List<Map<String, ToolbarEventHandler>>;
|
||||
ToolbarEventHandlers defaultToolbarEventHandlers = [
|
||||
{
|
||||
'bold': ((editorState, eventName) {}),
|
||||
'italic': ((editorState, eventName) {}),
|
||||
'strikethrough': ((editorState, eventName) {}),
|
||||
'underline': ((editorState, eventName) {}),
|
||||
'quote': ((editorState, eventName) {}),
|
||||
'number_list': ((editorState, eventName) {}),
|
||||
'bulleted_list': ((editorState, eventName) {}),
|
||||
}
|
||||
];
|
||||
typedef ToolbarEventHandlers = Map<String, ToolbarEventHandler>;
|
||||
|
||||
ToolbarEventHandlers defaultListToolbarEventHandlers = [
|
||||
{
|
||||
'h1': ((editorState, eventName) {}),
|
||||
},
|
||||
{
|
||||
'h2': ((editorState, eventName) {}),
|
||||
},
|
||||
{
|
||||
'h3': ((editorState, eventName) {}),
|
||||
},
|
||||
{
|
||||
'bulleted_list': ((editorState, eventName) {}),
|
||||
},
|
||||
{
|
||||
'quote': ((editorState, eventName) {}),
|
||||
}
|
||||
ToolbarEventHandlers defaultToolbarEventHandlers = {
|
||||
'bold': ((editorState) {
|
||||
formatRichTextStyle(editorState, {StyleKey.bold: true});
|
||||
}),
|
||||
'italic': ((editorState) {}),
|
||||
'strikethrough': ((editorState) {}),
|
||||
'underline': ((editorState) {}),
|
||||
'quote': ((editorState) {}),
|
||||
'number_list': ((editorState) {}),
|
||||
'bulleted_list': ((editorState) {}),
|
||||
};
|
||||
|
||||
List<String> defaultListToolbarEventNames = [
|
||||
'H1',
|
||||
'H2',
|
||||
'H3',
|
||||
'B-List',
|
||||
'N-List',
|
||||
];
|
||||
|
||||
class ToolbarWidget extends StatefulWidget {
|
||||
ToolbarWidget({
|
||||
const ToolbarWidget({
|
||||
Key? key,
|
||||
required this.editorState,
|
||||
required this.layerLink,
|
||||
@ -137,7 +129,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
|
||||
preferBelow: false,
|
||||
message: name,
|
||||
child: GestureDetector(
|
||||
onTap: onTap ?? () => debugPrint('toolbar tap $name'),
|
||||
onTap: onTap ?? () => _onTap(name),
|
||||
child: SizedBox.fromSize(
|
||||
size: width != null
|
||||
? Size(width, toolbarHeight)
|
||||
@ -154,9 +146,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
|
||||
|
||||
void _onTapListToolbar(BuildContext context) {
|
||||
// TODO: implement more detailed UI.
|
||||
final items = defaultListToolbarEventHandlers
|
||||
.map((handler) => handler.keys.first)
|
||||
.toList(growable: false);
|
||||
final items = defaultListToolbarEventNames;
|
||||
final renderBox =
|
||||
_listToolbarKey.currentContext?.findRenderObject() as RenderBox;
|
||||
final offset = renderBox
|
||||
@ -198,7 +188,7 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
debugPrint('tap on $index');
|
||||
_onTap(items[index]);
|
||||
},
|
||||
);
|
||||
}),
|
||||
@ -210,6 +200,14 @@ class _ToolbarWidgetState extends State<ToolbarWidget> {
|
||||
Overlay.of(context)?.insert(_listToolbarOverlay!);
|
||||
}
|
||||
|
||||
void _onTap(String eventName) {
|
||||
if (defaultToolbarEventHandlers.containsKey(eventName)) {
|
||||
defaultToolbarEventHandlers[eventName]!(widget.editorState);
|
||||
return;
|
||||
}
|
||||
assert(false, 'Could not find the event handler for $eventName');
|
||||
}
|
||||
|
||||
void _onSelectionChange() {
|
||||
_listToolbarOverlay?.remove();
|
||||
_listToolbarOverlay = null;
|
||||
|
@ -17,29 +17,38 @@ bool formatRichTextStyle(
|
||||
// 1. All nodes are text nodes.
|
||||
// 2. The first node is not TextNode.
|
||||
// 3. The last node is not TextNode.
|
||||
for (var i = 0; i < textNodes.length; i++) {
|
||||
final textNode = textNodes[i];
|
||||
if (i == 0 && textNode == nodes.first) {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
selection.start.offset,
|
||||
textNode.toRawString().length - selection.start.offset,
|
||||
attributes,
|
||||
);
|
||||
} else if (i == textNodes.length - 1 && textNode == nodes.last) {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
0,
|
||||
selection.end.offset,
|
||||
attributes,
|
||||
);
|
||||
} else {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
0,
|
||||
textNode.toRawString().length,
|
||||
attributes,
|
||||
);
|
||||
if (nodes.length == textNodes.length && textNodes.length == 1) {
|
||||
builder.formatText(
|
||||
textNodes.first,
|
||||
selection.start.offset,
|
||||
selection.end.offset - selection.start.offset,
|
||||
attributes,
|
||||
);
|
||||
} else {
|
||||
for (var i = 0; i < textNodes.length; i++) {
|
||||
final textNode = textNodes[i];
|
||||
if (i == 0 && textNode == nodes.first) {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
selection.start.offset,
|
||||
textNode.toRawString().length - selection.start.offset,
|
||||
attributes,
|
||||
);
|
||||
} else if (i == textNodes.length - 1 && textNode == nodes.last) {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
0,
|
||||
selection.end.offset,
|
||||
attributes,
|
||||
);
|
||||
} else {
|
||||
builder.formatText(
|
||||
textNode,
|
||||
0,
|
||||
textNode.toRawString().length,
|
||||
attributes,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class _FlowyToolbarState extends State<FlowyToolbar> with ToolbarService {
|
||||
editorState: widget.editorState,
|
||||
layerLink: layerLink,
|
||||
offset: offset.translate(0, -37.0),
|
||||
handlers: const [],
|
||||
handlers: const {},
|
||||
),
|
||||
);
|
||||
Overlay.of(context)?.insert(_toolbarOverlay!);
|
||||
|
Loading…
Reference in New Issue
Block a user