The place to learn about your Mac. Tips and tutorials for novices and experts.

Rolling a Revolution Application


We left off last week with having pretty much completed a completely new Revolution stack, named the "San Diego Activities and Coloring Book." There were still a number of issues and more than a few scripting challenges to be resolved. I had assumed, somewhat naively, that the balance of the scripts would not be a great deal different than their HyperCard counterparts. As I dug in to completing them, I found that was not exactly to be the case.

Admittedly, Revolution's scripting language, Transcript, is very much like HyperTalk, HyperCard's scripting language. But, in order to create a stack that may be converted to standalone applications for a number of different platforms, it appears that it is necessary to use handlers that may then call different APIs for the various platforms that display that platform's unique objects; whether they be dialogs or other elements that appear on the screen that have their own unique appearances and methods of doing things. This means selecting handler names that belong to Revolution, but may then, based on the particular platform, call APIs from those platforms. This may not be exactly the way it is done, but the most likely. So, we find many of the keywords are prefaced by the letters "rev," the balance of the name being pretty much the same as it would be in HyperTalk, but not always or consistently. Hence, finding the right call is not always that easy. So here is the script that is being used for the button "File" of group "Coloring Book Menu Bar":

on menuPick pWhich
  switch pWhich
  case "New Coloring Book..."
    ask file "Enter Name for new Coloring Book and show where to place it."
    if it is empty then exit menuPick
    put itemDelimiter into savedDL
    set itemDelimiter to "/"
    put last item of it into stkName
    set itemDelimiter to savedDL
    revCopyFile stkName,it
    go stack it in a new window
    set the name of this stack to quote&stkName&quote
    set the title of this stack to quote&stkName&quote
    break
  case "Open..."
    answer file "Select a Coloring Book to Open" --with type ".rev"
    if it is "Cancel" then exit menuPick
    go it in a new window
    break
  case "Close"
    hide this stack --it's still open, but not visible
    break
  case "Save..."
    get the long name of this stack --Puts stack name and path into it
    revCopyFile (the effective fileName of this stack), it
    break
  case "Save a Copy..."
    answer folder "Select destination folder for backup: "
    if the result is "Cancel" then exit menupick
    revCopyFile (the effective fileName of this stack), it
    break
  case "Page Setup..."
    answer printer
    break
  case "Print Current"
    set the backcolor of this stack to "white" --So we don't get a grayed backgound printout.
    hide group "Coloring Book Menu bar" --We don't want to have the Menu printed.
    -- Not all cards have the scrolling color field with it but for erasing color by whiting it
    if there is a fld "colorlist" and the visible of fld "colorlist" then
      hide fld "colorList"
      hide btn "button"
    end if
    open printing
    if thePaperSize is empty then doPrintThisCard (1224,792),72
    else print this cd
    -- After printing we restore the things we just hid
    show group "Coloring Book Menu bar"
    if there is a fld "colorlist" and not the visible of fld "colorlist" then
      show fld "colorList"
      show btn "button"
    end if
    close printing
    break
  case "Quit"
    put the name of this stack into stkName
    delete first word of stkName
    answer "Are you sure you wish to Quit "&stkName&"?" with "Cancel" or "OK"
    if it is "Cancel" then exit menuPick
    quit
    break
  end switch
end menuPick
 
on doPrintThisCard thePaperSize,theMargin
  -- set up defaults if no size and margin provided:
  if thePaperSize is empty then put the printPaperSize into thePaperSize
  if theMargin is empty then put 72 into theMargin --72 Pixels per inch
  -- get the page area:
  set the printMargins to \
      theMargin,theMargin,theMargin,theMargin
  put theMargin,theMargin, \
      item 1 of thePaperSize - theMargin, \
      item 2 of thePaperSize - theMargin \
      into destinationRect
  --print into that rectangle:
  print this card into destinationRect
end doPrintThisCard

