feat: support scaling the svg (#722)
* feat: support scaling the svg * fix: flutter test
This commit is contained in:
parent
f38328d9e5
commit
1715ed4549
10 changed files with 53 additions and 16 deletions
1
example/devtools_options.yaml
Normal file
1
example/devtools_options.yaml
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
extensions:
|
||||||
|
|
@ -3,20 +3,18 @@ import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
import 'package:example/pages/customize_theme_for_editor.dart';
|
import 'package:example/pages/customize_theme_for_editor.dart';
|
||||||
import 'package:example/pages/editor.dart';
|
import 'package:example/pages/editor.dart';
|
||||||
import 'package:example/pages/editor_list.dart';
|
import 'package:example/pages/editor_list.dart';
|
||||||
import 'package:example/pages/focus_example_for_editor.dart';
|
import 'package:example/pages/focus_example_for_editor.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:universal_html/html.dart' as html;
|
import 'package:universal_html/html.dart' as html;
|
||||||
|
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
|
||||||
|
|
||||||
enum ExportFileType {
|
enum ExportFileType {
|
||||||
documentJson,
|
documentJson,
|
||||||
markdown,
|
markdown,
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ class _MobileEditorState extends State<MobileEditor> {
|
||||||
// showcase 1: customize the editor style.
|
// showcase 1: customize the editor style.
|
||||||
EditorStyle _buildMobileEditorStyle() {
|
EditorStyle _buildMobileEditorStyle() {
|
||||||
return EditorStyle.mobile(
|
return EditorStyle.mobile(
|
||||||
|
textScaleFactor: 1.0,
|
||||||
cursorColor: const Color.fromARGB(255, 134, 46, 247),
|
cursorColor: const Color.fromARGB(255, 134, 46, 247),
|
||||||
dragHandleColor: const Color.fromARGB(255, 134, 46, 247),
|
dragHandleColor: const Color.fromARGB(255, 134, 46, 247),
|
||||||
selectionColor: const Color.fromARGB(50, 134, 46, 247),
|
selectionColor: const Color.fromARGB(50, 134, 46, 247),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class BulletedListBlockKeys {
|
class BulletedListBlockKeys {
|
||||||
const BulletedListBlockKeys._();
|
const BulletedListBlockKeys._();
|
||||||
|
|
@ -218,14 +219,17 @@ class _BulletedListIcon extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final textScaleFactor =
|
||||||
|
context.read<EditorState>().editorStyle.textScaleFactor;
|
||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
constraints:
|
||||||
|
const BoxConstraints(minWidth: 26, minHeight: 22) * textScaleFactor,
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
icon,
|
icon,
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
textScaler: const TextScaler.linear(0.5),
|
textScaler: TextScaler.linear(0.5 * textScaleFactor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -209,11 +209,14 @@ class _NumberedListIcon extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final editorState = context.read<EditorState>();
|
final editorState = context.read<EditorState>();
|
||||||
final text = editorState.editorStyle.textStyleConfiguration.text;
|
final text = editorState.editorStyle.textStyleConfiguration.text;
|
||||||
|
final textScaleFactor = editorState.editorStyle.textScaleFactor;
|
||||||
return Container(
|
return Container(
|
||||||
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
constraints:
|
||||||
|
const BoxConstraints(minWidth: 26, minHeight: 22) * textScaleFactor,
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text.rich(
|
child: Text.rich(
|
||||||
|
textScaler: TextScaler.linear(textScaleFactor),
|
||||||
textHeightBehavior: const TextHeightBehavior(
|
textHeightBehavior: const TextHeightBehavior(
|
||||||
applyHeightToFirstAscent: false,
|
applyHeightToFirstAscent: false,
|
||||||
applyHeightToLastDescent: false,
|
applyHeightToLastDescent: false,
|
||||||
|
|
|
||||||
|
|
@ -187,12 +187,15 @@ class _QuoteIcon extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final textScaleFactor =
|
||||||
|
context.read<EditorState>().editorStyle.textScaleFactor;
|
||||||
return Container(
|
return Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
constraints:
|
||||||
|
const BoxConstraints(minWidth: 26, minHeight: 22) * textScaleFactor,
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: 4,
|
width: 4 * textScaleFactor,
|
||||||
color: '#00BCF0'.tryToColor(),
|
color: '#00BCF0'.tryToColor(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,8 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
|
||||||
? widget.placeholderTextSpanDecorator!(textSpan)
|
? widget.placeholderTextSpanDecorator!(textSpan)
|
||||||
: textSpan,
|
: textSpan,
|
||||||
textDirection: textDirection(),
|
textDirection: textDirection(),
|
||||||
|
textScaler:
|
||||||
|
TextScaler.linear(widget.editorState.editorStyle.textScaleFactor),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -301,6 +303,8 @@ class _AppFlowyRichTextState extends State<AppFlowyRichText>
|
||||||
? widget.textSpanDecorator!(textSpan)
|
? widget.textSpanDecorator!(textSpan)
|
||||||
: textSpan,
|
: textSpan,
|
||||||
textDirection: textDirection(),
|
textDirection: textDirection(),
|
||||||
|
textScaler:
|
||||||
|
TextScaler.linear(widget.editorState.editorStyle.textScaleFactor),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
import 'package:appflowy_editor/src/editor/block_component/base_component/block_icon_builder.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class TodoListBlockKeys {
|
class TodoListBlockKeys {
|
||||||
const TodoListBlockKeys._();
|
const TodoListBlockKeys._();
|
||||||
|
|
@ -269,13 +270,16 @@ class _TodoListIcon extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final textScaleFactor =
|
||||||
|
context.read<EditorState>().editorStyle.textScaleFactor;
|
||||||
return MouseRegion(
|
return MouseRegion(
|
||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: const BoxConstraints(minWidth: 26, minHeight: 22),
|
constraints: const BoxConstraints(minWidth: 26, minHeight: 22) *
|
||||||
|
textScaleFactor,
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
padding: const EdgeInsets.only(right: 4.0),
|
||||||
child: EditorSvg(
|
child: EditorSvg(
|
||||||
width: 22,
|
width: 22,
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class EditorStyle {
|
||||||
this.cursorWidth = 2.0,
|
this.cursorWidth = 2.0,
|
||||||
this.defaultTextDirection,
|
this.defaultTextDirection,
|
||||||
this.enableHapticFeedbackOnAndroid = true,
|
this.enableHapticFeedbackOnAndroid = true,
|
||||||
|
this.textScaleFactor = 1.0,
|
||||||
});
|
});
|
||||||
|
|
||||||
// The padding of the editor.
|
// The padding of the editor.
|
||||||
|
|
@ -70,6 +71,8 @@ class EditorStyle {
|
||||||
// enable haptic feedback when updating selection by dragging the drag handler
|
// enable haptic feedback when updating selection by dragging the drag handler
|
||||||
final bool enableHapticFeedbackOnAndroid;
|
final bool enableHapticFeedbackOnAndroid;
|
||||||
|
|
||||||
|
final double textScaleFactor;
|
||||||
|
|
||||||
const EditorStyle.desktop({
|
const EditorStyle.desktop({
|
||||||
EdgeInsets? padding,
|
EdgeInsets? padding,
|
||||||
Color? cursorColor,
|
Color? cursorColor,
|
||||||
|
|
@ -78,6 +81,7 @@ class EditorStyle {
|
||||||
TextSpanDecoratorForAttribute? textSpanDecorator,
|
TextSpanDecoratorForAttribute? textSpanDecorator,
|
||||||
this.defaultTextDirection,
|
this.defaultTextDirection,
|
||||||
this.cursorWidth = 2.0,
|
this.cursorWidth = 2.0,
|
||||||
|
this.textScaleFactor = 1.0,
|
||||||
}) : padding = padding ?? const EdgeInsets.symmetric(horizontal: 100),
|
}) : padding = padding ?? const EdgeInsets.symmetric(horizontal: 100),
|
||||||
cursorColor = cursorColor ?? const Color(0xFF00BCF0),
|
cursorColor = cursorColor ?? const Color(0xFF00BCF0),
|
||||||
selectionColor =
|
selectionColor =
|
||||||
|
|
@ -107,6 +111,7 @@ class EditorStyle {
|
||||||
this.mobileDragHandleWidth = 2.0,
|
this.mobileDragHandleWidth = 2.0,
|
||||||
this.cursorWidth = 2.0,
|
this.cursorWidth = 2.0,
|
||||||
this.enableHapticFeedbackOnAndroid = true,
|
this.enableHapticFeedbackOnAndroid = true,
|
||||||
|
this.textScaleFactor = 1.0,
|
||||||
}) : padding = padding ?? const EdgeInsets.symmetric(horizontal: 20),
|
}) : padding = padding ?? const EdgeInsets.symmetric(horizontal: 20),
|
||||||
cursorColor = cursorColor ?? const Color(0xFF00BCF0),
|
cursorColor = cursorColor ?? const Color(0xFF00BCF0),
|
||||||
dragHandleColor = dragHandleColor ?? const Color(0xFF00BCF0),
|
dragHandleColor = dragHandleColor ?? const Color(0xFF00BCF0),
|
||||||
|
|
@ -132,6 +137,7 @@ class EditorStyle {
|
||||||
double? mobileDragHandleWidth,
|
double? mobileDragHandleWidth,
|
||||||
bool? enableHapticFeedbackOnAndroid,
|
bool? enableHapticFeedbackOnAndroid,
|
||||||
double? cursorWidth,
|
double? cursorWidth,
|
||||||
|
double? textScaleFactor,
|
||||||
}) {
|
}) {
|
||||||
return EditorStyle(
|
return EditorStyle(
|
||||||
padding: padding ?? this.padding,
|
padding: padding ?? this.padding,
|
||||||
|
|
@ -150,6 +156,7 @@ class EditorStyle {
|
||||||
enableHapticFeedbackOnAndroid:
|
enableHapticFeedbackOnAndroid:
|
||||||
enableHapticFeedbackOnAndroid ?? this.enableHapticFeedbackOnAndroid,
|
enableHapticFeedbackOnAndroid ?? this.enableHapticFeedbackOnAndroid,
|
||||||
cursorWidth: cursorWidth ?? this.cursorWidth,
|
cursorWidth: cursorWidth ?? this.cursorWidth,
|
||||||
|
textScaleFactor: textScaleFactor ?? this.textScaleFactor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class EditorSvg extends StatelessWidget {
|
class EditorSvg extends StatelessWidget {
|
||||||
const EditorSvg({
|
const EditorSvg({
|
||||||
|
|
@ -24,13 +26,23 @@ class EditorSvg extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final scaleFactor =
|
||||||
|
context.read<EditorState?>()?.editorStyle.textScaleFactor ?? 1.0;
|
||||||
|
final height = (this.height ?? _defaultHeight) * scaleFactor;
|
||||||
|
final width = (this.width ?? _defaultWidth) * scaleFactor;
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: padding ?? const EdgeInsets.all(0),
|
padding: padding ?? const EdgeInsets.all(0),
|
||||||
child: _buildSvg(),
|
child: _buildSvg(
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSvg() {
|
Widget _buildSvg(
|
||||||
|
double height,
|
||||||
|
double width,
|
||||||
|
) {
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
return SvgPicture.asset(
|
return SvgPicture.asset(
|
||||||
'assets/images/$name.svg',
|
'assets/images/$name.svg',
|
||||||
|
|
@ -46,8 +58,8 @@ class EditorSvg extends StatelessWidget {
|
||||||
'<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><text x="30" y="150" fill="black" font-size="160">$number.</text></svg>';
|
'<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"><text x="30" y="150" fill="black" font-size="160">$number.</text></svg>';
|
||||||
return SvgPicture.string(
|
return SvgPicture.string(
|
||||||
numberText,
|
numberText,
|
||||||
width: width ?? _defaultWidth,
|
width: width,
|
||||||
height: height ?? _defaultHeight,
|
height: height,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Container();
|
return Container();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue