mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: typo and document
This commit is contained in:
@ -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) =>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -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!);
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user