2012-10-03 90 views
5

Apple's sample code和閱讀the docs我看不出配置NSPathControl的行爲與例如在Xcode編輯器窗口中的 '跳吧':帶有彈出窗口的每個路徑組件的NSPathControl?

Xcode Editor custom path control

即讓它代表路徑(或其他類型的層次結構),並使路徑的每個組件都成爲一個可點擊的彈出窗口來瀏覽層次結構。

任何有幸運用NSPathControlDelegate聽取點擊並在臨時窗口中顯示菜單來僞造此類行爲的人?

似乎是一個常見的設計,其中一個甚至會期待一些OSS實現 - 但沒有這樣的運氣又google搜索它..

回答

3

我做NSPathControl的一個子類,這樣我可以用鼠標按下:彈出的右鍵菜單的組件單元在正確的位置。我還向菜單添加了一個委託,以根據需要創建更深的菜單。

- (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

我稍微擴展了斯蒂芬的回答,以適應延遲加載菜單項。我創建了一個小協議呼籲菜單,而不是建立每個單元格的時間菜單的未來:

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