Copy link to clipboard
Copied
Googling the phrase above gives loads of answers and it looks that what I want to achieve is doable... but still I can't get it to work.
Basically I've build a small class that can be imported anywhere in the program and one of it's public methods dispatch a listener, which as I understand can be received anywhere...
Is that correct?
In my project I've got a menu which slides in and out. It's movement can be triggered mainly bu the buttons on the menu, but I also want to be able to controll it's movement from various places in the program. So ie it can slide in or out when something completely unrelated has been clicked.
So I've got a class "SlidingPanel" and one of its children is class "SlidingPanelNavigation".
SlidingPanelNavigation uses the class that only dispatches the Event, wchich should be listened in class "SlidingPanel" and the problem is - it doesn't.
My code (in a short):
My main class that holds the whole menu together:
package com.zeeto.menu {
import flash.display.MovieClip;
import flash.events.Event;public class SlidingPanel extends MovieClip {
private var navigation :SlidingPanelNavigation;
public function SlidingPanel():void {
... some unrelated code...
}private function prepareMenu():void {
navigation.addEventListener(Event.ADDED_TO_STAGE, menuReady);
}private function menuReady(e:Event):void {
navigation.removeEventListener(Event.ADDED_TO_STAGE, menuReady);
addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
}private function slideMenu(e:Event):void {
trace("Hello World");
}
}
}
The class that holds objects which can trigger the slide in/out movement:
package com.zeeto.menu { import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; public class SlidingPanelNavigation extends MovieClip { private var eventFlag :SlidingPanelEvent = new SlidingPanelEvent; } private function buildItem(menuItem:Array) { ... some unrelated code ... button.addEventListener(MouseEvent.CLICK, clicked); addChild(button); } private function clicked(e:MouseEvent):void { eventFlag.slideMenu(); } }
And finally the class that is some kind of dispatcher:
package com.zeeto.menu {
import flash.events.Event;
import flash.events.EventDispatcher;
public class SlidingPanelEvent extends EventDispatcher {
public static const SLIDE:String = "slideMenu";
public function slideMenu():void {
dispatchEvent(new Event(SlidingPanelEvent.SLIDE, true));
}
}
}
Why the SlidingPanel.slideMenu() isn't fired?
Thanks!
SlidingPanelEvent is not a DisplayObject so the event can't bubble. You'll need to dispatch the event from the SlidingPanelNavigation instance, either directly, or by re-dispatching from SlidingPanelNavigation after receiving the event from the SlidingPanelEvent event
Copy link to clipboard
Copied
Is SlidingPanel instance added to stage? If not - there no stage, thus - no event.
Copy link to clipboard
Copied
Hi Andrei1,
Yes it is added to the stage. It even has addEventListener(Event.ADDED_TO_STAGE, init); in class constructor to make sure it is added before proceeding with the code...
Thanks
Copy link to clipboard
Copied
"It even has addEventListener(Event.ADDED_TO_STAGE, init); in class constructor."
Why do you say "even"? There is no correlation besides event dispatching.
There is no ADDED_TO_STAGE Event listener in SlidingPanel the way you showed it.
How do you add SlidingPanel instance to display list? Is it a document class?
When and how is prepareManu() method is called.
Also, how do you add navigation to display list? Is it on timeline? If so - by the time you add listener to it - it is already on stage and, thus, event is never dispatched.
I suspect that what you indicate as "... some unrelated code ..." is very much related.
Copy link to clipboard
Copied
Ok, so document class adds the SlidingPanel:
package {
import flash.display.MovieClip;
import flash.events.Event;
import com.zeeto.menu.SlidingPanel;
public class Main extends MovieClip {
private var mainMenu :SlidingPanel;
public function Main():void {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
mainMenu = new SlidingPanel(52, 0x000000, 50, true, true);
addChild(mainMenu);
}
}
}
The Sliding Panel in more detail:
package com.zeeto.menu {
import flash.display.MovieClip;
import flash.events.Event;
public class SlidingPanel extends MovieClip {
private var menuHeight :uint = new uint;
private var menuColor :uint = new uint;
private var menuTransparency :uint = new uint;
private var background :Background;
private var logo :Boolean;
private var contacts :Boolean;
private var navigation :SlidingPanelNavigation;
public function SlidingPanel(h:uint, c:uint, t:uint, l:Boolean, a:Boolean):void {
addEventListener(Event.ADDED_TO_STAGE, init);
menuHeight = h;
menuColor = c
menuTransparency = t / 100;
logo = l;
contacts = a;
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
this.y = stage.stageHeight;
background = new Background(menuHeight, menuColor);
addChild(background);
background.addEventListener(Event.ADDED_TO_STAGE, prepareMenu);
}
private function prepareMenu(e:Event):void {
background.removeEventListener(Event.ADDED_TO_STAGE, prepareMenu);
navigation = new SlidingPanelNavigation(structure, menuHeight);
navigation.addEventListener(Event.ADDED_TO_STAGE, menuReady);
addChild(navigation);
}
private function menuReady(e:Event):void {
navigation.removeEventListener(Event.ADDED_TO_STAGE, menuReady);
trace("menuReady");
addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
}
private function slideMenu(e:Event):void {
trace("Slide Event Received");
}
}
}
The "menuReady" trace appears in output, so I believe everything is ok...
I have also used .hasEventDispatcher() and .willTrigger(); to test if listener exists and it does...
Copy link to clipboard
Copied
when I changed the line:
addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
to:
navigation.eventFlag.addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
The event worked out, however the idea is to trigger the event SlidingPanelEvent.SLIDE anywhere in the code, so i can listen for the Event directly from SlidingPanel by either:
addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
or
this.addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
Without attaching the listener to the child.
Hope this all makes sense...Is this possible?
Copy link to clipboard
Copied
SlidingPanelEvent is not a DisplayObject so the event can't bubble. You'll need to dispatch the event from the SlidingPanelNavigation instance, either directly, or by re-dispatching from SlidingPanelNavigation after receiving the event from the SlidingPanelEvent event
Copy link to clipboard
Copied
1. These lines:
background = new Background(menuHeight, menuColor);
addChild(background);
background.addEventListener(Event.ADDED_TO_STAGE, prepareMenu);
make no sense. You expect something to occur that has already happened. Since background is added to to display list - this even will not be dispatched.
It should be (assun=ming that it is valid):
background = new Background(menuHeight, menuColor);
background.addEventListener(Event.ADDED_TO_STAGE, prepareMenu);
addChild(background);
2. These lines are overkill. Since background is added to stage - you just need to call prepareMenu() method. As a matter of fact, all these listeners are overkills and you don need them. Your code should be:
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
this.y = stage.stageHeight;
background = new Background(menuHeight, menuColor);
addChild(background);
prepareMenu();
}
private function prepareMenu():void
{
navigation = new SlidingPanelNavigation(structure, menuHeight);
addChild(navigation);
menuReady();
}
private function menuReady():void
{
trace("menuReady");
addEventListener(SlidingPanelEvent.SLIDE, slideMenu);
}
private function slideMenu(e:Event):void
{
trace("Slide Event Received");
}
Copy link to clipboard
Copied
Sorry for late reply, I had to digest the tips.
Thanks a lot, adding the SlidingPanelEvent to the Display List - of course it helped.
And thanks for the tip about overkilling.