views:

90

answers:

2

this is one of those upsurdly basic questions for which google does not work. I have usually dispatched events from my classes and dealt with the user interface in the document class. But now i want to separate all the UI in a separate class, accessible by other classes.

I have added it as a child to the main/document class, but how do i reference the main class without going through parent.parent shananigans?

edit. one more thing i remembered. Some of my UI elements are not programatically added.

here is the code i have. i get possibly undefined property error.

package rpflash.ui {

import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Stage;
import nowplaying;

public class RPUserInterface{

    public function RPUserInterface(){
        var np:nowplaying = new nowplaying();
        MovieClip(this.root).addChild(np);
        }


}   
}
+1  A: 

Root is deprecated in AS3 if I remember rightly; if what you're trying to do there with the np MovieClip is add it to the stage, just a straight-forward this.addChild(np) will do it.

As for referencing stuff in your main Document class from your UI, I assume you're creating the UI class from within Main? If so, the easiest way (though some may point out that you create a strong reference, which could leak memory) is to create a function in your UI class which accepts an object of type Main, and then call this from Main, while passing it itself, like this:

//inside Main
UIclassInstance.setMain(this);

//inside UI class
public function setMain(mainIn:Main):void
{
   main = mainIn;
}

You'll require a member variable in your UI class, of type Main. Like this, you can then access stuff inside Main using main.someObjectInMain;.

Hope that helps,

debu

debu
+1  A: 

you get a possibly undefined error because root is not what it used to be. root is now the programatic base of the structure, stage has taken its place as the holder of display objects, and thus should be referenced for adding children etc.

Stage is a dynamic property that is only given to objects that are on the displaylist. so if you are creating this class programatically this might return a null error if you just change root for stage, because it has not yet been given a stage reference because it hasnt been added to the list. try using the Event.ADDED_TO_STAGE listener if it might not be attached to be sure that stage will not be null.

more to the point is why you are planning to attach things to the stage this way. generally it isnt a wonderful idea as the stage itself will have no reference to the child directly (though you can use getChildByName or getChildAt) and could cause problems with losing references later on. try thinking about either adding the child to the current userinterface or adding a function that will assign some sort of value to the clip being passed, for instance:

public static const PLAY_THIS:String = "the event to play the mc";

public function RPUserInterface(){
    var np:nowplaying = new nowplaying();
    addEventListener(Event.ADDED_TO_STAGE, init);
}

public function getClip():nowplaying{
    return np;
}

private function init(ev:Event):void{
    //If you want it to play immediately, else use mouseEvent etc
    dispatchEvent(new Event(PLAY_THIS));
}

on your main timeline:

var userInt:RPUserInterface = new RPUserInterface();
userInt.addEventListener(RPUserInterface.PLAY_THIS, addFromThis);
addChild(userInt);

private function addFromThis(ev:Event){
    //add a global var ref here if needed.
    var clip = (ev.target as RPUserInterface).getClip();
    addChild(clip);
}

it might seem more complex and a waste of space, but its good practice and a lot easier to make the classes interact like this. its also a lot easier to change on the fly later.

shortstick