001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.vmd.game.editor.tiledlayer;
043:
044: import java.awt.Dimension;
045: import java.awt.Point;
046: import java.awt.dnd.DnDConstants;
047: import java.awt.dnd.DragGestureEvent;
048: import java.awt.dnd.DragGestureListener;
049: import java.awt.dnd.DragGestureRecognizer;
050: import java.awt.dnd.DragSource;
051: import java.awt.dnd.DragSourceAdapter;
052: import java.awt.dnd.DragSourceDropEvent;
053: import java.awt.event.FocusAdapter;
054: import java.awt.event.FocusEvent;
055: import java.awt.event.MouseAdapter;
056: import java.awt.event.MouseEvent;
057: import java.beans.PropertyChangeEvent;
058: import java.beans.PropertyChangeListener;
059: import java.util.Iterator;
060: import java.util.List;
061: import javax.swing.Action;
062: import javax.swing.DefaultListModel;
063: import javax.swing.JList;
064: import javax.swing.JPopupMenu;
065: import javax.swing.ListSelectionModel;
066: import javax.swing.SwingUtilities;
067: import javax.swing.event.ListSelectionEvent;
068: import javax.swing.event.ListSelectionListener;
069: import org.netbeans.modules.vmd.game.model.AnimatedTile;
070: import org.netbeans.modules.vmd.game.model.Editable;
071: import org.netbeans.modules.vmd.game.model.ImageResource;
072: import org.netbeans.modules.vmd.game.model.ImageResourceListener;
073: import org.netbeans.modules.vmd.game.model.Sequence;
074: import org.netbeans.modules.vmd.game.model.SequenceContainer;
075: import org.netbeans.modules.vmd.game.model.SequenceContainerListener;
076: import org.netbeans.modules.vmd.game.model.Tile;
077: import org.netbeans.modules.vmd.game.model.TileTransferable;
078:
079: /**
080: *
081: * @author kherink
082: */
083: public class AnimatedTileList extends JList {
084:
085: public static final boolean DEBUG = false;
086:
087: private TiledLayerEditorComponent editorComponent;
088: private ImageResource imageResource;
089: private AnimatedTileListDataModel model;
090:
091: /** Creates a new instance of AnimatedTileList */
092: public AnimatedTileList(TiledLayerEditorComponent editorComponent) {
093: this .editorComponent = editorComponent;
094: this .imageResource = this .editorComponent.getTiledLayer()
095: .getImageResource();
096: this .model = new AnimatedTileListDataModel();
097: this .init();
098: this .imageResource.addImageResourceListener(model);
099: this .setModel(model);
100: this .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
101: this .setCellRenderer(new AnimatedTileListCellRenderer());
102: this .setMinimumSize(new Dimension(this .editorComponent
103: .getTiledLayer().getTileWidth(), 20));
104: this .addListSelectionListener(new ListSelectionListener() {
105: public void valueChanged(ListSelectionEvent e) {
106: if (e.getValueIsAdjusting())
107: return;
108: AnimatedTileList.this .updatePaintTile();
109: }
110: });
111: this .addFocusListener(new FocusAdapter() {
112: public void focusGained(FocusEvent e) {
113: AnimatedTileList.this .updatePaintTile();
114: }
115: });
116: this .addMouseListener(new MouseAdapter() {
117: public void mousePressed(MouseEvent e) {
118: if (e.isPopupTrigger()) {
119: handlePopup(e);
120: }
121: }
122:
123: public void mouseReleased(MouseEvent e) {
124: if (e.isPopupTrigger()) {
125: handlePopup(e);
126: }
127: }
128:
129: public void mouseClicked(MouseEvent e) {
130: if (e.getClickCount() >= 2
131: && SwingUtilities.isLeftMouseButton(e)) {
132: AnimatedTile tile = (AnimatedTile) AnimatedTileList.this
133: .getSelectedValue();
134: tile.getImageResource().getGameDesign()
135: .getMainView().requestEditing(tile);
136: }
137: }
138: });
139: //DnD
140: DragSource dragSource = new DragSource();
141: DragGestureRecognizer dragGestureRecognizer = dragSource
142: .createDefaultDragGestureRecognizer(this ,
143: DnDConstants.ACTION_MOVE, new DGL());
144:
145: }
146:
147: private void handlePopup(MouseEvent e) {
148: JPopupMenu menu = new JPopupMenu();
149: int row = AnimatedTileList.this .locationToIndex(e.getPoint());
150: AnimatedTile at = (AnimatedTile) AnimatedTileList.this
151: .getModel().getElementAt(row);
152: List<Action> actions = at.getActions();
153: for (Action action : actions) {
154: menu.add(action);
155: }
156: menu.show(this , e.getX(), e.getY());
157: }
158:
159: private void updatePaintTile() {
160: Tile tile = (Tile) this .getSelectedValue();
161: if (tile == null)
162: return;
163: tile.getImageResource().getGameDesign().getMainView()
164: .requestPreview(tile);
165: this .editorComponent.setPaintTileIndex(tile.getIndex());
166: }
167:
168: private void init() {
169: List animatedTiles = this .imageResource.getAnimatedTiles(
170: this .editorComponent.getTiledLayer().getTileWidth(),
171: this .editorComponent.getTiledLayer().getTileHeight());
172: for (Iterator iter = animatedTiles.iterator(); iter.hasNext();) {
173: AnimatedTile tile = (AnimatedTile) iter.next();
174: tile.addSequenceContainerListener(this .model);
175: this .model.addElement(tile);
176: }
177: }
178:
179: public Dimension getMaximumSize() {
180: return this .getPreferredSize();
181: }
182:
183: private class DGL extends DragSourceAdapter implements
184: DragGestureListener {
185:
186: public void dragGestureRecognized(DragGestureEvent dge) {
187: Point dragOrigin = dge.getDragOrigin();
188: int row = AnimatedTileList.this .locationToIndex(dragOrigin);
189: Tile tile = (Tile) AnimatedTileList.this .getModel()
190: .getElementAt(row);
191: TileTransferable payload = new TileTransferable();
192: payload.getTiles().add(tile);
193: dge.startDrag(null, payload, this );
194: }
195:
196: public void dragDropEnd(DragSourceDropEvent dsde) {
197: super .dragDropEnd(dsde);
198: if (dsde.getDropSuccess()) {
199: if (DEBUG)
200: System.out.println("Drop successful"); // NOI18N
201: } else {
202: if (DEBUG)
203: System.out.println("Drop unsuccessful"); // NOI18N
204: }
205: }
206: }
207:
208: private class AnimatedTileListDataModel extends DefaultListModel
209: implements ImageResourceListener,
210: SequenceContainerListener, PropertyChangeListener {
211:
212: @Override
213: public void addElement(Object obj) {
214: AnimatedTile tile = (AnimatedTile) obj;
215: super .addElement(tile);
216: tile.addPropertyChangeListener(this );
217: }
218:
219: public void propertyChange(PropertyChangeEvent evt) {
220: int index = this .indexOf(evt.getSource());
221: if (evt.getPropertyName().equals(Editable.PROPERTY_NAME)) {
222: AnimatedTileListDataModel.this .fireContentsChanged(
223: this , index, index);
224: }
225: }
226:
227: //ImageResourceListener
228: public void animatedTileAdded(ImageResource source,
229: AnimatedTile tile) {
230: if (tile.getWidth() == AnimatedTileList.this .editorComponent
231: .getTiledLayer().getTileWidth()
232: && tile.getHeight() == AnimatedTileList.this .editorComponent
233: .getTiledLayer().getTileHeight()) {
234: this .addElement(tile);
235: tile.addSequenceContainerListener(this );
236: }
237: }
238:
239: public void animatedTileRemoved(ImageResource source,
240: AnimatedTile tile) {
241: tile.removeSequenceContainerListener(this );
242: this .removeElement(tile);
243: }
244:
245: public void sequenceAdded(ImageResource source,
246: Sequence sequence) {
247: }
248:
249: public void sequenceRemoved(ImageResource source,
250: Sequence sequence) {
251: }
252:
253: //SequenceContainerListener
254: public void sequenceAdded(SequenceContainer source,
255: Sequence sequence, int index) {
256: int tileIndex = this .indexOf(source);
257: this .fireContentsChanged(this , tileIndex, tileIndex);
258: }
259:
260: public void sequenceRemoved(SequenceContainer source,
261: Sequence sequence, int index) {
262: int tileIndex = this .indexOf(source);
263: this .fireContentsChanged(this , tileIndex, tileIndex);
264: }
265:
266: public void sequenceMoved(SequenceContainer source,
267: Sequence sequence, int indexOld, int indexNew) {
268: int tileIndex = this.indexOf(source);
269: this.fireContentsChanged(this, tileIndex, tileIndex);
270: }
271: }
272: }
|