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:
0042: package org.netbeans.modules.vmd.game;
0043:
0044: import java.awt.BorderLayout;
0045: import java.awt.Dialog;
0046: import java.awt.Point;
0047: import java.awt.event.ActionEvent;
0048: import java.awt.event.ActionListener;
0049: import java.beans.PropertyChangeEvent;
0050: import java.beans.PropertyChangeListener;
0051: import java.net.URL;
0052: import java.util.Set;
0053: import org.netbeans.modules.vmd.api.io.DataObjectContext;
0054: import org.netbeans.modules.vmd.api.io.DesignDocumentAwareness;
0055: import org.netbeans.modules.vmd.api.io.IOUtils;
0056: import org.netbeans.modules.vmd.api.model.DesignDocument;
0057: import java.util.ArrayList;
0058: import java.util.Collection;
0059: import java.util.HashMap;
0060: import java.util.HashSet;
0061: import java.util.Iterator;
0062: import java.util.List;
0063: import java.util.Map;
0064: import javax.swing.JComponent;
0065: import javax.swing.JPanel;
0066: import org.netbeans.modules.vmd.api.model.DesignComponent;
0067: import org.netbeans.modules.vmd.api.model.DesignEvent;
0068: import org.netbeans.modules.vmd.api.model.DesignEventFilter;
0069: import org.netbeans.modules.vmd.api.model.DesignListener;
0070: import org.netbeans.modules.vmd.api.model.PropertyValue;
0071: import org.netbeans.modules.vmd.api.model.TypeID;
0072: import org.netbeans.modules.vmd.game.integration.components.GameTypes;
0073: import org.netbeans.modules.vmd.game.model.AnimatedTile;
0074: import org.netbeans.modules.vmd.game.model.AnimatedTileCD;
0075: import org.netbeans.modules.vmd.game.model.Editable;
0076: import org.netbeans.modules.vmd.game.model.GlobalRepository;
0077: import org.netbeans.modules.vmd.game.model.GlobalRepositoryListener;
0078: import org.netbeans.modules.vmd.game.model.Identifiable;
0079: import org.netbeans.modules.vmd.game.model.ImageResource;
0080: import org.netbeans.modules.vmd.game.model.ImageResourceCD;
0081: import org.netbeans.modules.vmd.game.model.ImageResourceListener;
0082: import org.netbeans.modules.vmd.game.model.Layer;
0083: import org.netbeans.modules.vmd.game.model.LayerCD;
0084: import org.netbeans.modules.vmd.game.model.Scene;
0085: import org.netbeans.modules.vmd.game.model.Scene.LayerInfo;
0086: import org.netbeans.modules.vmd.game.model.SceneCD;
0087: import org.netbeans.modules.vmd.game.model.SceneItemCD;
0088: import org.netbeans.modules.vmd.game.model.SceneListener;
0089: import org.netbeans.modules.vmd.game.model.Sequence;
0090: import org.netbeans.modules.vmd.game.model.SequenceCD;
0091: import org.netbeans.modules.vmd.game.model.SequenceContainer;
0092: import org.netbeans.modules.vmd.game.model.SequenceContainerCDProperties;
0093: import org.netbeans.modules.vmd.game.model.SequenceContainerListener;
0094: import org.netbeans.modules.vmd.game.model.SequenceListener;
0095: import org.netbeans.modules.vmd.game.model.Sprite;
0096: import org.netbeans.modules.vmd.game.model.SpriteCD;
0097: import org.netbeans.modules.vmd.game.model.StaticTile;
0098: import org.netbeans.modules.vmd.game.model.TiledLayer;
0099: import org.netbeans.modules.vmd.game.model.TiledLayerCD;
0100: import org.netbeans.modules.vmd.game.model.TiledLayerListener;
0101: import org.netbeans.modules.vmd.game.nbdialog.SelectImageForLayerDialog;
0102: import org.netbeans.modules.vmd.midp.components.MidpProjectSupport;
0103: import org.netbeans.modules.vmd.midp.components.MidpTypes;
0104: import org.openide.DialogDescriptor;
0105: import org.openide.DialogDisplayer;
0106: import org.openide.NotifyDescriptor;
0107: import org.openide.filesystems.FileObject;
0108: import org.openide.filesystems.FileStateInvalidException;
0109: import org.openide.filesystems.FileUtil;
0110: import org.openide.util.NbBundle;
0111:
0112: /**
0113: *
0114: * @author Karel Herink
0115: */
0116: public class GameController implements DesignDocumentAwareness,
0117: GlobalRepositoryListener, SceneListener, TiledLayerListener,
0118: SequenceContainerListener, SequenceListener,
0119: ImageResourceListener, PropertyChangeListener, DesignListener {
0120:
0121: private static boolean DEBUG = false;
0122: private static boolean DEBUG_UNDO = false;
0123:
0124: private final Map<Long, String> changeMap = new HashMap<Long, String>();
0125:
0126: /**
0127: * Maps game builder model objects to the component ids of their designer2 design component
0128: * counter-parts. E.g. a TiledLayer instance is the key and value is design component id of
0129: * the design component that represents the tiled layer in the design document.
0130: */
0131: private final Map<Identifiable, DesignComponent> designIdMap = new HashMap<Identifiable, DesignComponent>();
0132:
0133: public static final String PROJECT_TYPE_GAME = "vmd-midp-game"; // NOI18N
0134:
0135: private DataObjectContext context;
0136: private GameEditorView gameEditorView;
0137: private JComponent loadingPanel;
0138: private JPanel panel = new JPanel(new BorderLayout());
0139:
0140: private DesignDocument document;
0141:
0142: /** Creates a new instance of GameController */
0143: public GameController(DataObjectContext context,
0144: GameEditorView gameEditorView) {
0145: this .context = context;
0146: this .gameEditorView = gameEditorView;
0147: this .loadingPanel = IOUtils.createLoadingPanel();
0148: this .panel.add(this .loadingPanel);
0149: this .context.addDesignDocumentAwareness(this );
0150: }
0151:
0152: public JComponent getVisualRepresentation() {
0153: return this .panel;
0154: }
0155:
0156: public DesignDocument getDesignDocument() {
0157: return document;
0158: }
0159:
0160: public GlobalRepository getGameDesign() {
0161: final DesignDocument doc = this .getDesignDocument();
0162: if (doc == null) {
0163: return null;
0164: }
0165: final GlobalRepository[] gameDesign = { null };
0166: doc.getTransactionManager().readAccess(new Runnable() {
0167: public void run() {
0168: GameAccessController controller = doc
0169: .getListenerManager().getAccessController(
0170: GameAccessController.class);
0171: gameDesign[0] = controller.getGameDesign();
0172: }
0173: });
0174: return gameDesign[0];
0175: }
0176:
0177: private DesignComponent getImageResourceDC(Set<DesignComponent> set) {
0178: for (DesignComponent designComponent : set) {
0179: if (designComponent == null) {
0180: continue;
0181: }
0182: if (designComponent.getType()
0183: .equals(ImageResourceCD.TYPEID)) {
0184: return designComponent;
0185: }
0186: }
0187: return null;
0188: }
0189:
0190: //handle external changes here (such as undo or redo events)
0191: public void designChanged(DesignEvent event) {
0192: if (DEBUG_UNDO)
0193: System.out.println("GameController.designChanged() : "
0194: + event.getEventID()); // NOI18N
0195:
0196: //first model the newly created design components
0197: for (DesignComponent designComponent : event
0198: .getCreatedComponents()) {
0199: this .modelComponent(designComponent);
0200: }
0201:
0202: DesignComponent imgResDC = null;
0203: DesignComponent root = this .document.getRootComponent();
0204:
0205: //we either added or removed a component from the game design root (scene, layer, image resource)
0206: if (event.getFullyAffectedHierarchies().contains(root)) {
0207: this .refreshGameDesign(root, event);
0208: }
0209:
0210: else if ((imgResDC = getImageResourceDC(event
0211: .getFullyAffectedHierarchies())) != null) {
0212: this .refreshImageResource(imgResDC, event);
0213: }
0214:
0215: //or we modified an existing component
0216: else {
0217: //then update exiting design components
0218: for (DesignComponent designComponent : event
0219: .getFullyAffectedComponents()) {
0220: TypeID typeId = designComponent.getType();
0221: assert (typeId != null);
0222:
0223: if (DEBUG_UNDO)
0224: System.out.println("Affected ComponentID: "
0225: + designComponent.getComponentID()
0226: + ", type: "
0227: + designComponent.getType().getString()); // NOI18N
0228:
0229: if (typeId.equals(SceneCD.TYPEID)) {
0230: this .refreshScene(designComponent, event);
0231: } else if (typeId.equals(TiledLayerCD.TYPEID)) {
0232: this .refreshTiledLayer(designComponent, event);
0233: } else if (typeId.equals(SpriteCD.TYPEID)) {
0234: this .refreshSprite(designComponent, event);
0235: } else if (typeId.equals(SequenceCD.TYPEID)) {
0236: this .refreshSequence(designComponent, event);
0237: } else if (typeId.equals(AnimatedTileCD.TYPEID)) {
0238: this .refreshAnimatedTile(designComponent, event);
0239: } else {
0240: if (DEBUG_UNDO)
0241: System.out
0242: .println("Currently not handling this in type in GameController.designChanged() typeId: "
0243: + typeId.getString()); // NOI18N
0244: }
0245: }
0246: }
0247: }
0248:
0249: private void refreshGameDesign(DesignComponent designComponent,
0250: DesignEvent event) {
0251:
0252: if (changeMap.remove(designComponent.getComponentID()) != null) {
0253: return;
0254: }
0255:
0256: this .getGameDesign().removeGlobalRepositoryListener(this );
0257: this .getGameDesign().removePropertyChangeListener(this );
0258:
0259: GlobalRepository globalRepo = this .getGameDesign();
0260: Collection<DesignComponent> dcChildren = designComponent
0261: .getComponents();
0262:
0263: Set<Identifiable> children = new HashSet<Identifiable>();
0264: children.addAll(globalRepo.getImageResources());
0265: children.addAll(globalRepo.getScenes());
0266: children.addAll(globalRepo.getSprites());
0267: children.addAll(globalRepo.getTiledLayers());
0268:
0269: //add any components present in designDocument but not present in globalRepo
0270: for (DesignComponent dc : dcChildren) {
0271: boolean found = false;
0272: for (Identifiable child : children) {
0273: if (dc.getComponentID() == child.getId()) {
0274: found = true;
0275: break;
0276: }
0277: }
0278: if (!found) {
0279: this .modelComponent(dc);
0280: }
0281: }
0282:
0283: //remove any components present in globalRepo but not present in designComponent
0284: for (Identifiable child : children) {
0285: boolean found = false;
0286: for (DesignComponent dc : dcChildren) {
0287: if (child.getId() == dc.getComponentID()) {
0288: found = true;
0289: break;
0290: }
0291: }
0292: if (!found) {
0293: globalRepo.removeIdentifiable(child.getId());
0294: }
0295: }
0296:
0297: this .getGameDesign().addGlobalRepositoryListener(this );
0298: this .getGameDesign().addPropertyChangeListener(this );
0299: globalRepo.getMainView().requestEditing(globalRepo);
0300: }
0301:
0302: private void refreshScene(DesignComponent designComponent,
0303: DesignEvent event) {
0304: Scene scene = this .getGameDesign().getScene(
0305: designComponent.getComponentID());
0306: scene.removePropertyChangeListener(this );
0307: scene.removeSceneListener(this );
0308:
0309: if (event.isComponentPropertyChanged(designComponent,
0310: SceneCD.PROPERTY_NAME)) {
0311: if (SceneCD.PROPERTY_NAME.equals(changeMap
0312: .get(designComponent.getComponentID()))) {
0313: changeMap.remove(designComponent.getComponentID());
0314: } else {
0315: String name = (String) designComponent.readProperty(
0316: SceneCD.PROPERTY_NAME).getPrimitiveValue();
0317: scene.setName(name);
0318: }
0319: } else {
0320: if (SceneCD.PROPERTY_SCENE_ITEMS.equals(changeMap
0321: .get(designComponent.getComponentID()))) {
0322: changeMap.remove(designComponent.getComponentID());
0323: } else {
0324: List<Layer> newLayers = new ArrayList<Layer>();
0325:
0326: List<PropertyValue> sceneItemsProps = designComponent
0327: .readProperty(SceneCD.PROPERTY_SCENE_ITEMS)
0328: .getArray();
0329: for (PropertyValue sceneItemProp : sceneItemsProps) {
0330: DesignComponent sceneItemDC = sceneItemProp
0331: .getComponent();
0332:
0333: Point layerLocation = (Point) sceneItemDC
0334: .readProperty(SceneItemCD.PROPERTY_POSITION)
0335: .getPrimitiveValue();
0336: Boolean locked = (Boolean) sceneItemDC
0337: .readProperty(SceneItemCD.PROPERTY_LOCK)
0338: .getPrimitiveValue();
0339: Boolean visible = (Boolean) sceneItemDC
0340: .readProperty(SceneItemCD.PROPERTY_VISIBLE)
0341: .getPrimitiveValue();
0342: DesignComponent layerDC = sceneItemDC.readProperty(
0343: SceneItemCD.PROPERTY_LAYER).getComponent();
0344: int zOrder = (Integer) sceneItemDC.readProperty(
0345: SceneItemCD.PROPERTY_Z_ORDER)
0346: .getPrimitiveValue();
0347:
0348: Layer layer = this .getGameDesign().getLayer(
0349: layerDC.getComponentID());
0350: newLayers.add(layer);
0351:
0352: if (!scene.contains(layer)) {
0353: scene.append(layer);
0354: }
0355:
0356: //temporarly unlock the layer so that we can change its position in scene if needed (proper lock is reapplied a few lines down anyway)
0357: scene.setLayerLocked(layer, false);
0358:
0359: scene.move(layer, zOrder);
0360: scene.setLayerPosition(layer, layerLocation, false);
0361: scene.setLayerVisible(layer, visible);
0362: scene.setLayerLocked(layer, locked);
0363: }
0364:
0365: //now remove all layers that are no longer in the scene
0366: List<Layer> origLayers = new ArrayList<Layer>(scene
0367: .getLayers());
0368: for (Layer origLayer : origLayers) {
0369: boolean found = false;
0370: for (Layer newLayer : newLayers) {
0371: if (origLayer.getName().equals(
0372: newLayer.getName())) {
0373: found = true;
0374: }
0375: }
0376: if (!found) {
0377: scene.remove(origLayer);
0378: }
0379: }
0380: }
0381: }
0382:
0383: scene.addPropertyChangeListener(this );
0384: scene.addSceneListener(this );
0385: this .getGameDesign().getMainView().requestEditing(scene);
0386: }
0387:
0388: private void refreshLayerProperties(
0389: DesignComponent designComponent, DesignEvent event) {
0390: Layer layer = (Layer) this .getGameDesign().getLayer(
0391: designComponent.getComponentID());
0392:
0393: if (LayerCD.PROPERTY_NAME.equals(changeMap.get(designComponent
0394: .getComponentID()))) {
0395: changeMap.remove(designComponent.getComponentID());
0396: } else {
0397: if (event.isComponentPropertyChanged(designComponent,
0398: LayerCD.PROPERTY_NAME)) {
0399: String name = (String) designComponent.readProperty(
0400: LayerCD.PROPERTY_NAME).getPrimitiveValue();
0401: layer.setName(name);
0402: }
0403: }
0404:
0405: if (event.isComponentPropertyChanged(designComponent,
0406: LayerCD.PROPERTY_IMAGE_RESOURCE)) {
0407: //not supported
0408: }
0409: if (event.isComponentPropertyChanged(designComponent,
0410: LayerCD.PROPERTY_TILE_WIDTH)) {
0411: //not supported
0412: }
0413: if (event.isComponentPropertyChanged(designComponent,
0414: LayerCD.PROPERTY_TILE_HEIGHT)) {
0415: //not supported
0416: }
0417: }
0418:
0419: private void refreshTiledLayer(DesignComponent designComponent,
0420: DesignEvent event) {
0421: TiledLayer layer = (TiledLayer) this .getGameDesign().getLayer(
0422: designComponent.getComponentID());
0423: layer.removePropertyChangeListener(this );
0424: layer.removeTiledLayerListener(this );
0425:
0426: this .refreshLayerProperties(designComponent, event);
0427: if (TiledLayerCD.PROPERTY_TILES.equals(changeMap
0428: .get(designComponent.getComponentID()))) {
0429: changeMap.remove(designComponent.getComponentID());
0430: } else {
0431: if (event.isComponentPropertyChanged(designComponent,
0432: TiledLayerCD.PROPERTY_TILES)) {
0433: int[][] grid = (int[][]) designComponent.readProperty(
0434: TiledLayerCD.PROPERTY_TILES)
0435: .getPrimitiveValue();
0436: layer.setTiles(grid);
0437: }
0438: }
0439:
0440: layer.addPropertyChangeListener(this );
0441: layer.addTiledLayerListener(this );
0442: this .getGameDesign().getMainView().requestEditing(layer);
0443: }
0444:
0445: private void refreshSprite(DesignComponent designComponent,
0446: DesignEvent event) {
0447: Sprite layer = (Sprite) this .getGameDesign().getLayer(
0448: designComponent.getComponentID());
0449: layer.removePropertyChangeListener(this );
0450: layer.removeSequenceContainerListener(this );
0451:
0452: this .refreshLayerProperties(designComponent, event);
0453:
0454: DesignComponent imgResDC = designComponent.readProperty(
0455: LayerCD.PROPERTY_IMAGE_RESOURCE).getComponent();
0456: ImageResource imgRes = this .getGameDesign().getImageResource(
0457: imgResDC.getComponentID());
0458:
0459: if (SequenceContainerCDProperties.PROP_SEQUENCES
0460: .equals(changeMap.get(designComponent.getComponentID()))) {
0461: changeMap.remove(designComponent.getComponentID());
0462: } else {
0463: if (event.isComponentPropertyChanged(designComponent,
0464: SequenceContainerCDProperties.PROP_SEQUENCES)) {
0465: List<PropertyValue> sequenceDCs = designComponent
0466: .readProperty(
0467: SequenceContainerCDProperties.PROP_SEQUENCES)
0468: .getArray();
0469: List<Sequence> oldSequences = layer.getSequences();
0470: List<Sequence> newSequences = new ArrayList<Sequence>();
0471:
0472: //add sequences not previously contained
0473: for (PropertyValue propertyValue : sequenceDCs) {
0474: DesignComponent sequenceDC = propertyValue
0475: .getComponent();
0476: Sequence sequence = (Sequence) this
0477: .findIdentifiable(sequenceDC
0478: .getComponentID());
0479: assert (sequence != null);
0480: newSequences.add(sequence);
0481:
0482: if (!oldSequences.contains(sequence)) {
0483: layer.append(sequence);
0484: }
0485: }
0486:
0487: List<Sequence> iterOldSequences = new ArrayList<Sequence>(
0488: layer.getSequences());
0489: //remove sequences previously contained but no longer present
0490: for (Sequence sequence : iterOldSequences) {
0491: if (!newSequences.contains(sequence)) {
0492:
0493: if (DEBUG_UNDO)
0494: System.out.println("remove seq: "
0495: + sequence + " from sprite: "
0496: + layer); // NOI18N
0497: layer.remove(sequence);
0498: }
0499: }
0500: }
0501: }
0502: if (SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE
0503: .equals(changeMap.get(designComponent.getComponentID()))) {
0504: changeMap.remove(designComponent.getComponentID());
0505: } else {
0506: if (event
0507: .isComponentPropertyChanged(
0508: designComponent,
0509: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)) {
0510: DesignComponent defaultSequenceDC = designComponent
0511: .readProperty(
0512: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)
0513: .getComponent();
0514: Sequence defSeq = imgRes.getSequence(defaultSequenceDC
0515: .getComponentID());
0516: layer.setDefaultSequence(defSeq);
0517: }
0518: }
0519:
0520: layer.addPropertyChangeListener(this );
0521: layer.addSequenceContainerListener(this );
0522: this .getGameDesign().getMainView().requestEditing(layer);
0523: }
0524:
0525: private void refreshAnimatedTile(DesignComponent designComponent,
0526: DesignEvent event) {
0527: DesignComponent imgResDC = designComponent.readProperty(
0528: AnimatedTileCD.PROP_IMAGE_RESOURCE).getComponent();
0529: //imgResDC will be null only if sequence is being removed from it's container - therefor we can just return
0530: if (imgResDC == null) {
0531: return;
0532: }
0533:
0534: ImageResource imgRes = this .getGameDesign().getImageResource(
0535: imgResDC.getComponentID());
0536:
0537: AnimatedTile animTile = (AnimatedTile) imgRes
0538: .getAnimatedTile(designComponent.getComponentID());
0539:
0540: animTile.removePropertyChangeListener(this );
0541: animTile.removeSequenceContainerListener(this );
0542:
0543: if (AnimatedTileCD.PROPERTY_NAME.equals(changeMap
0544: .get(designComponent.getComponentID()))) {
0545: changeMap.remove(designComponent.getComponentID());
0546: } else {
0547: if (event.isComponentPropertyChanged(designComponent,
0548: AnimatedTileCD.PROPERTY_NAME)) {
0549: String name = (String) designComponent.readProperty(
0550: AnimatedTileCD.PROPERTY_NAME)
0551: .getPrimitiveValue();
0552: animTile.setName(name);
0553: }
0554: }
0555:
0556: if (SequenceContainerCDProperties.PROP_SEQUENCES
0557: .equals(changeMap.get(designComponent.getComponentID()))) {
0558: changeMap.remove(designComponent.getComponentID());
0559: } else {
0560: if (event.isComponentPropertyChanged(designComponent,
0561: SequenceContainerCDProperties.PROP_SEQUENCES)) {
0562: List<PropertyValue> sequenceDCs = designComponent
0563: .readProperty(
0564: SequenceContainerCDProperties.PROP_SEQUENCES)
0565: .getArray();
0566: List<Sequence> sequences = animTile.getSequences();
0567: List<Sequence> newSequences = new ArrayList<Sequence>();
0568:
0569: //add sequences not previously contained
0570: for (PropertyValue propertyValue : sequenceDCs) {
0571: DesignComponent sequenceDC = propertyValue
0572: .getComponent();
0573: Sequence sequence = imgRes.getSequence(sequenceDC
0574: .getComponentID());
0575: newSequences.add(sequence);
0576:
0577: if (!sequences.contains(sequence)) {
0578: animTile.append(sequence);
0579: }
0580: }
0581:
0582: List<Sequence> iterOldSequences = new ArrayList<Sequence>(
0583: animTile.getSequences());
0584: //remove sequences previously contained but no longer present
0585: for (Sequence sequence : iterOldSequences) {
0586: if (!newSequences.contains(sequence)) {
0587: animTile.remove(sequence);
0588: }
0589: }
0590: }
0591: }
0592:
0593: if (SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE
0594: .equals(changeMap.get(designComponent.getComponentID()))) {
0595: changeMap.remove(designComponent.getComponentID());
0596: } else {
0597: if (event
0598: .isComponentPropertyChanged(
0599: designComponent,
0600: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)) {
0601: DesignComponent defaultSequenceDC = designComponent
0602: .readProperty(
0603: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)
0604: .getComponent();
0605: Sequence defSeq = imgRes.getSequence(defaultSequenceDC
0606: .getComponentID());
0607: animTile.setDefaultSequence(defSeq);
0608: }
0609: }
0610:
0611: animTile.addPropertyChangeListener(this );
0612: animTile.addSequenceContainerListener(this );
0613: this .getGameDesign().getMainView().requestEditing(animTile);
0614: }
0615:
0616: private Identifiable findIdentifiable(long id) {
0617: for (Iterator<Identifiable> it = this .designIdMap.keySet()
0618: .iterator(); it.hasNext();) {
0619: Identifiable identifiable = it.next();
0620: if (identifiable.getId() == id) {
0621: return identifiable;
0622: }
0623: }
0624: return null;
0625: }
0626:
0627: private void refreshSequence(DesignComponent designComponent,
0628: DesignEvent event) {
0629: DesignComponent imgResDC = designComponent.readProperty(
0630: SequenceCD.PROPERTY_IMAGE_RESOURCE).getComponent();
0631: //imgResDC will be null only if sequence is being removed from it's container - therefor we can just return
0632: if (imgResDC == null) {
0633: return;
0634: }
0635:
0636: Sequence sequence = (Sequence) this
0637: .findIdentifiable(designComponent.getComponentID());
0638: sequence.removePropertyChangeListener(this );
0639: sequence.removeSequenceListener(this );
0640:
0641: if (SequenceCD.PROPERTY_NAME.equals(changeMap
0642: .get(designComponent.getComponentID()))) {
0643: changeMap.remove(designComponent.getComponentID());
0644: } else {
0645: if (event.isComponentPropertyChanged(designComponent,
0646: SequenceCD.PROPERTY_NAME)) {
0647: String name = (String) designComponent.readProperty(
0648: SequenceCD.PROPERTY_NAME).getPrimitiveValue();
0649: sequence.setName(name);
0650: }
0651: }
0652: if (SequenceCD.PROPERTY_FRAME_MS.equals(changeMap
0653: .get(designComponent.getComponentID()))) {
0654: changeMap.remove(designComponent.getComponentID());
0655: } else {
0656: if (event.isComponentPropertyChanged(designComponent,
0657: SequenceCD.PROPERTY_FRAME_MS)) {
0658: int frameMs = (Integer) designComponent.readProperty(
0659: SequenceCD.PROPERTY_FRAME_MS)
0660: .getPrimitiveValue();
0661: sequence.setFrameMs(frameMs);
0662: }
0663: }
0664:
0665: if (SequenceCD.PROPERTY_FRAMES.equals(changeMap
0666: .get(designComponent.getComponentID()))) {
0667: changeMap.remove(designComponent.getComponentID());
0668: } else {
0669: if (event.isComponentPropertyChanged(designComponent,
0670: SequenceCD.PROPERTY_FRAMES)) {
0671: int[] frames = (int[]) designComponent.readProperty(
0672: SequenceCD.PROPERTY_FRAMES).getPrimitiveValue();
0673: sequence.setFrames(frames);
0674: }
0675: }
0676:
0677: if (event.isComponentPropertyChanged(designComponent,
0678: SequenceCD.PROPERTY_FRAME_WIDTH)) {
0679: //not supported
0680: } else if (event.isComponentPropertyChanged(designComponent,
0681: SequenceCD.PROPERTY_FRAME_HEIGHT)) {
0682: //not supported
0683: } else if (event.isComponentPropertyChanged(designComponent,
0684: SequenceCD.PROPERTY_ZERO_BASED_INDEX)) {
0685: //not supported
0686: }
0687:
0688: sequence.addPropertyChangeListener(this );
0689: sequence.addSequenceListener(this );
0690: //this.getGameDesign().getMainView().requestEditing(sequence.);
0691: }
0692:
0693: private void refreshImageResource(DesignComponent designComponent,
0694: DesignEvent event) {
0695: if (changeMap.remove(designComponent.getComponentID()) != null) {
0696: return;
0697: }
0698: ImageResource imgRes = this .getGameDesign().getImageResource(
0699: designComponent.getComponentID());
0700: imgRes.removeImageResourceListener(this );
0701:
0702: Collection<DesignComponent> dcChildren = designComponent
0703: .getComponents();
0704: Set<AnimatedTile> children = new HashSet<AnimatedTile>(imgRes
0705: .getAnimatedTiles());
0706:
0707: //add any components present in designDocument but not present in globalRepo
0708: for (DesignComponent dc : dcChildren) {
0709: boolean found = false;
0710: for (Identifiable child : children) {
0711: if (dc.getComponentID() == child.getId()) {
0712: found = true;
0713: break;
0714: }
0715: }
0716: if (!found) {
0717: this .modelComponent(dc);
0718: }
0719: }
0720:
0721: //remove any components present in globalRepo but not present in designComponent
0722: for (AnimatedTile child : children) {
0723: boolean found = false;
0724: for (DesignComponent dc : dcChildren) {
0725: if (child.getId() == dc.getComponentID()) {
0726: found = true;
0727: break;
0728: }
0729: }
0730: if (!found) {
0731: imgRes.removeAnimatedTile(child.getIndex());
0732: }
0733: }
0734:
0735: imgRes.addImageResourceListener(this );
0736:
0737: this .getGameDesign().getMainView().requestEditing(
0738: this .getGameDesign());
0739: }
0740:
0741: public void setDesignDocument(final DesignDocument designDocument) {
0742: if (DEBUG)
0743: System.out.println(">>>> Set design document to: "
0744: + designDocument); // NOI18N
0745:
0746: if (designDocument == this .document) {
0747: return;
0748: }
0749:
0750: this .panel.removeAll();
0751:
0752: GlobalRepository oldGameDesign = this .getGameDesign();
0753:
0754: //if we already have a document then de-register listeners and clean game model
0755: if (this .document != null) {
0756: this .document.getListenerManager().removeDesignListener(
0757: this );
0758: this .removeListeners(designIdMap.keySet().toArray());
0759: oldGameDesign.removeGlobalRepositoryListener(this );
0760: oldGameDesign.removeAllComponents();
0761: oldGameDesign.getMainView().removeEditorManagerListener(
0762: gameEditorView);
0763: designIdMap.clear();
0764: }
0765:
0766: JComponent view = null;
0767:
0768: this .document = designDocument;
0769: final GlobalRepository gameDesign = this .getGameDesign();
0770:
0771: this .gameEditorView.setGameDesign(gameDesign);
0772:
0773: if (designDocument == null) {
0774: view = this .loadingPanel;
0775: } else {
0776: designDocument.getTransactionManager().readAccess(
0777: new Runnable() {
0778: public void run() {
0779: if (true) {
0780: //add all components in the document
0781: DesignComponent root = designDocument
0782: .getRootComponent();
0783: GameController.this
0784: .modelComponent(root);
0785: GameController.this
0786: .registerListeners(designIdMap
0787: .keySet().toArray());
0788:
0789: DesignEventFilter f = new DesignEventFilter();
0790: f.setGlobal(true);
0791: f.addComponentFilter(root, true);
0792: designDocument.getListenerManager()
0793: .addDesignListener(
0794: GameController.this , f);
0795: }
0796: }
0797: });
0798:
0799: //get user to fix invalid image resources - i.e. those with null URLs
0800: Collection<ImageResource> imageResources = gameDesign
0801: .getImageResources();
0802: for (ImageResource imageResource : imageResources) {
0803: if (imageResource.getURL() == null) {
0804: DesignComponent imageResourceDC = designIdMap
0805: .get(imageResource);
0806: this .validateImageResource(imageResource,
0807: imageResourceDC);
0808: }
0809: }
0810: gameDesign.getMainView().addEditorManagerListener(
0811: gameEditorView);
0812: view = gameDesign.getMainView().getRootComponent();
0813:
0814: gameDesign.addGlobalRepositoryListener(GameController.this );
0815: gameDesign.getMainView().requestEditing(gameDesign);
0816: }
0817: this .panel.add(view);
0818: this .panel.validate();
0819: }
0820:
0821: private void removeListeners(Object... objectsOfInterest) {
0822: for (Object o : objectsOfInterest) {
0823: if (DEBUG_UNDO)
0824: System.out.println("removeListeners on: " + o); // NOI18N
0825: if (o instanceof Scene) {
0826: Scene s = (Scene) o;
0827: s.removeSceneListener(this );
0828: s.removePropertyChangeListener(this );
0829: } else if (o instanceof TiledLayer) {
0830: TiledLayer tl = (TiledLayer) o;
0831: tl.removeTiledLayerListener(this );
0832: tl.removePropertyChangeListener(this );
0833: } else if (o instanceof Sprite) {
0834: Sprite s = (Sprite) o;
0835: s.removeSequenceContainerListener(this );
0836: s.removePropertyChangeListener(this );
0837: } else if (o instanceof Sequence) {
0838: Sequence s = (Sequence) o;
0839: s.removeSequenceListener(this );
0840: s.removePropertyChangeListener(this );
0841: } else if (o instanceof AnimatedTile) {
0842: AnimatedTile a = (AnimatedTile) o;
0843: a.removeSequenceContainerListener(this );
0844: a.removePropertyChangeListener(this );
0845: } else if (o instanceof ImageResource) {
0846: ImageResource i = (ImageResource) o;
0847: i.removeImageResourceListener(this );
0848: }
0849: }
0850:
0851: }
0852:
0853: private void registerListeners(Object... objectsOfInterest) {
0854: for (Object o : objectsOfInterest) {
0855: if (DEBUG_UNDO)
0856: System.out.println("registerListeners on: " + o); // NOI18N
0857: if (o instanceof Scene) {
0858: Scene s = (Scene) o;
0859: s.addSceneListener(this );
0860: s.addPropertyChangeListener(this );
0861: } else if (o instanceof TiledLayer) {
0862: TiledLayer tl = (TiledLayer) o;
0863: tl.addTiledLayerListener(this );
0864: tl.addPropertyChangeListener(this );
0865: } else if (o instanceof Sprite) {
0866: Sprite s = (Sprite) o;
0867: s.addSequenceContainerListener(this );
0868: s.addPropertyChangeListener(this );
0869: } else if (o instanceof Sequence) {
0870: Sequence s = (Sequence) o;
0871: s.addSequenceListener(this );
0872: s.addPropertyChangeListener(this );
0873: } else if (o instanceof AnimatedTile) {
0874: AnimatedTile a = (AnimatedTile) o;
0875: a.addSequenceContainerListener(this );
0876: a.addPropertyChangeListener(this );
0877: } else if (o instanceof ImageResource) {
0878: ImageResource i = (ImageResource) o;
0879: i.addImageResourceListener(this );
0880: }
0881: }
0882: }
0883:
0884: private void modelComponent(DesignComponent designComponent) {
0885: //this is sometimes null when i close and open the same project :(
0886: if (designComponent == null) {
0887: return;
0888: }
0889:
0890: Collection<DesignComponent> children = designComponent
0891: .getComponents();
0892: for (DesignComponent child : children) {
0893: this .modelComponent(child);
0894: }
0895:
0896: TypeID typeId = designComponent.getType();
0897: assert (typeId != null);
0898:
0899: if (typeId.equals(SceneCD.TYPEID)) {
0900: Scene scene = this .constructScene(designComponent);
0901: designIdMap.put(scene, designComponent);
0902: } else if (typeId.equals(TiledLayerCD.TYPEID)) {
0903: TiledLayer layer = this
0904: .constructTiledLayer(designComponent);
0905: designIdMap.put(layer, designComponent);
0906: } else if (typeId.equals(SpriteCD.TYPEID)) {
0907: Sprite sprite = this .constructSprite(designComponent);
0908: designIdMap.put(sprite, designComponent);
0909: } else if (typeId.equals(SequenceCD.TYPEID)) {
0910: Sequence sequence = this .constructSequence(designComponent);
0911: designIdMap.put(sequence, designComponent);
0912: } else if (typeId.equals(ImageResourceCD.TYPEID)) {
0913: ImageResource imageResource = this
0914: .constructImageResource(designComponent);
0915: designIdMap.put(imageResource, designComponent);
0916: } else if (typeId.equals(AnimatedTileCD.TYPEID)) {
0917: AnimatedTile animatedTile = this
0918: .constructAnimatedTile(designComponent);
0919: designIdMap.put(animatedTile, designComponent);
0920: }
0921: }
0922:
0923: //These methods create game model from design components
0924:
0925: private AnimatedTile constructAnimatedTile(
0926: DesignComponent animatedTileDC) {
0927: int index = (Integer) animatedTileDC.readProperty(
0928: AnimatedTileCD.PROPERTY_INDEX).getPrimitiveValue();
0929: String name = (String) animatedTileDC.readProperty(
0930: AnimatedTileCD.PROPERTY_NAME).getPrimitiveValue();
0931: DesignComponent imgResDC = animatedTileDC.readProperty(
0932: AnimatedTileCD.PROP_IMAGE_RESOURCE).getComponent();
0933: ImageResource imgRes = this .constructImageResource(imgResDC);
0934:
0935: //if ImageResource already has an animated tile of that name it must have been already constructed
0936: AnimatedTile animatedTile = imgRes.getAnimatedTileByName(name);
0937: if (animatedTile != null) {
0938: return animatedTile;
0939: }
0940:
0941: DesignComponent defaultSequenceDC = animatedTileDC
0942: .readProperty(
0943: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)
0944: .getComponent();
0945: List<PropertyValue> sequenceDCs = animatedTileDC.readProperty(
0946: SequenceContainerCDProperties.PROP_SEQUENCES)
0947: .getArray();
0948:
0949: Sequence defaultSequence = this
0950: .constructSequence(defaultSequenceDC);
0951: animatedTile = imgRes.createAnimatedTile(index, name,
0952: defaultSequence);
0953: animatedTile.setId(animatedTileDC.getComponentID());
0954:
0955: for (PropertyValue propertyValue : sequenceDCs) {
0956: DesignComponent sequenceDC = propertyValue.getComponent();
0957: Sequence sequence = this .constructSequence(sequenceDC);
0958: //defaultSequence is already appended
0959: if (sequence != defaultSequence) {
0960: animatedTile.append(sequence);
0961: }
0962: }
0963:
0964: Identifiable old = this .findIdentifiable(animatedTileDC
0965: .getComponentID());
0966: if (old != null) {
0967: if (DEBUG_UNDO)
0968: System.out.println("> Recreated " + animatedTile
0969: + " remove old mapping and create a new one"); // NOI18N
0970: this .designIdMap.remove(old);
0971: this .removeListeners(old);
0972: this .designIdMap.put(animatedTile, animatedTileDC);
0973: this .registerListeners(animatedTile);
0974: }
0975:
0976: return animatedTile;
0977: }
0978:
0979: private Sprite constructSprite(DesignComponent spriteDC) {
0980: String name = (String) spriteDC.readProperty(
0981: LayerCD.PROPERTY_NAME).getPrimitiveValue();
0982: //if GlobalRepository already has a layer of that name it must have been already constructed
0983: Sprite sprite = (Sprite) this .getGameDesign().getLayerByName(
0984: name);
0985: if (sprite != null) {
0986: return sprite;
0987: }
0988:
0989: DesignComponent imgResDC = spriteDC.readProperty(
0990: LayerCD.PROPERTY_IMAGE_RESOURCE).getComponent();
0991: ImageResource imgRes = this .constructImageResource(imgResDC);
0992:
0993: DesignComponent defaultSequenceDC = spriteDC.readProperty(
0994: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE)
0995: .getComponent();
0996: List<PropertyValue> sequenceDCs = spriteDC.readProperty(
0997: SequenceContainerCDProperties.PROP_SEQUENCES)
0998: .getArray();
0999:
1000: Sequence defaultSequence = this
1001: .constructSequence(defaultSequenceDC);
1002: sprite = this .getGameDesign().createSprite(name, imgRes,
1003: defaultSequence);
1004: sprite.setId(spriteDC.getComponentID());
1005:
1006: for (PropertyValue propertyValue : sequenceDCs) {
1007: DesignComponent sequenceDC = propertyValue.getComponent();
1008: Sequence sequence = this .constructSequence(sequenceDC);
1009: //defaultSequence is already appended
1010: if (sequence != defaultSequence) {
1011: sprite.append(sequence);
1012: }
1013: }
1014:
1015: Identifiable old = this .findIdentifiable(spriteDC
1016: .getComponentID());
1017: if (old != null) {
1018: if (DEBUG_UNDO)
1019: System.out.println("> Recreated " + sprite
1020: + " remove old mapping and create a new one"); // NOI18N
1021: this .designIdMap.remove(old);
1022: this .removeListeners(old);
1023: this .designIdMap.put(sprite, spriteDC);
1024: this .registerListeners(sprite);
1025: }
1026:
1027: return sprite;
1028: }
1029:
1030: private TiledLayer constructTiledLayer(DesignComponent tiledLayerDC) {
1031: String name = (String) tiledLayerDC.readProperty(
1032: LayerCD.PROPERTY_NAME).getPrimitiveValue();
1033: //if GlobalRepository already has a layer of that name it must have been already constructed
1034: TiledLayer tiledLayer = (TiledLayer) this .getGameDesign()
1035: .getLayerByName(name);
1036: if (tiledLayer != null) {
1037: return tiledLayer;
1038: }
1039:
1040: DesignComponent imgResDC = tiledLayerDC.readProperty(
1041: LayerCD.PROPERTY_IMAGE_RESOURCE).getComponent();
1042: ImageResource imgRes = this .constructImageResource(imgResDC);
1043: int[][] gridOriginal = (int[][]) tiledLayerDC.readProperty(
1044: TiledLayerCD.PROPERTY_TILES).getPrimitiveValue();
1045: int tileWidth = MidpTypes.getInteger(tiledLayerDC
1046: .readProperty(LayerCD.PROPERTY_TILE_WIDTH));
1047: int tileHeight = MidpTypes.getInteger(tiledLayerDC
1048: .readProperty(LayerCD.PROPERTY_TILE_HEIGHT));
1049:
1050: int[][] grid = TiledLayer.cloneTiles(gridOriginal);
1051: tiledLayer = this .getGameDesign().createTiledLayer(name,
1052: imgRes, grid, tileWidth, tileHeight);
1053: tiledLayer.setId(tiledLayerDC.getComponentID());
1054:
1055: Identifiable old = this .findIdentifiable(tiledLayerDC
1056: .getComponentID());
1057: if (old != null) {
1058: if (DEBUG_UNDO)
1059: System.out.println("> Recreated " + tiledLayer
1060: + " remove old mapping and create a new one"); // NOI18N
1061: this .designIdMap.remove(old);
1062: this .removeListeners(old);
1063: this .designIdMap.put(tiledLayer, tiledLayerDC);
1064: this .registerListeners(tiledLayer);
1065: }
1066:
1067: return tiledLayer;
1068: }
1069:
1070: private Sequence constructSequence(DesignComponent sequenceDC) {
1071: String name = (String) sequenceDC.readProperty(
1072: SequenceCD.PROPERTY_NAME).getPrimitiveValue();
1073: DesignComponent imgResDC = sequenceDC.readProperty(
1074: SequenceCD.PROPERTY_IMAGE_RESOURCE).getComponent();
1075: ImageResource imgRes = this .constructImageResource(imgResDC);
1076:
1077: //if GlobalRepository already has a sequence of that name it must have been already constructed
1078: Sequence sequence = imgRes.getSequenceByName(name);
1079: if (sequence != null) {
1080: return sequence;
1081: }
1082:
1083: int frameMs = (Integer) sequenceDC.readProperty(
1084: SequenceCD.PROPERTY_FRAME_MS).getPrimitiveValue();
1085: int[] frames = (int[]) sequenceDC.readProperty(
1086: SequenceCD.PROPERTY_FRAMES).getPrimitiveValue();
1087: int frameWidth = (Integer) sequenceDC.readProperty(
1088: SequenceCD.PROPERTY_FRAME_WIDTH).getPrimitiveValue();
1089: int frameHeight = (Integer) sequenceDC.readProperty(
1090: SequenceCD.PROPERTY_FRAME_HEIGHT).getPrimitiveValue();
1091: boolean zeroBasedIndex = (Boolean) sequenceDC.readProperty(
1092: SequenceCD.PROPERTY_ZERO_BASED_INDEX)
1093: .getPrimitiveValue();
1094:
1095: sequence = imgRes.createSequence(name, frames.length,
1096: frameWidth, frameHeight, zeroBasedIndex);
1097: sequence.setId(sequenceDC.getComponentID());
1098: sequence.setFrameMs(frameMs);
1099:
1100: for (int i = 0; i < frames.length; i++) {
1101: sequence.setFrame((StaticTile) imgRes.getTile(frames[i],
1102: frameWidth, frameHeight, zeroBasedIndex), i);
1103: }
1104:
1105: Identifiable old = this .findIdentifiable(sequenceDC
1106: .getComponentID());
1107: if (old != null) {
1108: if (DEBUG_UNDO)
1109: System.out.println("> Recreated " + sequence
1110: + " remove old mapping and create a new one"); // NOI18N
1111: this .designIdMap.remove(old);
1112: this .removeListeners(old);
1113: this .designIdMap.put(sequence, sequenceDC);
1114: this .registerListeners(sequence);
1115: }
1116:
1117: return sequence;
1118: }
1119:
1120: private ImageResource constructImageResource(
1121: final DesignComponent imageResourceDC) {
1122: URL imgResUrl = null;
1123:
1124: final String imgResPath = (String) imageResourceDC
1125: .readProperty(ImageResourceCD.PROPERTY_IMAGE_PATH)
1126: .getPrimitiveValue();
1127: final String imgResName = (String) imageResourceDC
1128: .readProperty(ImageResourceCD.PROPERTY_NAME)
1129: .getPrimitiveValue();
1130: ImageResource imgRes = this .getGameDesign().getImageResource(
1131: imgResPath);
1132: if (imgRes != null) {
1133: return imgRes;
1134: }
1135:
1136: Map<FileObject, FileObject> imagesMap = MidpProjectSupport
1137: .getFileObjectsForRelativeResourcePath(document,
1138: imgResPath);
1139:
1140: //if there is a single image matching this image resource path then excellent - all is as it should be and we have
1141: //no image name conflicts
1142: if (imagesMap.size() == 1) {
1143: FileObject fo = imagesMap.keySet().iterator().next();
1144: try {
1145: imgResUrl = fo.getURL();
1146: } catch (FileStateInvalidException e) {
1147: e.printStackTrace();
1148: }
1149: }
1150:
1151: //if at this point imgResUrl is null then we need to resolve image name conflicts or missing
1152: //images after the design document is loaded by running method validateImageResource() on
1153: //all imageResources that have null imageURL
1154: ImageResource imageResource = this .getGameDesign()
1155: .getImageResource(imgResUrl, imgResPath);
1156: imageResource.setName(imgResName);
1157: imageResource.setId(imageResourceDC.getComponentID());
1158: return imageResource;
1159: }
1160:
1161: private void validateImageResource(ImageResource imageResource,
1162: final DesignComponent imageResourceDC) {
1163: FileObject fo;
1164: URL imgResUrl;
1165: final String imgResPath = imageResource
1166: .getRelativeResourcePath();
1167:
1168: Map<FileObject, FileObject> imagesMap = MidpProjectSupport
1169: .getFileObjectsForRelativeResourcePath(document,
1170: imgResPath);
1171: if (imagesMap.size() > 1) {
1172: //multiple locations (e.g. jars) contain the same image - show a dialog to let the
1173: //user choose which single image should be used
1174: if (DEBUG) {
1175: System.out
1176: .println("found multiple images matching the relative path:"); // NOI18N
1177: for (Map.Entry<FileObject, FileObject> entry : imagesMap
1178: .entrySet()) {
1179: System.out.println("root: " + entry.getValue()
1180: + ", path: " + entry.getKey()); // NOI18N
1181: }
1182: }
1183:
1184: final SelectImageForLayerDialog dialog = new SelectImageForLayerDialog(
1185: NbBundle
1186: .getMessage(
1187: GameController.class,
1188: "GameController.SelectImageDialog.description1_txt",
1189: imgResPath),
1190: //"Multiple images found matching the relative path: " + imgResPath,
1191: imagesMap.keySet());
1192:
1193: DialogDescriptor dd = new DialogDescriptor(dialog, NbBundle
1194: .getMessage(GameController.class,
1195: "GameController.SelectImageDialog.title"));
1196: dd.setValid(false);
1197: dd.setButtonListener(new ActionListener() {
1198: public void actionPerformed(ActionEvent e) {
1199: if (e.getSource() == NotifyDescriptor.CANCEL_OPTION) {
1200: //XXX close the document - user did not choose one of the available images
1201: }
1202: }
1203: });
1204: dialog.setDialogDescriptor(dd);
1205: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1206: d.setVisible(true);
1207:
1208: fo = dialog.getValue();
1209: final String newPath = "/"
1210: + FileUtil.getRelativePath(imagesMap.get(fo), fo);
1211: if (DEBUG)
1212: System.out.println("Setting new path: " + newPath); // NOI18N
1213:
1214: document.getTransactionManager().writeAccess(
1215: new Runnable() {
1216: public void run() {
1217: changeMap
1218: .put(
1219: imageResourceDC
1220: .getComponentID(),
1221: ImageResourceCD.PROPERTY_IMAGE_PATH);
1222: imageResourceDC
1223: .writeProperty(
1224: ImageResourceCD.PROPERTY_IMAGE_PATH,
1225: MidpTypes
1226: .createStringValue(newPath));
1227: }
1228: });
1229:
1230: if (DEBUG_UNDO)
1231: System.out.println("Set new path: " + newPath); // NOI18N
1232: } else if (imagesMap.isEmpty()) {
1233: //image is no longer on the classpath - prompt the user to select a replacement image
1234: fo = null;
1235: if (DEBUG)
1236: System.out.println("Image " + imgResPath
1237: + " doesn't exist, select a replacement."); // NOI18N
1238:
1239: Map<FileObject, String> images = MidpProjectSupport
1240: .getImagesForProject(document, false);
1241:
1242: final SelectImageForLayerDialog dialog = new SelectImageForLayerDialog(
1243: NbBundle
1244: .getMessage(
1245: GameController.class,
1246: "GameController.SelectImageDialog.description2_txt",
1247: imgResPath),
1248: //"Image " + imgResPath + " doesn't exist, select a replacement.",
1249: images.keySet());
1250:
1251: DialogDescriptor dd = new DialogDescriptor(dialog, NbBundle
1252: .getMessage(GameController.class,
1253: "GameController.SelectImageDialog.title"));
1254: dd.setValid(false);
1255: dd.setButtonListener(new ActionListener() {
1256: public void actionPerformed(ActionEvent e) {
1257: if (e.getSource() == NotifyDescriptor.CANCEL_OPTION) {
1258: //XXX close the document - missing image could not be recovered by the user
1259: }
1260: }
1261: });
1262: dialog.setDialogDescriptor(dd);
1263: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
1264: d.setVisible(true);
1265:
1266: fo = dialog.getValue();
1267: final String newPath = images.get(fo);
1268: if (DEBUG)
1269: System.out.println("Setting new path: " + newPath); // NOI18N
1270:
1271: document.getTransactionManager().writeAccess(
1272: new Runnable() {
1273: public void run() {
1274: changeMap
1275: .put(
1276: imageResourceDC
1277: .getComponentID(),
1278: ImageResourceCD.PROPERTY_IMAGE_PATH);
1279: imageResourceDC
1280: .writeProperty(
1281: ImageResourceCD.PROPERTY_IMAGE_PATH,
1282: MidpTypes
1283: .createStringValue(newPath));
1284: }
1285: });
1286: if (DEBUG_UNDO)
1287: System.out.println("Set new path: " + newPath); // NOI18N
1288: } else {
1289: //there is a single matching image on the classpath - excellent :)
1290: fo = imagesMap.keySet().iterator().next();
1291: if (DEBUG)
1292: System.out.println("Found single matching image ULR: "
1293: + fo.getPath()); // NOI18N
1294: }
1295:
1296: try {
1297: imgResUrl = fo.getURL();
1298: imageResource.setURL(imgResUrl);
1299: } catch (FileStateInvalidException e) {
1300: throw new RuntimeException(e);
1301: }
1302:
1303: }
1304:
1305: private Scene constructScene(DesignComponent sceneDC) {
1306: String name = (String) sceneDC.readProperty(
1307: SceneCD.PROPERTY_NAME).getPrimitiveValue();
1308: //if GlobalRepository already has a scene of that name it must have been already constructed
1309: Scene scene = this .getGameDesign().getSceneByName(name);
1310: if (scene != null) {
1311: return scene;
1312: }
1313:
1314: scene = this .getGameDesign().createScene(name);
1315: scene.setId(sceneDC.getComponentID());
1316:
1317: List<PropertyValue> sceneItemsProps = sceneDC.readProperty(
1318: SceneCD.PROPERTY_SCENE_ITEMS).getArray();
1319: for (PropertyValue sceneItemProp : sceneItemsProps) {
1320: DesignComponent sceneItemDC = sceneItemProp.getComponent();
1321:
1322: Point layerLocation = (Point) sceneItemDC.readProperty(
1323: SceneItemCD.PROPERTY_POSITION).getPrimitiveValue();
1324: Boolean locked = (Boolean) sceneItemDC.readProperty(
1325: SceneItemCD.PROPERTY_LOCK).getPrimitiveValue();
1326: Boolean visible = (Boolean) sceneItemDC.readProperty(
1327: SceneItemCD.PROPERTY_VISIBLE).getPrimitiveValue();
1328: DesignComponent layerDC = sceneItemDC.readProperty(
1329: SceneItemCD.PROPERTY_LAYER).getComponent();
1330: int zOrder = (Integer) sceneItemDC.readProperty(
1331: SceneItemCD.PROPERTY_Z_ORDER).getPrimitiveValue();
1332:
1333: Layer layer = null;
1334: if (layerDC.getType().equals(TiledLayerCD.TYPEID)) {
1335: layer = this .constructTiledLayer(layerDC);
1336: } else {
1337: layer = this .constructSprite(layerDC);
1338: }
1339:
1340: scene.append(layer);
1341:
1342: scene.move(layer, zOrder);
1343: scene.setLayerPosition(layer, layerLocation, false);
1344: scene.setLayerVisible(layer, visible);
1345: scene.setLayerLocked(layer, locked);
1346: }
1347:
1348: Identifiable old = this .findIdentifiable(sceneDC
1349: .getComponentID());
1350: if (old != null) {
1351: if (DEBUG_UNDO)
1352: System.out.println("> Recreated " + scene
1353: + " remove old mapping and create a new one"); // NOI18N
1354: this .designIdMap.remove(old);
1355: this .removeListeners(old);
1356: this .designIdMap.put(scene, sceneDC);
1357: this .registerListeners(scene);
1358: }
1359:
1360: return scene;
1361: }
1362:
1363: //These methods create design components from game identifiable model comnponents and update their ids
1364:
1365: public static DesignComponent createSceneDCFromScene(
1366: DesignDocument doc,
1367: Map<Identifiable, DesignComponent> designIdMap, Scene scene) {
1368: DesignComponent dcScene = designIdMap.get(scene);
1369: if (dcScene != null) {
1370: return dcScene;
1371: }
1372: dcScene = doc.createComponent(SceneCD.TYPEID);
1373: scene.setId(dcScene.getComponentID());
1374:
1375: dcScene.writeProperty(SceneCD.PROPERTY_NAME, MidpTypes
1376: .createStringValue(scene.getName()));
1377: writeSceneItemsToSceneDC(doc, designIdMap, dcScene, scene);
1378: return dcScene;
1379: }
1380:
1381: private static void writeSceneItemsToSceneDC(DesignDocument doc,
1382: Map<Identifiable, DesignComponent> designIdMap,
1383: DesignComponent dcScene, Scene scene) {
1384: //fist remove all scene items
1385: List<PropertyValue> sceneItemProps = dcScene.readProperty(
1386: SceneCD.PROPERTY_SCENE_ITEMS).getArray();
1387: for (Iterator<PropertyValue> it = sceneItemProps.iterator(); it
1388: .hasNext();) {
1389: PropertyValue propertyValue = it.next();
1390: DesignComponent dcSceneItemComp = propertyValue
1391: .getComponent();
1392: dcSceneItemComp.removeFromParentComponent();
1393: }
1394: dcScene.writeProperty(SceneCD.PROPERTY_SCENE_ITEMS,
1395: PropertyValue.createEmptyArray(SceneItemCD.TYPEID));
1396:
1397: //them add scene items according to the current state of the scene
1398: List<Layer> layers = scene.getLayers();
1399: List<PropertyValue> scenePropValues = new ArrayList<PropertyValue>();
1400:
1401: for (Iterator<Layer> it = layers.iterator(); it.hasNext();) {
1402: DesignComponent sceneItemDC = doc
1403: .createComponent(SceneItemCD.TYPEID);
1404:
1405: Layer layer = it.next();
1406: DesignComponent layerDC = designIdMap.get(layer);
1407: assert (layerDC != null);
1408:
1409: sceneItemDC.writeProperty(SceneItemCD.PROPERTY_LAYER,
1410: PropertyValue.createComponentReference(layerDC));
1411: sceneItemDC.writeProperty(SceneItemCD.PROPERTY_LOCK,
1412: MidpTypes.createBooleanValue(scene
1413: .isLayerLocked(layer)));
1414: sceneItemDC.writeProperty(SceneItemCD.PROPERTY_VISIBLE,
1415: MidpTypes.createBooleanValue(scene
1416: .isLayerVisible(layer)));
1417: sceneItemDC.writeProperty(SceneItemCD.PROPERTY_POSITION,
1418: GameTypes.createPointProperty(scene
1419: .getLayerPosition(layer)));
1420: sceneItemDC.writeProperty(SceneItemCD.PROPERTY_Z_ORDER,
1421: MidpTypes.createIntegerValue(scene.indexOf(layer)));
1422:
1423: dcScene.addComponent(sceneItemDC);
1424:
1425: PropertyValue sceneItemPropVal = PropertyValue
1426: .createComponentReference(sceneItemDC);
1427: scenePropValues.add(sceneItemPropVal);
1428: }
1429: dcScene.writeProperty(SceneCD.PROPERTY_SCENE_ITEMS,
1430: PropertyValue.createArray(SceneItemCD.TYPEID,
1431: scenePropValues));
1432: }
1433:
1434: public static DesignComponent createTiledLayerDCFromTiledLayer(
1435: DesignDocument doc,
1436: Map<Identifiable, DesignComponent> designIdMap,
1437: TiledLayer layer) {
1438: DesignComponent dcLayer = designIdMap.get(layer);
1439: if (dcLayer != null) {
1440: return dcLayer;
1441: }
1442: dcLayer = doc.createComponent(TiledLayerCD.TYPEID);
1443: layer.setId(dcLayer.getComponentID());
1444:
1445: dcLayer.writeProperty(LayerCD.PROPERTY_NAME, MidpTypes
1446: .createStringValue(layer.getName()));
1447:
1448: DesignComponent dcImgRes = designIdMap.get(layer
1449: .getImageResource());
1450: assert (dcImgRes != null);
1451:
1452: dcLayer.writeProperty(LayerCD.PROPERTY_IMAGE_RESOURCE,
1453: PropertyValue.createComponentReference(dcImgRes));
1454: PropertyValue propTiles = GameTypes.createTilesProperty(layer
1455: .getTiles());
1456: dcLayer.writeProperty(TiledLayerCD.PROPERTY_TILES, propTiles);
1457: dcLayer.writeProperty(LayerCD.PROPERTY_TILE_WIDTH, MidpTypes
1458: .createIntegerValue(layer.getTileWidth()));
1459: dcLayer.writeProperty(LayerCD.PROPERTY_TILE_HEIGHT, MidpTypes
1460: .createIntegerValue(layer.getTileHeight()));
1461:
1462: return dcLayer;
1463: }
1464:
1465: public DesignComponent createAnimatedTileDCFromAnimatedTile(
1466: AnimatedTile tile) {
1467: DesignComponent dcAt = designIdMap.get(tile);
1468: if (dcAt != null) {
1469: return dcAt;
1470: }
1471: dcAt = document.createComponent(AnimatedTileCD.TYPEID);
1472: tile.setId(dcAt.getComponentID());
1473:
1474: dcAt.writeProperty(AnimatedTileCD.PROPERTY_NAME, MidpTypes
1475: .createStringValue(tile.getName()));
1476: dcAt.writeProperty(AnimatedTileCD.PROPERTY_INDEX, MidpTypes
1477: .createIntegerValue(tile.getIndex()));
1478: dcAt.writeProperty(AnimatedTileCD.PROPERTY_WIDTH, MidpTypes
1479: .createIntegerValue(tile.getWidth()));
1480: dcAt.writeProperty(AnimatedTileCD.PROPERTY_HEIGHT, MidpTypes
1481: .createIntegerValue(tile.getHeight()));
1482:
1483: DesignComponent dcImgRes = designIdMap.get(tile
1484: .getImageResource());
1485: assert (dcImgRes != null);
1486: dcAt.writeProperty(AnimatedTileCD.PROP_IMAGE_RESOURCE,
1487: PropertyValue.createComponentReference(dcImgRes));
1488:
1489: List<PropertyValue> sequencePropValues = new ArrayList<PropertyValue>();
1490: for (Sequence seq : tile.getSequences()) {
1491: DesignComponent dcSeq = designIdMap.get(seq);
1492: if (dcSeq == null) {
1493: dcSeq = this .createSequenceDCFromSequence(seq);
1494: designIdMap.put(seq, dcSeq);
1495: }
1496: if (!dcAt.getComponents().contains(dcSeq)) {
1497: dcAt.addComponent(dcSeq);
1498: }
1499: if (seq == tile.getDefaultSequence()) {
1500: dcAt
1501: .writeProperty(
1502: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE,
1503: PropertyValue
1504: .createComponentReference(dcSeq));
1505: }
1506: PropertyValue seqPropertyValue = PropertyValue
1507: .createComponentReference(dcSeq);
1508: sequencePropValues.add(seqPropertyValue);
1509: }
1510: dcAt.writeProperty(
1511: SequenceContainerCDProperties.PROP_SEQUENCES,
1512: PropertyValue.createArray(SequenceCD.TYPEID,
1513: sequencePropValues));
1514:
1515: return dcAt;
1516: }
1517:
1518: public DesignComponent createSpriteDCFromSprite(Sprite layer) {
1519: DesignComponent dcLayer = designIdMap.get(layer);
1520: if (dcLayer != null) {
1521: return dcLayer;
1522: }
1523: dcLayer = document.createComponent(SpriteCD.TYPEID);
1524: layer.setId(dcLayer.getComponentID());
1525:
1526: dcLayer.writeProperty(LayerCD.PROPERTY_NAME, MidpTypes
1527: .createStringValue(layer.getName()));
1528: dcLayer.writeProperty(LayerCD.PROPERTY_TILE_WIDTH, MidpTypes
1529: .createIntegerValue(layer.getTileWidth()));
1530: dcLayer.writeProperty(LayerCD.PROPERTY_TILE_HEIGHT, MidpTypes
1531: .createIntegerValue(layer.getTileHeight()));
1532:
1533: DesignComponent dcImgRes = designIdMap.get(layer
1534: .getImageResource());
1535: assert (dcImgRes != null);
1536: dcLayer.writeProperty(LayerCD.PROPERTY_IMAGE_RESOURCE,
1537: PropertyValue.createComponentReference(dcImgRes));
1538:
1539: List<PropertyValue> sequencePropValues = new ArrayList<PropertyValue>();
1540: for (Sequence seq : layer.getSequences()) {
1541: DesignComponent dcSeq = designIdMap.get(seq);
1542: if (dcSeq == null) {
1543: dcSeq = this .createSequenceDCFromSequence(seq);
1544: designIdMap.put(seq, dcSeq);
1545: }
1546: if (!dcLayer.getComponents().contains(dcSeq)) {
1547: dcLayer.addComponent(dcSeq);
1548: }
1549: if (seq == layer.getDefaultSequence()) {
1550: dcLayer
1551: .writeProperty(
1552: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE,
1553: PropertyValue
1554: .createComponentReference(dcSeq));
1555: }
1556: PropertyValue seqPropertyValue = PropertyValue
1557: .createComponentReference(dcSeq);
1558: sequencePropValues.add(seqPropertyValue);
1559: }
1560: dcLayer.writeProperty(
1561: SequenceContainerCDProperties.PROP_SEQUENCES,
1562: PropertyValue.createArray(SequenceCD.TYPEID,
1563: sequencePropValues));
1564:
1565: return dcLayer;
1566: }
1567:
1568: public DesignComponent createImageResourceDCFromImageResource(
1569: ImageResource imageResource) {
1570: DesignComponent dcImgRes = designIdMap.get(imageResource);
1571: if (dcImgRes != null) {
1572: return dcImgRes;
1573: }
1574: dcImgRes = document.createComponent(ImageResourceCD.TYPEID);
1575: imageResource.setId(dcImgRes.getComponentID());
1576:
1577: dcImgRes.writeProperty(ImageResourceCD.PROPERTY_IMAGE_PATH,
1578: MidpTypes.createStringValue(imageResource
1579: .getRelativeResourcePath()));
1580: dcImgRes.writeProperty(ImageResourceCD.PROPERTY_NAME, MidpTypes
1581: .createStringValue(imageResource.getName(true)));
1582: this .writeAnimatedTilesToImageResourceDC(dcImgRes,
1583: imageResource);
1584: return dcImgRes;
1585: }
1586:
1587: private void writeAnimatedTilesToImageResourceDC(
1588: DesignComponent dcImgRes, ImageResource imageResource) {
1589: for (AnimatedTile at : imageResource.getAnimatedTiles()) {
1590: DesignComponent dcAnimTile = designIdMap.get(at);
1591: if (dcAnimTile == null) {
1592: assert (!dcImgRes.getComponents().contains(dcAnimTile));
1593: dcAnimTile = this
1594: .createAnimatedTileDCFromAnimatedTile(at);
1595: dcImgRes.addComponent(dcAnimTile);
1596: designIdMap.put(at, dcAnimTile);
1597: }
1598: }
1599: }
1600:
1601: public DesignComponent createSequenceDCFromSequence(
1602: Sequence sequence) {
1603: DesignComponent dcSequence = designIdMap.get(sequence);
1604: if (dcSequence != null) {
1605: return dcSequence;
1606: }
1607: dcSequence = document.createComponent(SequenceCD.TYPEID);
1608: sequence.setId(dcSequence.getComponentID());
1609:
1610: dcSequence.writeProperty(SequenceCD.PROPERTY_NAME, MidpTypes
1611: .createStringValue(sequence.getName()));
1612:
1613: DesignComponent dcImg = designIdMap.get(sequence
1614: .getImageResource());
1615: assert (dcImg != null);
1616: dcSequence.writeProperty(SequenceCD.PROPERTY_IMAGE_RESOURCE,
1617: PropertyValue.createComponentReference(dcImg));
1618: dcSequence.writeProperty(SequenceCD.PROPERTY_FRAMES, GameTypes
1619: .createFramesProperty(sequence.getFramesAsArray()));
1620: dcSequence.writeProperty(SequenceCD.PROPERTY_FRAME_MS,
1621: MidpTypes.createIntegerValue(sequence.getFrameMs()));
1622: dcSequence.writeProperty(SequenceCD.PROPERTY_FRAME_WIDTH,
1623: MidpTypes.createIntegerValue(sequence.getFrameWidth()));
1624: dcSequence
1625: .writeProperty(SequenceCD.PROPERTY_FRAME_HEIGHT,
1626: MidpTypes.createIntegerValue(sequence
1627: .getFrameHeight()));
1628: dcSequence.writeProperty(SequenceCD.PROPERTY_ZERO_BASED_INDEX,
1629: MidpTypes.createBooleanValue(sequence
1630: .isZeroBasedIndex()));
1631:
1632: this .registerListeners(sequence);
1633: return dcSequence;
1634: }
1635:
1636: //--------------- GlobalRepositoryListener ------------------
1637:
1638: public void sceneAdded(final Scene scene, int index) {
1639: final DesignDocument doc = document;
1640: document.getTransactionManager().writeAccess(new Runnable() {
1641: public void run() {
1642: DesignComponent sceneDC = createSceneDCFromScene(doc,
1643: designIdMap, scene);
1644: designIdMap.put(scene, sceneDC);
1645: changeMap.put(doc.getRootComponent().getComponentID(),
1646: scene.getName());
1647: scene.addSceneListener(GameController.this );
1648: scene.addPropertyChangeListener(GameController.this );
1649: doc.getRootComponent().addComponent(sceneDC);
1650: }
1651: });
1652: if (DEBUG_UNDO)
1653: System.out.println("Scene added " + scene); // NOI18N
1654: }
1655:
1656: public void sceneRemoved(final Scene scene, int index) {
1657: final DesignDocument doc = document;
1658: scene.removeSceneListener(this );
1659: final DesignComponent dcScene = designIdMap.get(scene);
1660: assert (dcScene != null);
1661: document.getTransactionManager().writeAccess(new Runnable() {
1662: public void run() {
1663: changeMap.put(doc.getRootComponent().getComponentID(),
1664: scene.getName());
1665: document.deleteComponent(dcScene);
1666: }
1667: });
1668: if (DEBUG_UNDO)
1669: System.out.println("Scene removed: " + scene); // NOI18N
1670: }
1671:
1672: public void tiledLayerAdded(final TiledLayer tiledLayer, int index) {
1673: final DesignDocument doc = document;
1674: document.getTransactionManager().writeAccess(new Runnable() {
1675: public void run() {
1676: DesignDocument doc = document;
1677: DesignComponent tiledLayerDC = createTiledLayerDCFromTiledLayer(
1678: doc, designIdMap, tiledLayer);
1679: changeMap.put(doc.getRootComponent().getComponentID(),
1680: tiledLayer.getName());
1681: tiledLayer.addTiledLayerListener(GameController.this );
1682: tiledLayer
1683: .addPropertyChangeListener(GameController.this );
1684: doc.getRootComponent().addComponent(tiledLayerDC);
1685: }
1686: });
1687: if (DEBUG_UNDO)
1688: System.out.println("TL added: " + tiledLayer); // NOI18N
1689: }
1690:
1691: public void tiledLayerRemoved(final TiledLayer tiledLayer, int index) {
1692: final DesignDocument doc = document;
1693: tiledLayer.removeTiledLayerListener(this );
1694: final DesignComponent dcLayer = designIdMap.get(tiledLayer);
1695: assert (dcLayer != null);
1696: document.getTransactionManager().writeAccess(new Runnable() {
1697: public void run() {
1698: changeMap.put(doc.getRootComponent().getComponentID(),
1699: tiledLayer.getName());
1700: document.deleteComponent(dcLayer);
1701: }
1702: });
1703: if (DEBUG_UNDO)
1704: System.out.println("TL removed: " + tiledLayer); // NOI18N
1705: }
1706:
1707: public void spriteAdded(final Sprite sprite, int index) {
1708: final DesignDocument doc = document;
1709: document.getTransactionManager().writeAccess(new Runnable() {
1710: public void run() {
1711: DesignComponent spriteDC = GameController.this
1712: .createSpriteDCFromSprite(sprite);
1713: designIdMap.put(sprite, spriteDC);
1714: changeMap.put(doc.getRootComponent().getComponentID(),
1715: sprite.getName());
1716: sprite
1717: .addSequenceContainerListener(GameController.this );
1718: sprite.addPropertyChangeListener(GameController.this );
1719: document.getRootComponent().addComponent(spriteDC);
1720: }
1721: });
1722: if (DEBUG_UNDO)
1723: System.out.println("Sprite added: " + sprite); // NOI18N
1724: }
1725:
1726: public void spriteRemoved(final Sprite sprite, int index) {
1727: final DesignDocument doc = document;
1728: sprite.removeSequenceContainerListener(this );
1729: final DesignComponent dcLayer = designIdMap.get(sprite);
1730: assert (dcLayer != null);
1731: document.getTransactionManager().writeAccess(new Runnable() {
1732: public void run() {
1733: changeMap.put(doc.getRootComponent().getComponentID(),
1734: sprite.getName());
1735: document.deleteComponent(dcLayer);
1736: }
1737: });
1738: if (DEBUG_UNDO)
1739: System.out.println("Sprite removed: " + sprite); // NOI18N
1740: }
1741:
1742: public void imageResourceAdded(final ImageResource imageResource) {
1743: final DesignDocument doc = document;
1744: document.getTransactionManager().writeAccess(new Runnable() {
1745: public void run() {
1746: DesignDocument doc = document;
1747: DesignComponent imgResDC = createImageResourceDCFromImageResource(imageResource);
1748: designIdMap.put(imageResource, imgResDC);
1749: changeMap.put(doc.getRootComponent().getComponentID(),
1750: imageResource.getName());
1751: imageResource
1752: .addImageResourceListener(GameController.this );
1753: doc.getRootComponent().addComponent(imgResDC);
1754: }
1755: });
1756: if (DEBUG_UNDO)
1757: System.out.println("ImgRes added: " + imageResource); // NOI18N
1758: }
1759:
1760: //----------------- SceneListener -------------------
1761:
1762: public void layerAdded(final Scene sourceScene, final Layer layer,
1763: int index) {
1764: document.getTransactionManager().writeAccess(new Runnable() {
1765: public void run() {
1766: DesignComponent dcScene = designIdMap.get(sourceScene);
1767: assert (dcScene != null);
1768: DesignComponent dcLayer = designIdMap.get(layer);
1769: assert (dcLayer != null);
1770: changeMap.put(dcScene.getComponentID(),
1771: SceneCD.PROPERTY_SCENE_ITEMS);
1772: writeSceneItemsToSceneDC(document, designIdMap,
1773: dcScene, sourceScene);
1774: }
1775: });
1776: if (DEBUG_UNDO)
1777: System.out.println("Layer added: " + layer); // NOI18N
1778: }
1779:
1780: public void layerRemoved(final Scene sourceScene,
1781: final Layer layer, final LayerInfo info, int index) {
1782: document.getTransactionManager().writeAccess(new Runnable() {
1783: public void run() {
1784: DesignComponent dcScene = designIdMap.get(sourceScene);
1785: assert (dcScene != null);
1786: DesignComponent dcLayer = designIdMap.get(layer);
1787: assert (dcLayer != null);
1788: changeMap.put(dcScene.getComponentID(),
1789: SceneCD.PROPERTY_SCENE_ITEMS);
1790: writeSceneItemsToSceneDC(document, designIdMap,
1791: dcScene, sourceScene);
1792: }
1793: });
1794: if (DEBUG_UNDO)
1795: System.out.println("Layer removed: " + layer); // NOI18N
1796: }
1797:
1798: public void layerMoved(final Scene sourceScene, final Layer layer,
1799: int indexOld, int indexNew) {
1800: document.getTransactionManager().writeAccess(new Runnable() {
1801: public void run() {
1802: DesignComponent dcScene = designIdMap.get(sourceScene);
1803: assert (dcScene != null);
1804: DesignComponent dcLayer = designIdMap.get(layer);
1805: assert (dcLayer != null);
1806: changeMap.put(dcScene.getComponentID(),
1807: SceneCD.PROPERTY_SCENE_ITEMS);
1808: writeSceneItemsToSceneDC(document, designIdMap,
1809: dcScene, sourceScene);
1810: }
1811: });
1812: if (DEBUG_UNDO)
1813: System.out.println("Layer moved: " + layer); // NOI18N
1814: }
1815:
1816: public void layerPositionChanged(final Scene sourceScene,
1817: final Layer layer, final Point oldPosition,
1818: final Point newPosition, boolean inTransition) {
1819: if (inTransition) {
1820: return;
1821: }
1822: document.getTransactionManager().writeAccess(new Runnable() {
1823: public void run() {
1824: DesignComponent dcScene = designIdMap.get(sourceScene);
1825: assert (dcScene != null);
1826: DesignComponent dcLayer = designIdMap.get(layer);
1827: assert (dcLayer != null);
1828: changeMap.put(dcScene.getComponentID(),
1829: SceneCD.PROPERTY_SCENE_ITEMS);
1830: writeSceneItemsToSceneDC(document, designIdMap,
1831: dcScene, sourceScene);
1832: }
1833: });
1834: if (DEBUG_UNDO)
1835: System.out.println("Layer position changed: " + layer); // NOI18N
1836: }
1837:
1838: public void layerLockChanged(final Scene sourceScene,
1839: final Layer layer, boolean locked) {
1840: document.getTransactionManager().writeAccess(new Runnable() {
1841: public void run() {
1842: DesignComponent dcScene = designIdMap.get(sourceScene);
1843: assert (dcScene != null);
1844: DesignComponent dcLayer = designIdMap.get(layer);
1845: assert (dcLayer != null);
1846: changeMap.put(dcScene.getComponentID(),
1847: SceneCD.PROPERTY_SCENE_ITEMS);
1848: writeSceneItemsToSceneDC(document, designIdMap,
1849: dcScene, sourceScene);
1850: }
1851: });
1852: if (DEBUG_UNDO)
1853: System.out.println("Layer lock changed: " + layer); // NOI18N
1854: }
1855:
1856: public void layerVisibilityChanged(final Scene sourceScene,
1857: final Layer layer, boolean visible) {
1858: document.getTransactionManager().writeAccess(new Runnable() {
1859: public void run() {
1860: DesignComponent dcScene = designIdMap.get(sourceScene);
1861: assert (dcScene != null);
1862: DesignComponent dcLayer = designIdMap.get(layer);
1863: assert (dcLayer != null);
1864: changeMap.put(dcScene.getComponentID(),
1865: SceneCD.PROPERTY_SCENE_ITEMS);
1866: writeSceneItemsToSceneDC(document, designIdMap,
1867: dcScene, sourceScene);
1868: }
1869: });
1870: if (DEBUG_UNDO)
1871: System.out.println("Layer visibility changed: " + layer); // NOI18N
1872: }
1873:
1874: //----------------- TiledLayerListener ---------------------
1875:
1876: public void tileChanged(TiledLayer source, int row, int col) {
1877: this .updateTiledLayerDCProps(source);
1878: }
1879:
1880: public void tilesChanged(TiledLayer source, Set positions) {
1881: this .updateTiledLayerDCProps(source);
1882: }
1883:
1884: public void tilesStructureChanged(TiledLayer source) {
1885: this .updateTiledLayerDCProps(source);
1886: }
1887:
1888: public void columnsInserted(TiledLayer source, int index, int count) {
1889: this .updateTiledLayerDCProps(source);
1890: }
1891:
1892: public void columnsRemoved(TiledLayer source, int index, int count) {
1893: this .updateTiledLayerDCProps(source);
1894: }
1895:
1896: public void rowsInserted(TiledLayer source, int index, int count) {
1897: this .updateTiledLayerDCProps(source);
1898: }
1899:
1900: public void rowsRemoved(TiledLayer source, int index, int count) {
1901: this .updateTiledLayerDCProps(source);
1902: }
1903:
1904: private void updateTiledLayerDCProps(final TiledLayer layer) {
1905: document.getTransactionManager().writeAccess(new Runnable() {
1906: public void run() {
1907: DesignComponent dcLayer = designIdMap.get(layer);
1908: assert (dcLayer != null);
1909: changeMap.put(dcLayer.getComponentID(),
1910: TiledLayerCD.PROPERTY_TILES);
1911: PropertyValue propTiles = GameTypes
1912: .createTilesProperty(layer.getTiles());
1913: dcLayer.writeProperty(TiledLayerCD.PROPERTY_TILES,
1914: propTiles);
1915: }
1916: });
1917: if (DEBUG_UNDO)
1918: System.out.println("Layer props changed: " + layer); // NOI18N
1919: }
1920:
1921: //------------------- SequenceContainerListener ------------------
1922:
1923: public void sequenceAdded(SequenceContainer source,
1924: Sequence sequence, int index) {
1925: this .sequenceContainerChanged(source);
1926: }
1927:
1928: public void sequenceRemoved(SequenceContainer source,
1929: Sequence sequence, int index) {
1930: this .sequenceContainerChanged(source);
1931: }
1932:
1933: public void sequenceMoved(SequenceContainer source,
1934: Sequence sequence, int indexOld, int indexNew) {
1935: this .sequenceContainerChanged(source);
1936: }
1937:
1938: private void sequenceContainerChanged(
1939: final SequenceContainer sequenceContainer) {
1940: DesignComponent dcSequenceContainer = designIdMap
1941: .get(sequenceContainer);
1942: assert (dcSequenceContainer != null);
1943: document.getTransactionManager().writeAccess(new Runnable() {
1944: public void run() {
1945: writeSequencesToSequenceContainerDC(sequenceContainer);
1946: }
1947: });
1948: if (DEBUG_UNDO)
1949: System.out.println("Seq container changed: "
1950: + sequenceContainer); // NOI18N
1951: }
1952:
1953: private void writeSequencesToSequenceContainerDC(
1954: SequenceContainer sequenceContainer) {
1955: DesignComponent dcSequenceContainer = designIdMap
1956: .get(sequenceContainer);
1957: assert (dcSequenceContainer != null);
1958:
1959: List<PropertyValue> sequenceDCs = new ArrayList<PropertyValue>();
1960: List<Sequence> sequences = sequenceContainer.getSequences();
1961:
1962: List<DesignComponent> iter = new ArrayList<DesignComponent>(
1963: dcSequenceContainer.getComponents());
1964: //remove sequences not present in sequence container but present in design document
1965: for (DesignComponent dcSequence : iter) {
1966: boolean found = false;
1967: for (Sequence sequence : sequences) {
1968: if (designIdMap.get(sequence) == dcSequence) {
1969: found = true;
1970: break;
1971: }
1972: }
1973: if (!found) {
1974: dcSequenceContainer.removeComponent(dcSequence);
1975: }
1976: }
1977:
1978: //add sequences present in sequence container and not present in design document
1979: for (Sequence sequence : sequences) {
1980: DesignComponent dcSequence = designIdMap.get(sequence);
1981: if (dcSequence == null) {
1982: dcSequence = createSequenceDCFromSequence(sequence);
1983: designIdMap.put(sequence, dcSequence);
1984: }
1985: if (!dcSequenceContainer.getComponents().contains(
1986: dcSequence)) {
1987: dcSequenceContainer.addComponent(dcSequence);
1988: }
1989: PropertyValue seqPropVal = PropertyValue
1990: .createComponentReference(dcSequence);
1991: sequenceDCs.add(seqPropVal);
1992: }
1993:
1994: changeMap.put(dcSequenceContainer.getComponentID(),
1995: SequenceContainerCDProperties.PROP_SEQUENCES);
1996: dcSequenceContainer.writeProperty(
1997: SequenceContainerCDProperties.PROP_SEQUENCES,
1998: PropertyValue.createArray(SequenceCD.TYPEID,
1999: sequenceDCs));
2000:
2001: }
2002:
2003: //----------------------- SequenceListener ----------------------------
2004:
2005: public void frameAdded(Sequence sequence, int index) {
2006: this .updateSequenceFrames(sequence);
2007: }
2008:
2009: public void frameRemoved(Sequence sequence, int index) {
2010: this .updateSequenceFrames(sequence);
2011: }
2012:
2013: public void frameModified(Sequence sequence, int index) {
2014: this .updateSequenceFrames(sequence);
2015: }
2016:
2017: public void framesChanged(Sequence sequence) {
2018: this .updateSequenceFrames(sequence);
2019: }
2020:
2021: private void updateSequenceFrames(final Sequence sequence) {
2022: document.getTransactionManager().writeAccess(new Runnable() {
2023: public void run() {
2024: DesignComponent dcSequence = designIdMap.get(sequence);
2025: assert (dcSequence != null);
2026: changeMap.put(dcSequence.getComponentID(),
2027: SequenceCD.PROPERTY_FRAMES);
2028: int[] frames = sequence.getFramesAsArray();
2029: dcSequence.writeProperty(SequenceCD.PROPERTY_FRAMES,
2030: GameTypes.createFramesProperty(frames));
2031: }
2032: });
2033: if (DEBUG_UNDO)
2034: System.out.println("Seq frames changed: " + sequence); // NOI18N
2035: }
2036:
2037: //----------------------- ImageResourceListener ---------------------------
2038:
2039: public void animatedTileAdded(final ImageResource imgRes,
2040: final AnimatedTile tile) {
2041: document.getTransactionManager().writeAccess(new Runnable() {
2042: public void run() {
2043: if (DEBUG)
2044: System.out.println("animatedTileAdded: " + tile); // NOI18N
2045: DesignComponent dcImgRes = designIdMap.get(imgRes);
2046: assert (dcImgRes != null);
2047:
2048: //update the image resource holding the animated tile
2049: GameController.this
2050: .writeAnimatedTilesToImageResourceDC(dcImgRes,
2051: imgRes);
2052:
2053: DesignComponent dcAnimTile = designIdMap.get(tile);
2054: assert (dcAnimTile != null);
2055: changeMap.put(dcImgRes.getComponentID(),
2056: ImageResourceCD.PROPERTY_NAME);
2057:
2058: tile.addSequenceContainerListener(GameController.this );
2059: tile.addPropertyChangeListener(GameController.this );
2060: }
2061: });
2062: if (DEBUG_UNDO)
2063: System.out.println("Anim tile added: " + tile); // NOI18N
2064: }
2065:
2066: public void animatedTileRemoved(final ImageResource imgRes,
2067: final AnimatedTile tile) {
2068: document.getTransactionManager().writeAccess(new Runnable() {
2069: public void run() {
2070:
2071: if (DEBUG)
2072: System.out.println("animatedTileRemoved: " + tile); // NOI18N
2073: DesignComponent dcAnimTile = designIdMap.get(tile);
2074: assert (dcAnimTile != null);
2075:
2076: DesignComponent dcImgRes = designIdMap.get(imgRes);
2077: assert (dcImgRes != null);
2078:
2079: dcImgRes.removeComponent(dcAnimTile);
2080:
2081: List<DesignComponent> tmp = new ArrayList<DesignComponent>(
2082: dcAnimTile.getComponents());
2083: for (DesignComponent child : tmp) {
2084: changeMap.put(child.getComponentID(), null);
2085: dcAnimTile.removeComponent(child);
2086: document.deleteComponent(child);
2087: }
2088: document.deleteComponent(dcAnimTile);
2089:
2090: //update the image resource holding the animated tile
2091: changeMap.put(dcImgRes.getComponentID(),
2092: ImageResourceCD.PROPERTY_NAME);
2093: }
2094: });
2095: if (DEBUG_UNDO)
2096: System.out.println("Anim tile removed: " + tile); // NOI18N
2097: this .gameEditorView.discardAllEdits();
2098: }
2099:
2100: public void sequenceAdded(final ImageResource source,
2101: final Sequence sequence) {
2102: //do nothing here - let sequence container listener methods create the sequences !!!
2103: if (DEBUG_UNDO)
2104: System.out
2105: .println("IGNORE ImageResourceListener Seq added: "
2106: + sequence); // NOI18N
2107: }
2108:
2109: public void sequenceRemoved(final ImageResource source,
2110: final Sequence sequence) {
2111: //do nothing here - let sequence container listener methods remove the sequences !!!
2112: if (DEBUG_UNDO)
2113: System.out
2114: .println("IGNORE ImageResourceListener Seq removed: "
2115: + sequence); // NOI18N
2116: }
2117:
2118: //----------------------- PropertyChangeListener --------------------------
2119:
2120: public void propertyChange(PropertyChangeEvent e) {
2121: //System.out.println("PropertyChangeEvent source: " + e.getSource() + ", prop: " + e.getPropertyName() + ", new: " + e.getNewValue() + ", old: " + e.getOldValue());
2122: DesignComponent dc = designIdMap.get(e.getSource());
2123: assert (dc != null);
2124:
2125: if (dc.getType() == SceneCD.TYPEID) {
2126: this .handleScenePropChange(dc, e);
2127: } else if (dc.getType() == AnimatedTileCD.TYPEID) {
2128: this .handleAnimatedTilePropChange(dc, e);
2129: } else if (dc.getType() == ImageResourceCD.TYPEID) {
2130: this .handleImageResourcePropChange(dc, e);
2131: } else if (dc.getType() == SequenceCD.TYPEID) {
2132: this .handleSequencePropChange(dc, e);
2133: } else if (dc.getType() == SpriteCD.TYPEID) {
2134: this .handleSpritePropChange(dc, e);
2135: } else if (dc.getType() == TiledLayerCD.TYPEID) {
2136: this .handleTiledLayerPropChange(dc, e);
2137: }
2138: }
2139:
2140: private void handleScenePropChange(final DesignComponent dcScene,
2141: final PropertyChangeEvent e) {
2142: if (e.getPropertyName().equals(Editable.PROPERTY_NAME)) {
2143: document.getTransactionManager().writeAccess(
2144: new Runnable() {
2145: public void run() {
2146: String newName = (String) e.getNewValue();
2147: dcScene
2148: .writeProperty(
2149: SceneCD.PROPERTY_NAME,
2150: MidpTypes
2151: .createStringValue(newName));
2152: changeMap.put(dcScene.getComponentID(),
2153: SceneCD.PROPERTY_NAME);
2154: }
2155: });
2156: if (DEBUG_UNDO)
2157: System.out.println("Scene name changed: " + dcScene); // NOI18N
2158: }
2159: }
2160:
2161: private void handleAnimatedTilePropChange(
2162: final DesignComponent dcAnimatedTile,
2163: final PropertyChangeEvent e) {
2164: if (e.getPropertyName().equals(Editable.PROPERTY_NAME)) {
2165: document.getTransactionManager().writeAccess(
2166: new Runnable() {
2167: public void run() {
2168: String newName = (String) e.getNewValue();
2169: dcAnimatedTile
2170: .writeProperty(
2171: AnimatedTileCD.PROPERTY_NAME,
2172: MidpTypes
2173: .createStringValue(newName));
2174: changeMap.put(dcAnimatedTile
2175: .getComponentID(),
2176: AnimatedTileCD.PROPERTY_NAME);
2177: }
2178: });
2179: if (DEBUG_UNDO)
2180: System.out.println("AnimatedTile name changed: "
2181: + dcAnimatedTile); // NOI18N
2182: }
2183: if (e.getPropertyName().equals(
2184: SequenceContainer.PROPERTY_DEFAULT_SEQUENCE)) {
2185: document.getTransactionManager().writeAccess(
2186: new Runnable() {
2187: public void run() {
2188: Sequence newDefSeq = (Sequence) e
2189: .getNewValue();
2190: DesignComponent dcDefSeq = designIdMap
2191: .get(newDefSeq);
2192: dcAnimatedTile
2193: .writeProperty(
2194: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE,
2195: PropertyValue
2196: .createComponentReference(dcDefSeq));
2197: changeMap
2198: .put(
2199: dcAnimatedTile
2200: .getComponentID(),
2201: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE);
2202: }
2203: });
2204: if (DEBUG_UNDO)
2205: System.out.println("AnimatedTile def seq changed: "
2206: + dcAnimatedTile); // NOI18N
2207: }
2208: }
2209:
2210: private void handleImageResourcePropChange(
2211: final DesignComponent dcImageResource,
2212: final PropertyChangeEvent e) {
2213:
2214: }
2215:
2216: private void handleSequencePropChange(
2217: final DesignComponent dcSequence,
2218: final PropertyChangeEvent e) {
2219: if (e.getPropertyName().equals(Sequence.PROPERTY_NAME)) {
2220: document.getTransactionManager().writeAccess(
2221: new Runnable() {
2222: public void run() {
2223: String newName = (String) e.getNewValue();
2224: dcSequence
2225: .writeProperty(
2226: SequenceCD.PROPERTY_NAME,
2227: MidpTypes
2228: .createStringValue(newName));
2229: changeMap.put(dcSequence.getComponentID(),
2230: SequenceCD.PROPERTY_NAME);
2231: }
2232: });
2233: if (DEBUG_UNDO)
2234: System.out.println("Sequence name changed: "
2235: + dcSequence); // NOI18N
2236: } else if (e.getPropertyName().equals(
2237: Sequence.PROPERTY_FRAME_MS)) {
2238: document.getTransactionManager().writeAccess(
2239: new Runnable() {
2240: public void run() {
2241: int ms = (Integer) e.getNewValue();
2242: dcSequence.writeProperty(
2243: SequenceCD.PROPERTY_FRAME_MS,
2244: MidpTypes.createIntegerValue(ms));
2245: changeMap.put(dcSequence.getComponentID(),
2246: SequenceCD.PROPERTY_FRAME_MS);
2247: }
2248: });
2249: if (DEBUG_UNDO)
2250: System.out.println("Sequence frame ms changed: "
2251: + dcSequence); // NOI18N
2252: }
2253: }
2254:
2255: private void handleSpritePropChange(final DesignComponent dcSprite,
2256: final PropertyChangeEvent e) {
2257: if (e.getPropertyName().equals(Editable.PROPERTY_NAME)) {
2258: document.getTransactionManager().writeAccess(
2259: new Runnable() {
2260: public void run() {
2261: String newName = (String) e.getNewValue();
2262: dcSprite
2263: .writeProperty(
2264: LayerCD.PROPERTY_NAME,
2265: MidpTypes
2266: .createStringValue(newName));
2267: changeMap.put(dcSprite.getComponentID(),
2268: LayerCD.PROPERTY_NAME);
2269: }
2270: });
2271: if (DEBUG_UNDO)
2272: System.out.println("Sprite name changed: " + dcSprite); // NOI18N
2273: } else if (e.getPropertyName().equals(
2274: SequenceContainer.PROPERTY_DEFAULT_SEQUENCE)) {
2275: document.getTransactionManager().writeAccess(
2276: new Runnable() {
2277: public void run() {
2278: Sequence newDefSeq = (Sequence) e
2279: .getNewValue();
2280: DesignComponent dcDefSeq = designIdMap
2281: .get(newDefSeq);
2282: dcSprite
2283: .writeProperty(
2284: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE,
2285: PropertyValue
2286: .createComponentReference(dcDefSeq));
2287: changeMap
2288: .put(
2289: dcSprite.getComponentID(),
2290: SequenceContainerCDProperties.PROP_DEFAULT_SEQUENCE);
2291: }
2292: });
2293: if (DEBUG_UNDO)
2294: System.out.println("Sprite def seq changed: "
2295: + dcSprite); // NOI18N
2296: }
2297: }
2298:
2299: private void handleTiledLayerPropChange(
2300: final DesignComponent dcTiledLayer,
2301: final PropertyChangeEvent e) {
2302: if (e.getPropertyName().equals(Editable.PROPERTY_NAME)) {
2303: document.getTransactionManager().writeAccess(
2304: new Runnable() {
2305: public void run() {
2306: String newName = (String) e.getNewValue();
2307: dcTiledLayer
2308: .writeProperty(
2309: LayerCD.PROPERTY_NAME,
2310: MidpTypes
2311: .createStringValue(newName));
2312: changeMap.put(
2313: dcTiledLayer.getComponentID(),
2314: LayerCD.PROPERTY_NAME);
2315: }
2316: });
2317: if (DEBUG_UNDO)
2318: System.out.println("TiledLayer name changed: "
2319: + dcTiledLayer); // NOI18N
2320: }
2321: }
2322:
2323: }
|