/* * BasicButtons.java * Examples * * Created by Stuart MacKay on Wed Sep 03 2003. * Copyright (c) 2001-2004 Flagstone Software Ltd. All rights reserved. * * This code is distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND Flagstone HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING * WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. */ package com.flagstone.transform.util.examples; import com.flagstone.transform.*; import com.flagstone.transform.util.*; import com.flagstone.transform.examples.Example; import java.util.*; /* * This example shows how to create buttons using the FSDefineButton and FSDefineButton2 * classes. Each button displays a web page in a browser when clicked. The second button * also plays a sound when clicked. * * To run this example, type the following on a command line: * * java com.flagstone.transform.util.examples.Buttons \ * --font font-file \ * --sound sound-file \ * --label string \ * [--resultDir path] * * where * * font-file is the path to a file containing a font definition used to * render the text for label on the button. * * sound-file is the path to a file containing a WAVE or MP3 format sound * which is played when a button is clicked. * * string the label that will be displayed on the button - enclose in quotes * if the label contains spaces. * * resultDir is the directory where the Flash file generated by the example * is written to. */ public class BasicButtons extends Example { private FSTextConstructor textGenerator = null; private FSSoundConstructor soundGenerator = null; private FSShapeConstructor path = null; public static void main(String[] args) { new BasicButtons(args); } public BasicButtons(String[] args) { super(args); String fontFile = getOption("font", ""); String soundFile = getOption("sound", ""); try { textGenerator = new FSTextConstructor(movie.newIdentifier(), fontFile); soundGenerator = new FSSoundConstructor(soundFile); path = new FSShapeConstructor(); } catch (Exception e) { /* Several exceptions could be thrown to get to this point. The * exceptions are all caught in a single handler to make the code * more readable. */ System.err.println("Cannot create the movie."); } createMovie(); writeFile("BasicButtons.swf"); } void createMovie() { /* * Arrays used to hold the objects added to the button definitions. */ ArrayList records = null; ArrayList actions = null; ArrayList events = null; /* * If no label is defined when the example is run then the label * defaults to "Button". */ String buttonLabel = getOption("label", "Button"); int layer = 1; // initial layer in the display list int fontSize = 280; // 280 twips == 14 point, 1 point == 20 twips /* * Define margins added to define the width of the button relative to * the size of the label and the screen width relative to the width of * the button. */ int buttonMargin = 200; // The margin between the label and the edge of the button. int screenMargin = 400; // The margin between the edge of the button and the screen. /* * Define colours used to fill the buttons in each of its states. */ FSColor lineColor = FSColorTable.black(); FSColor shadowColor = FSColorTable.gray(); FSColor upColor = FSColorTable.red(); FSColor overColor = FSColorTable.orange(); /* * Define coordinate transform applied to the basic button shape * to perform a simple animation giving the impression the button * was physically clicked. */ FSCoordTransform recess = new FSCoordTransform(60, 60); /* * Define the shapes used to create the buttons. * * The size of the shapes is calculated relative to the bounding rectangle * enclosing an arbitrary long label. The ascent of the text is used rather * than the full height of the bounding rectangle as this gives better * placement of the text relative to the button edges. */ FSDefineShape3 label = textGenerator.defineShape(movie.newIdentifier(), buttonLabel, fontSize, lineColor); // define a 10 pixel margin around the text. int buttonWidth = label.getBounds().getWidth() + buttonMargin; int buttonHeight = -label.getBounds().getMinY() + buttonMargin; int lineWidth = 20; int cornerRadius = 100; /* * The button will cast as shadow when it in the up state. Recessing the * button by changing the location of the shapes when the button is * clicked allows a very simple animation to be performed. More complex * animations can be created by using movie clips. */ int xShadow = 60; int yShadow = 60; /* * Used to hold the width and height of the bounding rectangle that * encloses the button labels. */ int width = 0; int height = 0; path.add(new FSSolidLine(lineWidth, shadowColor)); path.add(new FSSolidFill(shadowColor)); path.rect(0, 0, buttonWidth, buttonHeight, cornerRadius); FSDefineShape2 shadow = path.defineShape(movie.newIdentifier()); path.set(0, new FSSolidLine(lineWidth, lineColor)); path.set(0, new FSSolidFill(upColor)); path.rect(0, 0, buttonWidth, buttonHeight, cornerRadius); FSDefineShape2 upShape = path.defineShape(movie.newIdentifier()); path.set(0, new FSSolidLine(lineWidth, lineColor)); path.set(0, new FSSolidFill(overColor)); path.rect(0, 0, buttonWidth, buttonHeight, cornerRadius); FSDefineShape2 overShape = path.defineShape(movie.newIdentifier()); /************************** * First Button **************************/ /* * This button is created using the FSDefineButton class which only * defines actions when the button is clicked. The FSDefineButton2 class * supports a more complex model that allows actions to be performed for * a wide range of different button events. */ records = new ArrayList(); actions = new ArrayList(); events = new ArrayList(); /* * Define the label. For the first button the label text is traced out * as a shape. In the second half of this example the text object is * used directly. */ FSDefineShape3 firstLabel = textGenerator.defineShape(movie.newIdentifier(), buttonLabel, fontSize, lineColor); /* * Realign the labels so they are displayed in the centre of the button. * The ascent of the text is used rather than the full height of the * bounding rectangle. */ width = firstLabel.getBounds().getWidth(); height = -firstLabel.getBounds().getMinY(); /* * Create the FSButto objects that define the button's appearance. More * than one button record can be defined for a given state allowing for * example button definitions to be reused with only the label changing. * The layer number controls the order in which the shapes are displayed. * * Use one of the button shapes to define the active area where the * button will respond to events generated by the mouse. */ records.add(new FSButton(FSButton.Active, upShape.getIdentifier(), layer++)); /* * Define the appearance of the button in the up state. A shape giving a * drop shadow effect is placed in the background and the label is in * the foreground. */ records.add(new FSButton(FSButton.Up, shadow.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Up, upShape.getIdentifier(), layer++)); records.add(new FSButton(FSButton.Up, firstLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2, height/2))); /* * The button appears the same when the mouse is over the active area. * Only the colour changes to highlight the button. The drop shadow must * still be drawn. */ records.add(new FSButton(FSButton.Over, shadow.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Over, overShape.getIdentifier(), layer++)); records.add(new FSButton(FSButton.Over, firstLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2, height/2))); /* * The button appears is recessed when it is clicked so the shape for the drop shadow is * not required. */ records.add(new FSButton(FSButton.Down, overShape.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Down, firstLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2 + xShadow, height/2 + yShadow))); /* * When the button is clicked a web page will be loaded into the web * browser. The browser must be running for this to work, the Flash Player * won't launch the browser by itself. */ actions.add(new FSGetUrl("http://www.flagstonesoftware.com", "")); FSDefineButton firstButton = new FSDefineButton(movie.newIdentifier(), records, actions); /************************** * Second Button **************************/ /* * The second button is created using the FSDefineButton2 class which * provides a richer model for responding to moue events. It is similar * in appearance to the first except that the label is created using * FSDefineText2 objects rather than tracing out the text as a shape. */ records = new ArrayList(); actions = new ArrayList(); events = new ArrayList(); /* * The FSDefineText2 object contains an FSCoordTransform which is used * here to change the placement of the text so the label appears in the * middle of the button. */ FSDefineText2 secondLabel = textGenerator.defineText(movie.newIdentifier(), buttonLabel, fontSize, lineColor); width = secondLabel.getBounds().getWidth(); height = - secondLabel.getBounds().getMinY(); /* * Add the button records that define the button's appearance */ records.add(new FSButton(FSButton.Active, upShape.getIdentifier(), layer++)); records.add(new FSButton(FSButton.Up, shadow.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Up, upShape.getIdentifier(), layer++)); records.add(new FSButton(FSButton.Up, secondLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2, height/2))); records.add(new FSButton(FSButton.Over, shadow.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Over, overShape.getIdentifier(), layer++)); records.add(new FSButton(FSButton.Over, secondLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2, height/2))); records.add(new FSButton(FSButton.Down, overShape.getIdentifier(), layer++, recess)); records.add(new FSButton(FSButton.Down, secondLabel.getIdentifier(), layer++, new FSCoordTransform(-width/2 + xShadow, height/2 + yShadow))); /* * FSDefineButton2 contains a series of FSButtonEvent objects that define * the eactions performed in response to different mouse events. As in * the previous example a web page will be loaded into the web browser * when the button is clicked. */ actions.add(new FSGetUrl("http://www.flagstonesoftware.com", "")); events.add(new FSButtonEvent(FSButtonEvent.Release, actions)); FSDefineButton2 secondButton = new FSDefineButton2(movie.newIdentifier(), FSDefineButton2.Push, records, events); FSDefineSound sound = soundGenerator.defineSound(movie.newIdentifier()); FSButtonSound buttonSound = new FSButtonSound(secondButton.getIdentifier(), FSButtonEvent.Release, new FSSound(sound.getIdentifier(), 0)); /*************************************************** * Put all the objects together in a movie ***************************************************/ /* * Make the screen tall enough for a column of five buttons. */ int screenWidth = buttonWidth + 2*screenMargin; int rowHeight = buttonHeight + screenMargin; movie.setFrameSize(new FSBounds(0, 0, screenWidth, rowHeight*2)); movie.setFrameRate(1.0f); movie.add(new FSSetBackgroundColor(FSColorTable.lightblue())); // Add the font definition for the text labels movie.add(textGenerator.defineFont()); // Add the shapes used to define the buttons movie.add(shadow); movie.add(upShape); movie.add(overShape); // Add the first button and show it in the first row movie.add(firstLabel); movie.add(firstButton); movie.add(new FSPlaceObject2(firstButton.getIdentifier(), layer++, screenWidth/2 , rowHeight/2)); // Add the second button and show it in the second row movie.add(secondLabel); movie.add(secondButton); movie.add(sound); movie.add(buttonSound); movie.add(new FSPlaceObject2(secondButton.getIdentifier(), layer++, screenWidth/2 , rowHeight + rowHeight/2)); movie.add(new FSShowFrame()); } }