Text menu: handling choices

This lesson demonstrates how to handle a menu choice made by a user.

The menuPick message

The menuPick message is sent when the user chooses a menu item from the menu. When the menuPick message is sent to the button, it triggers this handler.

The menuPick handler

This menuPick handler works with a menu button that's set up as a hierarchical menu, with Font, Size, and Color submenus, plus menu items for "Plain", "Bold", "Italic", and "Underline".

The parameter, pMenuItem, that's passed with the menuPick message contains the text of the menu item the user chose. If the menu item is in a submenu, the parameter includes the submenu name and the menu item, separated by a bar (|). For example, if the user chose "Red" from the "Color" submenu, the pMenuItem parameter is "Color|Red".

Separating the menu item from the submenu

To make it easier to separate the menu item from the submenu, the first thing the handler does is to set the itemDelimiter property to "|". By default, the itemDelimiter is a comma, but you can set it to any character. Once this itemDelimiter is set, if the user chose a submenu item, the submenu name is item 1 of the parameter, and the menu item is item 2 of the parameter.

switch item 1 of pMenuItem 
	## the submenu name
	case "Font"
		set the textFont of field "Example Text" to item 2 of pMenuItem
		break
		...

The switch control structure that forms the heart of this handler checks the first item in the pMenuItem parameter. If the user chose a menu item from a submenu, item 1 is the name of the submenu. If the menu item is a plain menu item, not part of a submenu, then the parameter consists of the menu item's name, and "item 1" is the whole parameter. The switch control structure includes a clause for each top-level menu item, whether it's a submenu or a regular menu item.

The Font, Size and Color submenus

If the user chose a menu item from the "Font" submenu, the handler sets the field's textFont property to the font that was chosen from the submenu. (This is item 2 of the parameter.) The "Size" and "Color" submenus are handled similarly: item 2 of the parameter is the size or color the user chose from the submenu.

case "Font"
	set the textFont of field "Example Text" to item 2 of pMenuItem
	break

The Style items

This menu has four ordinary menu items at the bottom: Plain, Bold, Italic, and Underline. The parameter for ordinary menu items is just the name of the menu item, and there is only one "|"-delimited item in the parameter, so the expression item 1 of pMenuItem evaluates to the name of the menu item. Because of this, the same switch control structure, which tests item 1 of pMenuItem, works for the submenus and the ordinary menu items.

If the user chooses "Plain", it's simple to change the style. Setting the field's textStyle property to empty removes the style information.

case "Plain"
	## plain removes all styles:
	set the textStyle of field "Example Text" to empty

If the user chooses "Bold", "Italic", or "Underline", the handler must first figure out whether the style is already applied. If so, the style needs to be removed (without disturbing other styles); if not, it needs to be added to any existing styles. For example, if the field is already bold and underlined, and the user chooses "Underline", the underlining is removed but the boldfacing is retained.

put the textStyle of field "Example Text" into tCurrentStyle
set the itemDelimiter to comma
if pMenuItem is among the items of tCurrentStyle then
	## already has that style, so remove it
	delete item (itemOffset(pMenuItem,tCurrentStyle))  of tCurrentStyle
else
	## add the style to any existing styles
	if tCurrentStyle is "plain" then 
		put pMenuItem into tCurrentStyle
	else
		put comma & pMenuItem after tCurrentStyle
	end if
end if
set the textStyle of field "Example Text" to tCurrentStyle

The textStyle of an object

The textStyle of an object consists of one or more styles, separated by commas. For example, the textStyle of a bold underlined field reports "bold,underline". To find out whether the chosen menu item is already a style of the field, the handler checks whether it's one of the items in the field's textStyle. (Remember that earlier in the handler, we set the itemDelimiter to "|" to be able to separate submenus from their menu items. Since we've already handled all the submenus, we don't need to use this itemDelimiter any more, so we set it back to a comma in order to more easily handle the textStyle.)

If the style the user chose from the menu is already a textStyle of the field, the handler removes that style. If not, it adds the style to the existing textStyle. We need to handle one case, where no special styles are set yet, specially. If there are no styles set, the textStyle property reports "plain". However, if you set the textStyle to a string that includes "plain" as one of the items, any styles before "plain" are ignored. (For example, setting the textStyle to "italic,plain,bold" ignores the italic.) To avoid this problem, if the textStyle property reports "plain", the handler substitutes the chosen style, instead of adding it to the existing style.

The menuPick handler code

on menuPick pMenuItem
	local tCurrentStyle
   
	set the itemDelimiter to "|"   
	switch item 1 of pMenuItem 
		## the submenu name
		case "Font"
			set the textFont of field "Example Text" to item 2 of pMenuItem
			break
		case "Size"
			set the textSize of field "Example Text" to item 2 of pMenuItem
			break
		case "Color"
			set the textColor of field "Example Text" to item 2 of pMenuItem
			break
		case "Plain"
			## plain removes all styles:
			set the textStyle of field "Example Text" to empty
		case "Bold"      
		case "Italic"   
		case "Underline"
			## all three remaining menu items
			## are handled with the same piece of code
			put the textStyle of field "Example Text" into tCurrentStyle
			set the itemDelimiter to comma
			if pMenuItem is among the items of tCurrentStyle then
				## already has that style, so remove it
				delete item (itemOffset(pMenuItem,tCurrentStyle))  of tCurrentStyle
			else
				## add the style to any existing styles
				if tCurrentStyle is "plain" then 
					put pMenuItem into tCurrentStyle
				else
					put comma & pMenuItem after tCurrentStyle
				end if
			end if
		set the textStyle of field "Example Text" to tCurrentStyle
	 end switch
end menuPick

1 Comments

Steve

Just wondering: isn't there supposed to be a "break" after the case "Plain" line? Without it, the tCurrentStyle is set to "empty" and that will cause the script to hang on the last line.

Add your comment

E-Mail me when someone replies to this comment