package org.simantics.district.network.ui; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import org.simantics.g2d.participant.TransformUtil; import org.simantics.maps.MapScalingTransform; import org.simantics.scenegraph.utils.GeometryUtils; import org.simantics.utils.page.MarginUtils; import org.simantics.utils.page.MarginUtils.Margins; public class DistrictTransformUtil extends TransformUtil { @Override public void fitArea(Rectangle2D controlArea, Rectangle2D diagramArea, Margins margins) { if (margins == null) { MarginUtils.Margin margin = MarginUtils.marginOf(0, 0, 0); margins = new MarginUtils.Margins(margin, margin, margin, margin); } org.simantics.scenegraph.utils.GeometryUtils.expandRectangle(diagramArea, -1); diagramArea = GeometryUtils.expandRectangle(diagramArea, margins.top.diagramAbsolute, margins.bottom.diagramAbsolute, margins.left.diagramAbsolute, margins.right.diagramAbsolute); controlArea = GeometryUtils.expandRectangle(controlArea, -margins.top.controlAbsolute - margins.top.controlRelative * controlArea.getHeight(), -margins.bottom.controlAbsolute - margins.bottom.controlRelative * controlArea.getHeight(), -margins.left.controlAbsolute - margins.left.controlRelative * controlArea.getWidth(), -margins.right.controlAbsolute - margins.right.controlRelative * controlArea.getWidth()); double controlAspectRatio = controlArea.getWidth() / controlArea.getHeight(); double canvasAspectRatio = diagramArea.getWidth() / diagramArea.getHeight(); // Control is really wide => center canvas horizontally, match vertically double scale = 1.0; double tx = 0.0; double ty = 0.0; if (controlAspectRatio>canvasAspectRatio) { scale = controlArea.getHeight() / diagramArea.getHeight(); } else // Control is really tall => center canvas vertically, match horizontally { scale = controlArea.getWidth() / diagramArea.getWidth(); } AffineTransform current = getTransform(); double currentX = current.getScaleX(); double targetX = scale; double toBeX = currentX; if (targetX > 0) { // let's check that targetX zoomLevel is between 0-20 AffineTransform tar = new AffineTransform(); tar.scale(targetX, targetX); int tarZoomLevel = MapScalingTransform.zoomLevel(tar); if (tarZoomLevel < 20 && tarZoomLevel > 0) { toBeX = Math.pow(2.0, tarZoomLevel); } else if (tarZoomLevel > 20) { toBeX = Math.pow(2.0, 20); } else if (tarZoomLevel < 0) { toBeX = 2; } else { toBeX = targetX; } if (controlAspectRatio>canvasAspectRatio) { tx = ( controlArea.getWidth() - diagramArea.getWidth() * toBeX ) / 2; ty = diagramArea.getHeight() * (targetX - toBeX) / 2; } else { ty = ( controlArea.getHeight() - diagramArea.getHeight() * toBeX ) / 2; tx = diagramArea.getWidth() * (targetX - toBeX) / 2; } AffineTransform at = new AffineTransform(); at.translate(tx, ty); at.translate(controlArea.getMinX(), controlArea.getMinY()); at.scale(toBeX, toBeX); at.translate(-diagramArea.getMinX(), -diagramArea.getMinY()); setTransform(at); } else { // negative, how, no can do? } } }