There are still some aspects of the above script that do not work exactly as I would like; particularly the "New Coloring Book" portion. Note that the backslash character is used to continue the previous statement on the next line; and, in some cases, lines. The scripts are automatically indented and colorized, using the Courier Font. I'm still using the defaults for all of these items, but they CAN be changed to suit the users preferences. Where else to set them than the Preferences menu in the Revolution (Application) menu?

But for the ones I mentioned, you'll need to click on the "Script Editor" in the left column above.

As you can see, there are a whole host of Preferences that you may make your own.

I hadn't really intended to show much, if any, of the scripting for this stack, but I've decided that it is important that you see how similar it is to HyperTalk; so the following is the script that may be found in the Stack's script:

on mousemove
-- To easily reset the cursor by moving the mouse to the top
  if the mouseV < 11 then choose Browse tool
end mousemove
 
on openstack
  if the short name of this stack is "About Coloring Book®" \
         then exit openstack
  global gColor,gCyan,gEveningBlue,gGold,gMagenta,gDarkGreen,\
         gYellow, gOrange,gSalmon,gOrchid,gViolet,gBlack,\
         gRed,gSpringFrost,gBlue,gWhite
  put TheColor() into gColor
  repeat with i = 1 to 15
    set the checkMark of menuItem i of button "Color" of the \
         long name of this stack to (false)
  end repeat
  set the checkMark of menuitem gBlack of button "Color" of the\
         long name of this stack to true
 revSpeak "Welcome to " & the short name of this stack
  choose browse tool
end openstack
 
on openCard
  if the short name of this stack is not "About Coloring Book®" then
    if the number of this cd is 3 or 37 then enable button "Edit"
    else disable button "Edit" of the effective name of this stack
    if the number of this cd is 11 then
      repeat with c = 1 to 15
        put "Field "&c into afld
        set  the foreGroundColor of  Field afld  to "Red"
      end repeat
    end if
  end if
end openCard
 
on closeCard
  global gCurrentPicture
    get the number of this cd
  if there is a fld "Music Instructions" and the visible of fld\
  "Music Instructions" of cd it then hide fld "Music Instructions" of cd it
  if it is 3 then
    revStopSpeech
    revUnloadSpeech
  else if it is 13 or it is 32 or it is 33 or it is 34 then
    if gCurrentPicture is not empty then
      doHidePict gCurrentPicture
    end if
  end if
end closeCard
 
on arrowkey theKey
  if target is empty then pass arrowkey
  switch theKey
  case "up"
    go cd 1
    break
  case "down"
    go cd 57
    break
  case "right"
    go next
    break
  case "left"
    go prev
    break
  case else
    pass arrowkey
  end switch
end arrowKey
 
on Enterkey
  global gCurrentPicture
  get the number of this cd
  if it is 13 or it is 32 or it is 33 or it is 34 then
    doHidePict gCurrentPicture
  end if
end Enterkey
 
on doShowPict thePict
  global gCurrentPicture
  if thePict is "Museum of Man" then
    put "My Rectangle 2" into theGraphic
    put "Picture Title 2" into theFld
  else if thePict is "San Diego Museum of Art" then
    put "My Rectangle 3" into theGraphic
    put "Picture Title 3" into theFld
  else if thePict is "Sea World" then
    put "My Rectangle 4" into theGraphic
    put "Picture Title 4" into theFld
  else if thePict is "Mormon National Monument" then
    put "My Rectangle 5" into theGraphic
    put "Picture Title 5" into theFld
  else if thePict is "Lindbergh Field" then
    put "My Rectangle 6" into theGraphic
    put "Picture Title 6" into theFld
  else
    put "My Rectangle" into theGraphic
    put "Picture Title" into theFld
  end if
  put thePict into gCurrentPicture
  put thePict into field theFld
  put " - Click/ENTER Key to close" after field theFld
  show graphic theGraphic
  show field theFld
  show image thePict
  put "This izz thee"&thePict into where
  if thePict is "La Jolla Cove" then put "This is the "\
      & "La Hoya Cove" into where
  if thePict is "Cabrillo National Monument" then put \
     "This is the " & "Cabreyo National Monument" into where
  revspeak where
