A Flash Developer Resource Site

Results 1 to 7 of 7

Thread: accessing Parent Movieclip, dispatchEvent

  1. #1
    Member
    Join Date
    Jul 2009
    Location
    Florianópolis
    Posts
    81

    accessing Parent Movieclip, dispatchEvent

    help! i have a menu class that creates a menu dinamically.

    I want the main class (the one that loads the menu) to re- position the menu, but it has to do it after the menu is created so at this point the menu has its final width.

    I ´ve told the menu to dispatch an event but the main class doesn´t listen:

    Code:
    // menu.as:
    dispatchEvent(new Event("MENU_COMPLETED"));
    
    // main.as:
    addEventListener("MENU_COMPLETED", placeMenu);
    private function placeMenu(e:Event):void
    {
         trace ("hello!");    // nothing happens
    }
    i´ve tried to access the main class in the menu but it throws null.

    Code:
    // menu.as
    trace (MovieClip(parent));	// throws null
    trace (parent);	// throws null
    please help! thanks!
    Last edited by ziriguidum; 01-19-2010 at 09:33 AM. Reason: add stuff

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    If parent is null, then you probably have that code in the constructor (or a function called from the constructor), and so the menu is not yet on the stage. If your dispatchEvent call is also in the constructor, then the main class would not have had a chance to add a listener to your menu yet. And since the menu is not on the display list yet, events will not bubble up from it, even if you had set the event to allow bubbling, which you didn't.

    Since you said the menu is loading the content dynamically, I assume that there is some sort of Event.COMPLETE listener in it which builds/sizes the menu. That function should dispatch the MENU_COMPLETED event. You can either allow the event to bubble up, or add your listener in main directly to the menu instance. I recommend the latter.

    main:
    Code:
    var menu:Menu = new Menu("someResource.xml");
    menu.addEventListener(Menu.MENU_COMPLETED, positionMenu);
    addChild(menu);
    
    function positionMenu(e:Event):void{
      //positioning logic goes here
    }
    Menu.as
    Code:
    public static MENU_COMPLETED:String = "MENU_COMPLETED";
    
    public function Menu(url:String){
      //load stuff from url, blah blah blah.
    }
    
    private function loadComplete(e:Event):void{
      //process loaded content, blah blah blah
      dispatchEvent(new Event(MENU_COMPLETED)); //does not bubble, but that's okay.
    }
    In this, there is a ghost of a chance that internal load of the menu content will complete before the listener in main has a chance to be added, so you can add a listener in menu for ADDED_TO_STAGE to see whether it has already finished loading at that time. If it has, just re-dispatch MENU_COMPLETED.

  3. #3
    Member
    Join Date
    Jul 2009
    Location
    Florianópolis
    Posts
    81
    hey! thanks a lot. You´re right, the constructor was calling the function initMenu, which at the end, was dispatching the event.

    I´ve tried to do it the way you did but I runned into some problems so I did it like this in the main class:

    Code:
    		public function criarMenu(e:Event):void
    		{
    			simpleMenu = new SimpleMenu;
    			simpleMenu.addEventListener("MENU_COMPLETED", positionMenu);
    			
    			simpleMenu.criarMenu(menuXmlParser.myXML, 0, cmd - 1, 0);
    			// parameters: xml, offset, cmd, intro delay
    			
    			addChild(simpleMenu);
    		}
    		
    		private function positionMenu(e:Event):void
    		{
    			simpleMenu.x = (simpleMenu.width - stage.stageWidth)/2;
    			// not working right, will check afterlunch
    		}
    and at the simpleMenu class:

    Code:
    		// constructor
    		public function SimpleMenu():void
    		{
    		}
    		
    		public function criarMenu(xml:XML, _offset:Number, _cmd:int, _introDelay:Number):void
    		{
    			buttonMode = true;
    		
    			my_items = xml.children();
    			my_total=my_items.length();
    			
    			offset = _offset;
    			cmd = _cmd;
    			introDelay = _introDelay;
    			
    			initMenu();
    		}
    		
    		public function initMenu():void
    		{
    			for (var i:Number = 0; i < my_total; i++)
    			{
    				var menuItem:MenuItem = new MenuItem();
    				
    				menuItem._title.text=my_items[i].@title;
    				menuItem._title.autoSize= TextFieldAutoSize.LEFT;
    				menuItem._title.antiAliasType=AntiAliasType.ADVANCED;
    				
    				menuItem._title.x = 10;		// magic value!
    				
    				menuItem.hit.width = menuItem._title.textWidth + 30;	// another magic value!
    
    				if (i < my_total -1)
    					menuItem.barrinha.x = menuItem.hit.width;	// another magic value as well!
    				else
    					menuItem.barrinha.visible = false;
    
    				var xItem:Number=0;
    				for (var j:Number = 0; j < i; j++) {
    					xItem += menuArray[j].width + offset;
    				}
    				menuItem.x = xItem;
    				
    				
    				menuItem.linkTo=my_items[i].@link;
    				menuItem.linkType=my_items[i].@type;
    				menuItem.mouseChildren=false;
    
    				//menuItem.alpha=0;
    
    				addChild(menuItem);
    				menuArray[i]=menuItem;
    				
    				menuItem.indice=i;
    
    				menuItem.addEventListener(MouseEvent.ROLL_OVER, rollOverItem);
    				menuItem.addEventListener(MouseEvent.ROLL_OUT, rollOutItem);
    				menuItem.addEventListener(MouseEvent.CLICK, itemClicked);
    
    				if (i == cmd)
    				{
    
    				}			
    			}
    		
    			dispatchEvent(new Event("MENU_COMPLETED"));
    			
    			//introMenu();
    		}
    i´ve got the rollover rollout and clicks also in the simple menu, which I customize for each project. I want to implement a core simpleMenu class that I could use for each project but i don´t know exactly how to do it ... since menus often differs a lot... and my background is design so i´m not really good at programming ... though i´ve been learning lot of stuff lately and i´m getting each time more motivated.

    Thanks a lot for ur explanation it was really helpful!

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    If you have the SimpleMenu constructor separate from the call to process the XML, then adding the listener in between is actually a much better way to go. Good job.

    What sort of problems are you running into now? Is the positionMenu method being called? I think your position code is off a bit. You reversed the order of the subtraction, which will give you a negative x position. Try this:
    Code:
    simpleMenu.x = (stage.stageWidth - simpleMenu.width)/2;

  5. #5
    Member
    Join Date
    Jul 2009
    Location
    Florianópolis
    Posts
    81
    voilà ... another evidence showing me that I shouldn´t code while in a hurry. Thank you.

    About the constructor - i used to have all that code of "criarMenu" function inside the constructor . I don´t remember why.

    Actually, what kind of code one should put in a constructor ? why ?

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    In AS3, try to keep the constructor as simple as possible. Code in the constructor is always run in interpreted mode, instead of compiled, so it's much slower.

    In general, a constructor is for constructing things. Set some property values to defaults or values passed in, maybe call an initializer function if necessary.

  7. #7
    Member
    Join Date
    Jul 2009
    Location
    Florianópolis
    Posts
    81
    wow, really thanks dude!

    i´ll search for examples and improve that little class.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center