CanDo: An Interactive Authoring Tool, Part 3 - Building a Custom Object

by Randy Finch

Welcome to part 3 of what will now be a series of articles about CanDo. As I promised, this installment will cover developing a custom object by combining several standard CanDo objects. In the last part, I discussed using dynamic array variables, documents, and list objects to create hierarchical lists of names as part of a budgeting program entitled SimpleBudget. Now I will discuss a custom object I created to use on several cards in this same program.

The Love of Money

You have probably seen many programs that allow the input of a monetary amount in dollars and cents. Well, I obviously needed this capability in my budgeting program. I call the object I created for this purpose a Monetary Input Object (MIO). The MIO was designed to allow easy keyboard and mouse input. Several standard CanDo objects were combined to create the MIO.

The Ladder of Success

When designing a custom object, a plan is needed to make the development process as easy as possible. Here is my eight-step ladder of success plan:

  1. Decide what the custom object should do and how it should operate
  2. Determine which standard CanDo objects are needed to create the custom object
  3. Decide how the standard objects should be arranged on a CanDo card so the custom object will be user friendly
  4. Create a CanDo card and arrange the standard objects according to step 3
  5. Write the object event routines to give the custom object the appropriate functionality according to step 1
  6. Test and debug
  7. Repeat step 6 as often as needed
  8. If the custom object cannot be made to work as planned, start over with step 1

You may think that I am copping out with this last step. Well, I must admit that I am to some extent; however, any plan that does not allow for starting over in the event that things do not go well is a plan that will fail more often than not.

Climbing the MIO Ladder

Step 1 - I wanted the MIO to be easy to use with both the keyboard and the mouse. In order to avoid the round-off error that can occur when using floating point numbers for monetary values, and given that CanDo has no built-in support for a currency data type, I split the dollars and cents into two separate integer values. I wanted to allow the user to increment and decrement the dollar and cent values using the mouse. However, unlike other programs I have used, I wanted the user to be able to quickly set large values using the mouse without having to wait as the values changed only by one. Therefore, I decided that the increment value should increase as the user continues to hold down the mouse button. Finally, I wanted to have a quick way for the user to clear the MIO to $0.00.

Step 2 - In order to implement the above specifications, I needed the following standard CanDo objects: two TextField objects, one for the dollar value and one for the cent value; four AreaButton objects, two with up arrows and two with down arrows for allowing incrementing and decrementing of the dollar and cent values using a mouse; and one TextButton object for quickly clearing the MIO to $0.00.

Step 3 - Laying out the standard CanDo objects in a user-friendly fashion was rather easy since there seemed to be only one logical way to do it. I decided that the dollar TextField should be to the left of the cent TextField with a slight gap between the two to clearly show that they are separate from each other. A dollar sign ($) should appear to the left of the dollar field to indicate that the input should be a monetary quantity. The four AreaButton objects should be laid out in a two-by-two grid to the right of the cent field with the top two having up arrows on them to indicate incrementing and the bottom two having down arrows to indicate decrementing. The two buttons on the left would be used for changing the dollar value while the two on the right would be used for changing the cent value. Finally, the TextField button for clearing the MIO should enclose the text $CLR to indicate that the monetary value will be cleared. Its position should be flexible so it can be placed according to the layout of the card to which the MIO will be added.

