//// BWTransparentScroller.m// BWToolkit//// Created by Brandon Walkin (www.brandonwalkin.com)// All code is provided under the New BSD license.//#import "BWTransparentScroller.h"// Vertical scrollerstaticNSImage*knobTop,*knobVerticalFill,*knobBottom,*slotTop,*slotVerticalFill,*slotBottom;staticfloatverticalPaddingLeft=0.0;staticfloatverticalPaddingRight=1.0;staticfloatverticalPaddingTop=2.0;staticfloatverticalPaddingBottom=0.0;staticfloatminKnobHeight;// Horizontal scrollerstaticNSImage*knobLeft,*knobHorizontalFill,*knobRight,*slotLeft,*slotHorizontalFill,*slotRight;staticfloathorizontalPaddingLeft=2.0;staticfloathorizontalPaddingRight=2.0;staticfloathorizontalPaddingTop=0.0;staticfloathorizontalPaddingBottom=1.0;staticfloatminKnobWidth;staticNSColor*backgroundColor;@interfaceBWTransparentScroller(BWTSPrivate)-(void)drawKnobSlot;@end@interfaceNSScroller(BWTSPrivate)-(NSRect)_drawingRectForPart:(NSScrollerPart)aPart;@end@implementationBWTransparentScroller+(void)initialize{NSBundle*bundle=[NSBundlebundleForClass:[BWTransparentScrollerclass]];// Vertical scrollerknobTop=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobTop.tif"]];knobVerticalFill=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobVerticalFill.tif"]];knobBottom=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobBottom.tif"]];slotTop=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotTop.tif"]];slotVerticalFill=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotVerticalFill.tif"]];slotBottom=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotBottom.tif"]];// Horizontal scrollerknobLeft=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobLeft.tif"]];knobHorizontalFill=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobHorizontalFill.tif"]];knobRight=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerKnobRight.tif"]];slotLeft=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotLeft.tif"]];slotHorizontalFill=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotHorizontalFill.tif"]];slotRight=[[NSImagealloc]initWithContentsOfFile:[bundlepathForImageResource:@"TransparentScrollerSlotRight.tif"]];backgroundColor=[[NSColorcolorWithCalibratedWhite:0.13alpha:0.855]retain];minKnobHeight=knobTop.size.height+knobVerticalFill.size.height+knobBottom.size.height+10;minKnobWidth=knobLeft.size.width+knobHorizontalFill.size.width+knobRight.size.width+10;}-(id)initWithFrame:(NSRect)frameRect;{if(self=[superinitWithFrame:frameRect]){[selfsetArrowsPosition:NSScrollerArrowsNone];if([selfbounds].size.width/[selfbounds].size.height<1)isVertical=YES;elseisVertical=NO;}returnself;}-(id)initWithCoder:(NSCoder*)decoder;{if(self=[superinitWithCoder:decoder]){[selfsetArrowsPosition:NSScrollerArrowsNone];if([selfbounds].size.width/[selfbounds].size.height<1)isVertical=YES;elseisVertical=NO;}returnself;}+(CGFloat)scrollerWidth{returnslotVerticalFill.size.width+verticalPaddingLeft+verticalPaddingRight;}+(CGFloat)scrollerWidthForControlSize:(NSControlSize)controlSize{returnslotVerticalFill.size.width+verticalPaddingLeft+verticalPaddingRight;}-(void)drawRect:(NSRect)aRect;{[backgroundColorset];NSRectFill([selfbounds]);// Only draw if the slot is larger than the knobif(isVertical&&([selfbounds].size.height-verticalPaddingTop-verticalPaddingBottom+1)>minKnobHeight){[selfdrawKnobSlot];if([selfknobProportion]>0.0)[selfdrawKnob];}elseif(!isVertical&&([selfbounds].size.width-horizontalPaddingLeft-horizontalPaddingRight+1)>minKnobWidth){[selfdrawKnobSlot];if([selfknobProportion]>0.0)[selfdrawKnob];}}-(void)drawKnobSlot;{NSRectslotRect=[selfrectForPart:NSScrollerKnobSlot];if(isVertical)NSDrawThreePartImage(slotRect,slotTop,slotVerticalFill,slotBottom,YES,NSCompositeSourceOver,1,NO);elseNSDrawThreePartImage(slotRect,slotLeft,slotHorizontalFill,slotRight,NO,NSCompositeSourceOver,1,NO);}-(void)drawKnob;{NSRectknobRect=[selfrectForPart:NSScrollerKnob];if(isVertical)NSDrawThreePartImage(knobRect,knobTop,knobVerticalFill,knobBottom,YES,NSCompositeSourceOver,1,NO);elseNSDrawThreePartImage(knobRect,knobLeft,knobHorizontalFill,knobRight,NO,NSCompositeSourceOver,1,NO);}-(NSRect)_drawingRectForPart:(NSScrollerPart)aPart;{// Call super even though we're not using its value (has some side effects we need)[super_drawingRectForPart:aPart];// Return our own rects rather than use the default behaviorreturn[selfrectForPart:aPart];}-(NSRect)rectForPart:(NSScrollerPart)aPart;{switch(aPart){caseNSScrollerNoPart:return[selfbounds];break;caseNSScrollerKnob:{NSRectknobRect;NSRectslotRect=[selfrectForPart:NSScrollerKnobSlot];if(isVertical){floatknobHeight=roundf(slotRect.size.height*[selfknobProportion]);if(knobHeight<minKnobHeight)knobHeight=minKnobHeight;floatknobY=slotRect.origin.y+roundf((slotRect.size.height-knobHeight)*[selffloatValue]);knobRect=NSMakeRect(verticalPaddingLeft,knobY,slotRect.size.width,knobHeight);}else{floatknobWidth=roundf(slotRect.size.width*[selfknobProportion]);if(knobWidth<minKnobWidth)knobWidth=minKnobWidth;floatknobX=slotRect.origin.x+roundf((slotRect.size.width-knobWidth)*[selffloatValue]);knobRect=NSMakeRect(knobX,horizontalPaddingTop,knobWidth,slotRect.size.height);}returnknobRect;}break;caseNSScrollerKnobSlot:{NSRectslotRect;if(isVertical)slotRect=NSMakeRect(verticalPaddingLeft,verticalPaddingTop,[selfbounds].size.width-verticalPaddingLeft-verticalPaddingRight,[selfbounds].size.height-verticalPaddingTop-verticalPaddingBottom);elseslotRect=NSMakeRect(horizontalPaddingLeft,horizontalPaddingTop,[selfbounds].size.width-horizontalPaddingLeft-horizontalPaddingRight,[selfbounds].size.height-horizontalPaddingTop-horizontalPaddingBottom);returnslotRect;}break;caseNSScrollerIncrementLine:returnNSZeroRect;break;caseNSScrollerDecrementLine:returnNSZeroRect;break;caseNSScrollerIncrementPage:{NSRectincrementPageRect;NSRectknobRect=[selfrectForPart:NSScrollerKnob];NSRectslotRect=[selfrectForPart:NSScrollerKnobSlot];NSRectdecPageRect=[selfrectForPart:NSScrollerDecrementPage];if(isVertical){floatknobY=knobRect.origin.y+knobRect.size.height;incrementPageRect=NSMakeRect(verticalPaddingLeft,knobY,knobRect.size.width,slotRect.size.height-knobRect.size.height-decPageRect.size.height);}else{floatknobX=knobRect.origin.x+knobRect.size.width;incrementPageRect=NSMakeRect(knobX,horizontalPaddingTop,(slotRect.size.width+horizontalPaddingLeft)-knobX,knobRect.size.height);}returnincrementPageRect;}break;caseNSScrollerDecrementPage:{NSRectdecrementPageRect;NSRectknobRect=[selfrectForPart:NSScrollerKnob];if(isVertical)decrementPageRect=NSMakeRect(verticalPaddingLeft,verticalPaddingTop,knobRect.size.width,knobRect.origin.y-verticalPaddingTop);elsedecrementPageRect=NSMakeRect(horizontalPaddingLeft,horizontalPaddingTop,knobRect.origin.x-horizontalPaddingLeft,knobRect.size.height);returndecrementPageRect;}break;default:break;}returnNSZeroRect;}@end