/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.core.ui.model.graphic; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Robot; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.List; import java.util.Objects; import java.util.Optional; import javax.swing.SwingUtilities; import javax.xml.bind.annotation.XmlTransient; import org.weasis.core.ui.editor.image.ViewCanvas; import org.weasis.core.ui.model.utils.Draggable; import org.weasis.core.ui.model.utils.imp.DefaultDragSequence; import org.weasis.core.ui.model.utils.imp.DragLabelSequence; import org.weasis.core.ui.util.MouseEventDouble; @XmlTransient public abstract class AbstractDragGraphic extends AbstractGraphic implements DragGraphic { private static final long serialVersionUID = 4694941331227706591L; private Boolean resizingOrMoving = DEFAULT_RESIZE_OR_MOVING; public AbstractDragGraphic(Integer pointNumber) { super(pointNumber); } public AbstractDragGraphic(AbstractGraphic graphic) { super(graphic); } @Override public void setResizeOrMoving(Boolean value) { this.resizingOrMoving = Optional.ofNullable(value).orElse(DEFAULT_RESIZE_OR_MOVING); } @Override public void buildShape() { if (isShapeValid()) { buildShape(null); } } @Override protected void paintHandles(Graphics2D g2d, AffineTransform transform) { if (!getResizingOrMoving()) { super.paintHandles(g2d, transform); } } @Override public Boolean getResizingOrMoving() { return Optional.ofNullable(resizingOrMoving).orElse(Boolean.FALSE); } @Override public void forceToAddPoints(Integer fromPtIndex) { if (variablePointsNumber && fromPtIndex >= 0 && fromPtIndex < pts.size()) { if (fromPtIndex < pts.size() - 1) { List<Point2D.Double> list = pts.subList(fromPtIndex + 1, pts.size()); for (int i = 0; i <= fromPtIndex; i++) { list.add(pts.get(i)); } pts = list; } pointNumber = UNDEFINED; } } @Override public Point2D removeHandlePoint(Integer index, MouseEventDouble mouseEvent) { // To keep a valid shape, do not remove when there are 2 points left. if (variablePointsNumber && pts.size() > 2 && index >= 0 && index < pts.size()) { Point2D pt = pts.remove(index.intValue()); pointNumber = pts.size(); buildShape(mouseEvent); return pt; } return null; } /** * Adjust the mouse cursor at the center of the handle point * * @param handlePtIndex * @param event */ @Override public void moveMouseOverHandlePoint(Integer handlePtIndex, MouseEventDouble event) { ViewCanvas<?> graphPane = getDefaultView2d(event); if (graphPane != null) { Point2D handlePt = null; if (handlePtIndex >= 0 && handlePtIndex < pts.size()) { handlePt = pts.get(handlePtIndex); } if (handlePt != null) { Point mousePt = graphPane.getMouseCoordinatesFromImage(handlePt.getX(), handlePt.getY()); if (mousePt != null && (event.getX() != mousePt.x || event.getY() != mousePt.y)) { try { event.translatePoint(mousePt.x - event.getX(), mousePt.y - event.getY()); event.setImageCoordinates(handlePt); SwingUtilities.convertPointToScreen(mousePt, graphPane.getJComponent()); new Robot().mouseMove(mousePt.x, mousePt.y); } catch (Exception e) { // Do nothing } } } } } @Override public Draggable createMoveDrag() { return new DefaultDragSequence(this); } @Override public Draggable createResizeDrag() { return createResizeDrag(UNDEFINED); } @Override public Draggable createResizeDrag(Integer i) { return new DefaultDragSequence(this, i); } @Override public Draggable createDragLabelSequence() { return new DragLabelSequence(this); } @Override public Integer moveAndResizeOnDrawing(Integer handlePointIndex, Double deltaX, Double deltaY, MouseEventDouble mouseEvent) { if (Objects.equals(handlePointIndex, UNDEFINED)) { pts.stream().filter(Objects::nonNull).forEach(p -> p.setLocation(p.getX() + deltaX, p.getY() + deltaY)); } else if (handlePointIndex >= 0 && handlePointIndex < pts.size()) { Point2D point = pts.get(handlePointIndex); Optional.ofNullable(point).ifPresent(p -> p.setLocation(mouseEvent.getImageCoordinates())); } return handlePointIndex; } }