Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
BigEasy/BigEasyControls.c
/* |
File: BigEasyControls.c |
Copyright: © 1990-1991, 1994 by Apple Computer, Inc., all rights reserved. |
This file is used in these builds: Warhol |
Change History (most recent first): |
<10> 11-10-94 dvb |
<9> 6/10/94 dvb nil control list behaves better. |
<8> 4/13/92 dvb Minor bugs (empty controllist, &c) |
<7> 4/3/92 dvb New calls. |
<6> 5/28/91 JB Added prototypes for BigEasy Proc Ptrs |
<5> 5/22/91 PH new style prototypes |
<4> 4/25/91 JB Changing to new THINK_C interface files |
<3> 12/5/90 GW Fix dispose easycontrol |
<2> 11/17/90 dvb Return unprocessed key-actions |
<1> 11/17/90 dvb New again after 1st CD! |
To Do: |
*/ |
/* |
* file: BigEasyControls.c |
* |
* started 25 May 1990 12:07:24 Friday at 310 Nobel |
* |
* david van brink |
* |
*/ |
/************************************ |
* Inclusions |
************************************/ |
#include <Memory.h> |
#include <QuickDraw.h> |
#include <Events.h> |
#define privateEasyControls |
#include "BigEasy2.h" |
#include "BigEasyGrafish.h" |
#include "BigEasyTextish.h" |
#include "BigEasyControls.h" |
/************************************ |
* Globals |
************************************/ |
static short defaultColors[6] = |
{ |
0, |
PackColor555(46035,46035,46035), |
PackColor555(25535,65535,25535), |
PackColor555(24000,0,0), |
0, |
0 |
}; |
/************************************ |
* Prototypes |
************************************/ |
static void SelectEasyControl(easyControl ech, easyControlList list); |
static void UnhighlightSelection(easyControlList list); |
static void WalkDrawEasyControlList(easyControlList list,long,long); |
static void WalkInvalEasyControlList(easyControlList list,long,long); |
static short GetControlNumber(easyControl ech); |
static void SetListText(easyControlList listH); |
/************************************ |
* Routines |
************************************/ |
easyControl NewEasyControl(easyControlType *type,Rect *r, long variation, void *style, |
long refcon,long id,long value,easyControlList list) |
/* |
* Make a new handle for an easy control, and call the |
* init routine for that control. Then, add it to the |
* list passed in. |
*/ |
{ |
easyControl ech; |
register easyControlPtr ec; |
register easyControl w; |
easyControlListPtr l; |
ech = (easyControl)NewHandle(sizeof(easyControlRecord)); |
FailNil(ech); |
HLock((Handle)ech); |
ec = *ech; |
ec->next = nil; |
ec->list = list; |
l = *list; |
w = l->firstControl; |
if(!w) |
{ |
ec->prev = nil; |
l->firstControl = ech; |
} |
else |
{ |
while((**w).next) |
w = (**w).next; |
(**w).next = ech; |
ec->prev = w; |
} |
ec->type = type; |
ec->rect = *r; |
ec->flags = easyControlActive; |
ec->refcon = refcon; |
ec->id = id; |
ec->variation = variation; |
ec->value = value; |
ec->style = style; |
ec->state = nil; |
ec->color[0] = defaultColors[0]; |
ec->color[1] = defaultColors[1]; |
ec->color[2] = defaultColors[2]; |
ec->color[3] = defaultColors[3]; |
ec->color[4] = defaultColors[4]; |
ec->color[5] = defaultColors[5]; |
ec->actionProc = nil; |
ec->initActionProc = nil; |
ec->doneActionProc = nil; |
ec->valueProc = nil; |
/* ec->keyProc = nil; */ |
ec->low = 0; |
ec->high = 100; |
SetListText(list); |
(*type->newProc)(ec); |
HUnlock((Handle)ech); |
return ech; |
} |
void DisposeEasyControl(easyControl ech, easyControlList list) |
/* |
* remove a control from the list passed |
*/ |
{ |
register easyControl *w; |
register easyControlPtr ec; |
register easyControlListPtr l; |
easyControl last; |
l = *list; |
last = nil; |
ec = *ech; |
w = &l->firstControl; |
while(*w) |
{ |
if(*w == ech) |
{ |
*w = ec->next; |
if (*w != nil) /* Make sure its not nil - GW */ |
(**(ec->next)).prev = last; |
goto goHome; |
} |
else |
{ |
last = *w; |
w = &(***w).next; |
} |
} |
goHome:; |
DisposHandle((Handle)ech); |
} |
void DisposeEasyControlList(easyControlList list) |
{ |
register easyControl w,n; |
w = (**list).firstControl; |
while(w) |
{ |
n = (**w).next; |
DisposeEasyControl(w,list); |
w = n; |
} |
DisposHandle((Handle)list); |
} |
easyControlList NewEasyControlList(WindowPtr w,long refcon) |
{ |
easyControlList listH; |
easyControlListPtr list; |
listH = (easyControlList)NewHandle(sizeof(easyControlListRecord)); |
list = *listH; |
list->firstControl = nil; |
list->selectedControl = nil; |
list->nextSelectedControl = nil; |
list->ownerWindow = w; |
list->refcon = refcon; |
list->textFont = 3; /* geneva */ |
list->textSize = 9; |
list->textFace = 0; |
list->nextIdle = 0; |
list->ticksPerIdle = 30; |
return listH; |
} |
void SetListText(easyControlList listH) |
{ |
TextFont((**listH).textFont); |
TextFace((**listH).textFace); |
TextSize((**listH).textSize); |
} |
void KeyEasyControlList(easyControlList listH,short key,short mods,controlClickResult *ccr) |
/* |
* Pass a keypress to the currently |
* selected control. we swipe "tab"s |
* to skip from control to control, and |
* "esc" to say "no control selected". |
*/ |
{ |
register easyControl ech; |
register easyControlPtr ec; |
register easyControlListPtr list; |
short listHState; |
Boolean tookKey; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
if(ccr) |
{ |
ccr->whichControl = nil; |
ccr->tracked = false; |
ccr->value = 0; |
ccr->refcon = 0; |
ccr->id = 0; |
} |
ech = list->selectedControl; |
if(key == '\t') |
{ |
nextEch: |
if(ech) |
{ |
if(mods & shiftKey) |
ech = (**ech).prev; |
else |
ech =(**ech).next; |
} |
else |
{ |
ech = list->firstControl; |
if(mods & shiftKey && ech) |
while((**ech).next) |
ech = (**ech).next; |
} |
if(list->nextSelectedControl) |
{ |
ech = list->nextSelectedControl; |
list->nextSelectedControl = nil; |
} |
if(ech && !(**ech).type->keyProc) /* if its got no keyproc, it doesn't do keypresses */ |
goto nextEch; |
SelectEasyControl(ech,listH); |
} |
else if(key == 27) /* the escape key */ |
{ |
SelectEasyControl(nil,listH); |
list->nextSelectedControl = ech; |
} |
else |
{ |
if(ech) |
{ |
HLock((Handle)ech); |
ec = *ech; |
(*ec->type->keyProc)(ec,key,mods,&tookKey); |
if(ccr) |
{ |
ccr->whichControl = ech; |
ccr->tracked = tookKey; |
ccr->value = ec->value; |
ccr->refcon = ec->refcon; |
ccr->id = ec->id; |
} |
HUnlock((Handle)ech); |
UnhighlightSelection(listH); /* and forestall the next idle-blink for a while */ |
} |
} |
HSetState((Handle)listH,listHState); |
} |
short GetControlNumber(register easyControl ech) |
/* |
* return the position in whatever list owns this control |
*/ |
{ |
short n; |
n = 1; |
while( (**ech).prev) |
{ |
n++; |
ech = (**ech).prev; |
} |
return n; |
} |
void UnhighlightSelection(easyControlList listH) |
/* |
* if there's a selected control, |
* put it in the unhighlighted phase |
*/ |
{ |
register easyControl ech; |
register easyControlPtr ec; |
easyControlListPtr list; |
short listHState; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
ech = list->selectedControl; |
if(ech) |
{ |
list->nextIdle = TickCount()+list->ticksPerIdle; /* reset the idling phase to normal */ |
HLock((Handle)ech); |
ec = *ech; |
list->idleRef = 0; |
SetPort((*ec->list)->ownerWindow); |
(*ec->type->idleProc)(ec,&list->idleRef); |
HUnlock((Handle)ech); |
} |
HSetState((Handle)listH,listHState); |
} |
easyControl ClickEasyControlList(easyControlList listH,Point p, |
controlClickResult *ccr,short mods) |
{ |
register easyControl w; |
register easyControlPtr ec; |
easyControlListPtr list; |
short trackResult; |
short whichControl; |
short listHState; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
w = list->firstControl; |
whichControl = 0; |
if(ccr) |
{ |
ccr->whichControl = nil; |
ccr->tracked = false; |
ccr->value = 0; |
ccr->refcon = 0; |
ccr->id = 0; |
} |
while(w) |
{ |
whichControl++; |
if(PtInRect(p,&(**w).rect) && (**w).type->trackProc) /* in rect and mouse sensitive */ |
{ |
SelectEasyControl(nil,listH); |
HLock((Handle)w); |
ec = *w; |
ec->flags |= easyControlTracking; |
if(ec->type->keyProc) /* never select keyless control */ |
list->nextSelectedControl = w; |
trackResult = 0; |
ec->flags |= easyControlSetValue; |
(*ec->type->trackProc)(ec,p,&trackResult,mods); |
if(trackResult && ec->valueProc) |
(*ec->valueProc)(w); |
ec->flags &= ~easyControlSetValue; |
if(ccr) |
{ |
ccr->whichControl = w; |
ccr->tracked = true; |
ccr->value = ec->value; |
ccr->refcon = ec->refcon; |
ccr->id = ec->id; |
} |
ec->flags &= ~easyControlTracking; |
(*ec->type->drawValueProc)(ec); |
HUnlock((Handle)w); |
goto goHome; |
} |
else |
w = (**w).next; |
} |
goHome:; |
HSetState((Handle)listH,listHState); |
return w; |
} |
void DrawEasyControlList(register easyControlList list) |
{ |
WalkDrawEasyControlList(list,~0,0); |
} |
void DeactivateEasyControlList(easyControlList list) |
/* |
* A window should call this when it |
* becomes un-frontmost |
*/ |
{ |
WalkDrawEasyControlList(list,~0,easyControlBack); |
} |
void ActivateEasyControlList(easyControlList list) |
/* |
* A window should call this when it |
* becomes frontmost |
*/ |
{ |
WalkInvalEasyControlList(list,~easyControlBack,0); |
} |
void WalkDrawEasyControlList(easyControlList listH,long and,long or) |
/* |
* The gut routine of Draw, Activate, and DeactivateEasyControlList |
*/ |
{ |
register easyControlPtr ec; |
register easyControl w; |
register easyControlListPtr list; |
short listHState; |
GrafPtr oldPort; |
if(!listH) |
goto goHome; |
GetPort(&oldPort); |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
SetPort(list->ownerWindow); |
SetListText(listH); |
w = list->firstControl; |
while (w) |
{ |
HLock((Handle)w); |
ec = *w; |
ec->flags &= and; |
ec->flags |= or; |
(*ec->type->drawProc)(ec); |
ValidRect(&ec->rect); |
HUnlock((Handle)w); |
w = ec->next; |
} |
HSetState((Handle)listH,listHState); |
SetPort(oldPort); |
goHome:; |
} |
void WalkInvalEasyControlList(easyControlList listH,long and,long or) |
/* |
* The gut routine of Draw, Activate, and DeactivateEasyControlList |
*/ |
{ |
register easyControlPtr ec; |
register easyControl w; |
register easyControlListPtr list; |
short listHState; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
SetPort(list->ownerWindow); |
w = list->firstControl; |
while (w) |
{ |
HLock((Handle)w); |
ec = *w; |
ec->flags &= and; |
ec->flags |= or; |
InvalRect(&ec->rect); |
HUnlock((Handle)w); |
w = ec->next; |
} |
HSetState((Handle)listH,listHState); |
} |
void IdleEasyControlList(register easyControlList listH) |
{ |
register easyControl ech; |
easyControlPtr ec; |
register easyControlListPtr list; |
long t; |
short listHState; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
ech = list->selectedControl; |
if(ech) |
{ |
t = TickCount(); |
if(t > list->nextIdle) |
{ |
list->nextIdle = t+list->ticksPerIdle; |
list->idleRef++; |
HLock((Handle)ech); |
ec = *ech; |
SetPort((*ec->list)->ownerWindow); |
(*ec->type->idleProc)(ec,&list->idleRef); |
HUnlock((Handle)ech); |
} |
} |
HSetState((Handle)listH,listHState); |
} |
void SetEasyControlValue(register easyControl ech,long v) |
{ |
register easyControlPtr ec; |
becSetValueProcPtr svp; |
HLock((Handle)ech); |
ec = *ech; |
SetPort((**ec->list).ownerWindow); |
svp = ec->type->setValueProc; |
if(svp) |
(*svp)(ec,v); |
else |
ec->value = v; |
ec->flags |= easyControlSetValue; |
SetListText(ec->list); |
(*ec->type->drawValueProc)(ec); |
ec->flags &= ~easyControlSetValue; |
HUnlock((Handle)ech); |
} |
long GetEasyControlValue(easyControl ech) |
{ |
return (**ech).value; |
} |
long GetEasyControlRefcon(easyControl ech) |
{ |
return (**ech).refcon; |
} |
long GetEasyControlID(easyControl ech) |
{ |
return (**ech).id; |
} |
void SetEasyControlRange(easyControl ech,long l,long h) |
{ |
register easyControlPtr ec; |
ec = *ech; |
ec->low = l; |
ec->high = h; |
} |
void SetEasyControlValueProc(easyControl ech,becValueProcPtr proc) |
{ |
register easyControlPtr ec; |
ec = *ech; |
ec->valueProc = proc; |
} |
void SetEasyControlActionProc(easyControl ech,becActionProcPtr proc) |
{ |
register easyControlPtr ec; |
ec = *ech; |
ec->actionProc = proc; |
} |
void SetEasyControlInitActionProc(easyControl ech,becInitActionProcPtr proc) |
{ |
register easyControlPtr ec; |
ec = *ech; |
ec->initActionProc = proc; |
} |
void SetEasyControlDoneActionProc(easyControl ech,becDoneActionProcPtr proc) |
{ |
register easyControlPtr ec; |
ec = *ech; |
ec->doneActionProc = proc; |
} |
void GetEasyControlColors(easyControl ech,register short *colors) |
{ |
register short i; |
register short *src; |
if(ech) |
src = &(**ech).color[0]; |
else |
src = &defaultColors[0]; |
for(i = 5; i>=0; i--) |
*colors++ = *src++; |
} |
void SetEasyControlColors(easyControl ech,register short *colors) |
{ |
register short i; |
register short *dst; |
if(ech) |
dst = &(**ech).color[0]; |
else |
dst = &defaultColors[0]; |
for(i = 5; i>=0; i--) |
*dst++ = *colors++; |
} |
void SelectEasyControl(easyControl ech,easyControlList listH) |
/* |
* Unselect the current one (if any) |
* and start the new one blinking. |
*/ |
{ |
register easyControlListPtr list; |
short listHState; |
listHState = HGetState((Handle)listH); |
HLock((Handle)listH); |
list = *listH; |
list->idleRef = 0; |
UnhighlightSelection(listH); |
list->selectedControl = ech; |
list->nextIdle = 0; |
IdleEasyControlList(listH); |
HSetState((Handle)listH,listHState); |
} |
void GetEasyControlRect(easyControl ech,Rect *r) |
/* |
* Return the current bounds of the control |
*/ |
{ |
*r = (**ech).rect; |
} |
void SetEasyControlRect(easyControl ech,Rect *r) |
/* |
* Move the control to the newly specified rectangle |
*/ |
{ |
register easyControlPtr ec; |
HLock((Handle)ech); |
ec = *ech; |
SetPort((*ec->list)->ownerWindow); |
InvalRect(&ec->rect); |
ec->rect = *r; |
ec->flags |= easyControlMoved; |
InvalRect(&ec->rect); |
HUnlock((Handle)ech); |
} |
unsigned short Replicate555(register unsigned short x) |
{ |
x &= 0x001F; |
return (x<<11) | (x<<6) | (x<<1) | (x>>4); |
} |
void Color555(register short x,register RGBColor *c) |
{ |
c->red = Replicate555(x>>10); |
c->green = Replicate555(x>>5); |
c->blue = Replicate555(x); |
} |
void Fore555(register short x) |
{ |
RGBColor c; |
Color555(x,&c); |
RGBForeColor(&c); |
RGBBackColor(&c); |
} |
#define kGrade 24000 |
static long PinAdd(long,long); |
static long PinAdd(register long a,register long b) |
{ |
a+= b; |
if(a > 65535) |
a = 65535; |
else if(a < 0) |
a = 0; |
return a; |
} |
void Fore555Light(register short x) |
{ |
RGBColor c; |
Color555(x,&c); |
c.red = PinAdd(c.red,kGrade); |
c.green = PinAdd(c.green,kGrade); |
c.blue = PinAdd(c.blue,kGrade); |
/* |
c.green = (c.green + 65535L)>>1; |
c.blue = (c.blue + 65535L)>>1;*/ |
RGBForeColor(&c); |
} |
void Fore555Dark(register short x) |
{ |
RGBColor c; |
Color555(x,&c); |
c.red = PinAdd(c.red,-kGrade); |
c.green = PinAdd(c.green,-kGrade); |
c.blue = PinAdd(c.blue,-kGrade); |
/* c.red = c.red >> 1; |
c.green = c.green >> 1; |
c.blue = c.blue >> 1;*/ |
RGBForeColor(&c); |
} |
#define kCCEdge 10000 |
void Fore555Contrast(register short x) |
/* |
* Make a color that contrasts well with |
* the passed color: invert if close to a |
* side of the color cube, or shift by 32768 |
*/ |
{ |
RGBColor c; |
Color555(x,&c); |
if(c.red < kCCEdge || c.red > (65535-kCCEdge) || |
c.green < kCCEdge || c.green > (65535-kCCEdge) || |
c.blue < kCCEdge || c.blue > (65535-kCCEdge) ) |
{ |
c.red = ~c.red; |
c.green = ~c.green; |
c.blue = ~c.blue; |
} |
else |
{ |
c.red += 32768; |
c.green += 32768; |
c.blue += 32768; |
} |
RGBForeColor(&c); |
} |
void RaisedRect(register Rect *r,register short x) |
/* |
* Draw rectangle r with a 1 pixel highlight |
* to raise it off the screen |
*/ |
{ |
Fore555(x); |
if( ((r->right - r->left) <= 2) || ((r->bottom - r->top) <= 2) ) |
PaintRect(r); |
else |
{ |
PenSize(1,1); |
PaintRect(r); |
Fore555Light(x); |
MoveTo(r->left,r->bottom-1); |
LineTo(r->left,r->top); |
LineTo(r->right-1,r->top); |
Fore555Dark(x); |
LineTo(r->right-1,r->bottom-1); |
LineTo(r->left,r->bottom-1); |
} |
} |
void LoweredRect(Rect *r,register short x) |
/* |
* Draw rectangle r with a 1 pixel highlight |
* to raise it off the screen |
*/ |
{ |
PenSize(1,1); |
Fore555(x); |
PaintRect(r); |
Fore555Dark(x); |
MoveTo(r->left,r->bottom-1); |
LineTo(r->left,r->top); |
LineTo(r->right-1,r->top); |
Fore555Light(x); |
LineTo(r->right-1,r->bottom-1); |
LineTo(r->left,r->bottom-1); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-03-19