This is UITabActionCell.m in view mode; [Download] [Up]
/* UITabActionCell.m * * By Bill Edney, Sean Hill, Mark Onyschuk, and Art Isbell * */ #import "UITabActionCell.h" #import <appkit/appkit.h> #import <objc/List.h> #import "drawTab.h" // pswrap that draws tab ends. @implementation UITabActionCell // Methods Overridden From the Superclass - initTextCell:(const char *)aString // Initializes a new instance of the receiver. { [super initTextCell:aString]; // finish the initialization process [self finishInitializing]; return self; } - awake // Performs additional intialization of the receiver after reading // from an NXTypedStream. { // do the superclass' awake method [super awake]; // finish the initializing process [self finishInitializing]; return self; } - setFont:fontObj // Sets the receiver's font to <fontObj> and fetches font info used // during the receiver's display. { NXCoord lineHeight; // Do the superclass' init method [super setFont:fontObj]; // Grab the font information for the contents of the cell NXTextFontInfo(fontObj, &ascender, &descender, &lineHeight); // Set tabHeight to match that in EOF IB's StackView. This results in a // height of 17 for Helvetica 12. tabHeight = lineHeight - descender + 5.0; // Set tabBezierImageWidth to provide reasonable scaling behavior. tabBezierImageWidth = tabHeight * 14.0 / 17.0; return self; } - drawInside:(const NXRect *)cellFrame inView:controlView // Draws the receiver inside <cellFrame> in view <controlView>. { NXCoord halfImageWidth = tabBezierImageWidth / 2.0; NXPoint leftImageOrigin, rightImageOrigin; float unselectedGray; NXRect textFrame, lowerBezelFrame; List *controlCellList; int indx, intImageWidth = (int)(tabBezierImageWidth + 0.5); // if there are no contents, then punt... if (!contents) { return self; } if([Window defaultDepthLimit]<=NX_TwoBitGrayDepth) unselectedGray = NX_DKGRAY; else unselectedGray = 0.5; // if <controlView> is not a kind of Matrix (i.e. in IB) if (![controlView isKindOf:[Matrix class]]) { [super drawInside:cellFrame inView:controlView]; return self; } // set drawing to opaque PSsetalpha(1.0); PSsetgray([controlView backgroundGray]); NXRectFill(cellFrame); // fetch information about ourselves in our Matrix controlCellList = [controlView cellList]; indx = [controlCellList indexOf:self]; // set up the lowerBezelFrame that will be used for drawing the bezel // at our bottom NXSetRect(&lowerBezelFrame, NX_X(cellFrame) + halfImageWidth, NX_MAXY(cellFrame) - 1.0, NX_WIDTH(cellFrame), 1.0); // set textFrame to cellFrame textFrame = *cellFrame; // set up the leftImageOrigin leftImageOrigin.x = NX_X(cellFrame); leftImageOrigin.y = NX_MAXY(cellFrame); // if indx is 0 (we are the first cell) if (indx == 0) { // if we are selected if ([self isSelected]) { // Draw selected left tab bezier at leftImageOrigin. drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY); } else { // Otherwise, draw left tab bezier at leftImageOrigin. drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_LTGRAY, unselectedGray); // subtract a half tabBezierImageWidth from lowerBezelFrame's x lowerBezelFrame.origin.x -= halfImageWidth; } // add a tabBezierImageWidth to textFrame's x textFrame.origin.x += tabBezierImageWidth; // subtract a tabBezierImageWidth plus half tabBezierImageWidth minus 1.0 // from textFrame's width textFrame.size.width -= tabBezierImageWidth + halfImageWidth - 1.0; } else { // subtract a half tabBezierImageWidth from leftImageOrigin's x leftImageOrigin.x -= halfImageWidth; // if the cell to left of us is selected if ([[controlCellList objectAt:indx - 1] isSelected]) { // Draw left tab bezier at leftImageOrigin. drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_LTGRAY, unselectedGray); // Draw selected right tab bezier at leftImageOrigin. drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_BLACK, NX_LTGRAY); } else if ([self isSelected]) { // otherwise, if we are selected // Draw right tab bezier at leftImageOrigin. // composite tabEndImage to leftImageOrigin drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray); // Draw selected left tab bezier at leftImageOrigin. drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_WHITE, NX_LTGRAY); } else { // Draw left tab bezier at leftImageOrigin. drawLeftTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_LTGRAY, unselectedGray); // Draw right tab bezier at leftImageOrigin. drawRightTabBezier((int)leftImageOrigin.x, (int)leftImageOrigin.y, intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray); // subtract a half tabBezierImageWidth from lowerBezelFrame's x lowerBezelFrame.origin.x -= tabBezierImageWidth; // add 1.0 to lowerBezelFrame's width lowerBezelFrame.size.width += 1.0; } // add a half tabBezierImageWidth to textFrame's x textFrame.origin.x += halfImageWidth; // subtract a tabBezierImageWidth minus 1.0 from textFrame's width textFrame.size.width -= tabBezierImageWidth - 1.0; } // if indx is less than controlCellList's count minus 1 then we're // not the last cell, and... if (indx < [controlCellList count] - 1) { // draw the cell to the right of us [controlView drawCell:[controlCellList objectAt:indx + 1]]; } else { // set up the rightImageOrigin rightImageOrigin.x = NX_X(cellFrame) + NX_WIDTH(cellFrame) - tabBezierImageWidth; rightImageOrigin.y = NX_Y(cellFrame) + NX_HEIGHT(cellFrame); // if we are selected if ([self isSelected]) { // Draw selected right tab bezier at rightImageOrigin. drawRightTabBezier((int)rightImageOrigin.x, (int)rightImageOrigin.y, intImageWidth, (int)tabHeight, NX_BLACK, NX_LTGRAY); } else { // Draw right tab bezier at rightImageOrigin. drawRightTabBezier((int)rightImageOrigin.x, (int)rightImageOrigin.y, intImageWidth, (int)tabHeight, NX_BLACK, unselectedGray); } // subtract a tabBezierImageWidth from textFrame's width textFrame.size.width -= halfImageWidth; // add a half tabBezierImageWidth to lowerBezelFrame's width lowerBezelFrame.size.width += halfImageWidth; } // erase the cell // if we are selected if ([self isSelected]) { // set our drawing color to NX_LTGRAY PSsetgray(NX_LTGRAY); } else { PSsetgray(unselectedGray); } textFrame.size.height = tabHeight; textFrame.origin.y = NX_MAXY(cellFrame) - tabHeight; // fill in textFrame NXRectFill(&textFrame); // now draw the upper bezel // set our drawing color to NX_LTGRAY // if we are selected if ([self isSelected]) { // set our drawing color to NX_LTGRAY PSsetgray(NX_WHITE); } else { PSsetgray(NX_LTGRAY); } // set textFrame's height to 1.0 textFrame.size.height = 1.0; // fill in textFrame NXRectFill(&textFrame); // now draw the text // If we are enabled, draw NX_BLACK, else draw NX_LTGRAY if ([self isEnabled]) PSsetgray(NX_BLACK); else PSsetgray(NX_LTGRAY); // draw the cell's contents if (NXDrawingStatus == NX_DRAWING && [[self font] screenFont]) [[[self font] screenFont] set]; else [[self font] set]; // The offsets were empirically set by emulating the StackView used in the // EOF IB's File Window. PSmoveto(NX_X(&textFrame) + 3.0, NX_Y(&textFrame) + tabHeight - 4.0); PSshow(contents); // if we are not selected if (![self isSelected]) { // draw the lower bezel // set our drawing color to NX_WHITE PSsetgray(NX_WHITE); // fill in lowerBezelFrame NXRectFill(&lowerBezelFrame); } return self; } - highlight:(const NXRect *)cellFrame inView:aView lit:(BOOL)flag { [super highlight:cellFrame inView:aView lit:flag]; [self drawInside:cellFrame inView:aView]; return self; } - calcCellSize:(NXSize *)theSize inRect:(const NXRect *)aRect { theSize->height = tabHeight; theSize->width = (2*tabBezierImageWidth+ [[self font] getWidthOf:[self stringValue]]); return self; } - (BOOL)trackMouse:(NXEvent *)theEvent inRect:(const NXRect *)cellFrame ofView:controlView { BOOL boolValue = [super trackMouse:(NXEvent *)theEvent inRect:(const NXRect *)cellFrame ofView:controlView]; if (theEvent->type == NX_MOUSEUP) { [self incrementState]; } return boolValue; } - (BOOL)startTrackingAt:(const NXPoint *)startPoint inView:aView { [aView sendAction]; return NO; } // Other Instance Methods - finishInitializing { // all text displayed will be in Helvetica, 12 point //[self setFont:[Font newFont:"Helvetica" size:12.0]]; [self setFont:[self font]]; // send the action on no event; we'll handle sending the event ourselves [self sendActionOn:NX_NULLEVENTMASK]; return self; } // Accessor Methods - (BOOL)isSelected { return (cFlags1.highlighted || cFlags1.state); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.