This is RulerControl.m in view mode; [Download] [Up]
// // Time-stamp: <95/12/08 22:57:29 stephan> // // RulerControl.m // Project: Rulers // // Stephan Wacker // 93-01-31 #import "RulerControl.h" #import "RulerView.h" #import "RulerPreferencesControl.h" #import "RulerManager.h" #import "RulerPanel.h" #import "SuperimposedObject.h" @implementation RulerControl - (int) unitsMode // Answer the current units mode. { return unitsSystem; } - setUnitsMode: (int) system // Set new units mode. // PRIVATE { if( unitsSystem != system ) { unitsSystem = system; [view setCacheInvalid]; } return self; } #if 0 # - (int) screenMode // Answer the current screen mode. { id preferences = [[NXApp delegate] preferencesControl]; if( preferences ) { return [preferences screenMode]; } else { return [RulerPreferencesControl defaultScreenMode]; } } #else # - (float) screenDpi // Answer the current screen dpi setting. { id preferences = [[NXApp delegate] preferencesControl]; if( preferences ) { return [preferences screenDpi]; } else { return [RulerPreferencesControl defaultScreenDpi]; } } # #endif - (int) inchMode // Answer the current inch mode. { return inchMode; } - setInchMode: (int) mode // Set new inch mode. // PRIVATE { if( inchMode != mode ) { inchMode = mode; [view setCacheInvalid]; } return self; } - (BOOL) labelsMode // Answer current labels mode. { return displayLabels; } - setLabelsMode: (BOOL) enabled // Set new labels mode. // PRIVATE { if( displayLabels != enabled ) { displayLabels = enabled; [view setCacheInvalid]; } return self; } - (BOOL) floatMode // Answer current float mode. { return floatAboveWindows; } - setFloatMode: (BOOL) enabled // Set new float mode. // PRIVATE { // According to the documentation the Ruler windows don't qualify for // floating panels because // -- they become the key window, // -- they remain on-screen when the application is deactivated. // But we want to make the rulers float above other application // windows, too. floatAboveWindows = enabled; [window setFloatingPanel: enabled]; return self; } - (BOOL) hideMode // Answer current hide mode. { return hideWhenDeactivated; } - setHideMode: (BOOL) enabled // Set new hide mode. // PRIVATE { hideWhenDeactivated = enabled; [window setHideOnDeactivate: enabled]; return self; } - (NXColor) color // Answer current color. { return color; } - (NXColor) marksColor // Answer current color for drawing the marks and numbers. { return marksColor; } - setColor: (NXColor) col // Set new color. // See also subclasses. { float r, g, b; color = col; // The RulerView will take the new color automatically. // The other controls, however, need to have their images changed. [self makeColoredImage: &knobImage[0] shape: "RulerKnob" mask: "RulerKnobMask"]; [knob setImage: knobImage[0]]; [self makeColoredImage: &knobImage[1] shape: "RulerKnobH" mask: "RulerKnobMask"]; [knob setAltImage: knobImage[1]]; // Select the marks color: If the ruler color is very dark we use // white instead of black. // NXConvertColorToRGB( color, &r, &g, &b ); if( 1.2*r + 1.5*g + b < 0.3 ) { marksColor = NX_COLORWHITE; } else { marksColor = NX_COLORBLACK; } [view setCacheInvalid]; return self; } - window // Answer ruler window. { return window; } #define INIT_LOCATION_OFFSET 12 - initLocation // Place the window next to the current main ruler. { id ref = [[NXApp delegate] mainRuler]; NXRect refRect, rect; NXSize screenSize; if( ! ref ) return nil; [[ref window] getFrame: &refRect]; [window getFrame: &rect]; [NXApp getScreenSize: &screenSize]; // Make top left corner equal to reference. rect.origin.x = refRect.origin.x; rect.origin.y = refRect.origin.y + refRect.size.height - rect.size.height; // Make sure the window is completely visible. if( rect.origin.x < 0 ) { rect.origin.x = 0; } else if( rect.origin.x + rect.size.width > screenSize.width ) { rect.origin.x = screenSize.width - rect.size.width; } if( rect.origin.y < 0 ) { rect.origin.y = 0; } else if( rect.origin.y + rect.size.height > screenSize.height ) { rect.origin.y = screenSize.height - rect.size.height; } // Move towards the center of the screen. if( rect.origin.x + rect.size.width/2 < screenSize.width/2 ) { rect.origin.x += INIT_LOCATION_OFFSET; } else { rect.origin.x -= INIT_LOCATION_OFFSET; } if( rect.origin.y + rect.size.height/2 < screenSize.height/2 ) { rect.origin.y += INIT_LOCATION_OFFSET; } else { rect.origin.y -= INIT_LOCATION_OFFSET; } // Move the window to its initial location. [window moveTo: rect.origin.x : rect.origin.y]; return self; } - awakeFromNib // Initialize yourself after nib file has been loaded. { static int nextId = 0; id preferences = [[NXApp delegate] preferencesControl]; if( preferences ) { [self takePreferencesFrom: preferences]; } else { [self setUnitsMode: [RulerPreferencesControl defaultUnitsMode]]; // The screen mode is not an instance variable. [self setInchMode: [RulerPreferencesControl defaultInchMode]]; [self setLabelsMode: [RulerPreferencesControl defaultLabelsMode]]; [self setFloatMode: [RulerPreferencesControl defaultFloatMode]]; [self setHideMode: [RulerPreferencesControl defaultHideMode]]; [self setColor: [RulerPreferencesControl defaultColor]]; } myId = nextId ++; [self initLocation]; // The following statement in the RulerView's initFrame: method // doesn't work. It seems that the window is not yet placed // correctly on the screen and the translation to screen coordinates // gives wrong results. Therefore we choose this place to complete // the initialization. // [view synchScreenOrigin]; [window makeKeyAndOrderFront: nil]; return self; } - drag: sender // Drag the ruler window across the screen. // If the window is not dragged it becomes the key window // and the application is activated. { NXEvent *event = [NXApp currentEvent]; // MouseDown NXEvent nextEvent; int oldMask = [window eventMask]; int trackMask = NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK; // The next event determines whether we're dragging or not. [window setEventMask: (oldMask | trackMask)]; [NXApp peekNextEvent: trackMask into: &nextEvent waitFor: NX_FOREVER threshold: NX_MODALRESPTHRESHOLD ]; if( nextEvent.type == NX_MOUSEUP ) { [window makeKeyAndOrderFront: nil]; [NXApp activateSelf: YES]; } else { [window dragFrom: event->location.x : event->location.y eventNum: event->data.mouse.eventNum ]; rulerWasDragged = ([sender tag] > 0); // see windowDidMove: below } [window setEventMask: oldMask]; return self; } - resize: (SEL) action // Resize ruler window using action. { [view showRubberband]; [view trackMouseFor: view action: action]; [view hideRubberband]; [[window delegate] windowDidResize: nil]; // not generated automatically return self; } - applyPreferences: sender // Get current settings from the preferences control panel. { [self takePreferencesFrom: sender]; [window display]; return self; } - takePreferencesFrom: sender // Get all preferences settings from the sender object. // Subclasses may ask for more preferences and finish with // return [super takePreferencesFrom: sender]. { [self setUnitsMode: [sender unitsMode]]; // The screen mode is not an instance variable. [self setInchMode: [sender inchMode]]; [self setLabelsMode: [sender labelsMode]]; [self setFloatMode: [sender floatMode]]; [self setHideMode: [sender hideMode]]; [self setColor: [sender color]]; return self; } // Some aspects of the ruler can be controlled by keystrokes. // - keyDown: (NXEvent *) theEvent { switch( theEvent->data.key.charSet ) { case NX_ASCIISET: switch( theEvent->data.key.charCode ) { case 'c': [self setUnitsMode: UNIT_CM]; break; case 'C': [self setUnitsMode: UNIT_TRUE_CM]; break; case 'f': [self setFloatMode: ! [self floatMode]]; break; case 'h': [self setHideMode: ! [self hideMode]]; break; case 'i': [self setUnitsMode: UNIT_IN]; break; case 'I': [self setUnitsMode: UNIT_TRUE_IN]; break; case 'p': [self setUnitsMode: UNIT_PC]; break; case 't': [self setUnitsMode: UNIT_PT]; break; case '8': [self setInchMode: INCH_DIV_8]; break; case '0': [self setInchMode: INCH_DIV_10]; break; default: return nil; } // switch charCode break; // case NX_ASCIISET case NX_SYMBOLSET: switch( theEvent->data.key.charCode ) { default: return nil; } // switch charCode break; // case NX_SYMBOLSET } // switch charSet [window display]; return self; // event was handled } - makeColoredImage: (NXImage **) canvas shape: (const char *) shapeName mask: (const char *) maskName // Compose an image with the given shape and the current color. // The mask defines transparent areas. // If the shape icon doesn't exist, the image is filled with the color. // If the mask icon doesn't exist, the image is opaque. { NXImage *shape; NXImage *mask; NXRect rect; shape = [NXImage findImageNamed: shapeName]; mask = [NXImage findImageNamed: maskName]; // Create a new image having the same size as the shape. [shape getSize: &rect.size]; rect.origin.x = rect.origin.y = 0; if( ! *canvas ) { *canvas = [[NXImage alloc] initSize: &rect.size]; [*canvas useCacheWithDepth: NX_TwelveBitRGBDepth]; } // Draw into the canvas image. [*canvas lockFocus]; // Fill it with the current color. NXSetColor( [self color] ); NXRectFill( &rect ); // Composite the shape over it; the shape's transparency will determine // where the color is visible. [shape composite: NX_SOVER toPoint: &rect.origin]; // Composite the mask over it; the image will take on the transparency // of the mask. [mask composite: NX_DIN toPoint: &rect.origin]; [*canvas unlockFocus]; return self; } - makeKnobImage: (NXImage *) canvas { return nil; } - makeBattenImage: (NXImage *) canvas rotate: (int) turn { return nil; } @end // RulerControl @implementation RulerControl( WindowDelegate ) - windowWillClose: sender // Clean up before ruler window is closed. { [sender setDelegate: nil]; [[NXApp delegate] rulerWillClose: self]; [self free]; return self; } - windowDidMove: sender // If the window was dragged by its title bar the ruler view // will be adjusted so that its origin stays at the same // screen coordinates as before dragging. { if( rulerWasDragged ) { [view synchScreenOrigin]; // keep view coordinates rulerWasDragged = NO; } else { [view synchOrigin]; // move view coordinates [window display]; } return self; } - highlightMainRuler { [controlBoxBackground setTransparent: NO]; [controlBox display]; return self; } - unhighlightMainRuler { [controlBoxBackground setTransparent: YES]; [window display]; return self; } - windowDidBecomeKey: sender // We are now the main ruler. { [[NXApp delegate] rulerDidBecomeMain: self]; [self highlightMainRuler]; return self; } - windowDidResignKey: sender // We are no longer the main ruler. { [[NXApp delegate] rulerDidBecomeMain: self]; [self unhighlightMainRuler]; return self; } @end // RulerControl( WindowDelegate )
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.