HyperActive Software

Home What's New Who We Are What We Do Solutions Resources

We make software for humans. Custom Mac, Windows, iOS and Android solutions in HyperCard, MetaCard, and RunRev LiveCode


Converting a HyperCard stack to LiveCode

Editing the stack script and revising menus

The stack script contains handlers that create and delete cards. We commented out these handlers in HyperCard because they contain menu commands that LiveCode does not recognize. We are going to change those handlers to work with the new menus now.

We want to be able to use the card management handlers from the File menu button, but we neglected to include either a "New Card" or a "Delete Card" menu item when we built our initial menu group. We are also going to need a "Print Stack" command, which we'll change slightly to say "Print Records". We will add those items now.

Open the Menu Builder and click the "Edit" button. Choose "Menubar 1" to load the menu group into the Menu Builder. Insert these three lines at the top of the File menu items list (the third line is a hyphen):

&New Card/N
&Delete Card
In addition, after the Print Card menu item, add a new line:
Print &Records
Now edit the script of the File menu button. Change the menuPick handler to this:
on menuPick pWhich
  switch pWhich
  case "New Card"
  case "Delete Card"
  case "Save"
    save this stack
  case "Page Setup"
    answer printer
  case "Print Card"
    if the short name of this bg = "records"
    then print this card from "0,26" to "512,368"
    else beep
  case "Print Records"
  case "Quit"
  end switch
end menuPick
By the way, it isn't necessary to place the case statements in the same order as the menu items. It does makes them easier to locate in the script though.

The Print Stack menu item

In the HyperCard stack, users who wanted to print out the entire set of records could choose the "Print Stack" menu item and print only the marked cards. Since LiveCode has no built-in printing engine, we will write our own records-printing handler. While we're still in the File menu button script, add the following new handler at the end:

on printRecords
  answer "Print all records in this stack?" with "Cancel" or "Print"
  if it is "cancel" then exit to top
  push cd
  repeat with x = 1 to the number of marked cds
    go marked cd x
    print this card from "0,26" to "512,368"
  end repeat
  pop cd
end printRecords
This is a very basic printing handler which will print each card on a separate page. There are a number of different ways to adjust the printout to print 2 or more cards per page, or just the designated text, or even a formatted report with pictures and graphics, but that is beyond the scope of this tutorial.

Close and save the button script, and save the stack to disk.

Editing the stack script

Open the stack script and look at the doMenu handler that we commented out before the import. We have moved the newCardHandler and deleteCardHandler calls to the File menu, so we won't need to trap those two items here. The cut card condition is there to prevent a user from removing a card using one of the default menu items in HyperCard; since our LiveCode menus don't include a "cut card" item, we don't need to account for it. Similarly, the paste card condition also prevents a user from activating one of HyperCard's default menu items, but since we aren't going to include that item in our menus either, we don't need to disallow it -- the user won't have the opportunity to paste cards. Therefore the entire doMenu handler is superfluous in the LiveCode stack. Delete this handler from the script entirely.

Now change newCardHandler as indicated in red:

on newCardHandler
  if short name of this bg is "Records" then
    set cursor to busy
    create card
    mark this card
    put (number of this card - 2) && "of" && \
        (number of cards of this bg) into bg field "Card#"
    select text of fld "product name"
    answer "Sorry, you must be in the Records section to add a new card."
  end if
end newCardHandler
HyperCard's domenu "new card" command has been replaced by LiveCode's create card syntax. The tabkey command has been replaced by the command to select the text of the "Product Name" field. This would have worked in HyperCard too.

Now rewrite the indicated lines in deleteCardHandler:

on deleteCardHandler
  if short name of this bg is "Records" then
    if number of cards of this bg = 1 then
      answer "Delete this card?" &return&return&\
          "(This is currently the only record card, so" && \
          "it will be replaced with a new card.)" \
          with "Cancel" or "Delete"
      if it is "Cancel" then exit to HyperCard
      lock screen
      repeat with x = 1 to 11
        put empty into bg field x
      end repeat
      unlock screen
      select text of fld "product name"
      answer "Are you sure you want to delete this card?" \
      with "Cancel" or "Delete"
      if it is "Cancel" then exit to HyperCard
      set cursor to busy
      lock screen
      delete this card
      if the short name of this bg is not "Records"
      then go to previous card
    end if
  else answer "Sorry, you can't delete this card."
end deleteCardHandler
LiveCode honors exit to HyperCard for HyperCard compatibility, so you can leave those references in the script alone, though exit to top is another way to write the same thing. In this handler, tabkey has again been replaced with a command to select the text of the first field. The exit to HyperCard statement that occurred just before the first else statement has been removed entirely. It was there originally as a work-around to avoid a problem in HyperCard. Hypercard removes the insertion point from a field if the last line of the script is not the one that selected the text. This glitch requires a HyperCard script to do an immediate exit after a text selection. LiveCode doesn't have this problem, so the exit workaround isn't necessary.

The doMenu "delete card" instruction has been replaced with LiveCode's delete this card command.

Scripting the dynamic index

Now look at the openStack handler at the top of the script, which still contains the doMenu reference that we commented out before the import. That line can be deleted.

Below that is the makeIndex handler which creates the dynamic index. We will use most of it, changing only a few lines so that they work with the LiveCode menus. The original script inserted each product name into the menu as a menu item and assigned a menu message to it. Instead, we will just create a return-delimited list and assign it as the menu button contents. Since the menu button's script already knows how to work with the list, that's all the new indexing script needs to do. Remove the temporary stub we inserted before, and uncomment the original handler. Here is the revised script:

on makeIndexMenu -- updates Index menu
  global gNumUntitled
  put "1" into gNumUntitled
  repeat with i=1 to the number of cards of bg "Records"
    set cursor to busy
    get line 1 of bg field "Product Name" of card i of bg "Records"
    if it is not empty then
      put it & return after theIndexList
      put "Untitled #" & gNumUntitled & return after theIndexList
      add "1" to gNumUntitled
    end if
  end repeat
  put theIndexList into bg btn "Index" of grp "Menubar 1"
end makeIndexMenu
Note that this script does not add parentheses to the listing of an untitled card, which the HyperCard version displayed in the menu as (Untitled #1). The Mac OS uses the left parentheses as an indicator in menus that the menu item should be disabled, and so does LiveCode, but disabling the menu item isn't what we want. We have chosen to simply remove the parentheses, though they could also have been replaced with a different character instead, such as square brackets.

Close and save the script by typing the Enter key or clicking the OK button at the bottom of the script editor.

Up to top | Converting Stacks to LiveCode - TOC | Next Page