3

I need to use a custom NSView subclass to draw some content, but it isn't drawing as highlighted when the user hovers and it doesn't dismiss the NSMenu when the user clicks on it. Any ideas?

Edit

So using -drawRect: and [[self enclosingMenuItem] isHighlighted] I'm able to tell whether or not I need to draw the view as highlighted and am given the chance to do so. All I have to figure out is how to do that.

Alexsander Akers
  • 15,967
  • 12
  • 58
  • 83
  • 1
    By descendant, I think you mean subclass. – Rob Keniger May 27 '10 at 00:40
  • I don't want to change the title because links would break, but you're right. – Alexsander Akers May 27 '10 at 01:13
  • 1
    Alexsander Akers: Links won't break, as the site actually doesn't pay attention to the title portion of the link. Only the question or answer number counts. To wit: http://stackoverflow.com/questions/2917713/this-has-never-been-a-title-of-this-question – Peter Hosey May 27 '10 at 05:29

3 Answers3

5

Maybe you should try it this way:

#define menuItem ([self enclosingMenuItem])

- (void) drawRect: (NSRect) rect {
    BOOL isHighlighted = [menuItem isHighlighted];
    if (isHighlighted) {
        [[NSColor selectedMenuItemColor] set];
        [NSBezierPath fillRect:rect];
    } else {
        [super drawRect: rect];
    }
}
papr
  • 4,717
  • 5
  • 30
  • 38
  • 2
    I tried that, but [menuItem isHighlighted] returns NO all the time (even when the mouse is over the item). I assume the events are not propagated to the menuItem. What am I missing? – Mark Sep 14 '11 at 13:59
  • 1
    @Mark: Make sure your menu item is actually enabled. It needs an action set to a selector that exists. You can temporarily set your view to nil to make sure everything else is set up right. – robotspacer Sep 25 '16 at 10:33
1

I'm not sure if I understood your question. I think you mean the following: The Menu opened and all your drawings stopped drawing. I think this is because the opened NSMenu stopps the UI' NSRunLoop its thread. One of both. You should try to do your drawing thread-safe in an other thread.

papr
  • 4,717
  • 5
  • 30
  • 38
0

This worked for me. I use a Stackview. But this should work for views as well.

class MenuStackView: NSStackView {

override init(frame frameRect: NSRect) {
    super.init(frame: frameRect)
}

required init?(coder aDecoder: NSCoder) {
   super.init(coder: aDecoder)
}

override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)
    let menuItem = self.enclosingMenuItem
    let isHighlighted = menuItem?.isHighlighted ?? false
    if isHighlighted {
        NSColor.selectedMenuItemColor.set()
        NSBezierPath.fill(dirtyRect)
    } 
}
}
KamyFC
  • 858
  • 9
  • 17