mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-08-04 14:57:27 +00:00
feat: make the columns block same width width the editor (#7493)
* feat: make the columns block same width width the editor * chore: turn off column debug mode * feat: add block selection container in outline block * feat: use ratio instead of width in simple columns * fix: document rules * fix: turn off debug mode * fix: update the existing columns block data
This commit is contained in:
parent
7b32a92290
commit
c81f87dcdc
@ -104,6 +104,28 @@ class DocumentRules {
|
||||
} else {
|
||||
// otherwise, delete the column
|
||||
deleteColumnsTransaction.deleteNode(column);
|
||||
|
||||
final deletedColumnRatio =
|
||||
column.attributes[SimpleColumnBlockKeys.ratio];
|
||||
if (deletedColumnRatio != null) {
|
||||
// update the ratio of the columns
|
||||
final columnsNode = column.columnsParent;
|
||||
if (columnsNode != null) {
|
||||
final length = columnsNode.children.length;
|
||||
for (final columnNode in columnsNode.children) {
|
||||
final ratio =
|
||||
columnNode.attributes[SimpleColumnBlockKeys.ratio] ??
|
||||
1.0 / length;
|
||||
if (ratio != null) {
|
||||
deleteColumnsTransaction.updateNode(columnNode, {
|
||||
...columnNode.attributes,
|
||||
SimpleColumnBlockKeys.ratio:
|
||||
ratio + deletedColumnRatio / (length - 1),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class _DraggableOptionButtonState extends State<DraggableOptionButton> {
|
||||
interceptor: (context, targetNode) {
|
||||
// if the cursor node is in a columns block or a column block,
|
||||
// we will return the node's parent instead to support dragging a node to the inside of a columns block or a column block.
|
||||
final parentColumnNode = targetNode.parentColumn;
|
||||
final parentColumnNode = targetNode.columnParent;
|
||||
if (parentColumnNode != null) {
|
||||
final position = getDragAreaPosition(
|
||||
context,
|
||||
@ -147,7 +147,7 @@ class _DraggableOptionButtonState extends State<DraggableOptionButton> {
|
||||
interceptor: (context, targetNode) {
|
||||
// if the cursor node is in a columns block or a column block,
|
||||
// we will return the node's parent instead to support dragging a node to the inside of a columns block or a column block.
|
||||
final parentColumnNode = targetNode.parentColumn;
|
||||
final parentColumnNode = targetNode.columnParent;
|
||||
if (parentColumnNode != null) {
|
||||
final position = getDragAreaPosition(
|
||||
context,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/columns/simple_columns_block_constant.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart'
|
||||
@ -60,38 +59,37 @@ Future<void> dragToMoveNode(
|
||||
// 1. if the targetNode is a column block, it means we should create a column block to contain the node and insert the column node to the target node's parent
|
||||
// 2. if the targetNode is not a column block, it means we should create a columns block to contain the target node and the drag node
|
||||
final transaction = editorState.transaction;
|
||||
final targetNodeParent = targetNode.parentColumnsBlock;
|
||||
final targetNodeParent = targetNode.columnsParent;
|
||||
|
||||
if (targetNodeParent != null) {
|
||||
final length = targetNodeParent.children.length;
|
||||
final ratios = targetNodeParent.children
|
||||
.map(
|
||||
(e) =>
|
||||
e.attributes[SimpleColumnBlockKeys.ratio]?.toDouble() ??
|
||||
1.0 / length,
|
||||
)
|
||||
.map((e) => e * length / (length + 1))
|
||||
.toList();
|
||||
|
||||
final columnNode = simpleColumnNode(
|
||||
children: [node.deepCopy()],
|
||||
width: (node.rect.width * 1 / (length + 1)).clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
ratio: 1.0 / (length + 1),
|
||||
);
|
||||
|
||||
for (final column in targetNodeParent.children) {
|
||||
final width =
|
||||
column.attributes[SimpleColumnBlockKeys.width]?.toDouble() ??
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth;
|
||||
for (final (index, column) in targetNodeParent.children.indexed) {
|
||||
transaction.updateNode(column, {
|
||||
...column.attributes,
|
||||
SimpleColumnBlockKeys.width: (width * length / (length + 1)).clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
SimpleColumnBlockKeys.ratio: ratios[index],
|
||||
});
|
||||
}
|
||||
|
||||
transaction.insertNode(targetNode.path.next, columnNode);
|
||||
transaction.deleteNode(node);
|
||||
} else {
|
||||
final width = targetNode.rect.width / 2 - 16;
|
||||
final columnsNode = simpleColumnsNode(
|
||||
children: [
|
||||
simpleColumnNode(children: [targetNode.deepCopy()], width: width),
|
||||
simpleColumnNode(children: [node.deepCopy()], width: width),
|
||||
simpleColumnNode(children: [targetNode.deepCopy()], ratio: 0.5),
|
||||
simpleColumnNode(children: [node.deepCopy()], ratio: 0.5),
|
||||
],
|
||||
);
|
||||
|
||||
@ -109,39 +107,37 @@ Future<void> dragToMoveNode(
|
||||
// 1. if the target node is a column block, we should create a column block to contain the node and insert the column node to the target node's parent
|
||||
// 2. if the target node is not a column block, we should create a columns block to contain the target node and the drag node
|
||||
final transaction = editorState.transaction;
|
||||
final targetNodeParent = targetNode.parentColumnsBlock;
|
||||
final targetNodeParent = targetNode.columnsParent;
|
||||
if (targetNodeParent != null) {
|
||||
// find the previous sibling node of the target node
|
||||
final length = targetNodeParent.children.length;
|
||||
final ratios = targetNodeParent.children
|
||||
.map(
|
||||
(e) =>
|
||||
e.attributes[SimpleColumnBlockKeys.ratio]?.toDouble() ??
|
||||
1.0 / length,
|
||||
)
|
||||
.map((e) => e * length / (length + 1))
|
||||
.toList();
|
||||
final columnNode = simpleColumnNode(
|
||||
children: [node.deepCopy()],
|
||||
width: (node.rect.width * 1 / (length + 1)).clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
ratio: 1.0 / (length + 1),
|
||||
);
|
||||
|
||||
for (final column in targetNodeParent.children) {
|
||||
final width =
|
||||
column.attributes[SimpleColumnBlockKeys.width]?.toDouble() ??
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth;
|
||||
for (final (index, column) in targetNodeParent.children.indexed) {
|
||||
transaction.updateNode(column, {
|
||||
...column.attributes,
|
||||
SimpleColumnBlockKeys.width: (width * length / (length + 1)).clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
SimpleColumnBlockKeys.ratio: ratios[index],
|
||||
});
|
||||
}
|
||||
|
||||
transaction.insertNode(targetNode.path.previous, columnNode);
|
||||
transaction.deleteNode(node);
|
||||
} else {
|
||||
final width = targetNode.rect.width / 2 - 16;
|
||||
final columnsNode = simpleColumnsNode(
|
||||
children: [
|
||||
simpleColumnNode(children: [node.deepCopy()], width: width),
|
||||
simpleColumnNode(children: [targetNode.deepCopy()], width: width),
|
||||
simpleColumnNode(children: [node.deepCopy()], ratio: 0.5),
|
||||
simpleColumnNode(children: [targetNode.deepCopy()], ratio: 0.5),
|
||||
],
|
||||
);
|
||||
|
||||
|
@ -7,27 +7,62 @@ import 'package:provider/provider.dart';
|
||||
|
||||
Node simpleColumnNode({
|
||||
List<Node>? children,
|
||||
double? width,
|
||||
double? ratio,
|
||||
}) {
|
||||
return Node(
|
||||
type: SimpleColumnBlockKeys.type,
|
||||
children: children ?? [paragraphNode()],
|
||||
attributes: {
|
||||
SimpleColumnBlockKeys.width: width,
|
||||
SimpleColumnBlockKeys.ratio: ratio,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
extension SimpleColumnBlockAttributes on Node {
|
||||
// get the next column node of the current column node
|
||||
// if the current column node is the last column node, return null
|
||||
Node? get nextColumn {
|
||||
final index = path.last;
|
||||
final parent = this.parent;
|
||||
if (parent == null || index == parent.children.length - 1) {
|
||||
return null;
|
||||
}
|
||||
return parent.children[index + 1];
|
||||
}
|
||||
|
||||
// get the previous column node of the current column node
|
||||
// if the current column node is the first column node, return null
|
||||
Node? get previousColumn {
|
||||
final index = path.last;
|
||||
final parent = this.parent;
|
||||
if (parent == null || index == 0) {
|
||||
return null;
|
||||
}
|
||||
return parent.children[index - 1];
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleColumnBlockKeys {
|
||||
const SimpleColumnBlockKeys._();
|
||||
|
||||
static const String type = 'simple_column';
|
||||
|
||||
/// @Deprecated Use [SimpleColumnBlockKeys.ratio] instead.
|
||||
///
|
||||
/// This field is no longer used since v0.6.9
|
||||
@Deprecated('Use [SimpleColumnBlockKeys.ratio] instead.')
|
||||
static const String width = 'width';
|
||||
|
||||
/// The ratio of the column width.
|
||||
///
|
||||
/// The value is a double number between 0 and 1.
|
||||
static const String ratio = 'ratio';
|
||||
}
|
||||
|
||||
class SimpleColumnBlockComponentBuilder extends BlockComponentBuilder {
|
||||
SimpleColumnBlockComponentBuilder({super.configuration});
|
||||
SimpleColumnBlockComponentBuilder({
|
||||
super.configuration,
|
||||
});
|
||||
|
||||
@override
|
||||
BlockComponentWidget build(BlockComponentContext blockComponentContext) {
|
||||
@ -74,16 +109,6 @@ class SimpleColumnBlockComponentState extends State<SimpleColumnBlockComponent>
|
||||
|
||||
late final EditorState editorState = context.read<EditorState>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget child = Column(
|
||||
@ -121,7 +146,7 @@ class SimpleColumnBlockComponentState extends State<SimpleColumnBlockComponent>
|
||||
if (SimpleColumnsBlockConstants.enableDebugBorder) {
|
||||
child = Container(
|
||||
color: Colors.green.withValues(
|
||||
alpha: 0.2,
|
||||
alpha: 0.3,
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_configuration.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/drag_to_reorder/draggable_option_button.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/columns/simple_columns_block_constant.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@ -26,6 +25,13 @@ class _SimpleColumnBlockWidthResizerState
|
||||
|
||||
ValueNotifier<bool> isHovering = ValueNotifier(false);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
isHovering.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
@ -78,25 +84,47 @@ class _SimpleColumnBlockWidthResizerState
|
||||
|
||||
// update the column width in memory
|
||||
final columnNode = widget.columnNode;
|
||||
final columnsNode = columnNode.columnsParent;
|
||||
if (columnsNode == null) {
|
||||
return;
|
||||
}
|
||||
final editorWidth = columnsNode.rect.width;
|
||||
final rect = columnNode.rect;
|
||||
final width =
|
||||
columnNode.attributes[SimpleColumnBlockKeys.width] ?? rect.width;
|
||||
final width = rect.width;
|
||||
final originalRatio = columnNode.attributes[SimpleColumnBlockKeys.ratio];
|
||||
final newWidth = width + details.delta.dx;
|
||||
|
||||
final transaction = widget.editorState.transaction;
|
||||
final newRatio = newWidth / editorWidth;
|
||||
transaction.updateNode(columnNode, {
|
||||
...columnNode.attributes,
|
||||
SimpleColumnBlockKeys.width: newWidth.clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
SimpleColumnBlockKeys.ratio: newRatio,
|
||||
});
|
||||
final columnsNode = columnNode.parent;
|
||||
if (columnsNode != null) {
|
||||
|
||||
if (newRatio < 0.1 && newRatio < originalRatio) {
|
||||
return;
|
||||
}
|
||||
|
||||
final nextColumn = columnNode.nextColumn;
|
||||
if (nextColumn != null) {
|
||||
final nextColumnRect = nextColumn.rect;
|
||||
final nextColumnWidth = nextColumnRect.width;
|
||||
final newNextColumnWidth = nextColumnWidth - details.delta.dx;
|
||||
final newNextColumnRatio = newNextColumnWidth / editorWidth;
|
||||
if (newNextColumnRatio < 0.1) {
|
||||
return;
|
||||
}
|
||||
transaction.updateNode(nextColumn, {
|
||||
...nextColumn.attributes,
|
||||
SimpleColumnBlockKeys.ratio: newNextColumnRatio,
|
||||
});
|
||||
}
|
||||
|
||||
transaction.updateNode(columnsNode, {
|
||||
...columnsNode.attributes,
|
||||
ColumnsBlockKeys.columnCount: columnsNode.children.length,
|
||||
});
|
||||
}
|
||||
|
||||
widget.editorState.apply(
|
||||
transaction,
|
||||
options: ApplyOptions(inMemoryUpdate: true),
|
||||
@ -113,9 +141,15 @@ class _SimpleColumnBlockWidthResizerState
|
||||
|
||||
// apply the transaction again to make sure the width is updated
|
||||
final transaction = widget.editorState.transaction;
|
||||
transaction.updateNode(widget.columnNode, {
|
||||
...widget.columnNode.attributes,
|
||||
final columnsNode = widget.columnNode.columnsParent;
|
||||
if (columnsNode == null) {
|
||||
return;
|
||||
}
|
||||
for (final columnNode in columnsNode.children) {
|
||||
transaction.updateNode(columnNode, {
|
||||
...columnNode.attributes,
|
||||
});
|
||||
}
|
||||
widget.editorState.apply(transaction);
|
||||
|
||||
isDragging = false;
|
||||
|
@ -3,7 +3,7 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
extension SimpleColumnNodeExtension on Node {
|
||||
/// Returns the parent [Node] of the current node if it is a [SimpleColumnsBlock].
|
||||
Node? get parentColumnsBlock {
|
||||
Node? get columnsParent {
|
||||
Node? currentNode = parent;
|
||||
while (currentNode != null) {
|
||||
if (currentNode.type == SimpleColumnsBlockKeys.type) {
|
||||
@ -15,7 +15,7 @@ extension SimpleColumnNodeExtension on Node {
|
||||
}
|
||||
|
||||
/// Returns the parent [Node] of the current node if it is a [SimpleColumnBlock].
|
||||
Node? get parentColumn {
|
||||
Node? get columnParent {
|
||||
Node? currentNode = parent;
|
||||
while (currentNode != null) {
|
||||
if (currentNode.type == SimpleColumnBlockKeys.type) {
|
||||
@ -27,8 +27,8 @@ extension SimpleColumnNodeExtension on Node {
|
||||
}
|
||||
|
||||
/// Returns whether the current node is in a [SimpleColumnsBlock].
|
||||
bool get isInColumnsBlock => parentColumnsBlock != null;
|
||||
bool get isInColumnsBlock => columnsParent != null;
|
||||
|
||||
/// Returns whether the current node is in a [SimpleColumnBlock].
|
||||
bool get isInColumnBlock => parentColumn != null;
|
||||
bool get isInColumnBlock => columnParent != null;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/columns/simple_columns_block_constant.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
@ -5,20 +7,19 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:universal_platform/universal_platform.dart';
|
||||
|
||||
// if the children is not provided, it will create two columns by default.
|
||||
// if the columnCount is provided, it will create the specified number of columns.
|
||||
Node simpleColumnsNode({
|
||||
List<Node>? children,
|
||||
int? columnCount,
|
||||
double? width,
|
||||
double? ratio,
|
||||
}) {
|
||||
columnCount ??= 2;
|
||||
children ??= List.generate(
|
||||
columnCount,
|
||||
(index) => simpleColumnNode(
|
||||
width: width,
|
||||
ratio: ratio,
|
||||
children: [paragraphNode()],
|
||||
),
|
||||
);
|
||||
@ -91,6 +92,13 @@ class ColumnsBlockComponentState extends State<ColumnsBlockComponent>
|
||||
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_updateColumnsBlock();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.dispose();
|
||||
@ -100,23 +108,12 @@ class ColumnsBlockComponentState extends State<ColumnsBlockComponent>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget child = SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: scrollController,
|
||||
child: Row(
|
||||
Widget child = Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: _buildChildren(),
|
||||
),
|
||||
);
|
||||
|
||||
if (UniversalPlatform.isDesktop) {
|
||||
// only show the scrollbar on desktop
|
||||
child = Scrollbar(
|
||||
controller: scrollController,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
child = Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: IntrinsicHeight(
|
||||
@ -148,19 +145,18 @@ class ColumnsBlockComponentState extends State<ColumnsBlockComponent>
|
||||
}
|
||||
|
||||
List<Widget> _buildChildren() {
|
||||
final length = node.children.length;
|
||||
final children = <Widget>[];
|
||||
for (var i = 0; i < node.children.length; i++) {
|
||||
for (var i = 0; i < length; i++) {
|
||||
final childNode = node.children[i];
|
||||
final width =
|
||||
childNode.attributes[SimpleColumnBlockKeys.width]?.toDouble() ??
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth;
|
||||
final double ratio =
|
||||
childNode.attributes[SimpleColumnBlockKeys.ratio]?.toDouble() ??
|
||||
1.0 / length;
|
||||
|
||||
Widget child = editorState.renderer.build(context, childNode);
|
||||
|
||||
child = SizedBox(
|
||||
width: width.clamp(
|
||||
SimpleColumnsBlockConstants.minimumColumnWidth,
|
||||
double.infinity,
|
||||
),
|
||||
child = Expanded(
|
||||
flex: (max(ratio, 0.1) * 10000).toInt(),
|
||||
child: child,
|
||||
);
|
||||
|
||||
@ -176,6 +172,26 @@ class ColumnsBlockComponentState extends State<ColumnsBlockComponent>
|
||||
return children;
|
||||
}
|
||||
|
||||
// Update the existing columns block data
|
||||
// if the column ratio is not existing, it will be set to 1.0 / columnCount
|
||||
void _updateColumnsBlock() {
|
||||
final transaction = editorState.transaction;
|
||||
final length = node.children.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final childNode = node.children[i];
|
||||
final ratio = childNode.attributes[SimpleColumnBlockKeys.ratio];
|
||||
if (ratio == null) {
|
||||
transaction.updateNode(childNode, {
|
||||
...childNode.attributes,
|
||||
SimpleColumnBlockKeys.ratio: 1.0 / length,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (transaction.operations.isNotEmpty) {
|
||||
editorState.apply(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Position start() => Position(path: widget.node.path);
|
||||
|
||||
|
@ -227,6 +227,7 @@ class CustomImageBlockComponentState extends State<CustomImageBlockComponent>
|
||||
delegate: this,
|
||||
listenable: editorState.selectionNotifier,
|
||||
blockColor: editorState.editorStyle.selectionColor,
|
||||
selectionAboveBlock: true,
|
||||
supportTypes: const [BlockSelectionType.block],
|
||||
child: child,
|
||||
);
|
||||
@ -313,7 +314,7 @@ class CustomImageBlockComponentState extends State<CustomImageBlockComponent>
|
||||
}) {
|
||||
final imageBox = imageKey.currentContext?.findRenderObject();
|
||||
if (imageBox is RenderBox) {
|
||||
return Offset.zero & imageBox.size;
|
||||
return padding.topLeft & imageBox.size;
|
||||
}
|
||||
return Rect.zero;
|
||||
}
|
||||
|
@ -81,7 +81,9 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
|
||||
with
|
||||
BlockComponentConfigurable,
|
||||
BlockComponentTextDirectionMixin,
|
||||
BlockComponentBackgroundColorMixin {
|
||||
BlockComponentBackgroundColorMixin,
|
||||
DefaultSelectableMixin,
|
||||
SelectableMixin {
|
||||
// Change the value if the heading block type supports heading levels greater than '3'
|
||||
static const maxVisibleDepth = 6;
|
||||
|
||||
@ -95,6 +97,17 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
|
||||
late EditorState editorState = context.read<EditorState>();
|
||||
late Stream<EditorTransactionValue> stream = editorState.transactionStream;
|
||||
|
||||
@override
|
||||
GlobalKey<State<StatefulWidget>> blockComponentKey = GlobalKey(
|
||||
debugLabel: OutlineBlockKeys.type,
|
||||
);
|
||||
|
||||
@override
|
||||
GlobalKey<State<StatefulWidget>> get containerKey => widget.node.key;
|
||||
|
||||
@override
|
||||
GlobalKey<State<StatefulWidget>> get forwardKey => widget.node.key;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StreamBuilder(
|
||||
@ -102,6 +115,19 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
|
||||
builder: (context, snapshot) {
|
||||
Widget child = _buildOutlineBlock();
|
||||
|
||||
child = BlockSelectionContainer(
|
||||
node: node,
|
||||
delegate: this,
|
||||
listenable: editorState.selectionNotifier,
|
||||
remoteSelection: editorState.remoteSelections,
|
||||
blockColor: editorState.editorStyle.selectionColor,
|
||||
selectionAboveBlock: true,
|
||||
supportTypes: const [
|
||||
BlockSelectionType.block,
|
||||
],
|
||||
child: child,
|
||||
);
|
||||
|
||||
if (UniversalPlatform.isDesktopOrWeb) {
|
||||
if (widget.showActions && widget.actionBuilder != null) {
|
||||
child = BlockComponentActionWrapper(
|
||||
@ -176,6 +202,7 @@ class _OutlineBlockWidgetState extends State<OutlineBlockWidget>
|
||||
}
|
||||
|
||||
return Container(
|
||||
key: blockComponentKey,
|
||||
constraints: const BoxConstraints(
|
||||
minHeight: 40.0,
|
||||
),
|
||||
|
@ -90,13 +90,8 @@ SelectionMenuItem fourColumnsSlashMenuItem = SelectionMenuItem.node(
|
||||
);
|
||||
|
||||
Node _buildColumnsNode(EditorState editorState, int columnCount) {
|
||||
final selection = editorState.selection;
|
||||
double? width;
|
||||
if (selection != null) {
|
||||
final parentNode = editorState.getNodeAtPath(selection.start.path);
|
||||
if (parentNode != null) {
|
||||
width = parentNode.rect.width / columnCount - 16;
|
||||
}
|
||||
}
|
||||
return simpleColumnsNode(columnCount: columnCount, width: width);
|
||||
return simpleColumnsNode(
|
||||
columnCount: columnCount,
|
||||
ratio: 1.0 / columnCount,
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user