Naming your Rectangles
Objects of class Rect contain an ID string field. This ID string must be properly initialized if you want your GUI to accept mouse clicks. The ID string is what makes it possible to identify which rectangle the user clicked on. It is standard Wild Pockets practice to name your rectangles using a directory-tree-like naming system. Consider, for example, a dialog box with a message, an OK button, and a cancel button. It would be in keeping with standard practice to name the rectangles as follows:
| Rectangle Purpose | Rectangle ID String | |
| Entire Screen | screen | |
| The Dialog Box | screen/dialogbox | |
| The OK Button | screen/dialogbox/ok | |
| The Cancel Button | screen/dialogbox/cancel | |
| The Message | screen/dialogbox/message |
Note that these are logical, not spatial relationships. The ok button does not technically have to be physically inside the dialog box, it is just conceptually a part of the dialog box. There are a great many constructors that return rectangles. With the exception of Rect.new, all of these constructors require you to pass in a parent rectangle. These constructors concatenate the ID of the parent, a slash, and a sub-ID specified in the arguments to produce the resulting rectangle's ID. Because of this, it is very easy to construct rectangles with the standard naming conventions. Sometimes, a rectangle doesn't have any particular "parent." In that case, you should use the screen rectangle as the parent:
local screen = Rect.screen()
So here's an updated version of the paintScore function on the previous page. The rectangle is now properly named:
function paintScore()
local screen = Rect.screen()
local scorebox = screen:sub("scorebox",0,0,200,25)
scorebox:drawText(nil, {}, "Score: " .. currentScore .. " points")
end
The function Rect.new has been replaced with Rect:sub. These functions differ only in how they initialize the ID string of the rectangle. In Rect.new, the rectangle gets the exact ID string that you pass in. In Rect:sub, the ID is created using the Wild Pockets standard: by concatenating the parent ID, a slash, and the specified sub-ID ("scorebox"). Having a valid ID string in this rectangle will make it possible to detect the presence of the mouse.
Detecting Mouse Position
To detect the mouse, the first step is to activate a rectangle for mouse input using the 'Rect:activateRegion' method:
function paintScore()
local screen = Rect.screen()
local scorebox = screen:sub("scorebox",0,0,200,25)
scorebox:drawText(nil, {}, "Score: " .. currentScore .. " points")
scorebox:activateRegion()
end
This causes the rectangle to be recorded in a list of input-regions. This list, like the GUI as a whole, is rebuilt once per frame. Now that our rectangle is part of the list of input regions, we can check whether it contains the mouse:
local mx,my = Mouse.getXY() local region = GuiManager.find(mx,my)
The variable region will now contain the ID string of the region containing the mouse. This is subtly different from simply asking whether or not the rectangle contains the mouse using Rect.contains. If you have two active regions that overlap, GuiManager.find will choose the one which is on top.
Setting up Handlers
In addition to simply checking whether the mouse is inside a region, you can set up click handlers. As with the rest of the GUI, the handler tables are rebuilt once per frame, so they need to be set up inside the same paintScore function:
function paintScore()
local screen = Rect.screen()
local scorebox = screen:sub("scorebox",0,0,200,25)
scorebox:drawText(nil, {}, "Score: " .. currentScore .. " points")
scorebox:leftMouseDown(scoreDown)
end
function scoreDown()
print("You clicked on the score!")
end
Now clicking on the score rectangle will cause the scoreDown function to get called. In addition to leftMouseDown, you will find leftMouseClick, which doesn't call the handler until you have clicked the mouse down and then released it. Of course, rightMouseDown and rightMouseClick both exist as well. Functions that set up handlers call Rect:activateRegion implicitly.
Eating Click Events
When you click on a GUI element that is activated using leftMouseDown or the like, the GUI eats the mouse-down event and the corresponding mouse-up event. When this occurs, the event never gets to the EventHandler/EventMap system.
Other Operations
There are a great many functions in classes GuiManager and Rect to help detect the activity of the mouse. These include such functions as Rect:leftClickInProgress, Rect:hasMouse, and the like. See the documentation for these two classes.
- Printer-friendly version
- Login or register to post comments
-



