/*
* BasicButtonSound.java
* Cookbook
*
* Copyright (c) 2001-2009 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.
*/
import com.flagstone.transform.*;
import com.flagstone.transform.util.*;
import java.awt.Font;
import java.util.*;
import java.io.IOException;
import java.util.zip.DataFormatException;
/*
* This example shows how to create a button using FSDefineButton. The button
* displays a web page in a browser when clicked and also plays a sound.
*
* To run this example, type the following on a command line:
*
* java -cp cookbook.jar BasicButtonSound sound-file file-out
*
* where
*
* sound-file is the path to a file containing a WAVE or MP3 format sound
* which is played when a button is clicked.
*
* file-out is the path where the file will be written. If no output file
* is specified then a file named after the example will be written to the
* current directory.
*/
public class BasicButtonSound
{
public static void main(String[] args)
{
try
{
String filename = args[0];
String out = args.length == 1 ? "BasicButtonSound.swf" : args[1];
BasicButtonSound example = new BasicButtonSound();
FSMovie movie = new FSMovie();
example.createMovie(movie, filename);
movie.encodeToFile(out);
}
catch (Exception e)
{
e.printStackTrace();
}
}
void createMovie(FSMovie movie, String filename) throws IOException, DataFormatException
{
Font font = new Font("Arial", Font.PLAIN, 12);
String buttonLabel = "Click Me!";
FSTextConstructor textGenerator = new FSTextConstructor(movie.newIdentifier(), font);
FSShapeConstructor path = new FSShapeConstructor();
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.
*/
FSDefineText2 label = textGenerator.defineText(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;
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());
/*
* 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.
*/
ArrayList records = new ArrayList();
/*
* Used to hold the width and height of the bounding rectangle that
* encloses the button labels.
*/
int xOffset = -label.getBounds().getWidth()/2;
int yOffset = (buttonHeight - label.getBounds().getHeight())/2;
/*
* 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, label.getIdentifier(), layer++,
new FSCoordTransform(xOffset, yOffset)));
/*
* 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, label.getIdentifier(), layer++,
new FSCoordTransform(xOffset, yOffset)));
/*
* 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, label.getIdentifier(), layer++,
new FSCoordTransform(xOffset + xShadow, yOffset + 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.
*/
ArrayList actions = new ArrayList();
actions.add(new FSGetUrl("http://www.flagstonesoftware.com", ""));
FSDefineButton button = new FSDefineButton(movie.newIdentifier(),
records, actions);
/*
* Now define the sound that will be played when the button is clicked.
*/
FSSoundConstructor soundGenerator = new FSSoundConstructor(filename);
FSDefineSound sound = soundGenerator.defineSound(movie.newIdentifier());
FSButtonSound buttonSound = new FSButtonSound(button.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 screenHeight = buttonHeight + 2*screenMargin;
movie.setFrameSize(new FSBounds(0, 0, screenWidth, screenHeight));
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);
movie.add(label);
movie.add(button);
movie.add(sound);
movie.add(buttonSound);
movie.add(new FSPlaceObject2(button.getIdentifier(), layer++,
screenWidth/2 , screenHeight/2));
movie.add(new FSShowFrame());
}
}