home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-12-12 | 16.7 KB | 612 lines | [TEXT/KAHL] |
- //----------------------------------------------------------------------------------
- // File : cdef3D.c
- // Date : May 2, 1994
- // Author : Jim Stout
- // Purpose : A CDEF to implement 3D controls
- // :
- // : This CDEF supports the System 7 style gray drawing of an
- // : inactive control and the useWindFont varCode.
- // :
- // NOTE : There are NO restrictions on this source or resulting code.
- //
- //----------------------------------------------------------------------------------
-
- #define _DEBUGCDEF 1 // comment this line to build the CDEF
-
- #define PUSHED 1
-
- #include <SetUpA4.h>
-
- #include "colorCDEF.h"
- #include "grayCDEF.h"
- #include "miscCDEF.h"
-
- #define togButProc 0x04
-
- //----------------------------------------------------------------------------------
- // CDEF private data
- //----------------------------------------------------------------------------------
- typedef struct {
- short osVers;
- short txFont;
- short txSize;
- }cdefData,**cdefHdl;
-
- //----------------------------------------------------------------------------------
- // Function prototypes
- //----------------------------------------------------------------------------------
- static void doDraw (ControlHandle cHdl, short varCode);
- static void drawPush (ControlHandle cHdl, short varCode, Boolean inColor,
- Boolean bgInColor, short lnHt, short lnAdj);
- static void drawCheck (ControlHandle cHdl, short varCode, Boolean bgInColor);
- static void drawRadio (ControlHandle cHdl, short varCode, Boolean bgInColor);
- static void drawTog (ControlHandle cHdl, short varCode, Boolean bgInColor);
- static void drawTitle (ControlHandle cHdl, short varCode, short lnHt, short lnAdj,
- Boolean emboss, Boolean pushed);
- static void getNextLine (Str255 t, Str255 s, short num);
- static void frame3DRect (ControlHandle theControl, Rect *rr, Boolean inColor);
- static void frame3DRoundRect (ControlHandle theControl, Rect *rr, short radius,
- Boolean inColor);
-
- //----------------------------------------------------------------------------------
- // CDEF main
- //----------------------------------------------------------------------------------
- #ifdef _DEBUGCDEF
- pascal long CDmain (short varCode, ControlHandle theControl, short message, long param);
- pascal long CDmain (short varCode, ControlHandle theControl, short message, long param)
- #else
- pascal long main (short varCode, ControlHandle theControl, short message, long param)
- #endif
- {
- short txF,txS;
- long ret = 0L;
- cdefHdl hCdef;
- Point p;
- GrafPtr thisPort;
-
- RememberA0();
- SetUpA4();
-
- if((**theControl).contrlData)
- HLock((**theControl).contrlData);
-
- GetPort(&thisPort);
-
- // set window font & size info
-
- txF = thisPort->txFont;
- txS = thisPort->txSize;
- if(!(varCode & useWindFont)) { // use system font
- thisPort->txFont = SysFontFam;
- thisPort->txSize = SysFontSize;
- }
-
- // Process messages to control
-
- if (message == initCntl) {
- hCdef = (cdefHdl)NewHandle(sizeof(cdefData));
- (**hCdef).osVers = getOSVers();
- (**hCdef).txFont = txF;
- (**hCdef).txSize = txS;
- (**theControl).contrlData = (Handle)hCdef;
- HLock((**theControl).contrlData);
- }
- else
- if (message == dispCntl) {
- HUnlock((**theControl).contrlData);
- DisposeHandle((**theControl).contrlData);
- (**theControl).contrlData = 0;
- }
- if (message == drawCntl &&
- (**theControl).contrlVis != 0 &&
- ((WindowPeek)(**theControl).contrlOwner)->visible) {
- doDraw(theControl, varCode);
- }
- else
- if (message == testCntl) {
- p.v=HiWord(param);
- p.h=LoWord(param);
- if(PtInRect(p,&(*theControl)->contrlRect))
- ret = 1L;
- }
- else
- if (message == calcCRgns)
- RectRgn((RgnHandle)(param & 0x7fffffffL), &(*theControl)->contrlRect);
- else
- if (message == calcCntlRgn || message == calcThumbRgn)
- RectRgn((RgnHandle)(param), &(*theControl)->contrlRect);
-
- // restore window font & size info
-
- if(!(varCode & useWindFont)) {
- thisPort->txFont = txF;
- thisPort->txSize = txS;
- }
- if((**theControl).contrlData)
- HUnlock((**theControl).contrlData);
- RestoreA4();
- return (ret);
- }
-
- //----------------------------------------------------------------------------------
- // main drawing routine for all variations of the control. Also
- // handles setting of colors, inactive control drawing.
- //----------------------------------------------------------------------------------
-
- static void doDraw(ControlHandle theControl, short varCode)
- {
- Rect r;
- Point p;
- RgnHandle c;
- FontInfo f;
- Boolean grayOK=false, inColor=false, inactive=false, bgInColor = false;
- PenState penSt;
- short pixDepth,osVers,lnHt,lnAdj;
- RGBColor saveFore, saveBack;
- RGBColor rgbWhite = {-1, -1, -1};
- GrafPtr thisPort;
- cdefHdl hCdef;
-
- hCdef = (cdefHdl)(**theControl).contrlData;
- if(!hCdef)
- return;
- GetPort(&thisPort);
- GetPenState(&penSt);
- PenSize(1,1);
-
- GetFontInfo(&f);
- lnAdj = f.descent + f.leading;
- lnHt = f.ascent + lnAdj;
-
- r = (*theControl)->contrlRect;
- osVers = (**hCdef).osVers;
- pixDepth = getPixDepth(&r);
-
- if((*theControl)->contrlHilite == 255)
- inactive = true;
-
- if(pixDepth > 2) {
- saveColors(&saveFore, &saveBack);
- setPartColor(theControl, cFrameColor, true);
- inColor = true;
- bgInColor = true;
- if(saveBack.red == 65535 && // is bg white?
- saveBack.green == 65535 &&
- saveBack.blue == 65535)
- bgInColor = false;
- }
-
- if(thisPort->txFont != (**hCdef).txFont || // if font changed,
- thisPort->txSize != (**hCdef).txSize) { // clear rect to erase
- (**hCdef).txFont = thisPort->txFont; // old font
- (**hCdef).txSize = thisPort->txSize;
- EraseRect(&r);
- }
-
- c = NewRgn(); // set new clipping region
- GetClip(c);
- ClipRect(&r);
-
- // draw the body of the control
-
- if(varCode & checkBoxProc) {
- drawCheck(theControl, varCode, bgInColor);
- }
- else
- if(varCode & radioButProc) {
- drawRadio(theControl, varCode, bgInColor);
- }
- else
- if(varCode & togButProc) {
- drawTog(theControl, varCode, bgInColor);
- }
- else
- if(varCode == pushButProc || varCode == useWindFont) {
- drawPush(theControl, varCode, inColor, bgInColor, lnHt, lnAdj);
- }
-
- if((*theControl)->contrlHilite != PUSHED) { // not pushed down
- if(bgInColor) { // draw embossed title
- RGBForeColor(&rgbWhite);
- drawTitle (theControl, varCode, lnHt, lnAdj, true, false); // embossed, not pushed
- RGBForeColor(&saveFore);
- }
-
- // Draw the control title, in color or gray if it is inactive
-
- if(inColor) {
- setPartColor(theControl, cTextColor, true);
- grayOK = haveGrayText();
- if(inactive && grayOK)
- TextMode(grayishTextOr);
- }
- drawTitle(theControl, varCode, lnHt, lnAdj, false, false);
- }
-
- if(!grayOK && inactive) { // gray out the old way
- PenPat( (ConstPatternParam) "\xAA\x55\xAA\x55\xAA\x55\xAA\x55");
- PenMode(patBic);
- r = (*theControl)->contrlRect;
- if(varCode != pushButProc)
- r.left+=18;
- else
- InsetRect(&r, 2, 2);
- PaintRect(&r);
- }
-
- // Clean up and leave
-
- SetClip(c); // restore clip & pen
- DisposeRgn(c);
- SetPenState(&penSt);
- TextMode(srcOr);
- if(inColor)
- restoreColors(&saveFore, &saveBack);
- }
-
- //----------------------------------------------------------------------------------
- // The push button drawing routine
- //----------------------------------------------------------------------------------
- static void drawPush(ControlHandle theControl, short varCode, Boolean inColor,
- Boolean bgInColor, short lnHt, short lnAdj)
- {
- short radius;
- Rect r;
- RGBColor rgbGray;
- RGBColor rgbWhite = {-1, -1, -1};
-
- r = (*theControl)->contrlRect;
- EraseRect(&r);
-
- if(bgInColor) {
- RGBForeColor(&rgbWhite); // 3D button
- MoveTo(r.left, r.bottom-2);
- LineTo(r.left, r.top);
- LineTo(r.right-1, r.top);
-
- MoveTo(r.left+1, r.bottom-3);
- LineTo(r.left+1, r.top+1);
- LineTo(r.right-2, r.top+1);
-
- setPartColor(theControl, cFrameColor, true);
-
- MoveTo(r.right-1, r.top);
- LineTo(r.right-1, r.bottom-1);
- LineTo(r.left, r.bottom-1);
-
- if(getGray(&rgbGray))
- RGBForeColor(&rgbGray);
- MoveTo(r.right-2, r.top+1);
- LineTo(r.right-2, r.bottom-2);
- LineTo(r.left+1, r.bottom-2);
-
- if((*theControl)->contrlHilite == PUSHED) { // hilited button
- EraseRect(&r);
- setPartColor(theControl, cFrameColor, true);
- MoveTo(r.left, r.bottom-2);
- LineTo(r.left, r.top);
- LineTo(r.right-1, r.top);
-
- if(getGray(&rgbGray))
- RGBForeColor(&rgbGray);
- MoveTo(r.left+1, r.bottom-3);
- LineTo(r.left+1, r.top+1);
- LineTo(r.right-2, r.top+1);
-
- RGBForeColor(&rgbWhite);
- MoveTo(r.right-1, r.top);
- LineTo(r.right-1, r.bottom-1);
- LineTo(r.left, r.bottom-1);
-
- MoveTo(r.right-2, r.top+1);
- LineTo(r.right-2, r.bottom-2);
- LineTo(r.left+1, r.bottom-2);
- drawTitle(theControl, varCode, lnHt, lnAdj, true, true);
- setPartColor(theControl, cTextColor, true);
- drawTitle(theControl, varCode, lnHt, lnAdj, false, true);
- }
- }
- else { // normal button
- if(inColor) { // set background color
- if((*theControl)->contrlHilite == PUSHED)
- setPartColor(theControl, cTextColor, false);
- else
- setPartColor(theControl, cBodyColor, false);
- }
-
- r = (*theControl)->contrlRect;
- radius = (r.bottom - r.top)/2;
- EraseRoundRect(&r, radius, radius);
- if(inColor)
- setPartColor(theControl, cFrameColor, true); // set foreground color
- FrameRoundRect(&r, radius, radius);
-
- if((*theControl)->contrlHilite == PUSHED) { // draw title in
- if(inColor) // cBodyColor
- setPartColor(theControl, cBodyColor, true);
- drawTitle(theControl, varCode, lnHt, lnAdj, false, PUSHED);
- if(!inColor) {
- InsetRect(&r,1,1);
- radius = (r.bottom - r.top)/2;
- InvertRoundRect(&r, radius, radius);
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------
- // The check box drawing routine
- //----------------------------------------------------------------------------------
- static void drawCheck(ControlHandle theControl, short varCode, Boolean bgInColor)
- {
- Rect r,r2;
- Point p;
-
- r = r2 = (*theControl)->contrlRect;
- p.h = r.left;
- p.v = r.bottom - (r.bottom - r.top)/2 - 1;
-
- r2.left+=2;
- r2.bottom = p.v+7;
- r2.right = r2.left+12;
- r2.top = r2.bottom-12;
-
- if((*theControl)->contrlHilite != 1) { // remove old hiliting
- r.right = r2.right;
- EraseRect(&r);
- }
- frame3DRect(theControl, &r2, bgInColor); // button frame
-
- if((*theControl)->contrlHilite == 1) { // hilited button
- InsetRect(&r2, 1, 1);
- frame3DRect(theControl, &r2, bgInColor);
- }
- if((*theControl)->contrlValue != 0) { // button center
- MoveTo(r2.right-2, r2.top+1);
- LineTo(r2.left+1, r2.bottom-2);
- MoveTo(r2.left, r2.top);
- LineTo(r2.right-2, r2.bottom-2);
- }
- }
-
- //----------------------------------------------------------------------------------
- // The radio button drawing routine
- //----------------------------------------------------------------------------------
- static void drawRadio(ControlHandle theControl, short varCode, Boolean bgInColor)
- {
- Rect r,r2;
- Point p;
-
- r = r2 = (*theControl)->contrlRect; // get pen loc for drawing
- p.h = r.left;
- p.v = r.bottom - (r.bottom - r.top)/2 - 1;
-
- r2.left+=2;
- r2.bottom = p.v+7;
- r2.right = r2.left+12;
- r2.top = r2.bottom-12;
-
- if((*theControl)->contrlHilite != 1) { // remove old hiliting
- r.right = r2.right;
- EraseOval(&r);
- }
-
- frame3DRoundRect(theControl, &r2, 12, bgInColor); // button frame
-
- if((*theControl)->contrlHilite == 1) { // hilited button
- InsetRect(&r2, 1, 1);
- frame3DRoundRect(theControl, &r2, 10, bgInColor);
- InsetRect(&r2, -1, -1);
- }
- if((*theControl)->contrlValue != 0) { // button center
- InsetRect(&r2, 3, 3);
- FillOval(&r2, (ConstPatternParam)"\xff\xff\xff\xff\xff\xff\xff\xff");
- }
-
- }
-
- //----------------------------------------------------------------------------------
- // The "Tog Button" drawing routine
- //----------------------------------------------------------------------------------
- static void drawTog(ControlHandle theControl, short varCode, Boolean bgInColor)
- {
- Rect r;
- Point p;
- short i,x,y;
-
- r = (*theControl)->contrlRect; // get pen loc for drawing
-
- // Draw the diamond shaped control
-
- p.h = r.left+2;
- p.v = r.bottom - (r.bottom - r.top)/2 - 1;
-
- if((*theControl)->contrlHilite != 1) { // remove old hiliting
- r.right = r.left+18;
- EraseRect(&r);
- }
-
- if(bgInColor)
- ForeColor(whiteColor);
- MoveTo(p.h,p.v); // button frame
- LineTo(p.h+7,p.v+7);
- LineTo(p.h+14,p.v);
- if(bgInColor)
- setPartColor(theControl, cFrameColor, true);
- LineTo(p.h+7,p.v-7);
- LineTo(p.h,p.v);
-
- if((*theControl)->contrlHilite == 1) { // hilited button
- if(bgInColor)
- ForeColor(whiteColor);
- MoveTo(p.h+1,p.v);
- LineTo(p.h+7,p.v+6);
- LineTo(p.h+13,p.v);
- if(bgInColor)
- setPartColor(theControl, cFrameColor, true);
- LineTo(p.h+7,p.v-6);
- LineTo(p.h+1,p.v);
- }
- if((*theControl)->contrlValue != 0) { // button center
- x = p.h+4;
- y = p.v;
- for(i=1;i<=4;i++) {
- MoveTo(x,y);
- LineTo(x+3,y+3);
- x++;
- y--;
- }
- x = p.h+5;
- y = p.v;
- for(i=1;i<=3;i++) {
- MoveTo(x,y);
- LineTo(x+2,y+2);
- x++;
- y--;
- }
- }
- }
- //----------------------------------------------------------------------------------
- // Draw the control titles - handles multiple lines and 3D embossing
- //----------------------------------------------------------------------------------
- static void drawTitle (ControlHandle theControl, short varCode, short lnHt, short lnAdj,
- Boolean emboss, Boolean pushed)
- {
- short inx=1,lnCnt=1,lnSpace,ctlSpace,v,h,adj=0;
- Rect r;
- Str255 s;
-
- r = (*theControl)->contrlRect;
-
- do { // count number of lines
- if((*theControl)->contrlTitle[inx++] == 0x0d)
- lnCnt++;
- }while (inx <= (*theControl)->contrlTitle[0]);
-
- lnSpace = lnCnt * lnHt; // required space
- ctlSpace = r.bottom - r.top; // available height
- v = r.bottom; // baseline
- v-=(ctlSpace - lnSpace)/2; // minus free space
- v-=lnAdj; // minus descent+leading
- v-=((lnCnt-1)*lnHt); // minus other lines
- // v is now base for line 1
- for(inx=1;inx<=lnCnt;inx++) {
- getNextLine((*theControl)->contrlTitle, s, inx);
- if(s[0]) {
- if(varCode == pushButProc || varCode == useWindFont)
- h = r.left + (r.right - r.left - StringWidth(s))/2;
- else
- if(varCode & togButProc)
- h = r.left + 20;
- else
- h = r.left + 18;
- if(emboss & pushed)
- adj = -1;
- else
- if(emboss)
- adj = 1;
-
- MoveTo(h+adj, v+adj);
- DrawString(s);
- }
- v+=lnHt;
- }
- }
- //----------------------------------------------------------------------------------
- // Grab the next line of a control title (assumes lines separated
- // by CR
- //----------------------------------------------------------------------------------
- static void getNextLine(Str255 t, Str255 s, short line)
- {
- short inx=1,len=0,lnCnt=1;
-
- s[0] = 0; // always default to null string
-
- do {
- if(t[inx] == 0x0d) // next line
- lnCnt++;
- else
- if(lnCnt == line) { // return this line
- len++;
- s[0] = len;
- s[len] = t[inx];
- }
- inx++;
- }while (inx <= t[0]);
- }
- //----------------------------------------------------------------------------------
- // Frame a rectangle with a 3d effect - used for checkBoxes
- //----------------------------------------------------------------------------------
- static void frame3DRect(ControlHandle theControl, Rect *rr, Boolean inColor)
- {
- Rect r;
-
- r = *rr;
- if(inColor)
- ForeColor(whiteColor);
- MoveTo(r.right-1, r.top);
- LineTo(r.right-1, r.bottom-1);
- LineTo(r.left, r.bottom-1);
- if(inColor)
- setPartColor(theControl, cFrameColor, true);
- MoveTo(r.left, r.bottom-2);
- LineTo(r.left, r.top);
- LineTo(r.right-1, r.top);
- }
-
- //----------------------------------------------------------------------------------
- // Frame a rounded rectangle with a 3d effect - used for radioButtons
- //----------------------------------------------------------------------------------
- static void frame3DRoundRect(ControlHandle theControl, Rect *rr, short radius,
- Boolean inColor)
- {
- Rect r, r2;
- Boolean vert=false;
-
- r = r2 = *rr;
-
- if((r.right-r.left) < (r.bottom-r.top))
- vert = true;
-
- if(vert) {
- r2.bottom = r2.top + radius;
- if(inColor)
- ForeColor(whiteColor);
- FrameArc(&r2, 45, 45);
- MoveTo(r.right-1, r.top+radius/2);
- LineTo(r.right-1, r.bottom-radius/2);
- r2.bottom = r.bottom;
- r2.top = r.bottom-radius;
- FrameArc(&r2, 90, 135);
-
- if(inColor)
- setPartColor(theControl, cFrameColor, true);
- FrameArc(&r2, 225, 45);
- MoveTo(r.left, r.bottom-radius/2);
- LineTo(r.left, r.top+radius/2);
- r2.top = r.top;
- r2.bottom = r2.top+radius;
- FrameArc(&r2, 270, 135);
- }
- else {
- if(inColor)
- ForeColor(whiteColor);
- r2.left = r2.right - radius;
- FrameArc(&r2, 45, 135);
- MoveTo(r.right-radius/2, r.bottom-1);
- LineTo(r.left+radius/2, r.bottom-1);
- r2.left=r.left;
- r2.right=r.left+radius;
- FrameArc(&r2, 180, 45);
-
- if(inColor)
- setPartColor(theControl, cFrameColor, true);
- FrameArc(&r2, 225, 135);
- MoveTo(r.left+radius/2, r.top);
- LineTo(r.right-radius/2, r.top);
- r2.right=r.right;
- r2.left=r.right-radius;
- FrameArc(&r2, 0, 45);
- }
- }
-