2012-10-03 29 views
5

Từ Apple's sample code và đọc the docs Tôi không thể thấy cách nào định cấu hình NSPathControl để hoạt động tương tự như ví dụ: các 'nhảy thanh' trong cửa sổ Xcode Editor:NSPathControl với cửa sổ bật lên cho từng thành phần của đường dẫn?

Xcode Editor custom path control

Tức là có nó đại diện cho một con đường (hoặc loại khác của hệ thống phân cấp) và làm cho mỗi thành phần của đường dẫn một popup có thể click để điều hướng hệ thống phân cấp ..?

Bất kỳ ai có may mắn giả mạo hành vi đó bằng cách sử dụng số NSPathControlDelegate nghe nhấp chuột và hiển thị menu trong cửa sổ tạm thời?

Có vẻ như một thiết kế phổ biến nơi một thậm chí mong chờ một số thực hiện cơ chế một cửa - nhưng không có may mắn như vậy chưa googling cho nó ..

Trả lời

3

tôi đã thực hiện một lớp con của NSPathControl vì vậy mà tôi có thể sử dụng mouseDown: để bật lên các menu ngữ cảnh của các ô thành phần ở đúng vị trí. Tôi cũng thêm một đại biểu vào trình đơn để tạo ra các menu sâu hơn theo yêu cầu.

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

Tôi mở rộng câu trả lời của Stephan một chút để thích hợp cho việc tải các mục menu xuống một cách lười biếng. Tôi tạo ra một giao thức nhỏ để kêu gọi thực đơn thay vì phải xây dựng trước của trình đơn thời gian cho mỗi tế bào:

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 
Các vấn đề liên quan