// =========================================================================== // 3DUtilities.cp ©1995 J. Rodden, DD/MF & Associates. All rights reserved // =========================================================================== // Utilities for drawing 3D effects. // // This is intended to look and act as much like a Toolbox Manager as possible. // You should use the first set of procedures in general, but the second set // is directly available for flexibility. // // This source code is loosely based on and heavily inspired by source code // by James W. Osborne, copyright (c) 1993, Apple Computer. #include "3DUtilities.h" // =========================================================================== // Local variables. Statics are used rather than a class to allow ANSI C usage. // =========================================================================== static RGBColor theLightColor = kWhite; static RGBColor theShadowColor = kShadowGray; static RGBColor theBkgndColor = kBackgroundGray; static PenState thePnState = {{0,0},{1,1},srcCopy, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; // =========================================================================== // Static function prototypes. // =========================================================================== static PenState theOldPnState; // only used by static functions. static void GetCPen(); static void GetBWPen(); static void SavePenState(); static void RestorePenState(); // =========================================================================== // Accessor functions to 3D colors. // =========================================================================== // € Get 3D State void Get3DBackColor( RGBColor *outBkgndColor) { *outBkgndColor = theBkgndColor; } void Get3DLightColor( RGBColor *outLightColor) { *outLightColor = theLightColor; } void Get3DShadowColor( RGBColor *outShadowColor){ *outShadowColor= theShadowColor; } void Get3DPenState( PenState *outPnState) { *outPnState = thePnState; } // € Set 3D State void Set3DBackColor(const RGBColor *inBkgndColor) { theBkgndColor = *inBkgndColor; } void Set3DLightColor(const RGBColor *inLightColor) { theLightColor = *inLightColor; } void Set3DShadowColor(const RGBColor *inShadowColor){ theShadowColor = *inShadowColor; } void Set3DPenState(const PenState *inPnState) { thePnState = *inPnState; } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DOvalPanel // --------------------------------------------------------------------------- // Draw a 3D oval panel (raised or embedded) in the current grafPort // using the current PenState. void Draw3DOvalPanel( const Rect* inRect, const RGBColor* inBKColor, const RGBColor* inULColor, const RGBColor* inLRColor, const Boolean inFrameIt) { RGBColor theForeColor; GetForeColor( &theForeColor); // Paint background color RGBForeColor(inBKColor); PaintOval(inRect); // Draw oval border Draw3DOvalBorder( inRect, inULColor, inLRColor, inFrameIt); RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetOvalPanel void Draw3DInsetOvalPanel(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalPanel(inRect, &theLightColor, &theShadowColor, &theLightColor, true); RestorePenState(); } // € Draw3DRaisedOvalPanel void Draw3DRaisedOvalPanel(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalPanel(inRect, &theBkgndColor, &theLightColor, &theShadowColor, false); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DOvalBorder // --------------------------------------------------------------------------- // Draw a 3D oval border (raised or embedded) in the current grafPort // using the current PenState. void Draw3DOvalBorder( const Rect* inRect, const RGBColor* inULColor, const RGBColor* inLRColor, const Boolean inFrameIt) { RGBColor theForeColor; GetForeColor( &theForeColor); // Draw upper left color RGBForeColor(inULColor); FrameOval(inRect); // Draw lower right color RGBForeColor(inLRColor); FrameArc( inRect, 45, 180); // Draw inner oval (frame) if (inFrameIt) { Rect tempRect = *inRect; InsetRect(&tempRect,thePnState.pnSize.h,thePnState.pnSize.v); RGBForeColor(&kBlack); FrameOval(&tempRect); } RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetOvalBorder void Draw3DInsetOvalBorder(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalBorder(inRect, &theShadowColor, &theLightColor, false); RestorePenState(); } // € Draw3DRaisedOvalBorder void Draw3DRaisedOvalBorder(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalBorder(inRect, &theLightColor, &theShadowColor, false); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DOvalFrame // --------------------------------------------------------------------------- // Draw a 3D oval frame (raised or embedded) in the current grafPort // using the current PenState. void Draw3DOvalFrame( const Rect* inRect, const RGBColor* inULColor, const RGBColor* inLRColor) { Rect tempRect = *inRect; RGBColor theForeColor; GetForeColor( &theForeColor); RGBForeColor(inULColor); FrameOval(&tempRect); OffsetRect(&tempRect,thePnState.pnSize.h, thePnState.pnSize.v); RGBForeColor(inLRColor); FrameOval(&tempRect); RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetOvalFrame void Draw3DInsetOvalFrame(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalFrame(inRect, &theShadowColor, &theLightColor); RestorePenState(); } // € Draw3DRaisedOvalFrame void Draw3DRaisedOvalFrame(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DOvalFrame(inRect, &theLightColor, &theShadowColor); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DPanel // --------------------------------------------------------------------------- // Draw a 3D panel (raised or embedded) in the current grafPort // using the current PenState. void Draw3DPanel( const Rect* inRect, const RGBColor* inBKColor, const RGBColor* inULColor, const RGBColor* inLRColor, const Boolean inFrameIt) { RGBColor theForeColor; GetForeColor( &theForeColor); // Paint background color RGBForeColor(inBKColor); PaintRect(inRect); Draw3DBorder( inRect, inULColor, inLRColor, inFrameIt); RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetPanel void Draw3DInsetPanel(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DPanel(inRect, &theLightColor, &theShadowColor, &theLightColor, true); RestorePenState(); } // € Draw3DRaisedPanel void Draw3DRaisedPanel(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DPanel(inRect, &theBkgndColor, &theLightColor, &theShadowColor, false); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DBorder // --------------------------------------------------------------------------- // Draw a 3D panel border (raised or embedded) in the current grafPort // using the current PenState. void Draw3DBorder( const Rect* inRect, const RGBColor* inULColor, const RGBColor* inLRColor, const Boolean inFrameIt) { PenState thePnState; RGBColor theForeColor; GetPenState( &thePnState); GetForeColor( &theForeColor); // Draw lower right (shadow) lines RGBForeColor(inLRColor); FrameRect(inRect); // Draw upper left (light source) lines RGBForeColor(inULColor); MoveTo( inRect->left, inRect->bottom - thePnState.pnSize.v); LineTo( inRect->left, inRect->top); LineTo( inRect->right - thePnState.pnSize.h, inRect->top); // Draw inner box (frame) if (inFrameIt) { Rect tempRect = *inRect; InsetRect(&tempRect,thePnState.pnSize.h,thePnState.pnSize.v); RGBForeColor(&kBlack); FrameRect(&tempRect); } RGBForeColor(&theForeColor); } // =========================================================================== // € Draw3DInsetBorder void Draw3DInsetBorder(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DBorder(inRect, &theShadowColor, &theLightColor, false); RestorePenState(); } // € Draw3DRaisedBorder void Draw3DRaisedBorder(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DBorder(inRect, &theLightColor, &theShadowColor, false); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DFrame // --------------------------------------------------------------------------- // Draw a 3D rect (raised or embedded) in the current grafPort using the // current PenState. void Draw3DFrame( const Rect* inRect, const RGBColor* inULColor, const RGBColor* inLRColor) { Rect tempRect = *inRect; PenState thePnState; RGBColor theForeColor; GetPenState(&thePnState); GetForeColor(&theForeColor); tempRect.right -= thePnState.pnSize.h; tempRect.bottom -= thePnState.pnSize.v; RGBForeColor(inULColor); FrameRect(&tempRect); OffsetRect(&tempRect,thePnState.pnSize.h, thePnState.pnSize.v); RGBForeColor(inLRColor); FrameRect(&tempRect); RGBForeColor(&theForeColor); } // =========================================================================== // € Draw3DInsetFrame void Draw3DInsetFrame(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DFrame(inRect, &theShadowColor, &theLightColor); RestorePenState(); } // € Draw3DRaisedFrame void Draw3DRaisedFrame(const Rect *inRect) { SavePenState(); GetCPen(); Draw3DFrame(inRect, &theLightColor, &theShadowColor); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DHLine // --------------------------------------------------------------------------- // Draw a 3D line (raised or embedded) horizontally accross the current grafPort // using the current PenState. void Draw3DHLine(const short vpos, const short h1, const short h2, const RGBColor *inULColor, const RGBColor *inLRColor) { PenState thePnState; RGBColor theForeColor; GetPenState( &thePnState); GetForeColor( &theForeColor); DrawCLine( inULColor, h1, vpos, h2, vpos); DrawCLine( inLRColor, h1, vpos+thePnState.pnSize.v, h2, vpos+thePnState.pnSize.v); RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetHLine void Draw3DInsetHLine(const short vpos, const short h1, const short h2) { SavePenState(); GetCPen(); Draw3DHLine( vpos, h1, h2, &theShadowColor, &theLightColor); RestorePenState(); } // € Draw3DRaisedHLine void Draw3DRaisedHLine(const short vpos, const short h1, const short h2) { SavePenState(); GetCPen(); Draw3DHLine( vpos, h1, h2, &theLightColor, &theShadowColor); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € Draw3DVLine // --------------------------------------------------------------------------- // Draw a 3D line (raised or embedded) vertically accross the current grafPort // using the current PenState. void Draw3DVLine(const short hpos, const short v1, const short v2, const RGBColor *inULColor, const RGBColor *inLRColor) { PenState thePnState; RGBColor theForeColor; GetPenState( &thePnState); GetForeColor( &theForeColor); DrawCLine( inULColor, hpos, v1, hpos, v2); DrawCLine( inLRColor, hpos+thePnState.pnSize.h, v1, hpos+thePnState.pnSize.h, v2); RGBForeColor( &theForeColor); } // =========================================================================== // € Draw3DInsetVLine void Draw3DInsetVLine(const short hpos, const short v1, const short v2) { SavePenState(); GetCPen(); Draw3DVLine( hpos, v1, v2, &theShadowColor, &theLightColor); RestorePenState(); } // € Draw3DRaisedVLine void Draw3DRaisedVLine(const short hpos, const short v1, const short v2) { SavePenState(); SavePenState(); GetCPen(); Draw3DVLine( hpos, v1, v2, &theLightColor, &theShadowColor); RestorePenState(); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € DrawCLine // --------------------------------------------------------------------------- // Draw a colored line within the current grafPort using the current PenState. void DrawCLine(const RGBColor *theColor, const short h1, const short v1, const short h2, const short v2) { MoveTo( h1, v1); CLineTo( theColor, h2, v2); } // --------------------------------------------------------------------------- // € CLineTo // --------------------------------------------------------------------------- // Draw a colored line within the current grafPort using the current PenState. void CLineTo(const RGBColor *theColor, const short h, const short v) { RGBForeColor(theColor); LineTo( h, v); } // =========================================================================== // =========================================================================== // --------------------------------------------------------------------------- // € BWShadowInset // --------------------------------------------------------------------------- void BWShadowInset(const Rect* inRect) { if ( inRect != nil ) { SavePenState(); GetBWPen(); MoveTo( inRect->left, inRect->bottom); LineTo( inRect->left, inRect->top); LineTo( inRect->right, inRect->top); RestorePenState(); } } // --------------------------------------------------------------------------- // € BWShadowRaised // --------------------------------------------------------------------------- void BWShadowRaised(const Rect* inRect) { if ( inRect != nil ) { SavePenState(); GetBWPen(); MoveTo( inRect->left, inRect->bottom); LineTo( inRect->right, inRect->bottom); LineTo( inRect->right, inRect->top); RestorePenState(); } } // --------------------------------------------------------------------------- // € BWShadowLine // --------------------------------------------------------------------------- // Draw a BW shadowed line within the current grafPort using the current PenState. void BWShadowLine(const short h1, const short v1, const short h2, const short v2) { SavePenState(); GetBWPen(); MoveTo( h1, v1); LineTo( h2, v2); RestorePenState(); } // =========================================================================== // =========================================================================== void GetCPen() { SetPenState( &thePnState); } void GetBWPen() { Pattern grey = {0xFFFFFFE8}; GetCPen(); PenPat(&grey); } void SavePenState() { GetPenState( &theOldPnState); } void RestorePenState() { SetPenState( &theOldPnState); }