001: /*
002: * $Id: MultipageListCommand.java,v 1.1 2002/04/19 06:10:34 skavish Exp $
003: *
004: * ===========================================================================
005: *
006: * The JGenerator Software License, Version 1.0
007: *
008: * Copyright (c) 2000 Dmitry Skavish (skavish@usa.net). All rights reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions are met:
012: *
013: * 1. Redistributions of source code must retain the above copyright
014: * notice, this list of conditions and the following disclaimer.
015: *
016: * 2. Redistributions in binary form must reproduce the above copyright
017: * notice, this list of conditions and the following disclaimer in
018: * the documentation and/or other materials provided with the
019: * distribution.
020: *
021: * 3. The end-user documentation included with the redistribution, if
022: * any, must include the following acknowlegement:
023: * "This product includes software developed by Dmitry Skavish
024: * (skavish@usa.net, http://www.flashgap.com/)."
025: * Alternately, this acknowlegement may appear in the software itself,
026: * if and wherever such third-party acknowlegements normally appear.
027: *
028: * 4. The name "The JGenerator" must not be used to endorse or promote
029: * products derived from this software without prior written permission.
030: * For written permission, please contact skavish@usa.net.
031: *
032: * 5. Products derived from this software may not be called "The JGenerator"
033: * nor may "The JGenerator" appear in their names without prior written
034: * permission of Dmitry Skavish.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL DMITRY SKAVISH OR THE OTHER
040: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: *
049: */
050:
051: package org.openlaszlo.iv.flash.commands;
052:
053: import java.awt.geom.*;
054: import java.io.*;
055: import java.util.*;
056: import org.openlaszlo.iv.flash.api.*;
057: import org.openlaszlo.iv.flash.api.action.*;
058: import org.openlaszlo.iv.flash.api.button.*;
059: import org.openlaszlo.iv.flash.api.shape.*;
060: import org.openlaszlo.iv.flash.context.*;
061: import org.openlaszlo.iv.flash.util.*;
062:
063: /**
064: * Multipage List JGenerator Object
065: *
066: * @author William L. Thomson Jr.
067: * @company Obsidian-Studios Inc.
068: * @version 1.0
069: * @date April 17, 2002
070: */
071: public class MultipageListCommand extends GenericCommand {
072:
073: protected int textColumn, clipColumn, urlColumn, windowColumn = -1;
074: protected Script externalMediaScript, prevSymbol, homeSymbol,
075: nextSymbol, textSymbol, templateScript = null;
076: protected String dataSource, prevSymbolName, homeSymbolName,
077: nextSymbolName, textSymbolName, instanceName,
078: externalMediaName;
079:
080: protected void initColumnIndexes(String[][] data) {
081: textColumn = findColumn("Text", data);
082: urlColumn = findColumn("Url", data);
083: windowColumn = findColumn("Window", data);
084: if (textColumn == -1)
085: Log
086: .error("MultipageListCommand Error\nA text column was not specified in the data source.");
087: if (urlColumn != -1 && windowColumn == -1)
088: Log
089: .warn("MultipageListCommand Warning\nA url was specified but a window column was not specified in the data source. Will end up using default window, _blank");
090: }
091:
092: protected void initParams(Context context) {
093: dataSource = getParameter(context, "datasource", "");
094: prevSymbolName = getParameter(context, "prevsym", "");
095: homeSymbolName = getParameter(context, "homesym", "");
096: nextSymbolName = getParameter(context, "nextsym", "");
097: textSymbolName = getParameter(context, "textsym", "");
098: instanceName = getParameter(context, "instancename", "");
099: if (dataSource.equals(""))
100: Log
101: .error("MultipageListCommand Error\nA data source was not specified in authoring environment.");
102: if (prevSymbolName.equals(""))
103: Log
104: .error("MultipageListCommand Error\nA previous symbol was not specified in authoring environment.");
105: if (homeSymbolName.equals(""))
106: Log
107: .error("MultipageListCommand Error\nA home symbol was not specified in authoring environment.");
108: if (nextSymbolName.equals(""))
109: Log
110: .error("MultipageListCommand Error\nA next symbol was not specified in authoring environment.");
111: if (textSymbolName.equals(""))
112: Log
113: .error("MultipageListCommand Error\nA text symbol was not specified in authoring environment.");
114: if (instanceName.equals(""))
115: Log
116: .error("MultipageListCommand Error\nA instance name was not specified in authoring environment.");
117: }
118:
119: protected void initSymbols(FlashFile flashFile) {
120: prevSymbol = flashFile.getScript(prevSymbolName);
121: homeSymbol = flashFile.getScript(homeSymbolName);
122: nextSymbol = flashFile.getScript(nextSymbolName);
123: textSymbol = flashFile.getScript(textSymbolName);
124: if (prevSymbol == null)
125: Log
126: .error("MultipageListCommand Warning\nCould not get previous symbol script specified.");
127: if (homeSymbol == null)
128: Log
129: .error("MultipageListCommand Warning\nCould not get home symbol script specified.");
130: if (nextSymbol == null)
131: Log
132: .error("MultipageListCommand Warning\nCould not get next symbol script specified.");
133: if (textSymbol == null)
134: Log
135: .error("MultipageListCommand Error\nCould not get text symbol script specified.");
136: }
137:
138: public void doCommand(FlashFile flashFile, Context context,
139: Script parentScript, int frames) {
140: initParams(context);
141: initSymbols(flashFile);
142: String[][] data = null;
143: try {
144: UrlDataSource urlDataSource = new UrlDataSource(dataSource,
145: flashFile);
146: data = urlDataSource.getData();
147: } catch (IVException ive) {
148: Log
149: .error("MultipageListCommand Error\nCould not Parse the datasource into a multi-dimensional array because :\n"
150: + ive);
151: } catch (IOException ioe) {
152: Log
153: .error("MultipageListCommand Error\nCould not Parse the datasource into a multi-dimensional array because :\n"
154: + ioe);
155: }
156: if (data != null) {
157: initColumnIndexes(data);
158: makeLists(flashFile, data); // make the lists
159: } else {
160: Log
161: .error("MultipageListCommand Error\nThe datasource it empty.");
162: }
163: }
164:
165: protected void makeLists(FlashFile flashFile, String[][] data) {
166: Instance instance = getInstance(); // get an instance of the template
167: instance.name = instanceName; // set the name of the instance
168: double width = instance.matrix.getScaleX() * 2048; // determine the bounding box width
169: double height = instance.matrix.getScaleY() * 2048; // determine the bounding box height
170: GeomHelper.deScaleMatrix(instance.matrix); // scale the instance, otherwise every clip will be distorted
171: Script script = instance.copyScript();
172: Frame frame = script.getFrameAt(0);
173: frame.addStopAction();
174: double prevHeight = prevSymbol.getBounds().getHeight();
175: double prevWidth = prevSymbol.getBounds().getWidth();
176: Button2 prevButton = createButton(prevSymbol);
177: prevButton.addActionCondition(onReleasePrev());
178: double homeHeight = homeSymbol.getBounds().getHeight();
179: double homeWidth = homeSymbol.getBounds().getWidth();
180: Button2 homeButton = createButton(homeSymbol);
181: homeButton.addActionCondition(onReleaseHome());
182: double nextHeight = nextSymbol.getBounds().getHeight();
183: double nextWidth = nextSymbol.getBounds().getWidth();
184: Button2 nextButton = createButton(nextSymbol);
185: nextButton.addActionCondition(onReleaseNext());
186: double symbolHeight = (prevHeight > nextHeight) ? prevHeight
187: : nextHeight;
188: double y = -height / 2 + symbolHeight;
189: double x = -width / 2;
190: double clipHeight = 0;
191: double newPageHeight = 0; // this will be a cumlative total of clip heights on a page
192: double pageHeight = height - symbolHeight; // this will be used to determine the total height we have on a page
193: int level = 1;
194: for (int row = 1; row < data.length; row++) {
195: Script clipScript = textSymbol.copyScript();
196: Context clipContext = null;
197: try {
198: clipContext = ContextFactory.createContext(data, row); // create a new context
199: } catch (IVException ive) {
200: Log
201: .error("MultipageListCommand Error\nCould not make new button context because :\n"
202: + ive);
203: }
204: try {
205: flashFile.processScript(clipScript, clipContext);
206: } catch (IVException ive) {
207: Log
208: .error("MultipageListCommand Error\nCould not process new button context because :\n"
209: + ive);
210: }
211: clipHeight = clipScript.getBounds().getHeight(); // get the height before creating and adding a sub menu
212: newPageHeight += clipHeight; // add the clip height to our new page's height
213: if (newPageHeight > pageHeight) { // check to see if there is still room on the page
214: frame = script.newFrame(); // since there is no more room, let's make another page on a new frame
215: frame.addStopAction(); // add a stop action, unless you want ticking pages :)
216: script.removeAllInstances(frame); // remove all the previous instances from this frame
217: y = -height / 2 + symbolHeight; // reset the y coordinate to start were the nav symbols stop
218: newPageHeight = clipHeight; // reset the page height to just the clip height that will be added
219: level = 1; // start over again at the bottom level
220: }
221: if (urlColumn != -1) {
222: Button2 button2 = createButton(data, row, clipScript);
223: frame.addInstance(button2, level, AffineTransform
224: .getTranslateInstance(x, y), null);
225: } else {
226: frame.addInstance(clipScript, level, AffineTransform
227: .getTranslateInstance(x, y), null);
228: }
229: y += clipHeight; // add the clip height to the current y position
230: level++;
231: }
232: int frameCount = script.getFrameCount();
233: if (frameCount > 1) { // if we have more than one frame add the navigation buttons
234: Frame tempFrame = script.getFrameAt(1);
235: double navY = -height / 2;
236: tempFrame.addInstance(prevButton, 100, AffineTransform
237: .getTranslateInstance(x, navY), null); // add the previous button to all frames except the first
238: x += prevWidth + 40; // add 40 to space out nav buttons
239: tempFrame.addInstance(homeButton, 101, AffineTransform
240: .getTranslateInstance(x, navY), null); // add the home button to all frames except the first
241: x += homeWidth + 40; // add 40 to space out nav buttons
242: script.getFrameAt(0)
243: .addInstance(
244: nextButton,
245: 102,
246: AffineTransform.getTranslateInstance(x,
247: navY), null); // add the next button to all frames including the first
248: script.getFrameAt(frameCount - 1).removeInstance(102); // remove the next button from the last frame
249: }
250: }
251:
252: protected ActionCondition onReleasePrev() {
253: Program program = new Program();
254: program.prevFrame();
255: return (ActionCondition.onRelease(program));
256: }
257:
258: protected ActionCondition onReleaseHome() {
259: Program homeProgram = new Program();
260: homeProgram.gotoFrame(0);
261: return (ActionCondition.onRelease(homeProgram));
262: }
263:
264: protected ActionCondition onReleaseNext() {
265: Program nextProgram = new Program();
266: nextProgram.nextFrame();
267: return (ActionCondition.onRelease(nextProgram));
268: }
269:
270: protected Button2 createButton(Script symbol) {
271: Button2 button2 = new Button2();
272: int states = ButtonRecord.Up | ButtonRecord.Over
273: | ButtonRecord.Down; // add the symbol to define the rest of the states
274: button2.addButtonRecord(new ButtonRecord(states, symbol, 1,
275: AffineTransform.getTranslateInstance(0, 0), CXForm
276: .newIdentity(true)));
277: Shape shape = new Shape();
278: shape.setBounds(symbol.getBounds());
279: shape.setFillStyle0(FillStyle.newSolid(new Color(0, 0, 0)));
280: shape.drawRectangle(symbol.getBounds());
281: button2.addButtonRecord(new ButtonRecord(ButtonRecord.HitTest,
282: shape, 2, AffineTransform.getTranslateInstance(0, 0),
283: CXForm.newIdentity(true)));
284: button2.setTrackAs(Button2.TrackAsButton);
285: return (button2);
286: }
287:
288: protected Button2 createButton(String[][] data, int row,
289: Script clipScript) {
290: Button2 button2 = createButton(clipScript);
291: Program program = new Program();
292: if (windowColumn == -1)
293: program.getURL(data[row][urlColumn], "_blank");
294: else
295: program.getURL(data[row][urlColumn],
296: data[row][windowColumn]);
297: button2.addActionCondition(ActionCondition.onPress(program));
298: return (button2);
299: }
300: }
|