/*
* JSwiff is an open source Java API for Macromedia Flash file generation
* and manipulation
*
* Copyright (C) 2004-2005 Ralf Terdic (contact@jswiff.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.jswiff.swfrecords.tags;
import com.jswiff.io.InputBitStream;
import com.jswiff.io.OutputBitStream;
import com.jswiff.swfrecords.RGBA;
import com.jswiff.swfrecords.Rect;
import java.io.IOException;
/**
* <p>
* This tag defines a dynamic text field. A text field can be associated with a
* variable the contents of the text field are stored in and kept in sync
* with.
* </p>
*
* <p>
* Users may change the value of a text field interactively, unless the
* <code>readOnly</code> tag is set.
* </p>
*
* <p>
* Fonts used by this tag must be defined using <code>DefineFont2</code> (not
* <code>DefineFont</code>). If the <code>useOutlines</code> flag is cleared, the
* Flash Player will try to render text using device fonts rather than glyph
* fonts.
* </p>
*
* <p>
* When the <code>html</code> flag is set, the text may contain HTML tags.
* Allowed tags are:
*
* <ul>
* <li>
* <code><p>...</p></code>: paragraph
* </li>
* <li>
* <code><br></code>: line break
* </li>
* <li>
* <code><a href="...">...</a></code>: hyperlink. Optional
* attributes:
*
* <ul>
* <li>
* <code>target</code>: a window name
* </li>
* </ul>
*
* </li>
* <li>
* <code><font>...</font></code>: font properties. Available
* attributes:
*
* <ul>
* <li>
* <code>face</code>: font name supplied in a <code>DefineFont2</code> tag.
* </li>
* <li>
* <code>size</code> in twips (1/20 px). Leading <code>+</code> or
* <code>-</code> indicates a relative size
* </li>
* <li>
* <code>color</code> as a <code>#RRGGBB</code> hex value
* </li>
* </ul>
*
* </li>
* <li>
* <code><b>...</b></code>: bold text
* </li>
* <li>
* <code><i>...</i></code>: italic text
* </li>
* <li>
* <code><u>...</u></code>: underlined text
* </li>
* <li>
* <code><li>...</li></code>: bulleted list. Warning: <ul> is
* not supported
* </li>
* <li>
* <code><textformat>...</textformat></code> lets you specify
* formatting attributes:
*
* <ul>
* <li>
* <code>leftmargin</code> in twips (1/20 px)
* </li>
* <li>
* <code>rightmargin</code> in twips
* </li>
* <li>
* <code>indent</code> in twips
* </li>
* <li>
* <code>blockindent</code> in twips
* </li>
* <li>
* <code>leading</code> in twips
* </li>
* <li>
* <code>tabstops</code>: comma-separated list in twips
* </li>
* </ul>
*
* </li>
* <li>
* <code><tab></code>: advances to next tab stop (defined with
* <code><textformat></code>)
* </li>
* </ul>
* </p>
*
* <p>
* Multiple other parameters can be set, e.g. text layout attributes like
* margins and leading etc.
* </p>
*
* @since SWF 4
*/
public final class DefineEditText extends DefinitionTag {
/** Left text alignment */
public static final short ALIGN_LEFT = 0;
/** Right text alignment */
public static final short ALIGN_RIGHT = 1;
/** Center text alignment */
public static final short ALIGN_CENTER = 2;
/** Justify text alignment */
public static final short ALIGN_JUSTIFY = 3;
private Rect bounds;
private boolean wordWrap;
private boolean multiline;
private boolean password;
private boolean readOnly;
private boolean autoSize;
private boolean noSelect;
private boolean border;
private boolean html;
private boolean useOutlines;
private int fontId = -1;
private int fontHeight;
private RGBA textColor;
private int maxLength;
private short align;
private int leftMargin;
private int rightMargin;
private int indent;
private int leading;
private String variableName;
private String initialText;
private boolean hasText;
private boolean hasTextColor;
private boolean hasMaxLength;
private boolean hasFont;
private boolean hasLayout;
/**
* Creates a new DefineEditText tag. Specify the character ID of the text
* field, its bounds and the name of the variable the contents of the text
* field are stored in and kept in sync with.
*
* @param characterId character ID of the text field
* @param bounds the size of the rectangle which completely encloses the
* text field.
* @param variableName variable name (in dot or slash syntax)
*/
public DefineEditText(int characterId, Rect bounds, String variableName) {
code = TagConstants.DEFINE_EDIT_TEXT;
this.characterId = characterId;
this.bounds = bounds;
this.variableName = variableName;
}
DefineEditText() {
// empty
}
/**
* Returns the text alignment (one of the constants <code>ALIGN_LEFT,
* ALIGN_RIGHT, ALIGN_CENTER, ALIGN_JUSTIFY</code>). Check with
* <code>hasLayout()</code> first if value is set.
*
* @return text alignment
*/
public short getAlign() {
return align;
}
/**
* Sets the value of the <code>autoSize</code> flag. If set, the text field
* resizes depending on its content size.
*
* @param autoSize <code>true</code> if flag set, else <code>false</code>
*/
public void setAutoSize(boolean autoSize) {
this.autoSize = autoSize;
}
/**
* Checks if the <code>autoSize</code> flag is set, i.e. if the text field
* is supposed to resize depending on its content size.
*
* @return <code>true</code> if flag set, else <code>false</code>
*/
public boolean isAutoSize() {
return autoSize;
}
/**
* Sets the value of the <code>border</code> flag. A set flag causes a
* border to be drawn around the text field.
*
* @param border <code>true</code> if flag set, else <code>false</code>
*/
public void setBorder(boolean border) {
this.border = border;
}
/**
* Checks if the <code>border</code> flag, causing a border to be drawn
* around the text field.
*
* @return <code>true</code> if <code>border</code> flag is set, else
* <code>false</code>
*/
public boolean isBorder() {
return border;
}
/**
* Returns the bounds of the text field, i.e. the size of the rectangle
* which completely encloses the text field.
*
* @return text field bounds
*/
public Rect getBounds() {
return bounds;
}
/**
* Sets the font of the text.
*
* @param fontId character ID of the font
* @param fontHeight font height in twips (1/20 px)
*/
public void setFont(int fontId, int fontHeight) {
this.fontId = fontId;
this.fontHeight = fontHeight;
hasFont = true;
}
/**
* Returns the font height (in twips, i.e. 1/20 px). Check with
* <code>hasFont()</code> first if value is set.
*
* @return font height in twips
*/
public int getFontHeight() {
return fontHeight;
}
/**
* Returns the character ID of the used font. Check with
* <code>hasFont()</code> first if value is set.
*
* @return font character ID
*/
public int getFontId() {
return fontId;
}
/**
* Sets the value of the <code>html</code> flag. If set, html tags are
* allowed in the contained text.
*
* @param html <code>true</code> if flag set, else <code>false</code>
*/
public void setHtml(boolean html) {
this.html = html;
}
/**
* Returns the <code>html</code> flag, which specifies whether html tags
* are allowed in the contained text.
*
* @return <code>true</code> if <code>html</code> flag is set, otherwise
* <code>false</code>
*/
public boolean isHtml() {
return html;
}
/**
* Returns the text indent in twips (i.e. 1/20 px). Check with
* <code>hasLayout()</code> first if value is set.
*
* @return text indent in twips
*/
public int getIndent() {
return indent;
}
/**
* Sets the text initially contained in the text field.
*
* @param initialText initialText
*/
public void setInitialText(String initialText) {
this.initialText = initialText;
hasText = true;
}
/**
* Returns the initial text string. Check with <code>hasText()</code>
* first if value is set.
*
* @return initial text
*/
public String getInitialText() {
return initialText;
}
/**
* Sets the layout properties of the text: alignment, margins, indentation
* and line spacing.
*
* @param align text alignment, one of the constants <code>ALIGN_LEFT,
* ALIGN_RIGHT, ALIGN_CENTER, ALIGN_JUSTIFY</code>
* @param leftMargin left text margin in twips (i.e. 1/20 px)
* @param rightMargin right text margin
* @param indent text indentation in twips
* @param leading line spacing in twips
*/
public void setLayout(
short align, int leftMargin, int rightMargin, int indent, int leading) {
this.align = align;
this.leftMargin = leftMargin;
this.rightMargin = rightMargin;
this.indent = indent;
this.leading = leading;
hasLayout = true;
}
/**
* Returns the text leading (line spacing) in twips (i.e. 1/20 px). Check
* with <code>hasLayout()</code> first if value is set.
*
* @return line spacing in twips
*/
public int getLeading() {
return leading;
}
/**
* Returns the left text margin in twips (i.e. 1/20 px). Check with
* <code>hasLayout()</code> first if value is set.
*
* @return left margin in twips
*/
public int getLeftMargin() {
return leftMargin;
}
/**
* Restricts the text length to the specified amount of characters.
*
* @param maxLength maximum text length
*/
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
hasMaxLength = true;
}
/**
* Returns the maximum length of the text. Check with
* <code>hasMaxLength()</code> if value is set.
*
* @return maximum text length
*/
public int getMaxLength() {
return maxLength;
}
/**
* Sets the value of the <code>multiLine</code> flag. If set, the text
* field may contain more than one text line.
*
* @param multiline <code>true</code> if flag set, else <code>false</code>
*/
public void setMultiline(boolean multiline) {
this.multiline = multiline;
}
/**
* Checks if the <code>multiLine</code> flag is set. If set, the text field
* may contain more than one text line.
*
* @return <code>true</code> if <code>multiLine</code> flag set, otherwise
* <code>false</code>
*/
public boolean isMultiline() {
return multiline;
}
/**
* Sets the value of the <code>noSelect</code> flag. If set, the text
* cannot be interactively selected (and copied).
*
* @param noSelect <code>true</code> if flag set, else <code>false</code>
*/
public void setNoSelect(boolean noSelect) {
this.noSelect = noSelect;
}
/**
* Checks if the <code>noSelect</code> flag is set. If set, the text cannot
* be interactively selected (and copied).
*
* @return <code>true</code> if <code>noSelect</code> flag set, otherwise
* <code>false</code>
*/
public boolean isNoSelect() {
return noSelect;
}
/**
* Sets the value of the <code>password</code> flag. If set, the characters
* of the text are displayed as asterisks.
*
* @param password <code>true</code> if flag set, else <code>false</code>
*/
public void setPassword(boolean password) {
this.password = password;
}
/**
* Checks whether the <code>password</code> flag is set. If set, the
* characters of the text are displayed as asterisks.
*
* @return <code>true</code> if <code>password</code> flag set, otherwise
* <code>false</code>
*/
public boolean isPassword() {
return password;
}
/**
* Specifies the value of the <code>readOnly</code> flag. If set, the text
* cannot be interactively edited.
*
* @param readOnly <code>true</code> if flag set, else <code>false</code>
*/
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
/**
* Checks whether the <code>readOnly</code> flag is set. If set, the text
* cannot be interactively edited.
*
* @return <code>true</code> if <code>readOnly</code> flag set, otherwise
* <code>false</code>
*/
public boolean isReadOnly() {
return readOnly;
}
/**
* Returns the right text margin in twips (i.e. 1/20 px). Check with
* <code>hasLayout()</code> first if value is set.
*
* @return right margin in twips
*/
public int getRightMargin() {
return rightMargin;
}
/**
* Sets the text color to the specified color. Alpha channel (transparency)
* information can also be specified.
*
* @param textColor text color as RGBA value
*/
public void setTextColor(RGBA textColor) {
this.textColor = textColor;
hasTextColor = true;
}
/**
* Returns the text color and transparency value.
*
* @return text color as RGBA value
*/
public RGBA getTextColor() {
return textColor;
}
/**
* Sets the value of the <code>useOutlines</code> flag. If set, the Flash
* Player tries to use device fonts rather than glyph fonts.
*
* @param useOutlines <code>true</code> if flag set, else
* <code>false</code>
*/
public void setUseOutlines(boolean useOutlines) {
this.useOutlines = useOutlines;
}
/**
* Checks if the <code>useOutlines</code> flag is set. If set, the Flash
* Player tries to use device fonts rather than glyph fonts.
*
* @return <code>true</code> if <code>useOutlines</code> flag set,
* otherwise <code>false</code>
*/
public boolean isUseOutlines() {
return useOutlines;
}
/**
* Sets the name of the variable the contents of the text field are stored
* in and kept in sync with.
*
* @param variableName variable name (in dot or slash syntax)
*/
public void setVariableName(String variableName) {
this.variableName = variableName;
}
/**
* Returns the name of the variable the contents of the text field are
* stored in and kept in sync with.
*
* @return variable name (in dot or slash syntax)
*/
public String getVariableName() {
return variableName;
}
/**
* Sets the value of the <code>wordWrap</code> flag. If set, the text will
* wrap at the end of the line.
*
* @param wordWrap <code>true</code> if flag set, else <code>false</code>
*/
public void setWordWrap(boolean wordWrap) {
this.wordWrap = wordWrap;
}
/**
* Checks if the <code>wordWrap</code> flag is set. If set, the text will
* wrap at the end of the line.
*
* @return <code>true</code> if <code>wordWrap</code> flag set, otherwise
* <code>false</code>
*/
public boolean isWordWrap() {
return wordWrap;
}
/**
* Checks whether the text font (ID and size) has been specified.
*
* @return <code>true</code> if font specified, else <code>false</code>
*/
public boolean hasFont() {
return hasFont;
}
/**
* Checks if the text layout has been specified, i.e. if the following
* attributes have been set:
*
* <ul>
* <li>
* align
* </li>
* <li>
* left margin
* </li>
* <li>
* right margin
* </li>
* <li>
* indent
* </li>
* <li>
* leading
* </li>
* </ul>
*
*
* @return <code>true</code> if at least one layout attribute set
*/
public boolean hasLayout() {
return hasLayout;
}
/**
* Checks if the length of the text has been restricted to a maximum value.
*
* @return <code>true</code> if maximum text length is set, else
* <code>false</code>
*/
public boolean hasMaxLength() {
return hasMaxLength;
}
/**
* Checks if an initial text is provided.
*
* @return <code>true</code> if initial text set, else <code>false</code>
*/
public boolean hasText() {
return hasText;
}
/**
* Checks if the text color is set.
*
* @return <code>true</code> if text color set, else <code>false</code>
*/
public boolean hasTextColor() {
return hasTextColor;
}
protected void writeData(OutputBitStream outStream)
throws IOException {
outStream.writeUI16(characterId);
bounds.write(outStream);
outStream.writeBooleanBit(hasText);
outStream.writeBooleanBit(wordWrap);
outStream.writeBooleanBit(multiline);
outStream.writeBooleanBit(password);
outStream.writeBooleanBit(readOnly);
outStream.writeBooleanBit(hasTextColor);
outStream.writeBooleanBit(hasMaxLength);
outStream.writeBooleanBit(hasFont);
outStream.writeUnsignedBits(0, 1); // 1 reserved bit
outStream.writeBooleanBit(autoSize);
outStream.writeBooleanBit(hasLayout);
outStream.writeBooleanBit(noSelect);
outStream.writeBooleanBit(border);
outStream.writeUnsignedBits(0, 1); // 1 reserved bit
outStream.writeBooleanBit(html);
outStream.writeBooleanBit(useOutlines);
if (hasFont) {
outStream.writeUI16(fontId);
outStream.writeUI16(fontHeight);
}
if (hasTextColor) {
textColor.write(outStream);
}
if (hasMaxLength) {
outStream.writeUI16(maxLength);
}
if (hasLayout) {
outStream.writeUI8(align);
outStream.writeUI16(leftMargin);
outStream.writeUI16(rightMargin);
outStream.writeUI16(indent);
outStream.writeUI16(leading);
}
if (variableName != null) {
outStream.writeString(variableName);
} else {
outStream.writeString("");
}
if (hasText) {
outStream.writeString(initialText);
}
}
void setData(byte[] data) throws IOException {
InputBitStream inStream = new InputBitStream(data);
if (getSWFVersion() < 6) {
if (isJapanese()) {
inStream.setShiftJIS(true);
} else {
inStream.setANSI(true);
}
}
characterId = inStream.readUI16();
bounds = new Rect(inStream);
hasText = inStream.readBooleanBit();
wordWrap = inStream.readBooleanBit();
multiline = inStream.readBooleanBit();
password = inStream.readBooleanBit();
readOnly = inStream.readBooleanBit();
hasTextColor = inStream.readBooleanBit();
hasMaxLength = inStream.readBooleanBit();
hasFont = inStream.readBooleanBit();
inStream.readBooleanBit(); // ignore reserved bit
autoSize = inStream.readBooleanBit();
hasLayout = inStream.readBooleanBit();
noSelect = inStream.readBooleanBit();
border = inStream.readBooleanBit();
inStream.readBooleanBit(); // ignore reserved bit
html = inStream.readBooleanBit();
useOutlines = inStream.readBooleanBit();
if (hasFont) {
fontId = inStream.readUI16();
fontHeight = inStream.readUI16();
}
if (hasTextColor) {
textColor = new RGBA(inStream);
}
if (hasMaxLength) {
maxLength = inStream.readUI16();
}
if (hasLayout) {
align = inStream.readUI8();
leftMargin = inStream.readUI16();
rightMargin = inStream.readUI16();
indent = inStream.readUI16();
leading = inStream.readUI16();
}
variableName = inStream.readString();
if (hasText) {
initialText = inStream.readString();
}
}
}