diagram_editor 0.0.4 diagram_editor: ^0.0.4 copied to clipboard
A flutter diagram editor library that provides DiagramEditor widget and a possibility to customize all editor design and behavior.
import 'dart:math' as math;
import 'package:diagram_editor/diagram_editor.dart';
import 'package:flutter/material.dart';
void main() => runApp(DiagramApp());
class DiagramApp extends StatefulWidget {
@override
_DiagramAppState createState() => _DiagramAppState();
}
class _DiagramAppState extends State<DiagramApp> {
MyPolicySet myPolicySet = MyPolicySet();
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Stack(
children: [
Container(color: Colors.grey),
Padding(
padding: EdgeInsets.all(16),
child: Container(
color: Colors.green,
child: DiagramEditor(
diagramEditorContext: DiagramEditorContext(
policySet: myPolicySet,
),
),
),
),
GestureDetector(
onTap: () => myPolicySet.deleteAllComponents(),
child: Container(
width: 64,
height: 32,
color: Colors.red,
child: Center(child: Text('delete all')),
),
),
],
),
),
),
);
}
}
// Custom component Data
class MyComponentData {
bool isHighlightVisible;
Color color =
Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
MyComponentData({this.isHighlightVisible = false});
switchHighlight() {
isHighlightVisible = !isHighlightVisible;
}
showHighlight() {
isHighlightVisible = true;
}
hideHighlight() {
isHighlightVisible = false;
}
}
// Policy set and individual policy implementations.
class MyPolicySet extends PolicySet
with
MyInitPolicy,
MyComponentDesignPolicy,
MyCanvasPolicy,
MyComponentPolicy,
CustomPolicy,
//
CanvasControlPolicy,
LinkControlPolicy,
LinkJointControlPolicy,
LinkAttachmentRectPolicy {}
mixin MyInitPolicy implements InitPolicy {
@override
initializeDiagramEditor() {
canvasWriter.state.setCanvasColor(Colors.grey[300]);
}
}
mixin MyComponentDesignPolicy implements ComponentDesignPolicy {
@override
Widget showComponentBody(ComponentData componentData) {
return Container(
decoration: BoxDecoration(
color: componentData.data.color,
border: Border.all(
width: 2,
color: componentData.data.isHighlightVisible
? Colors.pink
: Colors.black),
),
child: Center(child: Text('component')),
);
}
}
mixin MyCanvasPolicy implements CanvasPolicy, CustomPolicy {
@override
onCanvasTapUp(TapUpDetails details) {
hideComponentHighlight(selectedComponentId);
selectedComponentId = null;
canvasWriter.model.hideAllLinkJoints();
canvasWriter.model.addComponent(
ComponentData(
size: Size(96, 72),
position:
canvasReader.state.fromCanvasCoordinates(details.localPosition),
data: MyComponentData(),
),
);
}
}
mixin MyComponentPolicy implements ComponentPolicy, CustomPolicy {
Offset lastFocalPoint;
@override
onComponentTap(String componentId) {
hideComponentHighlight(selectedComponentId);
canvasWriter.model.hideAllLinkJoints();
bool connected = connectComponents(selectedComponentId, componentId);
if (connected) {
selectedComponentId = null;
} else {
selectedComponentId = componentId;
highlightComponent(componentId);
}
}
@override
onComponentLongPress(String componentId) {
hideComponentHighlight(selectedComponentId);
selectedComponentId = null;
canvasWriter.model.hideAllLinkJoints();
canvasWriter.model.removeComponent(componentId);
}
@override
onComponentScaleStart(componentId, details) {
lastFocalPoint = details.localFocalPoint;
}
@override
onComponentScaleUpdate(componentId, details) {
Offset positionDelta = details.localFocalPoint - lastFocalPoint;
canvasWriter.model.moveComponent(componentId, positionDelta);
lastFocalPoint = details.localFocalPoint;
}
bool connectComponents(String sourceComponentId, String targetComponentId) {
if (sourceComponentId == null) {
return false;
}
if (sourceComponentId == targetComponentId) {
return false;
}
// test if the connection between two components already exists (one way)
if (canvasReader.model.getComponent(sourceComponentId).connections.any(
(connection) =>
(connection is ConnectionOut) &&
(connection.otherComponentId == targetComponentId))) {
return false;
}
canvasWriter.model.connectTwoComponents(
sourceComponentId: sourceComponentId,
targetComponentId: targetComponentId,
linkStyle: LinkStyle(
arrowType: ArrowType.pointedArrow,
lineWidth: 1.5,
backArrowType: ArrowType.centerCircle,
),
);
return true;
}
}
mixin CustomPolicy implements PolicySet {
String selectedComponentId;
highlightComponent(String componentId) {
canvasReader.model.getComponent(componentId).data.showHighlight();
canvasReader.model.getComponent(componentId).updateComponent();
}
hideComponentHighlight(String componentId) {
if (selectedComponentId != null) {
canvasReader.model.getComponent(componentId).data.hideHighlight();
canvasReader.model.getComponent(componentId).updateComponent();
}
}
deleteAllComponents() {
selectedComponentId = null;
canvasWriter.model.removeAllComponents();
}
}