FlxInputText - An input text field what "fits in" with the Flixel workflowWell...I'm working on hi-score submitting and I found out that I needed to
enter the initials of the player.So I did an
almost non-intrusive class to do the job.
See how it looks!It has some cool features like
forcing uppercase,
text filtering with regexps,
max length , colored border, colored background and such.
For example, if I want a 3-uppercase-letters input textbox I only need to do this:
initialsInput = layer.add(new FlxInputText(X, Y, Width, Height, "", 0xffffff, null, 24)) as FlxInputText;
initialsInput.setMaxLength(3);
initialsInput.filterMode = FlxInputText.ONLY_ALPHA;
initialsInput.forceUpperCase = true;
//...
var userInitials:String = initialsInput.getText();
Notes* If it's rendered (
visible && exists), it can be written to. Update does nothing.
This takes into account cascade-drawing... you can safely use layers or call render() yourself.* The default background color is the negated value of the text color, and the border color the same as the text color. They are both visible by default.
* There is no filtering by default.
* Filtering can be customized by using
filterMode=CUSTOM_FILTER and the
customFilterPattern member.
* Forcing uppercase is disabled by default.
* Works with zoomed games.
Bugs* The cursor changes to the default "caret" one, but you can still see the Flixel one. That's kind of buggy but should be easy to fix.
You need to change "private" to "protected" in FlxText's "_tf" member variable for this to work.Copy and paste the following code in a file named FlxInputText.as and leave it wherever you want

