2009-08-21 2 views
18

NSOutlineView에서 행을 마우스 오른쪽 버튼으로 클릭하는 기능을 추가하여 객체 또는 다른 작업을 삭제할 수 있습니다. (예 : 애플 메일 응용 프로그램에서 폴더를 마우스 오른쪽 버튼으로 클릭 할 때)NSOutlineView에 컨텍스트 센스티브 메뉴를 추가 하시겠습니까? (예 : 마우스 오른쪽 버튼 클릭 메뉴)

나는 반쪽 편이라고 생각합니다. NSOutlineView의 하위 클래스가있어서 마우스 오른쪽 버튼을 클릭하여 컨텍스트 메뉴를 표시 할 수 있습니다. 마우스가 클릭하고있는 행이 아닌 선택된 행

@implementation NSContextOutlineView 

    - (NSMenu *)defaultMenu { 
     if([self selectedRow] < 0) return nil; 
     NSMenu *theMenu = [[[NSMenu alloc] initWithTitle:@"Model browser context menu"] autorelease]; 
     [theMenu insertItemWithTitle:@"Add package" action:@selector(addSite:) keyEquivalent:@"" atIndex:0]; 
     NSString* deleteItem = [NSString stringWithFormat: @"Remove '%i'", [self selectedRow]]; 
     [theMenu insertItemWithTitle: deleteItem action:@selector(removeSite:) keyEquivalent:@"" atIndex:1]; 
     return theMenu; 
    } 

    - (NSMenu *)menuForEvent:(NSEvent *)theEvent { 
     return [self defaultMenu]; 
    } 
@end 

죄송합니다. 답변이 분명하면 온라인이나 설명서에서 도움을 얻을 수 없습니다.

감사는이를 사용하여 저를 인도, 답변을 무효합니다 :

- (NSMenu *)menuForEvent:(NSEvent *)theEvent { 
    NSPoint pt = [self convertPoint:[theEvent locationInWindow] fromView:nil]; 
    id item = [self itemAtRow: [self rowAtPoint:pt]]; 
    return [self defaultMenuFor: item]; 
} 
+0

실행하지 않으면 정상적으로 작동하는 것 같습니다. 그렇지 않습니까? 그렇지 않다면 어떤 문제가 있습니까? –

+4

또한 자신의 클래스에 NS 접두어를 사용하지 마십시오. Apple이 NSContextOutlineView 클래스를 향후 버전의 Cocoa에 추가하면 클래스와 클래스가 충돌하여 앱이 실행되지 않을 것입니다. –

+1

게시 된 코드의 문제는 selectedRow를 사용하고 오른쪽/Ctrl + 클릭을 수행 한 행을 사용하지 않는다고 생각합니다. 그것은 선택된 행일 수도 그렇지 않을 수도 있습니다. – VoidPointer

답변

21

당신의 menuForEvent 방법에서 당신은 클릭가 발생한 행 확인할 수 있습니다. 당신은 당신의 defaultMenu 방법에 매개 변수로 그것을 전달할 수 있습니다 - 어쩌면 전화 defaultMenuForRow :

-(NSMenu*)menuForEvent:(NSEvent*)evt 
{ 
    NSPoint pt = [self convertPoint:[evt locationInWindow] fromView:nil]; 
    int row=[self rowAtPoint:pt]; 
    return [self defaultMenuForRow:row]; 
} 

지금 당신이 이벤트에서 발견 된 행에 대한 메뉴를 만들 수 있습니다 ...

-(NSMenu*)defaultMenuForRow:(int)row 
{ 
    if (row < 0) return nil; 

    NSMenu *theMenu = [[[NSMenu alloc] 
           initWithTitle:@"Model browser context menu"] 
           autorelease]; 
    [theMenu insertItemWithTitle:@"Add package" 
          action:@selector(addSite:) 
        keyEquivalent:@"" 
         atIndex:0]; 
    [theMenu insertItemWithTitle:[NSString stringWithFormat:@"Remove '%i'", row] 
          action:@selector(removeSite:) 
        keyEquivalent:@"" 
         atIndex:0]; 
    // you'll need to find a way of getting the information about the 
    // row that is to be removed to the removeSite method 
    // assuming that an ivar 'contextRow' is used for this 
    contextRow = row; 

    return theMenu;   
} 

덧글에서 이미 언급했듯이, 당신은 실제로 자신의 클래스에서 NS 접두어를 사용하지 않아야합니다. 자신 :) 원하는 경우가 메뉴를 첨부 할 수 있습니다

+0

대단히 감사합니다! 이렇게 많은 것들이 그렇게 간단하지만 일단 당신이 어떻게 알게됩니다! – Jacob

+0

슬픈 우리는 이것을 달성하기 위해'NSOutlineView'를 서브 클래스화할 필요가 있습니다. 이 기능은 이미 델리게이트 프로토콜에 포함되어야합니다 :-) –

-1

이 도움이

희망 ... 포함 - 당신의 코드를 찾고 그것 모두를 혼란스럽게 할 것이다 플러스 미래의 충돌의 가능성이있다 인터페이스 빌더로 개별 셀보기 또는 행보기 그것을 구축 : 여기

@implementation BSMotleyOutlineView 

-(NSMenu *)menuForEvent:(NSEvent *)event 
{ 
    NSPoint pt = [self convertPoint:[event locationInWindow] fromView:nil]; 
    NSInteger row = [self rowAtPoint:pt]; 
    if (row >= 0) { 
     NSTableRowView* rowView = [self rowViewAtRow:row makeIfNecessary:NO]; 
     if (rowView) { 
      NSInteger col = [self columnAtPoint:pt]; 
      if (col >= 0) { 
       NSTableCellView* cellView = [rowView viewAtColumn:col]; 
       NSMenu* cellMenu = cellView.menu; 
       if(cellMenu) { 
        return cellMenu; 
       } 
      } 
      NSMenu* rowMenu = rowView.menu; 
      if (rowMenu) { 
       return rowMenu; 
      } 
     } 
    } 
    return [super menuForEvent:event]; 
} 
@end 
8

그래서 당신은 위임에 메뉴를 정의 할 수있는 기본 NSOutlineDelegate을 서브 클래스를 사용하고 확장하는 스위프트 2.0 예이다.

protocol MenuOutlineViewDelegate : NSOutlineViewDelegate { 
    func outlineView(outlineView: NSOutlineView, menuForItem item: AnyObject) -> NSMenu? 
} 

class MenuOutlineView: NSOutlineView { 

    override func menuForEvent(event: NSEvent) -> NSMenu? { 
     let point = self.convertPoint(event.locationInWindow, fromView: nil) 
     let row = self.rowAtPoint(point) 
     let item = self.itemAtRow(row) 

     if (item == nil) { 
      return nil 
     } 

     return (self.delegate() as! MenuOutlineViewDelegate).outlineView(self, menuForItem: item!) 
    } 

} 
관련 문제