Skip to content

Commit

Permalink
feat: support customizing the mobile magnifiter
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasXu0 committed Dec 19, 2023
1 parent e6b1336 commit 65387fe
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 9 deletions.
1 change: 1 addition & 0 deletions example/lib/pages/mobile_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class _MobileEditorState extends State<MobileEditor> {
),
),
padding: const EdgeInsets.symmetric(horizontal: 24.0),
magnifierSize: const Size(144, 96),
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/block_component/base_component/selection/selection_area_painter.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/selection/mobile_selection_service.dart';
import 'package:appflowy_editor/src/render/selection/cursor.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
Expand Down Expand Up @@ -123,10 +124,15 @@ class _BlockSelectionAreaState extends State<BlockSelectionArea> {
prevCursorRect == null) {
return sizedBox;
}
final editorState = context.read<EditorState>();
final dragMode =
editorState.selectionExtraInfo?[selectionDragModeKey];
final shouldBlink = widget.delegate.shouldCursorBlink &&
dragMode != MobileSelectionDragMode.cursor;
final cursor = Cursor(
key: cursorKey,
rect: prevCursorRect!,
shouldBlink: widget.delegate.shouldCursorBlink,
shouldBlink: shouldBlink,
cursorStyle: widget.delegate.cursorStyle,
color: widget.cursorColor,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,55 @@ class MobileMagnifier extends StatelessWidget {

@override
Widget build(BuildContext context) {
// the magnifier will blink if the center is the same as the offset.
final magicOffset = Offset(0, size.height - 22);
return Positioned.fromRect(
rect: Rect.fromCenter(
center: offset.translate(0, -size.height),
center: offset - magicOffset,
width: size.width,
height: size.height,
),
child: IgnorePointer(
child: Magnifier(
child: _CustomMagnifier(
size: size,
additionalFocalPointOffset: magicOffset,
),
),
);
}
}

class _CustomMagnifier extends StatelessWidget {
const _CustomMagnifier({
this.additionalFocalPointOffset = Offset.zero,
required this.size,
});

final Size size;
final Offset additionalFocalPointOffset;

@override
Widget build(BuildContext context) {
return RawMagnifier(
decoration: const MagnifierDecoration(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(40)),
),
shadows: <BoxShadow>[
BoxShadow(
blurRadius: 1.5,
offset: Offset(0, 2),
spreadRadius: 0.75,
color: Color.fromARGB(25, 0, 0, 0),
),
],
),
magnificationScale: 1.25,
focalPointOffset: additionalFocalPointOffset,
size: size,
child: const ColoredBox(
color: Color.fromARGB(8, 158, 158, 158),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ enum MobileSelectionHandlerType {
cursorHandler,
}

// the value type is MobileSelectionDragMode
const String selectionDragModeKey = 'selection_drag_mode';

class MobileSelectionServiceWidget extends StatefulWidget {
const MobileSelectionServiceWidget({
super.key,
this.cursorColor = const Color(0xFF00BCF0),
this.selectionColor = const Color.fromARGB(53, 111, 201, 231),
this.showMagnifier = true,
this.magnifierSize = const Size(72, 48),
required this.child,
});

Expand All @@ -37,6 +41,8 @@ class MobileSelectionServiceWidget extends StatefulWidget {
/// only works on iOS or Android.
final bool showMagnifier;

final Size magnifierSize;

@override
State<MobileSelectionServiceWidget> createState() =>
_MobileSelectionServiceWidgetState();
Expand Down Expand Up @@ -117,7 +123,7 @@ class _MobileSelectionServiceWidgetState
final renderBox = context.findRenderObject() as RenderBox;
final local = renderBox.globalToLocal(offset);
return MobileMagnifier(
size: const Size(72, 48),
size: widget.magnifierSize,
offset: local,
);
},
Expand Down Expand Up @@ -145,6 +151,9 @@ class _MobileSelectionServiceWidgetState
editorState.updateSelectionWithReason(
selection,
reason: SelectionUpdateReason.uiEvent,
extraInfo: {
selectionDragModeKey: dragMode,
},
);
}

Expand Down Expand Up @@ -266,7 +275,10 @@ class _MobileSelectionServiceWidgetState
return;
}

editorState.selection = Selection.collapsed(position);
editorState.updateSelectionWithReason(
Selection.collapsed(position),
extraInfo: null,
);
}

void _onDoubleTapUp(TapUpDetails details) {
Expand Down Expand Up @@ -375,6 +387,12 @@ class _MobileSelectionServiceWidgetState
void _onPanEnd(DragEndDetails details) {
// do nothing
_lastPanOffset.value = null;

// clear the status
editorState.updateSelectionWithReason(
editorState.selection,
extraInfo: null,
);
}

void _updateSelectionAreas(Selection selection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/selection/desktop_selection_service.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/selection/mobile_selection_service.dart';
import 'package:flutter/material.dart' hide Overlay, OverlayEntry;
import 'package:provider/provider.dart';

class SelectionServiceWidget extends StatefulWidget {
const SelectionServiceWidget({
Expand Down Expand Up @@ -48,11 +49,13 @@ class _SelectionServiceWidgetState extends State<SelectionServiceWidget>
);
}

final editorState = context.read<EditorState>();
return MobileSelectionServiceWidget(
key: forwardKey,
cursorColor: widget.cursorColor,
selectionColor: widget.selectionColor,
showMagnifier: widget.showMagnifier,
magnifierSize: editorState.editorStyle.magnifierSize,
child: widget.child,
);
}
Expand Down
10 changes: 8 additions & 2 deletions lib/src/editor/editor_component/style/editor_style.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import 'package:appflowy_editor/appflowy_editor.dart';

import 'package:flutter/material.dart';

/// The style of the editor.
Expand All @@ -14,6 +13,7 @@ class EditorStyle {
required this.selectionColor,
required this.textStyleConfiguration,
required this.textSpanDecorator,
this.magnifierSize = const Size(72, 48),
this.defaultTextDirection,
});

Expand Down Expand Up @@ -43,6 +43,10 @@ class EditorStyle {

final String? defaultTextDirection;

/// The size of the magnifier.
/// Only works on mobile.
final Size magnifierSize;

const EditorStyle.desktop({
EdgeInsets? padding,
Color? cursorColor,
Expand All @@ -59,7 +63,8 @@ class EditorStyle {
text: TextStyle(fontSize: 16, color: Colors.black),
),
textSpanDecorator =
textSpanDecorator ?? defaultTextSpanDecoratorForAttribute;
textSpanDecorator ?? defaultTextSpanDecoratorForAttribute,
magnifierSize = Size.zero;

const EditorStyle.mobile({
EdgeInsets? padding,
Expand All @@ -68,6 +73,7 @@ class EditorStyle {
TextStyleConfiguration? textStyleConfiguration,
TextSpanDecoratorForAttribute? textSpanDecorator,
this.defaultTextDirection,
this.magnifierSize = const Size(72, 48),
}) : padding = padding ?? const EdgeInsets.symmetric(horizontal: 20),
cursorColor = cursorColor ?? const Color(0xFF00BCF0),
selectionColor =
Expand Down
3 changes: 1 addition & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ dependencies:
keyboard_height_plugin: ^0.0.4
numerus: ^2.1.2


dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^3.0.1
network_image_mock: ^2.1.1
mockito: ^5.4.1
leak_tracker_flutter_testing: ^1.0.10
leak_tracker: '>=9.0.0 <11.0.0'
leak_tracker: 9.0.16

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
Expand Down

0 comments on commit 65387fe

Please sign in to comment.