From 4c0682d1c75e7abc0c32e0d9dffb2b9b12dfcc7d Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 14 Nov 2021 13:46:15 +0200 Subject: [PATCH 01/22] FBP-85. Continue working with expanded/collapsed subprocesses --- .../core/render/DefaultBpmnProcessRenderer.kt | 10 +++------- .../render/elements/shapes/ExpandableShapeNoIcon.kt | 13 ++++++++----- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt index 7d9905e17..8c5e7cedf 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt @@ -243,8 +243,8 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr is BpmnSubProcess -> NoIconShape(id, bpmn.id, shape, state, Colors.PROCESS_COLOR, Colors.ELEMENT_BORDER_COLOR, Colors.SUBPROCESS_TEXT_COLOR, areaType = AreaType.SHAPE_THAT_NESTS) is BpmnEventSubprocess -> NoIconShape(id, bpmn.id, shape, state, Colors.PROCESS_COLOR, Colors.ELEMENT_BORDER_COLOR, Colors.SUBPROCESS_TEXT_COLOR, areaType = AreaType.SHAPE_THAT_NESTS, borderStroke = DASHED_STROKE) is BpmnTransactionalSubProcess -> NoIconDoubleBorderShape(id, bpmn.id, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) - is BpmnCollapsedSubprocess -> ExpandableShapeNoIcon(id, bpmn.id, isCollapsed(bpmn.id, state), icons.plus, icons.minus, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) - is BpmnTransactionCollapsedSubprocess -> ExpandableShapeNoIcon(id, bpmn.id, isCollapsed(bpmn.id, state), icons.plus, icons.minus, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) + is BpmnCollapsedSubprocess -> ExpandableShapeNoIcon(id, bpmn.id, icons.plus, icons.minus, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) + is BpmnTransactionCollapsedSubprocess -> ExpandableShapeNoIcon(id, bpmn.id, icons.plus, icons.minus, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) is BpmnCallActivity -> NoIconShape(id, bpmn.id, shape, state) is BpmnAdHocSubProcess -> BottomMiddleIconShape(id, bpmn.id, icons.tilde, shape, state, areaType = AreaType.SHAPE_THAT_NESTS) is BpmnExclusiveGateway -> IconShape(id, bpmn.id, icons.exclusiveGateway, shape, state) @@ -269,10 +269,6 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr } } - private fun isCollapsed(id: BpmnElementId, state: () -> RenderState): Boolean { - return !(state().currentState.elemUiOnlyPropertiesByStaticElementId[id]?.get(UiOnlyPropertyType.EXPANDED)?.value as Boolean? ?: false) - } - private fun drawSelectionRect(state: RenderContext) { state.interactionContext.dragSelectionRect?.let { val rect = it.toRect() @@ -412,4 +408,4 @@ data class TreeState ( internal val version: Long, ) { internal lateinit var domRoot: BaseBpmnRenderElement -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index c5efb872d..9b58fdac4 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -19,7 +19,6 @@ import javax.swing.Icon class ExpandableShapeNoIcon( elementId: DiagramElementId, bpmnElementId: BpmnElementId, - private val collapsed: Boolean, plusIcon: Icon, minusIcon: Icon, shape: ShapeElement, @@ -33,8 +32,8 @@ class ExpandableShapeNoIcon( private val expandButton = ButtonWithAnchor( DiagramElementId("EXPAND:" + shape.id.id), Point2D.Float((shape.bounds().first.x + shape.bounds().second.x) / 2.0f, shape.bounds().second.y), - if (collapsed) plusIcon else minusIcon, - { mutableListOf(BooleanUiOnlyValueUpdatedEvent(bpmnElementId, UiOnlyPropertyType.EXPANDED, !collapsed)) }, + if (isCollapsed()) plusIcon else minusIcon, + { mutableListOf(BooleanUiOnlyValueUpdatedEvent(bpmnElementId, UiOnlyPropertyType.EXPANDED, isCollapsed())) }, state ) @@ -57,7 +56,7 @@ class ExpandableShapeNoIcon( } override fun createIfNeededExpandViewTransform() { - if (this.collapsed) { + if (isCollapsed()) { return } @@ -72,4 +71,8 @@ class ExpandableShapeNoIcon( )) super.createIfNeededExpandViewTransform() } -} \ No newline at end of file + + private fun isCollapsed(): Boolean { + return !(state().currentState.elemUiOnlyPropertiesByStaticElementId[bpmnElementId]?.get(UiOnlyPropertyType.EXPANDED)?.value as Boolean? ?: false) + } +} From faa751a4a19bd17ecfc5c9f9452e85ed06b1fa28 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 14 Nov 2021 14:39:20 +0200 Subject: [PATCH 02/22] FBP-85. Restore status quo of subprocesses as it was before state extraction --- .../core/render/DefaultBpmnProcessRenderer.kt | 4 ++-- .../plugin/core/render/RenderContext.kt | 19 ++++++++++++------- .../elements/BaseDiagramRenderElement.kt | 5 +++-- .../elements/edges/BaseEdgeRenderElement.kt | 4 ++-- .../elements/planes/PlaneRenderElement.kt | 5 ++--- .../elements/shapes/ExpandableShapeNoIcon.kt | 7 ++----- .../shapes/ResizeableShapeRenderElement.kt | 11 +++++------ .../elements/shapes/ShapeRenderElement.kt | 4 ++-- 8 files changed, 30 insertions(+), 29 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt index 8c5e7cedf..c49606b67 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt @@ -167,7 +167,7 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr } private fun createRootProcessElem(state: () -> RenderState, elements: MutableList, elementsById: MutableMap): BaseBpmnRenderElement { - val processElem = PlaneRenderElement(state().currentState.processDiagramId(), state().currentState.processId, state, mutableListOf()) + val processElem = PlaneRenderElement(state().currentState.processDiagramId(), state().currentState.processId, state) elements += processElem elementsById[state().currentState.processId] = processElem return processElem @@ -197,7 +197,7 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr elementsById.forEach { (id, renderElem) -> val elem = state().currentState.elementByBpmnId[id] elem?.parent?.let {elementsById[it]}?.let { if (it is BaseBpmnRenderElement) it else null }?.let { parent -> - parent.children.add(renderElem) + parent.innerElements.add(renderElem) parent.let { renderElem.parents.add(it) } } } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/RenderContext.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/RenderContext.kt index bd9d49d3d..76cde1924 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/RenderContext.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/RenderContext.kt @@ -9,10 +9,15 @@ import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.state.CurrentStateProvider data class RenderContext( - val project: Project, - val canvas: CanvasPainter, - val selectedIds: Set, - val interactionContext: ElementInteractionContext, - val stateProvider: CurrentStateProvider, - var cachedDom: TreeState? = null -) \ No newline at end of file + val project: Project, + val canvas: CanvasPainter, + val selectedIds: Set, + val interactionContext: ElementInteractionContext, + val stateProvider: CurrentStateProvider, + var cachedDom: TreeState? = null +) { + // Just a FIXME for Kotlin debugger not to get to OutOfMemory + override fun toString(): String { + return "" + } +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index 1ef61ebcb..0ee36e40d 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -31,7 +31,8 @@ abstract class BaseDiagramRenderElement( var isVisible: Boolean? = null abstract val areaType: AreaType - open val children: MutableList = mutableListOf() + val innerElements: MutableList = mutableListOf() + open val children: List = innerElements /** * Parents in the order: direct parent, parent of direct parent... @@ -283,4 +284,4 @@ abstract class BaseDiagramRenderElement( currentOnScreenRect(state().ctx.canvas.camera) children.forEach {it.currentOnScreenRect(state().ctx.canvas.camera)} } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt index 8497c381e..823bd8e1a 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt @@ -32,7 +32,7 @@ abstract class BaseEdgeRenderElement( private val anchors = computeAnchors() - override val children: MutableList = anchors as MutableList + override val children: List = anchors as MutableList + innerElements val edgeElem: EdgeWithIdentifiableWaypoints get() = edge @@ -172,4 +172,4 @@ abstract class BaseEdgeRenderElement( else -> null } } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt index 653cc6072..6d4a7e2ee 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt @@ -19,8 +19,7 @@ import java.awt.geom.Rectangle2D class PlaneRenderElement( elementId: DiagramElementId, bpmnElementId: BpmnElementId, - state: () -> RenderState, - override val children: MutableList = mutableListOf() + state: () -> RenderState ): BaseBpmnRenderElement(elementId, bpmnElementId, state) { override val areaType: AreaType @@ -105,4 +104,4 @@ private class InfiniteShape: Area() { override fun getBounds(): Rectangle { return Rectangle() } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index 9b58fdac4..0e6190569 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -37,13 +37,10 @@ class ExpandableShapeNoIcon( state ) - override val children: MutableList = ( - super.children + expandButton - - ).toMutableList() + override val children: List + get() = ((if (!isCollapsed()) innerElements else mutableListOf()) + actions + expandButton) override fun doRender(ctx: RenderContext, shapeCtx: ShapeCtx): Map { - val area = ctx.canvas.drawRoundedRect( shapeCtx.shape, shapeCtx.name, diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt index 3efff1836..60a5a2ea1 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt @@ -31,11 +31,10 @@ abstract class ResizeableShapeRenderElement( ShapeResizeAnchorBottom(DiagramElementId("BOTTOM:" + shape.id.id), elementId, Point2D.Float(shape.bounds().second.x, shape.bounds().second.y), { doComputeLocationChangesBasedOnTransformationWithCascade() }, state) ) - override val children: MutableList = mutableListOf( - anchors.first, - anchors.second, - edgeExtractionAnchor - ) + protected val actions = mutableListOf(anchors.first, anchors.second, edgeExtractionAnchor) + + override val children: List + get() = actions + innerElements override fun drawActionsRight(x: Float, y: Float): Map { val spaceCoeff = 1.5f @@ -131,4 +130,4 @@ abstract class ResizeableShapeRenderElement( } } } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index e46309097..cc2b7bcf1 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -46,7 +46,7 @@ abstract class ShapeRenderElement( cascadeTo = computeCascadables() } - override val children: MutableList = mutableListOf(edgeExtractionAnchor) + override val children: List = mutableListOf(edgeExtractionAnchor) + innerElements val shapeElem: ShapeElement get() = shape @@ -390,4 +390,4 @@ abstract class ShapeRenderElement( fun cartesianProduct(first: Collection, second: Collection): Sequence> { return first.asSequence().flatMap { lhsElem -> second.asSequence().map { rhsElem -> lhsElem to rhsElem } } } -} \ No newline at end of file +} From cc92f13da1b6a6251e87063af8aead31dc5677a2 Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 15 Nov 2021 10:11:07 +0200 Subject: [PATCH 03/22] FBP-85. Limit ExpandViewTransform propagation to elements of same level only --- .../elements/anchors/CircleAnchorElement.kt | 5 ++-- .../elements/anchors/EdgeExtractionAnchor.kt | 3 +- .../anchors/ShapeResizeAnchorBottom.kt | 3 +- .../elements/anchors/ShapeResizeAnchorTop.kt | 3 +- .../elements/buttons/ButtonWithAnchor.kt | 5 ++-- .../elements/shapes/ExpandableShapeNoIcon.kt | 1 + .../elements/shapes/ShapeRenderElement.kt | 2 +- .../elements/viewtransform/ViewTransform.kt | 28 ++++++++++++++----- 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt index 477fea0d0..376b7bd4d 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt @@ -39,7 +39,8 @@ abstract class CircleAnchorElement( 2.0f * radius, 2.0f * radius ), - AreaType.POINT + AreaType.POINT, + parents.map { it.elementId }.toSet() ) ) } @@ -95,4 +96,4 @@ abstract class CircleAnchorElement( protected open fun isRenderable(): Boolean { return true } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt index b50d64651..1649e2f94 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt @@ -39,6 +39,7 @@ class EdgeExtractionAnchor( imageHeight ), AreaType.POINT, + parents.map { it.elementId }.toSet(), parent ) ) @@ -78,4 +79,4 @@ class EdgeExtractionAnchor( override fun waypointAnchors(camera: Camera): MutableSet { return mutableSetOf(Anchor(transformedLocation)) } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt index 8703e5e47..5cf281229 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt @@ -31,6 +31,7 @@ class ShapeResizeAnchorBottom( icon.iconHeight.toFloat() ), AreaType.SHAPE, + parents.map { it.elementId }.toSet(), parent ) ) @@ -62,4 +63,4 @@ class ShapeResizeAnchorBottom( override fun zIndex(): Int { return ICON_Z_INDEX } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt index ad2ce6833..024c8c7af 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt @@ -36,6 +36,7 @@ class ShapeResizeAnchorTop( height ), AreaType.SHAPE, + parents.map { it.elementId }.toSet(), parent ) ) @@ -67,4 +68,4 @@ class ShapeResizeAnchorTop( override fun zIndex(): Int { return ICON_Z_INDEX } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt index 58ae16af6..75a112ef2 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt @@ -41,7 +41,8 @@ class ButtonWithAnchor( imageWidth, imageHeight ), - AreaType.POINT + AreaType.POINT, + parents.map { it.elementId }.toSet() ) ) } @@ -73,4 +74,4 @@ class ButtonWithAnchor( override fun waypointAnchors(camera: Camera): MutableSet { return mutableSetOf(Anchor(transformedLocation)) } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index 0e6190569..a9cb6e62c 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -59,6 +59,7 @@ class ExpandableShapeNoIcon( state().baseTransform.addPreTransform(ExpandViewTransform( elementId, + parents.firstOrNull()?.elementId ?: DiagramElementId(""), shape.rectBounds(), shape.rectBounds().centerX.toFloat(), shape.rectBounds().centerY.toFloat(), diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index cc2b7bcf1..8c7250bd6 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -182,7 +182,7 @@ abstract class ShapeRenderElement( } override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { - return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE)) + return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE, parents.map { it.elementId }.toSet())) } override fun currentRect(): Rectangle2D.Float { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index efe4e8f29..75d621fe0 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -8,7 +8,7 @@ import java.awt.geom.Rectangle2D import kotlin.math.abs import kotlin.random.Random.Default.nextFloat -data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val attachedTo: DiagramElementId? = null) +data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: Set, val attachedTo: DiagramElementId? = null) data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null) interface PreTransformable { @@ -114,6 +114,7 @@ data class ResizeViewTransform( } class ExpandViewTransform( + private val expandOnElementLevel: DiagramElementId, private val expandedElementId: DiagramElementId, private val shape: Rectangle2D.Float, private val cx: Float, @@ -140,11 +141,9 @@ class ExpandViewTransform( val center = transformPoint(Point2D.Float(transformed.x + halfWidth, transformed.y + halfHeight)) - if (rectTransformationIntrospection.type == AreaType.POINT) { - val quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] - if (null != quirkFound) { - return Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) - } + val managedTransform = transformManagedByParent(transformed, rect, rectTransformationIntrospection) + if (null != managedTransform) { + return managedTransform } if (elementId == expandedElementId) { @@ -157,6 +156,21 @@ class ExpandViewTransform( return Rectangle2D.Float(center.x - halfWidth, center.y - halfHeight, rect.width, rect.height) } + private fun transformManagedByParent(transformed: Rectangle2D.Float, rect: Rectangle2D.Float, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float? { + var quirkFound: RectangleQuirk? = null + if (rectTransformationIntrospection.type == AreaType.POINT) { + quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] + } else if (!rectTransformationIntrospection.parentElements.contains(expandOnElementLevel)) { + quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.first() + } + + if (null != quirkFound) { + return Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) + } else { + return null + } + } + private fun fillRectangleQuirkIfNeeded(rectTransformationIntrospection: RectangleTransformationIntrospection, elementId: DiagramElementId, rect: Rectangle2D.Float, center: Point2D.Float, transformed: Rectangle2D.Float, halfWidth: Float, halfHeight: Float) { if (rectTransformationIntrospection.type.nests || rectTransformationIntrospection.type == AreaType.SHAPE) { fillRectangleQuirk(elementId, rect, Point2D.Float(center.x - transformed.x - halfWidth, center.y - transformed.y - halfHeight)) @@ -352,4 +366,4 @@ class ViewTransformInverter { } private data class PointWithResidual(val point: Point2D.Float, val residual: Float) -} \ No newline at end of file +} From 5827db093c44b09a57c50505eda1293d3e51f649 Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 15 Nov 2021 10:31:57 +0200 Subject: [PATCH 04/22] FBP-85. Fixed wrong ctor arguments order --- .../core/render/elements/viewtransform/ViewTransform.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 75d621fe0..6b09d0860 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -114,8 +114,8 @@ data class ResizeViewTransform( } class ExpandViewTransform( - private val expandOnElementLevel: DiagramElementId, private val expandedElementId: DiagramElementId, + private val expandOnElementLevel: DiagramElementId, private val shape: Rectangle2D.Float, private val cx: Float, private val cy: Float, @@ -164,10 +164,10 @@ class ExpandViewTransform( quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.first() } - if (null != quirkFound) { - return Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) + return if (null != quirkFound) { + Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) } else { - return null + null } } From 86f4029357302e40c0557214ccd2fb84956593f8 Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 15 Nov 2021 10:41:43 +0200 Subject: [PATCH 05/22] FBP-85. Fixed exception --- .../plugin/core/render/elements/viewtransform/ViewTransform.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 6b09d0860..ae6105c68 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -161,7 +161,7 @@ class ExpandViewTransform( if (rectTransformationIntrospection.type == AreaType.POINT) { quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] } else if (!rectTransformationIntrospection.parentElements.contains(expandOnElementLevel)) { - quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.first() + quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() } return if (null != quirkFound) { From 06c0f956f8003777391c6ea57f8b9ba20743fa98 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 12:58:02 +0200 Subject: [PATCH 06/22] FBP-85. Improve anchor selection --- .../elements/shapes/ExpandableShapeNoIcon.kt | 23 +++++++++++++++++++ .../elements/viewtransform/ViewTransform.kt | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index a9cb6e62c..cae632025 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -8,7 +8,9 @@ import com.valb3r.bpmn.intellij.plugin.core.events.BooleanUiOnlyValueUpdatedEven import com.valb3r.bpmn.intellij.plugin.core.properties.uionly.UiOnlyPropertyType import com.valb3r.bpmn.intellij.plugin.core.render.AreaType import com.valb3r.bpmn.intellij.plugin.core.render.AreaWithZindex +import com.valb3r.bpmn.intellij.plugin.core.render.Camera import com.valb3r.bpmn.intellij.plugin.core.render.RenderContext +import com.valb3r.bpmn.intellij.plugin.core.render.elements.Anchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.BaseDiagramRenderElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.elements.buttons.ButtonWithAnchor @@ -70,6 +72,27 @@ class ExpandableShapeNoIcon( super.createIfNeededExpandViewTransform() } + // Simplifying anchor model as inversion of view transform of intermediate anchors is not stable + override fun waypointAnchors(camera: Camera): MutableSet { + val rect = currentOnScreenRect(camera) + val halfWidth = rect.width / 2.0f + val halfHeight = rect.height / 2.0f + + val cx = rect.x + rect.width / 2.0f + val cy = rect.y + rect.height / 2.0f + return mutableSetOf( + Anchor(Point2D.Float(cx - halfWidth, cy), 10), + Anchor(Point2D.Float(cx + halfWidth, cy), 10), + Anchor(Point2D.Float(cx, cy - halfHeight), 10), + Anchor(Point2D.Float(cx, cy + halfHeight), 10), + ) + } + + // Central anchor does not make sense for this kind of shape + override fun shapeAnchors(camera: Camera): MutableSet { + return mutableSetOf() + } + private fun isCollapsed(): Boolean { return !(state().currentState.elemUiOnlyPropertiesByStaticElementId[bpmnElementId]?.get(UiOnlyPropertyType.EXPANDED)?.value as Boolean? ?: false) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index ae6105c68..a3c0b647b 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -325,7 +325,7 @@ class ViewTransformInverter { minimizeGradientDescent(elementId, target, guess, batch, introspection) } - return result.minBy { it: PointWithResidual -> it.residual }!!.point + return result.minBy { it.residual }!!.point } private fun minimizeGradientDescent(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch, introspection: PointTransformationIntrospection): PointWithResidual { From b4707dcd13d7b20d51a11811de59068bf35c0c7f Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 13:47:48 +0200 Subject: [PATCH 07/22] FBP-85. Improve attaching to collapsed subprocess of elements --- .../render/elements/BaseDiagramRenderElement.kt | 3 ++- .../elements/shapes/ShapeRenderElement.kt | 17 ++++++++++++----- .../elements/viewtransform/ViewTransform.kt | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index 0ee36e40d..8c701cbb4 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -122,6 +122,8 @@ abstract class BaseDiagramRenderElement( return result } + abstract fun currentRect(): Rectangle2D.Float + protected open fun rootAndEnumerateChildrenRecursively(root: BaseDiagramRenderElement) : List { val result = mutableListOf() result += root @@ -220,7 +222,6 @@ abstract class BaseDiagramRenderElement( abstract fun doResizeWithoutChildren(dw: Float, dh: Float) abstract fun doResizeEndWithoutChildren(dw: Float, dh: Float): MutableList - protected abstract fun currentRect(): Rectangle2D.Float protected abstract fun currentOnScreenRect(camera: Camera): Rectangle2D.Float protected abstract fun waypointAnchors(camera: Camera): MutableSet diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index 8c7250bd6..2a9b7b187 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -4,10 +4,7 @@ import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.BpmnElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.elements.BpmnSequenceFlow import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.elements.WithParentId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.DiagramElementId -import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.BoundsElement -import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.EdgeElement -import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.ShapeElement -import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.WaypointElement +import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.* import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.LocationUpdateWithId import com.valb3r.bpmn.intellij.plugin.bpmn.api.info.Property @@ -22,6 +19,7 @@ import com.valb3r.bpmn.intellij.plugin.core.render.* import com.valb3r.bpmn.intellij.plugin.core.render.elements.* import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.EdgeExtractionAnchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.internal.CascadeTranslationOrChangesToWaypoint +import com.valb3r.bpmn.intellij.plugin.core.render.elements.planes.PlaneRenderElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.NullViewTransform import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.RectangleTransformationIntrospection import com.valb3r.bpmn.intellij.plugin.core.state.CurrentState @@ -296,13 +294,14 @@ abstract class ShapeRenderElement( } val sourceElem = state().currentState.elementByBpmnId[bpmnElementId] ?: return mutableListOf() + val targetElem = state().currentState.diagramByElementId[droppedOn]?.let { state().elemMap[it] } val newSequenceBpmn = newElementsFactory(state().ctx.project).newOutgoingSequence(sourceElem.element) val anchors = findSequenceAnchors(targetArea) ?: return mutableListOf() val notYetExistingDiagramId = DiagramElementId("") val sourceBounds = shape.rectBounds() val firstAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.first, Point2D.Float(sourceBounds.centerX.toFloat(), sourceBounds.centerY.toFloat())) - val secondAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.second, anchors.second) + val secondAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.second, initialGuess(targetElem, anchors.second)) val newSequenceDiagram = newElementsFactory(state().ctx.project).newDiagramObject(EdgeElement::class, newSequenceBpmn) .copy(waypoint = listOf( WaypointElement(firstAnchorCompensated.x, firstAnchorCompensated.y), @@ -323,6 +322,14 @@ abstract class ShapeRenderElement( ) } + private fun initialGuess(targetElem: BaseDiagramRenderElement?, pos: Point2D.Float): Point2D.Float { + if (targetElem is PlaneRenderElement || null == targetElem) { + return pos + } + + return Point2D.Float(targetElem.currentRect().centerX.toFloat(), targetElem.currentRect().centerY.toFloat()) + } + private fun findSequenceAnchors(droppedOnTarget: AreaWithZindex): Pair? { val allStartWaypointsAnchors = waypointAnchors(state().ctx.canvas.camera) val allEndWaypointsAnchors = droppedOnTarget.anchorsForWaypoints diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index a3c0b647b..ad91c4a08 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -292,7 +292,7 @@ class ViewTransformInverter { private val initialStepSize = 1.0f private val successMultiplier = 2.0f private val failMultiplier = 10.0f - private val diffStep = 1.0f + private val diffStep = 0.1f private val epsilon = 1.0f private val maxIter = 10 private val randomInitializationGuesses = 10 From ceb9e4b7d82343b43ebee8c7575f5bdb15a4f5e0 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 14:01:42 +0200 Subject: [PATCH 08/22] FBP-85. Improve attaching to collapsed subprocess of elements --- .../core/render/elements/viewtransform/ViewTransform.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index ad91c4a08..4e9837a01 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -315,13 +315,13 @@ class ViewTransformInverter { * shape changes are ignored so far */ private fun invert(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch, introspection: PointTransformationIntrospection): Point2D.Float { - val range = 1..randomInitializationGuesses + val range = 0..randomInitializationGuesses fun randomFromAreaRange(): Float { return (nextFloat() * 2.0f - 1.0f) * randomInitializationAreaSpan } val result = range.map { - val guess = Point2D.Float(initialGuess.x - randomFromAreaRange(), initialGuess.y - randomFromAreaRange()) + val guess = if (0 != it) Point2D.Float(initialGuess.x - randomFromAreaRange(), initialGuess.y - randomFromAreaRange()) else initialGuess minimizeGradientDescent(elementId, target, guess, batch, introspection) } From 679cbfae13e5f18beec6d3b82c7c1bdbe8eb6aee Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 14:41:58 +0200 Subject: [PATCH 09/22] FBP-85. Handle element quirks when drawing new sequence --- .../core/render/elements/BaseDiagramRenderElement.kt | 4 ++-- .../core/render/elements/shapes/ShapeRenderElement.kt | 4 ++-- .../core/render/elements/viewtransform/ViewTransform.kt | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index 8c701cbb4..e55a43076 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -255,10 +255,10 @@ abstract class BaseDiagramRenderElement( return Point2D.Float(inverted.x - rect.x, inverted.y - rect.y) } - protected fun compensateExpansionViewOnLocation(targetElement: DiagramElementId, location: Point2D.Float, initialGuess: Point2D.Float): Point2D.Float { + protected fun compensateExpansionViewOnLocation(elementToCompensate: DiagramElementId, location: Point2D.Float, initialGuess: Point2D.Float, target: DiagramElementId?): Point2D.Float { val batch = findExpansionViewTransformationsToCompensate() - val inverted = ViewTransformInverter().invert(targetElement, location, initialGuess, batch) + val inverted = ViewTransformInverter().invert(elementToCompensate, location, initialGuess, batch, PointTransformationIntrospection(target)) return Point2D.Float(inverted.x, inverted.y) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index 2a9b7b187..425f999bf 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -300,8 +300,8 @@ abstract class ShapeRenderElement( val anchors = findSequenceAnchors(targetArea) ?: return mutableListOf() val notYetExistingDiagramId = DiagramElementId("") val sourceBounds = shape.rectBounds() - val firstAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.first, Point2D.Float(sourceBounds.centerX.toFloat(), sourceBounds.centerY.toFloat())) - val secondAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.second, initialGuess(targetElem, anchors.second)) + val firstAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.first, Point2D.Float(sourceBounds.centerX.toFloat(), sourceBounds.centerY.toFloat()), elementId) + val secondAnchorCompensated = compensateExpansionViewOnLocation(notYetExistingDiagramId, anchors.second, initialGuess(targetElem, anchors.second), targetElem?.elementId) val newSequenceDiagram = newElementsFactory(state().ctx.project).newDiagramObject(EdgeElement::class, newSequenceBpmn) .copy(waypoint = listOf( WaypointElement(firstAnchorCompensated.x, firstAnchorCompensated.y), diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 4e9837a01..f5a941868 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -216,7 +216,7 @@ class ExpandViewTransform( return when { abs(point.x - cx) < EPSILON && abs(point.y - cy) < EPSILON -> point - // rectangle edges: + // rectangle forming points: // top-left abs(point.x - shape.x) < EPSILON && abs(point.y - shape.y) < EPSILON -> Point2D.Float(point.x - dx, point.y - dy) // bottom-left @@ -302,19 +302,19 @@ class ViewTransformInverter { * Minimizes (rect.x - transform(return.x)) ^ 2 + (rect.y - transform(return.y)) ^ 2 metric * shape changes are ignored so far */ - fun invert(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch): Point2D.Float { + fun invert(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch, introspection: PointTransformationIntrospection? = null): Point2D.Float { if (batch.isEmpty()) { return target } - return invert(elementId, target, initialGuess, batch, PointTransformationIntrospection()) + return doInvert(elementId, target, initialGuess, batch, introspection ?: PointTransformationIntrospection()) } /** * Minimizes (rect.x - transform(return.x)) ^ 2 + (rect.y - transform(return.y)) ^ 2 metric * shape changes are ignored so far */ - private fun invert(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch, introspection: PointTransformationIntrospection): Point2D.Float { + private fun doInvert(elementId: DiagramElementId, target: Point2D.Float, initialGuess: Point2D.Float, batch: ViewTransformBatch, introspection: PointTransformationIntrospection): Point2D.Float { val range = 0..randomInitializationGuesses fun randomFromAreaRange(): Float { return (nextFloat() * 2.0f - 1.0f) * randomInitializationAreaSpan From 9e82d7e3ececd5b568fda3858412fe03395a9584 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 14:51:01 +0200 Subject: [PATCH 10/22] FBP-85. Use DCEVM to runIde --- activiti-intellij-plugin/build.gradle | 6 +++++- build.gradle | 5 +++-- camunda-intellij-plugin/build.gradle | 6 +++++- flowable-intellij-plugin/build.gradle | 6 +++++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/activiti-intellij-plugin/build.gradle b/activiti-intellij-plugin/build.gradle index 742687344..d9bf5ed34 100644 --- a/activiti-intellij-plugin/build.gradle +++ b/activiti-intellij-plugin/build.gradle @@ -42,6 +42,10 @@ intellij { plugins = intellijPlatformPlugins } +runIde { + jbrVersion = runIdeJbrVersion +} + publishPlugin { token = intellijPublishToken } @@ -82,4 +86,4 @@ jacocoTestReport { xml.enabled true csv.enabled false } -} \ No newline at end of file +} diff --git a/build.gradle b/build.gradle index f13279474..c82a23b24 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.jetbrains.intellij' version '1.1.6' + id 'org.jetbrains.intellij' version '1.3.0' id 'org.jetbrains.kotlin.jvm' version '1.5.30' id 'org.jetbrains.kotlin.kapt' version '1.5.30' } @@ -8,6 +8,7 @@ plugins { ext { intellijPlatform = 'IU-2019.3' intellijPlatformPlugins = ['java', 'DatabaseTools'] // DatabaseTools is for BPMN process 'debugging' + runIdeJbrVersion = 'jbr_dcevm-11_0_13b1751.16' kotlinStdlib = '1.5.30' kotlinApiVersion = '1.3' // It must be same as JB supplied Kotlin STDLIB i.e. for 2018 = 1.3. See https://youtrack.jetbrains.com/issue/KT-37435 @@ -48,4 +49,4 @@ subprojects { tasks.withType(Test) { useJUnitPlatform() } -} \ No newline at end of file +} diff --git a/camunda-intellij-plugin/build.gradle b/camunda-intellij-plugin/build.gradle index 2f2849478..f27b9f8ad 100644 --- a/camunda-intellij-plugin/build.gradle +++ b/camunda-intellij-plugin/build.gradle @@ -42,6 +42,10 @@ intellij { plugins = intellijPlatformPlugins } +runIde { + jbrVersion = runIdeJbrVersion +} + publishPlugin { token = intellijPublishToken } @@ -82,4 +86,4 @@ jacocoTestReport { xml.enabled true csv.enabled false } -} \ No newline at end of file +} diff --git a/flowable-intellij-plugin/build.gradle b/flowable-intellij-plugin/build.gradle index 227c417f2..fe7c565ff 100644 --- a/flowable-intellij-plugin/build.gradle +++ b/flowable-intellij-plugin/build.gradle @@ -42,6 +42,10 @@ intellij { plugins = intellijPlatformPlugins } +runIde { + jbrVersion = runIdeJbrVersion +} + publishPlugin { token = intellijPublishToken } @@ -82,4 +86,4 @@ jacocoTestReport { xml.enabled true csv.enabled false } -} \ No newline at end of file +} From 704bce1df59be7551689f060adfe1030bcb0bc22 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 15:08:29 +0200 Subject: [PATCH 11/22] FBP-85. Correctly select anchors in case when quirks are active --- .../elements/viewtransform/ViewTransform.kt | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index f5a941868..4a5661277 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -5,11 +5,13 @@ import com.valb3r.bpmn.intellij.plugin.core.render.AreaType import com.valb3r.bpmn.intellij.plugin.core.render.elements.EPSILON import java.awt.geom.Point2D import java.awt.geom.Rectangle2D +import java.lang.Math.pow import kotlin.math.abs +import kotlin.math.pow import kotlin.random.Random.Default.nextFloat data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: Set, val attachedTo: DiagramElementId? = null) -data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null) +data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val selectCloseQuirkWithin: Float? = null) interface PreTransformable { fun preTransform(elementId: DiagramElementId, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float @@ -203,7 +205,15 @@ class ExpandViewTransform( return transformPoint(transformed) } - val quirkFound = quirkForRectangles[introspection.attachedTo] + var quirkFound = quirkForRectangles[introspection.attachedTo] + if (null == quirkFound && null != introspection.selectCloseQuirkWithin) { + fun quirkDistance(it: RectangleQuirk) = (point.x - it.originalRectangle2D.x).pow(2) + (point.y - it.originalRectangle2D.y).pow(2) + val bestQuirk = quirkForRectangles.values.minBy { quirkDistance(it) } + if (null != bestQuirk && (quirkDistance(bestQuirk) < introspection.selectCloseQuirkWithin)) { + quirkFound = bestQuirk + } + } + if (null != quirkFound) { return Point2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y) } @@ -297,6 +307,7 @@ class ViewTransformInverter { private val maxIter = 10 private val randomInitializationGuesses = 10 private val randomInitializationAreaSpan = 100.0f + private val minQuirkDistSq = 100.0f /** * Minimizes (rect.x - transform(return.x)) ^ 2 + (rect.y - transform(return.y)) ^ 2 metric @@ -322,7 +333,7 @@ class ViewTransformInverter { val result = range.map { val guess = if (0 != it) Point2D.Float(initialGuess.x - randomFromAreaRange(), initialGuess.y - randomFromAreaRange()) else initialGuess - minimizeGradientDescent(elementId, target, guess, batch, introspection) + minimizeGradientDescent(elementId, target, guess, batch, introspection.copy(selectCloseQuirkWithin = minQuirkDistSq)) } return result.minBy { it.residual }!!.point From aaa7bab96296e830988ba50f2a70c1cf6d91f322 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 17:51:56 +0200 Subject: [PATCH 12/22] FBP-85. Fixed internal diagram elements affected by view transform --- .../plugin/core/render/elements/anchors/AnchorElement.kt | 2 +- .../core/render/elements/anchors/CircleAnchorElement.kt | 2 +- .../core/render/elements/anchors/EdgeExtractionAnchor.kt | 2 +- .../render/elements/anchors/ShapeResizeAnchorBottom.kt | 2 +- .../core/render/elements/anchors/ShapeResizeAnchorTop.kt | 2 +- .../core/render/elements/buttons/ButtonWithAnchor.kt | 2 +- .../core/render/elements/shapes/ShapeRenderElement.kt | 2 +- .../core/render/elements/viewtransform/ViewTransform.kt | 8 ++++++-- 8 files changed, 13 insertions(+), 9 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt index 480bec466..fe89a12c9 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt @@ -25,7 +25,7 @@ abstract class AnchorElement( get() = currentLocation val transformedLocation: Point2D.Float - get() = state().viewTransform(elementId).transform(elementId, currentLocation, PointTransformationIntrospection(attachedTo)) + get() = state().viewTransform(elementId).transform(elementId, currentLocation, PointTransformationIntrospection(attachedTo, parents.flatMap { it.parents }.map { it.elementId })) override fun drawActionsRight(x: Float, y: Float): Map { // NOP diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt index 376b7bd4d..66a237ff3 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt @@ -40,7 +40,7 @@ abstract class CircleAnchorElement( 2.0f * radius ), AreaType.POINT, - parents.map { it.elementId }.toSet() + parents.map { it.elementId } ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt index 1649e2f94..690ef5595 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt @@ -39,7 +39,7 @@ class EdgeExtractionAnchor( imageHeight ), AreaType.POINT, - parents.map { it.elementId }.toSet(), + parents.map { it.elementId }, parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt index 5cf281229..6076e788c 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt @@ -31,7 +31,7 @@ class ShapeResizeAnchorBottom( icon.iconHeight.toFloat() ), AreaType.SHAPE, - parents.map { it.elementId }.toSet(), + parents.map { it.elementId }, parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt index 024c8c7af..1a2dd6cff 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt @@ -36,7 +36,7 @@ class ShapeResizeAnchorTop( height ), AreaType.SHAPE, - parents.map { it.elementId }.toSet(), + parents.map { it.elementId }, parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt index 75a112ef2..0f0ebcddb 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt @@ -42,7 +42,7 @@ class ButtonWithAnchor( imageHeight ), AreaType.POINT, - parents.map { it.elementId }.toSet() + parents.map { it.elementId } ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index 425f999bf..e9f2fd73d 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -180,7 +180,7 @@ abstract class ShapeRenderElement( } override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { - return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE, parents.map { it.elementId }.toSet())) + return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE, parents.map { it.elementId })) } override fun currentRect(): Rectangle2D.Float { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 4a5661277..992e96b97 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -10,8 +10,8 @@ import kotlin.math.abs import kotlin.math.pow import kotlin.random.Random.Default.nextFloat -data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: Set, val attachedTo: DiagramElementId? = null) -data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val selectCloseQuirkWithin: Float? = null) +data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: List, val attachedTo: DiagramElementId? = null) +data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val parentsOfParentElements: List = emptyList(), val selectCloseQuirkWithin: Float? = null) interface PreTransformable { fun preTransform(elementId: DiagramElementId, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float @@ -206,6 +206,10 @@ class ExpandViewTransform( } var quirkFound = quirkForRectangles[introspection.attachedTo] + // Managed quirk + if (null == quirkFound) { + quirkFound = introspection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() + } if (null == quirkFound && null != introspection.selectCloseQuirkWithin) { fun quirkDistance(it: RectangleQuirk) = (point.x - it.originalRectangle2D.x).pow(2) + (point.y - it.originalRectangle2D.y).pow(2) val bestQuirk = quirkForRectangles.values.minBy { quirkDistance(it) } From d46dc49256cee1a785bcbcd528e1239242c61f38 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 20:14:22 +0200 Subject: [PATCH 13/22] FBP-85. Register parent of parents for rectangular elements too --- .../core/render/elements/anchors/CircleAnchorElement.kt | 3 ++- .../core/render/elements/anchors/EdgeExtractionAnchor.kt | 3 ++- .../core/render/elements/anchors/ShapeResizeAnchorBottom.kt | 3 ++- .../core/render/elements/anchors/ShapeResizeAnchorTop.kt | 3 ++- .../plugin/core/render/elements/buttons/ButtonWithAnchor.kt | 3 ++- .../core/render/elements/viewtransform/ViewTransform.kt | 6 +++++- 6 files changed, 15 insertions(+), 6 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt index 66a237ff3..b71a3a1f4 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt @@ -40,7 +40,8 @@ abstract class CircleAnchorElement( 2.0f * radius ), AreaType.POINT, - parents.map { it.elementId } + parents.map { it.elementId }, + parents.flatMap { it.parents }.map { it.elementId } ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt index 690ef5595..d4eabe0b6 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt @@ -40,7 +40,8 @@ class EdgeExtractionAnchor( ), AreaType.POINT, parents.map { it.elementId }, - parent + parents.flatMap { it.parents }.map { it.elementId }, + attachedTo = parent ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt index 6076e788c..87ded9332 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt @@ -32,7 +32,8 @@ class ShapeResizeAnchorBottom( ), AreaType.SHAPE, parents.map { it.elementId }, - parent + parents.flatMap { it.parents }.map { it.elementId }, + attachedTo = parent ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt index 1a2dd6cff..c1a6236eb 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt @@ -37,7 +37,8 @@ class ShapeResizeAnchorTop( ), AreaType.SHAPE, parents.map { it.elementId }, - parent + parents.flatMap { it.parents }.map { it.elementId }, + attachedTo = parent ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt index 0f0ebcddb..50827e1be 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt @@ -42,7 +42,8 @@ class ButtonWithAnchor( imageHeight ), AreaType.POINT, - parents.map { it.elementId } + parents.map { it.elementId }, + parents.flatMap { it.parents }.map { it.elementId }, ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 992e96b97..5dbe1cd95 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -10,7 +10,7 @@ import kotlin.math.abs import kotlin.math.pow import kotlin.random.Random.Default.nextFloat -data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: List, val attachedTo: DiagramElementId? = null) +data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: List, val parentsOfParentElements: List = emptyList(), val attachedTo: DiagramElementId? = null) data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val parentsOfParentElements: List = emptyList(), val selectCloseQuirkWithin: Float? = null) interface PreTransformable { @@ -166,6 +166,10 @@ class ExpandViewTransform( quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() } + if (null == quirkFound) { + quirkFound = rectTransformationIntrospection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() + } + return if (null != quirkFound) { Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) } else { From 5cbae4bdd9622e7b8e7c3f7dc75c047400dc8337 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 20:54:45 +0200 Subject: [PATCH 14/22] FBP-85. Register parent of parents for rectangular elements too --- .../elements/edges/BaseEdgeRenderElement.kt | 20 +++++++++++++------ .../elements/shapes/ShapeRenderElement.kt | 4 +++- .../elements/viewtransform/ViewTransform.kt | 5 +---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt index 823bd8e1a..2f7983108 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt @@ -17,6 +17,7 @@ import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.AnchorElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.PhysicalWaypoint import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.VirtualWaypoint +import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.RectangleTransformationIntrospection import java.awt.Color import java.awt.geom.Area import java.awt.geom.Point2D @@ -95,12 +96,19 @@ abstract class BaseEdgeRenderElement( val maxX = edge.waypoint.maxBy { it.x }?.x ?: 0.0f val maxY = edge.waypoint.maxBy { it.y }?.y ?: 0.0f - // Edge itself can't be translated, so no viewTransform - return Rectangle2D.Float( - minX, - minY, - maxX - minX, - maxY - minY + return state().viewTransform(elementId).transform( + elementId, + RectangleTransformationIntrospection( + Rectangle2D.Float( + minX, + minY, + maxX - minX, + maxY - minY + ), + AreaType.POINT, + parents.map { it.elementId }, + parents.flatMap { it.parents }.map { it.elementId }, + ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index e9f2fd73d..35bd94480 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -273,7 +273,7 @@ abstract class ShapeRenderElement( } private fun computeAnchorLocation(currentElementId: DiagramElementId, state: () -> RenderState): EdgeExtractionAnchor { - return EdgeExtractionAnchor( + val anchor = EdgeExtractionAnchor( DiagramElementId("NEW-SEQUENCE:" + shape.id.id), currentElementId, actionsAnchorTopEnd(Rectangle2D.Float( @@ -285,6 +285,8 @@ abstract class ShapeRenderElement( { droppedOn, allDroppedOn -> onWaypointAnchorDragEnd(droppedOn, allDroppedOn) }, state ) + anchor.parents += this + return anchor } private fun onWaypointAnchorDragEnd(droppedOn: BpmnElementId?, allDroppedOnAreas: Map): MutableList { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 5dbe1cd95..e703dce0a 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -162,14 +162,11 @@ class ExpandViewTransform( var quirkFound: RectangleQuirk? = null if (rectTransformationIntrospection.type == AreaType.POINT) { quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] + ?: rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() } else if (!rectTransformationIntrospection.parentElements.contains(expandOnElementLevel)) { quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() } - if (null == quirkFound) { - quirkFound = rectTransformationIntrospection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() - } - return if (null != quirkFound) { Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) } else { From daa765f16eb9928606f496897b7ffaab96ab5a02 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 21:41:49 +0200 Subject: [PATCH 15/22] FBP-85. Fixed physical anchors rendering --- .../plugin/core/render/elements/viewtransform/ViewTransform.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index e703dce0a..87c4a9c39 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -163,6 +163,7 @@ class ExpandViewTransform( if (rectTransformationIntrospection.type == AreaType.POINT) { quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] ?: rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() + ?: rectTransformationIntrospection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() } else if (!rectTransformationIntrospection.parentElements.contains(expandOnElementLevel)) { quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() } From 4d45770da88260f1ece8c703d240d33d3e5716d9 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 21 Nov 2021 22:06:09 +0200 Subject: [PATCH 16/22] FBP-85. Fixed attachedTo ignored on physical waypoint --- .../plugin/core/render/elements/anchors/AnchorElement.kt | 2 +- .../plugin/core/render/elements/anchors/CircleAnchorElement.kt | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt index fe89a12c9..eb8a5fd80 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt @@ -16,7 +16,7 @@ import java.awt.geom.Rectangle2D abstract class AnchorElement( elementId: DiagramElementId, - private val attachedTo: DiagramElementId?, + protected val attachedTo: DiagramElementId?, protected val currentLocation: Point2D.Float, state: () -> RenderState ): BaseDiagramRenderElement(elementId, state) { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt index b71a3a1f4..4e43423ef 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt @@ -41,7 +41,8 @@ abstract class CircleAnchorElement( ), AreaType.POINT, parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId } + parents.flatMap { it.parents }.map { it.elementId }, + attachedTo = attachedTo ) ) } From 2f841de70f93c67bbbed2a2d06e3eb7f178551d7 Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 22 Nov 2021 13:47:31 +0200 Subject: [PATCH 17/22] FBP-85. Reorganize view transformation application mode --- .../core/render/DefaultBpmnProcessRenderer.kt | 2 +- .../elements/BaseDiagramRenderElement.kt | 16 +++- .../render/elements/anchors/AnchorElement.kt | 4 +- .../elements/anchors/CircleAnchorElement.kt | 5 +- .../elements/anchors/EdgeExtractionAnchor.kt | 3 +- .../anchors/ShapeResizeAnchorBottom.kt | 3 +- .../elements/anchors/ShapeResizeAnchorTop.kt | 3 +- .../elements/anchors/VirtualWaypoint.kt | 20 ++++- .../elements/buttons/ButtonWithAnchor.kt | 3 +- .../elements/edges/BaseEdgeRenderElement.kt | 42 +++++----- .../elements/planes/PlaneRenderElement.kt | 5 ++ .../shapes/AnyShapeNestableIconShape.kt | 8 +- .../elements/shapes/ExpandableShapeNoIcon.kt | 8 +- .../shapes/ResizeableShapeRenderElement.kt | 7 ++ .../elements/shapes/ShapeRenderElement.kt | 10 ++- .../elements/viewtransform/ViewTransform.kt | 76 ++++++++----------- 16 files changed, 130 insertions(+), 85 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt index c49606b67..6441c9c7f 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt @@ -197,7 +197,7 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr elementsById.forEach { (id, renderElem) -> val elem = state().currentState.elementByBpmnId[id] elem?.parent?.let {elementsById[it]}?.let { if (it is BaseBpmnRenderElement) it else null }?.let { parent -> - parent.innerElements.add(renderElem) + parent.addInnerElement(renderElem) parent.let { renderElem.parents.add(it) } } } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index e55a43076..588ec9c95 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -31,7 +31,7 @@ abstract class BaseDiagramRenderElement( var isVisible: Boolean? = null abstract val areaType: AreaType - val innerElements: MutableList = mutableListOf() + protected val innerElements: MutableList = mutableListOf() open val children: List = innerElements /** @@ -40,6 +40,11 @@ abstract class BaseDiagramRenderElement( */ open val parents: MutableList = mutableListOf() + /** + * View transformation level for this element (will limit scoped view transformation to this level) + */ + open var viewTransformLevel: DiagramElementId? = null + open fun multipleElementsSelected(): Boolean { return state().ctx.selectedIds.size > 1 } @@ -122,6 +127,11 @@ abstract class BaseDiagramRenderElement( return result } + open fun addInnerElement(elem: BaseDiagramRenderElement) { + elem.viewTransformLevel = this.viewTransformLevel + innerElements.add(elem) + } + abstract fun currentRect(): Rectangle2D.Float protected open fun rootAndEnumerateChildrenRecursively(root: BaseDiagramRenderElement) : List { @@ -222,7 +232,7 @@ abstract class BaseDiagramRenderElement( abstract fun doResizeWithoutChildren(dw: Float, dh: Float) abstract fun doResizeEndWithoutChildren(dw: Float, dh: Float): MutableList - protected abstract fun currentOnScreenRect(camera: Camera): Rectangle2D.Float + abstract fun currentOnScreenRect(camera: Camera): Rectangle2D.Float protected abstract fun waypointAnchors(camera: Camera): MutableSet protected abstract fun shapeAnchors(camera: Camera): MutableSet @@ -258,7 +268,7 @@ abstract class BaseDiagramRenderElement( protected fun compensateExpansionViewOnLocation(elementToCompensate: DiagramElementId, location: Point2D.Float, initialGuess: Point2D.Float, target: DiagramElementId?): Point2D.Float { val batch = findExpansionViewTransformationsToCompensate() - val inverted = ViewTransformInverter().invert(elementToCompensate, location, initialGuess, batch, PointTransformationIntrospection(target)) + val inverted = ViewTransformInverter().invert(elementToCompensate, location, initialGuess, batch, PointTransformationIntrospection(target, applyTransformationAt = this.viewTransformLevel)) return Point2D.Float(inverted.x, inverted.y) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt index eb8a5fd80..456589f81 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/AnchorElement.kt @@ -25,7 +25,7 @@ abstract class AnchorElement( get() = currentLocation val transformedLocation: Point2D.Float - get() = state().viewTransform(elementId).transform(elementId, currentLocation, PointTransformationIntrospection(attachedTo, parents.flatMap { it.parents }.map { it.elementId })) + get() = state().viewTransform(elementId).transform(elementId, currentLocation, PointTransformationIntrospection(attachedTo, viewTransformLevel)) override fun drawActionsRight(x: Float, y: Float): Map { // NOP @@ -68,4 +68,4 @@ abstract class AnchorElement( override fun getEventsToDeleteElement(): List { return listOf() } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt index 4e43423ef..263e2ad92 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/CircleAnchorElement.kt @@ -21,7 +21,7 @@ abstract class CircleAnchorElement( elementId: DiagramElementId, attachedTo: DiagramElementId?, currentLocation: Point2D.Float, - private val radius: Float, + protected val radius: Float, private val bodyColor: Colors, state: () -> RenderState ) : AnchorElement(elementId, attachedTo, currentLocation, state) { @@ -40,8 +40,7 @@ abstract class CircleAnchorElement( 2.0f * radius ), AreaType.POINT, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, + viewTransformLevel, attachedTo = attachedTo ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt index d4eabe0b6..705452d00 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/EdgeExtractionAnchor.kt @@ -39,8 +39,7 @@ class EdgeExtractionAnchor( imageHeight ), AreaType.POINT, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, + viewTransformLevel, attachedTo = parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt index 87ded9332..b628b560b 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorBottom.kt @@ -31,8 +31,7 @@ class ShapeResizeAnchorBottom( icon.iconHeight.toFloat() ), AreaType.SHAPE, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, + viewTransformLevel, attachedTo = parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt index c1a6236eb..da0ecbb38 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/ShapeResizeAnchorTop.kt @@ -36,8 +36,7 @@ class ShapeResizeAnchorTop( height ), AreaType.SHAPE, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, + viewTransformLevel, attachedTo = parent ) ) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt index 97a5b9b16..52cb2a5fd 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt @@ -1,5 +1,6 @@ package com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors +import com.intellij.sql.indexOf import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.BpmnElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.DiagramElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.BoundsElement @@ -12,7 +13,9 @@ import com.valb3r.bpmn.intellij.plugin.core.render.Camera import com.valb3r.bpmn.intellij.plugin.core.render.elements.ACTIONS_ICO_SIZE import com.valb3r.bpmn.intellij.plugin.core.render.elements.Anchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState +import com.valb3r.bpmn.intellij.plugin.core.render.elements.edges.BaseEdgeRenderElement import java.awt.geom.Point2D +import java.awt.geom.Rectangle2D private const val RADIUS = 3.0f @@ -49,4 +52,19 @@ class VirtualWaypoint( override fun waypointAnchors(camera: Camera): MutableSet { return if (isActiveOrDragged()) return super.waypointAnchors(camera) else mutableSetOf() } -} \ No newline at end of file + + override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { + val edge = state().elemMap[parentElementId] as BaseEdgeRenderElement + val edgeElems = edge.children.filter { it is PhysicalWaypoint || it.elementId == elementId } + val indexOfCurrentPoint = edgeElems.indexOf { it.elementId == elementId } + val prevRect = edgeElems[indexOfCurrentPoint - 1].currentOnScreenRect(camera) + val nextRect = edgeElems[indexOfCurrentPoint + 1].currentOnScreenRect(camera) + val currentPointLocation = Point2D.Float((prevRect.centerX.toFloat() + nextRect.centerX.toFloat()) / 2.0f, (prevRect.centerY.toFloat() + nextRect.centerY.toFloat()) / 2.0f) + return Rectangle2D.Float( + currentPointLocation.x - radius, + currentPointLocation.y - radius, + 2.0f * radius, + 2.0f * radius + ) + } +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt index 50827e1be..c454b3f70 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/buttons/ButtonWithAnchor.kt @@ -42,8 +42,7 @@ class ButtonWithAnchor( imageHeight ), AreaType.POINT, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, + viewTransformLevel ) ) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt index 2f7983108..7be24d580 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/BaseEdgeRenderElement.kt @@ -17,6 +17,7 @@ import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.AnchorElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.PhysicalWaypoint import com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors.VirtualWaypoint +import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.PointTransformationIntrospection import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.RectangleTransformationIntrospection import java.awt.Color import java.awt.geom.Area @@ -33,6 +34,14 @@ abstract class BaseEdgeRenderElement( private val anchors = computeAnchors() + override var viewTransformLevel: DiagramElementId? = null + get() = super.viewTransformLevel + set(value) { + super.viewTransformLevel = value + field = value + anchors.forEach { it.viewTransformLevel = value} + } + override val children: List = anchors as MutableList + innerElements val edgeElem: EdgeWithIdentifiableWaypoints @@ -91,24 +100,17 @@ abstract class BaseEdgeRenderElement( } override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { - val minX = edge.waypoint.minBy { it.x }?.x ?: 0.0f - val minY = edge.waypoint.minBy { it.y }?.y ?: 0.0f - val maxX = edge.waypoint.maxBy { it.x }?.x ?: 0.0f - val maxY = edge.waypoint.maxBy { it.y }?.y ?: 0.0f - - return state().viewTransform(elementId).transform( - elementId, - RectangleTransformationIntrospection( - Rectangle2D.Float( - minX, - minY, - maxX - minX, - maxY - minY - ), - AreaType.POINT, - parents.map { it.elementId }, - parents.flatMap { it.parents }.map { it.elementId }, - ) + val elems = anchors.filterIsInstance().map { it.transformedLocation } + val stX = elems.minBy { it.x }?.x ?: 0.0f + val stY = elems.minBy { it.y }?.y ?: 0.0f + val enX = elems.maxBy { it.x }?.x ?: 0.0f + val enY = elems.maxBy { it.y }?.y ?: 0.0f + + return Rectangle2D.Float( + stX, + stY, + enX - stX, + enY - stY ) } @@ -158,12 +160,14 @@ abstract class BaseEdgeRenderElement( val numPhysicals = edge.waypoint.filter { it.physical }.size var physicalPos = -1 return edge.waypoint.map { - if (it.physical) { + val result = if (it.physical) { physicalPos++ PhysicalWaypoint(it.id, findAttachedToElement(physicalPos, numPhysicals), edge.id, edge.bpmnElement, edge, physicalPos, numPhysicals, Point2D.Float(it.x, it.y), state).let { it.parents.add(this); it } } else { VirtualWaypoint(it.id, edge.id, edge, Point2D.Float(it.x, it.y), state).let { it.parents.add(this); it } } + result.viewTransformLevel = viewTransformLevel + return@map result }.toMutableList() } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt index 6d4a7e2ee..a0e85bc59 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/planes/PlaneRenderElement.kt @@ -69,6 +69,11 @@ class PlaneRenderElement( override fun drawActionsRight(x: Float, y: Float): Map { return mutableMapOf() } + + override fun addInnerElement(elem: BaseDiagramRenderElement) { + elem.viewTransformLevel = this.elementId + innerElements.add(elem) + } } private class InfiniteShape: Area() { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/AnyShapeNestableIconShape.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/AnyShapeNestableIconShape.kt index 43fe9352e..73af01e9c 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/AnyShapeNestableIconShape.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/AnyShapeNestableIconShape.kt @@ -12,6 +12,7 @@ import com.valb3r.bpmn.intellij.plugin.core.render.AreaWithZindex import com.valb3r.bpmn.intellij.plugin.core.render.Camera import com.valb3r.bpmn.intellij.plugin.core.render.elements.Anchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.BaseBpmnRenderElement +import com.valb3r.bpmn.intellij.plugin.core.render.elements.BaseDiagramRenderElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.elements.internal.CascadeTranslationOrChangesToWaypoint import java.awt.geom.Point2D @@ -27,6 +28,11 @@ class AnyShapeNestableIconShape( override val areaType: AreaType get() = AreaType.SELECTS_DRAG_TARGET + override fun addInnerElement(elem: BaseDiagramRenderElement) { + elem.viewTransformLevel = this.elementId + innerElements.add(elem) + } + fun handleParentNestingChange(droppedOn: BpmnElementId): MutableList { val newEvents = mutableListOf() val currentParent = parents.firstOrNull() @@ -103,4 +109,4 @@ class AnyShapeNestableIconShape( return parents.first().parents.first() } -} \ No newline at end of file +} diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index cae632025..d93e13763 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -31,6 +31,11 @@ class ExpandableShapeNoIcon( override val areaType: AreaType = AreaType.SHAPE ) : ResizeableShapeRenderElement(elementId, bpmnElementId, shape, state) { + override fun addInnerElement(elem: BaseDiagramRenderElement) { + elem.viewTransformLevel = this.elementId + innerElements.add(elem) + } + private val expandButton = ButtonWithAnchor( DiagramElementId("EXPAND:" + shape.id.id), Point2D.Float((shape.bounds().first.x + shape.bounds().second.x) / 2.0f, shape.bounds().second.y), @@ -61,13 +66,12 @@ class ExpandableShapeNoIcon( state().baseTransform.addPreTransform(ExpandViewTransform( elementId, - parents.firstOrNull()?.elementId ?: DiagramElementId(""), + viewTransformLevel!!, shape.rectBounds(), shape.rectBounds().centerX.toFloat(), shape.rectBounds().centerY.toFloat(), 100.0f, 100.0f, - enumerateChildrenRecursively().map { it.elementId }.toSet() )) super.createIfNeededExpandViewTransform() } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt index 60a5a2ea1..0a35391ed 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ResizeableShapeRenderElement.kt @@ -33,6 +33,13 @@ abstract class ResizeableShapeRenderElement( protected val actions = mutableListOf(anchors.first, anchors.second, edgeExtractionAnchor) + override var viewTransformLevel: DiagramElementId? + get() = super.viewTransformLevel + set(value) { + super.viewTransformLevel = value + actions.forEach { it.viewTransformLevel = viewTransformLevel } + } + override val children: List get() = actions + innerElements diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index 35bd94480..8145bf3fc 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -49,6 +49,14 @@ abstract class ShapeRenderElement( val shapeElem: ShapeElement get() = shape + override var viewTransformLevel: DiagramElementId? = null + get() = super.viewTransformLevel + set(value) { + super.viewTransformLevel = value + field = value + edgeExtractionAnchor.viewTransformLevel = viewTransformLevel + } + override fun doRenderWithoutChildren(ctx: RenderContext): Map { val elem = state().currentState.elementByDiagramId[shape.id] val props = state().currentState.elemPropertiesByStaticElementId[elem] @@ -180,7 +188,7 @@ abstract class ShapeRenderElement( } override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { - return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE, parents.map { it.elementId })) + return state().viewTransform(elementId).transform(elementId, RectangleTransformationIntrospection(shape.rectBounds(), AreaType.SHAPE, viewTransformLevel)) } override fun currentRect(): Rectangle2D.Float { diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 87c4a9c39..2001607bb 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -10,8 +10,8 @@ import kotlin.math.abs import kotlin.math.pow import kotlin.random.Random.Default.nextFloat -data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val parentElements: List, val parentsOfParentElements: List = emptyList(), val attachedTo: DiagramElementId? = null) -data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val parentsOfParentElements: List = emptyList(), val selectCloseQuirkWithin: Float? = null) +data class RectangleTransformationIntrospection(val rect: Rectangle2D.Float, val type: AreaType, val applyTransformationAt: DiagramElementId? = null, val attachedTo: DiagramElementId? = null) +data class PointTransformationIntrospection(val attachedTo: DiagramElementId? = null, val applyTransformationAt: DiagramElementId? = null, val selectCloseQuirkWithin: Float? = null) interface PreTransformable { fun preTransform(elementId: DiagramElementId, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float @@ -123,7 +123,6 @@ class ExpandViewTransform( private val cy: Float, private val dx: Float, private val dy: Float, - private val excludeIds: Set, private val preTransform: PreTransformHandler = PreTransformHandler() ): ViewTransform, PreTransformable by preTransform { @@ -133,7 +132,7 @@ class ExpandViewTransform( override fun transform(elementId: DiagramElementId, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float { val rect = rectTransformationIntrospection.rect val transformed = preTransform(elementId, rectTransformationIntrospection) - if (excludeIds.contains(elementId)) { + if (expandOnElementLevel != rectTransformationIntrospection.applyTransformationAt) { fillRectangleQuirk(elementId, rect, Point2D.Float()) return transformed } @@ -158,48 +157,13 @@ class ExpandViewTransform( return Rectangle2D.Float(center.x - halfWidth, center.y - halfHeight, rect.width, rect.height) } - private fun transformManagedByParent(transformed: Rectangle2D.Float, rect: Rectangle2D.Float, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float? { - var quirkFound: RectangleQuirk? = null - if (rectTransformationIntrospection.type == AreaType.POINT) { - quirkFound = quirkForRectangles[rectTransformationIntrospection.attachedTo] - ?: rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() - ?: rectTransformationIntrospection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() - } else if (!rectTransformationIntrospection.parentElements.contains(expandOnElementLevel)) { - quirkFound = rectTransformationIntrospection.parentElements.map { quirkForRectangles[it] }.firstOrNull() - } - - return if (null != quirkFound) { - Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) - } else { - null - } - } - - private fun fillRectangleQuirkIfNeeded(rectTransformationIntrospection: RectangleTransformationIntrospection, elementId: DiagramElementId, rect: Rectangle2D.Float, center: Point2D.Float, transformed: Rectangle2D.Float, halfWidth: Float, halfHeight: Float) { - if (rectTransformationIntrospection.type.nests || rectTransformationIntrospection.type == AreaType.SHAPE) { - fillRectangleQuirk(elementId, rect, Point2D.Float(center.x - transformed.x - halfWidth, center.y - transformed.y - halfHeight)) - } - } - - private fun fillRectangleQuirk(elementId: DiagramElementId, rect: Rectangle2D.Float, delta: Point2D.Float) { - quirkForRectangles[elementId] = RectangleQuirk( - Rectangle2D.Float( - rect.x - quirkEpsilon, - rect.y - quirkEpsilon, - rect.width + quirkEpsilon, - rect.height + quirkEpsilon - ), - delta - ) - } - override fun transform(elementId: DiagramElementId, point: Point2D.Float): Point2D.Float { return transform(elementId, point, PointTransformationIntrospection()) } override fun transform(elementId: DiagramElementId, point: Point2D.Float, introspection: PointTransformationIntrospection): Point2D.Float { val transformed = preTransform(elementId, point, introspection) - if (excludeIds.contains(elementId)) { + if (expandOnElementLevel != introspection.applyTransformationAt) { return transformed } @@ -208,10 +172,6 @@ class ExpandViewTransform( } var quirkFound = quirkForRectangles[introspection.attachedTo] - // Managed quirk - if (null == quirkFound) { - quirkFound = introspection.parentsOfParentElements.map { quirkForRectangles[it] }.firstOrNull() - } if (null == quirkFound && null != introspection.selectCloseQuirkWithin) { fun quirkDistance(it: RectangleQuirk) = (point.x - it.originalRectangle2D.x).pow(2) + (point.y - it.originalRectangle2D.y).pow(2) val bestQuirk = quirkForRectangles.values.minBy { quirkDistance(it) } @@ -227,6 +187,34 @@ class ExpandViewTransform( return transformPoint(transformed) } + private fun transformManagedByParent(transformed: Rectangle2D.Float, rect: Rectangle2D.Float, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float? { + val quirkFound: RectangleQuirk? = quirkForRectangles[rectTransformationIntrospection.attachedTo] + + return if (null != quirkFound) { + Rectangle2D.Float(transformed.x + quirkFound.displacement.x, transformed.y + quirkFound.displacement.y, rect.width, rect.height) + } else { + null + } + } + + private fun fillRectangleQuirkIfNeeded(rectTransformationIntrospection: RectangleTransformationIntrospection, elementId: DiagramElementId, rect: Rectangle2D.Float, center: Point2D.Float, transformed: Rectangle2D.Float, halfWidth: Float, halfHeight: Float) { + if (rectTransformationIntrospection.type.nests || rectTransformationIntrospection.type == AreaType.SHAPE) { + fillRectangleQuirk(elementId, rect, Point2D.Float(center.x - transformed.x - halfWidth, center.y - transformed.y - halfHeight)) + } + } + + private fun fillRectangleQuirk(elementId: DiagramElementId, rect: Rectangle2D.Float, delta: Point2D.Float) { + quirkForRectangles[elementId] = RectangleQuirk( + Rectangle2D.Float( + rect.x - quirkEpsilon, + rect.y - quirkEpsilon, + rect.width + quirkEpsilon, + rect.height + quirkEpsilon + ), + delta + ) + } + private fun transformPoint(point: Point2D.Float): Point2D.Float { // assuming left-right, top-down coordinate system return when { From bb9069028104c31a367d4f1c56b7ae9c3067bd87 Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 22 Nov 2021 15:05:27 +0200 Subject: [PATCH 18/22] FBP-85. Corrected indexOf usage --- .../plugin/core/render/elements/anchors/VirtualWaypoint.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt index 52cb2a5fd..e71f05d7b 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt @@ -1,6 +1,5 @@ package com.valb3r.bpmn.intellij.plugin.core.render.elements.anchors -import com.intellij.sql.indexOf import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.BpmnElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.DiagramElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.BoundsElement @@ -56,7 +55,7 @@ class VirtualWaypoint( override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { val edge = state().elemMap[parentElementId] as BaseEdgeRenderElement val edgeElems = edge.children.filter { it is PhysicalWaypoint || it.elementId == elementId } - val indexOfCurrentPoint = edgeElems.indexOf { it.elementId == elementId } + val indexOfCurrentPoint = edgeElems.indexOfFirst { it.elementId == elementId } val prevRect = edgeElems[indexOfCurrentPoint - 1].currentOnScreenRect(camera) val nextRect = edgeElems[indexOfCurrentPoint + 1].currentOnScreenRect(camera) val currentPointLocation = Point2D.Float((prevRect.centerX.toFloat() + nextRect.centerX.toFloat()) / 2.0f, (prevRect.centerY.toFloat() + nextRect.centerY.toFloat()) / 2.0f) From 1c07f6cfdf9f87a5e7a0a023a83e977fdec5f99b Mon Sep 17 00:00:00 2001 From: valb3r Date: Mon, 22 Nov 2021 16:17:57 +0200 Subject: [PATCH 19/22] FBP-85. Simplify model --- .../render/elements/anchors/VirtualWaypoint.kt | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt index e71f05d7b..991645aea 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/anchors/VirtualWaypoint.kt @@ -12,9 +12,7 @@ import com.valb3r.bpmn.intellij.plugin.core.render.Camera import com.valb3r.bpmn.intellij.plugin.core.render.elements.ACTIONS_ICO_SIZE import com.valb3r.bpmn.intellij.plugin.core.render.elements.Anchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState -import com.valb3r.bpmn.intellij.plugin.core.render.elements.edges.BaseEdgeRenderElement import java.awt.geom.Point2D -import java.awt.geom.Rectangle2D private const val RADIUS = 3.0f @@ -51,19 +49,4 @@ class VirtualWaypoint( override fun waypointAnchors(camera: Camera): MutableSet { return if (isActiveOrDragged()) return super.waypointAnchors(camera) else mutableSetOf() } - - override fun currentOnScreenRect(camera: Camera): Rectangle2D.Float { - val edge = state().elemMap[parentElementId] as BaseEdgeRenderElement - val edgeElems = edge.children.filter { it is PhysicalWaypoint || it.elementId == elementId } - val indexOfCurrentPoint = edgeElems.indexOfFirst { it.elementId == elementId } - val prevRect = edgeElems[indexOfCurrentPoint - 1].currentOnScreenRect(camera) - val nextRect = edgeElems[indexOfCurrentPoint + 1].currentOnScreenRect(camera) - val currentPointLocation = Point2D.Float((prevRect.centerX.toFloat() + nextRect.centerX.toFloat()) / 2.0f, (prevRect.centerY.toFloat() + nextRect.centerY.toFloat()) / 2.0f) - return Rectangle2D.Float( - currentPointLocation.x - radius, - currentPointLocation.y - radius, - 2.0f * radius, - 2.0f * radius - ) - } } From 5794e9902e33c8ad19e9e8eb65f2969b8a93103b Mon Sep 17 00:00:00 2001 From: valb3r Date: Tue, 23 Nov 2021 20:16:49 +0200 Subject: [PATCH 20/22] FBP-85. Fix not invoked inversion --- .../plugin/core/render/elements/BaseDiagramRenderElement.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index 588ec9c95..462878b80 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -258,9 +258,10 @@ abstract class BaseDiagramRenderElement( val batch = findExpansionViewTransformationsToCompensate() val trackingPoint = Point2D.Float(rect.x, rect.y) - val viewTransformedPoint = batch.transform(elementId, trackingPoint) + val transform = PointTransformationIntrospection(applyTransformationAt = viewTransformLevel) + val viewTransformedPoint = batch.transform(elementId, trackingPoint, transform) val currentPoint = Point2D.Float(viewTransformedPoint.x + dx, viewTransformedPoint.y + dy) - val inverted = ViewTransformInverter().invert(elementId, currentPoint, trackingPoint, batch) + val inverted = ViewTransformInverter().invert(elementId, currentPoint, trackingPoint, batch, transform) return Point2D.Float(inverted.x - rect.x, inverted.y - rect.y) } From f351d0f9a1dec997867835aaab12ffa2fc333628 Mon Sep 17 00:00:00 2001 From: valb3r Date: Wed, 24 Nov 2021 10:32:16 +0200 Subject: [PATCH 21/22] FBP-85. Increase search area --- .../plugin/core/render/elements/viewtransform/ViewTransform.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 2001607bb..13493863d 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -300,7 +300,7 @@ class ViewTransformInverter { private val epsilon = 1.0f private val maxIter = 10 private val randomInitializationGuesses = 10 - private val randomInitializationAreaSpan = 100.0f + private val randomInitializationAreaSpan = 1000.0f private val minQuirkDistSq = 100.0f /** From 5632c8901df9c5567ae8d1a1b957955e4e9a06bc Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 28 Nov 2021 05:52:14 +0200 Subject: [PATCH 22/22] FBP-85. Example file and initial coordinate transform handling --- .../elements/shapes/ExpandableShapeNoIcon.kt | 7 ++ .../elements/viewtransform/ViewTransform.kt | 4 +- .../resources/collapsed-subprocess.bpmn20.xml | 100 ++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 flowable-xml-parser/src/test/resources/collapsed-subprocess.bpmn20.xml diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt index d93e13763..49d5a3f51 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ExpandableShapeNoIcon.kt @@ -14,7 +14,9 @@ import com.valb3r.bpmn.intellij.plugin.core.render.elements.Anchor import com.valb3r.bpmn.intellij.plugin.core.render.elements.BaseDiagramRenderElement import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.elements.buttons.ButtonWithAnchor +import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.DragViewTransform import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.ExpandViewTransform +import com.valb3r.bpmn.intellij.plugin.core.render.elements.viewtransform.PreTransformHandler import java.awt.geom.Point2D import javax.swing.Icon @@ -34,6 +36,11 @@ class ExpandableShapeNoIcon( override fun addInnerElement(elem: BaseDiagramRenderElement) { elem.viewTransformLevel = this.elementId innerElements.add(elem) + state().viewTransforms[elem.elementId] = DragViewTransform( + shape.bounds().first.x, + shape.bounds().first.y, + PreTransformHandler(mutableListOf(state().viewTransform(elem.elementId))) + ) } private val expandButton = ButtonWithAnchor( diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt index 13493863d..36ac77c4b 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/viewtransform/ViewTransform.kt @@ -70,7 +70,9 @@ class NullViewTransform(private val preTransform: PreTransformHandler = PreTrans } data class DragViewTransform( - val dx: Float, val dy: Float, private val preTransform: PreTransformHandler = PreTransformHandler() + private val dx: Float, + private val dy: Float, + private val preTransform: PreTransformHandler = PreTransformHandler() ): ViewTransform, PreTransformable by preTransform { override fun transform(elementId: DiagramElementId, rectTransformationIntrospection: RectangleTransformationIntrospection): Rectangle2D.Float { diff --git a/flowable-xml-parser/src/test/resources/collapsed-subprocess.bpmn20.xml b/flowable-xml-parser/src/test/resources/collapsed-subprocess.bpmn20.xml new file mode 100644 index 000000000..eb4773ad1 --- /dev/null +++ b/flowable-xml-parser/src/test/resources/collapsed-subprocess.bpmn20.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file