This article is for new Revolution developers who have experience with HyperCard and the HyperTalk language, and who want to learn how to leverage their HyperCard knowledge and existing stacks to get a running start in Revolution.
This article is for new Revolution developers who have experience with HyperCard and the HyperTalk language, and who want to learn how to leverage their HyperCard knowledge and existing stacks to get a running start in Revolution.
Since Revolution can read HyperCard stacks, you can start out by converting or re-creating your existing stacks, then extend your work to include the new capabilities available in Revolution.
As an experienced HyperCard developer, youll find Revolutions object model and development environment very familiar. You create objects in a stack window (which can have one or more cards). You write handlers in the Revolution language, whose syntax is very similar to HyperTalk.
Revolution supports all the object types HyperCard does, plus more: buttons, fields, images (bitmaps you can either paint in or display a file in), draw graphics, QuickTime players, and scrollbars. You use the Object Properties palette to change the appearance and behavior of these objects and to edit scripts.
There are some differences between HyperCard and Revolution that you should understand in order to make the port as easy as possible from HyperCard to Revolution.
In HyperCard, each window is a stack, and each stack is a file. In Revolution, each window is still a stack, but a stack file can contain multiple stacks, so you can create a multi-window application in a single file.
Revolution also gives you additional window options. A stack can be displayed as a normal editable window, as a palette, or as a modal or modeless dialog box. This means you can easily create custom palettes and dialogs without using externals, and include them in the same file as your main windows.
Stacks can be resized either using the resize box in the lower left corner or under script control. You can remove the resize box as well as set minimum and maximum sizes for the window.
Use the Geometry Manager feature to have Revolution automatically move and resize objects in the stack when the user resizes the window.
In HyperCard, you place objects in the background layer, and each card with that background displays those objects behind the card objects.
In Revolution, you can use the Group menu item (or the group command) to combine any set of selected objects into a group. Unlike HyperCard backgrounds, groups can be added to any card in the stack, and a card can contain more than one group. Groups can be interleaved with, or in front of, non-grouped objects.
Groups are very flexible. You can select and move a group, show it, hide it, give it borders or scrollbars, and place it on any card or remove it from any card. Like a background, a group can have a script. You can even create a group that contains other groups.
When you create a new card, any groups on the current card are placed on the new card, just like the way HyperCard adds a new card to the current background. However, its important to remember that groups are not backgrounds. In HyperCard, every card belongs to a background. In Revolution, however, cards can exist without having any groups, and the groups belong to the cards theyre on rather than vice versa.
In HyperCard, you create popup menus by setting a buttons style property to popup and placing the menu contents in the button. You change menus in the menu bar using the create menu command, and use the doMenu command to simulate choosing a menu item.
In Revolution, all menus (including menus in the menu bar) are implemented as buttons. Button menus are created in much the same way as HyperCard popup menus. You set the style of the button to menu, and set its menuMode property to specify a pulldown menu, popup menu (called an option menu in Revolution), or combo box. These button menus can be placed anywhere in a stack.
To create a menu bar, you first create a button for each menu, setting the buttons menuMode to pulldown. Then you combine those menus into a group, placed at the top of the stack window. (This is the normal location for menu bars on Unix and Windows systems.)
If you set the stacks menubar property to the name of the group, Revolution displays the groups menus as a normal MacOS menu bar and changes the window size to hide the buttons. This means that the menu bar will appear in the proper place for each platform: on MacOS systems, the menus appear at the top of the screen in the menu bar, while on Unix and Windows systems they appear at the top of the stack window, in accordance with user-interface standards for those platforms.
Use the Menu Manager feature to automatically create and place the buttons for a menu bar, set its appearance appropriately for any platform, and specify keyboard equivalents for its menu items.
Many of the features HyperCard developers have called for over the years are included in Revolution:
In general, limits on size are larger, script execution is much faster, more media formats and object types are supported, and the number of built-in commands, functions, and properties is greater.
While Revolution supports the HyperCard 1.x XCMD model (which means that most XCMDs and XFCNs that dont display a window will work in Revolution without modification), most HyperCard developers find that they rarely need to use externals because equivalents for common externals are already part of Revolution. You can use the Revolution language to rename, move, and delete files; move resources among files; get the contents of a folder; set the cursor location; place a solid backdrop behind your stack; and get URLs, post data to a web server, or communicate directly with other systems on the Internet via sockets. Color is built in, and so is the ability to create and control palettes and dialog boxes. And the Revolution language is fast enough that repetitive tasks that once required externals for speed become practical to implement as handlers instead.
Here are a few specific enhancements you may find interesting:
Theis among operator tests whether a specified chunk exists in a string:
if "Fred" is among the items of "Adam,Fred,George"
then doSomething
Revolution containslineOffset,itemOffset, andwordOffset functions in addition to HyperTalks offset function, so you can find out which line, item, or word contains a specified string.
Chunk expressions can contain negative indexes to count backward from the end of a string. For example,word -2 of myString specifies the second-to-last word.
You can also loop over each chunk in a string:
repeat for each word currentWord in myString
if currentWord is "George" then beep
end repeat
In addition to chunk expressions, Revolution supports the powerful regular-expression syntax via its matchText function. Regular expressions are a method of specifying a text pattern you want to find.
Revolution treats URLs as containers, so you can work directly with the contents of any URL:
put URL "http://www.example.com/file.txt" into field "Text"
put myVar into URL "file:/Disk/Folder/File"
Revolution supports HyperTalksstart using command to let you use other stacks as script libraries. You can also use theinsert script command to place any object not just a stack into the message path, either after all objects or before any objects. A script inserted into the front of the message path can handle a message before the target object itself receives the message.
You can create custom properties for any object. These properties can contain any kind of data, of effectively unlimited length. You get and set them in the same way as built-in properties.
You can set thetextFont,textSize, andtextStyle properties of a card, group, or stack (as well as their color properties). Any object whose text and color properties are not set will inherit the font, size, style, and color of the next object in the message path.
For example, if youset the textFont of a stack to Helvetica, all the objects in the stack will automatically switch to Helvetica (unless youve specified an indepedenttextFont for them).
In Revolution, you can read and write binary files which may contain null characters, ASCII zero. (In HyperCard this is not possible because the null character cannot be handled by HyperTalks data structures.) The ability to read and write binary files and process binary data in variables allows you to create any type of file you wish, as long as you understand the format of the file type. For example, you can create JPEG files by writing the raw data directly to the file.
Revolution supports array variables (variables that contain more than one value). The parts, or elements, of an array can be indexed by number or by any string.
Scan the Revolution Dictionary to explore new language terms.
Revolutions development environment is similar to HyperCards. There is a message box (although the Revolution message box can execute multiple-line structures as well as one-line statements) and a tool palette for working with objects.
To select an object of any type, you use the pointer (arrow) tool, rather than having a different tool for each object type. This means that, for example, you can select several buttons and fields and move them all at once.
You access an objects properties by selecting the object, then choosing Object Properties from the Object menu. The Properties palette contains tabs across the top for basic properties (common to all objects), the objects script, the objects custom properties, and properties specific to the objects type. Some object types, such as buttons, have two tabs.
The script editor is accessed by clicking the second tab from the left on the objects Properties palette. The Revolution script editor accepts styled text, so you can use colors and fonts to emphasize portions of your handlers, mark unfinished code, and so on. To search a script, choose Find and Replace from the Script menu.
Just as in HyperCard, you can test a handler as soon as its written, and use your stack within the development environment. There is no compile step or separate runtime environment needed. However, if you want to test your stack in a clean environment without any of Revolutions own menus, palettes, or other parts of the development environment, you can use the Suspend Revolution UI item in the Development menu. When youre ready to build a standalone application, use the Build Distribution dialog box in the File menu. Here you can create standalone applications for any of Revolutions supported platforms.
The development environmentmenus, palettes, dialog boxes, and allis built entirely in Revolution. This not only demonstrates the power of the Revolution engine, it means that as you advance, there is the possibility of exploring the Revolution user interface and customizing it for your needs.
Revolutions scripting language is called Revolution. Since HyperTalk is one of Revolution's ancestors, almost all your knowledge of how to write HyperTalk code will translate easily.
As in HyperTalk, the script of an object is composed of one or more handlers that respond to messages sent to the object. All the familiar HyperTalk messages are supported (along with new ones), so you can set a buttons script to read
on mouseUp
beep
end mouseUp
and it will react as you expect it to.
As in HyperCard, messages are sent first to the target object, then proceed along a message path containing all the owning objects. For example, if you click a button, theresulting mouseUp message is normally sent first to the button, then to the card the button is on, then to the stack the card is in.
In Revolution, built-in commands and functions do not traverse the message path, but are sent straight to Revolution. This means you cannot override the behavior of a built-in command or function by inserting a handler in the message path. (To create your own functions and commands, use a custom message handler.) However, this means Revolution handlers typically run from five to one hundred times faster than their HyperTalk equivalents. This enormous speed increase means youll find that many computing-intensive tasks that were too slow to be practical in HyperCard are feasible in Revolution.
You can refer to objects by name, number, or ID. As in HyperCard, the ID of objects never changes. (Stacks, which do not have IDs in HyperCard, are the exception. You can change a stacks ID in Revolution.) No two objects in a stack can have the same ID.
Revolution supports all HyperTalk control structures (if/then/else/end if, repeat, pass, send, exit, return) as well as two new ones:
Revolution 1.0 has approximately three times as many commands, properties, and functions as HyperTalk 2.4, so only a few of the new capabilities are discussed in this topic. Refer to the Revolution Dictionary in the Revolution documentation for complete language information.
Revolution can read most HyperCard stacks directly. The basic process for importing a stack is simple:
For the most part, your stacks will be compatible and run properly in Revolution. Possible issues may crop up in these areas:
If any of these issues exist in your stack, to avoid encountering script errors, comment out the handlers involved before you compact your stack and import it into Revolution. For example, you should comment out any code that deals with color, calls an external, or changes the menu bar. After the stack is successfully imported, you can rewrite the affected handlers.
When importing a HyperCard stack, Revolution sets the stacksHCStack property to true. Check this property if you need to know whether a stack originated in HyperCard.
An imported stacksHCAddressing property is automatically set to true, which causes Revolution to assume that references to buttons refer to card buttons and references to fields refer to grouped fields. ThedynamicPaths property is also set to true, which implements HyperCards dynamic path in case your stack depends on that behavior
Revolution has a high level of compatibility with HyperCard, and almost all your knowledge will translate easily. However, there are a few incompatibilities and areas where Revolution offers a different method of doing things. Here are the most common gotchas and some useful tips:
Occasionally, youll need to store data (such as a card modification date) so that its not visible to users, but scripts can access it. In HyperCard, it is common practice to store such data in a hidden field on the card.
In Revolution, you can set a custom property instead. Custom properties can hold any data you want to place in them, are saved with the stack, can be associated with any object, and are used in handlers just like built-in properties.
In HyperCard, commands and functions pass through the message path, so a handler with the same name as a built-in command or function overrides its normal behavior.
In Revolution, built-in commands and functions are executed immediately rather than passing through the message path, so a handler with the same name as a built-in command or function will never be executed.
HyperCard saves changes to stacks automatically. Revolution uses the more usual method of requiring the user to save changes explicitly. (You can also write acloseCard handler to save the current stack automatically when you go to another card if you want to emulate the HyperCard automatic save.)
Since HyperCards Home stack is in the message path of all objects, many HyperCard developers place custom handlers in the Home stack script for easy availability while developing. In Revolution, you accomplish the same thing by placing a stack containing your handlers in the Plugins folder and using the Plugins Editor (in the Development menu) to automatically load it when Revolution starts up. You can create as many plugin stacks as you want, and control when they load, how theyre displayed, and which messages they receive.
When you open a stack file in Revolution, all its stacks are loaded into memory and kept resident until you purge the file. (Use thedestroyStack property to remove files automatically from memory when you close them.) This makes for much faster access, since stacks are pre-loaded in memory and Revolution doesnt need to access the disk when you go to another card.
This also means stack files cannot be too large to fit into memory. If you have a large collection of data in your stack, you may want to split it into multiple stack files, or keep media, such as pictures, videos, and sounds, in external files and display these items in referenced controls. (Files in referenced controls are loaded into memory only when you go to the card the control is on.)
The MacOS date routines (and therefore HyperCard) use midnight, January 1st, 1904 as the beginning of time. Theseconds function counts from this moment. However, since Revolution is cross-platform, it doesnt use the MacOS-specific date. Instead, time begins at midnight, January 1st, 1970 GMT. This will affect your stacks if you store or manipulate the value of the seconds function.
Theticks function in Revolution goes back to the start of the eon, not to the last time the system started up.
Thedate andtime functions and theconvert command always use the U.S. format for dates and times.
Revolution is pickier than HyperTalk about certain minor errors:
Revolution does not assume either the card or background layer when referencing buttons and fields. In other words, you can specifybutton myButton orfield ID 22 and Revolution will find the button or field either on the card or in a group, without needing to be told which.
Its easier and more efficient to use graphic objects instead of paint images for such things as lines and boxes. Instead of using the line tool (which is a paint tool), youll do this by creating a new graphic, either in a script or using the New Control item in the Object menu. You can then set the new graphicsstyle property to specify what shape it should be.
Graphic objects can be easily moved, resized, and changed, either by setting the objects properties in a handler or by using the Properties palette. You should use images only for complex pictures (such as photos) that go beyond simple shapes.
At times you will need to execute one or more commands periodically. In HyperCard, it is common practice to place such commands in an idle handler. In Revolution, you can instead use thesend command to send a message at a specified future time. This means you can place the commands to be executed in a handler, and at the end of that handler, send a message to execute it again after the delay you specify. This example handler beeps once per second:
on annoyUser
beep
send "annoyUser" to me in 1 second
end annoyUser
This approach offers greater efficiency, since Revolution does not need to continually execute an if/then statement in an idle handler to determine whether enough time has passed.
When you need to monitor the mouses position, it is usual in HyperCard to use amouseWithin handler that executes continually while the mouse pointer is within the object. In Revolution, it is more efficient to use amouseMove handler in the objects script to track the mouses motions while the pointer is within the object.
In most applications, the active window holds the current document, and menu commands operate on the active window. In Revolution, because you can open stacks as palettes and dialog boxes, this is not necessarily the case and occasionally the active window is not the frontmost stack. Use thetopStack function anddefaultStack property to control which stack is the active window.
In HyperCard, file pathnames use the MacOS convention of separating levels with a colon, and a file path might look like this: Hard Disk:Folder:File. Revolution uses the Unix style for pathnames, which uses slashes instead of colons, on all platforms to simplify writing cross-platform handlers. The same file path, written Revolution-style, looks like this: /Hard Disk/Folder/File. Revolution translates slashes to colons in pathnames, so if you have a file called And/Or, in a Revolution pathname it becomes And:Or.
Absolute paths begin with a slash and relative paths begin without a slash. The folder that contains the current folder is indicated in a relative path by ../. For example, if the current folder is Folder 1, the path to Folder 2 on the same level is written ../Folder 2/.
Revolutionts visual effect command does not allow the visual effect name to be enclosed in quotes. The statementvisual effect "barn door" does not work in Revolution, though it works in HyperCard.
In HyperTalk, the property that specifies whether a card has been marked for further processing is called the marked property. In Revolution, this property is called themark.
Pressing the Enter key doesnt automatically close the current field. To have the Enter key close a field, insert anenterInField message into an object in the fields message path:
on enterInField
select empty -- closes the field
end enterInField
In Revolution, fields whosesharedText property is false cant have shared text. Instead, set a custom property for the field.
In HyperCard, you use the show titlebar and hide titlebar commands to control a windows title bar. In Revolution, you set the stacks decorations property to control its title bar (and also its zoom box and collapse box).
Since resources are a MacOS-only service, for cross-platform compatibility Revolution uses images to display cursors and icons. You can either hide these images or create a substack in the same file as your main stack to hold them.
In Revolution, a stacks location designates its center, not its top left corner.