I did something similar (experiment). I introduced a mode stack for my morphs. So, all morphs has an initial "default" mode on stack. When mouse enters the morph, a new mode "over" pushed on stack.
So, the "state" is not singular, it is composite. The intent to use stack of modes was to associate a visual style (and any properties , in general for each mode). For example, in default mode, the morph's color is red, but when 'over' mode pushed on stack, it overrides color property with blue. This means, that to get a property, morph asks top-most mode (on stack) if it defines it, and if not, goes to next one, up until default mode, which responds with default value(s) for all properties. Another example, is "disabled" mode.. when this mode is on stack, it prevents "over" mode to be pushed. So, you can imagine, that when morph being dragged, it has "dragged" mode on stack, or if it in some transition (showing sliding/zooming animation), it has "animated mode" and so on. In my experiment i even made a draw method to be a property of mode.. so morph's draw method looks like: drawOn: aCanvas "Draw a morph by using method, supplied by current mode" | method | method := mode styleAt: #drawMethod. ^ self perform: method with: aCanvas like that, i could able to even control how morph is drawn, not just changing the colors. On 6 May 2013 02:31, Carla F. Griggio <carla.grig...@gmail.com> wrote: > Hello everyone! > I'm here to tell you that I started experimenting with a Pharo > implementation of this idea: http://swingstates.sourceforge.net/. For > those into UI programming I really recommend reading the first paper cited > in that page. It's for programming user interface interactions with state > machines, an approach to avoid the classical "callback spaghetti" that > sometimes we get with event handlers everywhere. > > I have a tiny first step that shows an example for changing the color of a > button on mouse over and changing it back to the original color on mouse > out. > > You can download the code from: > http://smalltalkhub.com/mc/CarlaGriggio/StateMachines/main > > Evaluate this for executing the example: > > SMButton openWithStateMachineInteraction > > And here is the code of the state machine for that example: > > SMButton class >> openWithStateMachineInteraction > > |button stateMachine iddle hover | > button := self new. > stateMachine := *SMStateMachine* newForWidget: button. > iddle := (*SMState* newWithName:'iddle') > > enter:[:stMachine | stMachine widget color: Color yellow ]; > > addTransition: ((*SMTransition* forEvent: 'mouse enter' withOutputState: > 'hover') > > transitionAction: [:stMachine | stMachine widget color: Color red ]). > > hover := (*SMState* newWithName:'hover') > > addTransition: (*SMTransition* forEvent: 'mouse out' withOutputState: > 'iddle'); > > addTransition: (*SMTransition* forEvent: 'mouse enter' withOutputState: > 'hover'). > > stateMachine addState: iddle; addState: hover. > stateMachine attachTo: button. > ^button openInWorld > > > That code corresponds to the following states diagram: > > [image: Inline image 2] > > I will keep experimenting with this during the next weeks, and specially > try to compare the pros and cons with regular event handling. > > Something cool about this approach is that the same widget could change > its interactive behaviour on the fly by just attaching a different > interaction state machine to it :) > > Also, I'm doing this for programming user interface interactions, but it > could be useful for anything that can be modelled with a state pattern. > > Is there something similar out there already working? I was so eager to > try this that I didn't look for related existing projects. > > Cheers! > Carla. > -- Best regards, Igor Stasenko.
<<Screen Shot 2013-05-06 at 2.27.20 AM.png>>