Skip to content

Commit

Permalink
Merge pull request #167 from LucasXu0/text_color_icon
Browse files Browse the repository at this point in the history
fix: toolbar item size and scroll widget layout
  • Loading branch information
LucasXu0 authored Jun 5, 2023
2 parents 2510f6b + 0a2b807 commit 94a5155
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 159 deletions.
2 changes: 1 addition & 1 deletion example/lib/pages/simple_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SimpleEditor extends StatelessWidget {
);
editorState.logConfiguration
..handler = debugPrint
..level = LogLevel.off;
..level = LogLevel.all;
onEditorStateChange(editorState);
final scrollController = ScrollController();
if (PlatformExtension.isDesktopOrWeb) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,20 @@ Node imageNode({
}

class ImageBlockComponentBuilder extends BlockComponentBuilder {
ImageBlockComponentBuilder();
ImageBlockComponentBuilder({
this.configuration = const BlockComponentConfiguration(),
});

@override
final BlockComponentConfiguration configuration;

@override
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
final node = blockComponentContext.node;
return ImageBlockComponentWidget(
node: node,
showActions: showActions(node),
configuration: configuration,
actionBuilder: (context, state) => actionBuilder(
blockComponentContext,
state,
Expand Down Expand Up @@ -97,7 +103,7 @@ class _ImageBlockComponentWidgetState extends State<ImageBlockComponentWidget> {
final align = attributes[ImageBlockKeys.align] ?? 'center';
final width = attributes[ImageBlockKeys.width]?.toDouble();

return ImageNodeWidget(
Widget child = ImageNodeWidget(
key: node.key,
node: node,
src: src,
Expand All @@ -107,11 +113,21 @@ class _ImageBlockComponentWidgetState extends State<ImageBlockComponentWidget> {
onResize: (width) {
final transaction = editorState.transaction
..updateNode(node, {
'width': width,
ImageBlockKeys.width: width,
});
editorState.apply(transaction);
},
);

if (widget.showActions && widget.actionBuilder != null) {
child = BlockComponentActionWrapper(
node: node,
actionBuilder: widget.actionBuilder!,
child: child,
);
}

return child;
}

Alignment _textToAlignment(String text) {
Expand All @@ -123,110 +139,3 @@ class _ImageBlockComponentWidgetState extends State<ImageBlockComponentWidget> {
return Alignment.center;
}
}

// class ImageNodeBuilder extends NodeWidgetBuilder<Node>
// with ActionProvider<Node> {
// @override
// Widget build(NodeWidgetContext<Node> context) {
// final src = context.node.attributes['image_src'];
// final align = context.node.attributes['align'];
// double? width;
// if (context.node.attributes.containsKey('width')) {
// width = context.node.attributes['width'].toDouble();
// }
// return ImageNodeWidget(
// key: context.node.key,
// node: context.node,
// src: src,
// width: width,
// editable: context.editorState.editable,
// alignment: _textToAlignment(align),
// onResize: (width) {
// final transaction = context.editorState.transaction
// ..updateNode(context.node, {
// 'width': width,
// });
// context.editorState.apply(transaction);
// },
// );
// }

// @override
// NodeValidator<Node> get nodeValidator => ((node) {
// return node.type == 'image' &&
// node.attributes.containsKey('image_src') &&
// node.attributes.containsKey('align');
// });

// @override
// List<ActionMenuItem> actions(NodeWidgetContext<Node> context) {
// return [
// ActionMenuItem.svg(
// name: 'image_toolbar/align_left',
// selected: () {
// final align = context.node.attributes['align'];
// return _textToAlignment(align) == Alignment.centerLeft;
// },
// onPressed: () => _onAlign(context, Alignment.centerLeft),
// ),
// ActionMenuItem.svg(
// name: 'image_toolbar/align_center',
// selected: () {
// final align = context.node.attributes['align'];
// return _textToAlignment(align) == Alignment.center;
// },
// onPressed: () => _onAlign(context, Alignment.center),
// ),
// ActionMenuItem.svg(
// name: 'image_toolbar/align_right',
// selected: () {
// final align = context.node.attributes['align'];
// return _textToAlignment(align) == Alignment.centerRight;
// },
// onPressed: () => _onAlign(context, Alignment.centerRight),
// ),
// ActionMenuItem.separator(),
// ActionMenuItem.svg(
// name: 'image_toolbar/copy',
// onPressed: () {
// final src = context.node.attributes['image_src'];
// AppFlowyClipboard.setData(text: src);
// },
// ),
// ActionMenuItem.svg(
// name: 'image_toolbar/delete',
// onPressed: () {
// final transaction = context.editorState.transaction
// ..deleteNode(context.node);
// context.editorState.apply(transaction);
// },
// ),
// ];
// }

// Alignment _textToAlignment(String text) {
// if (text == 'left') {
// return Alignment.centerLeft;
// } else if (text == 'right') {
// return Alignment.centerRight;
// }
// return Alignment.center;
// }

// String _alignmentToText(Alignment alignment) {
// if (alignment == Alignment.centerLeft) {
// return 'left';
// } else if (alignment == Alignment.centerRight) {
// return 'right';
// }
// return 'center';
// }

// void _onAlign(NodeWidgetContext context, Alignment alignment) {
// final transaction = context.editorState.transaction
// ..updateNode(context.node, {
// 'align': _alignmentToText(alignment),
// });
// context.editorState.apply(transaction);
// }
// }
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ void showImageMenu(
) {
menuService.dismiss();

final topLeft = menuService.topLeft;
final (left, top, bottom) = menuService.getPosition(
MediaQuery.of(container.context).size.height * 2.0 / 3.0,
);
final imageMenuEntry = FullScreenOverlayEntry(
top: topLeft.dy,
left: topLeft.dx,
left: left,
top: top,
bottom: bottom,
builder: (context) => UploadImageMenu(
backgroundColor: Colors.white, // TODO: customize the color
backgroundColor: menuService.style.selectionMenuBackgroundColor,
headerColor: menuService.style.selectionMenuItemTextColor,
width: MediaQuery.of(context).size.width * 0.5,
onSubmitted: editorState.insertImageNode,
onUpload: editorState.insertImageNode,
Expand All @@ -26,12 +30,14 @@ class UploadImageMenu extends StatefulWidget {
const UploadImageMenu({
Key? key,
this.backgroundColor = Colors.white,
this.headerColor = Colors.black,
this.width = 300,
required this.onSubmitted,
required this.onUpload,
}) : super(key: key);

final Color backgroundColor;
final Color headerColor;
final double width;
final void Function(String text) onSubmitted;
final void Function(String text) onUpload;
Expand Down Expand Up @@ -86,12 +92,12 @@ class _UploadImageMenuState extends State<UploadImageMenu> {
}

Widget _buildHeader(BuildContext context) {
return const Text(
return Text(
'URL Image',
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14.0,
color: Colors.black,
color: widget.headerColor,
fontWeight: FontWeight.w500,
),
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

const double blockComponentActionContainerWidth = 50;

class BlockComponentActionContainer extends StatelessWidget {
const BlockComponentActionContainer({
super.key,
Expand All @@ -17,7 +19,7 @@ class BlockComponentActionContainer extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
alignment: Alignment.centerRight,
width: 50,
width: blockComponentActionContainerWidth,
height: 25, // TODO: magic number, change it to the height of the block
color: Colors
.transparent, // have to set the color to transparent to make the MouseRegion work
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ class _AutoScrollableWidgetState extends State<AutoScrollableWidget> {

@override
Widget build(BuildContext context) {
return SingleChildScrollView(
controller: widget.scrollController,
child: Builder(
builder: (context) {
_scrollableState = Scrollable.of(context);
_initAutoScroller();
return widget.builder(context, _autoScroller);
},
return LayoutBuilder(
builder: (context, viewportConstraints) => SingleChildScrollView(
controller: widget.scrollController,
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: viewportConstraints.maxHeight,
),
child: Builder(
builder: (context) {
_scrollableState = Scrollable.of(context);
_initAutoScroller();
return widget.builder(context, _autoScroller);
},
),
),
),
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/editor/editor_component/service/renderer/block_component_action.dart';
import 'package:appflowy_editor/src/flutter/overlay.dart';
import 'package:appflowy_editor/src/service/context_menu/built_in_context_menu_item.dart';
import 'package:appflowy_editor/src/service/context_menu/context_menu.dart';
Expand Down Expand Up @@ -356,7 +357,13 @@ class _DesktopSelectionServiceWidgetState
currentSelectedNodes = nodes;

final node = nodes.first;
final rect = Offset.zero & node.rect.size;
var rect = Offset.zero & node.rect.size;

final builder = editorState.renderer.blockComponentBuilder(node.type);
if (builder != null && builder.showActions(node)) {
rect = rect.translate(blockComponentActionContainerWidth, 0);
}

final overlay = OverlayEntry(
builder: (context) => SelectionWidget(
color: widget.selectionColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ CommandShortcutEventHandler _copyCommandHandler = (editorState) {

AppFlowyClipboard.setData(
text: text,
html: html,
html: html.isEmpty ? null : html,
);

return KeyEventResult.handled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ CommandShortcutEventHandler _pasteCommandHandler = (editorState) {
final data = await AppFlowyClipboard.getData();
final text = data.text;
final html = data.html;
if (html != null) {
if (html != null && html.isNotEmpty) {
final nodes = htmlToDocument(html).root.children;
final transaction = editorState.transaction
..insertNodes(selection!.end.path, nodes);
await editorState.apply(transaction);
} else if (text != null) {
} else if (text != null && text.isNotEmpty) {
handlePastePlainText(editorState, data.text!);
}
}();
Expand Down
2 changes: 1 addition & 1 deletion lib/src/editor/toolbar/items/color/color_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void showColorMenu(

overlay = FullScreenOverlayEntry(
top: rect.bottom + 5,
left: rect.left + 10,
left: rect.left,
builder: (context) {
return ColorPicker(
isTextColor: isTextColor,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

final highlightColorItem = ToolbarItem(
id: 'editor.highlightColor',
Expand All @@ -16,6 +17,7 @@ final highlightColorItem = ToolbarItem(
});
return IconItemWidget(
iconName: 'toolbar/highlight_color',
iconSize: const Size.square(14),
isHighlight: isHighlight,
tooltip: AppFlowyEditorLocalizations.current.highlightColor,
onPressed: () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

final textColorItem = ToolbarItem(
id: 'editor.textColor',
Expand All @@ -16,6 +17,7 @@ final textColorItem = ToolbarItem(
return IconItemWidget(
iconName: 'toolbar/text_color',
isHighlight: isHighlight,
iconSize: const Size.square(14),
tooltip: AppFlowyEditorLocalizations.current.textColor,
onPressed: () {
showColorMenu(
Expand Down
12 changes: 7 additions & 5 deletions lib/src/editor/toolbar/items/link/link_toolbar_item.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ final linkItem = ToolbarItem(
final nodes = editorState.getNodesInSelection(selection);
final isHref = nodes.allSatisfyInSelection(selection, (delta) {
return delta.everyAttributes(
(attributes) => attributes['href'] != null,
(attributes) => attributes[FlowyRichTextKeys.href] != null,
);
});

Expand All @@ -39,9 +39,11 @@ void showLinkMenu(

// get node, index and length for formatting text when the link is removed
final node = editorState.getNodeAtPath(selection.end.path);
final index =
selection.isBackward ? selection.start.offset : selection.end.offset;
final length = (selection.start.offset - selection.end.offset).abs();
if (node == null) {
return;
}
final index = selection.normalized.startIndex;
final length = selection.length;

// get link address if the selection is already a link
String? linkText;
Expand Down Expand Up @@ -82,7 +84,7 @@ void showLinkMenu(
onRemoveLink: () {
final transaction = editorState.transaction
..formatText(
node!,
node,
index,
length,
{BuiltInAttributeKey.href: null},
Expand Down
Loading

0 comments on commit 94a5155

Please sign in to comment.