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: package org.netbeans.modules.vmd.game.model;
042:
043: import java.awt.Dialog;
044: import java.awt.Dimension;
045: import java.awt.Graphics2D;
046: import java.awt.event.ActionEvent;
047: import java.beans.PropertyChangeListener;
048: import java.beans.PropertyChangeSupport;
049: import java.util.ArrayList;
050: import java.util.Collections;
051: import java.util.Comparator;
052: import java.util.List;
053: import java.util.Set;
054: import javax.swing.AbstractAction;
055: import javax.swing.Action;
056: import javax.swing.JComponent;
057: import javax.swing.event.EventListenerList;
058: import org.netbeans.modules.vmd.game.dialog.RenameSequenceDialog;
059: import org.netbeans.modules.vmd.game.editor.sequece.SequenceEditingPanel;
060: import org.netbeans.modules.vmd.game.preview.SequencePreviewPanel;
061: import org.openide.DialogDescriptor;
062: import org.openide.DialogDisplayer;
063: import org.openide.util.NbBundle;
064:
065: public class Sequence implements Previewable, Editable, Identifiable {
066:
067: private long id = Identifiable.ID_UNKNOWN;
068:
069: public static final boolean DEBUG = false;
070:
071: public static final int DEFAULT_FRAMES = 1;
072: public static final int DEFAULT_SHOWTIME_MS = 200;
073:
074: public static final String PROPERTY_NAME = "sequence.prop.name"; // NOI18N
075: public static final String PROPERTY_FRAME_MS = "sequence.prop.frames.ms"; // NOI18N
076:
077: EventListenerList listenerList = new EventListenerList();
078:
079: private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
080: this );
081:
082: private SequenceEditingPanel editor;
083:
084: private String name;
085:
086: private ImageResource imageResource;
087: private boolean zeroBasedIndex;
088:
089: private int frameWidth;
090: private int frameHeight;
091: private int frameMs;
092: private ArrayList<StaticTile> frames;
093:
094: Sequence(String name, ImageResource imageResource, int frameWidth,
095: int frameHeight, boolean zeroBasedIndex) {
096: this (name, imageResource, 1, frameWidth, frameHeight,
097: zeroBasedIndex);
098: }
099:
100: Sequence(String name, ImageResource imageResource,
101: int numberFrames, int frameWidth, int frameHeight,
102: boolean zeroBasedIndex) {
103: this .name = name;
104: this .imageResource = imageResource;
105: this .frameWidth = frameWidth;
106: this .frameHeight = frameHeight;
107: this .zeroBasedIndex = zeroBasedIndex;
108:
109: this .frames = new ArrayList();
110: for (int i = 0; i < numberFrames; i++) {
111: this .frames.add((StaticTile) imageResource.getTile(0,
112: this .frameWidth, this .frameHeight,
113: this .zeroBasedIndex));
114: }
115: this .frameMs = DEFAULT_SHOWTIME_MS;
116: }
117:
118: Sequence(String name, Sequence sequence) {
119: this .name = name;
120: this .imageResource = sequence.getImageResource();
121: this .frameHeight = sequence.getFrameHeight();
122: this .frameWidth = sequence.getFrameWidth();
123: this .frameMs = sequence.frameMs;
124: this .zeroBasedIndex = sequence.zeroBasedIndex;
125:
126: this .frames = new ArrayList();
127: this .frames.addAll(sequence.getFrames());
128: }
129:
130: public GlobalRepository getGameDesign() {
131: return this .imageResource.getGameDesign();
132: }
133:
134: public boolean isZeroBasedIndex() {
135: return this .zeroBasedIndex;
136: }
137:
138: public void setName(String name) {
139: if (name == null) {
140: return;
141: }
142: if (this .getName().equals(name)) {
143: return;
144: }
145: if (!this .getGameDesign().isComponentNameAvailable(name)) {
146: throw new IllegalArgumentException(
147: "Sequence cannot be renamed because component name '"
148: + name + "' already exists."); // NOI18N
149: }
150: String oldName = this .name;
151: this .name = name;
152: this .propertyChangeSupport.firePropertyChange(
153: Sequence.PROPERTY_NAME, oldName, name);
154: }
155:
156: public void setFrames(int[] frames) {
157: ArrayList<StaticTile> newFrames = new ArrayList<StaticTile>();
158: for (int i = 0; i < frames.length; i++) {
159: StaticTile frame = new StaticTile(imageResource, frames[i],
160: frameWidth, frameHeight, zeroBasedIndex);
161: newFrames.add(frame);
162: }
163: this .frames = newFrames;
164: this .fireFramesChanged();
165: }
166:
167: public void addFrame(StaticTile frame) {
168: if (frame == null)
169: frame = (StaticTile) imageResource.getTile(0,
170: this .frameWidth, this .frameHeight,
171: this .zeroBasedIndex);
172: this .frames.add(frame);
173: int index = this .frames.indexOf(frame);
174: this .fireFrameAdded(frame, index);
175: }
176:
177: public void insertFrame(StaticTile frame, int index) {
178: if (frame == null)
179: frame = (StaticTile) imageResource.getTile(0,
180: this .frameWidth, this .frameHeight,
181: this .zeroBasedIndex);
182: this .frames.add(index, frame);
183: this .fireFrameAdded(frame, index);
184: }
185:
186: public void removeFrame(int index) {
187: StaticTile frame = (StaticTile) this .frames.remove(index);
188: this .fireFrameRemoved(frame, index);
189: }
190:
191: public void removeFrames(Set<Integer> indexes) {
192: //sort from largest to smallest so that we remove the largest indexes first
193: List<Integer> tmp = new ArrayList<Integer>(indexes);
194: Collections.sort(tmp, new Comparator<Integer>() {
195: public int compare(Integer a, Integer b) {
196: return (a.intValue() > b.intValue() ? -1 : (a
197: .intValue() == b.intValue() ? 0 : 1));
198: }
199: });
200: for (Integer integer : tmp) {
201: this .removeFrame(integer);
202: }
203: }
204:
205: public StaticTile getFrame(int index) {
206: return (StaticTile) this .frames.get(index);
207: }
208:
209: public void setFrame(StaticTile frame, int index) {
210: if (frame == null) {
211: frame = (StaticTile) imageResource.getTile(0,
212: this .frameWidth, this .frameHeight,
213: this .zeroBasedIndex);
214: }
215: this .frames.ensureCapacity(index + 1);
216: this .frames.set(index, frame);
217: this .fireFrameModified(frame, index);
218: }
219:
220: public int getFrameMs() {
221: return frameMs;
222: }
223:
224: public void setFrameMs(int frameMs) {
225: if (DEBUG)
226: System.out.println("FrameMS = " + frameMs); // NOI18N
227: int oldMs = this .frameMs;
228: this .frameMs = frameMs;
229: this .propertyChangeSupport.firePropertyChange(
230: Sequence.PROPERTY_FRAME_MS, oldMs, frameMs);
231: }
232:
233: public int getFrameHeight() {
234: return frameHeight;
235: }
236:
237: public int getFrameWidth() {
238: return frameWidth;
239: }
240:
241: public int getFrameCount() {
242: return this .frames.size();
243: }
244:
245: public Dimension getFrameSize() {
246: return new Dimension(this .getFrameWidth(), this
247: .getFrameHeight());
248: }
249:
250: public List getFrames() {
251: return Collections.unmodifiableList(this .frames);
252: }
253:
254: public int[] getFramesAsArray() {
255: int[] a = new int[this .frames.size()];
256: for (int i = 0; i < a.length; i++) {
257: a[i] = this .frames.get(i).getIndex();
258: }
259: return a;
260: }
261:
262: private void fireFramesChanged() {
263: Object[] listeners = listenerList.getListenerList();
264: for (int i = listeners.length - 2; i >= 0; i -= 2) {
265: if (listeners[i] == SequenceListener.class) {
266: ((SequenceListener) listeners[i + 1])
267: .framesChanged(this );
268: }
269: }
270: }
271:
272: private void fireFrameAdded(StaticTile frame, int index) {
273: Object[] listeners = listenerList.getListenerList();
274: for (int i = listeners.length - 2; i >= 0; i -= 2) {
275: if (listeners[i] == SequenceListener.class) {
276: ((SequenceListener) listeners[i + 1]).frameAdded(this ,
277: index);
278: }
279: }
280: }
281:
282: private void fireFrameRemoved(StaticTile frame, int index) {
283: Object[] listeners = listenerList.getListenerList();
284: for (int i = listeners.length - 2; i >= 0; i -= 2) {
285: if (listeners[i] == SequenceListener.class) {
286: ((SequenceListener) listeners[i + 1]).frameRemoved(
287: this , index);
288: }
289: }
290: }
291:
292: private void fireFrameModified(StaticTile frame, int index) {
293: Object[] listeners = listenerList.getListenerList();
294: for (int i = listeners.length - 2; i >= 0; i -= 2) {
295: if (listeners[i] == SequenceListener.class) {
296: ((SequenceListener) listeners[i + 1]).frameModified(
297: this , index);
298: }
299: }
300: }
301:
302: public JComponent getEditor() {
303: return this .editor == null ? this .editor = new SequenceEditingPanel(
304: this )
305: : this .editor;
306: }
307:
308: public ImageResource getImageResource() {
309: return this .imageResource;
310: }
311:
312: public ImageResourceInfo getImageResourceInfo() {
313: return new ImageResourceInfo(this .imageResource,
314: this .frameWidth, this .frameHeight, this .zeroBasedIndex);
315: }
316:
317: public JComponent getNavigator() {
318: return null;
319: }
320:
321: public void addPropertyChangeListener(PropertyChangeListener l) {
322: propertyChangeSupport.addPropertyChangeListener(l);
323: }
324:
325: public void removePropertyChangeListener(PropertyChangeListener l) {
326: propertyChangeSupport.removePropertyChangeListener(l);
327: }
328:
329: public synchronized void addSequenceListener(SequenceListener l) {
330: this .listenerList.add(SequenceListener.class, l);
331: }
332:
333: public synchronized void removeSequenceListener(SequenceListener l) {
334: this .listenerList.remove(SequenceListener.class, l);
335: }
336:
337: public String toString() {
338: return this .getName();
339: }
340:
341: //Previewable
342: public void paint(Graphics2D g, int x, int y) {
343: this .getFrame(0).paint(g, x, y);
344: }
345:
346: public int getWidth() {
347: return this .frameWidth;
348: }
349:
350: public int getHeight() {
351: return this .frameHeight;
352: }
353:
354: public JComponent getPreview() {
355: return new SequencePreviewPanel(this );
356: }
357:
358: public String getName() {
359: return this .name;
360: }
361:
362: //-------- Actions ---------
363:
364: public List<Action> getActions() {
365: ArrayList actions = new ArrayList<Action>();
366: actions.add(new RenameSequenceAction());
367: actions.add(new EditSequenceAction());
368: return Collections.unmodifiableList(actions);
369: }
370:
371: public class EditSequenceAction extends AbstractAction {
372: {
373: this .putValue(NAME, NbBundle.getMessage(Sequence.class,
374: "Sequence.EditSequenceAction.text"));
375: }
376:
377: public void actionPerformed(ActionEvent e) {
378: Sequence.this .getGameDesign().getMainView().requestEditing(
379: Sequence.this );
380: }
381: }
382:
383: public class RenameSequenceAction extends AbstractAction {
384: {
385: this .putValue(NAME, NbBundle.getMessage(Sequence.class,
386: "Sequence.RenameSequenceAction.text"));
387: }
388:
389: public void actionPerformed(ActionEvent e) {
390: RenameSequenceDialog dialog = new RenameSequenceDialog(
391: Sequence.this );
392: DialogDescriptor dd = new DialogDescriptor(dialog, NbBundle
393: .getMessage(Sequence.class,
394: "Sequence.RenameSequenceAction.text"));
395: dd.setButtonListener(dialog);
396: dd.setValid(false);
397: dialog.setDialogDescriptor(dd);
398: Dialog d = DialogDisplayer.getDefault().createDialog(dd);
399: d.setVisible(true);
400: }
401: }
402:
403: public long getId() {
404: return id;
405: }
406:
407: public void setId(long id) {
408: this.id = id;
409: }
410: }
|