calling a function in file1.as from file2.as? - apache-flex

How can I call a function in file1.as from file2.as?
here is the code.
package com.modestmaps
{
import com.modestmaps.overlays.MarkerClip;
import flash.display.Graphics;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.filters.BlurFilter;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.text.TextField;
//import mx.core.Application;
import mx.core.Application;
import flash.events.MouseEvent;
public class InfoBubble extends Sprite
{
private var btn_close:String = "http://(.yada.yada.)/media/close_button.swf";
public var textField:TextField;
public var background:Shape;
public var shadow:Shape;
public var infoClip:MarkerClip;
protected var map:InfoMap;
//var infoClip:MarkerClip;
public var infoBubble:InfoBubble;
public function InfoBubble(urlLink:String)
{
//the name of my markers are set to the links of the swf files in which I want to load into the infobubble
this.name = urlLink;
this.mouseEnabled = false;
this.mouseChildren = true;
this.buttonMode=false;
shadow = new Shape();
shadow.filters = [ new BlurFilter(16, 16) ];
shadow.transform.matrix = new Matrix(1, 0, -0.5, 0.5, 0, 0);
addChild(shadow);
background = new Shape();
addChild(background);
textField = new TextField();
textField.selectable = false;
//the infobubble is still sized according to the textField.width and height
//I don't know how to get the size of the loaded swf
textField.width = textField.textWidth+432+4;
textField.height = textField.textHeight+288+4;
//add main swf
var request:URLRequest = new URLRequest(urlLink);
var loader:Loader = new Loader();
loader.load(request);
addChild(loader);
//position the main swf
//current measurements of swf file w432 h288
loader.y = -288 - 37;
loader.x = mx.core.FlexGlobals.topLevelApplication.LBloaderX;
//add close button
var reqButton:URLRequest = new URLRequest(btn_close);
var loader2:Loader = new Loader();
loader2.load(reqButton);
addChild(loader2);
loader2.addEventListener(MouseEvent.CLICK, closeInfoBubble);
function closeInfoBubble(event:MouseEvent):void
{
infoClip.removeMarkerObject(infoBubble)
infoBubble = null
}
//position the closebutton swf
//current measurements of closebutton swf file w18 h18
loader2.y = -286 - 37;
loader2.x = mx.core.FlexGlobals.topLevelApplication.LBloader2X;
// remember that things in marker clips are positioned with (0,0) at the given location
textField.y = -textField.height - 35;
textField.x = -10;
//I need to find out how to detect the width and height of the swf file loaded into loader2
//instead of the size of the textField
var rect:Rectangle = textField.getRect(this);
// get your graph paper ready, here's a "speech bubble"
background.graphics.beginFill(0x12345);
shadow.graphics.beginFill(0x000000);
for each (var g:Graphics in [ background.graphics, shadow.graphics ] ) {
g.moveTo(rect.left, rect.top);
g.lineTo(rect.right, rect.top);
g.lineTo(rect.right, rect.bottom);
g.lineTo(rect.left+15, rect.bottom);
g.lineTo(rect.left+10, rect.bottom+15);
g.lineTo(rect.left+5, rect.bottom);
g.lineTo(rect.left, rect.bottom);
g.lineTo(rect.left, rect.top);
g.endFill();
}
}
}
}
in this package i am attempting to add the shadow, which works, and then add the infobubble, which works, and then add a main swf which works, and then add a close_button.swf which it does load the swf; however, when I try to add the listener, I am unable to make the infobubble close back up.

Convention typically allows for one .as file per class, so you would need to have a reference to an instantiated object of that class inside the second one.
That said, we need -way- more information to provide any kind of useful answer.

To add to Tegeril's answer: Aside from accessing the functions inside of an instantiated class, you could also (as is the case in a utility class), make the functions static. In this case you could call the method like so: ClassName.methodName(), without the need to instantiate.... my random 2p.

Related

How to distort images (or FXG) in Flex?

