Graphics Reference
In-Depth Information
When accessing
mouseLocation
, it gives us the location clicked as screen coordinates
(
x
and
y
values). These coordinates are not the same as those used by the application, so
you need to convert them to window coordinates by using one of the methods built into
the
NSWindow
and
NSView
classes. Also, because
CALayer
objects deal in
CGPoints
instead
of
NSPoints
, we also need to change the window coordinate's returned
NSRect
into a
CGRect
.
Now that we have the correct mouse coordinates, we need to find out which is the
deepest layer under the mouse. A call to
-hitTest:
on the
rootLayer
returns the correct
CALayer
information.
The
deepest layer
is defined as the layer that has no sublayers that would contain the point
being passed in. For instance, if you click on the text within
LZButtonLayer
,
CATextLayer
is returned from the
-hitTest:
call because it has no sublayers that contain the
CGPoint
being passed in. If, however, the edge of the button is clicked, then
LZButtonLayer
is
returned instead. Finally, the root layer is returned if the background root layer is clicked
(see Figure 11-2).
Mouse Click
Root Layer receives the mouse event
CATextLayer is returned from the hit test
FIGURE 11-2
The Hit Test
However, we care only if the user clicked on
LZButtonLayer
. It is possible that the user
thought they were clicking on
LZButtonLayer
, but were in fact clicking its sublayer.
Therefore, an additional check was added. If the clicked layer were not a
LZButtonLayer
,
we check that layer's superlayer to see if it is a
LZButtonLayer
. If the clicked layer is, then
its superlayer is returned instead. If neither the clicked layer nor its superlayer is a
LZButtonLayer
, we return
nil
.
With the hit test method defined, it's now time to handle
mouseUp
and
mouseDown
events
using the code shown in Listing 11-9.