| command |
(#(File Agents Help about) includes: command)
ifTrue: [^aCommandQuery beEnabled].
command == #saveAgentTape
ifTrue: [^aCommandQuery isEnabled: self tape name isEmpty not].
command == #recordPressed
ifTrue: [^aCommandQuery isEnabled: self tape canRecord].
command == #stopPressed
ifTrue: [^aCommandQuery isEnabled: self tape canStop].
command == #playPressed
ifTrue: [^aCommandQuery isEnabled: self tape canPlay].
command == #pausePressed
ifTrue: [^aCommandQuery isEnabled: self tape canPause].
ifTrue: [^aCommandQuery isEnabled: self tape canConvertToScript].
^super queryCommand: aCommandQuery.
YUCK! If you go searching through the code, you find CommandPolicy, Command, CommandQuery, etc and I thought to myself, "Why did they create so many objects if the code turns out like the above?" The answer is the framework is smart and has a lot of parts to it. So, I browsed the implementers of #queryCommand: and I found an interesting class that implemented it: AbstractMessageSend! Well, the interesting thing is that normally you add commands as symbols to the CommandDescription for things like Buttons and MenuItems. But, you don't have to. You can put any object that understands #forwardTo:! And if you add #queryCommand: to your object to use as your command, then you can allow the command to decide when to enable/disable itself! So, I whipped up a little CommandMessageSend that disables/enables itself by calling a canCommandName method if it exists to know when to disable/enable the command in the menu.
MessageSend subclass: #CommandMessageSend
| canSelector |
canSelector := ('can' , query command selector capitalized) asSymbol.
^(self receiver respondsTo: canSelector)
isEnabled: (self receiver perform: canSelector);
receiver: self receiver.
ifFalse: [super queryCommand: query]
Now, instead of adding a symbol, I add this object. I now no longer override the #queryCommand: method in my Shell class! And the code from above no longer exists! No more case like if statements! It turns out that the Dolphin guys came up with really nice Command framework that works its way from the Command object itself and works it's way asking at each level of Presenters until it reaches the Shell. I can understand doing the simplest possible thing from the examples, but it doesn't show the power that they have given you. There's also a undo/redo framework for your code to take advantage of. Just browse references to the Command class. Fire up those browsers and start looking at that code! Dolphin has a lot of cool frameworks inside (look at DeferredValue for more fun).