ScrollPane doesn't work with dynamic content in as3 - actionscript-3

scrollPane.setSize(400,400);
scrollPane.source=emptyc;
Where emptyc is a container in which I add content dynamically (i.e. by addChild method) doesn't work. It simply doesn't scroll at all.
Neither does work if I add content using scrollPane as a container itself (i.e.:
scrollPane.addChild(myChild);

The problem is the ScollPane instance has no clue you've updated it's content (added a child to emptyc/etc.) so you need to tell it to update().
Here's a basic example:
var b:BitmapData = new BitmapData(2,2,false,0xFFFFFF);
b.setPixel(0,0,0);b.setPixel(1,1,0);
var s:Shape = new Shape();
var sp:ScrollPane = new ScrollPane();
sp.scrollDrag = true;
sp.source = s;
addChild(sp);
s.graphics.beginBitmapFill(b);
s.graphics.drawRect(0,0,1000,1000);
s.graphics.endFill();
sp.update();
Notice that you get the same behaviour you mention if you comment out sp.update();.
Also, there's an example in the documentation.

Related

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.

Optimize ItemRenderer For Flex Mobile Application

I made this class, which is an ItemRenderer class, used in a DataGroup ( mobile application ),
and I am not entirely sure if I did the right thing or not, my issues are :
Is there a better way to show the image, which is 80x80 and directly loaded from the server;
How to make the height of the row dynamic, I mean, depending on the height of the 3 StyleableTextFeild
Is this the right way to add the listener on the image, that will trigger a simple HTTPService,
Here is the functions from the class, Any help would be much appreciated !!
Image
Declared it as a simple image :
var logo:Image;
On override createChildren
logo = new Image();
addChild(logo);
And I added on set Data
logo.source = "http://192.168.0.15:3000/"+value.logo_thumb_url;
Size
override protected function measure():void {
measuredWidth = measuredMinWidth = stage.fullScreenWidth;
measuredHeight = measuredMinHeight = 100;
}
Listener
override public function set data(value:Object):void {
tel.text = String(value.Tel);
description.text = String(value.Descricao);
nome.text = String(value.Nome);
logo.addEventListener(MouseEvent.CLICK, function():void{
var service:HTTPService = new HTTPService();
service.url = value.targer;
service.method = "GET";
// setting headers and other variables ...
service.send();
});
}
You can use URLLoader or Loader for loading the image if you are planning to cache the image on the client side, if you cache the image, it wil help you not load the image again when the users scrolls through the list. (What you have done is Ok, but you will hit performance issues)
For variable row height, if Datagroup does not work, use List. find it here Flex 4: Setting Spark List height to its content height
There should be a buttonMode property for some items, make it buttonMode for the logo, for variable row height, find something related to wordWrap and variableRowHeight properties on the datagroup.
There are a few suggestions, what you have coded is good, but, instead of adding the listeners on set data, add it in creation complete, as it is more appropriate. Also, the event listeners has to be weak referenced, http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/events/EventDispatcher.html#addEventListener()

AS3: Accessing a dynamicaly added child from another dynamicaly added child

So heres my question, I have a button on the stage that adds a MC called "fadeL" and "PDF1"
Quick note: "fadeL" and "PDF1" are instances of "fadeMC" and "PDFwindow" heres the code for them:
var fadeL:fadeMC = new fadeMC();
this.addChild(fadeL);
fadeL.x = 0;
fadeL.y = 0;
var PDF1:PDFwindow = new PDFwindow();
this.addChild(PDF1);
PDF1.x = 30;
PDF1.y = 130;
Within PDF1 is another MC called "PDFviewer" which contains a button called closeBtn
Here is the actionscript for that button:
var container:DisplayObjectContainer = stage.getChildAt(0) as DisplayObjectContainer;
var mc:MovieClip = container.getChildByName("fadeL") as MovieClip;
mc.gotoAndStop(12);
So basicly Im trying to tell "fadeL" to start playing at frame 12 (which ultimately makes it fade off the screen)
but here is the error I get when closeBtn is pressed:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at NovartisTable_fla::PDFviewer_4/closeTap()[NovartisTable_fla.PDFviewer_4::frame1:9]
Any suggestions here? been looking around for other ways to tackle this but all have failed me
-Todd
You're actually grabbing a reference to fadeL when you called stage.getChildAt(0) (assuming the code you are showing is the only time you're adding items to the display list).
Change your button handler to this:
var mc:MovieClip = stage.getChildAt(0) as DisplayObjectContainer;
mc.gotoAndStop(12);
Failing that, I would give fadeL an actual name so you can do the following:
fadeL.name = "fadeL";
...
var mc:MovieClip = stage.getChildByName("fadeL") as MovieClip;
mc.gotoAndStop(12);

