/* * Copyright 2014,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.supercanvas; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.io.Serializable; /** * A SuperCanvasComponent can be displayed and interacted with inside a * SuperCanvas. * * @author skeggsc */ public abstract class SuperCanvasComponent implements Serializable { private static final long serialVersionUID = -8154707099757626085L; /** * If true, don't show this component in operate mode. */ public final boolean hideInOperateMode; final int zIndex; private transient SuperCanvasPanel panel; /** * Create a new SuperCanvasComponent. This will be visible whether the * canvas is in EDIT mode or OPERATE mode. */ public SuperCanvasComponent() { zIndex = 0; hideInOperateMode = false; } /** * Create a new SuperCanvasComponent. * * @param zIndex the Z-index (ordering index) of this component. * @param hideInOperateMode if the component should be hidden when the * canvas is in OPERATE mode. */ public SuperCanvasComponent(int zIndex, boolean hideInOperateMode) { this.zIndex = zIndex; this.hideInOperateMode = hideInOperateMode; } /** * Called to render this component. * * @param g The graphics pen to use to render. * @param screenWidth The width of the screen. * @param screenHeight The height of the screen. * @param fontMetrics The metrics of the (monospaced) font. * @param mouseX The mouse X position. * @param mouseY The mouse Y position. */ public abstract void render(Graphics2D g, int screenWidth, int screenHeight, FontMetrics fontMetrics, int mouseX, int mouseY); /** * Check if the specified point is on this component. * * @param x The mouse X coordinate. * @param y The mouse Y coordinate. * @return if the point is contained in this component's area. */ public abstract boolean contains(int x, int y); /** * Called when the component is right-clicked. * * @param x The mouse X coordinate. * @param y The mouse Y coordinate. * @return true if the interaction event should not be sent to more * components. */ public abstract boolean onInteract(int x, int y); /** * Called when the component is left-clicked if it's not dragged. * * @param x The mouse X coordinate. * @param y The mouse Y coordinate. * @return true if the selection event should not be sent to more * components. */ public abstract boolean onSelect(int x, int y); /** * Called when the mouse enters this component. * * @param x The mouse X position. * @param y The mouse Y position. * @return true if the screen should be repainted because of this * transition. */ public boolean onMouseEnter(int x, int y) { return false; } /** * Called when the mouse moves within this component. * * @param x The mouse X position. * @param y The mouse Y position. * @return true if the screen should be repainted because of this change. */ public boolean onMouseMove(int x, int y) { return false; } /** * Called when the mouse exits this component. * * @param x The mouse X position. * @param y The mouse Y position. * @return true if the screen should be repainted because of this * transition. */ public boolean onMouseExit(int x, int y) { return false; } /** * Called when the mouse scroll wheel is changed while over this component. * * @param x The mouse X position. * @param y The mouse Y position. * @param wheelRotation The change in wheel rotation. * @return true if the scrolling event should not be sent to more * components. */ public boolean onScroll(int x, int y, int wheelRotation) { return false; } /** * Called when this component starts to be dragged to calculate the offset * used later - which will be added to the mouse position to get the new * position given to moveForDrag. * * @param x The mouse X position. * @return the relative X offset. */ public int getDragRelX(int x) { throw new UnsupportedOperationException("Dragging not supported!"); } /** * Called when this component starts to be dragged to calculate the offset * used later - which will be added to the mouse position to get the new * position given to moveForDrag. * * @param y The mouse Y position. * @return the relative Y offset. */ public int getDragRelY(int y) { throw new UnsupportedOperationException("Dragging not supported!"); } /** * Called when the component needs to be moved as part of a drag operation. * The relative difference between this position and the mouse position is * calculated by getDragRelX() and getDragRelY(). * * @param x The new X position. * @param y The new Y position. */ public void moveForDrag(int x, int y) { throw new UnsupportedOperationException("Dragging not supported!"); } /** * Called when the dragged entity is dropped onto this component. * * @param x The mouse X position. * @param y The mouse Y position. * @param activeEntity The entity that was dropped. * @return true if the drop has been received and shouldn't be sent to any * other components. */ public boolean onReceiveDrop(int x, int y, SuperCanvasComponent activeEntity) { return false; } void setPanel(SuperCanvasPanel npanel) { if (npanel == null) { throw new NullPointerException(); } if (panel != null) { throw new IllegalStateException("This already has a panel!"); } panel = npanel; onChangePanel(npanel); } void unsetPanel(SuperCanvasPanel npanel) { if (npanel == null) { throw new NullPointerException(); } if (panel != npanel) { throw new IllegalStateException("That's not the panel here!"); } panel = null; onChangePanel(null); } /** * @return the panel that this component is on. */ public SuperCanvasPanel getPanel() { return panel; } /** * Called when the current panel changes. * * @param newPanel the new panel. */ protected void onChangePanel(SuperCanvasPanel newPanel) { } /** * @return true if this component wants selection events to be sent while * the mouse is dragged, instead of just once when pressed. Note that this * is different from dragging components to move them. */ public boolean wantsDragSelect() { return false; } /** * @return true if this component can be dropped into other components (if * it gets dragged around). */ public boolean canDrop() { return true; } /** * Called when this component is about to be deleted. * * @param forced if this component has no choice in the matter. * @return false if this component doesn't want to be deleted. */ public boolean onDelete(boolean forced) { return true; } /** * Called to notify the component that enter has been pressed. */ public void onPressedEnter() { } /** * @return if dragging should be sent as a large number of interactions. */ public boolean canDragInteract() { return false; } }