Step 4 - The layout of the MIO on a CanDo card is shown in Figure 1. The details of the card can be found in the Window section of Listing 1 while the details of the objects making up the MIO can be found in the Definition sections of the objects in the same listing (see part II of this article in last month's issue for more detail on reading CanDo source code). The dollar sign ($) to the left of the MIO was put on the screen using CanDo commands in the AfterAttachment event routine near the beginning of Listing 1. The first three lines of code in this routine set the font and print style, and then print the dollar sign. You can get CanDo to write these lines of code for you by selecting the Text Editor Tool (the big A button to the right of the editing window) and selecting the font, style, and text.

Unfortunately, a graphic image cannot be attached directly to an AreaButton object. Rather, the image, which must be an IFF ILBM brush, has to be loaded with the LoadBrush command and then displayed with the ShowBrush command at the appropriate location on the screen. An ImageButton object could be used. This object allows an image to be attached directly to the object; however, no border can be specified. This means that the image itself must also include the button border if it is needed. This is okay if the button size will not be changing during development. If it does change, the image must be edited in a paint program. Since the four increment and decrement buttons needed borders, and I was not sure about the sizing at design time, I chose to use AreaButtons and ShowBrush commands.

The small up and down arrows used on the four AreaButtons are brushes I created in DeluxePaint IV. Their file names are SmallUpArrow.br and SmallDownArrow.br. Figure 2 shows an enlargement of the two brushes so you can easily create these brushes for your program. The last six lines of the AfterAttachment routine load and display these brushes in the four AreaButtons. If you need to move the MIO to a different location on the card, then the X,Y position in the ShowBrush commands will have to be changed. This is also true of the X,Y position for the $ in the PrintText command. The Transparent False command tells CanDo to display any transparent background color that may have been saved with the brush.

Step 5 - The object event routines are shown in Listing 1. Each object that makes up the MIO only has one event associated with it. The two TextField objects each have an OnRelease event routine. OnRelease means that the user has pressed the ENTER key. I will discuss these routines in more detail later.

The four AreaButton objects each have an OnClick routine. Normally an OnRelease routine is used for buttons since this gives the user a chance to change his or her mind about the selection after pressing the mouse button by moving the pointer off of the object before releasing. However, in the case of the increment and decrement buttons, I wanted the cent or dollar value to begin changing when the mouse button is first clicked and continue to change until the mouse button is released. Thus, I used the OnClick routine and increment or decrement the dollar or cent value until the user releases the mouse button. More about this later.

Finally, the TextButton object for clearing the MIO uses the standard OnRelease routine. It simply resets the dollar and cent fields to 0 and 00, respectively.

Step 6 - There were a few problems (dare I call them bugs) with the original implementation of the MIO. The version in Listing 1 is the result of following step 7 of my eight-step ladder of success plan several times.

Step 7 - 'Nuff said in step 6.

Step 8 - My original plan worked well, and I did not have to follow step 8 (he said as he blew on his fingers and stroked them gently on his chest). Luck or skill? I choose the latter.

Figure 3 shows the MIO as part of a more extensive card in my SimpleBudget program. Notice that I changed the relative position of the $CLR button to accommodate the design of the card.

More About the Code

One of the first problems I ran into when writing the event routines for the MIO was associated with the Dollars TextField. You may have already wondered why I did not make this an integer field. Well, I originally did. However, after entering a value in the Dollars field, there was always a trailing space in the field that made the MIO look unnatural. A few tricky techniques could be used to eliminate this problem for dollar values containing more than one digit, but I could not find a way to eliminate the problem for one-digit values. Therefore, I made the field a text field, which created another problem: any character could be input, not just numeric characters. The FormatValue function could not be used because it changes a -0 (for values such as $-0.28) to a 0. There was still a problem with a trailing space at the end of the dollar value. However, because it was a text field, there was a way around this problem. The Dollars field contents could be stored in a temporary variable, the field cleared, and the temporary variable put back in the field. This procedure eliminates the trailing space. (This technique did not work on an integer field with one-digit values.) It works fine from the user's perspective, but it is not a very glamorous solution from the programmer's perspective. INOVAtronics needs to address this problem in a future release of CanDo.

The Cents field was created as a text entry rather than an integer entry to prevent, for instance, a value of five from being displayed as 5 rather than 05 or a zero as a 0 rather than 00. For monetary amounts, the leading zero is always needed for single digit cent values. The FormatValue function could be applied to the Cents field since no -0 values are needed in this field. A single command line could be used to accomplish the appropriate formatting:

	SetText "Cents",FormatValue(TextFrom("Cents"),"00")

An equivalent method without the FormatValue function did not work with the Dollars field because it is right justified and the trailing space was not eliminated.

I will not give you a boring line-by-line description of how the increment and decrement buttons work; rather I will describe how they work from a user's perspective and then let you follow through the code in Listing 1 to see how it was implemented. I decided to limit the MIO to a maximum value of $99999.99 and a minimum value of $-99999.99. This was more than sufficient to cover any amounts I would be using in my budget program.

When the user first clicks on the increment cents button, the value in the Cents field begins incrementing by one. When the cents value reaches a multiple of 10, the increment value is increased to 10, thus allowing the user to more quickly reach the value needed. When the cents value reaches 100, the Cents field is cleared to 00 and the dollar value is incremented by one. When the user releases the mouse button, this process ends. It can be restarted with an increment value of one by clicking on the button once again. The decrement cents button works the same way except it subtracts the increment value. Note that if the dollar value is negative, then the increment cents button must decrement the cents value and the decrement button must increment it. I will leave it to you to determine why this is true.

When the user first clicks on the increment dollars button, the value in the Dollars field begins incrementing by one. When the dollar value reaches a multiple of 10, the increment value is increased to 10. When it reaches a multiple of 100, the increment value is increased to 100, and so on. Of course, as the dollar value approaches the maximum value of 99999, the increment value has to decrease to make sure the maximum value is never exceeded. When the user releases the mouse button, this process ends. It can be restarted with an increment value of one by clicking on the button once again. The decrement dollars button works the same way except it subtracts the increment value.

All of the increment and decrement buttons' event routines have to take special care when the dollar value is near 0. For instance, if the MIO contains a value of $0.00 and the user wants to decrement the cent value by one, what has to happen to the dollar value? If you answered that it must become a -0, then you have answered wisely, grasshopper. A negative one cent is displayed as $-0.01; the negative sign is in the Dollars field.

Reusing a Custom Object

If you need to reuse a custom object on other cards in your CanDo decks, you can create the custom object on a card by itself and then save it to disk as a one-card deck. Later, you can load this deck, move the standard objects making up the custom object to the appropriate place on the card and then add the additional objects needed for the card.

If you need to add a new card containing the custom object to an existing deck, you can load the one-card deck containing the custom object, copy the card using the Copy option in the Mode menu (part of the Main Control Panel), load the deck you wish to add the card to, paste the card containing the custom object to that deck, position the custom object, and then add other objects. The custom object can be added to an existing card containing other objects by copying and pasting each individual standard object making up the custom object.

One feature I would really like to see added to CanDo is the ability to group standard objects together and save them as a custom object for later loading directly to another card. This would allow a person to create custom objects and easily distribute them to other people. Of course, CanDo should allow the object to be placed anywhere on the card without having to rewrite any code. Maybe the next release of CanDo....

Now It's Your Turn

There are several nice features I would like to see added to the MIO custom object. I am challenging you, the reader, to develop the solutions. First, I would like to be able to prevent the user from entering any characters in the Dollars field except the ten digits 0-9 and a leading minus sign (-). Remember, -0 is a legitimate value. The Cents field should only accept the integers 0-9 and should always display its value with two digits such as 00, 07, and 23. A zero should not display as a single 0 or a seven as 7. This is confusing when viewing monetary values. Second, it would be nice if, when the user is entering the dollar amount and presses the period key (for a decimal point), the input field would change from the Dollars field to the Cents field.

If you will send me your solutions to the above challenges care of this magazine, I will choose the best solutions and include them in a future installment of this series of articles about CanDo.

Last Minute Info

Just before submitting this article for publication, I received my CanDo 2.5 upgrade. I plan to discuss the new features of this release in the next installment. So until next time, remember, you CanDo it.


Back to list of articles
Back to Randy Finch's Home Page
Last modified on April 1, 1996
Randy Finch at webmaster@rcfinch.com