We make software for humans. Custom Mac, Windows, iOS and Android solutions in HyperCard, MetaCard, and RunRev LiveCode
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):
In addition, after the Print Card menu item, add a new line:&New Card/N &Delete Card -
Now edit the script of the File menu button. Change the menuPick handler to this:Print &Records
on menuPick pWhich
switch pWhich
case "New Card"
newCardHandler
break
case "Delete Card"
deleteCardHandler
break
case "Save"
save this stack
break
case "Page Setup"
answer printer
break
case "Print Card"
if the short name of this bg = "records"
then print this card from "0,26" to "512,368"
else beep
break
case "Print Records"
printRecords
break
case "Quit"
quit
break
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.
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#"
makeIndexMenu
select text of fld "product name"
else
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
makeIndexMenu
unlock screen
select text of fld "product name"
else
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
makeIndexMenu
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.
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
else
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.