We will now create the three methods that are called by the button and the menu items that we created earlier. There is no default category for actions, but after you have created one of the methods, you can select "Categorize..." from the context menu and enter "actions" as the category name. Again, to create these methods, right-click in the instance methods list for our "ManHourCalculator" class, and select "New method...". Then enter and accept the code in the editor. Here are the first two methods:
exit "Stop the Smalltalk VM and return to the Palm apps panel." Smalltalk exit. about "Popup an About... dialog box" Form dialog: ##AboutForm.The first method is pretty straightforward. Whenever a user clicks on the "Exit" menu item, the
#exit
method is called, which just tells the Smalltalk virtual machine to exit. The second method calls a class-side method of theForm
class,dialog:
, passing it the resource ID of our aboutForm. This causes the form to display modally, returning to our main screen when the user clicks on the OK button.The final "actions" method is the aspect for our button widget. This is the most involved method in our application. Here is the code (don't enter the line numbers!):
0 calcButtonPressed 1 "Compute the actual number of man-hours to complete a task." 2 3 | totalHours adjustedHours factor | 4 5 (self widgetNamed: #hourField) updateModel. 6 totalHours := Double fromString: self hourFieldModel value. 7 8 factor := #(1.0 1.5 2.0) at: (popupListModel selectionIndex). 9 10 adjustedFieldModel value: totalHours * factor.The first thing we do is declare some temporary variables called
totalHours
,adjustedHours
andfactor
. These will be used in our computations. Line 5 gets a reference to the screen widget called#hourField
and tells it to update its model, which puts the value the user entered into the #hourFieldModel ValueHolder. Once that is done, line 6 gets the new value from that model by calling thevalue
method. Line 8 asks the popupListModel which of its items the user clicked on. This returns an integer index, which we then use to pull a multiplier out of a literal array. This value is then assigned to the temporary variable calledfactor
. If the user selected "Positive", then we will multiply the number of hours they entered in the#hourField
widget by 1.0 (no change) , as the actual number of hours the project will take. If the user selected "Somewhat," then we will multiply the hours the user entered by 1.5. And if the user selected "Not at all", then we will multiply by 2.0. (Amusing, no?) The final step is to update the model for the#adjustedField
textfield so that the "actual" hours for our project will appear in the proper field on the screen. Line 10 does this by multiplying thetotalHours
variable by the factor, and storing that value in theadjustedFieldModel
ValueHolder. By using a ValueHolder for each model, all we have to do is call thevalue:
method and the widget will get and display the new value.The final new instance method we will define is the other half of a dependency relationship. It is the
update:with:from:
. It lives in the "dependents" category and it looks like this:update: anAspect with: aValue from: anObject "Triggered from a model that we asked to send us updates." anObject = popupListModel ifTrue: [self calcButtonPressed].This method will be called when the user clicks on the popup list of choices, and makes a selection. When this method is invoked, we first need to make sure that it came from the component we think it did. Since we only asked one model for updates, the test isn't strictly necessary. If we had asked for updates from several models, then we would need to differentiate each call of this method to determine which action to take. In our case, assuming the invocation came from the popup list model, we will call the
#calcButtonPressed
method. The application will behave as if the user had clicked on the button, and will compute the new hours. Theupdate:with:from:
method in this application is not totally necessary, but I wanted to at least show it. The dependency mechanism in Smalltalk is an incredibly powerful tool.We will now move on to the final steps before generating our Palm app.