objective-c cocoa nsmenuitem

objective c - ¿Destacando un NSMenuItem con una vista personalizada?



objective-c cocoa (3)

Si está agregando una vista a un elemento de menú, esa vista tiene que dibujar el resaltado mismo. No tienes eso gratis, me temo. Desde el menú Temas de programación :

Un elemento de menú con una vista no dibuja su título, estado, fuente u otros atributos de dibujo estándar, y asigna responsabilidad de dibujo completamente a la vista.

NSStatusBar un NSMenu simple con un conjunto NSMenu como menú. También he agregado algunos NSMenuItems a este menú, que funcionan bien (incluidos los selectores y el resaltado), pero tan pronto como agregue una vista personalizada (setView :) no aparece el resaltado.

CustomMenuItem *menuItem = [[CustomMenuItem alloc] initWithTitle:@"" action:@selector(openPreferences:) keyEquivalent:@""]; [menuItem foo]; [menuItem setTarget:self]; [statusMenu insertItem:menuItem atIndex:0]; [menuItem release];

Y mi método foo es:

- (void)foo { NSView *view = [[NSView alloc] initWithFrame:CGRectMake(5, 10, 100, 20)]; [self setView:view]; }

Si elimino el método setView, se resaltará.

He buscado y buscado y no puedo encontrar una forma de implementar / habilitar esto.

Editar

Implementé resaltar siguiendo el código en esta pregunta en mi NSView SubClass:

La vista de un NSMenuItem (instancia de una subclase NSView) no se destaca en el vuelo estacionario

#define menuItem ([self enclosingMenuItem]) - (void) drawRect: (NSRect) rect { BOOL isHighlighted = [menuItem isHighlighted]; if (isHighlighted) { [[NSColor selectedMenuItemColor] set]; [NSBezierPath fillRect:rect]; } else { [super drawRect: rect]; } }


Sí, como se mencionó anteriormente, debe dibujarlo usted mismo. Uso NSDrawThreePartImage de AppKit (...) para dibujar, y también incluyo cheques para usar la apariencia de control del usuario (azul o grafito). Para obtener las imágenes, las tomé de una captura de pantalla (si alguien conoce una mejor manera, por favor agregue un comentario .) Aquí hay una parte de drawRect de mi MenuItemView:

// draw the highlight gradient if ([[self menuItem] isHighlighted]) { NSInteger tint = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleAquaColorVariant"]; NSImage *image = (AppleAquaColorGraphite == tint) ? menuItemFillGray : menuItemFillBlue; NSDrawThreePartImage(dirtyRect, nil, image, nil, NO, NSCompositeSourceOver, 1.0, [self isFlipped]); } else if ([self backgroundColor]) { [[self backgroundColor] set]; NSRectFill(dirtyRect); }

EDITAR

Debería haber definido estos:

enum AppleAquaColorVariant { AppleAquaColorBlue = 1, AppleAquaColorGraphite = 6, };

Estos corresponden a las dos opciones de apariencia en Preferencias del sistema. Además, menuItemFillGray y menuItemFillBlue son solo NSImages de los gradientes de relleno de elementos de menú estándar.


Aquí hay una versión bastante menos prolija de lo anterior. Me funcionó bien. (backgroundColour es un ivar).

- (void)drawRect:(NSRect)rect { if ([[self enclosingMenuItem] isHighlighted]) { [[NSColor selectedMenuItemColor] set]; } else if (backgroundColour) { [backgroundColour set]; } NSRectFill(rect); }