Refactor using platform helper

pull/602/head
X Code 3 years ago
parent 6b9c85f7cc
commit 53507416d0
  1. 23
      lib/src/utils/platform_helper.dart
  2. 49
      lib/src/widgets/cursor.dart
  3. 20
      lib/src/widgets/default_styles.dart
  4. 185
      lib/src/widgets/editor.dart
  5. 35
      lib/src/widgets/raw_editor.dart
  6. 24
      lib/src/widgets/text_line.dart

@ -5,8 +5,21 @@ bool isMobile([TargetPlatform? targetPlatform]) {
return {TargetPlatform.iOS, TargetPlatform.android}.contains(targetPlatform);
}
bool get isDesktop => {
TargetPlatform.macOS,
TargetPlatform.linux,
TargetPlatform.windows
}.contains(defaultTargetPlatform);
bool isDesktop([TargetPlatform? targetPlatform]) {
targetPlatform ??= defaultTargetPlatform;
return {TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows}
.contains(targetPlatform);
}
bool isKeyboardOS([TargetPlatform? targetPlatform]) {
targetPlatform ??= defaultTargetPlatform;
return isDesktop(targetPlatform) || targetPlatform == TargetPlatform.fuchsia;
}
bool isAppleOS([TargetPlatform? targetPlatform]) {
targetPlatform ??= defaultTargetPlatform;
return {
TargetPlatform.macOS,
TargetPlatform.iOS,
}.contains(targetPlatform);
}

@ -1,8 +1,8 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import '../utils/platform_helper.dart';
import 'box.dart';
/// Style properties of editing cursor.
@ -287,33 +287,26 @@ class CursorPainter {
final caretHeight = editable!.getFullHeightForCaret(position);
if (caretHeight != null) {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
// Override the height to take the full height of the glyph at the
// TextPosition when not on iOS. iOS has special handling that
// creates a taller caret.
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top - 2.0,
caretRect.width,
caretHeight,
);
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
// Center the caret vertically along the text.
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top + (caretHeight - caretRect.height) / 2,
caretRect.width,
caretRect.height,
);
break;
default:
throw UnimplementedError();
if (isKeyboardOS()) {
// Override the height to take the full height of the glyph at the
// TextPosition when not on iOS. iOS has special handling that
// creates a taller caret.
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top - 2.0,
caretRect.width,
caretHeight,
);
} else if (isAppleOS()) {
// Center the caret vertically along the text.
caretRect = Rect.fromLTWH(
caretRect.left,
caretRect.top + (caretHeight - caretRect.height) / 2,
caretRect.width,
caretRect.height,
);
} else {
throw UnimplementedError();
}
}