(you will need to change the package if you don't put it at the root of your project)
I hope you like it, good luck!
The class code/*
*** FlxInputText v0.9, Input text field extension for Flixel ***
IMPORTANT: You need to modify the FlxText class so that the _tf member is protected instead of private.
New members:
getText()
setMaxLength()
backgroundColor
borderColor
backgroundVisible
borderVisible
forceUpperCase
filterMode
customFilterPattern
Copyright (c) 2009 Martin Sebastian Wain
License: Creative Commons Attribution 3.0 United States
(http://creativecommons.org/licenses/by/3.0/us/)
(A tiny "single line comment" reference in the source code is more than sufficient as attribution :)
*/
package {
import com.adamatomic.flixel.*;
import flash.events.Event;
import flash.text.TextFieldType;
//@desc Input field class that "fits in" with Flixel's workflow
public class FlxInputText extends FlxText {
static public const NO_FILTER:uint = 0;
static public const ONLY_ALPHA:uint = 1;
static public const ONLY_NUMERIC:uint = 2;
static public const ONLY_ALPHANUMERIC:uint = 3;
static public const CUSTOM_FILTER:uint = 4;
//@desc Defines what text to filter. It can be NO_FILTER, ONLY_ALPHA, ONLY_NUMERIC, ONLY_ALPHA_NUMERIC or CUSTOM_FILTER
// (Remember to append "FlxInputText." as a prefix to those constants)
public var filterMode:uint = NO_FILTER;
//@desc This regular expression will filter out (remove) everything that matches. This is activated by setting filterMode = FlxInputText.CUSTOM_FILTER.
public var customFilterPattern:RegExp = /[]*/g;
//@desc If this is set to true, text typed is forced to be uppercase
public var forceUpperCase:Boolean = false;
//@desc Same parameters as FlxText
public function FlxInputText(X:Number, Y:Number, Width:uint, Height:uint, Text:String, Color:uint=0x000000, Font:String=null, Size:uint=8, Justification:String=null, Angle:Number=0)
{
super(X, Y, Width, Height, Text, Color, Font, Size, Justification, Angle);
_tf.selectable = true;
_tf.type = TextFieldType.INPUT;
_tf.background = true;
_tf.backgroundColor = (~Color) & 0xffffff;
_tf.border = true;
_tf.borderColor = Color;
_tf.visible = false;
_tf.addEventListener(Event.ENTER_FRAME, onEnterFrame);
_tf.addEventListener(Event.REMOVED_FROM_STAGE, onInputFieldRemoved);
_tf.addEventListener(Event.CHANGE, onTextChange);
FlxG.state.addChild(_tf);
}
//@desc Boolean flag in case render() is called BEFORE onEnterFrame() (_tf would be always hidden)
// NOTE: I don't think it's necessary, but I'll leave it just in case.
//@param Direction True is Right, False is Left (see static const members RIGHT and LEFT)
private var nextFrameHide:Boolean = false;
override public function render():void
{
_tf.x=x;
_tf.y=y;
_tf.visible = true;
nextFrameHide = false;
}
private function onInputFieldRemoved(event:Event):void
{
//Clean up after ourselves
_tf.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
_tf.removeEventListener(Event.REMOVED, onInputFieldRemoved);
_tf.removeEventListener(Event.CHANGE, onTextChange);
}
private function onEnterFrame(event:Event):void
{
if(nextFrameHide)
_tf.visible=false;
nextFrameHide = true;
}
private function onTextChange(event:Event):void
{
if(forceUpperCase)
_tf.text = _tf.text.toUpperCase();
if(filterMode != NO_FILTER) {
var pattern:RegExp;
switch(filterMode) {
case ONLY_ALPHA: pattern = /[^a-zA-Z]*/g; break;
case ONLY_NUMERIC: pattern = /[^0-9]*/g; break;
case ONLY_ALPHANUMERIC: pattern = /[^a-zA-Z0-9]*/g; break;
case CUSTOM_FILTER: pattern = customFilterPattern; break;
default:
throw new Error("FlxInputText: Unknown filterMode ("+filterMode+")");
}
_tf.text = _tf.text.replace(pattern, "");
}
}
//@desc Text field background color
public function set backgroundColor(Color:uint):void { _tf.backgroundColor = Color; }
//@desc Text field border color
public function set borderColor(Color:uint):void { _tf.borderColor = Color; }
//@desc Shows/hides background
public function set backgroundVisible(Enabled:Boolean):void { _tf.background = Enabled; }
//@desc Shows/hides border
public function set borderVisible(Enabled:Boolean):void { _tf.border = Enabled; }
//@desc Text field background color
public function get backgroundColor():uint { return _tf.backgroundColor; }
//@desc Text field border color
public function get borderColor():uint { return _tf.borderColor; }
//@desc Shows/hides background
public function get backgroundVisible():Boolean { return _tf.background; }
//@desc Shows/hides border
public function get borderVisible():Boolean { return _tf.border; }
//@desc Set the maximum length for the field (e.g. "3" for Arcade type hi-score initials)
//@param Length The maximum length. 0 means unlimited.
public function setMaxLength(Length:uint):void
{
_tf.maxChars = Length;
}
//@desc Get the text the user has typed
public function getText():String
{
return _tf.text;
}
}
}
FlxState source for the
See how it looks! demo.
package game
{
import com.adamatomic.flixel.*;
public class TEST_InputText extends FlxState
{
[Embed(source="../tbam_asd.png")] private var ImgTBAMLogo:Class;
[Embed(source="data/cursor.png")] private var ImgCursor:Class;
private var layer:FlxLayer;
override public function TEST_InputText():void
{
var logo:FlxSprite;
logo = new FlxSprite(ImgTBAMLogo, 0, 0);
logo.x=1;
logo.y=1;
this.add(logo);
FlxG.setCursor(ImgCursor);
FlxG.flash(0xff000000, 1);
this.add(new FlxButton(0,220,new FlxSprite(null,0,0,false,false,104,15,0xff3a5c39),function():void{layer.visible=false;},new FlxSprite(null,0,0,false,false,104,15,0xff729954),new FlxText(0,1,104,10,"Hide layer",0x729954, null, 8, "center"),new FlxText(0,1,104,10,"Hide layer",0xd8eba2, null, 8, "center")));
this.add(new FlxButton(150,220,new FlxSprite(null,0,0,false,false,104,15,0xff3a5c39),function():void{layer.visible=true;},new FlxSprite(null,0,0,false,false,104,15,0xff729954),new FlxText(0,1,104,10,"Show layer",0x729954, null, 8, "center"),new FlxText(0,1,104,10,"Show layer",0xd8eba2, null, 8, "center")));
layer = new FlxLayer;
layer.add(new FlxText(0, 170, 200, 20, "This FlxText is in a layer", 0xffffff));
var layerInput:FlxInputText = layer.add(new FlxInputText(0, 190, 220, 12, "this input textbox is in a layer too", 0xffffff)) as FlxInputText;
layerInput.borderVisible=false;
layerInput.backgroundColor=0x400000;
this.add(new FlxText(50, 50, 200, 24, "This input text has custom filtering\n(can only write .,:; and digits)", 0xffffff));
var customFilterInput:FlxInputText = this.add(new FlxInputText(50, 76, 220, 12, "", 0xffffff)) as FlxInputText;
customFilterInput.customFilterPattern = /[^.,:;0-9]*/g;
customFilterInput.filterMode = FlxInputText.CUSTOM_FILTER;
this.add(layer);
this.add(new FlxText(20, 100, FlxG.width-40, 30, "Enter your initials (max 3 chars, auto uppercase)", 0xffffff, null, 8, "center")) as FlxText;
var initialsInput:FlxInputText = this.add(new FlxInputText((FlxG.width-100)/2, 120, 100, 30, "MSW", 0xffffff, null, 24)) as FlxInputText;
initialsInput.setMaxLength(3);
initialsInput.filterMode = FlxInputText.ONLY_ALPHA;
initialsInput.forceUpperCase = true;
}
}
}