/* * Copyright 2016 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.transform; import pixelitor.gui.ImageComponent; import pixelitor.tools.ArrowKey; import pixelitor.utils.Utils; import java.awt.Cursor; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.geom.Rectangle2D; /** * Helps with interactive manipulation of selections/transforms */ public class TransformSupport { private final Handles handles; private Rectangle compSpaceRect; private Rectangle2D imageSpaceRect; private int dragStartX; private int dragStartY; private int dragStartRectWidth; private int dragStartRectHeight; // true while the user is adjusting the handles private boolean adjusting; public TransformSupport(Rectangle compSpaceRect, Rectangle2D imageSpaceRect) { this.compSpaceRect = compSpaceRect; this.imageSpaceRect = imageSpaceRect; handles = new Handles(compSpaceRect); } public void paintHandles(Graphics2D g) { handles.paint(g); } public void mousePressed(MouseEvent e) { dragStartX = e.getX(); dragStartY = e.getY(); dragStartRectWidth = (int) compSpaceRect.getWidth(); dragStartRectHeight = (int) compSpaceRect.getHeight(); } public void mouseDragged(MouseEvent e, ImageComponent ic) { int cursorType = ic.getCursor().getType(); int mouseX = e.getX(); int mouseY = e.getY(); switch (cursorType) { case Cursor.NW_RESIZE_CURSOR: compSpaceRect.setLocation(mouseX, mouseY); compSpaceRect.setSize(dragStartRectWidth + (dragStartX - mouseX), dragStartRectHeight + (dragStartY) - mouseY); break; case Cursor.SE_RESIZE_CURSOR: compSpaceRect.setSize(dragStartRectWidth + (mouseX - dragStartX), dragStartRectHeight + (mouseY - dragStartY)); break; case Cursor.SW_RESIZE_CURSOR: compSpaceRect.setLocation(mouseX, compSpaceRect.getLocation().y); compSpaceRect.setSize(dragStartRectWidth + (dragStartX - mouseX), dragStartRectHeight + (mouseY - dragStartY)); break; case Cursor.NE_RESIZE_CURSOR: compSpaceRect.setLocation(compSpaceRect.getLocation().x, mouseY); compSpaceRect.setSize(dragStartRectWidth + (mouseX - dragStartX), dragStartRectHeight + (dragStartY - mouseY)); break; case Cursor.N_RESIZE_CURSOR: compSpaceRect.setLocation(compSpaceRect.getLocation().x, mouseY); compSpaceRect.setSize(compSpaceRect.width, dragStartRectHeight + (dragStartY - mouseY)); break; case Cursor.S_RESIZE_CURSOR: compSpaceRect.setSize(dragStartRectWidth, dragStartRectHeight + (mouseY - dragStartY)); break; case Cursor.E_RESIZE_CURSOR: compSpaceRect.setSize(dragStartRectWidth + (mouseX - dragStartX), compSpaceRect.height); break; case Cursor.W_RESIZE_CURSOR: compSpaceRect.setLocation(mouseX, compSpaceRect.y); compSpaceRect.setSize(dragStartRectWidth + (dragStartX - mouseX), compSpaceRect.height); break; default: return; } adjusting = true; handles.updateRect(compSpaceRect); } public void mouseReleased() { adjusting = false; } public void mouseMoved(MouseEvent e, ImageComponent ic) { handles.setCursorForPoint(e.getX(), e.getY(), ic); } public Rectangle2D getImageSpaceRect(ImageComponent ic) { if(adjusting) { recalculateImageSpaceRect(ic); } return imageSpaceRect; } @Override public String toString() { return "TransformSupport{" + "handles=" + handles + ", compSpaceRect=" + compSpaceRect + ", dragStartX=" + dragStartX + ", dragStartY=" + dragStartY + ", dragStartRectWidth=" + dragStartRectWidth + ", dragStartRectHeight=" + dragStartRectHeight + '}'; } /** * Used only while the image component is resized */ public void setComponentSpaceRect(Rectangle compSpaceRect) { this.compSpaceRect = compSpaceRect; handles.updateRect(compSpaceRect); } private void recalculateImageSpaceRect(ImageComponent ic) { Rectangle2D possiblyNegativeRect = ic.fromComponentToImageSpace(compSpaceRect); this.imageSpaceRect = Utils.toPositiveRect(possiblyNegativeRect); } public void arrowKeyPressed(ArrowKey key, ImageComponent ic) { double viewScale = ic.getZoomLevel().getViewScale(); compSpaceRect.translate((int) (key.getMoveX() * viewScale), (int) (key.getMoveY() * viewScale)); handles.updateRect(compSpaceRect); recalculateImageSpaceRect(ic); ic.repaint(); } }