PureMVC Architects Lounge

Announcements and General Discussion => Architecture => Topic started by: jgervin on September 17, 2009, 07:01:24

Title: Modes
Post by: jgervin on September 17, 2009, 07:01:24
So I have an app that will have, in the near term two modes, edit and view mode, but could have 3 or 4 more modes in the future.  Really not sure if modes is the correct term, think Photoshop or Illustrator.

The user can click a tool and do certain things in my app so with a hand tool a click might mean to open an object; view mode.

In edit mode, that same click will could be something like add an object.

I am wondering how this fits into Puremvc?  I would rather not put messy conditional logic in giant mediators, so would it be better to create dual mediators? Or is there another way?

My app is huge (think upwards of 1000 UIComponents) and takes some time to start up to render everything, so I don't really want to use the multicore and open a second version of my app for editing.

What are my options?

What about making the mouse pointer/tool be "ALL MIGHTY"?

Think photoshop.

What I mean by almighty is, when you select a tool, the toolmediator recognizes the switch and updates the toolproxy to change the tool value. Then the tool would send out different toolEvents based on its state (aka what kind of tool it is) the toolMediator would thus send out notifications based on the type of toolEvent it receives?

See any downsides to this?  :-\

TIA, Jason

Title: Re: Modes
Post by: puremvc on September 17, 2009, 01:22:46
I would suggest using the StateMachine and devising FSM states for the various modes of the tool. For each State.CHANGED where the state is a tool mode, the ToolMediator would set the mouse pointer to the appropriate icon. And there is no need to store the mode in a proxy, as its an application-wide (or core-wide) state.


Title: Re: Modes
Post by: jgervin on September 17, 2009, 02:10:22
I haven't looked at the StateMachine, but I assume that wouldn't require me conditional statements similar in theory to this?

if(State == Edit){
  handle singleclick one way....
}else  if(State == View){
 handle singleclick another way

Title: Re: Modes
Post by: puremvc on September 18, 2009, 06:45:05
What you would likely do is have a ToolMediator that has a view component that implements an interface like 'ITool'. So all tools expose the same methods and properties and send the same events, they just do things differently.

The Mediator would be interested in StateMachine.CHANGED and in the handleNotification, would have separate cases for the tool modes. In those cases, you'd set the view component to be an instance of the appropriate tool. (and possibly set the mouse cursor here as well).


Title: Re: Modes
Post by: jgervin on September 19, 2009, 07:06:18
That is what I was thinking but then when a mouse click happens would not then have to send the mouse click event to my ApplicationMediator for it to send a notification of a click or in my case I have sprites allover the stage, so a Sprite would hear the click > send an event > SpriteMediator would then decide what to do with the event based on which state the app was in (aka another state object or if/switch) which I would rather not have unless I am missing something?

Is it possible to use the SystemManager or Cursor manager to catch the click or doubleclick or drag event from the cursor itself then the cursor sends out an event say "FingerCursorEvent" and the CursorMediator, which handles all events from all curors, would then dispatch the appropriate notification "ApplicationFacade.FINGERCURSORCLICK" or "ApplicationFacade.SELECTCURSOREVENT" if the select-tool was picked.

fingermouse's click = open thing clicked
zoommouse's click = zoom in 25%
mousepointer click = select to transform
pointer with a + on it = add a new thing to stage
ponter with a - on it = sub a new thing from stage

I guess this all hinges on if the SystemManager can catch the mouse event or if the cursormanager can catch it first?

Title: Re: Modes
Post by: jgervin on September 20, 2009, 12:04:26
When you say "they just do things differently" are you saying as I have asked above that they would dispatch the different click events, which the mediator would sen out different notifications?

Right now in my app, I have eventlisteners on my sprites, these sprites when clicked dispatch events that the mediator gets and the mediator makes changes to the sprites and then send out a notification saying what was changed or simply that a node was clicked (so other thing like menus can change).

But if continue down this path with the new tools, when switching of tools happens it would change the application state. But, then i would need to create state objects (like your ITool, as Gang of Four State Pattern says, for the sprites, menus, callouts, etc...), correct? Then anytime I introduce a new component, sprite class, or other type of class to my project they each would need a new state for each type of tool I create, correct?

I guess with the MegaCursor/SystemManager way I was hoping to prevent what I mentioned in the last paragraph; several types of state objects for each Class.

Title: Re: Modes
Post by: puremvc on September 21, 2009, 05:24:10
No, its not possible to grab the events that way. Dragging and clicking need to be encapsulated in the view component.

The 'tool' selected by the toolmediator would actually be placed on the stage. Faceless, it would listen for the events and do the actions. It would not need to involve notes flyiing aroind the system except when it completes an action or you choose on another tool.


Title: Re: Modes
Post by: jgervin on September 21, 2009, 07:03:47
Ok, thanks.

Title: Re: Modes
Post by: jgervin on September 21, 2009, 08:40:54
@Cliff, one more question.

Lets say you have an app that has two modes Edit and View. No tools this time. And lets say you are using the state machine.

Your app has a containerSprite, a nodeSprite and a lineSprite. When a click happens on a nodeSprite some of the click logic is in the nodeSprite, but some of the logic (for changing things) is in the containerSprite, like adding a Transformtool (resize, rotate, scale, etc...) to container which targets the nodeSprite. See senocular transformtool.

So if the app is in View mode, when a node receives a mouseclick it is highlighted with border and makes a popup show over it with information. In Edit mode things are different, a mouseclick causes the tranform tool to show up and nothing else happens.

So knowing this, where would the state object go? Would you create a IStateNodeMediator and then a viewStateNodeMediator and an editStateNodeMediator (concrete classes) or would you create a InodeSprite and viewNodeSprite and editNodeSprite (concrete classes).

And since the transform tool logic is in the containerSprite Would you create a IconatinerSpriteMediator and then a viewContainerMediator and an editContainerMediator (concrete classes) or would you create a IContainerSprite and viewContainerSprite and editContainerSprite (concrete classes).

Thanks, Jason

Title: Re: Modes
Post by: jgervin on September 21, 2009, 09:06:56
Or would I create an INodeState object and an editNodeState and editViewState objects put those in my nodeMediator. Then just pass all clicks off to what is current State object.


Title: Re: Modes
Post by: puremvc on September 21, 2009, 10:04:21
The StateMachine utility is a Finite State Machine (FSM)1 implementation that handles application- or core-wide state. This differs significantly from view component state. For the latter, you want to implement the State design pattern.2.

The differences in a nutshell:

An FSM defines the discrete states that exist within a system, the valid states that can be transitioned to from each state, and the actions that trigger those transitions.

The State Pattern allows an object to appear to change behavior based on its state. Stateful objects implement an interface for each method varied by state, and they are given a state object that implements the specific behaviors behind those methods.

FSM and the State pattern, though completely different, aren't mutually exclusive approaches to the same problem. The FSM is just more appropriate for application-level state, whereas the State pattern is more appropriate for individual component behavior. That doesn't mean there is never any overlap in the States. It could be useful for there to be application states that overlap with corresponding tool states, especially if a tool requires multiple steps to carry out an action. The application might do things based on the tool state like visually noting what tool is in effect, providing context sensitive help, etc. 

Hope this helps,
1 Finite State Machines: http://en.wikipedia.org/wiki/Finite-state_machine
2 State Design Pattern: http://en.wikipedia.org/wiki/State_pattern