Tuesday, August 5, 2008

Mouse entering View


On p. 274, Hillegass has an aside about how to pick up the event when a mouse enters and exits a view, e.g. to highlight the view, as we'll do here. Not the most exciting screenshot in the world, I know. I tried to get the mouse, but couldn't figure it out. The mouse tracking code is set up in "viewDidMoveToWindow," which I gather is called when that happens during launch. If we do that then we get events sent as calls to "mouseEntered_" and "mouseExited_." The highlighting part is handled in "drawRect_", with an important clean-up method below that. The other thing in this code is a demo of how to get additional colors besides the standard Apple ones, from the color list called "Crayons." Here is the code:

class MyView(NSView):
def initWithFrame_(self, frame):
self = super(MyView, self).initWithFrame_(frame)
if self:
return self

def awakeFromNib(self):
self.colorL = NSColorList.colorListNamed_('Crayons')
self.isHighlighted = False

def acceptsFirstResponder(self): return True

def viewDidMoveToWindow(self):
print 'viewDidMoveToWindow'
print self.window().description()

opts = NSTrackingMouseEnteredAndExited |\
NSTrackingActiveAlways |\
NSTrackingInVisibleRect

ta = NSTrackingArea.alloc()
ta.initWithRect_options_owner_userInfo_(
self.bounds(), opts, self, None)
self.addTrackingArea_(ta)

def mouseEntered_(self, event):
print 'mouseEntered_'
self.isHighlighted = True
self.setNeedsDisplay_(True)

def mouseExited_(self, event):
print 'mouseExited_'
self.isHighlighted = False
self.setNeedsDisplay_(True)

def drawRect_(self, rect):
salmon = self.colorL.colorWithKey_('Salmon')
salmon.set()
R = self.bounds()
p = NSBezierPath.bezierPathWithRect_(R)
p.fill()

if self.window().firstResponder() == self:
if NSGraphicsContext.currentContextDrawingToScreen():
if self.isHighlighted:
NSGraphicsContext.saveGraphicsState()
NSSetFocusRingStyle(NSFocusRingOnly)
NSBezierPath.fillRect_(R)
NSGraphicsContext.restoreGraphicsState()

def resignFromFirstResponder_(self,sender):
self.setKeyboardFocusRingNeedsDisplayInRect_(R)
return YES