I wanted to add some more comments here about using tracking areas, and about some errors and ambiguities in the docs concerning them.
The initWithRect_options_owner_userInfo_ method has the userInfo parameter typed as an NSDictionary, but it appears that it should be typed as “id” since you can pass strings, numbers, dates, etc. as well as dictionaries (or their applescript equivalents) for this parameter.
The docs say “When handling such an event you can obtain the dictionary by sending userData to the NSEvent object”. This is incorrect (in ASOC anyway, I haven’t tried it in Objective C). You need to say “theEvent’s trackingArea()'s userInfo()” where “theEvent” is the parameter passed in to the mouseEntered:, mouseExited:, etc. methods.
The mouseEntered:, mouseExited: and mouseMoved: methods can be implemented in whatever script is referenced in the initWithRect_options_owner_userInfo_ method in the “owner” parameter. However, if you want to implement the cursorUpdate: method, it is not called in the “owner’s” class unless that class (script) is the topmost view that the cursor is over. So, this means that you have to implement this method in a subclass of the view for which you are adding the tracking rectangle. This isn’t real obvious in the docs.
I made this example to illustrate these points. The “options” parameter value of 549 in this example is the sum of the 512, 32, 4 and 1 choices which I show in the commented out part of the script. If you wanted to have the mouseMoved: method called, you would have to add 2 ( to make 551). The interface just has two boxes that are referenced by the IBOutlets “box1” and “box2”. The boxes have their class set to my other script “TheBoxes”
script MouseWindowAppDelegate
property parent : class "NSObject"
property box1 : missing value
property box2 : missing value
property WD349info : missing value
on mouseEntered_(theEvent)
if theEvent's trackingArea()'s userInfo() as string is "box1" then
WD349info's orderFront_(me) -- Opens another window when the mouse enters box1
else if theEvent's trackingArea()'s userInfo() as string is "box2" then
log "I'm in box2"
end if
end mouseEntered_
on mouseMoved_(theEvent) -- Not called unless the options number in initWithRect_options_owner_userInfo_ is 551
log "mouse moved"
end mouseMoved_
on mouseExited_(theEvent)
log "Exited"
WD349info's orderOut_(me)
end mouseExited_
on applicationWillFinishLaunching_(aNotification)
set trackingArea1 to current application's NSTrackingArea's alloc()'s initWithRect_options_owner_userInfo_(box1's frame(), 549, me, "box1")
box1's addTrackingArea_(trackingArea1)
set trackingArea2 to current application's NSTrackingArea's alloc()'s initWithRect_options_owner_userInfo_(box2's frame(), 549, me, "box2")
box2's addTrackingArea_(trackingArea2)
(*log current application's NSTrackingMouseEnteredAndExited as integer -- 1
log current application's NSTrackingMouseMoved as integer -- 2
log current application's NSTrackingCursorUpdate as integer -- 4
log current application's NSTrackingActiveWhenFirstResponder as integer -- 16
log current application's NSTrackingActiveInKeyWindow as integer -- 32
log current application's NSTrackingActiveInActiveApp as integer --64
log current application's NSTrackingActiveAlways as integer -- 128
log current application's NSTrackingAssumeInside as integer -- 256
log current application's NSTrackingInVisibleRect as integer -- 512
log current application's NSTrackingEnabledDuringMouseDrag as integer -- 1024
*)
end applicationWillFinishLaunching_
end script
The cursorUpdate: method is then implemented in another class called TheBoxes:
script TheBoxes
property parent : class "NSBox"
on cursorUpdate_(theEvent)
if theEvent's trackingArea()'s userInfo() as string is "box1" then
current application's NSCursor's pointingHandCursor()'s |set|()
else if theEvent's trackingArea()'s userInfo() as string is "box2" then
current application's NSCursor's closedHandCursor()'s |set|()
end if
end cursorUpdate_
end script
By using the userInfo in my if statements instead of the trackingArea’s identity, as I did in the example I posted previously, I don’t need to have properties for them, which I would need to have reference to in my other script.
Ric