How to get current active stage? - actionscript-3

Is there any way to do something like this?
var text:TextField = new TextField();
text.type = TextFieldType.INPUT;
getCurrentActiveStage().focus = text;

If you have any display object added to the display chain in some way, you can reference it through the stage property. So, if text is already on the stage, just call:
text.stage.focus = text;
If not, you can't access the stage without some reference to it.

You can access stage from any place by FlexGlobals.topLevelApplication.stage

Related

How can I remove this child image Flash / AS3

Following tutorials I managed to cobble the following together that imports an image from an external XML file.
But how do I remove it?
I've read up on removeChild but it looks like it needs to have a ref passed to it and I'm not sure what that ref is. I've tried a few things that I thought it might be, including (image) but all of them throw up Access of undefined property errors.
This is the code I'm using to import :
var imgrequest:URLRequest = new URLRequest(artwork);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_loadComplete);
function on_loadComplete(e:Event):void {
var image:DisplayObject = loader.content;
image.x = 0;
image.y = 4;
image.width = 150;
image.height = 150;
addChild(image);
Bitmap(image).smoothing = true;
}
loader.load(imgrequest);
What do I need to do to remove it?
When you declare a variable inside a set of curly brackets, that variable only exists within those brackets. So when you try to remove the image (which DOES still exist outside the curly brackets) using that variable... no dice.
So you need to find a way to store that image with a method that results in a more permanently accessible object such as a global variable or putting it in an array (which is likewise stored globally). Now you can do
image.parent.removeChild(image);
or if it's in an array
array[ind].parent.removeChild(array[ind]);
where ind is the index of that array element you want to remove.
After using addChild(image); does later on using removeChild(image); not work?
Also try declaring var image:DisplayObject; outside of any functions (now can be universal to all functions) then in your on_loadComplete the first line can simply be image = loader.content;. Also removeChild will understand image when it's used later in another function.

AS3 How to keep text box in one frame

I'm trying to add a few text boxes so that people can select text and copy it to their clipboard.
I wrote the following, but the problem is that the text box stays through all the frames after it's been accessed and I just want it to stay in that frame. Do I have to set them on invisible elsewhere? How come other frames even have access to this code?
Any solutions? Thanks!
stop();
var myFont = new fontCandy();
var myFormat:TextFormat = new TextFormat();
myFormat.size = 10;
myFormat.font = myFont.fontName;
myFormat.color = 0xFFFFFF;
var myText:TextField = new TextField();
myText.defaultTextFormat = myFormat;
myText.embedFonts = true;
myText.antiAliasType = AntiAliasType.ADVANCED;
myText.text = "my#email.com";
addChild(myText);
myText.border = true;
myText.wordWrap = true;
myText.width = 100;
myText.height = 15;
myText.x = 70;
myText.y = 185;
In FlashPro, anything done in code is not subject to timeline keyframes. Something done in code will persist until it's scope (the timeline it's on) is unloaded or you've explicitly cleaned it up via code. (though certain things can keep your objects in memory even after this).
This also includes display objects that originated on the timeline (not through code) but have had their parentage or positioning manipulated via code (so if you use addChild/setChildIndex on a timeline object)
You have to explicitly remove it by using removeChild(instanceOrVarName);
So in your case: removeChild(myText); will remove that text field.
So, to sum it up:
Things done through code must be cleaned up through code.
Here are a few options for you to explore:
call removeChild(myText) on the very next frame
listen for the ENTER_FRAME event and check if the playhead has moved, if so then do removeChild(myText) and remove the listener.
on the frame you have this code, put a text field on the stage (just on that frame), give it an instance name of myText, then keep the code you have except for the new TextField() line, and the addChild line. This should make it do what you want but also let it be removed on the next frame.

Why can't set "defaultTextFormat" directly?

