/* * Copyright 2016 Cel Skeggs * * This file is part of the CCRE, the Common Chicken Runtime Engine. * * The CCRE is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * The CCRE 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with the CCRE. If not, see <http://www.gnu.org/licenses/>. */ package ccre.viewer; import java.awt.Color; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.io.IOException; import java.io.ObjectInputStream; import ccre.supercanvas.DraggableBoxComponent; /** * A draggable rectangle that can be used to keep track of a specific position * on the camera feed. * * @author skeggsc */ public class HighlightComponent extends DraggableBoxComponent { private static final long serialVersionUID = 4742533819471453628L; private static final Color[] chain = new Color[] { Color.BLACK, Color.RED, Color.BLUE, Color.ORANGE, Color.CYAN, Color.MAGENTA, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.PINK }; private static Color nextColor(Color color) { for (int i = 0; i < chain.length - 1; i++) { if (color.equals(chain[i])) { return chain[i + 1]; } } return chain[0]; } private transient ResizeState resizeState; private Color color = Color.BLACK; /** * Create a new HighlightComponent at the specified position. * * @param cx the X-coordinate. * @param cy the Y-coordinate. */ public HighlightComponent(int cx, int cy) { super(cx, cy, 1, false); halfWidth = 100; halfHeight = 50; resizeState = ResizeState.TRANSLATE; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); resizeState = ResizeState.TRANSLATE; } @Override public void moveForDrag(int x, int y) { int nx, ny; switch (resizeState) { case CORNER_BR: nx = 1; ny = 1; break; case CORNER_UR: nx = 1; ny = -1; break; case CORNER_BL: nx = -1; ny = 1; break; case CORNER_UL: nx = -1; ny = -1; break; default: super.moveForDrag(x, y); return; } int ox = centerX - nx * halfWidth; int oy = centerY - ny * halfHeight; halfWidth = x * nx / 2; halfHeight = y * ny / 2; if (halfWidth < 5) { halfWidth = 5; } if (halfHeight < 5) { halfHeight = 5; } centerX = ox + nx * halfWidth; centerY = oy + ny * halfHeight; } @Override public boolean canDrop() { return resizeState == ResizeState.TRANSLATE; } @Override public int getDragRelX(int x) { switch (resizeState) { case CORNER_BR: case CORNER_UR: return halfWidth * 2 - x; case CORNER_BL: case CORNER_UL: return -halfWidth * 2 - x; default: return super.getDragRelX(x); } } @Override public int getDragRelY(int y) { switch (resizeState) { case CORNER_BR: case CORNER_BL: return halfHeight * 2 - y; case CORNER_UR: case CORNER_UL: return -halfHeight * 2 - y; default: return super.getDragRelY(y); } } @Override public void render(Graphics2D g, int screenWidth, int screenHeight, FontMetrics fontMetrics, int mouseX, int mouseY) { g.setColor(color); g.drawRect(this.centerX - (this.halfWidth * 2) / 2, this.centerY - (this.halfHeight * 2) / 2, this.halfWidth * 2, this.halfHeight * 2); g.setColor(Color.WHITE); if (getPanel().editmode) { g.drawLine(centerX - halfWidth + 6, centerY - halfHeight + 10, centerX - halfWidth + 10, centerY - halfHeight + 6); g.drawLine(centerX + halfWidth - 6, centerY - halfHeight + 10, centerX + halfWidth - 10, centerY - halfHeight + 6); g.drawLine(centerX - halfWidth + 6, centerY + halfHeight - 10, centerX - halfWidth + 10, centerY + halfHeight - 6); g.drawLine(centerX + halfWidth - 6, centerY + halfHeight - 10, centerX + halfWidth - 10, centerY + halfHeight - 6); } } @Override public boolean onInteract(int x, int y) { this.color = nextColor(color); return true; } @Override public boolean onSelect(int x, int y) { if (containsForInteract(x, y)) { return onInteract(x, y); } resizeState = ResizeState.TRANSLATE; if (x >= centerX + halfWidth - 10) { if (y >= centerY + halfHeight - 10) { resizeState = ResizeState.CORNER_BR; } else if (y <= centerY - halfHeight + 10) { resizeState = ResizeState.CORNER_UR; } } else if (x <= centerX - halfWidth + 10) { if (y >= centerY + halfHeight - 10) { resizeState = ResizeState.CORNER_BL; } else if (y <= centerY - halfHeight + 10) { resizeState = ResizeState.CORNER_UL; } } getPanel().startDrag(this, x, y); return true; } @Override public String toString() { return "highlight"; } private static enum ResizeState { TRANSLATE, CORNER_BR, CORNER_UR, CORNER_BL, CORNER_UL } }