@ -3,6 +3,7 @@ import 'package:tuple/tuple.dart';
import '../../flutter_quill.dart';
import '../../models/documents/style.dart';
import '../utils/platform_helper.dart';
class QuillStyles extends InheritedWidget {
const QuillStyles({
@ -192,19 +193,12 @@ class DefaultStyles {
);
const baseSpacing = Tuple2<double, double>(6, 0);
String fontFamily;
switch (themeData.platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
fontFamily = 'Menlo';
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.windows:
case TargetPlatform.linux:
fontFamily = 'Roboto Mono';
break;
default:
throw UnimplementedError();
if (isAppleOS(themeData.platform)) {
fontFamily = 'Menlo';
} else if (isKeyboardOS(themeData.platform)) {
fontFamily = 'Roboto Mono';
} else {
throw UnimplementedError();
}
final inlineCodeStyle = TextStyle(

@ -398,34 +398,26 @@ class _QuillEditorState extends State<QuillEditor>
Color selectionColor;
Radius? cursorRadius;
switch (theme.platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
textSelectionControls = materialTextSelectionControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionTheme.selectionColor ??
theme.colorScheme.primary.withOpacity(0.40);
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
final cupertinoTheme = CupertinoTheme.of(context);
textSelectionControls = cupertinoTextSelectionControls;
paintCursorAboveText = true;
cursorOpacityAnimates = true;
cursorColor ??=
selectionTheme.cursorColor ?? cupertinoTheme.primaryColor;
selectionColor = selectionTheme.selectionColor ??
cupertinoTheme.primaryColor.withOpacity(0.40);
cursorRadius ??= const Radius.circular(2);
cursorOffset = Offset(
iOSHorizontalOffset / MediaQuery.of(context).devicePixelRatio, 0);
break;
default:
throw UnimplementedError();
if (isKeyboardOS(theme.platform)) {
textSelectionControls = materialTextSelectionControls;
paintCursorAboveText = false;
cursorOpacityAnimates = false;
cursorColor ??= selectionTheme.cursorColor ?? theme.colorScheme.primary;
selectionColor = selectionTheme.selectionColor ??
theme.colorScheme.primary.withOpacity(0.40);
} else if (isAppleOS(theme.platform)) {
final cupertinoTheme = CupertinoTheme.of(context);
textSelectionControls = cupertinoTextSelectionControls;
paintCursorAboveText = true;
cursorOpacityAnimates = true;
cursorColor ??= selectionTheme.cursorColor ?? cupertinoTheme.primaryColor;
selectionColor = selectionTheme.selectionColor ??
cupertinoTheme.primaryColor.withOpacity(0.40);
cursorRadius ??= const Radius.circular(2);
cursorOffset = Offset(
iOSHorizontalOffset / MediaQuery.of(context).devicePixelRatio, 0);
} else {
throw UnimplementedError();
}
final child = RawEditor(
@ -524,26 +516,21 @@ class _QuillEditorSelectionGestureDetectorBuilder
if (!delegate.selectionEnabled) {
return;
}
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
renderEditor!.selectWordsInRange(
details.globalPosition - details.offsetFromOrigin,
details.globalPosition,
SelectionChangedCause.longPress,
);
break;
default:
throw 'Invalid platform';
final _platform = Theme.of(_state.context).platform;
if (isAppleOS(_platform)) {
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
} else if (isKeyboardOS(_platform)) {
renderEditor!.selectWordsInRange(
details.globalPosition - details.offsetFromOrigin,
details.globalPosition,
SelectionChangedCause.longPress,
);
} else {
throw UnimplementedError();
}
}
@ -599,52 +586,40 @@ class _QuillEditorSelectionGestureDetectorBuilder
final positionSelected = _isPositionSelected(details);
if (delegate.selectionEnabled && !positionSelected) {
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
switch (details.kind) {
case PointerDeviceKind.mouse:
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
// Precise devices should place the cursor at a precise position.
// If `Shift` key is pressed then
// extend current selection instead.
if (isShiftClick(details.kind)) {
renderEditor!
..extendSelection(details.globalPosition,
cause: SelectionChangedCause.tap)
..onSelectionCompleted();
} else {
renderEditor!
..selectPosition(cause: SelectionChangedCause.tap)
..onSelectionCompleted();
}
break;
case PointerDeviceKind.touch:
case PointerDeviceKind.unknown:
// On macOS/iOS/iPadOS a touch tap places the cursor at the edge
// of the word.
try {
renderEditor!
..selectWordEdge(SelectionChangedCause.tap)
..onSelectionCompleted();
} finally {
break;
}
}
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
try {
final _platform = Theme.of(_state.context).platform;
if (isAppleOS(_platform)) {
switch (details.kind) {
case PointerDeviceKind.mouse:
case PointerDeviceKind.stylus:
case PointerDeviceKind.invertedStylus:
// Precise devices should place the cursor at a precise position.
// If `Shift` key is pressed then
// extend current selection instead.
if (isShiftClick(details.kind)) {
renderEditor!
..extendSelection(details.globalPosition,
cause: SelectionChangedCause.tap)
..onSelectionCompleted();
} else {
renderEditor!
..selectPosition(cause: SelectionChangedCause.tap)
..onSelectionCompleted();
}
break;
case PointerDeviceKind.touch:
case PointerDeviceKind.unknown:
// On macOS/iOS/iPadOS a touch tap places the cursor at the edge
// of the word.
renderEditor!
..selectPosition(cause: SelectionChangedCause.tap)
..selectWordEdge(SelectionChangedCause.tap)
..onSelectionCompleted();
} finally {
break;
}
}
} else if (isKeyboardOS(_platform)) {
renderEditor!
..selectPosition(cause: SelectionChangedCause.tap)
..onSelectionCompleted();
}
}
_state._requestKeyboard();
@ -661,23 +636,17 @@ class _QuillEditorSelectionGestureDetectorBuilder
}
if (delegate.selectionEnabled) {
switch (Theme.of(_state.context).platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
renderEditor!.selectWord(SelectionChangedCause.longPress);
Feedback.forLongPress(_state.context);
break;
default:
throw 'Invalid platform';
final _platform = Theme.of(_state.context).platform;
if (isAppleOS(_platform)) {
renderEditor!.selectPositionAt(
from: details.globalPosition,
cause: SelectionChangedCause.longPress,
);
} else if (isKeyboardOS(_platform)) {
renderEditor!.selectWord(SelectionChangedCause.longPress);
Feedback.forLongPress(_state.context);
} else {
throw UnimplementedError();
}
}
}

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
@ -16,6 +17,7 @@ import '../models/documents/attribute.dart';
import '../models/documents/document.dart';
import '../models/documents/nodes/block.dart';
import '../models/documents/nodes/line.dart';
import '../utils/platform_helper.dart';
import 'controller.dart';
import 'cursor.dart';
import 'default_styles.dart';
@ -524,10 +526,7 @@ class RawEditorState extends EditorState
_floatingCursorResetController = AnimationController(vsync: this);
_floatingCursorResetController.addListener(onFloatingCursorResetTick);
if (defaultTargetPlatform == TargetPlatform.windows ||
defaultTargetPlatform == TargetPlatform.macOS ||
defaultTargetPlatform == TargetPlatform.linux ||
defaultTargetPlatform == TargetPlatform.fuchsia) {
if (isKeyboardOS()) {
_keyboardVisible = true;
} else {
_keyboardVisibilityController = KeyboardVisibilityController();
@ -852,24 +851,16 @@ class RawEditorState extends EditorState
bringIntoView(textEditingValue.selection.extent);
hideToolbar(false);
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
break;
case TargetPlatform.macOS:
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
// Collapse the selection and hide the toolbar and handles.
userUpdateTextEditingValue(
TextEditingValue(
text: textEditingValue.text,
selection: TextSelection.collapsed(
offset: textEditingValue.selection.end),
),
SelectionChangedCause.toolbar,
);
break;
if (isKeyboardOS() || Platform.isAndroid) {
// Collapse the selection and hide the toolbar and handles.
userUpdateTextEditingValue(
TextEditingValue(
text: textEditingValue.text,
selection:
TextSelection.collapsed(offset: textEditingValue.selection.end),
),
SelectionChangedCause.toolbar,
);
}
}
}

@ -1,7 +1,6 @@
import 'dart:collection';
import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
@ -81,7 +80,7 @@ class _TextLineState extends State<TextLine> {
// Desktop platforms (macos, linux, windows):
// only allow Meta(Control)+Click combinations
if (isDesktop) {
if (isDesktop()) {
return _metaOrControlPressed;
}
// Mobile platforms (ios, android): always allow but we install a
@ -376,7 +375,7 @@ class _TextLineState extends State<TextLine> {
return _linkRecognizers[segment]!;
}
if (isDesktop || widget.readOnly) {
if (isDesktop() || widget.readOnly) {
_linkRecognizers[segment] = TapGestureRecognizer()
..onTap = () => _tapNodeLink(segment);
} else {
@ -854,19 +853,12 @@ class RenderEditableTextLine extends RenderEditableBox {
/// of the cursor for iOS is approximate and obtained through an eyeball
/// comparison.
void _computeCaretPrototype() {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
_caretPrototype = Rect.fromLTWH(0, 0, cursorWidth, cursorHeight + 2);
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
_caretPrototype = Rect.fromLTWH(0, 2, cursorWidth, cursorHeight - 4.0);
break;
default:
throw 'Invalid platform';
if (isAppleOS()) {
_caretPrototype = Rect.fromLTWH(0, 0, cursorWidth, cursorHeight + 2);
} else if (isKeyboardOS()) {
_caretPrototype = Rect.fromLTWH(0, 2, cursorWidth, cursorHeight - 4.0);
} else {
throw UnimplementedError();
}
}

Loading…
Cancel
Save