add readOnly to emdedBuilder

pull/307/head
li3317 4 years ago
parent 887a1f4ded
commit bb38db5ed0
  1. 2
      example/lib/universal_ui/universal_ui.dart
  2. 3
      lib/src/widgets/delegate.dart
  3. 5
      lib/src/widgets/editor.dart
  4. 35
      lib/src/widgets/raw_editor.dart
  5. 12
      lib/src/widgets/simple_viewer.dart
  6. 3
      lib/src/widgets/text_block.dart
  7. 4
      lib/src/widgets/text_line.dart
  8. 4
      lib/src/widgets/video_app.dart

@ -25,7 +25,7 @@ class UniversalUI {
var ui = UniversalUI(); var ui = UniversalUI();
Widget defaultEmbedBuilderWeb(BuildContext context, Embed node) { Widget defaultEmbedBuilderWeb(BuildContext context, Embed node, bool readOnly) {
switch (node.value.type) { switch (node.value.type) {
case 'image': case 'image':
final String imageUrl = node.value.data; final String imageUrl = node.value.data;

@ -7,7 +7,8 @@ import '../models/documents/nodes/leaf.dart';
import 'editor.dart'; import 'editor.dart';
import 'text_selection.dart'; import 'text_selection.dart';
typedef EmbedBuilder = Widget Function(BuildContext context, Embed node); typedef EmbedBuilder = Widget Function(
BuildContext context, Embed node, bool readOnly);
abstract class EditorTextSelectionGestureDetectorBuilderDelegate { abstract class EditorTextSelectionGestureDetectorBuilderDelegate {
GlobalKey<EditorState> getEditableTextKey(); GlobalKey<EditorState> getEditableTextKey();

@ -96,7 +96,8 @@ String _standardizeImageUrl(String url) {
return url; return url;
} }
Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { Widget _defaultEmbedBuilder(
BuildContext context, leaf.Embed node, bool readOnly) {
assert(!kIsWeb, 'Please provide EmbedBuilder for Web'); assert(!kIsWeb, 'Please provide EmbedBuilder for Web');
switch (node.value.type) { switch (node.value.type) {
case 'image': case 'image':
@ -108,7 +109,7 @@ Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) {
: Image.file(io.File(imageUrl)); : Image.file(io.File(imageUrl));
case 'video': case 'video':
final videoUrl = node.value.data; final videoUrl = node.value.data;
return VideoApp(videoUrl: videoUrl, context: context); return VideoApp(videoUrl: videoUrl, context: context, readOnly: readOnly);
default: default:
throw UnimplementedError( throw UnimplementedError(
'Embeddable type "${node.value.type}" is not supported by default ' 'Embeddable type "${node.value.type}" is not supported by default '

@ -229,23 +229,23 @@ class RawEditorState extends EditorState
} else if (node is Block) { } else if (node is Block) {
final attrs = node.style.attributes; final attrs = node.style.attributes;
final editableTextBlock = EditableTextBlock( final editableTextBlock = EditableTextBlock(
node, node,
_textDirection, _textDirection,
widget.scrollBottomInset, widget.scrollBottomInset,
_getVerticalSpacingForBlock(node, _styles), _getVerticalSpacingForBlock(node, _styles),
widget.controller.selection, widget.controller.selection,
widget.selectionColor, widget.selectionColor,
_styles, _styles,
widget.enableInteractiveSelection, widget.enableInteractiveSelection,
_hasFocus, _hasFocus,
attrs.containsKey(Attribute.codeBlock.key) attrs.containsKey(Attribute.codeBlock.key)
? const EdgeInsets.all(16) ? const EdgeInsets.all(16)
: null, : null,
widget.embedBuilder, widget.embedBuilder,
_cursorCont, _cursorCont,
indentLevelCounts, indentLevelCounts,
_handleCheckboxTap, _handleCheckboxTap,
); widget.readOnly);
result.add(editableTextBlock); result.add(editableTextBlock);
} else { } else {
throw StateError('Unreachable.'); throw StateError('Unreachable.');
@ -261,6 +261,7 @@ class RawEditorState extends EditorState
textDirection: _textDirection, textDirection: _textDirection,
embedBuilder: widget.embedBuilder, embedBuilder: widget.embedBuilder,
styles: _styles!, styles: _styles!,
readOnly: widget.readOnly,
); );
final editableTextLine = EditableTextLine( final editableTextLine = EditableTextLine(
node, node,

@ -25,6 +25,7 @@ import 'video_app.dart';
class QuillSimpleViewer extends StatefulWidget { class QuillSimpleViewer extends StatefulWidget {
const QuillSimpleViewer({ const QuillSimpleViewer({
required this.controller, required this.controller,
required this.readOnly,
this.customStyles, this.customStyles,
this.truncate = false, this.truncate = false,
this.truncateScale, this.truncateScale,
@ -52,6 +53,7 @@ class QuillSimpleViewer extends StatefulWidget {
final double scrollBottomInset; final double scrollBottomInset;
final EdgeInsetsGeometry padding; final EdgeInsetsGeometry padding;
final EmbedBuilder? embedBuilder; final EmbedBuilder? embedBuilder;
final bool readOnly;
@override @override
_QuillSimpleViewerState createState() => _QuillSimpleViewerState(); _QuillSimpleViewerState createState() => _QuillSimpleViewerState();
@ -98,7 +100,8 @@ class _QuillSimpleViewerState extends State<QuillSimpleViewer>
EmbedBuilder get embedBuilder => widget.embedBuilder ?? _defaultEmbedBuilder; EmbedBuilder get embedBuilder => widget.embedBuilder ?? _defaultEmbedBuilder;
Widget _defaultEmbedBuilder(BuildContext context, leaf.Embed node) { Widget _defaultEmbedBuilder(
BuildContext context, leaf.Embed node, bool readOnly) {
assert(!kIsWeb, 'Please provide EmbedBuilder for Web'); assert(!kIsWeb, 'Please provide EmbedBuilder for Web');
switch (node.value.type) { switch (node.value.type) {
case 'image': case 'image':
@ -110,7 +113,8 @@ class _QuillSimpleViewerState extends State<QuillSimpleViewer>
: Image.file(io.File(imageUrl)); : Image.file(io.File(imageUrl));
case 'video': case 'video':
final videoUrl = node.value.data; final videoUrl = node.value.data;
return VideoApp(videoUrl: videoUrl, context: context); return VideoApp(
videoUrl: videoUrl, context: context, readOnly: readOnly);
default: default:
throw UnimplementedError( throw UnimplementedError(
'Embeddable type "${node.value.type}" is not supported by default ' 'Embeddable type "${node.value.type}" is not supported by default '
@ -211,7 +215,8 @@ class _QuillSimpleViewerState extends State<QuillSimpleViewer>
embedBuilder, embedBuilder,
_cursorCont, _cursorCont,
indentLevelCounts, indentLevelCounts,
_handleCheckboxTap); _handleCheckboxTap,
widget.readOnly);
result.add(editableTextBlock); result.add(editableTextBlock);
} else { } else {
throw StateError('Unreachable.'); throw StateError('Unreachable.');
@ -238,6 +243,7 @@ class _QuillSimpleViewerState extends State<QuillSimpleViewer>
textDirection: _textDirection, textDirection: _textDirection,
embedBuilder: embedBuilder, embedBuilder: embedBuilder,
styles: _styles, styles: _styles,
readOnly: widget.readOnly,
); );
final editableTextLine = EditableTextLine( final editableTextLine = EditableTextLine(
node, node,

@ -62,6 +62,7 @@ class EditableTextBlock extends StatelessWidget {
this.cursorCont, this.cursorCont,
this.indentLevelCounts, this.indentLevelCounts,
this.onCheckboxTap, this.onCheckboxTap,
this.readOnly,
); );
final Block block; final Block block;
@ -78,6 +79,7 @@ class EditableTextBlock extends StatelessWidget {
final CursorCont cursorCont; final CursorCont cursorCont;
final Map<int, int> indentLevelCounts; final Map<int, int> indentLevelCounts;
final Function(int, bool) onCheckboxTap; final Function(int, bool) onCheckboxTap;
final bool readOnly;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -122,6 +124,7 @@ class EditableTextBlock extends StatelessWidget {
textDirection: textDirection, textDirection: textDirection,
embedBuilder: embedBuilder, embedBuilder: embedBuilder,
styles: styles!, styles: styles!,
readOnly: readOnly,
), ),
_getIndentWidth(), _getIndentWidth(),
_getSpacingForLine(line, index, count, defaultStyles), _getSpacingForLine(line, index, count, defaultStyles),

@ -24,6 +24,7 @@ class TextLine extends StatelessWidget {
required this.line, required this.line,
required this.embedBuilder, required this.embedBuilder,
required this.styles, required this.styles,
required this.readOnly,
this.textDirection, this.textDirection,
Key? key, Key? key,
}) : super(key: key); }) : super(key: key);
@ -32,6 +33,7 @@ class TextLine extends StatelessWidget {
final TextDirection? textDirection; final TextDirection? textDirection;
final EmbedBuilder embedBuilder; final EmbedBuilder embedBuilder;
final DefaultStyles styles; final DefaultStyles styles;
final bool readOnly;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -43,7 +45,7 @@ class TextLine extends StatelessWidget {
final childCount = line.childCount; final childCount = line.childCount;
if (line.hasEmbed || (childCount > 1 && line.children.first is Embed)) { if (line.hasEmbed || (childCount > 1 && line.children.first is Embed)) {
final embed = line.children.first as Embed; final embed = line.children.first as Embed;
return EmbedProxy(embedBuilder(context, embed)); return EmbedProxy(embedBuilder(context, embed, readOnly));
} }
final textSpan = _buildTextSpan(context); final textSpan = _buildTextSpan(context);

@ -8,10 +8,12 @@ import '../../flutter_quill.dart';
/// Widget for playing back video /// Widget for playing back video
/// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player /// Refer to https://github.com/flutter/plugins/tree/master/packages/video_player/video_player
class VideoApp extends StatefulWidget { class VideoApp extends StatefulWidget {
const VideoApp({required this.videoUrl, required this.context}); const VideoApp(
{required this.videoUrl, required this.context, required this.readOnly});
final String videoUrl; final String videoUrl;
final BuildContext context; final BuildContext context;
final bool readOnly;
@override @override
_VideoAppState createState() => _VideoAppState(); _VideoAppState createState() => _VideoAppState();

Loading…
Cancel
Save