/** Invoked when an action occurs. */ public void actionPerformed(final ActionEvent e) { final ReportSelectionModel model = getSelectionModel(); if (model == null) { return; } final Element[] visualElements = model.getSelectedVisualElements(); if (visualElements.length <= 1) { return; } final Element[] carrier = new Element[1]; final Element[] objects = ModelUtility.filterParents(visualElements); final MassElementStyleUndoEntryBuilder builder = new MassElementStyleUndoEntryBuilder(objects); long minY = Long.MAX_VALUE; long maxY = Long.MIN_VALUE; for (int j = 0; j < objects.length; j++) { final Element object = objects[j]; final CachedLayoutData data = ModelUtility.getCachedLayoutData(object); final long y1 = data.getY(); final long y2 = y1 + data.getHeight(); if (y2 > maxY) { maxY = y2; } if (y1 < minY) { minY = y1; } } final long centerPoint = minY + (maxY - minY) / 2; for (int j = 0; j < objects.length; j++) { final Element object = objects[j]; final CachedLayoutData data = ModelUtility.getCachedLayoutData(object); final long elementCenter = data.getY() + data.getHeight() / 2; final long delta = centerPoint - elementCenter; if (delta == 0) { continue; } carrier[0] = object; final MoveDragOperation mop = new MoveDragOperation( carrier, ORIGIN_POINT, EmptySnapModel.INSTANCE, EmptySnapModel.INSTANCE); mop.update(new Point2D.Double(0, StrictGeomUtility.toExternalValue(delta)), 1); mop.finish(); } final MassElementStyleUndoEntry massElementStyleUndoEntry = builder.finish(); getActiveContext() .getUndo() .addChange( ActionMessages.getString("AlignMiddleAction.UndoName"), massElementStyleUndoEntry); }
public void update(final Point2D normalizedPoint, final double zoomFactor) { final SnapPositionsModel horizontalSnapModel = getHorizontalSnapModel(); final Element[] selectedVisualElements = getSelectedVisualElements(); final long originPointX = getOriginPointX(); final long[] elementWidth = getElementWidth(); final long px = StrictGeomUtility.toInternalValue(normalizedPoint.getX()); final long dx = px - originPointX; for (int i = 0; i < selectedVisualElements.length; i++) { final Element element = selectedVisualElements[i]; if (element instanceof RootLevelBand) { continue; } final ElementStyleSheet styleSheet = element.getStyle(); final double elementMinWidth = styleSheet.getDoubleStyleProperty(ElementStyleKeys.MIN_WIDTH, 0); // this is where I want the element on a global scale... final long targetWidth = elementWidth[i] + dx; final CachedLayoutData data = ModelUtility.getCachedLayoutData(element); final long elementX = data.getX(); final long targetX2 = elementX + targetWidth; if (elementMinWidth >= 0) { // absolute position; resolving is easy here final long snapPosition = horizontalSnapModel.getNearestSnapPosition(targetX2, element.getObjectID()); if (Math.abs(snapPosition - targetX2) > snapThreshold) { final long localWidth = Math.max(0, targetX2 - elementX); final float position = (float) StrictGeomUtility.toExternalValue(localWidth); styleSheet.setStyleProperty(ElementStyleKeys.MIN_WIDTH, new Float(position)); } else { final long localWidth = Math.max(0, snapPosition - elementX); final float position = (float) StrictGeomUtility.toExternalValue(localWidth); styleSheet.setStyleProperty(ElementStyleKeys.MIN_WIDTH, new Float(position)); } } else { final Element parent = element.getParentSection(); final CachedLayoutData parentData = ModelUtility.getCachedLayoutData(parent); final long parentBase = parentData.getWidth(); if (parentBase > 0) { // relative position; resolve the percentage against the height of the parent. final long snapPosition = horizontalSnapModel.getNearestSnapPosition(targetX2, element.getObjectID()); if (Math.abs(snapPosition - targetX2) > snapThreshold) { final long localWidth = Math.max(0, targetX2 - elementX); // strict geometry: all values are multiplied by 1000 // percentages in the engine are represented by floats betwen 0 and 100. final long percentage = StrictGeomUtility.toInternalValue(localWidth * 100 / parentBase); styleSheet.setStyleProperty( ElementStyleKeys.MIN_WIDTH, new Float(StrictGeomUtility.toExternalValue(-percentage))); } else { final long localWidth = Math.max(0, snapPosition - elementX); // strict geometry: all values are multiplied by 1000 // percentages in the engine are represented by floats betwen 0 and 100. final long percentage = StrictGeomUtility.toInternalValue(localWidth * 100 / parentBase); styleSheet.setStyleProperty( ElementStyleKeys.MIN_WIDTH, new Float(StrictGeomUtility.toExternalValue(-percentage))); } } } element.notifyNodePropertiesChanged(); } }