I want to distort images (or FXGs) in Flex.
Basically just want to modify the edges of an image like the image below. I know how to make simple distortions but I can't find a way of doing that.
The answers were right... what you need is a DisplacementMapFilter!!
The displacementImage should be grey in general -> means no distortion, and add a white and a gray radial gradient to each lower and upper edgelike this:
And with the Map you go like this:
package {
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.Point;
import flash.net.URLRequest;
public class DistortImage extends Sprite
{
private var sourceImage:Loader;
private var distortMap:Loader;
public function DistortImage()
{
super();
// Loading the Image to be distorted
sourceImage = new Loader();
var requ: URLRequest = new URLRequest("text.jpg");
sourceImage.contentLoaderInfo.addEventListener(Event.COMPLETE, loadMap);
sourceImage.load(requ);
}
private function loadMap( E:Event = null ):void{
// loading distortion map ( grayscale )
distortMap = new Loader();
var requ: URLRequest = new URLRequest("distortMap.jpg");
distortMap.contentLoaderInfo.addEventListener(Event.COMPLETE, applyDistortion);
distortMap.load(requ);
}
private function applyDistortion( E:Event = null ):void{
// get jpg as BitmapData
var bmpData:BitmapData = new BitmapData( distortMap.content.width,distortMap.content.height);
bmpData.draw(distortMap);
// create the filter - notice gray(128,128,128) means no distortion white is negative black is positive distortion
var offsetOfMap:Point = new Point(0,0);
var redChannelCode:uint = BitmapDataChannel.RED; // is not important cause you just need oneway distortion
var yDistortion:int = 20; // strength
var distortFilter:DisplacementMapFilter = new DisplacementMapFilter(bmpData,offsetOfMap,0,redChannelCode,0,yDistortion,DisplacementMapFilterMode.COLOR,0xffffff,0);
// filters need to be included in an array to add on display Object
var filters:Array = new Array();
filters.push(distortFilter);
// adding filter to image
sourceImage.filters = filters;
addChild(sourceImage);
}
}
}

Streaming sound control in Flex (Newbie)

I'm assuming my lack of knowledge (I just started learning Flex yesterday, hah!) is the reasoning behind my inability to figure out how to make this work correctly - it may even just be a code positioning issue.
I've got several MP3 files I'm trying to stream. Right now I'm just trying to start and stop the main MP3. I've got the MP3 successfully playing, but stopping it is the issue I'm having. Here's my current code:
<mx:Script>
<![CDATA[
import flash.events.Event;
import flash.media.*;
import flash.media.Sound;
import flash.media.SoundLoaderContext;
import flash.net.URLRequest;
import mx.controls.Button;
//set current track & load song
var currentTrack:Number = 1;
var song:Sound = new Sound();
var req:URLRequest = new URLRequest("../assets/0"+currentTrack+".mp3");
var context:SoundLoaderContext = new SoundLoaderContext(8000, true);
//CREATE BUTTONS (being loaded in mx:application on load)
private function createControls():void {
var playButton:Button = new Button();
playButton.label = "PLAY";
playButton.id = "playButton";
playButton.addEventListener(MouseEvent.CLICK, clickPlayHandler);
playerControls.addChild(playButton);
var stopButton:Button = new Button();
stopButton.label = "STOP";
stopButton.id="stopButton";
stopButton.addEventListener(MouseEvent.CLICK, clickStopHandler);
playerControls.addChild(stopButton);
}
//HANDLE CLICKS
private function clickPlayHandler(event:Event):void {
var button:Button = event.currentTarget as Button;
song.load(req, context);
song.play();
}
private function clickStopHandler(event:Event):void {
var button:Button = event.currentTarget as Button;
//This is not working...
song.close();
}
]]>
So I've got the song.play working, but the song.close doesn't stop the stream, it does nothing. Any clue how I could do this correctly/what I'm doing wrong?
Thanks! :)
You need to use the SoundChannel class to stop the sound playing, you assign it this way:
private var channel:SoundChannel = new SoundChannel();
//first assign it to the sound variable
channel = sound.play();
//then you can stop your sound this way
channel.stop();

