2012-06-02 25 views
1

我有一個關於在NSTableViews/NSOutlineViews中實現一些特定行爲的問題。NSOutlineView模仿Photoshop圖層面板

什麼,我想實現:

我試圖創建一個NSOutlineView模仿Photoshop的圖層面板的行爲(除「層」列是分層次的)。我的大綱視圖是一個3列表格,包含一個「層」列,「可見性」列和一個「鎖定」列。我已經將「可見性」和「鎖定」列實現爲NSImageCells,將「圖層」列實現爲自定義文本和圖像單元格。

具體而言,這裏是我掙扎實施的行爲:

  • 就像Photoshop中,用戶應該能夠點擊可見性(眼球)圖標,上下拖動到不同的行根據所點擊的第一行的可見性,將其他行的可見性設置爲「開」或「關」......確切地說,Photoshop如何隱藏和顯示圖層。請注意,當表格中有許多行時,應支持autoscroll。

  • 就像Photoshop一樣,當選擇「圖層」列中的一行或多行時,可見性/鎖定列的背後不應該有高亮條(也就是說,行高亮不應該通過它們的列) 。

  • 在「可見性」或「鎖定」列中單擊和/或拖動不應更改表的選擇......僅如上所述更改表的選擇狀態。

我一直在撞牆,試圖讓這個工作一週。我已閱讀控件&單元編程指南,Table View編程指南,NSCell,NSActionCell,NSTableView,NSControl,NSOutlineView的類引用,以及NSOutlineViewDelegate和NSOutlineViewDataSource的協議引用......並且一直在嘗試不同的方法。我只是沒有想到這一個。

有人可以引導我在正確的方向嗎?先謝謝您的幫助!

回答

1

通過一些額外的網絡搜索和實驗,我可以回答大部分是我自己的問題:

高亮只的第一列中的NSOUTLINEVIEW

我能有選擇的亮點只出現過通過繼承NSOutlineView和實施

- (void)highlightSelectionInClipRect:(NSRect)clipRect 
{ 
    NSRange visibleRowIndexes = [self rowsInRect:clipRect]; 
    NSIndexSet *selectedRowIndexes = [self selectedRowIndexes]; 

    NSInteger currentRow = visibleRowIndexes.location; 
    NSInteger lastRow = currentRow + visibleRowIndexes.length; 

    NSColor *highlightColor; 

    //Determine color of selection bar based on key/main/first responder status. 
    if (self == [[self window] firstResponder] && [[self window] isMainWindow] && [[self window] isKeyWindow]) { 
     highlightColor = [NSColor colorWithDeviceRed:0.0 green:0.0 blue:0.3 alpha:1.0]; 
    } else 
     highlightColor = [NSColor lightGrayColor]; 
    } 
    [highlightColor setFill]; 

    //Get the Rect of only the name column. This is the only column that will be highlighted. 
    //We'll intersect this rect with the row rect for the area to fill in. 
    NSInteger nameColumn = [self columnWithIdentifier:@"name"]; 
    NSRect nameColumnRect = [self rectOfColumn:nameColumn]; 

    while (currentRow < lastRow) { 
     if ([selectedRowIndexes containsIndex:currentRow]) { 
      NSRect drawRect = NSIntersectionRect([self rectOfRow:currentRow], nameColumnRect); 
      NSRectFill(drawRect); 
     } 
     currentRow++; 
    } 
} 

需要注意的是,我不得不重寫我的自定義NSCe是很重要的第一列的選定行LL子類的drawInteriorWithFrame:inView:方法來保持它從圖紙標準的亮點,像這樣:

-(void) drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView 
{ 
    //do drawing here...don't call super. 
} 

所以這是對這個問題的部分解決方案。如果這不是「正確」的方式,請讓我知道:)。

點擊/拖移VIS/LOCK列應該不會改變選擇 現在我已經決定,我應該在

-(NSIndexSet *) outlineView:(NSOutlineView *)outlineView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes 

方法來這樣做。如果我處於源於可見性或鎖定列的拖動中,我只返回當前selectedRows以保持選擇相同。我還沒有實現,但是一旦我解決了最終的問題,它應該很容易(見下文)。

向上拖動或向下能見度中/鎖定列,以改變它們的狀態

我得到真正貼近這一個。在我的自定義的NSCell,我已經覆蓋了以下三種方法:

-(BOOL) startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView 
-(BOOL) continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView 
-(void) stopTracking:(NSPoint) lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag 

我到我的最後一個問題,那就是:我需要知道,當我在拖動操作中當拖動操作結束。有兩種方法我可以這樣做:

如果我在我的NSCell子類不覆蓋

+(BOOL) prefersTrackingUntilMouseUp 

(所以它返回默認值),則然後我收到stopTracking:在:inView: mouseIsUp:每當我離開一個單元格並在拖動操作過程中轉到下一個 ...這意味着我無法使用該方法來確定拖動操作何時完成。

相反,如果我做覆蓋

+(BOOL) prefersTrackingUntilMouseUp 

,並返回YES,我得到一個stopTracking:...調用只老鼠了,這是偉大的......但問題是,沒有按表似乎沒有在mouseDown上更新單元的UI,或者當我在單元格內拖動時。例如,在startTracking:...方法中,如果我將單元格的objectValue設置爲nil(以使其圖像不再顯示),則直到鼠標按鈕恢復或光標離開時纔會看到更新細胞。 (當prefersTrackingUntilMouseUp返回NO時,它立即更新)。

所以我需要既能夠立即更新(在鼠標按下)細胞的UI也有辦法的拖動操作完成時就知道了。這是拼圖的最後一部分。誰能幫忙?

+0

終於明白出了什麼問題。我的「drawInteriorWithFrame」繪製單元格的圖像屬性...不是它的對象值。直到鼠標離開單元后,圖像纔得到更新! –

+0

因爲我可以看到這是你的問題的最終答案只是接受它,以便其他人可以按照這個答案,如果他們有同樣的問題 –

+0

謝謝...我是新來的! –