Link to home
Start Free TrialLog in
Avatar of NiklasMoller
NiklasMoller

asked on

How can I store info and attach it to a sprite???

I am making a custom button class for creating and handling buttons.

What I would like to do is store some "info" for each button, such as:
- index-nr
- value
- description

etc etc

And then I would like to access that info in the eventlistner for mouse up for example.
My problem is that each button I make consists of a sprite....
And I want to "attach" this info to the sprite somehow. My question is HOW?

Ive tried "attaching" an object to the sprite, like this for example, it will not work:

---------------------------------
//_tempButHolder is a Sprite
//store necessary info for this button:
_tempButHolder.butInfo:Object = new Object();
_tempButHolder.butInfo.butValue = "special value";
_tempButHolder.butInfo.toolTipText = "tooltip text here...";

//this will give me an error "Label must be a simple identifier"

Do you have any good ideas for how to store this info?

I guess I could store one piece of info in the name property of the sprite, but thats not enough, i want to store more info than just one item per button...

I want to access the info that I have store in a way that is similar to this:

private function mouseUpHandler(evt:MouseEvent):void{
                  debugTrace("mouseOutHandler: " + evt.target.name + ", mouse out");                  
                  changeButtonState(evt.target, "out");
                  _stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
                  trace(evt.target.butInfo.butValue); // <== here I want to access the value that I have stored
            }//end

Please give me some creative solution to this problem!?

Thank you in advance!


Avatar of Dreammonkey
Dreammonkey
Flag of Belgium image

Try defining the variables (the info you want to save) in the class construcor.
Then you can assign them in your actions to your newly created class instance...

package {
   import flash.display.*;
   
   public class ButtonClass extends Sprite {
   
      public var butValue:Sprite = "special value";
      public var toolTipText:String;
      
      public function whatever():void {
 
      }
   }
}
 
//In Flash :
 
var but:Sprite = new ButtonClass();
but.toolTipText = "tooltip text here...";

Open in new window

Avatar of NiklasMoller
NiklasMoller

ASKER

Thanks for answering so quickly!

But I dont really understand...
(I am quite new to AS3 so forgive me for being a bit thick...)

You might as well see the whole class, because I'm not sure what you are suggesting..

I want to "reuse" the same class for creating many buttons,

so the way I use it now is:
-----------------------------------
//in the timeline:
var but:CustomButton = new CustomButton(stage); //instantiate class
but.butTextArray = ["button text"];
var myBut:Sprite = but.createButton(); // create a button
addChild(myBut);
-----------------------------------

What I would like to do is also pass some other array and save that info like for example:
-----------------------------------
//in the timeline:
var but:CustomButton = new CustomButton(stage); //instantiate class
but.butTextArray = ["button text"];
but.butInfoArray = ["index01", "myFrog.jpg", "killerSound", "tooltip text instructions"]; //<== I DONT have a setter function for this in the class right now, but what I am asking is how do I even store that info for access later????
var myBut:Sprite = but.createButton(); // create a button
addChild(myBut);
-----------------------------------



