This is VRulerView.m in view mode; [Download] [Up]
// // Time-stamp: <94/12/30 19:09:11 stephan> // // VRulerView.m // Project: Rulers // // Stephan Wacker // 93-02-11 #import "VRulerView.h" #import "VRulerControl.h" #import "RulerPreferencesControl.h" #import "math.h" // ceil() @implementation VRulerView - initFrame: (const NXRect *) frameRect // Initialize yourself after instance has been created. { NXSize offset; [super initFrame: frameRect]; // Move origin (from left bottom corner) up // by 80% of frame height (rounded up to an integer). offset.height = ceil( 0.8 * NX_HEIGHT( frameRect ) ); offset.width = 0.0; [self moveOrigin: &offset]; // Initially, the ``valid'' cached image is a rectangle of zero width // at the very bottom edge of the ruler view. validRect.size.width = NX_WIDTH( frameRect ); imageOrigin.y = origin.y; return self; } #if 0 - drawSelf: (const NXRect *) rects : (int) rectCount // Draw the marks in the ruler image. // Background is drawn by super. { NXCoord y; int k; char str[40]; NXCoord tick_baselength, tick_length; const TickMark *mark; BOOL displayLabels = [control labelsMode]; int marksPosition = [control vMarksMode]; int posNumDirection = [control vPosNumMode]; NXFontMetrics *metrics = [markFont metrics]; // font dimensions float capHeight = metrics->capHeight * [markFont pointSize]; #if 0 [super drawSelf: rects : rectCount]; #else NXSetColor( [control color] ); NXRectFill( rects ); #endif tick_baselength = 18.0; // main mark length PSsetlinewidth( 0.25 ); // thin lines [markFont set]; // Process every set of marks. // for( mark = [self tickMarkSystem]; mark->distance > 0.0; mark++ ) { tick_length = mark->length * tick_baselength; // start with // y = k * mark->distance + origin.y, // y >= NX_Y(&bounds) for( k = (int) ceil( (NX_Y(&bounds)-origin.y)/mark->distance ), y = k * mark->distance + origin.y, k *= mark->value; y <= NX_MAXY(&bounds); k += mark->value, y += mark->distance ) { PSnewpath(); if( marksPosition & VMARKS_LEFT ) { PSmoveto( NX_X(&bounds), y ); PSrlineto( tick_length, 0.0 ); // a tick mark } if( marksPosition & VMARKS_RIGHT ) { PSmoveto( NX_MAXX(&bounds), y ); PSrlineto( -tick_length, 0.0 ); // a tick mark } NXSetColor( [control marksColor] ); PSstroke(); // draw one tick mark if( displayLabels ) { if( mark->value > 0 ) { NXRect markFrame; sprintf( str, "%d", k < 0 ? ((posNumDirection & POSNUM_DOWN) ? -k : k) : ((posNumDirection & POSNUM_UP ) ? k : -k) ); NX_WIDTH(&markFrame) = [markFont getWidthOf: str] + 4.0; NX_HEIGHT(&markFrame) = capHeight + 4.0; NX_X(&markFrame) = 0.5 * (NX_WIDTH(&bounds) - NX_WIDTH(&markFrame)); NX_Y(&markFrame) = ceil( y - 0.5 * NX_HEIGHT(&markFrame) ); NXSetColor( [control color] ); // background of labels NXRectFill( &markFrame ); PSmoveto( NX_X(&markFrame) + 2.0, NX_Y(&markFrame) + 2.0 ); NXSetColor( [control marksColor] ); PSshow( str ); } else if( mark->value < 0 ) { // display a fraction like `3/8' // !toDo! } } } } return self; } #endif - drawMarks: (const NXRect *) aRect // Draw the marks in the ruler image. // aRect is given in Ruler coordinates. // Background is drawn by super. // Drawing is lockFocused in cachedImage. { NXCoord y; int k; char str[40]; NXCoord tick_baselength, tick_length; const TickMark *mark; BOOL displayLabels = [control labelsMode]; int marksPosition = [control vMarksMode]; int posNumDirection = [control vPosNumMode]; NXFontMetrics *metrics = [markFont metrics]; // font dimensions float capHeight = metrics->capHeight * [markFont pointSize]; tick_baselength = 18.0; // main mark length PSsetlinewidth( 0.25 ); // thin lines [markFont set]; // Process every set of marks. // for( mark = [self tickMarkSystem]; mark->distance > 0.0; mark++ ) { tick_length = mark->length * tick_baselength; // start with // y = k * mark->distance + imageOrigin.y, // y < NX_Y(&bounds) for( k = (int) ceil( (NX_Y(aRect)-imageOrigin.y)/mark->distance ) - 1, y = k * mark->distance + imageOrigin.y + 0.25, k *= mark->value; y < NX_MAXY(aRect) + mark->distance; k += mark->value, y += mark->distance ) { PSnewpath(); if( marksPosition & VMARKS_LEFT ) { PSmoveto( NX_X(&bounds), y ); PSrlineto( tick_length, 0.0 ); // a tick mark } if( marksPosition & VMARKS_RIGHT ) { PSmoveto( NX_MAXX(&bounds), y ); PSrlineto( -tick_length, 0.0 ); // a tick mark } NXSetColor( [control marksColor] ); PSstroke(); // draw one tick mark if( displayLabels ) { if( mark->value > 0 ) { NXRect markFrame; sprintf( str, "%d", k < 0 ? ((posNumDirection & POSNUM_DOWN) ? -k : k) : ((posNumDirection & POSNUM_UP ) ? k : -k) ); NX_WIDTH(&markFrame) = [markFont getWidthOf: str] + 4.0; NX_HEIGHT(&markFrame) = capHeight + 4.0; NX_X(&markFrame) = 0.5 * (NX_WIDTH(&bounds) - NX_WIDTH(&markFrame)); NX_Y(&markFrame) = ceil( y - 0.5 * NX_HEIGHT(&markFrame) ); NXSetColor( [control color] ); // background of labels NXRectFill( &markFrame ); PSmoveto( NX_X(&markFrame) + 2.0, NX_Y(&markFrame) + 2.0 ); NXSetColor( [control marksColor] ); PSshow( str ); } else if( mark->value < 0 ) { // display a fraction like `3/8' // !toDo! } } } } return self; } - (NXCoord) constrainDistance: (NXCoord) distance frame: (NXRect *) frameRect // PRIVATE // Change the frameRect's height by distance. // Observe minimum and maximum sizes. // Answer actual height change. { NXSize minSize, maxSize; NXCoord minDist, maxDist; NXCoord result = distance + off; [window getMinSize: &minSize]; [window getMaxSize: &maxSize]; maxDist = maxSize.height - NX_HEIGHT( frameRect ); minDist = minSize.height - NX_HEIGHT( frameRect ); off = 0; if( result < minDist ) { off = result - minDist; result = minDist; } if( result > maxDist ) { off = result - maxDist; result = maxDist; } if( result * distance < 0.0 ) // cancel opposite direction { off += result; result = 0.0; } NX_HEIGHT( frameRect ) += result; return result; } - sizeTop: (const NXSize *) delta // Change the window's height by delta (at the top). // Positive distance increases height. { NXCoord distance = delta->height; if( !(distance = [self constrainDistance: distance frame: &rubberRect]) ) return nil; // size is not changed [self drawRubberband]; return self; } - sizeBottom: (const NXSize *) delta // Change the window's height by delta (at the bottom). // Positive distance decreases height. { NXCoord distance = -delta->height; if( !(distance = [self constrainDistance: distance frame: &rubberRect]) ) return nil; // size is not changed NX_Y( &rubberRect ) -= distance; // move bottom edge origin.y += distance; // adjust local origin [self drawRubberband]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.