Now we have a User Interface and we can give some feedback to the user when they click an operator button. Next we want to get our calculator doing some calculations.

Entering numbers

Similar to the operator buttons the number buttons, including ".", all do the same thing, only the number changes. We will implement a numberPressed command on the Card Script and call it from each of the number buttons, passing the number as a parameter.

Open the Card Script from the Object menu and add this custom command, all this command does is put the pressed number after what is already in the display field.

command numberPressed pNumber
    put pNumber after field "display"
end numberPressed

You can also before a field or into a field, which replaces any text that is already in the field.

Now add a mouseUp handler which calls this custom command to each of the number buttons

on mouseUp
    numberPressed the short name of me
end mouseUp

Testing the Calculator

Now seems like a good time to test your app. Make sure you have saved it first.

Now switch to Run mode(1) in the Tools Palette, this allows you to interact with your app as a user, rather than Edit mode(2), which allows to you edit and modify your app.

Add a button

Try pressing some number and operator buttons to make sure everything is working as expected.

Add a button

Once you are done testing switch back to Edit mode to carry on with development.

The Percentage button

The first operation we will implement is the percentage operation.

Select the "percentage" button, and open its Script Editor by pressing the Code button in the Menubar. Add the following code to the button and apply it, again the button will call a custom command that we will implement on the Card Script.

on mouseUp
    percentagePressed
end mouseUp

Ensure the Card Script is open and add the percentagePressed command to the Card Script.

The percentagePressed command takes the number that is currently in the "display" field and calculates it as a percentage by dividing it by 100 and putting the result into the "display" field.

command percentagePressed 
  put field "display" into tCurrentValue
  put tCurrentValue / 100 into field "display"
end percentagePressed

The Toggle button

The Calculator uses the "toggle" button to toggle the number in the display between positive and negative.

Add the following code to the "toggle" button

on mouseUp
    togglePressed
end mouseUp

To toggle the displayed number between positive and negative we can multiply the number in the "display" field by -1.

Add the following code to the Card Script

command togglePressed
    put field "display" into tCurrentValue
    put tCurrentValue * -1 into field "display"
end togglePressed

The Clear button

Next we want to implement the "clear" button. Again we will add code to the button that will call a command on the Card Script.

Add the following code to the "clear" button

on mouseUp
    clearPressed
end mouseUp

To clear the display we just need to put 0 into the "display" field.

Add the following code to the Card Script

command clearPressed
    put 0 into field "display"
end clearPressed

Now seem like another good time to test the Calculator, save your stack and switch to Run mode.

  • try entering some numbers
  • try getting a percentage
  • try toggling the number
  • try clearing the display

Did you notice any problems?

Did you notice that if you clear the display and then click on more numbers the display always has a leading 0?

There is a simple way to fix this in the numberPressed command, but we need to use an if statement. An if statement allows you to check if a condition is true and then execute different code depending on the outcome.

Our if statement will check whether the "display" field only contains 0. If so it will overwrite the contents of the field, otherwise it will behave as it currently does and put the pressed number after the current contents of the field.

Update the numberPressed command in the Card Script to

command numberPressed pNumber
   if field "display" is 0 then
      put pNumber into field "display"
   else
      put pNumber after field "display"
   end if
end numberPressed

The Equals button

The final, and most import stage of implementing the Calculator is to implement the "equals" button.

When the "equals" button is pressed the calculation the user has entered is processed and the final result is displayed. To get this working there are a number of features we need to add to the calculator

  • when an operator is pressed the calculator need to know which operator has been chosen
  • when an operator is pressed the calculator needs to store the number that is currently in the display so it can be used when "equals" is pressed
  • when "equals" is pressed the stored number, current operator and value in the "display" field are used to do the calculation and the result is displayed

We also need to add some additional functionality to our "clear" button

  • The "clear" button can dislay "C" or "AC"
  • When "AC" is pressed we clear everything, the display, the selected operator and any stored values
  • When "C" is pressed only the current value in the "display" field is cleared, any stored value or operator are saved
  • The label of the "clear" button should change to "C" when a number is pressed
  • The label of the "clear" button should change to "AC" when the "clear" button is pressed

Storing information

Sometimes you want to store information for later use. To do this we use variables.

A variable is a place to store data that you create, which has no on-screen representation. Variables can hold any data you want to put into them. One way to think of a variable is as a box with a name on it. You can put anything you want into the box, and take it out later, by simply providing

the variable’s name:

But unlike some other types of containers, fields for example, variables are non-permanent and aren’t saved with the stack. Instead, variables are automatically deleted either when their handler is finished running or when you quit the application (depending on the variable’s scope).

Variables can have different levels of scope, the scope of a variable describes where is can be used in your code. There are three main levels of variable scope

  • local: A local variable can be used only in the handler that creates it. Once the handler finishes executing, the variable is deleted. The next time you execute the handler, the variable starts from scratch: it does not retain what you put into it the last time the handler was

    executed.

  • scriptlocal: A script local variable can be used in any handler in an object’s script. You cannot use a script local variable in handlers in other objects’ scripts. Unlike a local variable, a script local variable retains its value even after a handler finishes executing.
  • global: A global variable can be used in any handler, anywhere in the application. Unlike a local variable, a global variable retains its value even after the handler that created it finishes executing. Unlike a script local variable, a global variable can be used by any

    handler in any object’s script.