generate screenshot and send it to server (not using FileReference.upload)

Do you have any ideas?
Maybe this can help too, this example creates a BitmapData instance, and then sends that as a ByteArray to the server, (in my case, I was using PHP) ... you'll need to write the server side code, but there's nothing quite special here
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;
import flash.utils.ByteArray;
import mx.graphics.codec.PNGEncoder;
import mx.utils.Base64Encoder;
public class DataUpload extends Sprite
{
private var _loader:URLLoader;
public function DataUpload()
{
// create a bitmap data
var bd:BitmapData = createDummyImage();
var png:PNGEncoder = new PNGEncoder();
var ba:ByteArray = png.encode(bd);
var b64:Base64Encoder = new Base64Encoder();
b64.encodeBytes(ba);
// initialize loader
_loader = new URLLoader();
_loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
_loader.addEventListener(ProgressEvent.PROGRESS, loadProgressHandler);
var request:URLRequest = new URLRequest("http://localhost/YOUR_PHP_SCRIPT_URI");
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.fileData = b64;
variables.fileName = "foobar";
request.data = variables;
_loader.load(request);
}
protected function loadCompleteHandler(event:Event):void {
trace("complete");
}
protected function loadProgressHandler(event:ProgressEvent):void {
trace("progress : ", event.bytesLoaded / event.bytesTotal);
}
private function createDummyImage():BitmapData {
var bd:BitmapData = new BitmapData(300, 300, true, 0x00ffffff);
var shape:Shape = new Shape();
shape.graphics.beginFill(0xff0000);
shape.graphics.drawCircle(10, 10, 10);
shape.graphics.endFill();
bd.draw(shape);
return bd;
}
}
}
Step 1: Use ImageSnapshot to capture the screenshot (I assume we're just talking about the Flash screen, not the OS). This can handle the image encoding for you, or you can capture BitmapData and reencode yourself.
Step 2(a): Use a MultipartLoader to post the generated bytes. Flash security in Flash Player 10 will require the HTTP post to occur on user interaction.
or
Step 2(b): Use a regular URLLoader/URLRequest to post the generated bytes (Base64 encoded, say).

AIR: new window...adding content to it doesnt show up

OK I created a class called WindowManager, so far it just as 1 method, to create a new window. You pass the DisplayObject to it that should be contained in the window. The problem is if I added a newly created display object to the new window it does not show up. However if I first as the new display object to the main window, then try to add it to the new window it works right.
here is this class:
package
{
import flash.display.DisplayObject;
import flash.display.NativeWindow;
import flash.display.NativeWindowInitOptions;
import flash.display.NativeWindowSystemChrome;
import flash.display.NativeWindowType;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.geom.Rectangle;
import flash.display.Screen;
public class WindowManager
{
public function WindowManager()
{
}
public function newWindow(content:DisplayObject):void
{
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.NONE;
windowOptions.type = NativeWindowType.NORMAL;
windowOptions.transparent = true;
var newWindow:NativeWindow = new NativeWindow(windowOptions);
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.bounds = new Rectangle(0, 0, content.width, content.height);
newWindow.title = "New Window Number 2";
newWindow.alwaysInFront = true;
newWindow.x = (Screen.mainScreen.bounds.width - newWindow.bounds.width)/2;
newWindow.y = (Screen.mainScreen.bounds.height - newWindow.bounds.height)/2;
newWindow.stage.addChild(content);
newWindow.activate();
}
}
}
If I call it like this:
var notifierBox:NotifierBox = new NotifierBox();
new WindowManager().newWindow(notifierBox);
The new window will contain nothing..but If I add the dispay object to the main window before trying to add it to the new window it works fine:
var notifierBox:NotifierBox = new NotifierBox();
addChild(notifierBox);
new WindowManager().newWindow(notifierBox);
Can someone tell me why?
Thanks.
http://livedocs.adobe.com/flex/3/langref/flash/display/NativeWindow.html says:
Content can be added to a window using the DisplayObjectContainer methods of the Stage object such as addChild().
You cannot not add Flex components directly to the display list of a NativeWindow instance. Instead, use the Flex mx:WindowedApplication and mx:Window components to create your windows and add the other Flex components as children of those objects. [...]
Maybe you could try the Window class instead of the NativeWindow?

Best way to get the color where a mouse was clicked in AS3

I have an image (mx) and i want to get the uint of the pixel that was clicked.
Any ideas?
A few minutes on the BitmapData LiveDoc Page will take you where you need to go. Once you have your image loaded into a Bitmap variable, you can access its BitmapData property. Add a Mouse Click Event Listener to the image and then use BitmapData::getPixel. The example for getPixel shows how to convert the uint response to an rgb hex code.
Here's a modification of the Example given on the BitmapData page that worked for me (using mxmlc - YMMV):
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
public class BitmapDataExample extends Sprite {
private var url:String = "santa-drunk1.jpg";
private var size:uint = 200;
private var image:Bitmap;
public function BitmapDataExample() {
configureAssets();
}
private function configureAssets():void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
var request:URLRequest = new URLRequest(url);
loader.load(request);
addChild(loader);
}
private function completeHandler(event:Event):void {
var loader:Loader = Loader(event.target.loader);
this.image = Bitmap(loader.content);
this.addEventListener(MouseEvent.CLICK, this.clickListener);
}
private function clickListener(event:MouseEvent):void {
var pixelValue:uint = this.image.bitmapData.getPixel(event.localX, event.localY)
trace(pixelValue.toString(16));
}
}
}
Here's an even simpler implementation. All you do is take a snapshot of the stage using the draw() method of bitmapData, then use getPixel() on the pixel under the mouse. The advantage of this is that you can sample anything that's been drawn to the stage, not just a given bitmap.
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;
stage.addEventListener(MouseEvent.CLICK, getColorSample);
function getColorSample(e:MouseEvent):void {
var bd:BitmapData = new BitmapData(stage.width, stage.height);
bd.draw(stage);
var b:Bitmap = new Bitmap(bd);
trace(b.bitmapData.getPixel(stage.mouseX,stage.mouseX));
}
Hope this is helpful!
Edit:
This edited version uses a single BitmapData, and removes the unnecessary step of creating a Bitmap. If you're sampling the color on MOUSE_MOVE then this is essential to avoid memory issues.
Note: if you're using a custom cursor sprite you'll have to use an object other than 'state' or else you'll be sampling the color of the custom sprite instead of what's under it.
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;
private var _stageBitmap:BitmapData;
stage.addEventListener(MouseEvent.CLICK, getColorSample);
function getColorSample(e:MouseEvent):void
{
if (_stageBitmap == null) {
_stageBitmap = new BitmapData(stage.width, stage.height);
}
_stageBitmap.draw(stage);
var rgb:uint = _stageBitmap.getPixel(stage.mouseX,stage.mouseY);
var red:int = (rgb >> 16 & 0xff);
var green:int = (rgb >> 8 & 0xff);
var blue:int = (rgb & 0xff);
trace(red + "," + green + "," + blue);
}
This is not specific to Flex or mx:Image, and allows you to grab a pixel color value from any bitmap drawable object (provided you have permission):
private const bitmapData:BitmapData = new BitmapData(1, 1);
private const matrix:Matrix = new Matrix();
private const clipRect:Rectangle = new Rectangle(0, 0, 1, 1);
public function getColor(drawable:IBitmapDrawable, x:Number, y:Number):uint
{
matrix.setTo(1, 0, 0, 1, -x, -y)
bitmapData.draw(drawable, matrix, null, null, clipRect);
return bitmapData.getPixel(0, 0);
}
You could easily grab a pixel from the stage or your mx:Image instance. It's a lot more efficient than drawing the entire stage (or drawable object), and should be fast enough to hook up to MouseEvent.MOUSE_MOVE for instant visual feedback.

Resources