2012-10-03 13 views
5

De Apple's sample code y leyendo the docs No veo la manera de configurar el NSPathControl para que se comporte de manera similar a, p. Ej. la 'barra de salto ' en la ventana de Xcode Editor:NSPathControl con ventanas emergentes para cada componente de la ruta?

Xcode Editor custom path control

es decir, hacer que represente una ruta (u otro tipo de jerarquía) y hacer que cada componente de la ruta sea una ventana emergente en la que se pueda hacer clic para navegar por la jerarquía ...?

¿Alguien tiene suerte simulando tal comportamiento usando un NSPathControlDelegate escuchando clics y mostrando un menú en una ventana temporal?

parece un diseño común donde se podría incluso contar con una cierta aplicación OSS - pero no hubo suerte todavía buscando en Google para ello ..

Respuesta

3

hice una subclase de NSPathControl de modo que pueda utilizar mouseDown: popup los menús de contexto de las celdas componentes en la posición correcta. También agregué un delegado al menú para crear menús más profundos a pedido.

- (void)mouseDown:(NSEvent *)event { 

    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; 


    NSPathCell *cell = self.cell; 
    NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point 
                   withFrame:self.bounds 
                   inView:self]; 

    NSRect componentRect = [cell rectOfPathComponentCell:componentCell 
               withFrame:self.bounds 
                inView:self]; 

    NSMenu *menu = [componentCell menuForEvent:event 
             inRect:componentRect 
             ofView:self]; 

    if (menu.numberOfItems > 0) { 
     NSUInteger selectedMenuItemIndex = 0; 
     for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) { 
      if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) { 
       selectedMenuItemIndex = menuItemIndex; 
       break; 
      } 
     } 

     NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex]; 
     [menu popUpMenuPositioningItem:selectedMenuItem 
          atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2) 
           inView:self]; 
    } 
} 

- (NSMenu *)menuForEvent:(NSEvent *)event { 
    if (event.type != NSLeftMouseDown) { 
     return nil; 
    } 
    return [super menuForEvent:event]; 
} 
1

Extendí la respuesta de Stephan ligeramente para permitir la carga lenta de los elementos del menú. He creado un pequeño protocolo para pedir el menú en lugar de tener que construir por delante del menú de tiempo para cada celda:

NSPathControlExtended.h

@protocol NSPathControlExtendedDelegate <NSPathControlDelegate> 

@required 
- (NSMenu *)pathControl:(NSPathControl *)pathControl menuForCell:(NSPathComponentCell *)cell; 

@end 

@interface NSPathControlExtended : NSPathControl 

@property (weak) id <NSPathControlExtendedDelegate> delegate; 

@end 

NSPathControlExtended.m

#import "NSPathControlExtended.h" 

@implementation NSPathControlExtended 

@synthesize delegate; 

- (instancetype)initWithFrame:(NSRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 
    } 
    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect { 
    [super drawRect:dirtyRect]; 

    // Drawing code here. 
} 

- (void)mouseDown:(NSEvent *)event { 

    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil]; 


    NSPathCell *cell = self.cell; 
    NSPathComponentCell *componentCell = [cell pathComponentCellAtPoint:point 
                   withFrame:self.bounds 
                   inView:self]; 

    NSRect componentRect = [cell rectOfPathComponentCell:componentCell 
               withFrame:self.bounds 
                inView:self]; 

    NSMenu *menu = [delegate pathControl:self menuForCell:componentCell]; 

    if (menu.numberOfItems > 0) { 
     NSUInteger selectedMenuItemIndex = 0; 
     for (NSUInteger menuItemIndex = 0; menuItemIndex < menu.numberOfItems; menuItemIndex++) { 
      if ([[menu itemAtIndex:menuItemIndex] state] == NSOnState) { 
       selectedMenuItemIndex = menuItemIndex; 
       break; 
      } 
     } 

     NSMenuItem *selectedMenuItem = [menu itemAtIndex:selectedMenuItemIndex]; 
     [menu popUpMenuPositioningItem:selectedMenuItem 
          atLocation:NSMakePoint(NSMinX(componentRect) - 17, NSMinY(componentRect) + 2) 
           inView:self]; 
    } 
} 

- (NSMenu *)menuForEvent:(NSEvent *)event { 
    if (event.type != NSLeftMouseDown) { 
     return nil; 
    } 
    return [super menuForEvent:event]; 
} 

@end 
Cuestiones relacionadas