AS3: finding an object by it Instance name in a dynamic added child

I am doing an Adobe AIR Kiosk app but I am having a little problem.
First step is to generate a webcam container:
var bandwidth:int = 0;
var quality:int = 100;
var camera:Camera = Camera.getCamera();
camera.setQuality(bandwidth, quality);
camera.setMode(885,575,30,true);
var video:Video = new Video(885,575);
video.attachCamera(camera);
video.name = "camara";
webcam.addChild(video);
It works ok, the problem is that I want to apply to it a custom filter
It works ok if I write it this way:
MovieClip(parent).contenedor_postal.postal.webcam.filters = [filter];
But I want to affect only the child inside the clip "webcam" without affecting other MC's, so I write it like this:
MovieClip(parent).contenedor_postal.postal.webcam.camara.filters = [filter];
and does not work. I used to program in AS2, so maybe the trick is very simple but I can't find anything that works. Thanks in advance!
If the video has a name property "camara" then this should work:
MovieClip(parent).contenedor_postal.postal.webcam.getChildByName("camara").filters = [filter];

flex: Create a screenshot of UI element

I want to make a screenshot of custom as3 ui element (which was extended from Canvas), and then upload the image on the server.
Could you help me with a small example of this?
I am trying to do the following:
// This is UI component extended from Canvas
var chessBoard:ChessBoard = new ChessBoard();
// I displayed pieces on the board, but didn't add it to the stage (I just need a
// a screenshot, not need them on the canvas)
chessBoard.displayPosition(DataStorage.getInstance().getStoredPosition(0));
var img:ImageSnapshot = ImageSnapshot.captureImage(chessBoard, 300, new PNGEncoder());
var obj:Object = new Object();
obj.complexity = complexity.value;
obj.img = img;
httpService.send(obj);
and getting this error:
ArgumentError: Error #2015: Invalid
BitmapData. at
flash.display::BitmapData() at
mx.graphics::ImageSnapshot$/captureBitmapData()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:186]
at
mx.graphics::ImageSnapshot$/captureImage()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\graphics\ImageSnapshot.as:282]
at
ui::SendForm/send()[/Users/oleg/Documents/chess_problems/problemme/src/ui/SendForm.mxml:53]
at
> ui::SendForm/___SendForm_Button1_click()[/Users/oleg/Documents/chess_problems/problemme/src/ui/SendForm.mxml:16]
This error was caused by missing width and height of the Canvas. I set them and it helped to create bitmap data this way:
var bitmapData:BitmapData = new BitmapData(chessBoard.width,chessBoard.height);
var encoder:PNGEncoder = new PNGEncoder();
var data:ByteArray = encoder.encode(bitmapData);
I wonder how do I send the image to the server via httpService? Is there a way. Also is data = image file?
Here is a post on someone who has done this exact thing in AS3:
Dynamically Create an Image in Flash and Save it to the Desktop or Server
It is possible, and although I have never done it, this may be useful to you: http://www.flash-db.com/Tutorials/snapshot/