Skip to main content
September 26, 2013
Answered

Having one scroll class for an entire project.

  • September 26, 2013
  • 1 reply
  • 1445 views

Hi

I'm using greensock's blitmask and scrolling in an Air iOS project, and am wondering what the best way is to set it up so you can have one central scroll class that all the classes can add clips to.

Is it doable to have a global model var that holds the movieclip that you want to scroll? ie a class sends one of it's moveiclips to the global var, and the global var dispatches an even to your scroll class, which removes the current MC it's scrolling, and injects the new one from the model?

Or am I going to have to have a new instance of the scroll class in every class that needs scrolling?

Cheers

This topic has been closed for replies.
Correct answer Amy Blankenship

I think you're right that LoginController is the wrong place for this. When I was asking about the end goal, I meant more conceptually what you're trying to accomplish by having this scroller. Without more information that cuts to the heart of that and also more about how your Classes are actually relating with one another, I still can't give you a better implementation than dispatching a custom event with the MovieClip in it.

However, I think that there's a bad design smell about that--why on earth do these controllers and views have references to these MovieClips they're not showing themselves? There has to be some deeper "something" about how these could be made/managed without this awkwardness. Where are these components that you're adding to the scroller when they're not in the scroller?

In the absence of that type of information, I can ony give you an example of how to implement my first (admittedly sort of crap) suggestion.

public interface IEventBusClient {

     function get eventBus():IEventDispatcher;

     function set eventBus(value:IEventDispatcher):void;

}

public class MovieClipEvent extends Event {

     pubic static const SEND_TO_SCROLLER:String = 'sendToScroller';

     public var movieClip:MovieClip;

     public function MovieClipEvent(type:String, mc:MovieClip) {

          super(type, false, true);

          movieClip = mc;

     }

     override publlic function clone():Event {

          return new MovieClipEvent(type, movieClip);

     }

}

public class SomeController implements IEventBusClient {

     protected var _eventBus:IEventDispatcher;

     public function get eventBus():IEventDispatcher {

          return _eventBus;

     }

     public function set eventBus(value:IEventDispatcher):void {

          _eventBus = value;

     }

     protected function invokeScroller(e:SomeEventType):void {

          if (_eventBus && someMovieClip) {

               _eventBus.dispatchEvent(new MovieClipEvent(MovieClipEvent.SEND_TO_SCROLLER, someMovieClip);

          }

     }

}

public class ScrollerController implements IEventBusClient {

    

     protected var _eventBus:IEventDispatcher; 

     protected var _scroller:ActualGreenSockTypeGoesHere;

     public function get eventBus():IEventDispatcher {

          return _eventBus;

     }

