This is MiscTabButtonCell.m in view mode; [Download] [Up]
/* MiscTabButtonCell.m created by stephane on Sun 15-Dec-1996 */ // // MiscTabButtonCell.m -- // Written by Stephane Corthesy Copyright 1997 by Stephane Corthesy. // Version 1.1. All rights reserved. // Based upon MiscTabActionCell 1.5 by Sean Hill, 1995 // // This notice may not be removed from this source code. // // This object is included in the MiscKit by permission from the author // and its use is governed by the MiscKit license, found in the file // "License.rtf" in the MiscKit distribution. Please refer to that file // for a list of all applicable permissions and restrictions. // #ifdef MISCKIT #import <misckit/MiscTabButtonCell.h> #import <misckit/MiscDrawTab.h> #else #import "MiscTabButtonCell.h" #import "MiscDrawTab.h" #endif #define CURRENT_VERSION 1 #define TAB_ASPECT_RATIO (14.0 / 17.0) //Defines the ratio tabBezierImageWidth/tabBezierImageHeight @interface MiscTabButtonCell(Private) - (NSRect) _outerRectForCellFrame:(NSRect)aFrame; - (NSRect) _innerRectForCellFrame:(NSRect)aFrame; - (void) _finishInitializing; @end static float lightBorderColor; static float darkBorderColor; static float selectedFillColor; static float unselectedFillColor; @implementation MiscTabButtonCell + (void) initialize { [super initialize]; if(self == [MiscTabButtonCell class]) [self setVersion:CURRENT_VERSION]; #ifndef STRICT_OPENSTEP lightBorderColor = [[[NSColor controlLightHighlightColor] colorUsingColorSpaceName:NSDeviceWhiteColorSpace] whiteComponent]; darkBorderColor = [[[NSColor controlDarkShadowColor] colorUsingColorSpaceName:NSDeviceWhiteColorSpace] whiteComponent]; selectedFillColor = [[[NSColor controlColor] colorUsingColorSpaceName:NSDeviceWhiteColorSpace] whiteComponent]; #ifdef WIN32 unselectedFillColor = 0.5;//Because gridColor is nearly the same as controlColor! #else unselectedFillColor = [[[NSColor gridColor] colorUsingColorSpaceName:NSDeviceWhiteColorSpace] whiteComponent]; #endif WIN32 #else lightBorderColor = NSWhite; darkBorderColor = NSBlack; selectedFillColor = NSLightGray; if([NSWindow defaultDepthLimit] <= NSBestDepth(NSCalibratedWhiteColorSpace, 2, 2, YES, NULL)) unselectedFillColor = NSDarkGray; else unselectedFillColor = 0.5; #endif STRICT_OPENSTEP } - (NSRect) _outerRectForCellFrame:(NSRect)cellFrame // Returns the rectangle envelopping the whole tab, i.e. including overlapping parts { int row, col; int lastColumn = [(NSMatrix *)[self controlView] numberOfColumns] - 1; float tabBezierImageWidth = NSHeight(cellFrame) * TAB_ASPECT_RATIO; (void) [(NSMatrix *)[self controlView] getRow:&row column:&col ofCell:self]; if(col == 0){ if(col != lastColumn) cellFrame.size.width += tabBezierImageWidth / 2.0; return cellFrame; } else if(col == lastColumn) return NSInsetRect(NSOffsetRect(cellFrame, - tabBezierImageWidth / 4.0, 0.0), - tabBezierImageWidth / 4.0, 0.0); else return NSInsetRect(cellFrame, - tabBezierImageWidth / 2.0, 0.0); } - (NSRect) _innerRectForCellFrame:(NSRect)cellFrame // Returns the rectangle between the two tab ends; it has the same height as the tabs { int row, col; int lastColumn = [(NSMatrix *)[self controlView] numberOfColumns] - 1; NSRect innerRect = cellFrame; float tabBezierImageWidth = NSHeight(cellFrame) * TAB_ASPECT_RATIO; (void) [(NSMatrix *)[self controlView] getRow:&row column:&col ofCell:self]; if(col == 0) if(col == lastColumn) innerRect = NSInsetRect(innerRect, tabBezierImageWidth, 0.0); else innerRect = NSInsetRect(NSOffsetRect(innerRect, tabBezierImageWidth / 4.0, 0.0), (3.0 * tabBezierImageWidth) / 4.0, 0.0); else if(col == lastColumn) innerRect = NSInsetRect(NSOffsetRect(innerRect, - tabBezierImageWidth / 4.0, 0.0), (3.0 * tabBezierImageWidth) / 4.0, 0.0); else innerRect = NSInsetRect(innerRect, tabBezierImageWidth / 2.0, 0.0); return innerRect; } - (void) _finishInitializing { [self setButtonType:NSMomentaryPushButton]; [self setBordered:NO]; [self setBezeled:NO]; [self setHighlightsBy:NSNoCellMask]; // So we can overload super's method -drawInteriorWithFrame:inView: #ifndef STRICT_OPENSTEP [self setImageDimsWhenDisabled:YES]; #endif } - (id) init { self = [super init]; [self _finishInitializing]; return self; } - (id) initTextCell:(NSString *)aString { self = [super initTextCell:aString]; [self _finishInitializing]; return self; } - (id) initImageCell:(NSImage *)anImage { self = [super initImageCell:anImage]; [self _finishInitializing]; return self; } - (id) initWithCoder:(NSCoder *)coder { int version = [coder versionForClassName:NSStringFromClass([MiscTabButtonCell class])]; self = [super initWithCoder:coder]; switch(version){ case 0: _tbcFlags.orientation = MiscTopTab; _tbcFlags.doNotRotateText = NO; _tbcFlags.doNotRotateImage = NO; break; default: [coder decodeValueOfObjCType:@encode(unsigned int) at:&_tbcFlags]; } [self _finishInitializing]; return self; } - (void) encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeValueOfObjCType:@encode(unsigned int) at:&_tbcFlags]; } - (void) drawInteriorWithFrame:(NSRect)cellFrame inView:controlView { int row, col, lastRow, lastCol; NSRect innerRect, outerRect, contentRect; float tabBezierImageWidth; int intTabBezierImageWidth; MiscTabButtonCell *neighbourCell; BOOL isSelected; if(![controlView isKindOfClass:[NSMatrix class]]){ [super drawInteriorWithFrame:cellFrame inView:controlView]; return; } lastRow = [controlView numberOfRows] - 1; lastCol = [controlView numberOfColumns] - 1; (void) [controlView getRow:&row column:&col ofCell:self]; isSelected = [[controlView selectedCell] isEqual:self]; innerRect = [self _innerRectForCellFrame:cellFrame]; contentRect = NSInsetRect(innerRect, 0.0, 1.0);//because of the top and bottom lines tabBezierImageWidth = NSHeight(innerRect) * TAB_ASPECT_RATIO; intTabBezierImageWidth = (int) (tabBezierImageWidth); outerRect = [self _outerRectForCellFrame:cellFrame]; if(row == 0){ if([controlView drawsBackground]){ [[controlView backgroundColor] set]; NSRectFill(cellFrame); } } else{ PSsetgray(unselectedFillColor); NSRectFill(cellFrame); } if(isSelected) PSsetgray(selectedFillColor); else PSsetgray(unselectedFillColor); NSRectFill(NSInsetRect(innerRect, -1.0, 0.0)); //Because of some problems with float->int rounding, we need to use NSInsetRect() [super drawInteriorWithFrame:contentRect inView:controlView]; if(isSelected){ //If there is a neighbour cell to the left, draw its right part if(col != 0) if(neighbourCell = [controlView cellAtRow:row column:col - 1]){ NSRect aRect = [neighbourCell _innerRectForCellFrame:[controlView cellFrameAtRow:row column:col - 1]]; Misc_drawRightTabBezier((int) NSMaxX(aRect), (int) NSMaxY(aRect), intTabBezierImageWidth, (int) NSHeight(aRect), darkBorderColor, unselectedFillColor);//Unselected cell to the left } //Draw my left overlapping selected part Misc_drawLeftTabBezier((int) NSMinX(outerRect) -1.0, (int) NSMaxY(outerRect), intTabBezierImageWidth + 1, (int) NSHeight(innerRect), lightBorderColor, selectedFillColor); if(col != lastCol){ //If there is a neighbour to the right, draw its left part if(neighbourCell = [controlView cellAtRow:row column:col + 1]){ NSRect aRect = [neighbourCell _outerRectForCellFrame:[controlView cellFrameAtRow:row column:col + 1]]; Misc_drawLeftTabBezier((int) NSMinX(aRect), (int) NSMaxY(aRect), intTabBezierImageWidth, (int) NSHeight(aRect), lightBorderColor, unselectedFillColor);//Unselected cell to the right } //Draw my right overlapping selected part Misc_drawRightTabBezier((int) NSMaxX(innerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), darkBorderColor, selectedFillColor); } else{ //Draw my right selected part Misc_drawRightTabBezier((int) NSMaxX(innerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), darkBorderColor, selectedFillColor); } } else{//I'm not selected NSRect bottomLineRect = NSInsetRect(outerRect, -1.0, 0.0); //Because of some problems with float->int rounding, we need to use NSInsetRect() bottomLineRect.origin.y += NSHeight(bottomLineRect) - 1.0; bottomLineRect.size.height = 1.0; Misc_drawLeftTabBezier((int) NSMinX(outerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), lightBorderColor, unselectedFillColor); if(col != 0){ NSRect aRect; neighbourCell = [controlView cellAtRow:row column:col - 1]; aRect = [neighbourCell _innerRectForCellFrame:[controlView cellFrameAtRow:row column:col - 1]]; if([[controlView selectedCell] isEqual:neighbourCell] || (col == 1 && [controlView selectedRow] != row)){ bottomLineRect.size.width -= tabBezierImageWidth; bottomLineRect.origin.x += tabBezierImageWidth - 1.0; bottomLineRect.size.width += 1.0; //Because of some problems with float->int rounding, we need to enlarge it a bit } if([[controlView selectedCell] isEqual:neighbourCell]){ Misc_drawRightTabBezier((int) NSMaxX(aRect), (int) NSMaxY(aRect), intTabBezierImageWidth, (int) NSHeight(aRect), darkBorderColor, selectedFillColor);//Previous cell } else{ Misc_drawRightTabBezier((int) NSMaxX(aRect), (int) NSMaxY(aRect), intTabBezierImageWidth, (int) NSHeight(aRect), darkBorderColor, unselectedFillColor);//Previous cell } } if(col != lastCol){ //If next cell is not selected, draw its left part, than my right part. //Else draw only my right part if(![[controlView selectedCell] isEqual:(neighbourCell = [controlView cellAtRow:row column:col + 1])]){ NSRect aRect = [neighbourCell _outerRectForCellFrame:[controlView cellFrameAtRow:row column:col + 1]]; Misc_drawLeftTabBezier((int) NSMinX(aRect), (int) NSMaxY(aRect), intTabBezierImageWidth, (int) NSHeight(aRect), lightBorderColor, unselectedFillColor);//Next cell Misc_drawRightTabBezier((int) NSMaxX(innerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), darkBorderColor, unselectedFillColor); } else{ NSRect aRect = [neighbourCell _outerRectForCellFrame:[controlView cellFrameAtRow:row column:col + 1]]; Misc_drawRightTabBezier((int) NSMaxX(innerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), darkBorderColor, unselectedFillColor); Misc_drawLeftTabBezier((int) NSMinX(aRect) -1.0, (int) NSMaxY(aRect), intTabBezierImageWidth + 1, (int) NSHeight(aRect), lightBorderColor, selectedFillColor);//Next cell bottomLineRect.size.width -= tabBezierImageWidth; bottomLineRect.size.width += 1.0; //Because of some problems with float->int rounding, we need to enlarge it a bit } } else//I'm last on the row Misc_drawRightTabBezier((int) NSMaxX(innerRect), (int) NSMaxY(outerRect), intTabBezierImageWidth, (int) NSHeight(innerRect), darkBorderColor, unselectedFillColor); if(col == 0 && [controlView selectedRow] != row) PSsetgray(unselectedFillColor); else PSsetgray(lightBorderColor); if(col != 0 || [controlView selectedRow] == row) NSFrameRect(bottomLineRect); } //Draw top line innerRect.size.height = 1.0; innerRect = NSInsetRect(innerRect, -1.0, 0.0); //Because of some problems with float->int rounding, we need to use NSInsetRect() PSsetgray(lightBorderColor); NSFrameRect(innerRect); } - (BOOL) trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:(NSView *)controlView untilMouseUp:(BOOL)flag { BOOL boolValue = [super trackMouse:(NSEvent *)theEvent inRect:(NSRect)cellFrame ofView:controlView untilMouseUp:(BOOL)flag]; [controlView display]; if([theEvent type] == NSLeftMouseUp) [self setState:![self state]]; return boolValue; } - (BOOL) startTrackingAt:(NSPoint)startPoint inView:aView { (void)[super startTrackingAt:startPoint inView:aView]; [aView sendAction]; return NO; } - (BOOL) isOpaque { return YES; } - (NSSize) cellSizeForBounds:(NSRect)aRect { NSSize aSize = [super cellSizeForBounds:aRect]; int row, col; int lastColumn = [(NSMatrix *)[self controlView] numberOfColumns] - 1; float tabBezierImageWidth; aSize.height += 4.0; tabBezierImageWidth = aSize.height * TAB_ASPECT_RATIO; (void) [(NSMatrix *)[self controlView] getRow:&row column:&col ofCell:self]; if(col == 0) if(col == lastColumn) aSize.width += 2 * tabBezierImageWidth; else aSize.width += 1.5 * tabBezierImageWidth; else if(col == lastColumn) aSize.width += 1.5 * tabBezierImageWidth; else aSize.width += tabBezierImageWidth; return aSize; } - (void) setOrientation:(MiscTabButtonCellOrientation)orientation { _tbcFlags.orientation = orientation; } - (MiscTabButtonCellOrientation) orientation { return _tbcFlags.orientation; } - (void) setRotateImage:(BOOL)doRotateImage { _tbcFlags.doNotRotateImage = !doRotateImage; } - (BOOL) doesRotateImage { return !_tbcFlags.doNotRotateImage; } - (void) setRotateText:(BOOL)doRotateText { _tbcFlags.doNotRotateText = !doRotateText; } - (BOOL) doesRotateText { return !_tbcFlags.doNotRotateText; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.