Popping up a menu after a delay timer

This lesson demonstrates how to popup a menu after a certain amount of time has passed.

The script

This script uses three handlers to control a "settable" button. Clicking the button changes the color of any text that is selected in a particular field to green. However, if you hold down the mouse over the button, a popup menu appears that lets you change the color.

The mouseDown handler

The mouseDown message is sent whenever the user clicks, to whatever object was clicked. When the mouseDown message is sent to this button, it triggers the mouseDown handler. This mouseDown handler sends a message called "popGoesTheMenu" that pops up a menu after a two-second delay. When the user releases the mouse, a mouseUp message is sent to the button, triggering the mouseUp handler.

The sDidPopupMenu variable

The local declaration at the top of the script creates a variable called sDidPopUpMenu. Because it is declared outside any handler, sDidPopUpMenu is a script local variable, meaning it's available to all three of the handlers in this script. This is important, since more than one handler needs to access the variable. We'll put either true or false into the sDidPopUpMenu variable, depending on whether the user triggered the popup menu.

local sDidPopUpMenu

When the user first clicks the button, a mouseDown message is sent. The mouseDown handler puts false into sDidPopUpMenu. This ensures that the variable will be set to false unless we set it to true later. In other words, this line of code sets a default value of false for the variable.

The popGoesTheMenu message

Next, the mouseDown handler sends the "popGoesTheMenu" message after a two-second delay. (The delay is so the user has to hold down the mouse button to see the popup menu.) This message is sent to me. The keyword me refers to the current object: the object whose script contains the handler that is executing. In this example, then, the "popGoesTheMenu" message is sent to the button, because the mouseDown handler is in the button's script.

Two seconds later, the "popGoesTheMenu" handler is triggered by the delayed message. This handler displays the popup menu, so first of all, it needs to figure out whether the mouse is still being pressed and whether the mouse pointer is still inside the button. If the mouse function returns "up", the mouse button isn't down any longer. If the expression the mouseLoc is not within the rect of me evaluates the true, the mouse pointer isn't in the button. If either of these things is true, the popup menu shouldn't be displayed. In this case, the exit command skips the rest of the handler.

if the mouse is up or the mouseLoc is not within the rect of me then 
	exit popGoesTheMenu
end if

Otherwise, the handler uses the popup command to display the menu. (Because we're about to pop up the menu, at this point the handler puts true into the variable sDidPopupMenu.) The popup menu is contained in a button called (in this example) "Colors". This is a separate button whose style property is "menu" and whose menuMode is "popup". This extra button is hidden in this example, and should be for most situations. The popup command displays this popup button's contents as a popup menu. When the user chooses a menu item from it, a menuPick message is sent to the popup button. In this example, the popup button's script looks like this:

on menuPick pColor
	set the label of button "Color" to "Change color to" && toLower(pColor)
end menuPick

This simply puts the color that the user picked into the main button's label property. For example, if you pick "blue" from the popup menu, the menuPick handler changes the main button's visible label to "Change color to blue".

Checking if the user held the button down

What happens if the user just clicks, and doesn't hold down the mouse button long enough to show the menu? In this case, after the mouseDown is sent, a mouseUp message is sent to the button when the user releases the mouse. We don't want to perform the button action if the user popped up the menu, so we'll check that first.

To find out whether the popup menu was used, the mouseUp handler checks the sDidPopupMenu variable. Remember that this variable was set to false in the mouseDown handler, and to true in the "popGoesTheMenu" handler. If it's true, the menu was popped up. In this case, the pass command skips the rest of the handler and passes the mouseUp message on to the next object. But if it's still false, the user didn't hold down the mouse button long enough to pop up the menu, so it's time to do the button action: set the selected text's color.

on mouseUp
	## if the user popped up the menu, don't do the click action
	if sDidPopUpMenu then pass mouseUp
	## if there is a text selection, set its color:
	if the short name of the selectedField is "Example Text" then
		set the textColor of the selectedChunk to (last word of the label of me)
	end if
end mouseUp

We use pass here instead of exit because, since mouseUp is a LiveCode message rather than a custom message, it's possible that there's a handler further along the message path that needs to receive this message in order to do housekeeping or other tasks. That doesn't happen to be the case for this example, there are no mouseUp handlers in the example card or stack, but it's a good habit to pass LiveCode messages instead of exiting, unless you specifically want to prevent the message from passing.

Setting the text color

Setting the text's color is fairly simple. First we check to make sure the selection is in the example field, and then we set the textColor property of the selected piece of text to the last word of the button's label. Since the popup menu changes the last word to a color name, we know that the last word of the label is always a color.

if the short name of the selectedField is "Example Text" then
	set the textColor of the selectedChunk to (last word of the label of me)
end if

The menu code

local sDidPopUpMenu ## keeps track of whether the menu was popped up
on mouseDown
	## start out by assuming no menu
	put false into sDidPopUpMenu
	send "popGoesTheMenu" to me in 2 seconds
end mouseDown
on popGoesTheMenu pLocation
	-- The menu will pop up only if the user is still pressing
	-- the mouse over the button after 2 seconds:
	if the mouse is up or the mouseLoc is not within the rect of me then 
		exit popGoesTheMenu
	end if
   
	## skip the mouseUp actions
	put true into sDidPopUpMenu
	## show the hidden popup menu
	popup button "Colors"
end popGoesTheMenu
on mouseUp
	## if the user popped up the menu, don't do the click action
	if sDidPopUpMenu then pass mouseUp
	## if there is a text selection, set its color:
	if the short name of the selectedField is "Example Text" then
		set the textColor of the selectedChunk to (last word of the label of me)
	end if
end mouseUp

0 Comments

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.