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.