Source List View (Mail-like) controls


大家注意到Mail.app得左下角得,那个add/remove/resize控件了嘛?






不少程序都有类似功能,最近也在Nambu.app上作了这个工作。

第一步,加上Source list view controls

把NSSplitView放到window上,加上两个button,选择为Square button,然后分别设置image为NSAddTemplate和NSRemoveTemplate.

第二步,设置这两个button得autoresize类型为保持左、下即可








第三步,这两个按钮占用了很少得空间,剩余部分,我们用个custom view来填充,这个view会处理我们第一步添加得splite view得
resize工作,并且会画三条竖线来提示用户那个区域可以作为拖动手柄。添加了custom view后,subclass这个custom view,比如
类名为NBResizeGripView. 这个custom view因为一直要保持与split view左子view同宽,因此autoresize设置为保持左、下、右,
自动放缩宽度。






到这里,我们已经画出了add/remove/resize三个控件了,并且你拉动split view的分界线,也不会出现resize问题

第四步,弄一个类,来做为split view的delegate,不妨叫做NBMainWindowController

第五步,NBMainWindowController加个指向那个resize控件的outlet
	    IBOutlet NBResizeGripView  *splitViewResizer

第六步,告诉split view,你的add/remove/resize控件的尾巴部分(画着三个竖线那块儿)也可以控制split view的大小变化。代码
如下,你要写到你的那个split view的delegate类里。

// NBMainWindow.m
// 除了那个split view分界线外,再设置一个额外的Divider,也就是那个画了三个竖线的区域
-(NSRect)splitView:(NSSplitView *)splitView additionalEffectiveRectOfDividerAtIndex:(NSInteger)dividerIndex
{
	NSRect resizeBounds = [splitViewResizer bounds]; // 得到画了三个竖线的区域的bounds
	resizeBounds.origin.x = resizeBounds.size.width - 15.0;
	resizeBounds.size.width = 15.0;
	return [splitViewResizer convertRect:resizeBounds toView:splitView];
}

第七步,就是要让我们的NBResizeGripView能够在右边画三条灰色线了.
// NBResizeGripView.m 
- (void)drawRect:(NSRect)rect
{
	// fill with gradient
	NSRect bounds = self.bounds;
	NSColor* color1 = [NSColor colorWithCalibratedRed:249.0/255
									      green:249.0/255
										blue:249.0/255
									      alpha:1.0];

	NSColor* color2 = [NSColor colorWithCalibratedRed:223.0/255
									      green:223.0/255
										blue:223.0/255
									      alpha:1.0];

	NSColor* color3 = [NSColor colorWithCalibratedRed:243.0/255
									      green:243.0/255
										blue:243.0/255
									      alpha:1.0];

	NSGradient* gradient = [[[NSGradient alloc] initWithColorsAndLocations:
			color1, 0.0,
			color2, 18.0/21.0,
			color3, 1.0,
			nil]
		autorelease];

	[gradient drawInRect:bounds angle:90.0];
	// draw the top border
	NSColor* borderColor = [NSColor grayColor:131.0/255.0];
	[borderColor setStroke];
	CGFloat y = bounds.size.height;
	CGFloat x = bounds.size.width;
	[NSBezierPath strokeLineFromPoint:NSMakePoint(0.0, y-0.5)
		toPoint:NSMakePoint(x, y-0.5)];

	// draw the grip lines
	NSColor* gripColor = [NSColor grayColor:(66.0/255.0)];
	[gripColor setStroke];
	NSInteger lineIndex;
	CGFloat lineXPos = x - 4.5;
	for (lineIndex = 0; lineIndex < 3; ++lineIndex)
	{
		[NSBezierPath strokeLineFromPoint:NSMakePoint(lineXPos, 5.5)
			toPoint:NSMakePoint(lineXPos, y-5.5)];
		lineXPos -= 3.0;
	}
}

第八步,完了,build and go.