diff --git a/Makefile b/Makefile index bc1eb66..5b263f7 100644 --- a/Makefile +++ b/Makefile @@ -27,13 +27,18 @@ clean: flutter clean docker: - DOCKER_BUILDKIT=1 docker build -t oc/oc-front:0.0.1 --build-arg HOST=$(HOST) -f Dockerfile . - docker tag oc/oc-front:0.0.1 oc/oc-front:latest + DOCKER_BUILDKIT=1 docker build -t oc-front --build-arg HOST=$(HOST) -f Dockerfile . + docker tag oc-front:latest oc/oc-front:0.0.1 publish-kind: - kind load docker-image oc/oc-front:0.0.1 --name opencloud + kind load docker-image oc/oc-front:0.0.1 --name opencloud | true publish-registry: @echo "TODO" +docker-deploy: + docker compose up -d + +run-docker: docker publish-kind publish-registry docker-deploy + .PHONY: build run clean docker publish-kind publish-registry diff --git a/lib/models/workflow.dart b/lib/models/workflow.dart index 3d6b047..28da539 100644 --- a/lib/models/workflow.dart +++ b/lib/models/workflow.dart @@ -335,7 +335,7 @@ class Graph extends SerializerDeserializer { // should find arrow env info and add it to the env List extParams = []; var arrows = links.where( (e) => (e.source?.id?.contains(item.id ?? "") ?? false) || (e.destination?.id?.contains(item.id ?? "") ?? false)); - for (var arrow in arrows) { + /*for (var arrow in arrows) { for (var info in arrow.infos) { var i = info as Map; for (var entry in i.entries) { @@ -352,7 +352,7 @@ class Graph extends SerializerDeserializer { } } } - } + }*/ for ( var param in what) { if (param.attr == null) { continue; } var varName = param.name != null && (param.name!.contains("LINK_") diff --git a/lib/pages/workflow.dart b/lib/pages/workflow.dart index 3a10a44..150e4de 100644 --- a/lib/pages/workflow.dart +++ b/lib/pages/workflow.dart @@ -66,7 +66,8 @@ final WorflowService _service = WorflowService(); var from = dash.getElement(arrow.fromID); var to = dash.getElement(arrow.toID); if ((from?.element?.getType() == "storage" && to?.element?.getType() == "processing") - || (from?.element?.getType() == "processing" && to?.element?.getType() == "storage")) { + || (from?.element?.getType() == "processing" && to?.element?.getType() == "storage") + || (from?.element?.getType() == "processing" && to?.element?.getType() == "processing")) { return StorageProcessingLinkFormsWidget( dash: dash, item: arrow); } return Container(); diff --git a/lib/widgets/forms/container_forms.dart b/lib/widgets/forms/container_forms.dart index 3cc8769..6bff370 100644 --- a/lib/widgets/forms/container_forms.dart +++ b/lib/widgets/forms/container_forms.dart @@ -20,14 +20,25 @@ class ContainerFormsWidgetState extends State { List widgets = []; var instance = widget.item.getSelectedInstance(); if (instance != null && instance is ProcessingInstance && instance.access?.container != null) { + List exposes = []; var container = instance.access!.container!; + for (var expose in container.exposes) { + exposes.add(SubExposeFormsWidget( + readOnly: false, + width: 180, + dash: widget.dash, + empty: false, + item: expose, + elementID: widget.elementID + )); + } widgets.add(Container( padding: const EdgeInsets.only(bottom: 10), width: 180, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + const Text("", style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center), SubTextInputWidget(subkey: "image", width: 180, empty: false, change: (value) { }, initialValue: container.image, readOnly: true), SubTextInputWidget(subkey: "command", width: 180, empty: false, change: (value) { @@ -39,7 +50,7 @@ class ContainerFormsWidgetState extends State { } } widget.dash.saveDash(widget.dash.id, context); - }, initialValue: container.command, readOnly: false,), + }, initialValue: container.command, readOnly: false), SubTextInputWidget(subkey: "args", width: 180, empty: false, change: (value) { container.args = value; for (var el in widget.dash.elements) { @@ -54,7 +65,7 @@ class ContainerFormsWidgetState extends State { ],) )); widgets.add(Container( - width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), + width: 200, decoration: const BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), )); widgets.add(Container( padding: const EdgeInsets.symmetric(vertical: 10), @@ -86,19 +97,19 @@ class ContainerFormsWidgetState extends State { setState(() {}); }, child: Container( margin: const EdgeInsets.only(left: 5, top: 5), - decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.grey, width: 1)), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + border: Border.all(color: Colors.grey, width: 1) + ), width: 45, height: 30, child: const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.delete, color: Colors.black) ]), - ) ) - ]), - ],) + ) + ]), + ...exposes + ]) )); - for (var expose in container.exposes) { - widgets.add(SubExposeFormsWidget( readOnly: true, width: 180, dash: widget.dash, empty: widgets.isEmpty, - item: expose, elementID: widget.elementID)); - } } return Column(children: widgets); } diff --git a/lib/widgets/forms/credentials_forms.dart b/lib/widgets/forms/credentials_forms.dart index b4c4a8c..763ce55 100644 --- a/lib/widgets/forms/credentials_forms.dart +++ b/lib/widgets/forms/credentials_forms.dart @@ -19,8 +19,8 @@ class CredentialsFormsWidgetState extends State { var instance = widget.item.getSelectedInstance(); if (instance != null && instance.credential != null) { var creds = instance.credential!; - widgets.add(Container( margin: EdgeInsets.only(bottom: 15), - width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), + widgets.add(Container( margin: const EdgeInsets.only(bottom: 15), + width: 200, decoration: const BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), )); widgets.add(Container( padding: const EdgeInsets.only(bottom: 10), @@ -28,9 +28,9 @@ class CredentialsFormsWidgetState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Text("", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center), + const Text("", style: TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center), SubTextInputWidget(subkey: "login", width: 180, empty: false, change: (value) { - creds.password = value; + creds.login = value; for (var el in widget.dash.elements) { if (el.id == widget.elementID) { el.element = widget.item; diff --git a/lib/widgets/forms/resource_forms.dart b/lib/widgets/forms/resource_forms.dart index aff14b4..de81666 100644 --- a/lib/widgets/forms/resource_forms.dart +++ b/lib/widgets/forms/resource_forms.dart @@ -1,6 +1,5 @@ import 'package:oc_front/main.dart'; import 'package:flutter/material.dart'; -import 'package:oc_front/models/workflow.dart'; import 'package:oc_front/models/resources/resources.dart'; import 'package:oc_front/core/services/perms_service.dart'; import 'package:oc_front/widgets/forms/credentials_forms.dart'; @@ -37,7 +36,7 @@ class ResourceFormsWidgetState extends State { } } if (widgets.isNotEmpty) { - widgets.add(SizedBox( width: 200, height: 15) ); + widgets.add(const SizedBox( width: 200, height: 15) ); } return widgets; } @@ -55,6 +54,7 @@ class ResourceFormsWidgetState extends State { @override Widget build(BuildContext context) { + print("STATE"); List instancesCat = []; List childrenReadOnly = getWidgets(widget.item.infos()); List> dpItems = []; @@ -62,11 +62,11 @@ class ResourceFormsWidgetState extends State { dpItems.add(DropdownMenuItem(value: '$i', child: Text('${instance.name}', overflow: TextOverflow.ellipsis,))); } if (dpItems.isNotEmpty) { - childrenReadOnly.add(Padding( padding: EdgeInsets.only(top: 20), + childrenReadOnly.add(Padding( padding: const EdgeInsets.only(top: 20), child : Container( - width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), + width: 200, decoration: const BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), ))); - childrenReadOnly.add(Padding(padding: EdgeInsets.only(bottom: 15), child: + childrenReadOnly.add(Padding(padding: const EdgeInsets.only(bottom: 15), child: SubDropdownInputWidget( dropdownMenuEntries: dpItems, subkey: "", width: 180, empty: false, initialValue: "${widget.item.selectedInstance}", change: (value) { if (value != null) { setState(() { widget.item.selectedInstance = int.parse(value); }); } @@ -81,7 +81,7 @@ class ResourceFormsWidgetState extends State { instancesCat.add(CredentialsFormsWidget(dash: widget.dash, item: widget.item, elementID: widget.elementID)); if (instancesCat.isNotEmpty) { instancesCat.add(Container( - width: 200, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), + width: 200, decoration: const BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), )); } bool readOnly = !PermsService.getPerm(Perms.WORKFLOW_EDIT); diff --git a/lib/widgets/forms/storage_processing_link_forms.dart b/lib/widgets/forms/storage_processing_link_forms.dart index 34c9bcf..7c84e9c 100644 --- a/lib/widgets/forms/storage_processing_link_forms.dart +++ b/lib/widgets/forms/storage_processing_link_forms.dart @@ -38,7 +38,7 @@ class StorageProcessingLinkFormsWidgetState extends State children = [ - Padding( padding: const EdgeInsets.only(top: 10), + const Padding( padding: const EdgeInsets.only(top: 10), child: Text("", style: const TextStyle(fontSize: 13, fontWeight: FontWeight.bold), textAlign: TextAlign.center)), ]; @@ -54,9 +54,9 @@ class StorageProcessingLinkFormsWidgetState extends State).keys) { @@ -112,7 +112,7 @@ class StorageProcessingLinkFormsWidgetState extends State { "write": false, "source": null, "destination": null, @@ -125,7 +125,7 @@ class StorageProcessingLinkFormsWidgetState extends State { @override Widget build(BuildContext context) { + print("qsfqs"); + try { + var w = SubTextInputWidget(subkey: "reference port", readOnly: widget.readOnly, + initialValue: widget.item.port != null ? '${widget.item.port}' : null, + width: widget.width, + empty: widget.empty, + change: (value) { + try { + widget.item.port = int.parse(value); + Future.delayed(const Duration(seconds: 2), () { + if (widget.item.port == int.parse(value) && int.parse(value) != 0) { + widget.dash.saveDash(widget.dash.id, context); + } + }); + } catch (e) { widget.item.port = null; } + var el = widget.dash.getElement(widget.elementID); + el!.element = widget.item as dynamic; + }); + } catch (e,s) { + print(e); + print(s); + } return Column( children : [ - Container( margin: const EdgeInsets.only(left: 10, right: 10, top: 5), - decoration: BoxDecoration(border: Border.all(color: Colors.grey, width: 1)), + Container( margin: const EdgeInsets.only(left: 10, right: 10, top: 15), + decoration: const BoxDecoration(border: Border( top: BorderSide(color: Colors.grey, width: 1))), width: 180 ), SubTextInputWidget(subkey: "reference port", readOnly: widget.readOnly, initialValue: widget.item.port != null ? '${widget.item.port}' : null, - width: widget.width, empty: widget.empty, change: (value) { + width: 180, + empty: widget.empty, + change: (value) { try { widget.item.port = int.parse(value); Future.delayed(const Duration(seconds: 2), () { diff --git a/lib/widgets/inputs/sub_text_input.dart b/lib/widgets/inputs/sub_text_input.dart index 994b2a9..1747b0b 100644 --- a/lib/widgets/inputs/sub_text_input.dart +++ b/lib/widgets/inputs/sub_text_input.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:oc_front/widgets/dialog/alert.dart'; +// ignore: must_be_immutable class SubTextInputWidget extends StatefulWidget { String subkey; String? initialValue; @@ -12,10 +13,9 @@ class SubTextInputWidget extends StatefulWidget { bool readOnly = false; bool copyLabel = false; void Function(String) change = (value) {}; - SubTextInputWidget ({ Key? key, + SubTextInputWidget ({ super.key, required this.subkey, this.readOnly = false, this.noLabel = false, this.copyLabel = false, - this.initialValue, required this.width, required this.empty, required this.change }): - super(key: key); + this.initialValue, required this.width, required this.empty, required this.change }); @override SubTextInputWidgetState createState() => SubTextInputWidgetState(); } class SubTextInputWidgetState extends State { @@ -24,12 +24,13 @@ class SubTextInputWidgetState extends State { if (widget.readOnly && widget.initialValue == null) { return Container(); } + TextEditingController ctrl = TextEditingController(text: widget.initialValue); return Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Tooltip( message: widget.subkey, child: Container( margin: EdgeInsets.only(top: widget.empty ? 0 : 15), width: widget.width - (widget.readOnly ? 40 : 0), height: 30, child: TextFormField( textAlign: TextAlign.start, enabled: !widget.readOnly, - initialValue: widget.initialValue, + controller: ctrl, onChanged: widget.change, style: const TextStyle(fontSize: 12), decoration: InputDecoration( diff --git a/library/flutter_flow_chart/lib/src/flow_chart.dart b/library/flutter_flow_chart/lib/src/flow_chart.dart index 9905801..606bcd7 100755 --- a/library/flutter_flow_chart/lib/src/flow_chart.dart +++ b/library/flutter_flow_chart/lib/src/flow_chart.dart @@ -743,18 +743,22 @@ class ChartWidgetState extends State { onTapDown: (details) { hoverImportant = false; tapDownPos = details.localPosition; + for (var arr in widget.dashboard.arrows) { if (arr.isLine(tapDownPos)) { hoverImportant = true; + for (var arr in widget.dashboard.arrows) { + arr.isSelected = false; + } arr.isSelected = !arr.isSelected; for (var sel in widget.dashboard.elements) { sel.isSelected = false; } - Future.delayed(Duration(milliseconds: 100), () { + Future.delayed(const Duration(milliseconds: 100), () { widget.dashboard.selectedMenuKey.currentState?.setState(() {}); DrawingArrow.instance.notifyListeners(); }); - + break; } } if (!hoverImportant) { diff --git a/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart b/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart index 4d7adcd..963baab 100644 --- a/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart +++ b/library/flutter_flow_chart/lib/src/flow_chart_selected_menu.dart @@ -79,9 +79,8 @@ class FlowChartSelectedMenuState extends State { widget.dashboard.infoLinkWidget!(widget.dashboard.arrowsSelected.first) : Container(), widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container( width: 200, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration(border: Border( - top: BorderSide(color: Colors.grey, width: 1))), + margin: const EdgeInsets.only(top: 15), + decoration: const BoxDecoration(border: Border(top: BorderSide(color: Colors.grey, width: 1))), child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ Tooltip( message: "remove", child: InkWell( mouseCursor: SystemMouseCursors.click, @@ -92,13 +91,13 @@ class FlowChartSelectedMenuState extends State { } return element.isSelected; }, context); - Future.delayed(Duration(milliseconds: 100), () { + Future.delayed( const Duration(milliseconds: 100), () { widget.dashboard.flutterChartKey.currentState?.setState(() { }); }); - }, child: Container( margin: EdgeInsets.all(10), + }, child: Container( margin: const EdgeInsets.all(10), decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)), width: 200, height: 30, - child: Icon(Icons.delete_outline, color: Colors.black), + child: const Icon(Icons.delete_outline, color: Colors.black), )) ), ]) @@ -118,22 +117,22 @@ class FlowChartSelectedMenuState extends State { height: widget.height, color: widget.dashboard.midDashColor, child: Column( children: [ - Container( padding: EdgeInsets.all(10), width: 200, height: 60, - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + Container( padding: const EdgeInsets.all(10), width: 200, height: 60, + decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("STYLE ${widget.dashboard.elementSelected.isNotEmpty ? "ELEMENT" : "ARROW"}", style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), textAlign: TextAlign.center), Text("<${widget.dashboard.arrowsSelected.isEmpty && widget.dashboard.elementSelected.isEmpty ? "general" : "selected"}>", style: TextStyle(fontSize: 12), textAlign: TextAlign.center), ])), SizedBox( width: 200, height: widget.height - 60, child: SingleChildScrollView( child: Column( children: [ widget.dashboard.elementSelected.isNotEmpty ? Container() : Container( padding: EdgeInsets.symmetric(horizontal: 10, vertical: 20), - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), child: Column( children: [ Row( children: [ InkWell( mouseCursor: SystemMouseCursors.click, - child: Padding( padding: EdgeInsets.only(left: 10, right: 10), + child: Padding( padding: const EdgeInsets.only(left: 10, right: 10), child: PopupMenuButton( tooltip: "line defaults", - constraints: BoxConstraints(maxWidth: 100), + constraints: const BoxConstraints(maxWidth: 100), initialValue: null, onSelected: (ArrowDash value) { if (widget.dashboard.elementSelected.isEmpty) { @@ -199,14 +198,14 @@ class FlowChartSelectedMenuState extends State { dashSpace: widget.dashboard.defaultDashSpace, color: Colors.black ), - SizedBox(height: 25, width: 10), - Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) + const SizedBox(height: 25, width: 10), + const Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) ), ) ), PopupMenuButton( tooltip: "color picker", - constraints: BoxConstraints(maxWidth: 664), + constraints: const BoxConstraints(maxWidth: 664), initialValue: null, onSelected: (void value) {}, itemBuilder: (BuildContext context) => >[ @@ -222,12 +221,12 @@ class FlowChartSelectedMenuState extends State { ], child: Row( children: [ Container(width: 15, height: 15, color: widget.dashboard.defaultColor), - SizedBox(height: 25, width: 5), - Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) + const SizedBox(height: 25, width: 5), + const Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) ), Tooltip( message: "stroke width", child: Container( - margin: EdgeInsets.only(left: 10), + margin: const EdgeInsets.only(left: 10), width: 55, height: 25, child: TextFormField( textAlign: TextAlign.center, readOnly: widget.dashboard.defaultDashWidth <= 0, @@ -239,8 +238,8 @@ class FlowChartSelectedMenuState extends State { } setState(() { widget.dashboard.defaultStroke = double.parse(value); }); }, - style: TextStyle(fontSize: 12), - decoration: InputDecoration( + style: const TextStyle(fontSize: 12), + decoration: const InputDecoration( fillColor: Colors.white, filled: true, labelText: "stroke", @@ -266,7 +265,7 @@ class FlowChartSelectedMenuState extends State { ]), Row(children: [ InkWell( mouseCursor: SystemMouseCursors.click, child: Padding( - padding: EdgeInsets.only(left: 10, top: 10, right: 10), + padding: const EdgeInsets.only(left: 10, top: 10, right: 10), child: PopupMenuButton( initialValue: null, onSelected: (ArrowStyle value) { @@ -279,7 +278,7 @@ class FlowChartSelectedMenuState extends State { }, tooltip: "line styles", itemBuilder: (BuildContext context) => >[ - PopupMenuItem( + const PopupMenuItem( value: ArrowStyle.segmented, child: Row( children: [ Icon(Icons.turn_slight_left), @@ -287,7 +286,7 @@ class FlowChartSelectedMenuState extends State { child: Text('straight', textAlign: TextAlign.center,)) ]), ), - PopupMenuItem( + const PopupMenuItem( value: ArrowStyle.curve, child: Row( children: [ Icon(Icons.roundabout_left), @@ -295,7 +294,7 @@ class FlowChartSelectedMenuState extends State { child: Text('curved', textAlign: TextAlign.center,)) ]), ), - PopupMenuItem( + const PopupMenuItem( value: ArrowStyle.rectangular, child: Row( children: [ Icon(Icons.turn_sharp_left_outlined), @@ -307,13 +306,13 @@ class FlowChartSelectedMenuState extends State { child: Row( children: [ Icon(widget.dashboard.defaultArrowStyle == ArrowStyle.segmented ? Icons.turn_slight_left : widget.dashboard.defaultArrowStyle == ArrowStyle.curve ? Icons.roundabout_left : Icons.turn_sharp_left_outlined , color: Colors.black), - Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) + const Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) ) ) ), Tooltip( message: "space dash", child: Container( - margin: EdgeInsets.only(top: 10), + margin: const EdgeInsets.only(top: 10), width: 105 / 2, height: 25, child: TextFormField( textAlign: TextAlign.center, readOnly: widget.dashboard.defaultDashWidth <= 0, @@ -325,14 +324,14 @@ class FlowChartSelectedMenuState extends State { } setState(() { widget.dashboard.defaultDashWidth = double.parse(value); }); }, - style: TextStyle(fontSize: 12), + style: const TextStyle(fontSize: 12), decoration: InputDecoration( fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white, filled: true, labelText: "dash", - labelStyle: TextStyle(fontSize: 10), - border: OutlineInputBorder(), - contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), + labelStyle: const TextStyle(fontSize: 10), + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), ), inputFormatters: [ NumberTextInputFormatter( @@ -351,7 +350,7 @@ class FlowChartSelectedMenuState extends State { ))), Tooltip( message: "space width", child: Container( - margin: EdgeInsets.only(left: 10, top: 10), + margin: const EdgeInsets.only(left: 10, top: 10), width: 105 / 2, height: 25, child: TextFormField( textAlign: TextAlign.center, initialValue: "${widget.dashboard.defaultDashSpace}", @@ -362,14 +361,14 @@ class FlowChartSelectedMenuState extends State { } setState(() { widget.dashboard.defaultDashSpace = double.parse(value); }); }, - style: TextStyle(fontSize: 12), + style: const TextStyle(fontSize: 12), decoration: InputDecoration( fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white, filled: true, labelText: "space", - labelStyle: TextStyle(fontSize: 10), - border: OutlineInputBorder(), - contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), + labelStyle: const TextStyle(fontSize: 10), + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), ), inputFormatters: [ NumberTextInputFormatter( @@ -389,12 +388,12 @@ class FlowChartSelectedMenuState extends State { ]), ])), widget.dashboard.elementSelected.isNotEmpty ? Container() : - Container( padding: EdgeInsets.only(left: 10, right: 10, bottom: 20, top: 15), - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + Container( padding: const EdgeInsets.only(left: 10, right: 10, bottom: 20, top: 15), + decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children : [ InkWell( mouseCursor: SystemMouseCursors.click, - child: Padding( padding: EdgeInsets.symmetric(horizontal: 10), + child: Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: PopupMenuButton( initialValue: null, onSelected: (ArrowDirection value) { @@ -407,7 +406,7 @@ class FlowChartSelectedMenuState extends State { }, tooltip: widget.dashboard.defaultArrowDirection == ArrowDirection.forward ? 'forward' : widget.dashboard.defaultArrowDirection == ArrowDirection.backward ? 'backward' : 'bidirectionnal', itemBuilder: (BuildContext context) => >[ - PopupMenuItem( + const PopupMenuItem( value: ArrowDirection.forward, child: Row( children: [ Icon(Icons.arrow_forward), @@ -415,7 +414,7 @@ class FlowChartSelectedMenuState extends State { child: Text('forward', textAlign: TextAlign.center,)) ]), ), - PopupMenuItem( + const PopupMenuItem( value: ArrowDirection.backward, child: Row( children: [ Icon(Icons.arrow_back), @@ -423,7 +422,7 @@ class FlowChartSelectedMenuState extends State { child: Text('curved', textAlign: TextAlign.center,)) ]), ), - PopupMenuItem( + const PopupMenuItem( value: ArrowDirection.bidirectionnal, child: Row( children: [ Icon(Icons.sync_alt_outlined), @@ -435,16 +434,16 @@ class FlowChartSelectedMenuState extends State { child: Row( children: [ Icon(widget.dashboard.defaultArrowDirection == ArrowDirection.forward ? Icons.arrow_forward : widget.dashboard.defaultArrowDirection == ArrowDirection.backward ? Icons.arrow_back : Icons.sync_alt_outlined, color: Colors.black), - Padding( padding: EdgeInsets.symmetric(horizontal: 10), + Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text(widget.dashboard.defaultArrowDirection == ArrowDirection.forward ? 'forward' : widget.dashboard.defaultArrowDirection == ArrowDirection.backward ? 'backward' : 'bidirectionnal')), - Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) + const Icon(Icons.arrow_drop_down, size: 10, color: Colors.black) ]) ),) ), ]), Row(children: [ Tooltip( message: "forward size", child: Container( - margin: EdgeInsets.only(top: 10), + margin: const EdgeInsets.only(top: 10), width: 150, height: 25, child: TextFormField( textAlign: TextAlign.center, initialValue: "${widget.dashboard.defaultForwardWidth}", @@ -467,14 +466,14 @@ class FlowChartSelectedMenuState extends State { } }); }, - style: TextStyle(fontSize: 12), + style: const TextStyle(fontSize: 12), decoration: InputDecoration( fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white, filled: true, labelText: "forward size", - labelStyle: TextStyle(fontSize: 10), - border: OutlineInputBorder(), - contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), + labelStyle: const TextStyle(fontSize: 10), + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), ), inputFormatters: [ NumberTextInputFormatter( @@ -491,12 +490,12 @@ class FlowChartSelectedMenuState extends State { ], keyboardType: TextInputType.number, ))), - Padding( padding: EdgeInsets.only(top: 10, left: 5), child: Icon(Icons.arrow_forward, color: Colors.black)) + const Padding( padding: EdgeInsets.only(top: 10, left: 5), child: Icon(Icons.arrow_forward, color: Colors.black)) ]), Row(children: [ Tooltip( message: "back size", child: Container( - margin: EdgeInsets.only(top: 10), + margin: const EdgeInsets.only(top: 10), width: 150, height: 25, child: TextFormField( textAlign: TextAlign.center, initialValue: "${widget.dashboard.defaultBackWidth}", @@ -519,14 +518,14 @@ class FlowChartSelectedMenuState extends State { } }); }, - style: TextStyle(fontSize: 12), + style: const TextStyle(fontSize: 12), decoration: InputDecoration( fillColor: widget.dashboard.defaultDashWidth <= 0 ? widget.dashboard.midDashColor : Colors.white, filled: true, labelText: "back size", - labelStyle: TextStyle(fontSize: 10), - border: OutlineInputBorder(), - contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 5), + labelStyle: const TextStyle(fontSize: 10), + border: const OutlineInputBorder(), + contentPadding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), ), inputFormatters: [ NumberTextInputFormatter( @@ -543,12 +542,12 @@ class FlowChartSelectedMenuState extends State { ], keyboardType: TextInputType.number, ))), - Padding( padding: EdgeInsets.only(top: 10, left: 5), child: Icon(Icons.arrow_back, color: Colors.black)) + const Padding( padding: EdgeInsets.only(top: 10, left: 5), child: Icon(Icons.arrow_back, color: Colors.black)) ]) ])), widget.dashboard.arrowsSelected.isNotEmpty || widget.dashboard.elementSelected.isNotEmpty ? Container( width: 200, - decoration: BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [ Tooltip( message: "remove", child: InkWell( mouseCursor: SystemMouseCursors.click, @@ -559,13 +558,13 @@ class FlowChartSelectedMenuState extends State { } return element.isSelected; }, context); - Future.delayed(Duration(milliseconds: 100), () { + Future.delayed(const Duration(milliseconds: 100), () { widget.dashboard.flutterChartKey.currentState?.setState(() { }); }); - }, child: Container( margin: EdgeInsets.all(10), + }, child: Container( margin: const EdgeInsets.all(10), decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)), width: 200, height: 30, - child: Icon(Icons.delete_outline, color: Colors.black), + child: const Icon(Icons.delete_outline, color: Colors.black), )) ), Tooltip( message: "copy", @@ -573,15 +572,15 @@ class FlowChartSelectedMenuState extends State { onTap: () { for (var sel in widget.dashboard.elementSelected) { widget.dashboard.addElement(FlowElement.fromMap(widget.dashboard, sel.toMap()), context); - widget.dashboard.elements.last.position += Offset(50, 50); + widget.dashboard.elements.last.position += const Offset(50, 50); } - Future.delayed(Duration(milliseconds: 100), () { + Future.delayed( const Duration(milliseconds: 100), () { widget.dashboard.chartKey.currentState?.setState(() { }); }); - }, child: Container( margin: EdgeInsets.only(left: 10, right: 10, bottom: 10), + }, child: Container( margin: const EdgeInsets.only(left: 10, right: 10, bottom: 10), decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), border: Border.all(color: Colors.black, width: 1)), width: 200, height: 30, - child: Icon(Icons.copy, color: Colors.black), + child: const Icon(Icons.copy, color: Colors.black), )) ), ]) @@ -594,15 +593,15 @@ class FlowChartSelectedMenuState extends State { Container( // SHORTCUT width: 200, height: 50, decoration: BoxDecoration(color: widget.dashboard.midDashColor, - border: Border(bottom: BorderSide(color: Colors.grey, width: 1))), + border: const Border(bottom: BorderSide(color: Colors.grey, width: 1))), child: Row( children: [ Tooltip( message: "dashboard information", child: InkWell( onTap: () => setState(() {widget.isDashboardInfo = true; }), mouseCursor: SystemMouseCursors.click, child: Container( alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 10), + padding: const EdgeInsets.symmetric(vertical: 10), color: widget.isDashboardInfo ? Colors.grey : widget.dashboard.midDashColor, - width: 200 / 2, child: Icon(Icons.info, color: Colors.white)) + width: 200 / 2, child: const Icon(Icons.info, color: Colors.white)) ) ), Tooltip( @@ -610,9 +609,9 @@ class FlowChartSelectedMenuState extends State { child: InkWell( onTap: () => setState(() {widget.isDashboardInfo = false; }), mouseCursor: SystemMouseCursors.click, child: Container( alignment: Alignment.center, - padding: EdgeInsets.symmetric(vertical: 10), + padding: const EdgeInsets.symmetric(vertical: 10), color: !widget.isDashboardInfo ? Colors.grey : widget.dashboard.midDashColor, - width: 200 / 2, child: Icon(Icons.format_paint, color: Colors.white)), + width: 200 / 2, child: const Icon(Icons.format_paint, color: Colors.white)), ) ) ] @@ -620,7 +619,7 @@ class FlowChartSelectedMenuState extends State { ), widget.dashboard.error != null ? Container( width: 200, color: Colors.red, padding: EdgeInsets.all(10), child: Center( child: Text(widget.dashboard.error!, - style: TextStyle(color: Colors.white, fontSize: 15), textAlign: TextAlign.center))) : Container(), + style: const TextStyle(color: Colors.white, fontSize: 15), textAlign: TextAlign.center))) : Container(), w ]); } diff --git a/library/flutter_flow_chart/lib/src/ui/draw_arrow.dart b/library/flutter_flow_chart/lib/src/ui/draw_arrow.dart index c20a71b..cd1b1a7 100755 --- a/library/flutter_flow_chart/lib/src/ui/draw_arrow.dart +++ b/library/flutter_flow_chart/lib/src/ui/draw_arrow.dart @@ -744,8 +744,28 @@ class ArrowPainter extends CustomPainter { return _dashedPathProperties.path; } - - bool isLine(Offset position) { + bool isLine(Offset point) { + final metrics = path.computeMetrics(forceClosed: false); + for (final metric in metrics) { + final length = metric.length; + const steps = 100; + for(int i = 0; i <= steps; i++) { + final distance = length * i / steps; + final tangent = metric.getTangentForOffset(distance); + if (tangent != null) { + final position = tangent.position; + if ((position - point).distance <= 10) { + return true; + } + } + } + } + return false; + } +/* + bool isLine(Offset position, String name) { + position = Offset(position.dx, position.dy + 10); + print("${position.dx} ${position.dy}"); for (double i=-5; i < 5; i++) { for (double y=-5; y < 5; y++) { var pos = position + Offset(i, y); @@ -756,7 +776,7 @@ class ArrowPainter extends CustomPainter { } return false; } - +*/ @override bool? hitTest(Offset position) { /* graphkey?.currentState?.widget.isShowed = isLine(position);