As3 Movieclip loaded in container reports exaggerated .width value - actionscript-3

I am trying to load a swf(as3) into another As3 Swf with the Movieclip loader. After loading however Loader.width/loader.content.width returns an exaggerated value than the actual width of the swf being loaded. Any pointers on where to begin looking for the discrepancy?
Thanks in advance.
More Details (if it helps)
The swf being loaded has UI components like dropdowns, input boxes and combo boxes (its a Form to fill up), and a coded one-time tween.
When the child MC loads into the parent movieclip, the Loader.width value returned is exaggerated by about 28 pixels (although the height remains the same). Loader.content.width also returns a 28 pixel exaggerated value. The Exaggerated value is more than even the stage width of the child MC. The extra ~30 px are upsetting subsequent code in the parent movie to scale and center the loaded swf.
update:
stage.stageWidth returns the correct Value.
Code used in the parent MC, to load external SWF:
private var deadURL = "child.swf";
private var deadReq:URLRequest = new URLRequest(deadURL);
private var deadLoader:Loader = new Loader();
deadLoader.load(deadReq);
deadLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onDeadLoad);
public function onDeadLoad(e:Event):void
{
addChild(deadLoader);
trace("content.width: " + deadloader.content.width); //returns exaggerated value
trace("width: " + deadLoader.width); //returns same exaggerated value
}

Could you post the code you are using to load the external SWF?
In which method are you reading the width/height value?
Which value do the following code return when executed inside the external swf?
trace(stage.stageWidth);
trace(stage.stageHeight);

If the parent MC is resized i.e. if in the Transform dialog it reads other than 100% then that transformation is passed on to any children.

Related

Handling Editable Objects

Here's the scenario.
A user selects an image, video, or other type of display object. It gets loaded inside a custom class known as EditableObject. The goal of EditableObject is re-sizing and re-positioning. EditableObject has 4 movieclips.
center_mc : Handles drag and drop and contains the display object.
rightside_mc : Handles re-sizing of width on mousedown
bottomside_mc : Handles re-sizing of height on mousedown
bottomright_mc : Handles scaling of object on mousedown
So far I can scale all parts of these objects. The bugs are what's causing trouble.
When I click down on the bottom or right side of the display object, the display object increases size from whichever side it's handling before I move the mouse. I get the amount to move based on the difference of the stageX and stageY positions of the mouse passed on MOUSE_DOWN and at the end of every MOUSE_MOVE. This isn't a problem, it just looks bad and currently solves the second bug..
When I handle bottomright_mc, I can only scale the object down. When trying to scale out, I have to position the mouse outside of EditableObject to get a difference greater than bottomright_mc's current position. This doesn't work because any attempts to exit the bounds of EditableObject trigger MOUSE_UP, even if I add the event listener using this.parent..
I want to be able to re-position and scale anything inside EditableObject using two sides and one corner of EditableObject when a mouse is held down and moved. Currently I can only move the object, scale the object less than its current size, and use the two sides to adjust the objects width and height but without having the mouse match the position of the side it's currently handling on initialization.
Here's an excerpt for the MOUSE_MOVE handler.
private function handleMouseMove(e:MouseEvent):void
{
switch(dragType)
{
case "right":
trace("Right triggered.");
this.width = e.stageX - this.x;
break;
case "bottom":
trace("Bottom triggered");
this.height = e.stageY - this.y;
break;
case "bottomright":
resizeMe(this, e.stageX - this.x, this.height);
break;
}
prevMouseX = e.stageX;
prevMouseY = e.stageY;
}
The full code for the class can be found here on pastebin.
Here's Editable Object in Adobe Flash CC
Here's EditableObject currently containing and handling an image inside the editor.
Based on this answer on stackoverflow provided by TOMATO in the comments, I found a great API that easily lets you handle DisplayObjects with just a few lines of code.
The one I have chosen is senocular's transform tool. A demonstration of his work can be found here. Broken down, this is how to use it.
//Constructor
var editTool:TransformTool = new TransformTool();
//Add to stage (This will not be visible until you give your TransformTool a target)
addChild(editTool);
desiredDisplayObject.addEventListener(MouseEvent.CLICK, handleMouseClick)
function handleMouseClick(e:MouseEvent):void
{
//Set the object clicked as the target for the TransformTool
editTool.target = e.target as Sprite;
//Swap the positioning in the display list so the TransformTool appears in front
editTool.parent.setChildIndex(editTool, editTool.parent.numChildren - 1);
}
You can do this a number of ways, but the basics of it is to simply add the transform tool to the stage and assign whatever display object you would like to the TransformTool.