end doShowPict
 
on doHidePict thePict
  global gCurrentPicture
  hide image thePict
  if thePict is "Museum of Man" then
    put "My Rectangle 2" into theGraphic
    put "Picture Title 2" into theFld
  else if thePict is "San Diego Museum of Art" then
    put "My Rectangle 3" into theGraphic
    put "Picture Title 3" into theFld
  else if thePict is "Sea World" then
    put "My Rectangle 4" into theGraphic
    put "Picture Title 4" into theFld
  else if thePict is "Mormon National Monument" then
    put "My Rectangle 5" into theGraphic
    put "Picture Title 5" into theFld
  else if thePict is "Lindbergh Field" then
    put "My Rectangle 6" into theGraphic
    put "Picture Title 6" into theFld
  else
    put "My Rectangle" into theGraphic
    put "Picture Title" into theFld
  end if
  hide graphic theGraphic
  hide field theFld
  put empty into gCurrentPicture
end doHidePict
 
on mouseup
  choose browse tool
end mouseup
 
function TheColor
  global gCyan,gEveningBlue,gGold,gMagenta,gDarkGreen,gYellow,gOrange\
         ,gSalmon,gOrchid,gViolet,gBlack,gRed,gSpringFrost,gBlue,gWhite
  put 1 into gCyan
  put 2 into gEveningBlue
  put 3 into gGold
  put 4 into gMagenta
  put 5 into gDarkGreen
  put 6 into gYellow
  put 7 into gOrange
  put 8 into gSalmon
  put 9 into gOrchid
  put 10 into gViolet
  put 11 into gBlack
  put 12 into gRed
  put 13 into gSpringFrost
  put 14 into gBlue
  put 15 into gWhite
  return gBlack
end TheColor

The above script is by no means perfect, and there are a number of things that might be done to improve the handlers it contains, but this will have to do for now. Being at the highest level, some of these handlers are called from other places in the stack; such as the Color Menu - see below.

on menuPick pWhich
  global gColor,gCyan,gEveningBlue,gGold,gMagenta,gDarkGreen,gYellow,gOrange,\
         gSalmon,gOrchid,gViolet,gBlack,gRed,gSpringFrost,gBlue,gWhite
  set the checkmark of menuitem gColor of button "color" to (false)
  put empty into gColor
  switch pWhich
  case "Cyan"
    set the checkMark of menuItem gCyan of button "Color" to (true)
    put gCyan into gColor
    break
  case "Evening Blue"
    set the checkMark of menuItem gEveningBlue of button "Color" to (true)
    put gEveningBlue into gColor
    break
  case "Gold"
    set the checkMark of menuItem gGold of button "Color" to (true)
    put gGold into gColor
    break
  case "Magenta"
    set the checkMark of menuItem gMagenta of button "Color" to (true)
    put gMagenta into gColor
    break
  case "Dark Green"
    set the checkMark of menuItem gDarkGreen of button "Color" to (true)
    put gDarkGreen into gColor
    break
  case "Yellow"
    set the checkMark of menuItem gYellow of button "Color" to (true)
    put gYellow into gColor
    break
  case "Orange"
    set the checkMark of menuItem gOrange of button "Color" to (true)
    put gOrange into gColor
    break
  case "Salmon"
    set the checkMark of menuItem gSalmon of button "Color" to (true)
    put gSalmon into gColor
    break
  case "Orchid"
    set the checkMark of menuItem gOrchid of button "Color" to (true)
    put gOrchid into gColor
    break
  case "Violet"
    set the checkMark of menuItem gViolet of button "Color" to (true)
    put gViolet into gColor
    break
  case "Black"
    set the checkMark of menuItem gBlack of button "Color" to (true)
    put gBlack into gColor
    break
  case "Red"
    set the checkMark of menuItem gRed of button "Color" to (true)
    put gRed into gColor
    break
  case "Spring Frost"
    set the checkMark of menuItem gSpringFrost of button "Color"\
        to (true)
    put gSpringFrost into gColor
    break
  case "Blue"
    set the checkMark of menuItem gBlue of button "Color" to (true)
    put gBlue into gColor
    break
  case "White"
    set the checkMark of menuItem gWhite of button "Color" to (true)
    put gWhite into gColor
    break
  case "Browse Tool"
    choose the browse tool
    set the checkmark of menuitem gColor of button "color" to (true)
    exit menuPick
  case "Paint Tool"
    choose the bucket tool
    set the checkmark of menuitem gColor of button "color" to (true)
    exit menuPick
  case "Show Kolor Field"
    set the visible of fld "ColorList" to (true)
    if the tool is not "browse" then choose browse tool
    put "Hide Kolor Field/K" into last line of button "Color" of\
         stack "San Diego Activities and Coloring Book"
    exit menuPick
  case "Hide Kolor Field"
    set the visible of fld "ColorList" to (false)
    put "Show Kolor Field/K" into last line of button "Color" \
         of stack "San Diego Activities and Coloring Book"
    exit menuPick
  end switch
  if gColor is not empty then
    set the brushcolor to pwhich
    set the checkmark of menuitem gColor of button "color" to (true)
  end if