For more on variables see Chapter 5.5 Variables of the User Guide, which can be accessed from the Help menu.

Storing the operator

The first piece of information we want to store is the operator that has been pressed. We will use a script local variable, sCurrentOperator to store the operator.

To create a script local variable we define it at the top of the script, but outside of any handlers. This makes it accessible to all handlers on that script.

Open the Card Script and add this line to the first line of the script.

local sCurrentOperator

This variable can now be referred to anywhere in the Card Script.

We will update our operatorPressed handler to store the chose operator in this script local variable. Add the line

put pOperator into sCurrentOperator

to the end of the operatorPressed handler, now the operator is stored in the variable, ready to be used later.

Storing the current value

When an operator is pressed we store the chosen operator, but we also want to store the current value in the display so that it can be used in the calculation later. We will use another script local variable, sCurrentTotal, to store this value. We also want to know when a new number has been

started, for example after an operator has been pressed, so we will use another script local variable to store whether a number is new or not, sNewNumber.

You can list all the variables you want to define by separating them with commas. Update the first line in your Card Script to

local sCurrentOperator, sCurrentTotal, sNewNumber

There are 3 places we need to record the current total

  • operatorPressed
  • percentagePressed
  • togglePressed

There are 4 places we need to record whether a new number has been started

  • operatorPressed
  • numberPressed
  • percentagePressed
  • togglePressed

We need to update these 4 handlers to store our information in these variables.

command operatorPressed pOperator
   set the showBorder of button "divide" to false
   set the showBorder of button "multiply" to false
   set the showBorder of button "minus" to false
   set the showBorder of button "plus" to false
   
   set the borderColor of button pOperator to black
   set the showBorder of button pOperator to true
   
   ## Store the operator, current total and start a new number
   put pOperator into sCurrentOperator
   put field "display" into sCurrentTotal
   put true into sNewNumber
end operatorPressed
command numberPressed pNumber
   ## Check if a new number is to start
   if sNewNumber is true then
      put pNumber into field "display"
      put false into sNewNumber
   else
      put pNumber after field "display"
   end if
end numberPressed
command percentagePressed 
   put field "display" into tCurrentValue
   put tCurrentValue / 100 into field "display"
 
   ## Store the current total
   put field "display" into sCurrentTotal
end percentagePressed
command togglePressed
   put field "display" into tCurrentValue
   put tCurrentValue * -1 into field "display"
   
   ## Store the current total
   put field "display" into sCurrentTotal
end togglePressed

These three variables will allow us to implement our "equals" button.

Adding code to the Equals button

Now we want to implement the "equals" button. Again we will add code to the button that will call a command on the Card Script.

Add the following code to the "equals" button

on mouseUp
    equalsPressed
end mouseUp

And add a equalsPressed handler to the Card Script.

The equalsPressed command takes the stored total, operator and value in the display field, calculates the result and puts it in the "display" field. It also resets the variables and display ready for the next calculation.

Becase the contents of the "display" field are used as the current total strings of calculations can be done in this way.

command equalsPressed
   ## if no operator has been pressed there is no calculation to do
   if sCurrentOperator is empty then exit pressEquals
   
   ## store the value in the display field
   put field "display" into tCurrentValue
   
   ## check which operator was chosen
   ## perform the calculation using the stored total, stored operator and current value
   switch sCurrentOperator
      case "divide"
         put sCurrentTotal / tCurrentValue into sCurrentTotal
         break
      case "multiply"
         put sCurrentTotal * tCurrentValue into sCurrentTotal
         break
      case "minus"
         put sCurrentTotal - tCurrentValue into sCurrentTotal
         break
      case "plus"
         put sCurrentTotal + tCurrentValue into sCurrentTotal
         break
   end switch
   
   ## put the result into the "display" field
   put sCurrentTotal into field "display"
   
   ## clear the operator button and stored values
   set the ShowBorder of button sCurrentOperator to false
   put empty into sCurrentOperator
   put true into sNewNumber
end equalsPressed

Now try it out! remember to switch to Run mode.

Updating the Clear button

The very last step is to update the "clear" button. At the moment it only puts 0 into the "display" field, but now it needs to do a bit more

  • allow us to clear the current value but retain the stored total and operator
  • allow us to clear everything

This is the difference between the 2 modes of the "clear" button in a calculator. C only clears the current value, AC clears the current value, total and operator.

The first step is to update out clearPressed handler on the Card Script to reflect these 2 modes.

on clearPressed
   ## Clear the current value
   put 0 into field "display"
   
   ## Start a new number
   put true into sNewNumber
   
   if the label of button "clear" is "AC" thencd ..
      ## Clear the stored total
      put 0 into sCurrentTotal
      
      ## Clear the current operator
      if sCurrentOperator is not empty then set the showBorder of button sCurrentOperator to false
      put empty into sCurrentOperator
   else
      ## Change the mode to "AC"
      set the label of button "clear" to "AC"
   end if
end clearPressed

We also need to update the equalsPressed handler to set the mode to AC. Add a line to the end of your equalsPressed handler.

set the label of button "clear" to "AC"

The other time the mode changes is when a number is enetered, this requires an update to the numberPressed handler.

Add the following line to the end of your numberPressed handler.

set the label of button "clear" to "C"

The Completed Calculator

And that’s it, you should now have a fully functional Calculator app. Make sure you save your work and try it out in Run mode.

ArnaudAdding Logic to the Calculator