home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************
- * CLASS: MiscArrowButtonCell
- *
- * See the header for more information on this class.
- *
- * 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.
- *******************************************************************/
-
- #import "wraps.h"
- #import <dpsclient/psops.h>
- #import <apps/InterfaceBuilder.h>
- #import "MiscArrowButtonCell.h"
-
-
- @implementation MiscArrowButtonCell
-
- // The initializing methods just call the designated initializer
- // and give some default values.
-
- - init
- {
- return [self initTextCell: "Left" altTitle: "Right"];
- }
-
-
-
- - initTextCell: (const char *)aString
- {
- return [self initTextCell: aString altTitle: "Right"];
- }
-
-
-
- // The desinated initializer for this class.
-
- - initTextCell: (const char *)aString altTitle: (const char *)altString
- {
- [super initTextCell: aString];
-
- [self setAltTitle: altString];
- [self setState: 0];
- [self setBordered: NO];
- [self setShowsStateBy: NX_NONE];
- [self setHighlightsBy: NX_NONE];
- [self setArrowAlignment: MISC_ARROW_ABSOLUTE];
- [self setType: NX_TOGGLE];
-
- return self;
- }
-
-
-
- // Since the stringValue in Button does not do much, it now
- // returns the currently selected text.
-
- - (const char *)stringValue
- {
- if ([self state] == 0)
- return (const char *)[self title];
- else
- return (const char *)[self altTitle];
- }
-
-
-
- // I believe this method is supposed to calculate the minimum size needed to
- // fit the currently displayed contents (contents, altContents, and the arrow)
- // in the cellframe.
-
- - calcCellSize: (NXSize *)theSize inRect: (NXRect *)theRect
- {
- float contentsWidth = [ [self font] getWidthOf: [self title] ];
- float altContentsWidth = [ [self font] getWidthOf: [self altTitle] ];
-
- // first calculate the width needed to draw all text and the arrow
-
- theSize->width = 0.0;
- if ([self arrowAlignment] == MISC_ARROW_RELATIVE)
- {
- theSize->width += contentsWidth;
- theSize->width += altContentsWidth;
- }
- else // absolute alignment
- {
- if (contentsWidth > altContentsWidth)
- theSize->width += contentsWidth * 2.0;
- else
- theSize->width += altContentsWidth * 2.0;
- }
-
- theSize->width += cellHeight + 10.0;
-
- // now the height (which will usually be cellHeight)
-
- theSize->height = cellHeight;
-
- if ([ [self font] pointSize] > cellHeight)
- theSize->height = [ [self font] pointSize];
-
- return self;
- }
-
-
-
- // As far as I can tell (which may not be all that far) is that this
- // function is only used by the Button's IBEditor to tell how large
- // the editor should be.
-
- - getTitleRect : (NXRect *)theRect
- {
- float size = [ [self font] pointSize];
- float theY;
- float maxWidth = theRect->size.width/2.0;
-
- // this is a hack so you can double click on the altTitle in IB
-
- if ([self state])
- return [self getAltTitleRect: theRect];
-
- [self setAlignment: NX_LEFTALIGNED]; // used for the IBEditor
-
- theY = theRect->origin.y + theRect->size.height/2.0 - size/2.0;
-
- if ([self arrowAlignment] == MISC_ARROW_RELATIVE)
- maxWidth = [ [self font] getWidthOf: [self title] ] + 10.0;
-
- NXSetRect (theRect, theRect->origin.x, theY-2.0, maxWidth, size+2.0);
-
- return self;
- }
-
-
-
- // If the state is 1 (altContents selected), then this method will be
- // called. It returns the location for editor to appear when editing
- // the altContents.
-
- - getAltTitleRect: (NXRect *)theRect
- {
- float size = [ [self font] pointSize];
- float newX, newY, newWidth;
-
- [self setAlignment: NX_RIGHTALIGNED]; // used for the IBEditor
-
- newX = theRect->origin.x + theRect->size.width/2.0;
- newY = theRect->origin.y + theRect->size.height/2.0 - size/2.0;
- newWidth = theRect->size.width/2.0;
-
- NXSetRect (theRect, newX, newY-2.0, newWidth, size+2.0);
-
- return self;
- }
-
-
-
- // New method to set the alignment of the arrow. MISC_ARROW_ABSOLUTE aligns
- // the arrow in the center of the cellFrame, where MISC_ARROW_RELATIVE
- // centers the arrow between the contents and altContents.
-
- - setArrowAlignment: (int)alignment
- {
- arrowAlignment = alignment;
- return self;
- }
-
-
-
- - (int)arrowAlignment
- {
- return arrowAlignment;
- }
-
-
-
- // This method is used to draw only the parts of the cell that
- // do change when the state changes. Therefore, only the black arrow
- // and the text are drawn here.
-
- - drawInside: (const NXRect *)cellFrame inView: controlView
- {
- float gray;
- float size = [ [self font] pointSize];
-
- // draw the arrow
-
- if ([self arrowAlignment] == MISC_ARROW_RELATIVE)
- {
- NXRect relativeFrame;
- float contentsWidth = [ [self font] getWidthOf: [self title] ];
- float altContentsWidth = [ [self font] getWidthOf: [self altTitle] ];
-
- // since it the arrow is drawn relative to the text, a little
- // calculation is needed
-
- relativeFrame.origin.x = cellFrame->origin.x + contentsWidth;
- relativeFrame.size.width = cellFrame->size.width -
- (contentsWidth + altContentsWidth);
-
- PSABdrawarrow (relativeFrame.origin.x, cellFrame->origin.y + 3.0,
- relativeFrame.size.width, cellFrame->size.height - 6.0,
- (int)[self state], [self isEnabled]);
- }
- else
- // draw the arrow in the center of the cellFrame
-
- PSABdrawarrow (cellFrame->origin.x, cellFrame->origin.y + 3.0,
- cellFrame->size.width, cellFrame->size.height - 6.0,
- (int)[self state], [self isEnabled]);
-
- // draw the left and right hand text
-
- [ [self font] set];
-
- if ([self title] != NULL)
- {
- float theY;
-
- if ([self state] || ![self isEnabled])
- gray = NX_DKGRAY;
- else
- gray = 0.0;
-
- // calculate the placement of the contents and print it
-
- theY = cellFrame->origin.y + cellFrame->size.height/2.0 + size/3.0;
-
- PSABshowstring (cellFrame->origin.x + 3.0, theY, gray, [self title]);
- }
-
- if ([self altTitle] != NULL)
- {
- float theX, theY;
- float strWidth = [ [self font] getWidthOf: [self altTitle] ];
-
- if ([self state] && [self isEnabled])
- gray = 0.0;
- else
- gray = NX_DKGRAY;
-
- // calculate the placement of the altContents and print it
-
- theX = cellFrame->origin.x+(cellFrame->size.width - strWidth - 3.0);
- theY = cellFrame->origin.y + cellFrame->size.height/2.0 + size/3.0;
-
- PSABshowstring (theX, theY, gray, [self altTitle]);
- }
-
- return self;
- }
-
-
-
- // This part of the drawing displays only the parts that don't change
- // often, which includes the diamond that encloses the arrow, and the
- // border when I get around to adding one.
-
- - drawSelf: (const NXRect *)cellFrame inView: controlView
- {
- // if transparent draw the background white (when in IB) and
- // same as the background when in an app (or testing interface)
-
- if ([self isTransparent])
- {
- if ([NXApp respondsTo: @selector(isTestingInterface)])
- if ([NXApp isTestingInterface])
- PSsetgray (NX_LTGRAY);
- else
- PSsetgray (1.0);
- else
- PSsetgray (NX_LTGRAY);
-
- NXRectFill (cellFrame);
-
- return self;
- }
-
- // set cellHeight since some of the calculations that are in other
- // methods have to know the height of the cell (this is probably the
- // wrong way to go about this)
-
- cellHeight = cellFrame->size.height;
-
- // draw the border or bezel, then call drawInside
-
- if ([self isBordered])
- NXDrawButton (cellFrame, cellFrame);
-
- PSgsave();
-
- // have to flip drawing if we are drawing into a flipped view
-
- if ([controlView isFlipped])
- PSABflipme (cellFrame->size.height + (cellFrame->origin.y * 2.0));
-
- if ([self arrowAlignment] == MISC_ARROW_RELATIVE)
- {
- NXRect relativeFrame;
- float contentsWidth = [ [self font] getWidthOf: [self title] ];
- float altContentsWidth = [ [self font] getWidthOf: [self altTitle] ];
-
- relativeFrame.origin.x = cellFrame->origin.x + contentsWidth;
- relativeFrame.size.width = cellFrame->size.width -
- (contentsWidth + altContentsWidth);
-
- PSABdrawdiamond (relativeFrame.origin.x, cellFrame->origin.y + 3.0,
- relativeFrame.size.width, cellFrame->size.height - 6.0);
- }
- else
- PSABdrawdiamond (cellFrame->origin.x, cellFrame->origin.y + 3.0,
- cellFrame->size.width, cellFrame->size.height - 6.0);
-
- PSgrestore();
-
- // draw the rest of the cell
-
- [self drawInside: cellFrame inView: controlView];
-
- return self;
- }
-
-
-
- // Archiving methods
-
- - read: (NXTypedStream *)stream
- {
- [super read: stream];
-
- // NXReadType (stream, @encode(unsigned int), &arrowAlignment);
- return self;
- }
-
-
-
- - write: (NXTypedStream *)stream
- {
- [super write: stream];
-
- // NXWriteType (stream, @encode(unsigned int), &arrowAlignment);
- return self;
- }
-
- @end
-
-
-
- @implementation MiscArrowButtonCell (IB)
-
- // This is used in IB when inspecting a matrix full of ArrowButton
- // cells. We just use the same inspector that ArrowButton uses.
-
- - (const char *)getInspectorClassName
- {
- return "ABInspector";
- }
-
-
-
- // Here for when NeXT gets around to disclosing the rest of the API
- // for IBEditors.
-
- - (const char *)getEditorClassName
- {
- return "ArrowButtonEditor";
- }
-
- @end
-
-