end menuPick

The color menu was done before I realized that an easier way to implement color selection and provide for a greater number of colors at the same time was to put a scrolling field onto each card that was intended for coloring and list all 552 available colors in it. By showing the names of the colors in THEIR colors, the user knows what they are getting - kind of. Some show up pretty faintly, even when the font is enlarged considerably.

After the field was created on the first card on which it would appear, the following script was placed in its script:

on mouseup
  --  get the colornames
  --  repeat with i = 1 to the number of lines in it
  --    put line i of it into line i of me
  --    set the forecolor of line i of me to line i of it
  --  end repeat
  get the value of the clickline
  set brushcolor to it
  choose bucket tool
end mouseup

Note that the first 5 lines are now commented out, so they aren't used anymore. I left them in place in case I mess up and need to recreate the field's contents. If this were actually to be done again, a number of times, then it would have been better to replace the references to the field by "me" with a local variable of some kind; and, then, when the entire list was completed, put the variable into the field. This is a pretty universal approach when manipulating the contents of fields. Do the manipulating in memory (using variables) rather than in the fields.

Once I was satisfied with the appearance and functioning of this field, and had created a button to make selecting the color "white," for the purpose of "erasing" other colors, as easy as possible, I copied the field and the button at the same time and proceeded to cycle through the stack's cards, pasting the copied objects into many, but not all, of them. There was no need to show "where" they were to be placed, since Revolution is smart enough to place them all in the same spot on each of the cards, so long as I don't click anywhere on the cards, which would probably mess things up. I'm going to show just one more script; that of the Music Menu. There are nine preloaded Music clips in a folder named "Music Folder," and the clips have names "Music 1" through "Music 9." Note that you are always taken to the first card to play music. This is how the clips are played:

on menuPick pWhich
  global gPlayer
  if the number of this cd is not 1 then go cd 1
  switch pWhich
  case "About Music"
    set the visible of fld "Music Instructions" to not the visible of \
        fld "Music Instructions"
    put fld "Music Instructions" into temp
    revspeak temp -- The instructions are read to the user
    exit menuPick
  case "Music 1"
    put "Player 1" into gPlayer
    break
  case "Music 2"
    put "Player 2" into gPlayer
    break
  case "Music 3"
    put "Player 3" into gPlayer
    break
  case "Music 4"
    put "Player 4" into gPlayer
    break
  case "Music 5"
    put "Player 5" into gPlayer
    break
  case "Music 6"
    put "Player 6" into gPlayer
    break
  case "Music 7"
    put "Player 7" into gPlayer
    break
  case "Music 8"
    put "Player 8" into gPlayer
    break
  case "Music 9"
    put "Player 9" into gPlayer
    break
  case "Stop Music"
    stop playing gPlayer
    exit menuPick
  end switch
