0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.vmd.game.editor.scene;
0042:
0043: import java.awt.BorderLayout;
0044: import java.awt.Color;
0045: import java.awt.Dialog;
0046: import java.awt.Dimension;
0047: import java.awt.Font;
0048: import java.awt.Graphics;
0049: import java.awt.Graphics2D;
0050: import java.awt.Point;
0051: import java.awt.Rectangle;
0052: import java.awt.event.ActionEvent;
0053: import java.awt.event.ItemEvent;
0054: import java.awt.event.ItemListener;
0055: import java.awt.event.MouseEvent;
0056: import java.awt.event.MouseListener;
0057: import java.awt.event.MouseMotionListener;
0058: import java.awt.font.LineMetrics;
0059: import java.awt.geom.Rectangle2D;
0060: import java.beans.PropertyChangeEvent;
0061: import java.beans.PropertyChangeListener;
0062: import java.util.ArrayList;
0063: import java.util.HashMap;
0064: import java.util.HashSet;
0065: import java.util.Iterator;
0066: import java.util.List;
0067: import java.util.Map;
0068: import java.util.Set;
0069: import javax.swing.AbstractAction;
0070: import javax.swing.JCheckBoxMenuItem;
0071: import javax.swing.JComponent;
0072: import javax.swing.JMenu;
0073: import javax.swing.JPanel;
0074: import javax.swing.JPopupMenu;
0075: import javax.swing.SwingUtilities;
0076: import javax.swing.ToolTipManager;
0077: import javax.swing.UIManager;
0078: import org.netbeans.modules.vmd.game.dialog.NewSceneDialog;
0079: import org.netbeans.modules.vmd.game.model.Editable;
0080: import org.netbeans.modules.vmd.game.model.Layer;
0081: import org.netbeans.modules.vmd.game.model.Position;
0082: import org.netbeans.modules.vmd.game.model.Scene;
0083: import org.netbeans.modules.vmd.game.model.SceneListener;
0084: import org.netbeans.modules.vmd.game.model.SequenceContainer;
0085: import org.netbeans.modules.vmd.game.model.Sprite;
0086: import org.netbeans.modules.vmd.game.model.TiledLayer;
0087: import org.netbeans.modules.vmd.game.model.TiledLayerListener;
0088: import org.netbeans.modules.vmd.game.model.Scene.CreateSpriteAction;
0089: import org.netbeans.modules.vmd.game.model.Scene.CreateTiledLayerAction;
0090: import org.netbeans.modules.vmd.game.model.Scene.LayerInfo;
0091: import org.netbeans.modules.vmd.game.model.Scene.RemoveSceneAction;
0092: import org.netbeans.modules.vmd.game.model.Scene.RenameSceneAction;
0093: import org.netbeans.modules.vmd.game.nbdialog.SpriteDialog;
0094: import org.netbeans.modules.vmd.game.nbdialog.TiledLayerDialog;
0095: import org.openide.DialogDescriptor;
0096: import org.openide.DialogDisplayer;
0097: import org.openide.util.NbBundle;
0098:
0099: public class ScenePanel extends JPanel implements SceneListener,
0100: TiledLayerListener, PropertyChangeListener,
0101: MouseMotionListener, MouseListener {
0102:
0103: private static final boolean DEBUG = false;
0104:
0105: private static final int DEFAULT_GRID_X = 20;
0106: private static final int DEFAULT_GRID_Y = 20;
0107: private static final int GRID_MINORS_IN_A_MAJOR = 5;
0108:
0109: private static final Color COLOR_BG = Color.WHITE;
0110: private static final Color COLOR_GRID_MINOR = Color.GRAY;
0111: private static final Color COLOR_GRID_MAJOR = Color.BLACK;
0112: private static final Color COLOR_GRID_QUADRANT = Color.LIGHT_GRAY;
0113:
0114: private Scene scene;
0115:
0116: private Ruler horizontalRuler = new Ruler(Ruler.HORIZONTAL);
0117: private Ruler verticalRuler = new Ruler(Ruler.VERTICAL);
0118: private GridButton gridButton = new GridButton();
0119:
0120: private boolean showGrid = true;
0121: private boolean snapGrid = false;
0122:
0123: private int gridX = DEFAULT_GRID_X;
0124: private int gridY = DEFAULT_GRID_Y;
0125:
0126: // ///////// ANIMATION SUPPORT ///////////
0127: // TODO finish animation support for AnimatedTiles and Sprites
0128: private boolean animated;
0129:
0130: public ScenePanel(Scene scene) {
0131: ToolTipManager.sharedInstance().registerComponent(this );
0132: this .scene = scene;
0133: this .scene.addSceneListener(this );
0134: this .scene.addPropertyChangeListener(this );
0135: this .addMouseMotionListener(this );
0136: this .addMouseListener(this );
0137:
0138: this .getAccessibleContext().setAccessibleName(
0139: NbBundle.getMessage(ScenePanel.class,
0140: "ScenePanel.accessible.name"));
0141: this .getAccessibleContext().setAccessibleDescription(
0142: NbBundle.getMessage(ScenePanel.class,
0143: "ScenePanel.accessible.description"));
0144:
0145: for (Iterator iter = this .scene.getLayers().iterator(); iter
0146: .hasNext();) {
0147: Layer layer = (Layer) iter.next();
0148: this .registerLayerListeners(layer);
0149: }
0150: // vlv: print
0151: putClientProperty(java.awt.print.Printable.class, ""); // NOI18N
0152: }
0153:
0154: private void registerLayerListeners(Layer layer) {
0155: layer.addPropertyChangeListener(this );
0156: if (layer instanceof TiledLayer) {
0157: TiledLayer tl = (TiledLayer) layer;
0158: tl.addTiledLayerListener(this );
0159: }
0160: if (layer instanceof Sprite) {
0161: Sprite sprite = (Sprite) layer;
0162: // /sprite.addSequenceContainerListener(this);
0163: }
0164: }
0165:
0166: private void unregisterLayerListeners(Layer layer) {
0167: layer.removePropertyChangeListener(this );
0168: if (layer instanceof TiledLayer) {
0169: TiledLayer tl = (TiledLayer) layer;
0170: tl.removeTiledLayerListener(this );
0171: }
0172: if (layer instanceof Sprite) {
0173: Sprite sprite = (Sprite) layer;
0174: // sprite.removeSequenceContainerListener(this);
0175: }
0176: }
0177:
0178: public Dimension getPreferredSize() {
0179: Rectangle bounds = this .scene.getAllLayersBounds();
0180: bounds.add(0, 0);
0181: return bounds.getSize();
0182: }
0183:
0184: public void paintComponent(Graphics g) {
0185: //System.out.println("paintComponent " + g.getClipBounds());
0186: this .clearBackground(g);
0187:
0188: this .drawQuadrants(g);
0189:
0190: if (isShowGrid()) {
0191: this .drawGrid(g);
0192: }
0193:
0194: this .drawSceneItems(g);
0195: }
0196:
0197: private void clearBackground(Graphics g) {
0198: Rectangle rect = g.getClipBounds();
0199: g.setColor(COLOR_BG);
0200: g.fillRect(rect.x, rect.y, rect.width, rect.height);
0201: }
0202:
0203: private void drawGrid(Graphics g) {
0204: Point quadrantOrigin = this .adjustFromOriginShift(new Point(0,
0205: 0));
0206:
0207: Rectangle rect = g.getClipBounds();
0208: //System.out.println("repaint " + rect);
0209: int colMin = (int) (rect.getX() / this .gridX);
0210: int colMax = (int) ((rect.getX() + rect.getWidth()) / this .gridX);
0211:
0212: int rowMin = (int) (rect.getY() / this .gridY);
0213: int rowMax = (int) ((rect.getY() + rect.getHeight()) / this .gridY);
0214:
0215: for (int r = rowMin; r <= rowMax; r++) {
0216: for (int c = colMin; c <= colMax; c++) {
0217: if ((0 == (c % GRID_MINORS_IN_A_MAJOR))
0218: || (0 == (r % GRID_MINORS_IN_A_MAJOR))) {
0219: g.setColor(COLOR_GRID_MAJOR);
0220: } else {
0221: g.setColor(COLOR_GRID_MINOR);
0222: }
0223: int x = (c * this .gridX) + quadrantOrigin.x
0224: % this .gridX;
0225: int y = (r * this .gridY) + quadrantOrigin.y
0226: % this .gridY;
0227: //System.out.println("dot: " + x + ", " + y);
0228: g.drawLine(x, y, x, y);
0229: }
0230: }
0231: }
0232:
0233: private void drawQuadrants(Graphics g) {
0234: Point quadrantOrigin = this .adjustFromOriginShift(new Point(0,
0235: 0));
0236:
0237: Rectangle clip = g.getClipBounds();
0238: g.setColor(COLOR_GRID_QUADRANT);
0239:
0240: // vertical quadrant separator
0241: if (clip.intersectsLine(quadrantOrigin.x, Integer.MAX_VALUE,
0242: quadrantOrigin.x, Integer.MIN_VALUE)) {
0243: g.drawLine(quadrantOrigin.x, clip.y, quadrantOrigin.x,
0244: clip.y + clip.height);
0245: }
0246:
0247: // horizontal quadrant separator
0248: if (clip.intersectsLine(Integer.MAX_VALUE, quadrantOrigin.y,
0249: Integer.MIN_VALUE, quadrantOrigin.y)) {
0250: g.drawLine(clip.x, quadrantOrigin.y, clip.x + clip.width,
0251: quadrantOrigin.y);
0252: }
0253: }
0254:
0255: private void drawSceneItems(Graphics g) {
0256: this .drawLayers(g);
0257: for (int i = 0; i < this .scene.getLayerCount(); i++) {
0258: Layer layer = (Layer) this .scene.getLayerAt(i);
0259: this .drawLayerDecorations((Graphics2D) g, layer);
0260: }
0261: }
0262:
0263: void drawLayers(Graphics g) {
0264: for (int i = this .scene.getLayerCount() - 1; i >= 0; i--) {
0265: Layer layer = (Layer) this .scene.getLayerAt(i);
0266: if (this .scene.isLayerVisible(layer)) {
0267: this .drawLayer(g, layer);
0268: }
0269: }
0270: }
0271:
0272: private void drawLayer(Graphics g, Layer layer) {
0273: Rectangle origClipBounds = g.getClipBounds();
0274: Point layerPos = scene.getLayerPosition(layer);
0275: this .adjustFromOriginShift(layerPos);
0276: Rectangle layerRect = new Rectangle(layerPos.x, layerPos.y,
0277: layer.getWidth(), layer.getHeight());
0278:
0279: Rectangle intersection = layerRect.intersection(origClipBounds);
0280: if (intersection.isEmpty())
0281: return;
0282:
0283: // set the graphics object relative to layer
0284: g.setClip(intersection);
0285: g.translate(layerPos.x, layerPos.y);
0286:
0287: // paint layer
0288: layer.paint((Graphics2D) g);
0289:
0290: // reset the graphics object
0291: g.translate(-layerPos.x, -layerPos.y);
0292: g.setClip(origClipBounds);
0293: }
0294:
0295: private void drawLayerDecorations(Graphics2D g, Layer layer) {
0296: if (!this .hilitedLayers.containsKey(layer)
0297: && !this .selectedLayers.contains(layer)) {
0298: return;
0299: }
0300:
0301: if (this .selectedLayers.contains(layer)) {
0302: if (this .scene.isLayerLocked(layer)) {
0303: g.setColor(colorSelectionLocked);
0304: } else {
0305: g.setColor(colorSelection);
0306: }
0307: } else if (this .hilitedLayers.containsKey(layer)) {
0308: g.setColor(this .hilitedLayers.get(layer));
0309: } else {
0310: return;
0311: }
0312:
0313: Rectangle r = null;
0314:
0315: //top
0316: r = this .getDecorationRectangleForLayerBottom(layer);
0317: r.translate(0, -layer.getHeight() - DECOR_BOTTOM_H);
0318: g.fillRect(r.x, r.y, r.width, r.height);
0319: //bottom
0320: r = this .getDecorationRectangleForLayerBottom(layer);
0321: g.fillRect(r.x, r.y, r.width, r.height);
0322: //left
0323: r = this .getDecorationRectangleForLayerLeft(layer);
0324: g.fillRect(r.x, r.y, r.width, r.height);
0325: //right
0326: r = this .getDecorationRectangleForLayerRight(layer);
0327: g.fillRect(r.x, r.y, r.width, r.height);
0328: }
0329:
0330: private static final int DECOR_TOP_W = 0;
0331: private static final int DECOR_TOP_H = 25;
0332: private static final int DECOR_SIDE_W = 5;
0333: private static final int DECOR_BOTTOM_W = 5;
0334: private static final int DECOR_BOTTOM_H = 5;
0335:
0336: private Rectangle getDecorationRectangleForLayerTop(Layer layer) {
0337: Point pos = this .adjustFromOriginShift(scene
0338: .getLayerPosition(layer));
0339: return this .getDecorationRectangleForLayerTop(pos, layer);
0340: }
0341:
0342: private Rectangle getDecorationRectangleForLayerBottom(Layer layer) {
0343: Point pos = this .adjustFromOriginShift(scene
0344: .getLayerPosition(layer));
0345: return this .getDecorationRectangleForLayerBottom(pos, layer);
0346: }
0347:
0348: private Rectangle getDecorationRectangleForLayerLeft(Layer layer) {
0349: Point pos = this .adjustFromOriginShift(scene
0350: .getLayerPosition(layer));
0351: return this .getDecorationRectangleForLayerLeft(pos, layer);
0352: }
0353:
0354: private Rectangle getDecorationRectangleForLayerRight(Layer layer) {
0355: Point pos = this .adjustFromOriginShift(scene
0356: .getLayerPosition(layer));
0357: return this .getDecorationRectangleForLayerRight(pos, layer);
0358: }
0359:
0360: private Rectangle getDecorationRectangleForLayerTop(Point pos,
0361: Layer layer) {
0362: return new Rectangle(pos.x - DECOR_TOP_W, pos.y - DECOR_TOP_H,
0363: DECOR_TOP_W + layer.getWidth() + DECOR_TOP_W,
0364: DECOR_TOP_H);
0365: }
0366:
0367: private Rectangle getDecorationRectangleForLayerBottom(Point pos,
0368: Layer layer) {
0369: return new Rectangle(pos.x - DECOR_BOTTOM_W, pos.y
0370: + layer.getHeight(), DECOR_BOTTOM_W + layer.getWidth()
0371: + DECOR_BOTTOM_W, DECOR_BOTTOM_H);
0372: }
0373:
0374: private Rectangle getDecorationRectangleForLayerLeft(Point pos,
0375: Layer layer) {
0376: return new Rectangle(pos.x - DECOR_SIDE_W, pos.y, DECOR_SIDE_W,
0377: layer.getHeight());
0378: }
0379:
0380: private Rectangle getDecorationRectangleForLayerRight(Point pos,
0381: Layer layer) {
0382: return new Rectangle(pos.x + layer.getWidth(), pos.y,
0383: DECOR_SIDE_W, layer.getHeight());
0384: }
0385:
0386: private void repaintLayerWithDecorations(Layer layer) {
0387: Point p = this .scene.getLayerPosition(layer);
0388: this .repaintLayerWithDecorations(p, layer);
0389: }
0390:
0391: private void repaintLayerWithDecorations(Point posUnadjusted,
0392: Layer layer) {
0393: Point pos = this .adjustFromOriginShift(posUnadjusted);
0394: this .repaintLayer(pos, layer);
0395: this .repaintLayerDecorations(pos, layer);
0396: }
0397:
0398: private void repaintLayer(Layer layer) {
0399: Point p = this .adjustFromOriginShift(this .scene
0400: .getLayerPosition(layer));
0401: this .repaintLayer(p, layer);
0402: }
0403:
0404: private void repaintLayer(Point pos, Layer layer) {
0405: this .repaint(pos.x, pos.y, layer.getWidth(), layer.getHeight());
0406: }
0407:
0408: private void repaintLayerDecorations(Point pos, Layer layer) {
0409: this
0410: .repaint(this .getDecorationRectangleForLayerTop(pos,
0411: layer));
0412: this .repaint(this .getDecorationRectangleForLayerBottom(pos,
0413: layer));
0414: this .repaint(this
0415: .getDecorationRectangleForLayerLeft(pos, layer));
0416: this .repaint(this .getDecorationRectangleForLayerRight(pos,
0417: layer));
0418: }
0419:
0420: private void repaintLayerDecorations(Layer layer) {
0421: if (layer == null)
0422: return;
0423: Point p = this .adjustFromOriginShift(this .scene
0424: .getLayerPosition(layer));
0425: this .repaintLayerDecorations(p, layer);
0426: }
0427:
0428: private void repaintAllLayerDecorations() {
0429: List<Layer> layers = this .scene.getLayers();
0430: for (Layer layer : layers) {
0431: this .repaintLayerDecorations(layer);
0432: }
0433: }
0434:
0435: // -------- SceneListener ---------
0436:
0437: public void layerAdded(Scene sourceScene, Layer layer, int index) {
0438: this .registerLayerListeners(layer);
0439: //this.repaintLayerWithDecorations(layer);
0440: this .repaintAllLayerDecorations();
0441: }
0442:
0443: public void layerMoved(Scene sourceScene, Layer layer,
0444: int indexOld, int indexNew) {
0445: //this.repaintLayerWithDecorations(layer);
0446: this .repaintAllLayerDecorations();
0447: }
0448:
0449: public void layerRemoved(Scene sourceScene, Layer layer,
0450: LayerInfo info, int index) {
0451: this .unregisterLayerListeners(layer);
0452: //this.repaintLayerWithDecorations(layer);
0453: this .repaintAllLayerDecorations();
0454: }
0455:
0456: public void layerLockChanged(Scene sourceScene, Layer layer,
0457: boolean locked) {
0458: this .repaintAllLayerDecorations();
0459: }
0460:
0461: public void layerPositionChanged(Scene sourceScene, Layer layer,
0462: Point oldPosition, Point newPosition, boolean inTransition) {
0463: this .repaintLayerWithDecorations(oldPosition, layer);
0464: this .repaintLayerWithDecorations(newPosition, layer);
0465: }
0466:
0467: public void layerVisibilityChanged(Scene sourceScene, Layer layer,
0468: boolean visible) {
0469: this .repaintLayerWithDecorations(layer);
0470: }
0471:
0472: private Point adjustFromOriginShift(Point p) {
0473: Rectangle layersBox = this .scene.getAllLayersBounds();
0474: layersBox.add(0, 0);
0475: p.translate(-layersBox.x, -layersBox.y);
0476: return p;
0477: }
0478:
0479: private Point adjustToOriginShift(Point p) {
0480: Rectangle layersBox = this .scene.getAllLayersBounds();
0481: layersBox.add(0, 0);
0482: p.translate(layersBox.x, layersBox.y);
0483: return p;
0484: }
0485:
0486: // -------- PropertyChangeListener ---------
0487:
0488: public void propertyChange(PropertyChangeEvent e) {
0489: //System.out.println("ScenePanel.propertyChange: " + e);
0490: if (e.getSource() == this .scene) {
0491: if (e.getPropertyName()
0492: .equals(Scene.PROPERTY_LAYERS_BOUNDS)) {
0493: this .revalidate();
0494: this .repaint();
0495: this .horizontalRuler.repaint();
0496: this .verticalRuler.repaint();
0497: }
0498: } else if (e.getSource() instanceof TiledLayer) {
0499: TiledLayer tl = (TiledLayer) e.getSource();
0500: // TODO
0501: } else if (e.getSource() instanceof Sprite) {
0502: Sprite s = (Sprite) e.getSource();
0503: if (e.getPropertyName().equals(
0504: SequenceContainer.PROPERTY_DEFAULT_SEQUENCE)) {
0505: this .repaintLayerWithDecorations(s);
0506: } else if (e.getPropertyName().equals(
0507: Editable.PROPERTY_NAME)) {
0508: // TODO
0509: }
0510: }
0511: }
0512:
0513: // -------- TiledLayerListener ---------
0514:
0515: public void columnsInserted(TiledLayer source, int index, int count) {
0516: this .repaintLayerWithDecorations(source);
0517: }
0518:
0519: public void columnsRemoved(TiledLayer source, int index, int count) {
0520: this .repaintLayerWithDecorations(source);
0521: }
0522:
0523: public void rowsInserted(TiledLayer source, int index, int count) {
0524: this .repaintLayerWithDecorations(source);
0525: }
0526:
0527: public void rowsRemoved(TiledLayer source, int index, int count) {
0528: this .repaintLayerWithDecorations(source);
0529: }
0530:
0531: public void tilesStructureChanged(TiledLayer source) {
0532: this .repaintLayerWithDecorations(source);
0533: }
0534:
0535: public void tileChanged(TiledLayer source, int row, int col) {
0536: int w = source.getTileWidth();
0537: int h = source.getTileHeight();
0538: Point p = this .scene.getLayerPosition(source);
0539: p.translate(col * w, row * h);
0540: this .adjustFromOriginShift(p);
0541: this .repaint(p.x, p.y, w, h);
0542: }
0543:
0544: public void tilesChanged(TiledLayer source, Set positions) {
0545: for (Object object : positions) {
0546: Position pos = (Position) object;
0547: this .tileChanged(source, pos.getRow(), pos.getCol());
0548: }
0549: }
0550:
0551: public String getToolTipText(MouseEvent e) {
0552: StringBuffer sb = new StringBuffer();
0553: Point p = this .adjustToOriginShift(e.getPoint());
0554: List<Layer> layers = this .scene.getLayersAtPoint(p);
0555: if (layers.isEmpty()) {
0556: return null;
0557: }
0558: for (Layer layer : layers) {
0559: sb.append(layer.getName());
0560: sb.append(", ");
0561: }
0562: sb.setLength(sb.length() - 2);
0563: return sb.toString();
0564: }
0565:
0566: // -------- MouseMotionListener ---------
0567:
0568: private Layer topHilitedLayer;
0569: private Map<Layer, Color> hilitedLayers = new HashMap<Layer, Color>();
0570: private Color colorSelection = new Color(0, 0, 255, 170);
0571: private Color colorSelectionLocked = new Color(255, 0, 0, 170);
0572: private Color colorHilitePrimary = new Color(0, 0, 0, 120);
0573: private Color colorHiliteSecondary = new Color(0, 0, 0, 50);
0574:
0575: public void mouseMoved(MouseEvent e) {
0576: Point p = this .adjustToOriginShift(e.getPoint());
0577: List<Layer> layers = this .scene.getLayersAtPoint(p);
0578: if (layers.size() == 0)
0579: return;
0580:
0581: //add hilited layers
0582: for (Layer layer : layers) {
0583: if (!hilitedLayers.containsKey(layer)) {
0584: this .hilitedLayers.put(layer, colorHiliteSecondary);
0585: this .repaintLayerDecorations(layer);
0586: }
0587: }
0588: Layer oldTop = this .topHilitedLayer;
0589: Layer top = layers.get(0);
0590: if (oldTop != top) {
0591: this .hilitedLayers.put(top, colorHilitePrimary);
0592: this .hilitedLayers.put(oldTop, colorHiliteSecondary);
0593: this .topHilitedLayer = top;
0594: this .repaintLayerDecorations(oldTop);
0595: this .repaintLayerDecorations(top);
0596: }
0597:
0598: //find layers that are no longer hilited
0599: for (Iterator iter = this .hilitedLayers.keySet().iterator(); iter
0600: .hasNext();) {
0601: Layer layer = (Layer) iter.next();
0602: if (!layers.contains(layer)) {
0603: this .repaintLayerDecorations(layer);
0604: iter.remove();
0605: }
0606: }
0607: }
0608:
0609: private Set<Layer> selectedLayers = new HashSet<Layer>();
0610: private Map<Layer, Point> dragLayerStartPoints = new HashMap<Layer, Point>();
0611:
0612: private Point startDragPoint = null;
0613: private Point lastDragPoint = null;
0614: private Layer snapToGridReferenceLayer = null;
0615: private String dragDirectionVertical = BorderLayout.NORTH;
0616: private String dragDirectionHorizontal = BorderLayout.WEST;
0617:
0618: private boolean mouseDragging;
0619:
0620: private void clearSelectedLayers() {
0621: for (Iterator iter = this .selectedLayers.iterator(); iter
0622: .hasNext();) {
0623: Layer layer = (Layer) iter.next();
0624: iter.remove();
0625: this .repaintLayerDecorations(layer);
0626: }
0627: this .dragLayerStartPoints.clear();
0628: this .lastDragPoint = null;
0629: this .startDragPoint = null;
0630: this .snapToGridReferenceLayer = null;
0631: this .dragDirectionHorizontal = BorderLayout.WEST;
0632: this .dragDirectionVertical = BorderLayout.NORTH;
0633: }
0634:
0635: private void addSelectedLayer(Layer layer, boolean toogleSelection) {
0636: if (toogleSelection) {
0637: if (this .selectedLayers.contains(layer)) {
0638: this .selectedLayers.remove(layer);
0639: } else {
0640: this .selectedLayers.add(layer);
0641: }
0642: } else {
0643: this .selectedLayers.add(layer);
0644: }
0645:
0646: this .repaintLayerDecorations(layer);
0647:
0648: //TODO : repaint only the layer outlines not the whole rulers
0649: this .horizontalRuler.repaint();
0650: this .verticalRuler.repaint();
0651: }
0652:
0653: public void mouseDragged(MouseEvent e) {
0654: //System.out.println("mouseDragged");
0655: Point p = this .adjustToOriginShift(e.getPoint());
0656:
0657: //initialize dragging
0658: if (this .mouseDragging == false) {
0659: //check that there are layers to drag and that were starting the drag inside a layer
0660: if (selectedLayers.isEmpty()
0661: || this .scene.getLayersAtPoint(p).isEmpty())
0662: return;
0663:
0664: //make sure that we are starting the drag inside a layer selected for dragging
0665: boolean dragStartPointOK = false;
0666: for (Layer selectedLayer : this .selectedLayers) {
0667: if (scene.getLayerBounds(selectedLayer).contains(p)) {
0668: dragStartPointOK = true;
0669: break;
0670: }
0671: }
0672: if (!dragStartPointOK)
0673: return;
0674:
0675: //now i know i am doing a drag and that the cursor is inside a dragged layer
0676: //use the topmost layer as the reference for snapping to grid
0677: for (Layer tmp : this .scene.getLayersAtPoint(p)) {
0678: if (this .selectedLayers.contains(tmp)) {
0679: this .snapToGridReferenceLayer = tmp;
0680: break;
0681: }
0682: }
0683:
0684: for (Layer dragLayer : this .selectedLayers) {
0685: this .dragLayerStartPoints.put(dragLayer, this .scene
0686: .getLayerPosition(dragLayer));
0687: }
0688:
0689: this .startDragPoint = p;
0690: this .mouseDragging = true;
0691: return;
0692: }
0693:
0694: int dx = p.x - this .startDragPoint.x;
0695: int dy = p.y - this .startDragPoint.y;
0696:
0697: //determine the direction of drag
0698: if (this .lastDragPoint != null) {
0699: if (p.x < this .lastDragPoint.x) {
0700: //System.out.println("drag left");
0701: this .dragDirectionHorizontal = BorderLayout.WEST;
0702: } else if (p.x > this .lastDragPoint.x) {
0703: //System.out.println("drag right");
0704: this .dragDirectionHorizontal = BorderLayout.EAST;
0705: }
0706: if (p.y < this .lastDragPoint.y) {
0707: //System.out.println("drag up");
0708: this .dragDirectionVertical = BorderLayout.NORTH;
0709: } else if (p.y > this .lastDragPoint.y) {
0710: //System.out.println("drag down");
0711: this .dragDirectionVertical = BorderLayout.SOUTH;
0712: }
0713: }
0714:
0715: //if grid snapping
0716: if (isSnapGrid() && (this .lastDragPoint != null)) {
0717: Point delta = findSnapToGridDelta(p, dx, dy);
0718: this .translateSelectedLayers(delta.x, delta.y, true);
0719: } else {
0720: //System.out.println("translate dx = " + dx);
0721: this .translateSelectedLayers(dx, dy, true);
0722: }
0723:
0724: this .lastDragPoint = p;
0725: //System.out.println("last drag point: " + this.lastDragPoint);
0726:
0727: //TODO : repaint only the layer outlines not the whole rulers
0728: this .horizontalRuler.repaint();
0729: this .verticalRuler.repaint();
0730:
0731: //make sure to scroll while dragging outside the visible area
0732: this .scrollRectToVisible(new Rectangle(e.getPoint()));
0733: }
0734:
0735: private Point findSnapToGridDelta(Point p, int dx, int dy) {
0736: Point s = new Point(this .dragLayerStartPoints
0737: .get(snapToGridReferenceLayer));
0738:
0739: //reference point for grid snapping
0740: Point ref = new Point(s);
0741: ref.translate(dx, dy);
0742:
0743: if (p.x < this .lastDragPoint.x) {
0744: //do nothing
0745: } else if (p.x > this .lastDragPoint.x) {
0746: ref.translate(this .snapToGridReferenceLayer.getWidth(), 0);
0747: } else {
0748: if (this .dragDirectionHorizontal == BorderLayout.EAST) {
0749: ref.translate(this .snapToGridReferenceLayer.getWidth(),
0750: 0);
0751: }
0752: }
0753: if (p.y < this .lastDragPoint.y) {
0754: //do nothing
0755: } else if (p.y > this .lastDragPoint.y) {
0756: ref.translate(0, this .snapToGridReferenceLayer.getHeight());
0757: } else {
0758: if (this .dragDirectionVertical == BorderLayout.SOUTH) {
0759: ref.translate(0, this .snapToGridReferenceLayer
0760: .getHeight());
0761: }
0762: }
0763:
0764: //find grid point closest to the reference point
0765: Point nearest = this .findNearestGridPoint(ref);
0766:
0767: //translate nearest to be at the left top corner of the layer
0768: if (this .dragDirectionHorizontal == BorderLayout.EAST) {
0769: nearest.translate(
0770: -this .snapToGridReferenceLayer.getWidth(), 0);
0771: //System.out.println("moving EAST - setting left top at " + nearest);
0772: }
0773: if (this .dragDirectionVertical == BorderLayout.SOUTH) {
0774: nearest.translate(0, -this .snapToGridReferenceLayer
0775: .getHeight());
0776: //System.out.println("moving SOUTH - setting left top at " + nearest);
0777: }
0778:
0779: dx = nearest.x - s.x;
0780: dy = nearest.y - s.y;
0781:
0782: return new Point(dx, dy);
0783: }
0784:
0785: private Point findNearestGridPoint(Point p) {
0786:
0787: Point nearest = new Point(p);
0788: int offX = p.x % this .gridX;
0789: int offY = p.y % this .gridY;
0790:
0791: if (offX == 0 && offY == 0) {
0792: return nearest;
0793: }
0794:
0795: if (offX != 0) {
0796: int gx1 = (p.x / this .gridX);
0797: int gx2 = (p.x >= 0 ? gx1 + 1 : gx1 - 1);
0798: gx1 *= this .gridX;
0799: gx2 *= this .gridX;
0800: //System.out.println("X " + gx1 + " -- " + gx2);
0801: if (Math.abs(p.x - gx1) < Math.abs(p.x - gx2)) {
0802: nearest.x = gx1;
0803: } else {
0804: nearest.x = gx2;
0805: }
0806: }
0807:
0808: if (offY != 0) {
0809: int gy1 = (p.y / this .gridY);
0810: int gy2 = (p.y >= 0 ? gy1 + 1 : gy1 - 1);
0811: gy1 *= this .gridY;
0812: gy2 *= this .gridY;
0813: //System.out.println("Y " + gy1 + " -- " + gy2);
0814: if (Math.abs(p.y - gy1) < Math.abs(p.y - gy2)) {
0815: nearest.y = gy1;
0816: } else {
0817: nearest.y = gy2;
0818: }
0819: }
0820: //System.out.println(p + " -> " + nearest);
0821: return nearest;
0822: }
0823:
0824: private void translateSelectedLayers(int dx, int dy,
0825: boolean inTransition) {
0826: //System.out.println("translate dx: " + dx + ", dy: " + dy + ", " + inTransition);
0827: for (Layer dragLayer : this .selectedLayers) {
0828: Point slp = new Point(this .dragLayerStartPoints
0829: .get(dragLayer));
0830: slp.translate(dx, dy);
0831: if (this .scene.isLayerLocked(dragLayer)) {
0832: continue;
0833: }
0834: this .scene.setLayerPosition(dragLayer, slp, inTransition);
0835: }
0836: }
0837:
0838: // -------- MouseListener ---------
0839:
0840: private Layer lastAddedLayerByMousePress = null;
0841:
0842: public void mouseReleased(MouseEvent e) {
0843: //System.out.println("mouseReleased");
0844: if (e.isPopupTrigger()) {
0845: this .handlePopUp(e);
0846: return;
0847: }
0848:
0849: Point p = this .adjustToOriginShift(e.getPoint());
0850: List<Layer> layers = this .scene.getLayersAtPoint(p);
0851: if (!layers.isEmpty()) {
0852: Layer layer = layers.get(0);
0853: if (this .mouseDragging == false
0854: && this .lastAddedLayerByMousePress != layer) {
0855: if (!this .isMultiSelect(e)) {
0856: this .clearSelectedLayers();
0857: }
0858: }
0859: if (this .mouseDragging == true
0860: && this .lastDragPoint != null
0861: && this .startDragPoint != null) {
0862: int dx = this .lastDragPoint.x - this .startDragPoint.x;
0863: int dy = this .lastDragPoint.y - this .startDragPoint.y;
0864: if (isSnapGrid()) {
0865: Point delta = findSnapToGridDelta(
0866: this .lastDragPoint, dx, dy);
0867: this .translateSelectedLayers(delta.x, delta.y,
0868: false);
0869: } else {
0870: this .translateSelectedLayers(dx, dy, false);
0871: }
0872: }
0873: }
0874: this .mouseDragging = false;
0875: }
0876:
0877: public void mousePressed(MouseEvent e) {
0878: //System.out.println("mousePressed");
0879: this .mouseDragging = false;
0880: this .lastAddedLayerByMousePress = null;
0881: if (e.isPopupTrigger()) {
0882: this .handlePopUp(e);
0883: return;
0884: }
0885:
0886: //only left mouse button manipulates the scene
0887: if (!SwingUtilities.isLeftMouseButton(e)) {
0888: return;
0889: }
0890: Point p = this .adjustToOriginShift(e.getPoint());
0891: List<Layer> layers = this .scene.getLayersAtPoint(p);
0892:
0893: if (!isMultiSelect(e)) {
0894: for (Layer layer : layers) {
0895: if (this .selectedLayers.contains(layer)) {
0896: return;
0897: }
0898: }
0899: //System.out.println("NOT MultiSelect - clearDragSelection");
0900: this .clearSelectedLayers();
0901: }
0902: if (layers.isEmpty()) {
0903: Layer tmp = this .topHilitedLayer;
0904: this .topHilitedLayer = null;
0905: this .hilitedLayers.remove(tmp);
0906: this .repaintLayerDecorations(tmp);
0907: return;
0908: }
0909:
0910: Layer layer = layers.get(0);
0911: if (!this .selectedLayers.contains(layer)) {
0912: this .addSelectedLayer(layer, false);
0913: this .lastAddedLayerByMousePress = layer;
0914: this .repaintLayerDecorations(layer);
0915: } else {
0916: if (isMultiSelect(e)) {
0917: this .addSelectedLayer(layer, true);
0918: }
0919: }
0920: //System.out.println("selected layer: " + layer);
0921: }
0922:
0923: public void mouseClicked(MouseEvent e) {
0924: //System.out.println("mouseClicked");
0925: this .mouseDragging = false;
0926: if (e.getClickCount() >= 2) {
0927:
0928: Point p = this .adjustToOriginShift(e.getPoint());
0929: List<Layer> layers = this .scene.getLayersAtPoint(p);
0930: if (!layers.isEmpty()) {
0931: this .scene.getGameDesign().getMainView()
0932: .requestEditing(layers.get(0));
0933: }
0934: }
0935: }
0936:
0937: public void mouseEntered(MouseEvent arg0) {
0938: }
0939:
0940: public void mouseExited(MouseEvent arg0) {
0941: }
0942:
0943: private void handlePopUp(MouseEvent e) {
0944:
0945: //scene stuff
0946:
0947: // CreateSceneAction cs = new CreateSceneAction();
0948: DuplicateSceneAction ds = new DuplicateSceneAction();
0949: RenameSceneAction rs = this .scene.new RenameSceneAction();
0950: RemoveSceneAction rsa = this .scene.new RemoveSceneAction();
0951:
0952: //add stuff
0953:
0954: CreateTiledLayerAction ctl = this .scene.new CreateTiledLayerAction();
0955: CreateSpriteAction csp = this .scene.new CreateSpriteAction();
0956:
0957: JMenu sub2MenuTiledLayers = new JMenu(NbBundle.getMessage(
0958: ScenePanel.class, "ScenePanel.menuAddTiledLayer.txt"));
0959: List<TiledLayer> tiledLayers = this .scene.getGameDesign()
0960: .getTiledLayers();
0961: for (TiledLayer layer : tiledLayers) {
0962: if (this .scene.contains(layer)) {
0963: continue;
0964: }
0965: AddLayerAction al = new AddLayerAction();
0966: al.putValue(AbstractAction.NAME, layer.getName());
0967: al.putValue(AddLayerAction.PROP_LAYER, layer);
0968: al.putValue(AddLayerAction.PROP_POSITION, this
0969: .adjustToOriginShift(e.getPoint()));
0970: sub2MenuTiledLayers.add(al);
0971: }
0972: if (sub2MenuTiledLayers.getItemCount() == 0) {
0973: sub2MenuTiledLayers.setEnabled(false);
0974: }
0975:
0976: JMenu sub2MenuSprites = new JMenu(NbBundle.getMessage(
0977: ScenePanel.class, "ScenePanel.menuAddSprite.txt"));
0978: List<Sprite> sprites = this .scene.getGameDesign().getSprites();
0979: for (Sprite layer : sprites) {
0980: if (this .scene.contains(layer)) {
0981: continue;
0982: }
0983: AddLayerAction al = new AddLayerAction();
0984: al.putValue(AbstractAction.NAME, layer.getName());
0985: al.putValue(AddLayerAction.PROP_LAYER, layer);
0986: al.putValue(AddLayerAction.PROP_POSITION, this
0987: .adjustToOriginShift(e.getPoint()));
0988: sub2MenuSprites.add(al);
0989: }
0990: if (sub2MenuSprites.getItemCount() == 0) {
0991: sub2MenuSprites.setEnabled(false);
0992: }
0993:
0994: //order stuff
0995:
0996: JMenu sub2MenuPushUp = new JMenu(NbBundle.getMessage(
0997: ScenePanel.class, "ScenePanel.menuPushUp.txt"));
0998: JMenu sub2MenuPushDown = new JMenu(NbBundle.getMessage(
0999: ScenePanel.class, "ScenePanel.menuPushDown.txt"));
1000: JMenu sub2MenuToTop = new JMenu(NbBundle.getMessage(
1001: ScenePanel.class, "ScenePanel.menuLayerToTop.txt"));
1002: JMenu sub2MenuToBottom = new JMenu(NbBundle.getMessage(
1003: ScenePanel.class, "ScenePanel.menuLayerToBottom.txt"));
1004:
1005: Point poitAdjusted = this .adjustToOriginShift(e.getPoint());
1006: List<Layer> layersUnderCursor = this .scene
1007: .getLayersAtPoint(poitAdjusted);
1008:
1009: if (layersUnderCursor.size() < 2) {
1010: sub2MenuPushUp.setEnabled(false);
1011: sub2MenuPushDown.setEnabled(false);
1012: } else {
1013: //can push up any except the first (it's already on top)
1014: for (int i = 0; i < layersUnderCursor.size(); i++) {
1015: PushUpLayerAction pul = new PushUpLayerAction();
1016: sub2MenuPushUp.add(pul);
1017: pul.putValue(AbstractAction.NAME, layersUnderCursor
1018: .get(i).getName());
1019: if (i == 0) {
1020: pul.setEnabled(false);
1021: continue;
1022: }
1023: pul.putValue(PushUpLayerAction.PROP_LAYER,
1024: layersUnderCursor.get(i));
1025: pul.putValue(PushUpLayerAction.PROP_LAYER_TO_TOP,
1026: layersUnderCursor.get(i - 1));
1027: }
1028: //can push down any except the last (it's already at bottom)
1029: for (int i = 0; i < layersUnderCursor.size(); i++) {
1030: PushDownLayerAction pdl = new PushDownLayerAction();
1031: sub2MenuPushDown.add(pdl);
1032: pdl.putValue(AbstractAction.NAME, layersUnderCursor
1033: .get(i).getName());
1034: if (i == layersUnderCursor.size() - 1) {
1035: pdl.setEnabled(false);
1036: continue;
1037: }
1038: pdl.putValue(PushDownLayerAction.PROP_LAYER,
1039: layersUnderCursor.get(i));
1040: pdl.putValue(PushDownLayerAction.PROP_LAYER_TO_BELOW,
1041: layersUnderCursor.get(i + 1));
1042: }
1043: }
1044:
1045: //can push to the top any except the one that's already on top
1046: for (int i = 0; i < layersUnderCursor.size(); i++) {
1047: LayerToTopAction ltt = new LayerToTopAction();
1048: sub2MenuToTop.add(ltt);
1049: ltt.putValue(AbstractAction.NAME, layersUnderCursor.get(i)
1050: .getName());
1051: if (this .scene.getLayerAt(0) == layersUnderCursor.get(i)) {
1052: ltt.setEnabled(false);
1053: continue;
1054: }
1055: ltt.putValue(LayerToTopAction.PROP_LAYER, layersUnderCursor
1056: .get(i));
1057: }
1058: if (layersUnderCursor.isEmpty()) {
1059: sub2MenuToTop.setEnabled(false);
1060: }
1061:
1062: //can push any to the bottom except the one that's already at bottom
1063: for (int i = 0; i < layersUnderCursor.size(); i++) {
1064: LayerToBottomAction ltb = new LayerToBottomAction();
1065: sub2MenuToBottom.add(ltb);
1066: ltb.putValue(AbstractAction.NAME, layersUnderCursor.get(i)
1067: .getName());
1068: if (this .scene.getLayerAt(this .scene.getLayerCount() - 1) == layersUnderCursor
1069: .get(i)) {
1070: ltb.setEnabled(false);
1071: continue;
1072: }
1073: ltb.putValue(LayerToBottomAction.PROP_LAYER,
1074: layersUnderCursor.get(i));
1075: }
1076: if (layersUnderCursor.isEmpty()) {
1077: sub2MenuToBottom.setEnabled(false);
1078: }
1079:
1080: //edit stuff
1081: JMenu sub1MenuEditLayers = new JMenu(NbBundle.getMessage(
1082: ScenePanel.class, "ScenePanel.menuEdit.txt"));
1083: if (layersUnderCursor.isEmpty()) {
1084: sub1MenuEditLayers.setEnabled(false);
1085: } else {
1086: for (int i = 0; i < layersUnderCursor.size(); i++) {
1087: EditLayerAction rl = new EditLayerAction();
1088: sub1MenuEditLayers.add(rl);
1089: rl.putValue(EditLayerAction.PROP_LAYER,
1090: layersUnderCursor.get(i));
1091: rl.putValue(AbstractAction.NAME, layersUnderCursor.get(
1092: i).getName());
1093: }
1094: }
1095: //
1096: //view stuff
1097: JMenu sub1MenuViewLayers = new JMenu(NbBundle.getMessage(
1098: ScenePanel.class, "ScenePanel.menuView.txt"));
1099: if (layersUnderCursor.isEmpty()) {
1100: sub1MenuViewLayers.setEnabled(false);
1101: } else {
1102: for (int i = 0; i < layersUnderCursor.size(); i++) {
1103: Layer layer = layersUnderCursor.get(i);
1104: JCheckBoxMenuItem item = new JCheckBoxMenuItem(layer
1105: .getName(), this .scene.isLayerVisible(layer));
1106: sub1MenuViewLayers.add(item);
1107: item.addItemListener(new VisibilityListener(layer));
1108: }
1109: }
1110:
1111: //lock stuff
1112: JMenu sub1MenuViewLocks = new JMenu(NbBundle.getMessage(
1113: ScenePanel.class, "ScenePanel.menuLock.txt"));
1114: if (layersUnderCursor.isEmpty()) {
1115: sub1MenuViewLocks.setEnabled(false);
1116: } else {
1117: for (int i = 0; i < layersUnderCursor.size(); i++) {
1118: Layer layer = layersUnderCursor.get(i);
1119: JCheckBoxMenuItem item = new JCheckBoxMenuItem(layer
1120: .getName(), this .scene.isLayerLocked(layer));
1121: sub1MenuViewLocks.add(item);
1122: item.addItemListener(new LockListener(layer));
1123: }
1124: }
1125:
1126: //align stuff
1127: JMenu sub1MenuAlign = new JMenu(NbBundle.getMessage(
1128: ScenePanel.class, "ScenePanel.menuAlign.txt"));
1129: if (this .selectedLayers.size() < 2) {
1130: sub1MenuAlign.setEnabled(false);
1131: } else {
1132: AlignLayersTopAction alt = new AlignLayersTopAction();
1133: alt.putValue(AlignLayersTopAction.PROP_LAYERS,
1134: this .selectedLayers);
1135: AlignLayersLeftAction all = new AlignLayersLeftAction();
1136: all.putValue(AlignLayersTopAction.PROP_LAYERS,
1137: this .selectedLayers);
1138: AlignLayersBottomAction alb = new AlignLayersBottomAction();
1139: alb.putValue(AlignLayersBottomAction.PROP_LAYERS,
1140: this .selectedLayers);
1141: AlignLayersRightAction alr = new AlignLayersRightAction();
1142: alr.putValue(AlignLayersRightAction.PROP_LAYERS,
1143: this .selectedLayers);
1144:
1145: sub1MenuAlign.add(alt);
1146: sub1MenuAlign.add(all);
1147: sub1MenuAlign.add(alb);
1148: sub1MenuAlign.add(alr);
1149: }
1150:
1151: //select stuff
1152: JMenu sub1MenuSelectLayers = new JMenu(NbBundle.getMessage(
1153: ScenePanel.class, "ScenePanel.menuSelect.txt"));
1154: if (!layersUnderCursor.isEmpty()) {
1155: for (int i = 0; i < layersUnderCursor.size(); i++) {
1156: Layer layer = layersUnderCursor.get(i);
1157: JCheckBoxMenuItem item = new JCheckBoxMenuItem(layer
1158: .getName(), this .selectedLayers.contains(layer));
1159: sub1MenuSelectLayers.add(item);
1160: item.addItemListener(new SelectListener(layer));
1161: }
1162: sub1MenuSelectLayers.addSeparator();
1163: SelectLayersUnderCursorAction slc = new SelectLayersUnderCursorAction();
1164: poitAdjusted = this .adjustToOriginShift(e.getPoint());
1165: slc.putValue(SelectLayersUnderCursorAction.PROP_POINT,
1166: poitAdjusted);
1167: sub1MenuSelectLayers.add(slc);
1168: }
1169: SelectAllLayersAction sal = new SelectAllLayersAction();
1170: sub1MenuSelectLayers.add(sal);
1171:
1172: //remove stuff
1173: JMenu sub1MenuRemoveLayers = new JMenu(NbBundle.getMessage(
1174: ScenePanel.class, "ScenePanel.menuRemove.txt"));
1175: if (layersUnderCursor.isEmpty()) {
1176: sub1MenuRemoveLayers.setEnabled(false);
1177: } else {
1178: for (int i = 0; i < layersUnderCursor.size(); i++) {
1179: RemoveLayerAction rl = new RemoveLayerAction();
1180: sub1MenuRemoveLayers.add(rl);
1181: rl.putValue(RemoveLayerAction.PROP_LAYER,
1182: layersUnderCursor.get(i));
1183: rl.putValue(AbstractAction.NAME, layersUnderCursor.get(
1184: i).getName());
1185: }
1186: }
1187: RemoveSelectedLayersAction rsl = new RemoveSelectedLayersAction();
1188: if (this .selectedLayers.isEmpty()) {
1189: rsl.setEnabled(false);
1190: } else {
1191: rsl.putValue(RemoveSelectedLayersAction.PROP_LAYERS,
1192: this .selectedLayers);
1193: }
1194:
1195: JPopupMenu menu = new JPopupMenu();
1196: // menu.add(cs);
1197: menu.add(ds);
1198: menu.add(rs);
1199: menu.add(rsa);
1200: menu.addSeparator();
1201:
1202: //menu.add(sub1MenuAddLayers);
1203: menu.add(ctl);
1204: menu.add(csp);
1205: menu.add(sub2MenuTiledLayers);
1206: menu.add(sub2MenuSprites);
1207: menu.addSeparator();
1208:
1209: //menu.add(sub1MenuOrderLayers);
1210: menu.add(sub2MenuPushUp);
1211: menu.add(sub2MenuPushDown);
1212: menu.add(sub2MenuToTop);
1213: menu.add(sub2MenuToBottom);
1214: menu.addSeparator();
1215:
1216: menu.add(sub1MenuEditLayers);
1217: menu.add(sub1MenuViewLayers);
1218: menu.add(sub1MenuViewLocks);
1219: menu.add(sub1MenuAlign);
1220: menu.addSeparator();
1221:
1222: menu.add(sub1MenuSelectLayers);
1223: menu.addSeparator();
1224:
1225: menu.add(sub1MenuRemoveLayers);
1226: menu.add(rsl);
1227:
1228: menu.show(this , e.getX(), e.getY());
1229: }
1230:
1231: private class VisibilityListener implements ItemListener {
1232: private Layer layer;
1233:
1234: public VisibilityListener(Layer layer) {
1235: this .layer = layer;
1236: }
1237:
1238: public void itemStateChanged(ItemEvent e) {
1239: boolean visible = e.getStateChange() == ItemEvent.SELECTED ? true
1240: : false;
1241: ScenePanel.this .scene.setLayerVisible(this .layer, visible);
1242: if (DEBUG)
1243: System.out.println("set " + layer.getName()
1244: + " visible " + visible); // NOI18N
1245: }
1246: }
1247:
1248: private class LockListener implements ItemListener {
1249: private Layer layer;
1250:
1251: public LockListener(Layer layer) {
1252: this .layer = layer;
1253: }
1254:
1255: public void itemStateChanged(ItemEvent e) {
1256: boolean locked = e.getStateChange() == ItemEvent.SELECTED ? true
1257: : false;
1258: ScenePanel.this .scene.setLayerLocked(this .layer, locked);
1259: if (DEBUG)
1260: System.out.println("set " + layer.getName()
1261: + " locked " + locked); // NOI18N
1262: }
1263: }
1264:
1265: private class SelectListener implements ItemListener {
1266: private Layer layer;
1267:
1268: public SelectListener(Layer layer) {
1269: this .layer = layer;
1270: }
1271:
1272: public void itemStateChanged(ItemEvent e) {
1273: //boolean selected = e.getStateChange() == ItemEvent.SELECTED ? true : false;
1274: ScenePanel.this .addSelectedLayer(layer, true);
1275: if (DEBUG)
1276: System.out.println("set " + layer.getName()
1277: + " selection toogled"); // NOI18N
1278: }
1279: }
1280:
1281: private boolean isMultiSelect(MouseEvent e) {
1282: return e.isControlDown() || e.isMetaDown();
1283: }
1284:
1285: private class EditLayerAction extends AbstractAction {
1286: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1287:
1288: public void actionPerformed(ActionEvent e) {
1289: Layer layer = (Layer) this .getValue(PROP_LAYER);
1290: ScenePanel.this .scene.getGameDesign().getMainView()
1291: .requestEditing(layer);
1292: }
1293: }
1294:
1295: private class AlignLayersTopAction extends AbstractAction {
1296: public static final String PROP_LAYERS = "PROP_LAYERS"; // NOI18N
1297: {
1298: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1299: "ScenePanel.menuTop.txt"));
1300: }
1301:
1302: public void actionPerformed(ActionEvent e) {
1303: Set<Layer> layers = (Set<Layer>) this .getValue(PROP_LAYERS);
1304: int top = Integer.MAX_VALUE;
1305: for (Layer layer : layers) {
1306: top = scene.getLayerPosition(layer).y < top ? scene
1307: .getLayerPosition(layer).y : top;
1308: }
1309: for (Layer layer : layers) {
1310: scene.setLayerPositionY(layer, top, false);
1311: }
1312: }
1313: }
1314:
1315: private class AlignLayersLeftAction extends AbstractAction {
1316: public static final String PROP_LAYERS = "PROP_LAYERS"; // NOI18N
1317: {
1318: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1319: "ScenePanel.menuLeft.txt"));
1320: }
1321:
1322: public void actionPerformed(ActionEvent e) {
1323: Set<Layer> layers = (Set<Layer>) this .getValue(PROP_LAYERS);
1324: int top = Integer.MAX_VALUE;
1325: for (Layer layer : layers) {
1326: top = scene.getLayerPosition(layer).x < top ? scene
1327: .getLayerPosition(layer).x : top;
1328: }
1329: for (Layer layer : layers) {
1330: scene.setLayerPositionX(layer, top, false);
1331: }
1332: }
1333: }
1334:
1335: private class AlignLayersBottomAction extends AbstractAction {
1336: public static final String PROP_LAYERS = "PROP_LAYERS"; // NOI18N
1337: {
1338: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1339: "ScenePanel.menuBottom.txt"));
1340: }
1341:
1342: public void actionPerformed(ActionEvent e) {
1343: Set<Layer> layers = (Set<Layer>) this .getValue(PROP_LAYERS);
1344: int bottom = Integer.MIN_VALUE;
1345: for (Layer layer : layers) {
1346: bottom = scene.getLayerPosition(layer).y
1347: + layer.getHeight() > bottom ? scene
1348: .getLayerPosition(layer).y
1349: + layer.getHeight() : bottom;
1350: }
1351: for (Layer layer : layers) {
1352: scene.setLayerPositionY(layer, bottom
1353: - layer.getHeight(), false);
1354: }
1355: }
1356: }
1357:
1358: private class AlignLayersRightAction extends AbstractAction {
1359: public static final String PROP_LAYERS = "PROP_LAYERS"; // NOI18N
1360: {
1361: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1362: "ScenePanel.menuRight.txt"));
1363: }
1364:
1365: public void actionPerformed(ActionEvent e) {
1366: Set<Layer> layers = (Set<Layer>) this .getValue(PROP_LAYERS);
1367: int right = Integer.MIN_VALUE;
1368: for (Layer layer : layers) {
1369: right = scene.getLayerPosition(layer).x
1370: + layer.getWidth() > right ? scene
1371: .getLayerPosition(layer).x
1372: + layer.getWidth() : right;
1373: }
1374: for (Layer layer : layers) {
1375: scene.setLayerPositionX(layer,
1376: right - layer.getWidth(), false);
1377: }
1378: }
1379: }
1380:
1381: private class RemoveLayerAction extends AbstractAction {
1382: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1383:
1384: public void actionPerformed(ActionEvent e) {
1385: Layer layer = (Layer) this .getValue(PROP_LAYER);
1386: ScenePanel.this .scene.remove(layer);
1387: }
1388: }
1389:
1390: private class RemoveSelectedLayersAction extends AbstractAction {
1391: public static final String PROP_LAYERS = "PROP_LAYERS"; // NOI18N
1392: {
1393: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1394: "ScenePanel.menuRemoveSelected.txt"));
1395: }
1396:
1397: public void actionPerformed(ActionEvent e) {
1398: Set<Layer> layers = (Set<Layer>) this .getValue(PROP_LAYERS);
1399: for (Layer layer : layers) {
1400: ScenePanel.this .scene.remove(layer);
1401: }
1402: }
1403: }
1404:
1405: private class SelectLayersUnderCursorAction extends AbstractAction {
1406: public static final String PROP_POINT = "PROP_POINT"; // NOI18N
1407:
1408: {
1409: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1410: "ScenePanel.menuSelectUnder.txt"));
1411: }
1412:
1413: public void actionPerformed(ActionEvent e) {
1414: Point p = (Point) this .getValue(PROP_POINT);
1415: List<Layer> layers = ScenePanel.this .scene
1416: .getLayersAtPoint(p);
1417: for (Layer layer : layers) {
1418: ScenePanel.this .addSelectedLayer(layer, false);
1419: }
1420: }
1421: }
1422:
1423: private class SelectAllLayersAction extends AbstractAction {
1424: {
1425: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1426: "ScenePanel.menuSelectAll.txt"));
1427: }
1428:
1429: public void actionPerformed(ActionEvent e) {
1430: List<Layer> layers = ScenePanel.this .scene.getLayers();
1431: for (Layer layer : layers) {
1432: ScenePanel.this .addSelectedLayer(layer, false);
1433: }
1434: }
1435: }
1436:
1437: private class PushUpLayerAction extends AbstractAction {
1438: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1439: public static final String PROP_LAYER_TO_TOP = "PROP_LAYER_TO_TOP"; // NOI18N
1440:
1441: public void actionPerformed(ActionEvent e) {
1442: Layer layer = (Layer) this .getValue(PROP_LAYER);
1443: Layer toTop = (Layer) this .getValue(PROP_LAYER_TO_TOP);
1444: ScenePanel.this .scene.insert(layer, ScenePanel.this .scene
1445: .indexOf(toTop));
1446: }
1447: }
1448:
1449: private class PushDownLayerAction extends AbstractAction {
1450: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1451: public static final String PROP_LAYER_TO_BELOW = "PROP_LAYER_TO_BELOW"; // NOI18N
1452:
1453: public void actionPerformed(ActionEvent e) {
1454: Layer layer = (Layer) this .getValue(PROP_LAYER);
1455: Layer toBelow = (Layer) this .getValue(PROP_LAYER_TO_BELOW);
1456: ScenePanel.this .scene.insert(layer, ScenePanel.this .scene
1457: .indexOf(toBelow));
1458: }
1459: }
1460:
1461: private class LayerToTopAction extends AbstractAction {
1462: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1463:
1464: public void actionPerformed(ActionEvent e) {
1465: Layer layer = (Layer) this .getValue(PROP_LAYER);
1466: ScenePanel.this .scene.insert(layer, 0);
1467: }
1468: }
1469:
1470: private class LayerToBottomAction extends AbstractAction {
1471: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1472:
1473: public void actionPerformed(ActionEvent e) {
1474: Layer layer = (Layer) this .getValue(PROP_LAYER);
1475: ScenePanel.this .scene.insert(layer, ScenePanel.this .scene
1476: .getLayerCount() - 1);
1477: }
1478: }
1479:
1480: // private class CreateSceneAction extends AbstractAction {
1481: // {
1482: // this.putValue(NAME, "Create new scene");
1483: // }
1484: //
1485: // public void actionPerformed(ActionEvent e) {
1486: // NewSceneDialog dialog = new NewSceneDialog(ScenePanel.this.scene.getGameDesign());
1487: // DialogDescriptor dd = new DialogDescriptor(dialog, "Create a new Scene");
1488: // dd.setButtonListener(dialog);
1489: // dd.setValid(false);
1490: // dialog.setDialogDescriptor(dd);
1491: // Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1492: // d.setVisible(true);
1493: // }
1494: // }
1495:
1496: public class DuplicateSceneAction extends AbstractAction {
1497: {
1498: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1499: "ScenePanel.actionDuplicateScene.txt"));
1500: }
1501:
1502: public void actionPerformed(ActionEvent e) {
1503: NewSceneDialog dialog = new NewSceneDialog(
1504: ScenePanel.this .scene);
1505: DialogDescriptor dd = new DialogDescriptor(dialog, NbBundle
1506: .getMessage(ScenePanel.class,
1507: "ScenePanel.actionDuplicateScene.txt"));
1508: dd.setButtonListener(dialog);
1509: dd.setValid(false);
1510: dialog.setDialogDescriptor(dd);
1511: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1512: d.setVisible(true);
1513: }
1514: }
1515:
1516: public class AddNewTiledLayerAction extends AbstractAction {
1517: {
1518: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1519: "ScenePanel.actionNewTiledLayer.txt"));
1520: }
1521:
1522: public void actionPerformed(ActionEvent e) {
1523: TiledLayerDialog nld = new TiledLayerDialog(
1524: ScenePanel.this .scene);
1525: DialogDescriptor dd = new DialogDescriptor(nld, NbBundle
1526: .getMessage(ScenePanel.class,
1527: "ScenePanel.actionNewTiledLayer.txt"));
1528: dd.setButtonListener(nld);
1529: dd.setValid(false);
1530: nld.setDialogDescriptor(dd);
1531: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1532: d.setVisible(true);
1533: }
1534: }
1535:
1536: public class AddNewSpriteAction extends AbstractAction {
1537: {
1538: this .putValue(NAME, NbBundle.getMessage(ScenePanel.class,
1539: "ScenePanel.actionNewSprite.txt"));
1540: }
1541:
1542: public void actionPerformed(ActionEvent e) {
1543: SpriteDialog nld = new SpriteDialog(ScenePanel.this .scene);
1544: DialogDescriptor dd = new DialogDescriptor(nld, NbBundle
1545: .getMessage(ScenePanel.class,
1546: "ScenePanel.actionNewSprite.txt"));
1547: dd.setButtonListener(nld);
1548: dd.setValid(false);
1549: nld.setDialogDescriptor(dd);
1550: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1551: d.setVisible(true);
1552: }
1553: }
1554:
1555: public class AddLayerAction extends AbstractAction {
1556: public static final String PROP_LAYER = "PROP_LAYER"; // NOI18N
1557: public static final String PROP_POSITION = "PROP_POSITION"; // NOI18N
1558:
1559: public void actionPerformed(ActionEvent e) {
1560: Layer layer = (Layer) this .getValue(PROP_LAYER);
1561: Point position = (Point) this .getValue(PROP_POSITION);
1562:
1563: ScenePanel.this .scene.insert(layer, 0);
1564: ScenePanel.this .scene.setLayerPosition(layer, position,
1565: false);
1566: }
1567: }
1568:
1569: public JComponent getGridButton() {
1570: return this .gridButton;
1571: }
1572:
1573: private class GridButton extends JComponent implements
1574: MouseListener {
1575: private static final int BORDER = 4;
1576:
1577: public GridButton() {
1578: ToolTipManager.sharedInstance().registerComponent(this );
1579: this .addMouseListener(this );
1580: }
1581:
1582: @Override
1583: public String getToolTipText() {
1584: return NbBundle.getMessage(ScenePanel.class,
1585: "ScenePanel.gridButton.tooltip");
1586: }
1587:
1588: @Override
1589: protected void paintComponent(Graphics g) {
1590: g.setColor(UIManager.getColor("Panel.background")); // NOI18N
1591: g.fillRect(0, 0, this .getWidth(), this .getHeight());
1592: g.setColor(Color.BLACK);
1593: int startx = BORDER;
1594: int starty = BORDER;
1595: int x = BORDER;
1596: int y = BORDER;
1597: int w = this .getWidth() - (3 * BORDER);
1598: int h = this .getHeight() - (3 * BORDER);
1599: if (ScenePanel.this .isShowGrid()) {
1600: if (ScenePanel.this .isSnapGrid()) {
1601: g.setColor(Color.RED);
1602: }
1603: int offX = w / 3;
1604: int offY = h / 3;
1605:
1606: x += offX;
1607: g.drawLine(x, starty, x, starty + h);
1608: x += offX;
1609: g.drawLine(x, starty, x, starty + h);
1610:
1611: y += offY;
1612: g.drawLine(startx, y, startx + w, y);
1613: y += offY;
1614: g.drawLine(startx, y, startx + w, y);
1615:
1616: }
1617: g.setColor(Color.BLACK);
1618: g.drawRoundRect(startx, starty, w, h, BORDER, BORDER);
1619: }
1620:
1621: public void mouseClicked(MouseEvent e) {
1622: if (ScenePanel.this .isShowGrid()) {
1623: if (ScenePanel.this .isSnapGrid()) {
1624: ScenePanel.this .setShowGrid(false);
1625: ScenePanel.this .setSnapGrid(false);
1626: } else {
1627: ScenePanel.this .setSnapGrid(true);
1628: }
1629: } else {
1630: ScenePanel.this .setShowGrid(true);
1631: ScenePanel.this .setSnapGrid(false);
1632: }
1633: this .repaint();
1634: }
1635:
1636: public void mouseEntered(MouseEvent e) {
1637: }
1638:
1639: public void mouseExited(MouseEvent e) {
1640: }
1641:
1642: public void mousePressed(MouseEvent e) {
1643: }
1644:
1645: public void mouseReleased(MouseEvent e) {
1646: }
1647: }
1648:
1649: public Ruler getRulerHorizontal() {
1650: return this .horizontalRuler;
1651: }
1652:
1653: public Ruler getRulerVertical() {
1654: return this .verticalRuler;
1655: }
1656:
1657: class Ruler extends JComponent {
1658:
1659: public static final int HORIZONTAL = 0;
1660: public static final int VERTICAL = 1;
1661:
1662: private static final int SIZE_H = 24;
1663: private static final int SIZE_W = 37;
1664:
1665: private static final int TICK_MAJOR = 6;
1666: private static final int TICK_MINOR = 3;
1667:
1668: private static final int LOC_INSET = 2;
1669: private static final int SHADOW_OFF = 3;
1670: public final Color locFgColor = Color.WHITE;
1671: public final Color locBgColor = new Color(0, 0, 255, 200);
1672: public final Color locOutlineColor = Color.WHITE;
1673: public final Color locShadowColor = new Color(0, 0, 255, 64);
1674:
1675: public final Color locFgColorSecondary = Color.WHITE;
1676: public final Color locBgColorSecondary = new Color(128, 128,
1677: 255, 200);
1678: public final Color locOutlineColorSecondary = locFgColorSecondary;
1679: public final Color locShadowColorSecondary = new Color(128,
1680: 128, 255, 64);
1681:
1682: private final Color COLOR_MAJOR = Color.BLACK;
1683: private final Color COLOR_MINOR = Color.GRAY;
1684: private final Font FONT = new Font("SansSerif", Font.PLAIN, 9); // NOI18N
1685:
1686: public final Color RulerColor = UIManager
1687: .getColor("Panel.background"); // NOI18N
1688: //new Color(230, 230, 255);
1689:
1690: public int orientation;
1691: private int increment = 10;
1692: private int units = 50;
1693:
1694: public Ruler(int orientation) {
1695: this .orientation = orientation;
1696: }
1697:
1698: @Override
1699: public Dimension getPreferredSize() {
1700: Rectangle bounds = ScenePanel.this .scene
1701: .getAllLayersBounds();
1702: bounds.add(0, 0);
1703: if (this .orientation == HORIZONTAL) {
1704: return new Dimension(bounds.width, SIZE_H);
1705: }
1706: return new Dimension(SIZE_W, bounds.height);
1707: }
1708:
1709: public int getIncrement() {
1710: return increment;
1711: }
1712:
1713: protected void paintComponent(Graphics graph) {
1714: Graphics2D g = (Graphics2D) graph;
1715: Rectangle clip = g.getClipBounds();
1716:
1717: Rectangle sceneBounds = ScenePanel.this .scene
1718: .getAllLayersBounds();
1719: sceneBounds.add(0, 0);
1720: int offX = sceneBounds.x;
1721: int offY = sceneBounds.y;
1722:
1723: // Fill clipping area blue
1724: g.setColor(RulerColor);
1725: g.fillRect(clip.x, clip.y, clip.width, clip.height);
1726:
1727: // Do the ruler labels in a small font that's black.
1728: g.setFont(FONT);
1729:
1730: // Some vars we need.
1731:
1732: int end;
1733: int start;
1734: int tickLength = 0;
1735: String text = null;
1736:
1737: // Use clipping bounds to calculate first and last tick locations.
1738: if (orientation == HORIZONTAL) {
1739: start = ((clip.x + offX) / increment) * increment;
1740: end = (((clip.x + offX + clip.width) / increment) + 1)
1741: * increment;
1742: //System.out.println("HOR start: " + start + " end: " + end);
1743: } else {
1744: start = ((clip.y + offY) / increment) * increment;
1745: end = (((clip.y + offY + clip.height) / increment) + 1)
1746: * increment;
1747: //System.out.println("VER start: " + start + " end: " + end);
1748: }
1749:
1750: // ticks and labels
1751: for (int i = start; i < end; i += increment) {
1752: if (i % units == 0) {
1753: g.setColor(COLOR_MAJOR);
1754: tickLength = TICK_MAJOR;
1755: if (i == 0) {
1756: text = " " + Integer.toString(i);
1757: } else {
1758: text = Integer.toString(i);
1759: }
1760: } else {
1761: g.setColor(COLOR_MINOR);
1762: tickLength = TICK_MINOR;
1763: text = null;
1764: }
1765:
1766: if (tickLength != 0) {
1767: if (orientation == HORIZONTAL) {
1768: g.drawLine(i - offX, SIZE_H - 1, i - offX,
1769: SIZE_H - tickLength - 1);
1770: if (text != null) {
1771: int y = SIZE_H - tickLength
1772: - (FONT.getSize() / 2);
1773: int x = (int) (i - offX - (FONT
1774: .getStringBounds(text,
1775: g.getFontRenderContext())
1776: .getWidth() / 2));
1777: g.drawString(text, x, y);
1778: }
1779: } else {
1780: g.drawLine(SIZE_W - 1, i - offY, SIZE_W
1781: - tickLength - 1, i - offY);
1782: if (text != null) {
1783: int y = i - offY + (FONT.getSize() / 2);
1784: g.drawString(text, 1, y);
1785: }
1786: }
1787: }
1788: }
1789:
1790: //draw outlines of all selected layers on the rulers
1791: //make sure to draw the ScenePanel.this.snapToGridReferenceLayer last (i.e. on top of the other layers)
1792:
1793: List<Layer> tmp = new ArrayList<Layer>(
1794: ScenePanel.this .selectedLayers);
1795: if (ScenePanel.this .snapToGridReferenceLayer != null) {
1796: tmp.remove(ScenePanel.this .snapToGridReferenceLayer);
1797: tmp.add(ScenePanel.this .snapToGridReferenceLayer);
1798: }
1799:
1800: for (Layer layer : tmp) {
1801: Color bgColor = null;
1802: Color fgColor = null;
1803: Color shadowColor = null;
1804: Color outlineColor = null;
1805: //set painting colors
1806: if (ScenePanel.this .snapToGridReferenceLayer == null
1807: || layer == ScenePanel.this .snapToGridReferenceLayer) {
1808: bgColor = locBgColor;
1809: fgColor = locFgColor;
1810: shadowColor = locShadowColor;
1811: outlineColor = locOutlineColor;
1812: } else {
1813: bgColor = locBgColorSecondary;
1814: fgColor = locFgColorSecondary;
1815: shadowColor = locShadowColorSecondary;
1816: outlineColor = locOutlineColorSecondary;
1817: }
1818:
1819: Rectangle bounds = ScenePanel.this .scene
1820: .getLayerBounds(layer);
1821: if (orientation == HORIZONTAL) {
1822: int leftLim = clip.x + offX;
1823: int rightLim = clip.x + offX + clip.width;
1824: if (leftLim <= (bounds.x + bounds.width)
1825: && (bounds.x + bounds.width) < rightLim) {
1826: //draw layers right outline
1827: g.setColor(colorSelection);
1828: g.drawLine(bounds.x + bounds.width - offX, 0,
1829: bounds.x + bounds.width - offX, SIZE_H);
1830: //draw layer X position on the right
1831: //if (ScenePanel.this.dragDirectionHorizontal == BorderLayout.EAST) {
1832: String strPosX = Integer.toString(bounds.x
1833: + bounds.width);
1834: Rectangle2D strBounds = FONT.getStringBounds(
1835: strPosX, g.getFontRenderContext());
1836: LineMetrics lm = FONT.getLineMetrics(strPosX, g
1837: .getFontRenderContext());
1838: float ascend = lm.getAscent();
1839: Rectangle strOutline = new Rectangle(
1840: (int) strBounds.getX() - LOC_INSET,
1841: (int) strBounds.getY() - LOC_INSET,
1842: (int) strBounds.getWidth() + LOC_INSET
1843: * 2, (int) strBounds
1844: .getHeight()
1845: + LOC_INSET * 2);
1846: g.setColor(bgColor);
1847: g
1848: .fillRoundRect(
1849: (int) ((bounds.x + bounds.width - offX) - strOutline
1850: .getWidth() / 2), 0,
1851: (int) strOutline.getWidth(),
1852: (int) strOutline.getHeight(),
1853: LOC_INSET * 2, LOC_INSET * 2);
1854: g.setColor(shadowColor);
1855: g
1856: .fillRoundRect(
1857: (int) ((bounds.x + bounds.width - offX) - strOutline
1858: .getWidth() / 2)
1859: + SHADOW_OFF,
1860: 0 + SHADOW_OFF,
1861: (int) strOutline.getWidth(),
1862: (int) strOutline.getHeight(),
1863: LOC_INSET * 2, LOC_INSET * 2);
1864: g.setColor(fgColor);
1865: g.drawString(strPosX, (int) ((bounds.x
1866: + bounds.width - offX) - strBounds
1867: .getWidth() / 2), LOC_INSET + ascend);
1868: //hi-lite the reference layer position
1869: if (layer == ScenePanel.this .snapToGridReferenceLayer) {
1870: g.setColor(outlineColor);
1871: g.drawRoundRect(
1872: (int) ((bounds.x + bounds.width
1873: - offX - 1) - strOutline
1874: .getWidth() / 2), 0,
1875: (int) strOutline.getWidth() + 1,
1876: (int) strOutline.getHeight(),
1877: LOC_INSET * 2, LOC_INSET * 2);
1878: }
1879: //}
1880: }
1881: if (leftLim <= bounds.x && bounds.x < rightLim) {
1882: //draw layers left outline
1883: g.setColor(colorSelection);
1884: g.drawLine(bounds.x - offX, 0, bounds.x - offX,
1885: SIZE_H);
1886: //draw layer X position on the left
1887: //if (ScenePanel.this.dragDirectionHorizontal == BorderLayout.WEST) {
1888: String strPosX = Integer.toString(bounds.x);
1889: Rectangle2D strBounds = FONT.getStringBounds(
1890: strPosX, g.getFontRenderContext());
1891: LineMetrics lm = FONT.getLineMetrics(strPosX, g
1892: .getFontRenderContext());
1893: float ascend = lm.getAscent();
1894: Rectangle strOutline = new Rectangle(
1895: (int) strBounds.getX() - LOC_INSET,
1896: (int) strBounds.getY() - LOC_INSET,
1897: (int) strBounds.getWidth() + LOC_INSET
1898: * 2, (int) strBounds
1899: .getHeight()
1900: + LOC_INSET * 2);
1901: g.setColor(bgColor);
1902: g.fillRoundRect(
1903: (int) ((bounds.x - offX) - strOutline
1904: .getWidth() / 2), 0,
1905: (int) strOutline.getWidth(),
1906: (int) strOutline.getHeight(),
1907: LOC_INSET * 2, LOC_INSET * 2);
1908: g.setColor(shadowColor);
1909: g.fillRoundRect(
1910: (int) ((bounds.x - offX) - strOutline
1911: .getWidth() / 2)
1912: + SHADOW_OFF, 0 + SHADOW_OFF,
1913: (int) strOutline.getWidth(),
1914: (int) strOutline.getHeight(),
1915: LOC_INSET * 2, LOC_INSET * 2);
1916: g.setColor(fgColor);
1917: g.drawString(strPosX,
1918: (int) ((bounds.x - offX) - strBounds
1919: .getWidth() / 2), LOC_INSET
1920: + ascend);
1921: //hi-lite the reference layer position
1922: if (layer == ScenePanel.this .snapToGridReferenceLayer) {
1923: g.setColor(outlineColor);
1924: g
1925: .drawRoundRect(
1926: (int) ((bounds.x - offX - 1) - strOutline
1927: .getWidth() / 2),
1928: 0,
1929: (int) strOutline.getWidth() + 1,
1930: (int) strOutline
1931: .getHeight(),
1932: LOC_INSET * 2,
1933: LOC_INSET * 2);
1934: }
1935: //}
1936: }
1937: } else {
1938: int topLim = clip.y + offY;
1939: int bottomLim = clip.y + offY + clip.height;
1940: if (topLim <= (bounds.y + bounds.height)
1941: && (bounds.y + bounds.height) < bottomLim) {
1942: //draw layers bottom outline
1943: g.setColor(colorSelection);
1944: g
1945: .drawLine(0, bounds.y + bounds.height
1946: - offY, SIZE_W, bounds.y
1947: + bounds.height - offY);
1948: //if (ScenePanel.this.dragDirectionVertical == BorderLayout.SOUTH) {
1949: //draw layer Y position on the bottom
1950: String strPosY = Integer.toString(bounds.y
1951: + bounds.height);
1952: Rectangle2D strBounds = FONT.getStringBounds(
1953: strPosY, g.getFontRenderContext());
1954: LineMetrics lm = FONT.getLineMetrics(strPosY, g
1955: .getFontRenderContext());
1956: float ascend = lm.getAscent();
1957: Rectangle strOutline = new Rectangle(
1958: (int) strBounds.getX() - LOC_INSET,
1959: (int) strBounds.getY() - LOC_INSET,
1960: (int) strBounds.getWidth() + LOC_INSET
1961: * 2, (int) strBounds
1962: .getHeight()
1963: + LOC_INSET * 2);
1964: g.setColor(bgColor);
1965: g.fillRoundRect(1, bounds.y + bounds.height
1966: - offY - strOutline.height / 2,
1967: strOutline.width, strOutline.height,
1968: LOC_INSET * 2, LOC_INSET * 2);
1969: g.setColor(shadowColor);
1970: g.fillRoundRect(1 + SHADOW_OFF, bounds.y
1971: + bounds.height - offY
1972: - strOutline.height / 2 + SHADOW_OFF,
1973: strOutline.width, strOutline.height,
1974: LOC_INSET * 2, LOC_INSET * 2);
1975: g.setColor(fgColor);
1976: g.drawString(strPosY, 1 + LOC_INSET, bounds.y
1977: + bounds.height - offY
1978: - strOutline.height / 2 + ascend
1979: + LOC_INSET);
1980: //hi-lite the reference layer position
1981: if (layer == ScenePanel.this .snapToGridReferenceLayer) {
1982: g.setColor(outlineColor);
1983: g.drawRoundRect(0, bounds.y + bounds.height
1984: - offY - strOutline.height / 2,
1985: strOutline.width + 1,
1986: strOutline.height, LOC_INSET * 2,
1987: LOC_INSET * 2);
1988: }
1989: //}
1990: }
1991: if (topLim <= bounds.y && bounds.y < bottomLim) {
1992: //draw layers top outline
1993: g.setColor(colorSelection);
1994: g.drawLine(0, bounds.y - offY, SIZE_W, bounds.y
1995: - offY);
1996: //draw layer Y position on the top
1997: //if (ScenePanel.this.dragDirectionVertical == BorderLayout.NORTH) {
1998: String strPosY = Integer.toString(bounds.y);
1999: Rectangle2D strBounds = FONT.getStringBounds(
2000: strPosY, g.getFontRenderContext());
2001: LineMetrics lm = FONT.getLineMetrics(strPosY, g
2002: .getFontRenderContext());
2003: float ascend = lm.getAscent();
2004: Rectangle strOutline = new Rectangle(
2005: (int) strBounds.getX() - LOC_INSET,
2006: (int) strBounds.getY() - LOC_INSET,
2007: (int) strBounds.getWidth() + LOC_INSET
2008: * 2, (int) strBounds
2009: .getHeight()
2010: + LOC_INSET * 2);
2011: g.setColor(bgColor);
2012: g.fillRoundRect(1, bounds.y - offY
2013: - strOutline.height / 2,
2014: strOutline.width, strOutline.height,
2015: LOC_INSET * 2, LOC_INSET * 2);
2016: g.setColor(shadowColor);
2017: g.fillRoundRect(1 + SHADOW_OFF, bounds.y - offY
2018: - strOutline.height / 2 + SHADOW_OFF,
2019: strOutline.width, strOutline.height,
2020: LOC_INSET * 2, LOC_INSET * 2);
2021: g.setColor(fgColor);
2022: g.drawString(strPosY, 1 + LOC_INSET, bounds.y
2023: - offY - strOutline.height / 2 + ascend
2024: + LOC_INSET);
2025: //hi-lite the reference layer position
2026: if (layer == ScenePanel.this .snapToGridReferenceLayer) {
2027: g.setColor(outlineColor);
2028: g.drawRoundRect(0, bounds.y - offY
2029: - strOutline.height / 2,
2030: strOutline.width + 1,
2031: strOutline.height, LOC_INSET * 2,
2032: LOC_INSET * 2);
2033: }
2034: //}
2035: }
2036: }
2037: }
2038: }
2039: }
2040:
2041: public boolean isSnapGrid() {
2042: return this .snapGrid;
2043: }
2044:
2045: public void setSnapGrid(boolean snapGrid) {
2046: if (this .snapGrid == snapGrid) {
2047: return;
2048: }
2049: this .snapGrid = snapGrid;
2050: this .repaint();
2051: }
2052:
2053: public boolean isShowGrid() {
2054: return showGrid;
2055: }
2056:
2057: public void setShowGrid(boolean showGrid) {
2058: if (this .showGrid == showGrid) {
2059: return;
2060: }
2061: this .showGrid = showGrid;
2062: this .repaint();
2063: }
2064:
2065: public void setGridSizeHorizontal(int unitSize) {
2066: this .gridX = unitSize;
2067: this .repaint();
2068: }
2069:
2070: public void setGridSizeVertical(int unitSize) {
2071: this.gridY = unitSize;
2072: this.repaint();
2073: }
2074: }
|