home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-08 | 28.9 KB | 1,000 lines | [TEXT/KAHL] |
- //------------------------- © 1992-1995 by James G. Stout --------------------------
- // File : cdefSpinner.c
- // Date : 24 October 1992
- // Author : Jim Stout
- // :
- // Purpose : a "Spinner Control" CDEF that allows adjustment of a
- // : number via an up/down spinner - a "little arrow" control.
- // :
- // : see cdefSpinner.h for more detail and variation codes
- // :
- // : If you find a use for this, I'd love to know about it. Bug reports
- // : are always interesting.
- // :
- // : Internet : JimS@WRQ.COM(work hours, PST)
- // : AppleLink : WRQ (daily)
- // : CompuServe : 73240,2052 (weekly or so)
- // : AOL : JasG (weekly or so)
- // : eWorld : Jim Stout (weekly or so)
- //----------------------------------------------------------------------------------
- //#define _DEBUGCDEF 1
-
- #include "fatCDEF.h"
-
- #include <Controls.h>
- #include <Dialogs.h>
- #include <GestaltEqu.h>
- #include <LowMem.h>
- #include <QDOffscreen.h>
- #include <ToolUtils.h>
- #include <Types.h>
-
- #include "cdefSpinner.h"
-
- #include "grayCDEF.h"
- #include "colorCDEF.h"
- #include "miscCDEF.h"
- #include "qdCDEF.h"
-
-
- #ifdef _DEBUGCDEF
- pascal long CDmain (short, ControlHandle, short, long);
-
- pascal long CDmain (short varCode, ControlHandle theCtl, short message, long param)
- #else
-
- //==================================================================================
- // CDEF entry point
- //==================================================================================
-
- pascal long main (short varCode, ControlHandle theCtl, short message, long param)
- #endif
- {
- long ret = 0L;
- short txF,txS;
- GrafPtr thisPort;
- hSpinData hCDEF;
- SignedByte cState, dState;
-
- #include "fatEntry.c"
-
- cState = HGetState((Handle)theCtl);
- HLock((Handle)theCtl);
-
- //----------------------------------------------------------------------------------
- // make sure we've got the correct font…
- //----------------------------------------------------------------------------------
-
- if(!(varCode & useWindFont)) { // don't use the window font
- GetPort(&thisPort);
- txF = thisPort->txFont;
- txS = thisPort->txSize;
- TextFont(LMGetSysFontFam()); // set system as current
- TextSize(LMGetSysFontSize());
- }
-
- //----------------------------------------------------------------------------------
- // get our private data
- //----------------------------------------------------------------------------------
-
- if((**theCtl).contrlData) {
- dState = HGetState((**theCtl).contrlData);
- HLock((**theCtl).contrlData);
- hCDEF = (hSpinData)(**theCtl).contrlData;
- }
-
- //----------------------------------------------------------------------------------
- // handle the standard control messages
- //----------------------------------------------------------------------------------
-
- switch(message) {
- case initCntl:
- doInit(theCtl, varCode);
- if((**theCtl).contrlData) {
- dState = HGetState((**theCtl).contrlData);
- HLock((**theCtl).contrlData);
- }
- break;
- case dispCntl:
- doDisp(theCtl);
- break;
- case testCntl:
- if((**theCtl).contrlHilite != 0xFF) // only if active
- ret = doTest (theCtl, varCode, param);
- break;
- case drawCntl:
- if ((**theCtl).contrlVis != 0 &&
- ((WindowPeek)(**theCtl).contrlOwner)->visible) {
- doDraw(theCtl, varCode);
- }
- break;
- case calcCRgns:
- RectRgn((RgnHandle)(param & 0x7fffffffL), &(**theCtl).contrlRect);
- break;
- case calcCntlRgn:
- case calcThumbRgn:
- RectRgn((RgnHandle)(param), &(**theCtl).contrlRect);
- break;
- }
-
- //----------------------------------------------------------------------------------
- // restore window font & size info
- //----------------------------------------------------------------------------------
-
- if(!(varCode & useWindFont)) {
- TextFont(txF);
- TextSize(txS);
- }
-
- if((**theCtl).contrlData)
- HSetState((**theCtl).contrlData, dState);
- HSetState((Handle)theCtl, cState);
-
- #include "fatExit.c"
-
- return (ret);
- }
-
- //==================================================================================
- // initialize our private data and save in contrlData field.
- //==================================================================================
-
- static void doInit (ControlHandle theCtl, short varCode)
- {
- hSpinData hCDEF;
-
- hCDEF = (hSpinData) NewHandle(sizeof(spinData));
- if(hCDEF) {
-
- //----------------------------------------------------------------------------------
- // If the control refCon is non-zero, the LoWord is the increment
- // to use and the HiWord is a DITL item number for an editText item
- // that we will set with the contrlValue in updateValue.
- //----------------------------------------------------------------------------------
-
- HLock((Handle)hCDEF);
-
- (**hCDEF).currIncr = 1;
- (**hCDEF).increment = 1;
- (**hCDEF).itemNum = 0;
-
- if((**theCtl).contrlRfCon) {
- (**hCDEF).increment = LoWord((**theCtl).contrlRfCon);
- if((**hCDEF).increment < 1 ||
- (**hCDEF).increment > 1000) {
- (**hCDEF).increment = 1;
- }
- (**hCDEF).currIncr = (**hCDEF).increment;
- if((*(WindowPeek)(**theCtl).contrlOwner).windowKind == dialogKind)
- (**hCDEF).itemNum = HiWord((**theCtl).contrlRfCon);
- if((**hCDEF).itemNum < 0 || (**hCDEF).itemNum > 100)
- (**hCDEF).itemNum = 0;
- }
- (**hCDEF).bumpit = -3;
-
- (**hCDEF).offPort = 0; // offPort &
- (**hCDEF).pDepth = 0; // pDepth filled in in doDraw()
- (**hCDEF).qdVers = getQDVers();
-
- (**hCDEF).poly[0] = 0; // filled in in makePolys()
- (**hCDEF).poly[1] = 0;
- (**hCDEF).poly[2] = 0;
- (**theCtl).contrlData = (Handle)hCDEF;
- makePolys(theCtl, varCode); // draw arrows & frame
-
- HUnlock((Handle)hCDEF);
- }
- else
- (**theCtl).contrlData = 0;
- }
-
- //==================================================================================
- // dispose of our private data (offscreen bitmap)
- //==================================================================================
-
- static void doDisp (ControlHandle theCtl)
- {
- hSpinData hCDEF;
- BitMap *theBits;
- short inx;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(hCDEF) {
- if((**hCDEF).offPort) {
- if(((**hCDEF).offPort->portVersion & 0x8000) != 0) { // offPort is GWorld
- DisposeGWorld((**hCDEF).offPort);
- }
- else { // offport is bitmap
- theBits = &((GrafPtr)(**hCDEF).offPort)->portBits;
- DisposePtr((*theBits).baseAddr);
- ClosePort((GrafPtr)(**hCDEF).offPort);
- DisposePtr((Ptr)(**hCDEF).offPort);
- }
- }
- for(inx=0;inx<3;inx++) {
- if((**hCDEF).poly[inx])
- KillPoly((**hCDEF).poly[inx]);
- }
- HUnlock((Handle)hCDEF);
- DisposeHandle((Handle)hCDEF);
- (**theCtl).contrlData = 0;
- }
- }
-
- //==================================================================================
- // create polygons for the VERTICAL arrow frame and the up and down arrows
- //==================================================================================
-
- static void makePolys(ControlHandle theCtl, short varCode)
- {
- short c,v,w,b1,b2;
- Rect r,parts[NUMPARTS];
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(!hCDEF) { // ooops!
- return;
- }
- getRects(theCtl, varCode, parts); // rects for control parts
- OffsetRect(&parts[FRAME], // adjust to 0,0
- -parts[ALL].left, -parts[ALL].top);
- r = parts[FRAME];
-
- (**hCDEF).poly[0] = OpenPoly(); // draw frame for arrows
-
- if((**hCDEF).poly[0]) {
- MoveTo(r.left+2,r.top);
- LineTo(r.right-3,r.top);
- Line(2,3);
- LineTo(r.right-1,r.bottom-3);
- Line(-2,2);
- LineTo(r.left+2,r.bottom-1);
- Line(-2,-2);
- LineTo(r.left,r.top+3);
- Line(2,-3);
- ClosePoly(); // poly[0]
- }
-
- if(varCode & horizArrows) {
- v = (r.bottom - r.top)/2 + r.top;
- b1 = (r.bottom - r.top -2)/3;
- b2 = (r.bottom - r.top -2)/4;
- c = r.right -3;
- w = b2;
- if(varCode & bigArrows) {
- c--;
- w++;
- }
- }
- else {
- c = (r.right - r.left)/2 + r.left;
- b1 = (r.right - r.left -2)/3;
- b2 = (r.right - r.left -2)/4;
- v = r.top+2;
- w = b2;
- if(varCode & bigArrows) {
- v++;
- w++;
- }
- }
- (**hCDEF).poly[1] = OpenPoly(); // draw UP arrow
-
- if((**hCDEF).poly[1]) {
- if(varCode & horizArrows) {
- MoveTo(c,v); // apex of arrow
- Line(-b1,-b1); // upper slope of arrow head
- Line(0,2); // down to shaft
- Line(-b2,0); // left to end
- Line(0,w); // down for shaft end
- Line(b2,0); // botttom edge of shaft
- Line(0,2); // bottom of arrow
- Line(b1,-b1); // lower slope of arrow head
- }
- else {
- MoveTo(c,v); // see above
- Line(-b1,b1);
- Line(2,0);
- Line(0,b2);
- Line(w,0);
- Line(0,-b2);
- Line(2,0);
- Line(-b1,-b1);
- }
- ClosePoly(); // poly[1]
- }
-
- (**hCDEF).poly[2] = OpenPoly(); // draw LEFT arrow
-
- if((**hCDEF).poly[2]) {
- if(varCode & horizArrows) {
- c = r.left+2;
- if(varCode & bigArrows)
- c++;
-
- MoveTo(c,v); // see above
- Line(b1,-b1);
- Line(0,2);
- Line(b2,0);
- Line(0,w);
- Line(-b2,0);
- Line(0,2);
- Line(-b1,-b1);
- }
- else { // draw DOWN arrow
- v = r.bottom-3;
- if(varCode & bigArrows)
- v--;
-
- MoveTo(c,v); // see above
- Line(-b1,-b1);
- Line(2,0);
- Line(0,-b2);
- Line(w,0);
- Line(0,b2);
- Line(2,0);
- Line(-b1,b1);
- }
- ClosePoly(); // poly[2]
- }
- }
-
- //==================================================================================
- // check for a mouseDown in our control. Actually, we do all of our
- // tracking, drawing and updating of the control here.
- //==================================================================================
-
- static long doTest (ControlHandle theCtl, short varCode, long param)
- {
- Point p;
- short inx,partCode;
- long ret = 0;
- Rect parts[NUMPARTS];
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(!hCDEF)
- return(ret);
-
- p.h = LoWord(param); // get the mouse hit point
- p.v = HiWord(param);
-
- getRects(theCtl, varCode, parts);
-
- partCode = (**theCtl).contrlHilite;
-
-
- for(inx = UPARROW;inx <= DOWNARROW;inx++) {
- if(PtInRect(p,&parts[inx])) {
- if(inx == partCode) {
- updateValue(theCtl, inx); // change value
- doDraw(theCtl, varCode); // draw it
- accelerate(theCtl); // speed up if needed
- }
- else { // reset increment
- (**hCDEF).currIncr = (**hCDEF).increment;
- (**hCDEF).bumpit = -3;
- }
- ret = inx;
- }
- }
- return(ret);
- }
-
- //==================================================================================
- // update the controlValue and pause a bit
- //==================================================================================
-
- static void updateValue (ControlHandle theCtl, short partCode)
- {
- short t,incr1,incr2,incr3;
- Handle hEdit;
- Rect r;
- long secs;
- Str31 s;
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(!hCDEF)
- return;
-
- //----------------------------------------------------------------------------------
- // Update the controValue
- //----------------------------------------------------------------------------------
- if(partCode == UPARROW) {
- if((**theCtl).contrlValue <= (**theCtl).contrlMax - (**hCDEF).currIncr)
- (**theCtl).contrlValue += (**hCDEF).currIncr;
- else
- (**theCtl).contrlValue = (**theCtl).contrlMax;
- }
- else {
- if((**theCtl).contrlValue >= (**theCtl).contrlMin + (**hCDEF).currIncr)
- (**theCtl).contrlValue -= (**hCDEF).currIncr;
- else
- (**theCtl).contrlValue = (**theCtl).contrlMin;
- }
-
- //----------------------------------------------------------------------------------
- // if we got an Edit Text item number in the RefCon, put the text
- // into the edit item
- //----------------------------------------------------------------------------------
-
- if((**hCDEF).itemNum) {
- GetDItem((**theCtl).contrlOwner, // get handle to text item
- (**hCDEF).itemNum, &t, &hEdit, &r);
- if(hEdit && (t & editText)) { // is it valid ?
- NumToString((long)(**theCtl).contrlValue, s);
- SetIText(hEdit,s);
- SelIText((**theCtl).contrlOwner, (**hCDEF).itemNum, 32767, 32767);
- }
- else
- (**hCDEF).itemNum = 0;
- }
-
- //----------------------------------------------------------------------------------
- // now, pause a bit to let the user catch up
- //----------------------------------------------------------------------------------
-
- incr1 = (**hCDEF).increment;
- if(incr1 == 1)
- incr2 = 10;
- else
- incr2 = incr1*incr1;
- incr3 = incr2*incr2;
-
- if((**hCDEF).currIncr == incr1)
- Delay(10L, &secs);
- else
- if((**hCDEF).currIncr == incr2)
- Delay(12L, &secs);
- else
- if((**hCDEF).currIncr == incr3)
- Delay(16L, &secs);
- }
-
- //==================================================================================
- // process the drawCntl message
- //==================================================================================
-
- void doDraw (ControlHandle theCtl, short varCode)
- {
- RgnHandle saveClip, newClip;
- Boolean inactive=false,inColor=false,bgInColor=false;
- Boolean haveGW=false,haveGray=false,drawText=true;
- PenState penSt;
- short partCode=0,val,wid,h,v;
- Str31 s;
- Rect parts[NUMPARTS];
- BitMap *offBits;
- PixMapHandle pmHdl;
- CGrafPtr savePort;
- GDHandle saveGDev;
- RGBColor saveFore,saveBack;
- RGBColor rgbBlack = {0,0,0};
- RGBColor rgbWhite = {-1,-1,-1};
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(!hCDEF) // ooops!
- return;
-
- //----------------------------------------------------------------------------------
- // Get drawing rects, offPort and lock down the pixels
- //----------------------------------------------------------------------------------
-
- getRects(theCtl, varCode, parts); // rects for control parts
-
- (**hCDEF).pDepth = getOff(&(**hCDEF).offPort, &parts[ALL]);
-
- if((**hCDEF).pDepth == 0) // oh… oh…
- return;
-
- if(((**hCDEF).offPort->portVersion & 0x8000) != 0) { // have a GWorld
- haveGW = true;
- pmHdl = getLockedPixels(&(**hCDEF).offPort, (**hCDEF).qdVers);
- if(!pmHdl)
- return; // nuts…
- }
-
- //----------------------------------------------------------------------------------
- // initialize our drawing stuff
- //----------------------------------------------------------------------------------
-
- if((**theCtl).contrlHilite == 0xFF)
- inactive = true;
- else
- partCode = (**theCtl).contrlHilite;
-
- GetPenState(&penSt);
-
- if ((**hCDEF).pDepth > 2) {
- inColor = true;
- saveColors(&saveFore, &saveBack);
- bgInColor = true;
- if(saveBack.red == 65535 && // is bg white?
- saveBack.green == 65535 &&
- saveBack.blue == 65535)
- bgInColor = false;
- }
- #ifdef NOEMBOSS
- bgInColor = false;
- #endif
-
- //----------------------------------------------------------------------------------
- // Do the clip region properly. Thanks Ari!
- //----------------------------------------------------------------------------------
-
- saveClip = NewRgn();
- GetClip(saveClip);
-
- newClip = NewRgn();
- RectRgn(newClip, &parts[ALL]);
- SectRgn(saveClip, newClip, newClip);
-
- if(EmptyRgn(newClip)) { // if empty, don't waste
- DisposeRgn(saveClip); // time drawing...
- DisposeRgn(newClip);
- return;
- }
-
- SetClip(newClip);
-
- //----------------------------------------------------------------------------------
- // set our offScreen port so we can draw to it
- //----------------------------------------------------------------------------------
-
- if(haveGW) { // we have a pixMap
- GetGWorld(&savePort, &saveGDev);
- SetGWorld((**hCDEF).offPort, nil);
- offBits = (BitMap *)*pmHdl;
- if((**(*savePort).bkPixPat).patType != 0 &&
- (savePort->portVersion & 0x8000) != 0)
- BackPixPat((*savePort).bkPixPat);
- }
- else { // we have a bitMap
- GetPort((GrafPtr*)&savePort);
- SetPort((GrafPtr)(**hCDEF).offPort);
- offBits = (BitMap *)&((GrafPtr)(**hCDEF).offPort)->portBits;
- }
-
- if(inColor) { // set colors in offPort
- RGBForeColor(&saveFore);
- RGBBackColor(&saveBack);
- }
- else {
- ForeColor(blackColor);
- BackColor(whiteColor);
- }
-
- if(varCode & useWindFont) { // set font in offPort
- TextFont(savePort->txFont);
- TextSize(savePort->txSize);
- }
-
- //----------------------------------------------------------------------------------
- // Finally, we are ready to start drawing... first, erase the background.
- //----------------------------------------------------------------------------------
-
- SetOrigin((**theCtl).contrlRect.left, (**theCtl).contrlRect.top);
- EraseRect(&offBits->bounds);
- SetOrigin(0, 0);
-
- //----------------------------------------------------------------------------------
- // draw control title into offPort
- //----------------------------------------------------------------------------------
-
- wid = parts[ALL].right - parts[ALL].left;
- if(varCode & bigArrows && wid == ARROWID1)
- drawText = false;
- else
- if(wid <= ARROWID+15)
- drawText = false;
-
- if(drawText) {
- OffsetRect(&parts[TITLE], // adjust to 0,0
- -parts[ALL].left, -parts[ALL].top);
- h = parts[TITLE].left +1;
- v = parts[TITLE].bottom -parts[BASELINE].bottom;
-
- if(bgInColor && varCode & ctl3D) { // emboss the title
- RGBForeColor(&rgbWhite);
- MoveTo(h+1, v+1);
- DrawString((**theCtl).contrlTitle);
- }
- if(inColor) {
- setPartColor(theCtl, cTextColor, true);
- if(inactive) { // draw in gray
- if(haveGrayText()) {
- TextMode(grayishTextOr);
- haveGray = true;
- }
- }
- }
- MoveTo(h, v);
- DrawString((**theCtl).contrlTitle);
- TextMode(srcOr);
-
- //----------------------------------------------------------------------------------
- // draw control value into offPort after converting to a string
- //----------------------------------------------------------------------------------
-
- val = (**theCtl).contrlValue;
- NumToString((long)val, s);
- wid = StringWidth(s) + 6;
- h = parts[TITLE].right - wid;
-
- if(bgInColor && varCode & ctl3D) { // emboss the value
- RGBForeColor(&rgbWhite);
- MoveTo(h+1, v+1);
- DrawString(s);
- }
- if(inColor) {
- setPartColor(theCtl, cTextColor, true);
- if(haveGray) // draw in gray
- TextMode(grayishTextOr);
- }
- MoveTo(h, v);
- DrawString(s);
- TextMode(srcOr);
- }
- else
- if(inactive && inColor)
- haveGray = haveGrayText();
-
- //----------------------------------------------------------------------------------
- // draw the arrows into the offPort
- //----------------------------------------------------------------------------------
-
- drawArrows(theCtl, varCode, partCode, inactive, inColor);
-
- //----------------------------------------------------------------------------------
- // now blit the image from offscreen port to onscreen
- //----------------------------------------------------------------------------------
-
- if(haveGW) // back to onscreen port
- SetGWorld(savePort, saveGDev);
- else
- SetPort((GrafPtr)savePort);
-
- if(inColor) {
- RGBForeColor(&rgbBlack);
- RGBBackColor(&rgbWhite);
- }
-
- CopyBits(offBits, // from bitmap
- &((GrafPtr)savePort)->portBits, // to onscreen port
- &(**hCDEF).offPort->portRect, // from rect
- &parts[ALL], // to rect
- srcCopy, nil);
-
- if(haveGW) {
- unlockPixels(pmHdl, (**hCDEF).qdVers);
- DisposeGWorld((**hCDEF).offPort);
- (**hCDEF).offPort = 0;
- }
-
- if(inColor)
- restoreColors(&saveFore, &saveBack);
-
- //----------------------------------------------------------------------------------
- // if inactive & System 6.0.x, gray out the control the old way
- //----------------------------------------------------------------------------------
-
- if(inactive && !haveGray) {
- PenPat( (ConstPatternParam) "\xAA\x55\xAA\x55\xAA\x55\xAA\x55");
- PenMode(patBic);
- PaintRect(&parts[ALL]);
- }
- SetClip(saveClip);
- DisposeRgn(saveClip);
- DisposeRgn(newClip);
-
- SetPenState(&penSt);
- }
-
- //==================================================================================
- // Draw the arrow control image.
- //==================================================================================
-
- static void drawArrows(ControlHandle theCtl, short varCode, short partCode,
- Boolean inactive, Boolean inColor)
- {
- short inx;
- Rect arrowRect,parts[NUMPARTS];
- RGBColor rgbBlack = {0,0,0};
- RGBColor rgbWhite = {-1,-1,-1};
- RGBColor rgbA = {0xAAAA, 0xAAAA, 0xAAAA};
- RGBColor grayColor;
- Boolean gotGray=false, canHilite[2];
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
-
- getRects(theCtl, varCode, parts); // rects for control parts
-
- if((**theCtl).contrlValue == (**theCtl).contrlMax)
- canHilite[0] = false;
- else
- canHilite[0] = true;
-
- if((**theCtl).contrlValue == (**theCtl).contrlMin)
- canHilite[1] = false;
- else
- canHilite[1] = true;
-
-
- //----------------------------------------------------------------------------------
- // Draw a frame around the up and down arrows (poly[0] is the frame).
- //----------------------------------------------------------------------------------
-
- if((**hCDEF).poly[0]) { // this poly is the frame for both
- ForeColor(whiteColor); // arrows
- PaintPoly((**hCDEF).poly[0]);
- ForeColor(blackColor);
- if(inColor) {
- gotGray = getGray(&grayColor);
- setPartColor(theCtl, cFrameColor, true);
- if(inactive && gotGray)
- RGBForeColor(&grayColor);
- }
- FramePoly((**hCDEF).poly[0]);
-
- //----------------------------------------------------------------------------------
- // draw shadow around frame if 3D arrows were requested
- //----------------------------------------------------------------------------------
-
- if(inColor && varCode & ctl3D && !inactive) {
- arrowRect = parts[FRAME];
- OffsetRect(&arrowRect, -parts[ALL].left, -parts[ALL].top);
- RGBForeColor(&rgbA);
-
- MoveTo(arrowRect.left+1, arrowRect.bottom-1);
- LineTo(arrowRect.left-1, arrowRect.bottom-3);
- LineTo(arrowRect.left-1, arrowRect.top+3);
- Move(0,-1);
- LineTo(arrowRect.left+2, arrowRect.top-1);
- LineTo(arrowRect.right-4, arrowRect.top-1);
-
- ForeColor(whiteColor);
- Move(1,0);
- LineTo(arrowRect.right, arrowRect.top+2);
- LineTo(arrowRect.right, arrowRect.bottom-3);
- LineTo(arrowRect.right-3, arrowRect.bottom);
- LineTo(arrowRect.left+2, arrowRect.bottom);
-
- setPartColor(theCtl, cFrameColor, true);
- }
- }
-
- //----------------------------------------------------------------------------------
- // If a small b&w arrow was clicked, fill half the frame with black (fg color,
- // leaving frame untouched). Then we fill/paint the arrow poly in white.
- //----------------------------------------------------------------------------------
-
- if(!(varCode & ctl3D) || !inColor) {
- if(partCode == UPARROW || partCode == DOWNARROW) {
- if(canHilite[partCode-2] && !(varCode & bigArrows)) {
-
- arrowRect = parts[partCode];
- OffsetRect(&arrowRect, -parts[ALL].left, -parts[ALL].top);
-
- if(varCode & horizArrows) {
- if(partCode == UPARROW)
- MoveTo(arrowRect.left, arrowRect.top+1);
- else
- MoveTo(arrowRect.left+1,arrowRect.top+1);
- for(inx=0;inx<8;inx++) {
- Line(0,8);
- Move(1,-8);
- }
- }
- else {
- if(partCode == UPARROW)
- MoveTo(arrowRect.left+1, arrowRect.top+1);
- else
- MoveTo(arrowRect.left+1,arrowRect.top-1);
- for(inx=0;inx<8;inx++) {
- Line(8,0);
- Move(-8,1);
- }
- }
- }
- }
- }
-
- //----------------------------------------------------------------------------------
- // Draw both the top & bottom arrows (poly[1] & poly[2])
- //----------------------------------------------------------------------------------
-
- for(inx=1;inx<=2;inx++) {
- if((**hCDEF).poly[inx]) { // Need the poly!
-
- //----------------------------------------------------------------------------------
- // First check to see if we are drawing a hilited arrow - and fill the center
- // appropriately.
- //----------------------------------------------------------------------------------
-
- if(partCode == inx+1 && canHilite[inx-1]) { // arrow is hilited
- if(varCode & bigArrows) {
- if(inColor)
- RGBForeColor(&rgbBlack); // always black
- }
- else { // small arrow
- if(inColor) {
- if(varCode & ctl3D) // drawn in black
- RGBForeColor(&rgbBlack); // for 3D
- else
- RGBForeColor(&rgbWhite); // white for non-3D
- }
- else // b&w hilited arrow
- ForeColor(whiteColor); // must draw white
- }
- PaintPoly((**hCDEF).poly[inx]); // fill the arrow
- }
-
- //----------------------------------------------------------------------------------
- // Nope, it is not hilited
- //----------------------------------------------------------------------------------
-
- else {
- if(!canHilite[inx-1]) {
- if(inColor)
- RGBForeColor(&grayColor);
- }
- if(varCode & ctl3D) { // make it look like a
- if(inColor) { // scroll bar arrow
- if(!inactive && canHilite[inx-1]) { // with lighter center
- setPartColor(theCtl, cTingeLight, true);
- GetForeColor(&grayColor);
- grayColor.red -= 13107;
- grayColor.green -= 13107;
- grayColor.blue -= 13107;
- RGBForeColor(&grayColor);
- PaintPoly((**hCDEF).poly[inx]); // filled color is light
- ForeColor(blackColor); // needed for sys6
- setPartColor(theCtl, cTingeDark, true);
- }
- }
- else
- if(!(varCode & bigArrows)) // 3D, but in b&w, small
- PaintPoly((**hCDEF).poly[inx]); // arrow is solid fgColor
- }
- else // not 3D
- if(!(varCode & bigArrows)) // so, small arrow
- PaintPoly((**hCDEF).poly[inx]); // is solid fgColor
- }
-
- //----------------------------------------------------------------------------------
- // Finally, frame the arrow
- //----------------------------------------------------------------------------------
-
- FramePoly((**hCDEF).poly[inx]); // frame the arrow
-
- if(!inactive) { // set fg for next arrow
- if(inColor)
- setPartColor(theCtl, cFrameColor, true);
- else
- ForeColor(blackColor);
- }
- }
- }
- }
-
- //==================================================================================
- // Get the rectangles for each part of the control. These are used for
- // detecting mouse actions and drawing the control.
- //==================================================================================
-
- static void getRects (ControlHandle theCtl, short varCode, Rect parts[])
- {
- short aHt,aWid,fHt,cHt,offset;
- Rect base,work,rUp,rDown;
- FontInfo f;
-
- //----------------------------------------------------------------------------------
- // set sizes for arrow height & width
- //----------------------------------------------------------------------------------
- if(varCode & bigArrows) {
- if(varCode & horizArrows) {
- aHt = ARROWID1;
- aWid = ARROWHT1;
- }
- else {
- aHt = ARROWHT1;
- aWid = ARROWID1;
- }
- }
- else {
- if(varCode & horizArrows) {
- aHt = ARROWID;
- aWid = ARROWHT;
- }
- else {
- aHt = ARROWHT;
- aWid = ARROWID;
- }
- }
-
- //----------------------------------------------------------------------------------
- // part rectangles for Arrow portions of control, right justified in control rect
- //----------------------------------------------------------------------------------
- base = (**theCtl).contrlRect; // the entire control
- cHt = base.bottom-base.top; // control height
- parts[ALL] = parts[BASELINE] = base;
-
- base.top = base.top + (cHt - aHt)/2; // center arrow in rect
- base.bottom = base.top + aHt;
-
- rUp = work = base;
- OffsetRect(&rUp,-1,0);
- rUp.left = rUp.right - aWid; // shift arrow to right
- parts[FRAME] = rDown = rUp; // rUp & rDown are full rects
-
- if(varCode & horizArrows)
- rUp.left = rUp.right - (rUp.right - rUp.left)/2;// split them in half
- else
- rUp.bottom = rUp.top + (rUp.bottom - rUp.top)/2;
- parts[UPARROW] = rUp; // rUp is top/right half
-
- if(varCode & horizArrows)
- rDown.right = rUp.left-1;
- else
- rDown.top = rUp.bottom+1;
- parts[DOWNARROW] = rDown; // rDown is bottom/left half
-
- //----------------------------------------------------------------------------------
- // set text drawing from font metrics
- //----------------------------------------------------------------------------------
- GetFontInfo(&f);
- fHt = f.ascent + f.descent+f.leading;
- if(f.leading == 0)
- fHt++;
-
- offset = (aHt - fHt)/2; // center digits in rect
- work.bottom -= offset;
- work.right -= aWid;
- parts[TITLE] = work;
- parts[BASELINE].bottom = fHt - f.ascent; // baseline for DrawStr
- }
-
- //==================================================================================
- // Accelerate the control. If we roll over a tens or hundreds FIVE times
- // and the mouse is still down, bump the increment. This lets the control
- // spin a number up by 1's from 0-50, by 10's from 50-100, then by 100's.
- //==================================================================================
-
- static void accelerate(ControlHandle theCtl)
- {
- long mult;
- short incr2;
- hSpinData hCDEF;
-
- hCDEF = (hSpinData)(**theCtl).contrlData;
- if(!hCDEF)
- return;
-
- if((**hCDEF).increment == 1)
- incr2 = 10;
- else
- incr2 = (**hCDEF).increment*(**hCDEF).increment;
-
- mult = (**theCtl).contrlValue % incr2;
- if((**hCDEF).currIncr ==
- (**hCDEF).increment && !mult) { // just rolled over a ten
- if((**hCDEF).bumpit == 1) { // for the fifth time
- (**hCDEF).currIncr = incr2; // bump our increment value
- (**hCDEF).bumpit = -3;
- }
- else {
- (**hCDEF).bumpit += 1; // for the first time
- }
- }
- else
- if((**hCDEF).currIncr == incr2 && !mult) { // just rolled over a hundred
- if((**hCDEF).bumpit == 1) { // for the fifth time
- (**hCDEF).currIncr = incr2*incr2; // bump our increment value
- }
- else {
- (**hCDEF).bumpit += 1; // for the first time
- }
- }
- }