for example,we can set graphics of a shape directly(without creating an external Graphics variable):
var my_shape:Shape=new Shape();
my_shape.graphics.beginFill(0);
but that's not same as defaultTextFormat
the below code doesn't work:
var my_text:TextField=new TextField();
my_text.defaultTextFormat.size=47;
typing dot after defaultTextFormat,the code hint of text format appears and there is no compiler error but still doesn't work
we must create an external TextFormat variable:
var my_text:TextField=new TextField();
var my_format:TextFormat=new TextFormat();
my_format.size=47;
my_text.defaultTextFormat=my_format;
but why can't set directly?
I don't like a lot of variables.
after that,explain the difference between textFormat and Graphics.
Thanks for your help.
When you access/read a TextField's defaultTextFormat property (which is what's happening in the line my_text.defaultTextFormat.size=47;), you end up getting a whole new object returned. Eg, it creates a new TextFormat and returns that.
Here is an example to illustrate:
var tf:TextFormat = new TextFormat();
textField.defaultTextFormat = tf;
trace(tf == textField.defaultTextFormat) //false
The TextField doesn't know anything about the TextFormat it returns from defaultTextFormat. So when you change it, it doesn't update anything automatically because it has no scope inside the TextField that generated it.
In order to see the change, you have to reassign the whole object, and
then reassign the text (if you've already set the text).
This unfortunately means you'll have do it like in your second example.
It's probably some kind of an efficiency thing under the hood to help prevent memory leaks and the like.
Here are some examples to consider further:
var txt:TextField = new TextField();
addChild(txt);
var tf:TextFormat;
txt.text = "hi"; //default formatting;
tf = txt.defaultTextFormat; //get the default formatting, which actually returns a brand new object
tf.color = 0xFF0000; //make it red;
//nothing has changed visually
txt.defaultTextFormat = tf; //this won't update it either
//nothing has changed visually
txt.text = txt.text; //now that we've 'changed' the text, you'll see red
my_text.defaultTextFormat = my_format;
my_format is the defaultTextFormat of your textField my_text. defaultTextFormat is a property of your TextField (which value is my_format).
my_format.size = 47;
47 is the size of your TextFormat my_format. size is a property of your TextFormat (which value is 47).
my_text.defaultTextFormat.size = 47;
...but size has never been a property of a defaultTextFormat.
So you cannot put properties directly on the defaultTextFormat. What
you need to do is to make a text format, set the properties, THEN set
defaultTextFormat = myTextFormat.
Adobe help about defaultTextFormat.

Edit movie clip definition as3

I'm a bit new to as3, so forgive me if these are dumb questions. Two questions...
Premise:
I'm loading a character from a swf file, and want to add avatar to it. I have him animated walking and also standing (stand_mc, walk_mc). I also have his body parts separated out, so inside each of the animations mc's is a head_mc, body_mc, etc etc.
First question, how can I access the body parts for any animation? here's my code so far:
var WalkAnim:Class = SWFLoader.getClass('walk_mc'); //Using Greensock loader; but it's the same as using appDomain.getDefinition();
var walkAnim:MovieClip = new WalkAnim();
addChild(walkAnim);
Second question, adding walkAnim just creates an instance of the mc definition. How can I edit the definition in the library to do something like..
var Hat:Class = SWFLoader.getClass('accessory_hat_mc');
var hat = new Hat();
WalkAnim:addChild(Hat)//???
So that if I have multiple instances on stage, they'll all be updated. Thanks in advance for the help!
Basically, to access child elements, you use dot syntax. That would look something like this (last line):
var WalkAnim:Class = SWFLoader.getClass('walk_mc');
var walkAnim:WalkAnim = new WalkAnim(); // I have typed your var as WalkAnim, not MovieClip.
addChild(walkAnim);
walkAnim.head_mc.rotation += 5;
To answer your second question, you wont be able to edit the definition at runtime. You can add an item to each instance though:
var Hat:Class = SWFLoader.getClass('accessory_hat_mc');
var myHat:Hat = new Hat();
walkAnim.head_mc.addChild(myHat);

ActionScript 3 name property is not returning the right name...?

I experienced a problem with the name property in as3, I created this "dot" movieclip and I exported to a class,
then I anonymously created a bunch of dots using a loop. I assigned numbers as name to each dots
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
dotContainer.addChild(d]);
}
}
so far so good, I checked that if I trace the name here, I will get the number I want.
However, it's not giving me the numbers if I trace it in other functions.
I added all of my dots to "dotContainer", and if I click on one of the dots, it will call this function
private function callFullSub(e:MouseEvent):void
{
var full_loader:Loader = new Loader();
var temp:XMLList = subImages[sub];
var full_url = temp[e.target.name].#IMG;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);
}
e.target.name is suppose to be numbers like 1 or 2, but it's giving me "instance66" "instance70" and I
have no idea why. Because I did the same thing with loaders before and it totally worked.
Any ideas? Thanks.
christine
The e.target returns the inner most object clicked on, this could be a TextField, another MovieClip or posibly a shape (I'm not 100% of the last one) inside the "Dot".
To prevent this you could try to set the mouseChildren property to false on the Dot's when you add them. This should insure that nothing inside the dots can dispatch the click event, and thus the Dot's should do it.
Perhaps you could also in the event handler verify the target type with code like this:
private function callFullSub(e:MouseEvent):void
{
if(!e.target is Dot)
throw new Error("target in callFullSub is not Dot but: " + e.target.toString());
//The rest of you code here
}
The answer is [e.currentTarget.name] I perform this all the time!
Should return "Dot1" "Dot2", etc.
If the value you wish to return is a number or other data type other than a string (name of object) use [e.currentTarget.name.substr(3,1).toString()]
Should return 1, 2, etc.
Navee
I tried to reproduce your problem first with Flex using runtime created movieClips and then with Flash using Dot movieClip symbols exported for ActionScript. Neither application exhibited the problem.
You may already know names like "instance66" "instance70" are default enumerated instance names. So, whatever is dispatching the MouseEvent is NOT the dot instance. Perhaps you are unintentionally assigning callFullSub to the wrong targets, maybe your containers? Try assigning it to dot instance right after you create them, like this:
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
d.addEventListener(MouseEvent.CLICK, callFullSub);
dotContainer.addChild(d]);
}
}
Be sure to temporarily comment out your original assignment.
Try this might work,..
d.name = i.toString();
You have not shown enough of your code for me to be able to give you a DEFINATE answer, I will however say this.
//After you create each loader you need to set its mouseEnabled
//property to false if you do not want it to be the target of
//Mouse Events, which may be superseding the actual intended target;
var full_loader:Loader = new Loader();
full_loader.mouseEnabled = false;
//Also you could name the loaders and see if what comes back when you click is the same.
ALSO! Add this to your Mouse Event handler for CLICK or MOUSE_DOWN:
trace(e.target is Loader); //If traces true you have an answer
I believe that the mouse events are being dispatched by the Loaders.
please provide more of your code, the code where the Loader.contentLoaderInfo's COMPLETE handler fires. I assume this is where you adding the loaders to the display list as I cannot see that now.