Bitmap inside a Sprite - But still not clickable? AS3

Basically I've got a bitmap which is an image that the user captures from a webcam which was previously stored as bitmapdata which I converted into a bitmap and added it onto the stage..
From here I want the bitmap to be selectable so I can do other things to it, so I realised I would need to add this into sprite in order to add event listeners onto it.
Having done so, for some reason my application ain't wanting to recognise the events added?
Here is the code I've got..
Bitmap..
//Create a new bitmap from the video capture
image = new Bitmap(bitmap,"auto",true);
//Set the width and height properties
image.width=150;
image.height=125;
//Set the stage position
image.x = 430;
image.y = 280;
stage.addChild(image);
Sprite..
var imageSprite:Sprite;
imageSprite = new Sprite();
imageSprite.x = 200;
imageSprite.y = 50;
imageSprite.addChild(image);
stage.addChild(imageSprite);
Event listener:
imageSprite.addEventListener(MouseEvent.MOUSE_DOWN, SelectWebImage1);
Function:
function SelectWebImage1(e:MouseEvent): void {
trace("Clicked");
}
I receive no errors from this but I noticed that when I have that code written in my application, all of the code underneath it doesn't seem to function?
I really don't know what i'm doing wrong, any help appreciated thanks!
When you set Sprite's dimensions, you implicitly set its scale, and also if you place some graphics by using width and height, the width and height includes any sprite's children, accounting for their position. You should place that bitmap into imageSprite and not set x,y proerties for the bitmap, this way you won't have to account for its position inside the sprite to position the bitmap.

How to add movieclip inside textfield