package {
		
	import flash.display.*;
	import flash.text.*;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	public class CustomButton extends Sprite{
		
		private var _index:int = 0;
		
		private var _w:uint = 30; //default/start value
		private var _h:uint = 15; //default/start value
		private var _cornerRadius:uint = 0;//default/start value
		
		//if this is true the button width will expand
		//depending on amount of text
		private var _fixedWidth = true;
		private var _fixedHeight = true;
		
		//default texts for button states:
		private var _butTextArray:Array = ["Out Text", "Over Text", "Down Text"];
		//default colors for background: (out, over, down)
		private var _bgColorArray:Array = ["0x00FF00", "0x0000FF", "0xFF0000"];	
		
		//default styling for textfields:
		var _butTextFormatDef:TextFormat = new TextFormat();
		
		private var _butArray:Array;
		
		private var _butTextOut_txt:TextField;
		private var _butTextOver_txt:TextField;
		private var _butTextDown_txt:TextField;
		private var _butTextFormatArray:Array;
		
		//FIX IT:
		//this class needs a reference to the stage
		//(to listen for mouse ups on stage)
		public var _stage:Object;
		
		//for debug:
		private var _debugTraceEnabled:Boolean = false;
		private var _debugTraceStartText:String = "CLASS: CustomButton.as: ";
		
		public function CustomButton(stageReference:Object):void{
			//constructor			
			forceTrace("running constructor");
			_stage = stageReference;
			init();
			
		}//end constructor
		
		
		private function init():void{
			//set default values:
			forceTrace("method start: init()");
			
			_butArray = new Array();
			
			//set default styling for text labels:
			_butTextFormatDef.color = 0x000000;
			_butTextFormatDef.font = "Arial";
			_butTextFormatDef.size = 10;					
			//_butTextFormatDef.align = "center";
			_butTextFormatDef.align = "center";
		
			//as default, store the default textstyle for all 3 states:
			_butTextFormatArray = [_butTextFormatDef, _butTextFormatDef, _butTextFormatDef];
		}//end init()
		
		public function createButton(w:Number = 10000, h:Number=10000, cornerRadius:Number=10000):Sprite{
			//debug:
			debugTrace("method start: createButton");
			
			//if either of w, h, or cornerRadius come through as 10000
			//there was no value passed, so use default, or latest value passed
			(w == 10000)? w = _w: _w = w;
			(h == 10000)? h = _h: _h = h;
			(cornerRadius == 10000) ? cornerRadius = _cornerRadius : _cornerRadius = cornerRadius;
			
			var _tempButHolder:Sprite = new Sprite();
			//FIX IT:
			//is this index really necessary?
			
			_tempButHolder.name = "button" + String(_index);
			_index++;
			
			//create sprites for button holder and states:
			var butOut:Sprite = new Sprite();
			butOut.name = "butOut_sp";
			var butOver:Sprite = new Sprite();
			butOver.name = "butOver_sp";
			var butDown:Sprite = new Sprite();
			butDown.name = "butDown_sp";
			
			//add text for out state:
			_butTextOut_txt = createTextLabel(_butTextArray[0], _butTextFormatArray[0]);
			_butTextOut_txt.name = "_butTextOut_txt";
			butOut.addChild(_butTextOut_txt);
			
			//get width (either fixed, or adapted to text)
			_w = getWidthForBg(_butTextOut_txt);
			//draw Out (normal) state:
			var gOut:Object = butOut.graphics;				
			gOut.beginFill(_bgColorArray[0], 1);
			gOut.drawRoundRect(0, 0, _w, _h, _cornerRadius)
			gOut.endFill();
			
			//over:
			_butTextOver_txt = createTextLabel(_butTextArray[1], _butTextFormatArray[1]);
			_butTextOver_txt.name = "_butTextOver_txt";
			butOver.addChild(_butTextOver_txt);
			
			//get width (either fixed, or adapted to text)
			_w = getWidthForBg(_butTextOver_txt);
			
			//draw Over state:
			var gOver:Object = butOver.graphics;				
			gOver.beginFill(_bgColorArray[1], 1);
			gOver.drawRoundRect(0, 0, _w, _h, _cornerRadius);
			gOver.endFill();
			
			//down state
			_butTextDown_txt = createTextLabel(_butTextArray[2], _butTextFormatArray[2]);
			_butTextDown_txt.name = "_butTextDown_txt";
			butDown.addChild(_butTextDown_txt);
			
			//get width (either fixed, or adapted to text)
			_w = getWidthForBg(_butTextDown_txt);
			//draw Down state:
			var gDown:Object = butDown.graphics;				
			gDown.beginFill(_bgColorArray[2], 1);
			gDown.drawRoundRect(0, 0, _w, _h, _cornerRadius);
			gDown.endFill();
 
			_tempButHolder.addChild(butOut);
			_tempButHolder.addChild(butOver);
			_tempButHolder.addChild(butDown);
			
			//add event listeners to container:
			_tempButHolder.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler, false, 0, true);
			_tempButHolder.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler, false, 0, true);
			//we will add mouse up listener to stage, dont add to button holder
			//_butHolder.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
			_tempButHolder.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler, false, 0, true);
			
			//hide all but the out (normal) state:
			changeButtonState(_tempButHolder, "start");
			
			//disable mouse-events for all children of container:
			_tempButHolder.mouseChildren = false;
			//this will make the hand cursor show etc:
			_tempButHolder.buttonMode = true;
			
			// HERE is where I want to store the info
			//and attach it to the _tempButHolder Sprite
			// HOW?
			
			_butArray.push(_tempButHolder);
			
			return _tempButHolder;
			
		}//end
		
		private function getVertCenterPos(itemToCenter){
			//get width of object:
			var newPos:Number = (_h/2) - (itemToCenter.height/2);
			return newPos;
			
		}//end
		
		private function createTextLabel(label_text:String, format_object:TextFormat = null):TextField{
			debugTrace("start: function createTextLabel()");
			
			var _tempTextField = new TextField();
			
			_tempTextField.defaultTextFormat = format_object;
			_tempTextField.autoSize = TextFieldAutoSize.LEFT;
			_tempTextField.selectable = false;
			
			_tempTextField.height = 1;
			_tempTextField.width = 1;
			_tempTextField.text = label_text;
			
			if (_fixedWidth){
				if (_tempTextField.width > _w){
					//the texfield width is bigger than button, 
					//let user know clipping may occur:
					debugTrace("textfield width too wide for button, some clipping may occur");
				}
				_tempTextField.width = _w;
				_tempTextField.wordWrap = true;
				_tempTextField.multiline = true;
			}
			if (_fixedHeight){
				if (_tempTextField.height > _h){
				//the texfield has become bigger than the button size,
				//let user know clipping will occur:
				debugTrace("textfield height too high for button, some clipping may occur");
				//turn off autosize:
				_tempTextField.autoSize = TextFieldAutoSize.NONE;
				}
				//cut the textfield down to size:
				_tempTextField.height = _h;
			}
			//position correctly vertically in middle:
			_tempTextField.y = getVertCenterPos(_tempTextField);
						
			return _tempTextField;
		}
		
		private function mouseOutHandler(evt:MouseEvent):void{
			debugTrace("mouseOutHandler: " + evt.target.name + ", mouse out");			
			changeButtonState(evt.target, "out");
			_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		}//end
		
		private function mouseOverHandler(evt:MouseEvent):void{
			debugTrace("mouseOverHandler: " + evt.target.name + ", mouse over");	
			changeButtonState(evt.target, "over");
			
		}//end
		
		private function mouseDownHandler(evt:MouseEvent):void{
			debugTrace("mouseDownHandler: " + evt.target.name + ", mouse down");	
			//evt.target.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
			changeButtonState( evt.target, "down" );
			
			//*********************************
			//This is where I want to add the listener to the stage like so for example:
			//FIX IT: this uses a reference to the stage passed into the classe when running constructor
			//remove the need for the reference (somehow...), and instead find the stage from the class
			_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler, false, 0, true);
			
		}//end
		
		private function mouseUpHandler(evt:MouseEvent):void{
			debugTrace("mouseUpHandler: " + evt.target.name + ", mouse up");	
			changeButtonState( evt.target, "up" );
		}//end
		
		private function changeButtonState(target:*, currentState:String){
			
			var debugStart:String = "changeButtonState() ";
			
			switch (currentState){
				case "start":
					debugTrace(debugStart + "start");
					target.getChildByName("butOut_sp").visible = 1;
					target.getChildByName("butOver_sp").visible = 0;
					target.getChildByName("butDown_sp").visible = 0;
					break;
				
				case "out":
					debugTrace(debugStart + "out");
					target.getChildByName("butOut_sp").visible = 1;
					target.getChildByName("butOver_sp").visible = 0;
					target.getChildByName("butDown_sp").visible = 0;
					break;
				
				case "over":
					debugTrace(debugStart + "over");
					target.getChildByName("butOut_sp").visible = 0;
					target.getChildByName("butOver_sp").visible = 1;
					break;
					
				case "down":
					debugTrace(debugStart + "down");
					target.getChildByName("butDown_sp").visible = true;
					target.getChildByName("butOver_sp").visible = false;
					break;
					
				case "up":
					debugTrace(debugStart + "up");
					target.getChildByName("butDown_sp").visible = false;
					target.getChildByName("butOver_sp").visible = true;
					break;
			}//end switch
			
		}//end hideShowStates		
		
		private function getWidthForBg(txtField:TextField):Number{
			
			if (_fixedWidth){
				return _w;
			} else {
				_w = txtField.width;
				return _w;
			}
			
		}//end function
		
		
 
		
		///////////////////////////////////////////////////
		// Setters and Getters
		//////////////////////////////////////////////////
		public function set bgColorArray(bgColorArray:Array){
			//pass an array containing 3 strings into this function
			//sets up the text for the labels to be used
			
			//presume that there might be errors in array:
			var errorArray:Array = new Array();
			
			//check for errors in array, all items must be strings:
			for each (var item in bgColorArray){
				if (item is String){
					//everything is ok, dont do anything
				} else {
					debugTrace("set bgColorArray: rejecting butTextArray, all items have to be String type!");
					debugTrace("set bgColorArray: the faulty item was: "+item);
					errorArray.push(1);
				}
			}
			
			if (errorArray.length == 0) {
				//check length of passed array:
				switch (bgColorArray.length){
					case 1:
						//use the same label for all states:
						_bgColorArray[0] = bgColorArray[0];
						_bgColorArray[1] = bgColorArray[0];
						_bgColorArray[2] = bgColorArray[0];
						break;
					case 2:
						//use the same label for over and down
						_bgColorArray[0] = bgColorArray[0];
						_bgColorArray[1] = bgColorArray[1];
						_bgColorArray[2] = bgColorArray[1];
						break;
					case 3:
						//use different labels for out, over, down:
						//just equate the arrays:
						_bgColorArray = bgColorArray;	
						break;
					default:
						//if no cases above matched, it means array is no good:
						debugTrace("Error: set bgColorArray: Rejecting butTextArray.");
						debugTrace("Error: set bgColorArray: Length of butTextArray was " + bgColorArray.length);
						debugTrace("Error: set bgColorArray: It needs to be betw. 1 and 3");
						break;
				}//end switch
			}//end if
				
		}//end function set
		
		
		
		
		
		
		
		
		public function set butTextArray(butTextArray:Array){
			//pass an array containing 3 strings into this function
			//sets up the text for the labels to be used
			
			//presume that there might be errors in array:
			var errorArray:Array = new Array();
			
			//check for errors in array, all items must be strings:
			for each (var item in butTextArray){
				if (item is String){
					//everything is ok, dont do anything
				} else {
					debugTrace("set butTextArray: rejecting butTextArray, all items have to be String type!");
					debugTrace("set butTextArray: the faulty item was: "+item);
					errorArray.push(1);
				}
			}
			
			if (errorArray.length == 0) {
				//check length of passed array:
				switch (butTextArray.length){
					case 1:
						//use the same label for all states:
						_butTextArray[0] = butTextArray[0];
						_butTextArray[1] = butTextArray[0];
						_butTextArray[2] = butTextArray[0];
						break;
					case 2:
						//use the same label for over and down
						_butTextArray[0] = butTextArray[0];
						_butTextArray[1] = butTextArray[1];
						_butTextArray[2] = butTextArray[1];
						break;
					case 3:
						//use different labels for out, over, down:
						//just equate the arrays:
						_butTextArray = butTextArray;	
						break;
					default:
						//if no cases above matched, it means array is no good:
						debugTrace("Error: set butTextArray: Rejecting butTextArray.");
						debugTrace("Error: set butTextArray: Length of butTextArray was " + butTextArray.length);
						debugTrace("Error: set butTextArray: It needs to be betw. 1 and 3");
						break;
				}//end switch
			}//end if
				
		}//end function set
		
		public function set butTextFormatArray(butTextFormatArray:Array):void{
			//presume that there might be errors in array:
			var errorArray:Array = new Array();
			
			//check for errors in array, all items must be objects:
			for each (var item in butTextFormatArray){
				if (item is TextFormat){
					//everything is ok, do nothing
				} else {
					debugTrace("set butTextFormatArray: rejecting butTextFormatArray, does not contain TextFormat Objects!");
					debugTrace("set butTextFormatArray: the faulty item was: "+item);
					errorArray.push(1);
				}
			}
			
			if (errorArray.length == 0) {
				//check length of passed array:
				switch (butTextFormatArray.length){
					case 1:
						//use the same style for all states:
						_butTextFormatArray[0] = butTextFormatArray[0];
						_butTextFormatArray[1] = butTextFormatArray[0];
						_butTextFormatArray[2] = butTextFormatArray[0];
						break;
					case 2:
						//use the same style for up and over, different for down
						_butTextFormatArray[0] = butTextFormatArray[0];
						_butTextFormatArray[1] = butTextFormatArray[0];
						_butTextFormatArray[2] = butTextFormatArray[1];
						break;
					case 3:
						//use different labels for out, over, down:
						//just equate the arrays:
						_butTextFormatArray = butTextFormatArray;	
						break;
					default:
						//if no cases above matched, it means array is no good:
						debugTrace("Error: set butTextFormatArray: Rejecting butTextFormatArray.");
						debugTrace("Error: set butTextFormatArray: Length of butTextFormatArray was " + butTextFormatArray.length);
						debugTrace("Error: set butTextFormatArray: It needs to be betw. 1 and 3");
						break;
					
				}//end switch
			}//end if errorArray.length
		}//end function
		
		/////////////////////////////////////////////////////////
		// For debugging:
		/////////////////////////////////////////////////////////
		
		private function debugTrace(textToTrace:String){
			if (_debugTraceEnabled){
				trace(_debugTraceStartText + textToTrace);
			}//end if
		}//end debugtrace
		
		private function forceTrace(textToTrace:String){
			//this function will always trace, 
			//does not consider _debugTraceEnabled
				trace(_debugTraceStartText + textToTrace);
		}//end forcetrace
		
		private function onlyTrace(textToTrace:String){
			if (_debugTraceEnabled){
				_debugTraceEnabled = false;
				forceTrace(_debugTraceStartText +"_debugTraceEnabled = " + _debugTraceEnabled);
			}//end if
				forceTrace(_debugTraceStartText + textToTrace);
		}//end debugtrace
		
		public function set debugTraceEnabled(debugTraceEnabled:Boolean):void{
			_debugTraceEnabled = debugTraceEnabled;
			forceTrace("_debugTraceEnabled = " + _debugTraceEnabled);
			if (!_debugTraceEnabled){
				forceTrace("Tracing of debug messages will now stop.");
			}
		}
		
		public function get debugTraceEnabled():Boolean{
			return _debugTraceEnabled;
		}
		
	}//end class	
	
}//end package

Open in new window

just to clarify, the place where I want to store the info is inside the createButton() function of the class, almost all the way at the bottom of that function, you will find the text:

// HERE is where I want to store the info
//and attach it to the _tempButHolder Sprite
// HOW?

just to point you in the right direction....
how about creating an array that stores each sprite data and access them by the sprite name or the sprite number.
because you can push an array into another array so each array slot would be an array with all the data for one sprite
ASKER CERTIFIED SOLUTION
Avatar of Dreammonkey
Dreammonkey
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ok i think this sounds promising!

I will try to make these changes.
Thanks alot, I will award the points soon (or ask more) when I know how it worked out!

thankyou!
Thanks for the solution. I did something similar to what you suggested and that works!
thanks.