feat: typo and document

This commit is contained in:
Lucas.Xu
2022-07-25 20:18:14 +08:00
parent 0bf1e61d55
commit fcb09e9636
13 changed files with 80 additions and 51 deletions

View File

@ -97,11 +97,22 @@ class _MyHomePageState extends State<MyHomePage> {
return FlowyEditor( return FlowyEditor(
editorState: _editorState, editorState: _editorState,
keyEventHandler: const [], keyEventHandler: const [],
shortCuts: [ shortcuts: [
// TODO: this won't work, just a example for now. // TODO: this won't work, just a example for now.
{ {
'heading': (editorState, eventName) => 'h1': (editorState, eventName) {
debugPrint('shortcut => $eventName') debugPrint('shortcut => $eventName');
final selectedNodes = editorState.selectedNodes;
if (selectedNodes.isEmpty) {
return;
}
final textNode = selectedNodes.first as TextNode;
TransactionBuilder(editorState)
..formatText(textNode, 0, textNode.toRawString().length, {
'heading': 'h1',
})
..commit();
}
}, },
{ {
'bold': (editorState, eventName) => 'bold': (editorState, eventName) =>

View File

@ -52,7 +52,7 @@ class __ImageNodeWidgetState extends State<_ImageNodeWidget> with Selectable {
} }
@override @override
TextSelection? getTextSelection() { TextSelection? getCurrentTextSelection() {
return null; return null;
} }
@ -62,12 +62,12 @@ class __ImageNodeWidgetState extends State<_ImageNodeWidget> with Selectable {
} }
@override @override
Offset getLeftOfOffset() { Offset getBackwardOffset() {
return Offset.zero; return Offset.zero;
} }
@override @override
Offset getRightOfOffset() { Offset getForwardOffset() {
return Offset.zero; return Offset.zero;
} }

View File

@ -100,7 +100,7 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
} }
@override @override
TextSelection? getTextSelection() { TextSelection? getCurrentTextSelection() {
return _textSelection; return _textSelection;
} }
@ -111,7 +111,7 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
} }
@override @override
Offset getLeftOfOffset() { Offset getBackwardOffset() {
final textSelection = _textSelection; final textSelection = _textSelection;
if (textSelection != null) { if (textSelection != null) {
final leftTextSelection = TextSelection.collapsed( final leftTextSelection = TextSelection.collapsed(
@ -123,7 +123,7 @@ class _SelectedTextNodeWidgetState extends State<_SelectedTextNodeWidget>
} }
@override @override
Offset getRightOfOffset() { Offset getForwardOffset() {
final textSelection = _textSelection; final textSelection = _textSelection;
if (textSelection != null) { if (textSelection != null) {
final leftTextSelection = TextSelection.collapsed( final leftTextSelection = TextSelection.collapsed(

View File

@ -1,9 +1,9 @@
import 'package:flowy_editor/flowy_editor.dart'; import 'package:flowy_editor/flowy_editor.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
typedef FloatingShortCutHandler = void Function( typedef FloatingShortcutHandler = void Function(
EditorState editorState, String eventName); EditorState editorState, String eventName);
typedef FloatingShortCuts = List<Map<String, FloatingShortCutHandler>>; typedef FloatingShortcuts = List<Map<String, FloatingShortcutHandler>>;
class FloatingShortcutWidget extends StatelessWidget { class FloatingShortcutWidget extends StatelessWidget {
const FloatingShortcutWidget({ const FloatingShortcutWidget({
@ -17,11 +17,11 @@ class FloatingShortcutWidget extends StatelessWidget {
final EditorState editorState; final EditorState editorState;
final LayerLink layerLink; final LayerLink layerLink;
final Rect rect; final Rect rect;
final FloatingShortCuts floatingShortcuts; final FloatingShortcuts floatingShortcuts;
List<String> get _shortcutNames => List<String> get _shortcutNames =>
floatingShortcuts.map((shortcut) => shortcut.keys.first).toList(); floatingShortcuts.map((shortcut) => shortcut.keys.first).toList();
List<FloatingShortCutHandler> get _shortcutHandlers => List<FloatingShortcutHandler> get _shortcutHandlers =>
floatingShortcuts.map((shortcut) => shortcut.values.first).toList(); floatingShortcuts.map((shortcut) => shortcut.values.first).toList();
@override @override
@ -38,7 +38,7 @@ class FloatingShortcutWidget extends StatelessWidget {
itemCount: floatingShortcuts.length, itemCount: floatingShortcuts.length,
itemBuilder: ((context, index) { itemBuilder: ((context, index) {
final name = _shortcutNameInIndex(index); final name = _shortcutNameInIndex(index);
final handler = _shortCutHandlerInIndex(index); final handler = _shortcutHandlerInIndex(index);
return Card( return Card(
child: GestureDetector( child: GestureDetector(
onTap: () => handler(editorState, name), onTap: () => handler(editorState, name),
@ -53,6 +53,6 @@ class FloatingShortcutWidget extends StatelessWidget {
} }
String _shortcutNameInIndex(int index) => _shortcutNames[index]; String _shortcutNameInIndex(int index) => _shortcutNames[index];
FloatingShortCutHandler _shortCutHandlerInIndex(int index) => FloatingShortcutHandler _shortcutHandlerInIndex(int index) =>
_shortcutHandlers[index]; _shortcutHandlers[index];
} }

View File

@ -2,24 +2,40 @@ import 'package:flutter/material.dart';
/// ///
mixin Selectable<T extends StatefulWidget> on State<T> { mixin Selectable<T extends StatefulWidget> on State<T> {
/// Returns a [Rect] list for overlay. /// Returns a [List] of the [Rect] selection sorrounded by start and end
/// [start] and [end] are global offsets. /// in current widget.
/// The return result must be an local offset. ///
/// [start] and [end] are the offsets under the global coordinate system.
///
/// The return result must be a [List] of the [Rect]
/// under the local coordinate system.
List<Rect> getSelectionRectsInRange(Offset start, Offset end); List<Rect> getSelectionRectsInRange(Offset start, Offset end);
/// Returns a [Rect] for cursor. /// Returns a [Rect] for the offset in current widget.
/// The return result must be an local offset. ///
/// [start] is the offset of the global coordination system.
///
/// The return result must be an offset of the local coordinate system.
Rect getCursorRect(Offset start); Rect getCursorRect(Offset start);
/// Returns one unit offset to the left of the offset /// Returns a backward offset of the current offset based on the cause.
Offset getLeftOfOffset(/* Cause */); Offset getBackwardOffset(/* Cause */);
/// Returns one unit offset to the right of the offset /// Returns a forward offset of the current offset based on the cause.
Offset getRightOfOffset(/* Cause */); Offset getForwardOffset(/* Cause */);
/// For [TextNode] only. /// For [TextNode] only.
TextSelection? getTextSelection(); ///
/// Returns a [TextSelection] or [Null].
///
/// Only the widget rendered by [TextNode] need to implement the detail,
/// and the rest can return null.
TextSelection? getCurrentTextSelection();
/// For [TextNode] only. /// For [TextNode] only.
///
/// Retruns a [Offset].
/// Only the widget rendered by [TextNode] need to implement the detail,
/// and the rest can return [Offset.zero].
Offset getOffsetByTextSelection(TextSelection textSelection); Offset getOffsetByTextSelection(TextSelection textSelection);
} }

View File

@ -15,12 +15,12 @@ class FlowyEditor extends StatefulWidget {
Key? key, Key? key,
required this.editorState, required this.editorState,
required this.keyEventHandler, required this.keyEventHandler,
required this.shortCuts, required this.shortcuts,
}) : super(key: key); }) : super(key: key);
final EditorState editorState; final EditorState editorState;
final List<FlowyKeyEventHandler> keyEventHandler; final List<FlowyKeyEventHandler> keyEventHandler;
final FloatingShortCuts shortCuts; final FloatingShortcuts shortcuts;
@override @override
State<FlowyEditor> createState() => _FlowyEditorState(); State<FlowyEditor> createState() => _FlowyEditorState();
@ -44,11 +44,11 @@ class _FlowyEditorState extends State<FlowyEditor> {
...widget.keyEventHandler, ...widget.keyEventHandler,
], ],
editorState: editorState, editorState: editorState,
child: FloatingShortCut( child: FloatingShortcut(
key: editorState.service.floatingShortcutServiceKey, key: editorState.service.floatingShortcutServiceKey,
size: const Size(200, 150), // TODO: support customize size. size: const Size(200, 150), // TODO: support customize size.
editorState: editorState, editorState: editorState,
floatingShortCuts: widget.shortCuts, floatingShortcuts: widget.shortcuts,
child: editorState.build(context), child: editorState.build(context),
), ),
), ),

View File

@ -1,33 +1,35 @@
import 'package:flowy_editor/document/node.dart';
import 'package:flowy_editor/flowy_editor.dart'; import 'package:flowy_editor/flowy_editor.dart';
import 'package:flowy_editor/render/selection/floating_shortcut_widget.dart'; import 'package:flowy_editor/render/selection/floating_shortcut_widget.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
mixin FlowyFloatingShortCutService { mixin FlowyFloatingShortcutService {
/// Show the floating shortcut widget beside the offset.
void showInOffset(Offset offset, LayerLink layerLink); void showInOffset(Offset offset, LayerLink layerLink);
/// Hide the floating shortcut widget.
void hide(); void hide();
} }
class FloatingShortCut extends StatefulWidget { class FloatingShortcut extends StatefulWidget {
const FloatingShortCut({ const FloatingShortcut({
Key? key, Key? key,
required this.size, required this.size,
required this.editorState, required this.editorState,
required this.floatingShortCuts, required this.floatingShortcuts,
required this.child, required this.child,
}) : super(key: key); }) : super(key: key);
final Size size; final Size size;
final EditorState editorState; final EditorState editorState;
final Widget child; final Widget child;
final FloatingShortCuts floatingShortCuts; final FloatingShortcuts floatingShortcuts;
@override @override
State<FloatingShortCut> createState() => _FloatingShortCutState(); State<FloatingShortcut> createState() => _FloatingShortcutState();
} }
class _FloatingShortCutState extends State<FloatingShortCut> class _FloatingShortcutState extends State<FloatingShortcut>
with FlowyFloatingShortCutService { with FlowyFloatingShortcutService {
OverlayEntry? _floatintShortcutOverlay; OverlayEntry? _floatintShortcutOverlay;
@override @override
@ -38,7 +40,7 @@ class _FloatingShortCutState extends State<FloatingShortCut>
editorState: widget.editorState, editorState: widget.editorState,
layerLink: layerLink, layerLink: layerLink,
rect: offset.translate(10, 0) & widget.size, rect: offset.translate(10, 0) & widget.size,
floatingShortcuts: widget.floatingShortCuts), floatingShortcuts: widget.floatingShortcuts),
); );
Overlay.of(context)?.insert(_floatintShortcutOverlay!); Overlay.of(context)?.insert(_floatintShortcutOverlay!);
} }

View File

@ -24,9 +24,9 @@ FlowyKeyEventHandler arrowKeysHandler = (editorState, event) {
final selectable = node?.key?.currentState?.unwrapOrNull<Selectable>(); final selectable = node?.key?.currentState?.unwrapOrNull<Selectable>();
Offset? offset; Offset? offset;
if (event.logicalKey == LogicalKeyboardKey.arrowLeft) { if (event.logicalKey == LogicalKeyboardKey.arrowLeft) {
offset = selectable?.getLeftOfOffset(); offset = selectable?.getBackwardOffset();
} else if (event.logicalKey == LogicalKeyboardKey.arrowRight) { } else if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
offset = selectable?.getRightOfOffset(); offset = selectable?.getForwardOffset();
} }
final selectionService = editorState.service.selectionService; final selectionService = editorState.service.selectionService;
if (offset != null) { if (offset != null) {

View File

@ -17,7 +17,7 @@ FlowyKeyEventHandler deleteSingleTextNodeHandler = (editorState, event) {
final node = selectionNodes.first.unwrapOrNull<TextNode>(); final node = selectionNodes.first.unwrapOrNull<TextNode>();
final selectable = node?.key?.currentState?.unwrapOrNull<Selectable>(); final selectable = node?.key?.currentState?.unwrapOrNull<Selectable>();
if (selectable != null) { if (selectable != null) {
final textSelection = selectable.getTextSelection(); final textSelection = selectable.getCurrentTextSelection();
if (textSelection != null) { if (textSelection != null) {
if (textSelection.isCollapsed) { if (textSelection.isCollapsed) {
/// Three cases: /// Three cases:

View File

@ -17,7 +17,7 @@ FlowyKeyEventHandler slashShortcutHandler = (editorState, event) {
final textNode = selectedNodes.first.unwrapOrNull<TextNode>(); final textNode = selectedNodes.first.unwrapOrNull<TextNode>();
final selectable = textNode?.key?.currentState?.unwrapOrNull<Selectable>(); final selectable = textNode?.key?.currentState?.unwrapOrNull<Selectable>();
final textSelection = selectable?.getTextSelection(); final textSelection = selectable?.getCurrentTextSelection();
if (textNode != null && selectable != null && textSelection != null) { if (textNode != null && selectable != null && textSelection != null) {
final offset = selectable.getOffsetByTextSelection(textSelection); final offset = selectable.getOffsetByTextSelection(textSelection);
final rect = selectable.getCursorRect(offset); final rect = selectable.getCursorRect(offset);

View File

@ -1,5 +1,5 @@
import 'package:flowy_editor/render/selection/cursor_widget.dart'; import 'package:flowy_editor/render/selection/cursor_widget.dart';
import 'package:flowy_editor/render/selection/selection_widget.dart'; import 'package:flowy_editor/render/selection/flowy_selection_widget.dart';
import 'package:flowy_editor/extensions/object_extensions.dart'; import 'package:flowy_editor/extensions/object_extensions.dart';
import 'package:flowy_editor/service/floating_shortcut_service.dart'; import 'package:flowy_editor/service/floating_shortcut_service.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@ -293,9 +293,9 @@ class _FlowySelectionState extends State<FlowySelection>
} }
void _clearFloatingShorts() { void _clearFloatingShorts() {
final shortCutService = editorState final shortcutService = editorState
.service.floatingShortcutServiceKey.currentState .service.floatingShortcutServiceKey.currentState
?.unwrapOrNull<FlowyFloatingShortCutService>(); ?.unwrapOrNull<FlowyFloatingShortcutService>();
shortCutService?.hide(); shortcutService?.hide();
} }
} }

View File

@ -14,14 +14,14 @@ class FlowyService {
// keyboard service // keyboard service
final keyboardServiceKey = GlobalKey(debugLabel: 'flowy_keyboard_service'); final keyboardServiceKey = GlobalKey(debugLabel: 'flowy_keyboard_service');
// floating toolbar service // floating shortcut service
final floatingShortcutServiceKey = final floatingShortcutServiceKey =
GlobalKey(debugLabel: 'flowy_floating_shortcut_service'); GlobalKey(debugLabel: 'flowy_floating_shortcut_service');
FlowyFloatingShortCutService get floatingToolbarService { FlowyFloatingShortcutService get floatingToolbarService {
assert(floatingShortcutServiceKey.currentState != null && assert(floatingShortcutServiceKey.currentState != null &&
floatingShortcutServiceKey.currentState floatingShortcutServiceKey.currentState
is FlowyFloatingShortCutService); is FlowyFloatingShortcutService);
return floatingShortcutServiceKey.currentState! return floatingShortcutServiceKey.currentState!
as FlowyFloatingShortCutService; as FlowyFloatingShortcutService;
} }
} }