I would like to add a movieclip to a textfield. The objective is to be able to scroll the movie clip, since the uiscrollbar only works for textfield, i think my solution to scrolling the movie clip is to put it inside a textfield.
I have tried something like:
myText.addChild(myClip);
but failed with error: 1061: Call to a possibly undefined method addChild through a reference with static type flash.text:TextField.
The problem is that a TextField is not a DisplayObjectContainer, so you can't add children.
(The good news is that there are a number of alternate solutions you can find through Google)
You won't be able to add it to a textfield and I'm not exactly sure what you're mean by "scrolling the movie clip" but assuming you have a movieclip that is larger than the area you want to display it, something like this might work:
<s:Group>
<s:Scroller>
<mx:SWFLoader source="#Embed(source='movieclip.swf')"/>
</s:Scroller>
</s:Group>
Sorry if this is a bit of a thread-jack, but I recently had a situation where I needed this type of functionality. And while I'm sure you no longer need an answer to this, I hope that the solution that I came up with will help someone else.
Dear god, why would someone do this?!
In my particular case, I had an extremely long textfield that needed to scroll. In my experience, scrolling by moving the movieclip vertially is unreliable when dealing with extremely long textfields which necessitated that I use the Adobe/Flash uiscrollbar-esk method of adjusting the scrollV of the text field.
This was further complicated by the need for both in-line images which pulled from the library (as opposed to an external source) as well as a black-box border around a section of the text, both of which needed to scroll along with the text.
In a nutshell, one would probably only need to do something like this for a completely self contained swf and under extenuating circumstances (like pharma banners).
Inserting Images From Library:
To accomplish this you need to create a movieclip from an image in the library and export that movieclip for Actionscript. Then, in your code, add something like this:
//This is a string from your textfield that you will replace with an image
var matchForImageSplit:String = 'IMAGE 1 GOES HERE';
//This is the code to replace the above string
//Here, "Image1" is the class name of the exported MovieClip
var imageToAdd:String = '<img src="Image1" />';
my_text.htmlText = my_text.htmlText.split(matchForImageSplit).join(imageToAdd);
Adding the black-box border around text:
This was a bit more tricky. What I had to do was create a MovieClip with a border at the size I needed and give it a name. Then I positioned it behind the text where it was supposed to go, and enclose all of that in a parent_mc movieclip.
I then had to code the box to move along with the scrolling. The below is specific my project, but this is the gist of it:
//THIS CODE IS NON-FUNCTIONAL AND SHOULD ONLY BE USED AS A REFERENCE
//Redundant - just making the example more clear.
var my_text:TextField = parent_mc.my_text;
var borderBox:Sprite = parent_mc.borderBox;
//Vars for calculating position and movement
var borderBoxStartY:Number = borderBox.y;
var incrementRate:Number = my_text.textHeight/my_text.numLines;
var sPos:Number;
var top:Number = dragger.y;
var bottom:Number = (dragger.y + track.height) - dragger.height;
var range:Number = bottom - top;
var ctrl:Number = parent_mc.y; //"parent_mc" is the parent MC that contains the textField and borderBox
function dragScroll():void {
ratio = my_text.maxScrollV/range;
sPos = (dragger.y * ratio) - ctrl;
my_text.scrollV = Math.ceil(sPos);
borderBox.y = ((borderBoxStartY + incrementRate) - (my_text.scrollV * incrementRate));
}
One caveat to note before trying all of this is that when utilizing scrollV, text is moved line-by-line and therefore does NOT scroll smoothly (as it would with position based scrolling). This can result in the scrolling looking "jerky".
EDIT:
I should also note that this was all custom programmed and does not actually utilize the scrollPane/uiscrollbar components, but behaves in the same fashion.

getting movieclip on top of everything else

i have a bunch of movieclips on the stage and some are nested into others, i would like to have 1 of them to be put on top of everything else on the stage when i start dragging it. Anyone know how to get a nested movieclip on top of parents etc?
You could have a top layer & a bottom layer , whenever you want to add a child on top of everything else, simply add the child to the top layer. This way you don't need to figure what the parent position is , just keep this layer on top for that specific purpose.
var topLayer:Sprite = new Sprite();
var bottomLayer:Sprite = new Sprite();
var childMc:MovieClip; // the mc you want to have on top
//somewhere in your code...
childMc.addEventListener(MouseEvent.MOUSE_DOWN , childMcMouseDownListener );
addChild( bottomLayer );
addChild( topLayer );
//add everything to the bottom layer
//leave the topLayer empty until you add the child mc
//add the following code in your MouseDown Listener
function childMcMouseDownListener(event:MouseEvent ):void
{
topLayer.addChild( event.currentTarget );
}
top of everything else on stage:
stage.addChild(target);
warning from AS3 doc :
The command stage.addChild() can cause problems with a published SWF
file, including security problems and conflicts with other loaded SWF
files. There is only one Stage within a Flash runtime instance, no
matter how many SWF files you load into the runtime. So, generally,
objects should not be added to the Stage, directly, at all. The only
object the Stage should contain is the root object. Create a
DisplayObjectContainer to contain all of the items on the display
list. Then, if necessary, add that DisplayObjectContainer instance to
the Stage.
Suppose, Container is your parent movieClip and it has many children then Now your target and currentTarget property depends on which object the listener is attached and how much you have nested your movieclips. in my case the Container is your parent movieClip having two or more children.
Container.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
public function pickUp(param1:MouseEvent) : void
{
var objectToDrag = param1.target;
Container.setChildIndex(param1.target,Container.numChildren-1);
objectToDrag.startDrag(true);
}

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}