     public function set eventBus(value:IEventDispatcher):void {

          if (_eventBus != value) {

               if (_eventBus) {

                    _eventBus.removeEventistener(MovieClipEvent.ADD_TO_SCROLLER, updateScroller);

               }

               _eventBus = value;

               if (_eventBus) { 

                    _eventBus.addEventistener(MovieClipEvent.ADD_TO_SCROLLER, updateScroller);

               }

     }

     protected function updateScroller(e:MovieClipEvent):void {

          //remove old clip using whatever the greensock api says

          var mc:MovieClip = e.movieClip;

          if (mc) {

               //add movieclip to scroller using greensock api

          }

     }

}

You can then set eventBus on instances of these Classes to the display list or to an event dispatcher that you make for the purpose of providing communication. I like to have a separate event dispatcher that serves as a communication backbone in the "data" space (and by that I mean the model and controller classes), but I also will sometimes populate that variable with a reference to the display list or a more local event bus depending on what I'm doing--the thing that makes this technique tremendously powerful is that you can get a lot of flexibility just based on what object you pass in as the event bus.

I think I've made this suggestion before, but in case I haven't, you may want to consider using RobotLetg, since it can automate the process of providing those references.

1 reply

Amy Blankenship
Legend
September 26, 2013

One way you could do it is have your Classes dispatch custom events that have the MovieClip as a property on the event, then a Controller that is listening on the Display list or an event bus that you create for communication hear the event and add it to the scroller.

However, that doesn't seem like the best implementation. It's simply the best I can do with the limited information you've provided. What's the end goal, are the Classes that have references to the MovieClips data Classes or View Classes, and what is their relationship to each other and the application as a whole?

September 27, 2013

Thanks Amy

My end goal...

Have one scroller class that I can send any one of the 30 moveiclips in the project to, and have the old moveiclip in the scroller be replaced. Some of the movieclips are static, and others dynamic, displaying new data retrieved from the server each time.

The classes that reference the movieclips are controller classes.

The problem I encountered was, in order to have just one instance of the scroller class (which happens to be instantiated in LoginController.as), LoginController.as now contains code for the help section, contact page etc... anything that needs scrolling - not good.

I then experimented sending each movieclip to be displayed (after it is dynamically created) to a setter in a common model I've injected into each of the classes constructors, and then trigger the scroller to kick the old MC out, and get this new MC.

Amy Blankenship
Amy BlankenshipCorrect answer
Legend
September 27, 2013

I think you're right that LoginController is the wrong place for this. When I was asking about the end goal, I meant more conceptually what you're trying to accomplish by having this scroller. Without more information that cuts to the heart of that and also more about how your Classes are actually relating with one another, I still can't give you a better implementation than dispatching a custom event with the MovieClip in it.

However, I think that there's a bad design smell about that--why on earth do these controllers and views have references to these MovieClips they're not showing themselves? There has to be some deeper "something" about how these could be made/managed without this awkwardness. Where are these components that you're adding to the scroller when they're not in the scroller?

In the absence of that type of information, I can ony give you an example of how to implement my first (admittedly sort of crap) suggestion.

public interface IEventBusClient {

     function get eventBus():IEventDispatcher;

     function set eventBus(value:IEventDispatcher):void;

}

public class MovieClipEvent extends Event {

     pubic static const SEND_TO_SCROLLER:String = 'sendToScroller';

     public var movieClip:MovieClip;

     public function MovieClipEvent(type:String, mc:MovieClip) {

          super(type, false, true);

          movieClip = mc;

     }

     override publlic function clone():Event {

          return new MovieClipEvent(type, movieClip);

     }

}

public class SomeController implements IEventBusClient {

     protected var _eventBus:IEventDispatcher;

     public function get eventBus():IEventDispatcher {

          return _eventBus;

     }

     public function set eventBus(value:IEventDispatcher):void {

          _eventBus = value;

     }

     protected function invokeScroller(e:SomeEventType):void {

          if (_eventBus && someMovieClip) {

               _eventBus.dispatchEvent(new MovieClipEvent(MovieClipEvent.SEND_TO_SCROLLER, someMovieClip);

          }

     }

}

public class ScrollerController implements IEventBusClient {

    

     protected var _eventBus:IEventDispatcher; 

     protected var _scroller:ActualGreenSockTypeGoesHere;

     public function get eventBus():IEventDispatcher {

          return _eventBus;

     }

     public function set eventBus(value:IEventDispatcher):void {

          if (_eventBus != value) {

               if (_eventBus) {

                    _eventBus.removeEventistener(MovieClipEvent.ADD_TO_SCROLLER, updateScroller);

               }

               _eventBus = value;

               if (_eventBus) { 

                    _eventBus.addEventistener(MovieClipEvent.ADD_TO_SCROLLER, updateScroller);

               }

     }

     protected function updateScroller(e:MovieClipEvent):void {

          //remove old clip using whatever the greensock api says

          var mc:MovieClip = e.movieClip;

          if (mc) {

               //add movieclip to scroller using greensock api

          }

     }

}

You can then set eventBus on instances of these Classes to the display list or to an event dispatcher that you make for the purpose of providing communication. I like to have a separate event dispatcher that serves as a communication backbone in the "data" space (and by that I mean the model and controller classes), but I also will sometimes populate that variable with a reference to the display list or a more local event bus depending on what I'm doing--the thing that makes this technique tremendously powerful is that you can get a lot of flexibility just based on what object you pass in as the event bus.

I think I've made this suggestion before, but in case I haven't, you may want to consider using RobotLetg, since it can automate the process of providing those references.