start playing gPlayer -- This is outside of the switch statement
end menuPick

In order for the users to have their own music played, all they have to do is replace the nine files in the Music Folder with audio clips of their own (that have the same names as the ones currently there). You might think this was pretty easy, but there were issues to overcome. Getting this external folder to be recognized required some exploration. I tore what little hair I have nearly out by the roots before I finally discovered the secret. Revolution has a lot of "secrets"! I don't even remember exactly how I managed to solve this problem. It all had to do with "paths." Initially, I tried rolling my own, but then I found that once I had created nine different player objects with the names "Player 1" thru "Player 9," and took a look at their Inspector, there was a little folder icon to the right of where the "path" was to be put that allowed me to browse my hard drive until I located the "Music Folder". See below:

This automatically put the correct "path" into the "source" field on the Inspector. I'm sure that I could get this to work on all of the cards, but this is another one of those group "things" that I really haven't mastered yet; plus it's not that important right now.

Well, that's all I'm going to explain before saving as a standalone application, something I went through successfully a couple of weeks back with my Picture Fonts Stack. I set the "Standalone Application Settings" as I did before, but this time I had some external files (the music clips) that needed to be attached. So when clicking the "Copy Files" icon, the following dialog appeared, though it was empty at the time.

Clicking on the Add File... button allowed me to navigate to the "MusicFolder" and then to select each one of the clips. My only complaint here was that I had to do it nine times since it would not allow me to choose more than one file at a time.

Then I selected "Save as Standalone Application...", but before I did, it was necessary to reopen the Menu Builder from the Tools Menu, so that I could check the "Set as Menu Bar on Mac OS" checkbox. Otherwise, even on the Mac version the Menus would appear at the top of the Card. Unfortunately, doing this lopped off about 40 pixels from the bottom of the cards. Fortunately, I had taken this into consideration at the outset, and that didn't adversely affect the appearance of any of the cards.

After doing this, I decided to build the standalones, since I've just about run out of time for this week's column. After a very short time, during which I noticed that the Externals were being added, the completed application dialog appeared, so all looked well. This was the final Mac opening screen shot:

I transferred the Windows version over to my other Mac, one that has Virtual PC 6 on it. When I transferred the file over to the other Mac, I put it in my "Shared Folder" file. Then, opening VPC, I located the Windows version and noticed that the Externals were all there in an Externals Folder and the About stack was there as well; however, double clicking on the Coloring Book icon immediately produced a dialog that said it had failed to initialize, so I had to quit, and then close VPC6. At this point I decided to present the problem to the RevList for some guidance. After trying a few suggestions, I have come to the conclusion that it is not a Revolution problem, but a Windows problem - probably an incompatibility between XP running under VPC 6 and my hard drives.

As those of you who have experimented with Windows over the years well know, things never work as easily on that platform as they do on the Mac OS. I have yet to check the Mac version to make sure that it works on the new Intel Macs, but I am fairly confident that it will. Be sure to check back next week to see the end - I hope - of this little mystery.



Meet Your Macinstructor

Joe Wilkins is a licensed architect who produces all of his work on Macs (yes, even when all he had to work with was a Mac Plus, floppy disks and a wide carriage dot-matrix printer). He has produced his own "Picture" fonts, programmed 5 commercial applications, and chalked up more than twenty-two years of Mac experience - starting with the Lisa. He also authored the "University of HyperCard" on the original Macinstruct website.


 
                          





Copyright © 2016 Macinstruct. This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.