2009-08-21 172 views
18

如何添加在NSOutlineView中右鍵單擊某行的能力,以便您可以說刪除對象或其他活動。 (即就像當你右擊在Apple Mail應用程序的文件夾上)如何添加上下文感性菜單到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 

對不起,如果答案是顯而易見的我只是不能找到任何幫助這個在線或在文檔中。

感謝void對於答案,這導致我使用這個:

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

沒有運行它,看起來它應該工作得很好。不是嗎?如果不是,你有什麼問題呢? – 2009-08-21 03:10:01

+4

另外,不要在你自己的類上使用NS前綴。如果Apple向將來的Cocoa版本添加NSContextOutlineView類,它們的類和你的類將發生衝突,並且你的應用程序可能不會運行。 – 2009-08-21 03:10:48

+1

我認爲發佈代碼的問題是它將使用selectedRow,而不是執行右/ ctrl單擊的行。這可能是也可能不是選定的行。 – VoidPointer 2009-08-21 16:40:24

回答

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 2009-08-22 02:15:40

+0

傷心,我們需要繼承'NSOutlineView'來實現這一點。此功能應該已包含在委託協議中:-) – 2017-08-20 12:52:18

-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!) 
    } 

} 
相關問題