Demonstration Program
//
// Controls3.h
//
//
// This program demonstrates the creation and handling of those controls not demonstrated
// in the programs Controls1 and Controls2 (Chapter 7), with the exception of List boxes
// and determinate progress bars.
//
// The program utilises the following resources:
//
// An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit, and Demonstration
// menus (preload, non-purgeable).
//
// 'MENU' resources (non-purgeable) for bevel button menus and for a pop-up group box.
//
// A 'WIND' resource (purgeable) (initially not visible).
//
// 'DLOG' resources and associated 'DITL', 'dlgx' and 'dftb' resources (purgeable).
//
// 'CNTL' resources (purgeable).
//
// A 'tab#' resource (purgeable.
//
// An icon family resource (purgeable).
//
// 'PICT' resources (purgeable).
//
// 'cicn' resources (purgeable).
//
// 'STR#' resources (purgeable).
//
// 'TEXT' and 'styl' resources (purgeable).
//
// 'hrct' and an 'hwin' resources (preload, purgeable), which provide help
// balloons describing the various controls.
//
// A 'SIZE' resource with the acceptSuspendResumeEvents, doesActivateOnFGSwitch,
// and is32BitCompatible flags set.
//
//
// ............................................................................. includes
#include <Appearance.h>
#include <ControlDefinitions.h>
#include <Devices.h>
#include <Gestalt.h>
#include <LowMem.h>
#include <Sound.h>
#include <ToolUtils.h>
#include <Resources.h>
// .............................................................................. defines
#define rMenubar 128
#define mApple 128
#define iAbout 1
#define mFile 129
#define iQuit 11
#define mDemonstration 131
#define iBevelAndImage 1
#define iTabEditClock 2
#define iGroupArrowsProgress 3
#define iSliders 4
#define rBevelImageWindow 128
#define cBevelButton1 128
#define cBevelButton2 129
#define cBevelButton3 130
#define cBevelButton4 131
#define cBevelButton5 132
#define cBevelButton6 133
#define cBevelButton7 134
#define cBevelButton8 135
#define cBevelButton9 136
#define cBevelButton10 137
#define cBevelButton11 138
#define cBevelButton12 139
#define cBevelButton13 140
#define cBevelButton14 141
#define cBevelButton15 142
#define cBevelButton16 143
#define cBevelButton17 144
#define cBevelButton18 145
#define cBevelButton19 146
#define cBevelButton20 147
#define cBevelButton21 148
#define cImageWell1 149
#define cImageWell2 150
#define cPicture1 151
#define cPicture2 152
#define cColourIcon1 153
#define cColourIcon2 154
#define cIconSuite1 155
#define cIconSuite2 156
#define cWindowHeader 157
#define rPartCodeStrings 128
#define rGraphicAlignStrings 129
#define rTextAlignStrings 130
#define rTextPlacementStrings 131
#define rTabEditClockDialog 128
#define iTabs 2
#define tabEditText 1
#define tabClocks 2
#define iEditTextUserPane 3
#define iEditText1 5
#define iEditText2 7
#define iEditText3 9
#define iExtractEditText 10
#define iClocksUserPane 12
#define iImageWellEditText 11
#define iClocks1 14
#define iClocks2 16
#define iClocks3 18
#define iExtractClocks 19
#define iImageWellClocks 20
#define kLeftArrow 0x1C
#define kRightArrow 0x1D
#define kUpArrow 0x1E
#define kDownArrow 0x1F
#define kBackspace 0x08
#define rGroupArrowsProgDialog 129
#define iCheckboxGroup 2
#define iRadioGroupColour 3
#define iStaticTextColourDepth 7
#define iPopupGroup 8
#define iUserPaneNamesInitials 9
#define iRadioGroupNames 10
#define iCheckboxShowInitials 13
#define iUserPaneScoreAverage 15
#define iRadioGroupScores 16
#define iCheckboxShowAverages 19
#define iStaticTextCache 26
#define iLittleArrows 27
#define iPushButtonExtract 28
#define iImageWell 29
#define iDisclosureTriangle 31
#define iStaticTextDisclosure 32
#define iProgressBar 34
#define rSlidersDialog 131
#define iSlider1 2
#define iSlider2 3
#define iSlider3 4
#define iSlider4 5
#define iSlider1StaticText 9
#define iSlider2StaticText 11
#define iSlider3StaticText 13
#define iSlider4StaticText 15
#define iSlider5 17
#define iUserPane1 18
#define iSlider6 19
#define rAboutDialog 132
#define MAXLONG 0x7FFFFFFF
#define MIN(a,b) ((a) < (b) ? (a) : (b))
// ............................................................................. typedefs
typedef struct
{
ControlHandle bevelButton1Hdl;
ControlHandle bevelButton2Hdl;
ControlHandle bevelButton3Hdl;
ControlHandle bevelButton4Hdl;
ControlHandle bevelButton5Hdl;
ControlHandle bevelButton6Hdl;
ControlHandle bevelButton7Hdl;
ControlHandle bevelButton8Hdl;
ControlHandle bevelButton9Hdl;
ControlHandle bevelButton10Hdl;
ControlHandle bevelButton11Hdl;
ControlHandle bevelButton12Hdl;
ControlHandle bevelButton13Hdl;
ControlHandle bevelButton14Hdl;
ControlHandle bevelButton15Hdl;
ControlHandle bevelButton16Hdl;
ControlHandle bevelButton17Hdl;
ControlHandle bevelButton18Hdl;
ControlHandle bevelButton19Hdl;
ControlHandle bevelButton20Hdl;
ControlHandle bevelButton21Hdl;
ControlHandle imageWell1Hdl;
ControlHandle imageWell2Hdl;
ControlHandle picture1Hdl;
ControlHandle picture2Hdl;
ControlHandle colourIcon1Hdl;
ControlHandle colourIcon2Hdl;
ControlHandle iconSuite1Hdl;
ControlHandle iconSuite2Hdl;
ControlHandle windowHeaderHdl;
} BevelDocStruc;
typedef BevelDocStruc **BevelDocStrucHandle;
// .................................................................. function prototypes
void main (void);
void doInitManagers (void);
void doGetControls (WindowPtr);
void doEvents (EventRecord *);
void doMouseDown (EventRecord *);
void doMenuChoice (SInt32);
void doUpdate (EventRecord *);
void doActivate (EventRecord *);
void doActivateWindow (WindowPtr,Boolean);
void doConcatPStrings (Str255,Str255);
void doCopyPString (Str255,Str255);
void doGetDepthAndDevice (void);
void doBevelImagePictIcon (void);
void doBevelImagePictIconContent (EventRecord *,WindowPtr);
void doDrawPartCode (WindowPtr,ControlHandle,SInt16,SInt16);
void doGraphicAlignment (WindowPtr,ControlHandle,ControlHandle);
void doTextAlignment (WindowPtr,ControlHandle,ControlHandle);
void doTextOffset (WindowPtr,ControlHandle,ControlHandle);
void doTextPlacement (WindowPtr,ControlHandle,ControlHandle);
void doDrawMessage (WindowPtr,Boolean);
void doDrawLegends (Boolean);
void doTabEditClock (void);
void doExtractEditText (DialogPtr);
void doExtractDateTime (DialogPtr);
void doGroupArrowsProgress (void);
void doCheckBoxGroupBox (DialogPtr);
void doPopupGroupBox (DialogPtr);
void doAsynchronousAndProgress (DialogPtr);
void doExtractCurrentStatus (DialogPtr);
void doSliderUserPane (void);
void doDrawSliderValues (DialogPtr,ControlHandle);
void doAboutBox (void);
pascal Boolean eventFilter (DialogPtr,EventRecord *,SInt16 *);
pascal void editTextValidator (ControlHandle controlHdl);
pascal ControlKeyFilterResult numericFilter (ControlHandle,SInt16 *,SInt16 *,SInt16 *);
pascal void arrowsActionFunction (ControlHandle,SInt16);
pascal void sliderActionFunction1 (ControlHandle,SInt16);
pascal void sliderActionFunction2 (ControlHandle,SInt16);
pascal void userPaneDrawFunction (ControlHandle,SInt16);
pascal void userPaneActivateFunction (ControlHandle,Boolean);
//
// Controls3.c
//
// ............................................................................. includes
#include "Controls3.h"
// ..................................................................... global variables
Boolean gInBackground;
Boolean gDone;
Str255 gCurrentString;
Boolean gBevelAndImageActive = false;
Boolean gGroupArrowsProgressActive = false;
Boolean gSlidersActive = false;
Boolean gPixelDepth;
Boolean gIsColourDevice;
// main
void main(void)
{
OSErr osError;
SInt32 response;
Boolean macOS85Present = false;
Handle menubarHdl;
MenuHandle menuHdl;
EventRecord EventStructure;
// ................................................................ initialise managers
doInitManagers();
// ....................................... check whether Mac OS 8.5 or later is present
osError = Gestalt(gestaltSystemVersion,&response);
if(osError == noErr && response >= 0x00000850)
macOS85Present = true;
// .......................................................... set up menu bar and menus
menubarHdl = GetNewMBar(rMenubar);
if(menubarHdl == NULL)
ExitToShell();
SetMenuBar(menubarHdl);
DrawMenuBar();
menuHdl = GetMenuHandle(mApple);
if(menuHdl == NULL)
ExitToShell();
else
AppendResMenu(menuHdl,'DRVR');
// .............. if Mac OS 8.5 or later not present, disable About. item in Apple menu
if(!macOS85Present)
{
menuHdl = GetMenuHandle(mApple);
DisableItem(menuHdl,iAbout);
}
// .................................................................... enter eventLoop
gDone = false;
while(!gDone)
{
if(WaitNextEvent(everyEvent,&EventStructure,MAXLONG,NULL))
doEvents(&EventStructure);
}
}
// doInitManagers
void doInitManagers(void)
{
MaxApplZone();
MoreMasters();
InitGraf(&qd.thePort);
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs(NULL);
InitCursor();
FlushEvents(everyEvent,0);
RegisterAppearanceClient();
}
// doEvents
void doEvents(EventRecord *eventStrucPtr)
{
SInt8 charCode;
SInt32 menuChoice;
SInt16 menuID, menuItem;
switch(eventStrucPtr->what)
{
case keyDown:
case autoKey:
charCode = eventStrucPtr->message & charCodeMask;
if((eventStrucPtr->modifiers & cmdKey) != 0)
{
menuChoice = MenuEvent(eventStrucPtr);
menuID = HiWord(menuChoice);
menuItem = LoWord(menuChoice);
if(menuID == mFile && menuItem == iQuit)
gDone = true;
}
break;
case mouseDown:
doMouseDown(eventStrucPtr);
break;
case updateEvt:
doUpdate(eventStrucPtr);
break;
case activateEvt:
doActivate(eventStrucPtr);
break;
case osEvt:
switch((eventStrucPtr->message >> 24) & 0x000000FF)
{
case suspendResumeMessage:
gInBackground = (eventStrucPtr->message & resumeFlag) == 0;
doActivateWindow(FrontWindow(),!gInBackground);
break;
}
HiliteMenu(0);
break;
}
}
// doMouseDown
void doMouseDown(EventRecord *eventStrucPtr)
{
SInt16 partCode;
WindowPtr windowPtr;
MenuHandle menuHdl;
partCode = FindWindow(eventStrucPtr->where,&windowPtr);
switch(partCode)
{
case inMenuBar:
menuHdl = GetMenuHandle(mDemonstration);
if(gBevelAndImageActive)
DisableItem(menuHdl,iBevelAndImage);
else
EnableItem(menuHdl,iBevelAndImage);
doMenuChoice(MenuSelect(eventStrucPtr->where));
break;
case inContent:
if(windowPtr != FrontWindow())
SelectWindow(windowPtr);
else
{
if(gBevelAndImageActive)
doBevelImagePictIconContent(eventStrucPtr,windowPtr);
}
break;
case inDrag:
DragWindow(windowPtr,eventStrucPtr->where,&qd.screenBits.bounds);
break;
case inGoAway:
if(TrackGoAway(windowPtr,eventStrucPtr->where) == true)
{
DisposeWindow(windowPtr);
gBevelAndImageActive = false;
}
break;
}
}
// doMenuChoice
void doMenuChoice(SInt32 menuChoice)
{
SInt16 menuID, menuItem;
Str255 itemName;
SInt16 daDriverRefNum;
menuID = HiWord(menuChoice);
menuItem = LoWord(menuChoice);
if(menuID == 0)
return;
switch(menuID)
{
case mApple:
if(menuItem == iAbout)
doAboutBox();
else
{
GetMenuItemText(GetMenuHandle(mApple),menuItem,itemName);
daDriverRefNum = OpenDeskAcc(itemName);
}
break;
case mFile:
if(menuItem == iQuit)
gDone = true;
break;
case mDemonstration:
switch(menuItem)
{
case iBevelAndImage:
gBevelAndImageActive = true;
doBevelImagePictIcon();
break;
case iTabEditClock:
doTabEditClock();
break;
case iGroupArrowsProgress:
gGroupArrowsProgressActive = true;
doGroupArrowsProgress();
break;
case iSliders:
gSlidersActive = true;
doSliderUserPane();
break;
}
break;
}
HiliteMenu(0);
}
// doUpdate
void doUpdate(EventRecord *eventStrucPtr)
{
WindowPtr windowPtr;
Boolean drawMode = false;
windowPtr = (WindowPtr) eventStrucPtr->message;
BeginUpdate(windowPtr);
if(gBevelAndImageActive)
{
SetPort(windowPtr);
UpdateControls(windowPtr,windowPtr->visRgn);
if(windowPtr == FrontWindow())
drawMode = true;
doDrawMessage(windowPtr,drawMode);
doDrawLegends(drawMode);
}
EndUpdate(windowPtr);
}
// doActivate
void doActivate(EventRecord *eventStrucPtr)
{
WindowPtr windowPtr;
Boolean becomingActive;
windowPtr = (WindowPtr) eventStrucPtr->message;
becomingActive = ((eventStrucPtr->modifiers & activeFlag) == activeFlag);
doActivateWindow(windowPtr,becomingActive);
}
// doActivateWindow
void doActivateWindow(WindowPtr windowPtr,Boolean becomingActive)
{
ControlHandle controlHdl;
GetRootControl(windowPtr,&controlHdl);
if(becomingActive)
{
if(gBevelAndImageActive)
{
ActivateControl(controlHdl);
doDrawMessage(windowPtr,becomingActive);
doDrawLegends(becomingActive);
}
}
else
{
if(gBevelAndImageActive)
{
DeactivateControl(controlHdl);
doDrawMessage(windowPtr,becomingActive);
doDrawLegends(becomingActive);
}
}
}
// doConcatPStrings
void doConcatPStrings(Str255 targetString,Str255 appendString)
{
SInt16 appendLength;
appendLength = MIN(appendString[0],255 - targetString[0]);
if(appendLength > 0)
{
BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
targetString[0] += appendLength;
}
}
// doCopyPString
void doCopyPString(Str255 sourceString,Str255 destinationString)
{
SInt16 stringLength;
stringLength = sourceString[0];
BlockMove(sourceString + 1,destinationString + 1,stringLength);
destinationString[0] = stringLength;
}
// doGetDepthAndDevice
void doGetDepthAndDevice(void)
{
GDHandle deviceHdl;
deviceHdl = LMGetMainDevice();
gPixelDepth = (*(*deviceHdl)->gdPMap)->pixelSize;
if(BitTst(&(*deviceHdl)->gdFlags,gdDevType))
gIsColourDevice = true;
}
//
// BevelImagePictIcon.c
//
// ............................................................................. includes
#include "Controls3.h"
// ..................................................................... global variables
extern Str255 gCurrentString;
extern Boolean gInBackground;
extern SInt16 gPixelDepth;
extern Boolean gIsColourDevice;
// doBevelImagePictIcon
void doBevelImagePictIcon(void)
{
WindowPtr windowPtr;
BevelDocStrucHandle bevelDocStrucHdl;
// ............................................ initial advisory text for window header
doCopyPString("\pBalloon help is available",gCurrentString);
// ... open a window, set font size, set Appearance-compliant colour/pattern for window
if(!(windowPtr = GetNewCWindow(rBevelImageWindow,NULL,(WindowPtr)-1)))
ExitToShell();
SetPort(windowPtr);
TextSize(10);
SetThemeWindowBackground(windowPtr,kThemeBrushDialogBackgroundActive,true);
// ...... get block for document structure, assign handle to window record refCon field
if(!(bevelDocStrucHdl = (BevelDocStrucHandle) NewHandle(sizeof(BevelDocStruc))))
ExitToShell();
SetWRefCon(windowPtr,(SInt32) bevelDocStrucHdl);
// .................................. get controls, adjust scroll bars, and show window
doGetControls(windowPtr);
ShowWindow(windowPtr);
// ......... get pixel depth and whether colour device for certain Appearance functions
doGetDepthAndDevice();
}
// doGetControls
void doGetControls(WindowPtr windowPtr)
{
ControlHandle controlHdl;
BevelDocStrucHandle bevelDocStrucHdl;
ControlButtonTextPlacement textPlacement = kControlBevelButtonPlaceAboveGraphic;
Boolean centrePopupGlyph = true;
ControlFontStyleRec controlFontStyleStruc;
// .......... create root control for window, get handle to window's document structure
CreateRootControl(windowPtr,&controlHdl);
bevelDocStrucHdl = (BevelDocStrucHandle) (GetWRefCon(windowPtr));
// ................................................................... get the controls
if(!((*bevelDocStrucHdl)->bevelButton1Hdl = GetNewControl(cBevelButton1,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton2Hdl = GetNewControl(cBevelButton2,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton3Hdl = GetNewControl(cBevelButton3,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton4Hdl = GetNewControl(cBevelButton4,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton5Hdl = GetNewControl(cBevelButton5,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton6Hdl = GetNewControl(cBevelButton6,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton7Hdl = GetNewControl(cBevelButton7,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton8Hdl = GetNewControl(cBevelButton8,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton9Hdl = GetNewControl(cBevelButton9,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton10Hdl = GetNewControl(cBevelButton10,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton11Hdl = GetNewControl(cBevelButton11,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton12Hdl = GetNewControl(cBevelButton12,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton13Hdl = GetNewControl(cBevelButton13,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton14Hdl = GetNewControl(cBevelButton14,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton15Hdl = GetNewControl(cBevelButton15,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton16Hdl = GetNewControl(cBevelButton16,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton17Hdl = GetNewControl(cBevelButton17,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton18Hdl = GetNewControl(cBevelButton18,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton19Hdl = GetNewControl(cBevelButton19,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton20Hdl = GetNewControl(cBevelButton20,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->bevelButton21Hdl = GetNewControl(cBevelButton21,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->imageWell1Hdl = GetNewControl(cImageWell1,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->imageWell2Hdl = GetNewControl(cImageWell2,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->picture1Hdl = GetNewControl(cPicture1,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->picture2Hdl = GetNewControl(cPicture2,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->colourIcon1Hdl = GetNewControl(cColourIcon1,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->colourIcon2Hdl = GetNewControl(cColourIcon2,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->iconSuite1Hdl= GetNewControl(cIconSuite1,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->iconSuite2Hdl= GetNewControl(cIconSuite2,windowPtr)))
ExitToShell();
if(!((*bevelDocStrucHdl)->windowHeaderHdl = GetNewControl(cWindowHeader,windowPtr)))
ExitToShell();
// ................................... set text placement for 2nd and 21st bevel button
SetControlData((*bevelDocStrucHdl)->bevelButton2Hdl,kControlNoPart,
kControlBevelButtonTextPlaceTag,sizeof(textPlacement),
(Ptr) &textPlacement);
SetControlData((*bevelDocStrucHdl)->bevelButton21Hdl,kControlNoPart,
kControlBevelButtonTextPlaceTag,sizeof(textPlacement),
(Ptr) &textPlacement);
// ................................... set position of pop-up arrow in 6th bevel button
SetControlData((*bevelDocStrucHdl)->bevelButton6Hdl,kControlNoPart,
kControlBevelButtonCenterPopupGlyphTag,sizeof(centrePopupGlyph),
(Ptr) ¢rePopupGlyph);
// ........................... set font for 20th bevel button to small bold system font
controlFontStyleStruc.flags = kControlUseFontMask;
controlFontStyleStruc.font = kControlFontSmallBoldSystemFont;
SetControlFontStyle((*bevelDocStrucHdl)->bevelButton20Hdl,&controlFontStyleStruc);
// ............................................ set 3rd bevel button to the mixed state
SetControlValue((*bevelDocStrucHdl)->bevelButton3Hdl,2);
}
// doBevelImagePictIconContent
void doBevelImagePictIconContent(EventRecord *eventStrucPtr,WindowPtr windowPtr)
{
BevelDocStrucHandle bevelDocStrucHdl;
ControlHandle controlHdl;
SInt16 partCode, menuItem;
bevelDocStrucHdl = (BevelDocStrucHandle) (GetWRefCon(windowPtr));
SetPort(windowPtr);
GlobalToLocal(&eventStrucPtr->where);
partCode = FindControl(eventStrucPtr->where,windowPtr,&controlHdl);
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,1234);
if(partCode)
{
partCode = TrackControl(controlHdl,eventStrucPtr->where,NULL);
if(controlHdl == (*bevelDocStrucHdl)->bevelButton1Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton2Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton3Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton4Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton9Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton13Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton14Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton15Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton16Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton17Hdl)
{
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton5Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton6Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton7Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton8Hdl)
{
if(partCode == kControlMenuPart)
{
GetControlData(controlHdl,kControlMenuPart,kControlBevelButtonMenuValueTag,
sizeof(menuItem),(Ptr) &menuItem,NULL);
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,menuItem);
}
else
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton10Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton11Hdl ||
controlHdl == (*bevelDocStrucHdl)->bevelButton12Hdl)
{
if(partCode != kControlNoPart)
{
SetControlValue((*bevelDocStrucHdl)->bevelButton10Hdl,0);
SetControlValue((*bevelDocStrucHdl)->bevelButton11Hdl,0);
SetControlValue((*bevelDocStrucHdl)->bevelButton12Hdl,0);
SetControlValue(controlHdl,1);
}
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton18Hdl)
{
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
doGraphicAlignment(windowPtr,controlHdl,(*bevelDocStrucHdl)->windowHeaderHdl);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton19Hdl)
{
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
doTextAlignment(windowPtr,controlHdl,(*bevelDocStrucHdl)->windowHeaderHdl);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton20Hdl)
{
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
doTextOffset(windowPtr,controlHdl,(*bevelDocStrucHdl)->windowHeaderHdl);
}
else if(controlHdl == (*bevelDocStrucHdl)->bevelButton21Hdl)
{
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
doTextPlacement(windowPtr,controlHdl,(*bevelDocStrucHdl)->windowHeaderHdl);
}
else
doDrawPartCode(windowPtr,(*bevelDocStrucHdl)->windowHeaderHdl,partCode,4321);
}
}
// doDrawPartCode
void doDrawPartCode(WindowPtr windowPtr,ControlHandle windowHeaderHdl,SInt16 partCode,
SInt16 menuItem)
{
SInt16 stringIndex;
Str255 theString;
if(partCode == kControlNoPart)
stringIndex = 1;
else if(partCode == kControlMenuPart)
stringIndex = 2;
else if(partCode == kControlTrianglePart)
stringIndex = 3;
else if(partCode == kControlEditTextPart)
stringIndex = 4;
else if(partCode == kControlPicturePart)
stringIndex = 5;
else if(partCode == kControlIconPart)
stringIndex = 6;
else if(partCode == kControlClockPart)
stringIndex = 7;
else if(partCode == kControlListBoxPart)
stringIndex = 8;
else if(partCode == kControlListBoxDoubleClickPart)
stringIndex = 9;
else if(partCode == kControlImageWellPart)
stringIndex = 10;
else if(partCode == kControlRadioGroupPart)
stringIndex = 11;
else if(partCode == kControlButtonPart)
stringIndex = 12;
else if(partCode == kControlIndicatorPart)
stringIndex = 13;
if(menuItem > 0 && menuItem < 1234)
{
doCopyPString("\pTrackControl returned ",gCurrentString);
GetIndString(theString,rPartCodeStrings,stringIndex);
doConcatPStrings(gCurrentString,theString);
doConcatPStrings(gCurrentString,"\p GetControlData returned menu item ");
NumToString((SInt32) menuItem,theString);
doConcatPStrings(gCurrentString,theString);
}
else if(menuItem == 1234 || menuItem == 4321)
{
if(menuItem == 1234)
doCopyPString("\pMouse-down in ",gCurrentString);
else if(menuItem == 4321)
doCopyPString("\pTrackControl returned ",gCurrentString);
GetIndString(theString,rPartCodeStrings,stringIndex);
doConcatPStrings(gCurrentString,theString);
}
Draw1Control(windowHeaderHdl);
doDrawMessage(windowPtr,!gInBackground);
}
// doGraphicAlignment
void doGraphicAlignment(WindowPtr windowPtr,ControlHandle controlHdl,
ControlHandle windowHeaderHdl)
{
SInt16 a;
UInt32 finalTicks;
ControlButtonGraphicAlignment alignmentConstant = 0;
SetCursor(*(GetCursor(watchCursor)));
for(a=1;a<10;a++)
{
Delay(60,&finalTicks);
alignmentConstant++;
if(alignmentConstant == 9)
alignmentConstant = 0;
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonGraphicAlignTag,
sizeof(alignmentConstant),(Ptr) &alignmentConstant);
Draw1Control(controlHdl);
Draw1Control(windowHeaderHdl);
GetIndString(gCurrentString,rGraphicAlignStrings,a);
doDrawMessage(windowPtr,!gInBackground);
}
SetCursor(&qd.arrow);
}
// doTextAlignment
void doTextAlignment(WindowPtr windowPtr,ControlHandle controlHdl,
ControlHandle windowHeaderHdl)
{
SInt16 a;
UInt32 finalTicks;
ControlButtonTextAlignment alignmentConstant = -3;
SetCursor(*(GetCursor(watchCursor)));
for(a=1;a<4;a++)
{
Delay(60,&finalTicks);
alignmentConstant++;
if(alignmentConstant == 0)
alignmentConstant++;
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextAlignTag,
sizeof(alignmentConstant),(Ptr) &alignmentConstant);
Draw1Control(controlHdl);
Draw1Control(windowHeaderHdl);
GetIndString(gCurrentString,rTextAlignStrings,a);
doDrawMessage(windowPtr,!gInBackground);
}
SetCursor(&qd.arrow);
}
// doTextOffset
void doTextOffset(WindowPtr windowPtr,ControlHandle controlHdl,
ControlHandle windowHeaderHdl)
{
ControlButtonTextAlignment alignmentConstant;
SInt16 offset;
UInt32 finalTicks;
SetCursor(*(GetCursor(watchCursor)));
Draw1Control(windowHeaderHdl);
doCopyPString("\pOffset from left",gCurrentString);
doDrawMessage(windowPtr,!gInBackground);
alignmentConstant = kControlBevelButtonAlignTextFlushLeft;
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextAlignTag,
sizeof(alignmentConstant),(Ptr) &alignmentConstant);
Draw1Control(controlHdl);
for(offset=1;offset<28;offset++)
{
Delay(15,&finalTicks);
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextOffsetTag,
sizeof(offset),(Ptr) &offset);
Draw1Control(controlHdl);
}
Delay(60,&finalTicks);
Draw1Control(windowHeaderHdl);
doCopyPString("\pOffset from right",gCurrentString);
doDrawMessage(windowPtr,!gInBackground);
alignmentConstant = kControlBevelButtonAlignTextFlushRight;
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextAlignTag,
sizeof(alignmentConstant),(Ptr) &alignmentConstant);
for(offset=0;offset<14;offset++)
{
Delay(15,&finalTicks);
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextOffsetTag,
sizeof(offset),(Ptr) &offset);
Draw1Control(controlHdl);
}
SetCursor(&qd.arrow);
}
// doTextPlacement
void doTextPlacement(WindowPtr windowPtr,ControlHandle controlHdl,
ControlHandle windowHeaderHdl)
{
ControlButtonTextPlacement placementConstant;
UInt32 finalTicks;
SetCursor(*(GetCursor(watchCursor)));
for(placementConstant = 1;placementConstant < 5;placementConstant++)
{
Delay(60,&finalTicks);
SetControlData(controlHdl,kControlNoPart,kControlBevelButtonTextPlaceTag,
sizeof(placementConstant),(Ptr) &placementConstant);
Draw1Control(controlHdl);
Draw1Control(windowHeaderHdl);
GetIndString(gCurrentString,rTextPlacementStrings,placementConstant);
doDrawMessage(windowPtr,!gInBackground);
}
SetCursor(&qd.arrow);
}
// doDrawMessage
void doDrawMessage(WindowPtr windowPtr,Boolean inState)
{
SInt16 windowWidth, stringWidth;
if(inState == kThemeStateActive)
SetThemeTextColor(kThemeTextColorWindowHeaderActive,gPixelDepth,gIsColourDevice);
else
SetThemeTextColor(kThemeTextColorWindowHeaderInactive,gPixelDepth,gIsColourDevice);
windowWidth = (windowPtr)->portRect.right - (windowPtr)->portRect.left;
stringWidth = StringWidth(gCurrentString);
MoveTo((windowWidth / 2) - (stringWidth / 2), 17);
DrawString(gCurrentString);
}
// doDrawLegends
void doDrawLegends(Boolean inState)
{
if(inState == kThemeStateActive)
SetThemeTextColor(kThemeTextColorWindowHeaderActive,gPixelDepth,gIsColourDevice);
else
SetThemeTextColor(kThemeTextColorWindowHeaderInactive,gPixelDepth,gIsColourDevice);
MoveTo(30,63);
DrawString("\pBevel sizes and bevel button content");
MoveTo(313,63);
DrawString("\pMenu position and behaviour");
MoveTo(30,154);
DrawString("\pBevel button behaviour");
MoveTo(313,154);
DrawString("\pGraphic/text alignment and offset");
MoveTo(490,154);
DrawString("\pText Placement");
MoveTo(30,245);
DrawString("\pImage wells");
MoveTo(168,245);
DrawString("\pPicture controls");
MoveTo(313,245);
DrawString("\pIcon controls (cicn)");
MoveTo(451,245);
DrawString("\pIcon controls (icon suite)");
}
//
// TabEditClock.c
//
// ............................................................................. includes
#include "Controls3.h"
// doTabEditClock
void doTabEditClock(void)
{
DialogPtr dialogPtr;
ControlHandle controlHdl;
Str255 initialName = "\pYour name here";
ControlEditTextSelectionRec selectionRec;
ControlKeyFilterUPP numericFilterUPP;
ModalFilterUPP eventFilterUPP;
ControlEditTextValidationUPP editTextValidatorUPP;
SInt16 tabHit, itemHit;
if(FrontWindow())
doActivateWindow(FrontWindow(),false);
if(!(dialogPtr = GetNewDialog(rTabEditClockDialog,NULL,(WindowPtr) -1)))
ExitToShell();
SetWTitle(dialogPtr,"\pTabs, Edit Text Fields, and Clocks");
// ............................................. set default button and cursor tracking
SetDialogDefaultItem(dialogPtr,kStdOkItemIndex);
SetDialogTracksCursor(dialogPtr,true);
// ................................................ hide user pane with embedded clocks
GetDialogItemAsControl(dialogPtr,iClocksUserPane,&controlHdl);
HideControl(controlHdl);
// .......... assign some text to the first edit text control and select the whole text
GetDialogItemAsControl(dialogPtr,iEditText1,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlEditTextTextTag,initialName[0],
(Ptr) &initialName[1]);
selectionRec.selStart = 0;
selectionRec.selEnd = 32767;
SetControlData(controlHdl,kControlNoPart,kControlEditTextSelectionTag,
sizeof(selectionRec),(Ptr) &selectionRec);
// ... create routine descriptors for event filter, key filter, and edit text validator
eventFilterUPP = NewModalFilterProc(eventFilter);
numericFilterUPP = NewControlKeyFilterProc(numericFilter);
editTextValidatorUPP = NewControlEditTextValidationProc(editTextValidator);
// ............. attach an edit text validation function to the first edit text control
GetDialogItemAsControl(dialogPtr,iEditText1,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlEditTextValidationProcTag,
sizeof(editTextValidatorUPP),(Ptr) &editTextValidatorUPP);
// ......................... attach a key filter function to the second edit text control
GetDialogItemAsControl(dialogPtr,iEditText2,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlEditTextKeyFilterTag,
sizeof(numericFilterUPP),(Ptr) &numericFilterUPP);
// ............................................ show dialog and enter modal dialog loop
ShowWindow(dialogPtr);
do
{
ModalDialog(eventFilterUPP,&itemHit);
if(itemHit == iTabs)
{
GetDialogItemAsControl(dialogPtr,iTabs,&controlHdl);
tabHit = GetControlValue(controlHdl);
if(tabHit == tabEditText)
{
SetWTitle(dialogPtr,"\pTabs, Edit Text Fields, and Clocks");
GetDialogItemAsControl(dialogPtr,iClocksUserPane,&controlHdl);
HideControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iEditTextUserPane,&controlHdl);
ActivateControl(controlHdl);
ShowControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iEditText1,&controlHdl);
SetKeyboardFocus(dialogPtr,controlHdl,kControlFocusNextPart);
}
else if(tabHit == tabClocks)
{
SetWTitle(dialogPtr,"\pTabs, Clocks, and Edit Text Fields");
GetDialogItemAsControl(dialogPtr,iEditTextUserPane,&controlHdl);
DeactivateControl(controlHdl);
HideControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iClocksUserPane,&controlHdl);
ShowControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iClocks1,&controlHdl);
SetKeyboardFocus(dialogPtr,controlHdl,kControlFocusNextPart);
}
}
else if(itemHit == iExtractEditText)
{
GetDialogItemAsControl(dialogPtr,iImageWellEditText,&controlHdl);
Draw1Control(controlHdl);
doExtractEditText(dialogPtr);
}
else if(itemHit == iExtractClocks)
{
GetDialogItemAsControl(dialogPtr,iImageWellClocks,&controlHdl);
Draw1Control(controlHdl);
doExtractDateTime(dialogPtr);
}
} while(itemHit != kStdOkItemIndex);
DisposeDialog(dialogPtr);
DisposeRoutineDescriptor(eventFilterUPP);
DisposeRoutineDescriptor(numericFilterUPP);
DisposeRoutineDescriptor(editTextValidatorUPP);
}
// doExtractEditText
void doExtractEditText(DialogPtr dialogPtr)
{
GrafPtr oldPort;
RGBColor saveBackColour, whiteColour = { 0xFFFF, 0xFFFF, 0xFFFF };
SInt16 iType;
Handle theHandle;
Rect theRect;
Str255 theString;
ControlHandle controlHdl;
Size actualSize;
GetPort(&oldPort);
SetPort(dialogPtr);
GetBackColor(&saveBackColour);
RGBBackColor(&whiteColour);
GetDialogItem(dialogPtr,iEditText1,&iType,&theHandle,&theRect);
GetDialogItemText(theHandle,theString);
MoveTo(100,182);
DrawString(theString);
GetDialogItem(dialogPtr,iEditText2,&iType,&theHandle,&theRect);
GetDialogItemText(theHandle,theString);
MoveTo(100,196);
DrawString(theString);
GetDialogItemAsControl(dialogPtr,iEditText3,&controlHdl);
GetControlDataSize(controlHdl,kControlEditTextPart,kControlEditTextTextTag,&actualSize);
GetControlData(controlHdl,kControlNoPart,kControlEditTextPasswordTag,actualSize,
(Ptr) &theString[1],NULL);
theString[0] = actualSize;
MoveTo(100,208);
DrawString(theString);
RGBBackColor(&saveBackColour);
SetPort(oldPort);
}
// doExtractDateTime
void doExtractDateTime(DialogPtr dialogPtr)
{
GrafPtr oldPort;
RGBColor saveBackColour, whiteColour = { 0xFFFF, 0xFFFF, 0xFFFF };
ControlHandle controlHdl;
LongDateRec longDateTimeStruc;
SInt16 second, minute, hour, day, month, year;
Str255 theString, tempString;
GetPort(&oldPort);
SetPort(dialogPtr);
GetBackColor(&saveBackColour);
RGBBackColor(&whiteColour);
GetDialogItemAsControl(dialogPtr,iClocks1,&controlHdl);
GetControlData(controlHdl,kControlNoPart,kControlClockLongDateTag,
sizeof(longDateTimeStruc),(Ptr) &longDateTimeStruc,NULL);
hour = longDateTimeStruc.ld.hour;
minute = longDateTimeStruc.ld.minute;
second = longDateTimeStruc.ld.second;
doCopyPString("\pHour ",theString);
NumToString((SInt32) hour,tempString);
doConcatPStrings(theString,tempString);
doConcatPStrings(theString,"\p, Minute ");
NumToString((SInt32) minute,tempString);
doConcatPStrings(theString,tempString);
doConcatPStrings(theString,"\p, Second ");
NumToString((SInt32) second,tempString);
doConcatPStrings(theString,tempString);
MoveTo(100,182);
DrawString(theString);
GetDialogItemAsControl(dialogPtr,iClocks2,&controlHdl);
GetControlData(controlHdl,kControlNoPart,kControlClockLongDateTag,
sizeof(longDateTimeStruc),(Ptr) &longDateTimeStruc,NULL);
day = longDateTimeStruc.ld.day;
month = longDateTimeStruc.ld.month;
year = longDateTimeStruc.ld.year;
doCopyPString("\pDay ",theString);
NumToString((SInt32) day,tempString);
doConcatPStrings(theString,tempString);
doConcatPStrings(theString,"\p, Month ");
NumToString((SInt32) month,tempString);
doConcatPStrings(theString,tempString);
doConcatPStrings(theString,"\p, Year ");
NumToString((SInt32) year,tempString);
doConcatPStrings(theString,tempString);
MoveTo(100,196);
DrawString(theString);
GetDialogItemAsControl(dialogPtr,iClocks3,&controlHdl);
GetControlData(controlHdl,kControlNoPart,kControlClockLongDateTag,
sizeof(longDateTimeStruc),(Ptr) &longDateTimeStruc,NULL);
month = longDateTimeStruc.ld.month;
year = longDateTimeStruc.ld.year;
doCopyPString("\pMonth ",theString);
NumToString((SInt32) month,tempString);
doConcatPStrings(theString,tempString);
doConcatPStrings(theString,"\p, Year ");
NumToString((SInt32) year,tempString);
doConcatPStrings(theString,tempString);
MoveTo(100,210);
DrawString(theString);
RGBBackColor(&saveBackColour);
SetPort(oldPort);
}
// numericFilter
pascal ControlKeyFilterResult numericFilter(ControlHandle controlHdl,SInt16* keyCode,
SInt16 *charCode,SInt16 *modifiers)
{
if(((char) *charCode >= '0') && ((char) *charCode <= '9'))
return kControlKeyFilterPassKey;
switch(*charCode)
{
case '-':
case kLeftArrow:
case kRightArrow:
case kUpArrow:
case kDownArrow:
case kBackspace:
return kControlKeyFilterPassKey;
break;
default:
SysBeep(10);
return kControlKeyFilterBlockKey;
break;
}
}
// editTextValidator
pascal void editTextValidator(ControlHandle controlHdl)
{
Str255 oldText, newText;
Size actualSize;
UInt8 a, count = 0;
GetControlData(controlHdl,kControlNoPart,kControlEditTextTextTag,sizeof(oldText) -1,
(Ptr) &oldText[1],&actualSize);
if(actualSize <= 255)
oldText[0] = actualSize;
else
oldText[0] = 255;
for(a=1;a<=oldText[0];a++)
{
if(((oldText[a] >= 'A') && (oldText[a] <= 'Z') ||
(oldText[a] >= 'a') && (oldText[a] <= 'z')) ||
(oldText[a] == ' ') || (oldText[a] == '.'))
{
newText[count + 1] = oldText[a];
count++;
}
}
newText[0] = count;
SetControlData(controlHdl,kControlNoPart,kControlEditTextTextTag,newText[0],
(Ptr) &newText[1]);
Draw1Control(controlHdl);
}
//
// GroupArrowsProgress.c
//
// ............................................................................. includes
#include "Controls3.h"
// ..................................................................... global variables
ControlHandle gCacheSizeControlHdl;
ControlHandle gLittleArrowsControlHdl;
ControlActionUPP arrowsActionFunctionUPP;
extern Boolean gGroupArrowsProgressActive;
// doTabEditClock
void doGroupArrowsProgress(void)
{
DialogPtr dialogPtr;
ControlHandle controlHdl;
ModalFilterUPP eventFilterUPP;
SInt16 controlValue, itemHit;
Str255 theString;
if(FrontWindow())
doActivateWindow(FrontWindow(),false);
if(!(dialogPtr = GetNewDialog(rGroupArrowsProgDialog,NULL,(WindowPtr) -1)))
ExitToShell();
// ................................................................. set default button
SetDialogDefaultItem(dialogPtr,kStdOkItemIndex);
// ...... create routine descriptors for event filter and little arrows action function
eventFilterUPP = NewModalFilterProc((ProcPtr) eventFilter);
arrowsActionFunctionUPP = NewControlActionProc((ProcPtr) arrowsActionFunction);
// ........................................... set initial value for checkbox group box
GetDialogItemAsControl(dialogPtr,iCheckboxGroup,&controlHdl);
SetControlValue(controlHdl,1);
// .................................. get and set initial cache value for little arrows
GetDialogItemAsControl(dialogPtr,iLittleArrows,&gLittleArrowsControlHdl);
NumToString((SInt32) GetControlValue(gLittleArrowsControlHdl),theString);
doConcatPStrings(theString,"\pK");
GetDialogItemAsControl(dialogPtr,iStaticTextCache,&gCacheSizeControlHdl);
SetControlData(gCacheSizeControlHdl,kControlNoPart,kControlStaticTextTextTag,theString[0],
(Ptr) &theString[1]);
// .......................................... hide second user pane in pop-up group box
GetDialogItemAsControl(dialogPtr,iUserPaneScoreAverage,&controlHdl);
HideControl(controlHdl);
// ............................................. show dialog and enter ModalDialog loop
ShowWindow(dialogPtr);
do
{
ModalDialog(eventFilterUPP,&itemHit);
if(itemHit == iCheckboxGroup)
{
doCheckBoxGroupBox(dialogPtr);
}
else if(itemHit == iPopupGroup)
{
doPopupGroupBox(dialogPtr);
}
else if(itemHit == iCheckboxShowInitials)
{
GetDialogItemAsControl(dialogPtr,iCheckboxShowInitials,&controlHdl);
controlValue = (!(GetControlValue(controlHdl)));
SetControlValue(controlHdl,controlValue);
}
else if(itemHit == iCheckboxShowAverages)
{
GetDialogItemAsControl(dialogPtr,iCheckboxShowAverages,&controlHdl);
controlValue = (!(GetControlValue(controlHdl)));
SetControlValue(controlHdl,controlValue);
}
else if(itemHit == iDisclosureTriangle)
{
doAsynchronousAndProgress(dialogPtr);
}
else if(itemHit == iPushButtonExtract)
{
GetDialogItemAsControl(dialogPtr,iImageWell,&controlHdl);
Draw1Control(controlHdl);
doExtractCurrentStatus(dialogPtr);
}
} while(itemHit != kStdOkItemIndex);
// ........................................................................... clean up
DisposeDialog(dialogPtr);
DisposeRoutineDescriptor(eventFilterUPP);
DisposeRoutineDescriptor(arrowsActionFunctionUPP);
gGroupArrowsProgressActive = false;
}
// doCheckBoxGroupBox
void doCheckBoxGroupBox(DialogPtr dialogPtr)
{
ControlHandle controlHdl;
SInt16 controlValue;
GetDialogItemAsControl(dialogPtr,iCheckboxGroup,&controlHdl);
controlValue = (!(GetControlValue(controlHdl)));
SetControlValue(controlHdl,controlValue);
if(controlValue == 0)
{
GetDialogItemAsControl(dialogPtr,iRadioGroupColour,&controlHdl);
DeactivateControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iStaticTextColourDepth,&controlHdl);
DeactivateControl(controlHdl);
}
else if(controlValue == 1)
{
GetDialogItemAsControl(dialogPtr,iRadioGroupColour,&controlHdl);
ActivateControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iStaticTextColourDepth,&controlHdl);
ActivateControl(controlHdl);
}
}
// doPopupGroupBox
void doPopupGroupBox(DialogPtr dialogPtr)
{
ControlHandle controlHdl;
SInt16 controlValue;
GetDialogItemAsControl(dialogPtr,iPopupGroup,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
{
GetDialogItemAsControl(dialogPtr,iUserPaneScoreAverage,&controlHdl);
HideControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iUserPaneNamesInitials,&controlHdl);
ShowControl(controlHdl);
}
else if(controlValue == 2)
{
GetDialogItemAsControl(dialogPtr,iUserPaneNamesInitials,&controlHdl);
HideControl(controlHdl);
GetDialogItemAsControl(dialogPtr,iUserPaneScoreAverage,&controlHdl);
ShowControl(controlHdl);
}
}
// doAsynchronousAndProgress
void doAsynchronousAndProgress(DialogPtr dialogPtr)
{
ControlHandle controlHdl;
SInt16 controlValue;
Handle ditlHdl;
Boolean indeterminateFlag = 1;
Str255 expandString = "\pHide Progress Indicator and Asynchronous Arrows";
Str255 collapseString = "\pShow Progress Indicator and Asynchronous Arrows";
GetDialogItemAsControl(dialogPtr,iDisclosureTriangle,&controlHdl);
controlValue = (!(GetControlValue(controlHdl)));
SetControlValue(controlHdl,controlValue);
if(controlValue == 1)
{
ditlHdl = GetResource('DITL',130);
AppendDITL(dialogPtr,ditlHdl,appendDITLBottom);
ReleaseResource(ditlHdl);
GetDialogItemAsControl(dialogPtr,iProgressBar,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlProgressBarIndeterminateTag,
sizeof(indeterminateFlag),(Ptr) &indeterminateFlag);
GetDialogItemAsControl(dialogPtr,kStdOkItemIndex,&controlHdl);
MoveControl(controlHdl,267,336);
GetDialogItemAsControl(dialogPtr,iStaticTextDisclosure,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlStaticTextTextTag,
expandString[0],(Ptr) &expandString[1]);
Draw1Control(controlHdl);
}
else if(controlValue == 0)
{
GetDialogItemAsControl(dialogPtr,kStdOkItemIndex,&controlHdl);
MoveControl(controlHdl,267,259);
SizeWindow(dialogPtr,348,302,false);
GetDialogItemAsControl(dialogPtr,iStaticTextDisclosure,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlStaticTextTextTag,
collapseString[0],(Ptr) &collapseString[1]);
Draw1Control(controlHdl);
}
}
// doExtractCurrentStatus
void doExtractCurrentStatus(DialogPtr dialogPtr)
{
GrafPtr oldPort;
RGBColor saveBackColour, whiteColour = { 0xFFFF, 0xFFFF, 0xFFFF };
ControlHandle controlHdl;
SInt16 controlValue;
Str255 theString;
GetPort(&oldPort);
SetPort(dialogPtr);
GetBackColor(&saveBackColour);
RGBBackColor(&whiteColour);
GetDialogItemAsControl(dialogPtr,iCheckboxGroup,&controlHdl);
controlValue = GetControlValue(controlHdl);
MoveTo(98,191);
if(controlValue)
{
doCopyPString("\pUse colour,",theString);
GetDialogItemAsControl(dialogPtr,iRadioGroupColour,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
doConcatPStrings(theString,"\p 8 bit.");
else if(controlValue == 2)
doConcatPStrings(theString,"\p 16 bit.");
else if(controlValue == 3)
doConcatPStrings(theString,"\p 32 bit.");
}
else
doCopyPString("\pDont use colour.",theString);
DrawString(theString);
GetDialogItemAsControl(dialogPtr,iPopupGroup,&controlHdl);
controlValue = GetControlValue(controlHdl);
MoveTo(98,205);
if(controlValue == 1)
{
doCopyPString("\pPlayer, ",theString);
GetDialogItemAsControl(dialogPtr,iRadioGroupNames,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
doConcatPStrings(theString,"\pname first,");
else if(controlValue == 2)
doConcatPStrings(theString,"\pname last,");
GetDialogItemAsControl(dialogPtr,iCheckboxShowInitials,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
doConcatPStrings(theString,"\p show number.");
else if(controlValue == 0)
doConcatPStrings(theString,"\p no number.");
}
else if(controlValue == 2)
{
doCopyPString("\pScore, ",theString);
GetDialogItemAsControl(dialogPtr,iRadioGroupScores,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
doConcatPStrings(theString,"\pbatting, ");
else if(controlValue == 2)
doConcatPStrings(theString,"\pbowling, ");
GetDialogItemAsControl(dialogPtr,iCheckboxShowAverages,&controlHdl);
controlValue = GetControlValue(controlHdl);
if(controlValue == 1)
doConcatPStrings(theString,"\pshow average.");
else if(controlValue == 0)
doConcatPStrings(theString,"\pno average.");
}
DrawString(theString);
MoveTo(98,219);
DrawString("\pCache size: ");
GetDialogItemAsControl(dialogPtr,iLittleArrows,&controlHdl);
NumToString((SInt32) GetControlValue(controlHdl),theString);
DrawString(theString);
RGBBackColor(&saveBackColour);
SetPort(oldPort);
}
//
// Sliders.c
//
// ............................................................................. includes
#include "Controls3.h"
// ..................................................................... global variables
ControlActionUPP sliderActionFunction1UPP;
ControlActionUPP sliderActionFunction2UPP;
ControlUserPaneDrawUPP userPaneDrawFunctionUPP;
ControlUserPaneActivateUPP userPaneActivateFunctionUPP;
ControlHandle gSlider1Hdl;
ControlHandle gSlider2Hdl;
ControlHandle gSlider3Hdl;
ControlHandle gSlider4Hdl;
ControlHandle gSlider5Hdl;
ControlHandle gSlider6Hdl;
RGBColor gRedColour = { 0x0000, 0x0000, 0x0000 };
RGBColor gBlueColour = { 0x0000, 0x0000, 0x0000 };
Boolean gDrawActivated = true;
extern Boolean gSlidersActive;
// doSliderUserPane
void doSliderUserPane(void)
{
DialogPtr dialogPtr;
ModalFilterUPP eventFilterUPP;
ControlHandle controlHdl;
SInt16 itemHit;
if(FrontWindow())
doActivateWindow(FrontWindow(),false);
if(!(dialogPtr = GetNewDialog(rSlidersDialog,NULL,(WindowPtr) -1)))
ExitToShell();
// ................................................................. set default button
SetDialogDefaultItem(dialogPtr,kStdOkItemIndex);
// ................................ create routine descriptor for event filter function
eventFilterUPP = NewModalFilterProc(eventFilter);
// ............................. create routine descriptors for slider action functions
sliderActionFunction1UPP = NewControlActionProc((ProcPtr) sliderActionFunction1);
sliderActionFunction2UPP = NewControlActionProc((ProcPtr) sliderActionFunction2);
// ........ create routine descriptors for user pane functions, set user pane functions
userPaneDrawFunctionUPP = NewControlUserPaneDrawProc(userPaneDrawFunction);
GetDialogItemAsControl(dialogPtr,iUserPane1,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlUserPaneDrawProcTag,
sizeof(userPaneDrawFunctionUPP),(Ptr) &userPaneDrawFunctionUPP);
userPaneActivateFunctionUPP = NewControlUserPaneActivateProc(userPaneActivateFunction);
GetDialogItemAsControl(dialogPtr,iUserPane1,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlUserPaneActivateProcTag,
sizeof(userPaneActivateFunctionUPP),(Ptr) &userPaneActivateFunctionUPP);
// ...... get control handles of, and draw initial control values for, top four sliders
GetDialogItemAsControl(dialogPtr,iSlider1,&gSlider1Hdl);
doDrawSliderValues(dialogPtr,gSlider1Hdl);
GetDialogItemAsControl(dialogPtr,iSlider2,&gSlider2Hdl);
doDrawSliderValues(dialogPtr,gSlider2Hdl);
GetDialogItemAsControl(dialogPtr,iSlider3,&gSlider3Hdl);
doDrawSliderValues(dialogPtr,gSlider3Hdl);
GetDialogItemAsControl(dialogPtr,iSlider4,&gSlider4Hdl);
doDrawSliderValues(dialogPtr,gSlider4Hdl);
// .................. get control handles and values for bottom two sliders, set colour
GetDialogItemAsControl(dialogPtr,iSlider5,&gSlider5Hdl);
gRedColour.red = 2 * GetControlValue(gSlider5Hdl);
GetDialogItemAsControl(dialogPtr,iSlider6,&gSlider6Hdl);
gBlueColour.blue = 2 * GetControlValue(gSlider5Hdl);
// ............................................. show dialog and enter ModalDialog loop
ShowWindow(dialogPtr);
do
{
ModalDialog(eventFilterUPP,&itemHit);
} while(itemHit != kStdOkItemIndex);
// ........................................................................... clean up
DisposeDialog(dialogPtr);
DisposeRoutineDescriptor(eventFilterUPP);
DisposeRoutineDescriptor(sliderActionFunction1UPP);
DisposeRoutineDescriptor(sliderActionFunction2UPP);
DisposeRoutineDescriptor(userPaneDrawFunctionUPP);
DisposeRoutineDescriptor(userPaneActivateFunctionUPP);
gSlidersActive = false;
}
// ................................................................... doDrawSliderValues
void doDrawSliderValues(DialogPtr dialogPtr,ControlHandle controlHdl)
{
Str255 theString;
SInt16 staticTextItem;
NumToString((SInt32) GetControlValue(controlHdl),theString);
if(controlHdl == gSlider1Hdl)
staticTextItem = iSlider1StaticText;
else if(controlHdl == gSlider2Hdl)
staticTextItem = iSlider2StaticText;
else if(controlHdl == gSlider3Hdl)
staticTextItem = iSlider3StaticText;
else if(controlHdl == gSlider4Hdl)
staticTextItem = iSlider4StaticText;
GetDialogItemAsControl(dialogPtr,staticTextItem,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlStaticTextTextTag,theString[0],
(Ptr) &theString[1]);
Draw1Control(controlHdl);
}
// userPaneDrawFunction
pascal void userPaneDrawFunction(ControlHandle theControl,SInt16 thePart)
{
Rect theRect;
SetRect(&theRect,225,186,239,200);
DrawThemeGenericWell(&theRect,gDrawActivated,true);
if(gDrawActivated)
{
RGBForeColor(&gRedColour);
PaintRect(&theRect);
}
SetRect(&theRect,225,207,239,221);
DrawThemeGenericWell(&theRect,gDrawActivated,true);
if(gDrawActivated)
{
RGBForeColor(&gBlueColour);
PaintRect(&theRect);
}
}
// userPaneActivateFunction
pascal void userPaneActivateFunction(ControlHandle control,Boolean activating)
{
if(activating)
gDrawActivated = true;
else
gDrawActivated = false;
}
//
// TextBox.c.c
//
// ............................................................................. includes
#include "Controls3.h"
// ........................................................................... doAboutBox
void doAboutBox(void)
{
DialogPtr dialogPtr;
ModalFilterUPP eventFilterUPP;
SInt16 itemHit;
if(FrontWindow())
doActivateWindow(FrontWindow(),false);
if(!(dialogPtr = GetNewDialog(rAboutDialog,NULL,(WindowPtr) -1)))
ExitToShell();
SetWTitle(dialogPtr,"\pAbout Box (Text Boxes)");
// ................................................................. set default button
SetDialogDefaultItem(dialogPtr,kStdOkItemIndex);
// ......................................... create routine descriptor for event filter
eventFilterUPP = NewModalFilterProc(eventFilter);
// ............................................ show dialog and enter modal dialog loop
ShowWindow(dialogPtr);
do
{
ModalDialog(eventFilterUPP,&itemHit);
} while(itemHit != kStdOkItemIndex);
DisposeDialog(dialogPtr);
DisposeRoutineDescriptor(eventFilterUPP);
}
// /
// Callbacks.c
//
// ............................................................................. includes
#include "Controls3.h"
// ..................................................................... global variables
extern Boolean gGroupArrowsProgressActive;
extern Boolean gSlidersActive;
extern ControlActionUPP arrowsActionFunctionUPP;
extern ControlActionUPP sliderActionFunction1UPP;
extern ControlActionUPP sliderActionFunction2UPP;
extern ControlHandle gLittleArrowsControlHdl;
extern ControlHandle gCacheSizeControlHdl;
extern ControlHandle gSlider1Hdl;
extern ControlHandle gSlider2Hdl;
extern ControlHandle gSlider3Hdl;
extern ControlHandle gSlider4Hdl;
extern ControlHandle gSlider5Hdl;
extern ControlHandle gSlider6Hdl;
extern RGBColor gRedColour;
extern RGBColor gBlueColour;
// eventFilter
pascal Boolean eventFilter(DialogPtr dialogPtr,EventRecord *eventStrucPtr,
SInt16 *itemHit)
{
Boolean handledEvent;
GrafPtr oldPort;
Point mouseXY;
ControlHandle controlHdl;
handledEvent = false;
if((eventStrucPtr->what == updateEvt) &&
((WindowPtr) eventStrucPtr->message != dialogPtr))
{
doUpdate(eventStrucPtr);
}
else
{
GetPort(&oldPort);
SetPort(dialogPtr);
if(gGroupArrowsProgressActive)
{
if(eventStrucPtr->what == mouseDown)
{
mouseXY = eventStrucPtr->where;
GlobalToLocal(&mouseXY);
if(FindControl(mouseXY,dialogPtr,&controlHdl))
{
if(controlHdl == gLittleArrowsControlHdl)
{
TrackControl(controlHdl,mouseXY,arrowsActionFunctionUPP);
handledEvent = true;
}
}
}
}
else if(gSlidersActive)
{
if(eventStrucPtr->what == mouseDown)
{
mouseXY = eventStrucPtr->where;
GlobalToLocal(&mouseXY);
if(FindControl(mouseXY,dialogPtr,&controlHdl))
{
if(controlHdl == gSlider1Hdl || controlHdl == gSlider2Hdl)
{
TrackControl(controlHdl,mouseXY,NULL);
doDrawSliderValues(dialogPtr,controlHdl);
handledEvent = true;
}
else if(controlHdl == gSlider3Hdl || controlHdl == gSlider4Hdl)
{
TrackControl(controlHdl,mouseXY,sliderActionFunction1UPP);
handledEvent = true;
}
else if(controlHdl == gSlider5Hdl || controlHdl == gSlider6Hdl)
{
TrackControl(controlHdl,mouseXY,sliderActionFunction2UPP);
handledEvent = true;
}
}
}
}
else
{
handledEvent = StdFilterProc(dialogPtr,eventStrucPtr,itemHit);
}
SetPort(oldPort);
}
return(handledEvent);
}
// arrowsActionFunction
pascal void arrowsActionFunction(ControlHandle controlHdl,SInt16 partCode)
{
Str255 theString;
SInt32 controlValue;
if(partCode)
{
controlValue = GetControlValue(controlHdl);
switch(partCode)
{
case kControlUpButtonPart:
controlValue += 32;
if(controlValue > GetControlMaximum(controlHdl))
{
controlValue = GetControlMaximum(controlHdl);
return;
}
break;
case kControlDownButtonPart:
controlValue -= 32;
if(controlValue < GetControlMinimum(controlHdl))
{
controlValue = GetControlMinimum(controlHdl);
return;
}
break;
}
SetControlValue(controlHdl,controlValue);
NumToString((SInt32) controlValue,theString);
doConcatPStrings(theString,"\pK");
SetControlData(gCacheSizeControlHdl,kControlNoPart,kControlStaticTextTextTag,
theString[0],(Ptr) &theString[1]);
Draw1Control(gCacheSizeControlHdl);
}
}
// sliderActionFunction1
pascal void sliderActionFunction1(ControlHandle controlHdl,SInt16 partCode)
{
SInt16 staticTextItem;
Str255 theString;
DialogPtr dialogPtr;
NumToString((SInt32) GetControlValue(controlHdl),theString);
dialogPtr = (*controlHdl)->contrlOwner;
if(controlHdl == gSlider3Hdl)
staticTextItem = iSlider3StaticText;
else if(controlHdl == gSlider4Hdl)
staticTextItem = iSlider4StaticText;
GetDialogItemAsControl(dialogPtr,staticTextItem,&controlHdl);
SetControlData(controlHdl,kControlNoPart,kControlStaticTextTextTag,theString[0],
(Ptr) &theString[1]);
Draw1Control(controlHdl);
}
// sliderActionFunction2
pascal void sliderActionFunction2(ControlHandle controlHdl,SInt16 partCode)
{
SInt16 controlValue;
Rect theRect;
controlValue = GetControlValue(controlHdl);
if(controlHdl == gSlider5Hdl)
{
gRedColour.red = 2 * controlValue;
RGBForeColor(&gRedColour);
SetRect(&theRect,225,186,239,200);
}
else if(controlHdl == gSlider6Hdl)
{
gBlueColour.blue = 2 * controlValue;
RGBForeColor(&gBlueColour);
SetRect(&theRect,225,207,239,221);
}
PaintRect(&theRect);
}
//
Demonstration Program Comments
When this program is run, the user should:
* Choose the About Controls3... item from the Apple menu to view an About dialog
containing a standard Text Box control and an auto-scrolling Text Box control.
(Note: If Mac OS 8.5 is not present, the About Controls3... item will be disabled
and this action will not be possible.)
* Choose items from the Demonstration menu to view and operate the various controls.
* Choose Show Balloons from the Help menu and note the information (and, in some cases,
the instructions) in the help balloons as the cursor is moved over the various
controls in the window and dialog boxes.
* Click in the Finder and then back in the window/dialog box, noting control
activation/deactivation.
* In the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window:
* Click in the various controls, noting in the window header the control part code
returned by FindControl (or immediately by TrackControl in the case of the
non-tracking icon controls).
* Click in the various controls and then release the mouse button both within and
outside the control, noting the control part code returned by TrackControl.
* In the Tab, Edit Text, and Clock Controls dialog box:
* In the Edit Text Controls tab:
* Change the keyboard focus using the tab key and mouse clicks.
* Enter a name, age, and password, noting the effect of the key filter
function attached to the "Age" edit text control and the behaviour of the
"Password" edit text control.
* Paste some text containing characters other than alphabetic characters, the
space character, and the period character to the "Name" edit text control,
noting that the edit text validation function strips out the "illegal"
characters.
* Note the cursor shape change when the cursor is over the top two edit text
fields.
* Click the Extract push button to extract and display the contents of the
edit text controls.
* In the Clock Controls Tab:
* Change the keyboard focus using the tab key and mouse clicks.
* Change the clock setting by typing and by using the integral little
arrows.
* Click the Extract push button to extract and display the clock settings.
* In the Group Boxes, Arrows, and Progress Bar dialog box:
* Change the group box settings, the settings of the controls within the group
boxes, and the (simulated) cache size setting controlled by the little arrows,
and then click the Extract button to extract and display the settings of the
various controls.
* Click the disclosure triangle to show and hide the asynchronous arrows and
indeterminate progress bar.
* In the Sliders and User Pane Functions dialog:
* Operate the sliders and note the difference in the appearance of the dragged
indicator in the live scrolling and non-live scrolling variants of the sliders.
* Note the appearance, in the activated and deactivated modes, of the two custom
"controls" to the right of the two horizontal sliders. Also note that these
controls are re-drawn, in the appropriate mode, when an overlaying window or
help balloon is removed.
Control3.h
#define
After the usual constants relating to the menu bar resource, menu resources and IDs,
and menu items are established, constants are established for the resource IDs and dialog
item numbers associated with the various demonstrations.
#typedef
A variable of type BevelDocStruc will be used to hold handles to the various controls
created in the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window.
Control3.c
Controls3.c is simply the basic "engine" which supports the demonstration. There is
nothing in this file which has not featured in previous demonstration programs.
Global Variables
gBevelAndImageActive will be set to true while the Bevel Buttons, Image Wells, Picture
Controls, and Icon Controls window is open. gGroupArrowsProgressActive will be set to
true while the Group Boxes, Arrows, and Progress Bar dialog box is open. gSlidersActive
will be set to true while the Sliders and User Pane Functions dialog is open.
main
The Gestalt call determines whether Mac OS 8.5 or later is present. If so, the
About Controls 3... item in the Apple menu is disabled. (The dialog box opened when
this item is chosen contains Text Box controls, the CDEFs for which are only included
with Mac OS 8.5 and later.)
doMouseDown
In the inContent case, if a mouse-down occurs in the Bevel Buttons, Image Wells, Picture
Controls, and Icon Controls window when it is the front window, the function
doBevelImagePictIconContent is called.
In the inGoAway case, the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls
window is disposed of and the global variable gBevelAndImageActive is set to false.
doMenuChoice
In the mDemonstration case, the relevant application-defined function is called when the
user chooses items in the Demonstration menu. In three cases, the relevant global
variable is also set to true.
doUpdate
If the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window is open,
UpdateControls is called to redraw the controls in the appropriate mode. Also, two
application-defined functions are called to draw the current window header string and the
legends in the appropriate mode.
doActivateWindow
If the Bevel Buttons, Image Wells, Picture Controls, and Icon Controls window is open,
and if it receives an activate event, GetRootControl is called to get a handle to the
root control created for the window by the application (see below). The controls are
then activated or deactivated en masse, and the window header string and the legends are
re-drawn in the appropriate mode.
BevelImagePictIcon.c
BevelImagePictIcon.c contains most of the source code relating to the Bevel Buttons,
Image Wells, Picture Controls, and Icon Controls window.
doBevelImagePictIcon
doBevelImagePictIcon opens a window, creates a relocatable block for a structure of type
BevelDocStruc (to whose fields handles to the various controls will be assigned) and
assigns the handle to this block to the refCon field of the window structure.
First, some initial advisory text for display in the window header is assigned to a
global variable. The call to GetNewCWindow then creates the window. (Note that error
handling here and in other areas of the demonstration is somewhat rudimentary in that the
program simply terminates.) The window's graphics port is set as the current port for
drawing and the window's text size is set to 10pt.
The call to SetThemeWindowBackground sets an Appearance-compliant colour/pattern for the
window's content area. NewHandle creates the block for the variable of type
BevelDocStruc and SetWRefCon assigns the handle to the block to the window structure's
refCon field.
Before ShowWindow is called to make the window visible, the application-defined function
doGetControls is called to create the controls. The call to doGetDepthAndDevice assigns
appropriate values to two global variables required in later calls to the Appearance
Manager function SetThemeTextColor.
doGetControls
doGetControls creates the controls from the various 'CNTL' resources.
At the first line, the root control is created. The first control created must be always
be the root control (which is implemented as a user pane).
A handle to the structure in which the handles to the control structures will be stored
is then retrieved. The following calls to GetNewControl create a control structure for
each control, insert the structure into the control list for the specified window and
draw the control. At the same time, the handle to each control is assigned to the
appropriate field of the window's "document" structure.
At the next block, SetControlData is twice called with the
kControlBevelButtonTextPlaceTag control data tag constant. The bevel button text
placement constant passed in these calls causes the text in the specified bevel buttons
to be placed above the graphic.
At the next block, SetControlData is called with the
kControlBevelButtonCenterPopupGlyphTag control data tag constant to cause the pop-up
glyph in the specified bevel button to be centred.
At the next block, the font for the text in the specified bevel button is changed. The
flags and font fields of a control font style structure are assigned constants so that
the following call to SetControlFontStyle will set the font to the small emphasised
system font.
The final line sets the value of the specified bevel button to 2, causing it to appear in
the mixed state.
doBevelImagePictIconContent
Recall that, if a mouse-down occurs in the Bevel Buttons, Image Wells, Picture Controls,
and Icon Controls window when it is the front window, doBevelImagePictIconContent is
called to further handle the event.
At the first line a handle to the structure containing handles to all the controls is
obtained.
The call to GlobalToLocal changes the coordinates at which the mouse-down occurred to the
local coordinates required by the following call to FindControl. The constant
representing the part code returned by FindControl is then drawn in the window header.
If the part code returned by FindControl is not kControlNoPart (0), meaning that an
enabled control was under the mouse cursor at the time of the mouse-down, the if block
executes. TrackControl takes control while the mouse button remains down, returning a
part code when the button is released.
In the case of the first 10 specified controls (bevel buttons), the control part code
returned by TrackControl is simply drawn in the window header.
The next four controls are bevel button with menus. In these cases, if the part code
returned indicates that the mouse button was released while the cursor was within the
menu, GetControlData is called with the kControlBevelButtonMenuValueTag tag constant to
get the menu item number. The part code and menu item number are then drawn in the
window header. If the cursor was not in the menu when the mouse button was released, the
part code returned by TrackControl is drawn in the window header.
The 10th, 11th, and 12th bevel buttons have toggle behaviour. With some assistance from
the application, they behave like radio buttons. If the control in which the mouse-down
occurred was one of these bevel buttons, and if the cursor was still within the control
when the mouse button was released, SetControlValue is called to set the three controls
to the unchecked state, following which the selected control is set to the checked state.
Either way, the part code returned by TrackControl is drawn in the window header.
The 18th bevel button is used to demonstrate bevel button graphic alignments using a
single bevel button. A mouse-down within this button causes the application-defined
function doGraphicAlignment to be called.
The 19th bevel button is used to demonstrate bevel button text alignments using a single
bevel button. A mouse-down within this button causes the application-defined function
doTextAlignment to be called.
The 20th bevel button is used to demonstrate text offsetting using a single bevel button.
A mouse-down within this button causes the application-defined function doTextOffset to
be called.
The 21st bevel button is used to demonstrate bevel button text placement in relation to
the bevel button's graphic using a single bevel button. A mouse-down within this button
causes the application-defined function doTextPlacement to be called.
Finally, if the mouse-down was in an image well, picture control, or icon control, and
except for the non-tracking picture and icon control variants, the part code returned by
TrackControl is drawn in the window header.
doDrawPartCode
doDrawPartCode takes part codes and menu item numbers and assembles them into descriptive
strings for drawing in the window header. The constants used are stored in 'STR#'
resources, and are retrieved using GetIndString. In the final two lines, Draw1Control is
called to redraw the window header control (in effect erasing the current text drawn
within the window header area) and doDrawMessage is called to draw the assembled string.
doGraphicAlignment
doGraphicAlignment is called to demonstrate the effect of all bevel button graphic
alignment constants except kControlBevelButtonAlignSysDirection. Each time around the
for loop, the alignment constant is changed before SetControlData is called with the
kControlBevelButtonGraphicAlignTag tag constant to set the alignment, Draw1Control is
called to redraw the bevel button, and the alignment constant used during that pass is
drawn in the window header.
doTextAlignment
doTextAlignment is called to demonstrate the effect of all bevel button text alignment
constants except kControlBevelButtonAlignTextSysDirection. Each time around the for
loop, the alignment constant is changed before SetControlData is called with the
kControlBevelButtonTextAlignTag tag constant to set the alignment, Draw1Control is called
to redraw the bevel button, and the alignment constant used during that pass is drawn in
the window header.
doTextOffset
doTextOffset is called to demonstrate text offsetting from the left and the right within
a bevel button. For the purposes of the demonstration, two animations involving
incrementing offsets values are used. Prior to first animation, SetControlData is called
with the kControlBevelButtonTextOffsetTag tag to align the text on the left. Prior to
second animation, SetControlData is called with the kControlBevelButtonTextOffsetTag tag
to align the text on the right. Within the for loops, SetControlData is called with the
kControlBevelButtonTextOffsetTag tag to offset the text from the left or right by the
specified number of pixels, and Draw1Control re-draws the control.
doTextPlacement
doTextPlacement is called to demonstrate the effect of all bevel button text placement
constants except kControlBevelButtonPlaceSysDirection. Within a for loop which
increments the text placement constant, SetControlData is called with the
kControlBevelButtonTextPlaceTag tag and Draw1Control re-draws the control.
doDrawMessage and doDrawLegends
doDrawMessage and doDrawLegends are incidental to the demonstration. Both functions draw
text in the window in an Appearance-compliant colour which depends on whether the window
is currently in front or in the background.
TabEditClock.c
TabEditClock.c creates a movable modal dialog in which is demonstrated a tab control,
edit text controls and clock controls. An application-defined numeric key filter function
is attached to the second edit text control. The third edit text control is for password
input. The controls displayed by each tab are embedded in user panes.
The kDialogFlagsUsesControlHierarchy flag is set in the 'dlgx' resources for all dialogs
used in the demonstration. Recall that this means that the Dialog Manager creates a root
control in the dialog and establishes an embedding hierarchy, that all dialog items
automatically become controls, and that the Dialog Manager uses AutoEmbedControl to
position dialog items in an embedding hierarchy based on both visual containment and
their item list number.
The dialog item list used by the dialog created by TabEditClock.c is shown in the
following, in which the indentation represents the embedding hierarchy:
1. OK push button primitive.
2. Tab control (kTabControlLargeProc variant).
Visually contains the two user panes (items 3 and 12) and thus automatically
embeds those items.
3. User pane control with kControlSupportsEmbedding feature bit set (initial
value set to 2).
Visually contains items 4 to 11 and thus automatically embeds those items.
4. Static text primitive "Name:".
5 Edit text primitive.
6. Static text primitive "Age:".
7. Edit text primitive.
8. Static text primitive "Password:".
9. Edit text control (kControlEditTextPasswordProc variant).
10. Extract push button primitive.
11. Image well control.
12. User pane control with kControlSupportsEmbedding feature bit set (initial
value set to 2).
Visually contains items 13 to 20 and thus automatically embeds those items.
13. Static text primitive "Hours, Mins, Secs:".
14. Clock control (kControlClockTimeSecondsProc variant).
15. Static text primitive "Date, Month, Year:".
16. Clock control (kControlClockDateProc variant).
17. Static text primitive "Month, Year:".
18. Clock control (kControlClockMonthYearProc variant).
19. Extract push button primitive.
20. Image well control.
21. Clock control (kControlClockTimeSecondsProc variant, live, display only.)
22. Group box (kControlGroupBoxSecondaryTextTitleProc variant).
Visually contains item 23 and thus automatically embeds that item:
23. Static text primitive.
doTabEditClock
doTabEditClock creates the dialog, calls ModalDialog to handle events in the dialog, and
disposes of the dialog when the user hits the OK push button.
Firstly, and as is always required when a dialog box is to be displayed, the front window
(if one exists) is explicitly deactivated.
The call to GetNewDialog creates the dialog. The call to SetWTitle sets the window's
title so as to force an association with the 'hrct' resource containing the help balloons
for the Edit Text Control tab. (Later calls to SetWTitle in this function are used for
similar purposes.)
SetDialogDefaultItem tells the Dialog Manager which is the default push button item, to
alias the Return and Enter keys to that item, and to draw the default ring around that
item. SetDialogTracksCursor will cause the Dialog Manager to change the cursor shape to
the I-Beam cursor whenever the cursor is over an edit text control specified in the
'DITL' as an edit text primitive.
The first call to GetDialogItemAsControl gets a handle to the user pane used for the
clocks tab. HideControls hides this user pane and all the controls automatically
embedded within it.
At the next block, SetControlData is called with the kControlEditTextTextTag tag to
assign some text to the first edit text control. The fields of an edit text selection
structure are then assigned values which will cause the following call to SetControlData
to select the entire edit text control.
The next block creates routine descriptors for application-defined event filter, key
filter, and edit text validator functions. (The event filter function is defined in
the source code file Callbacks.c.) SetControlData is then called with the
kControlEditTextValidationProcTag tag to attach the edit text validation function to
the first edit text control. SetControlData is then called again with the
kControlEditTextKeyFilterTag tag to attach the key filter function to the second edit
text control.
With those preliminaries attended to, ShowWindow is called to display the window,
following which the ModalDialog loop is entered. The loop will execute until the user
hits the OK push button. Note that the previously created UPP is passed in the filterProc
parameter of ModalDialog.
When a mouse-down event occurs in an enabled item, ModalDialog returns the item number of
the item hit. If the item hit was the tab item, GetDialogItemAsControl is called to get
a handle to the tab control and GetControlValue is called to determine which of the two
tabs was hit. If the tab hit was the Edit Text Controls tab, the Clock Controls user
pane is hidden, the Edit Text Controls user pane is shown, and the keyboard focus is
set to the first edit text control. If the tab hit was the Clock Controls tab, the
Edit Text Controls user pane is hidden, the Clock Controls user pane is shown, and the
keyboard focus is set to the first clock control.
If the item hit was the Extract push button in the Edit Text Controls pane, the image
well control is re-drawn to erase any previous text and an application-defined function
is called to extract and display the contents of the edit text controls.
If the item hit was the Extract push button in the Clock Controls pane, the image well
control is re-drawn to erase any previous text and an application-defined function is
called to extract and display the contents of the clock controls.
When the user hits the OK button, DisposeDialog closes the dialog and disposes of the
associated memory, and the routine descriptors associated with the event filter function
and key filter function are disposed of.
doExtractEditText
doExtractEditText extracts the text from the edit text controls and draws it in the
image well area. In the case of the Password edit text control, the text extracted is
the actual password typed, not the bullet text.
In the case of the first two edit text controls, GetDialogItem is used to get the handle
to the hText field of the TERec structure used by the item. This is where the
characters are located. (Exactly what is returned in the iHandle field of a
GetDialogItem call depends on the item type.) GetDialogItemText then copies these
characters to a variable of type Str255.
In the case of the third (password) edit text control, GetDialogItemAsControl gets a
handle to the control. GetControlDataSize is then called with the
kControlEditTextTextTag tag to get the number of characters and GetControlData is called
with the kControlEditTextPasswordTag to get the clear password text from the
control.
doExtractDateTime
doExtractDateTime gets the settings in the three clock controls into a long date
structure, extracts the content of the relevant fields of that structure, and draws that
content in the image well area.
For each clock, GetControlData is called with the kControlClockLongDateTag tag to get the
information into a long date structure. The rest of the code simply converts the values
in the relevant fields of this structure to strings, which are concatenated with other
identifying strings prior to being drawn in the image well.
numericFilter
numericFilter is the key filter function attached to the second edit text control.
The character code passed to this function by the control is first examined to determine
whether it represents the numeric characters between 0 and 9 inclusive. If so, the
function returns kControlKeyFilterPassKey, meaning that the character is to be accepted.
If a return is not effected at that point, the character code is further examined to
determine whether it represents one of the arrow keys or the "dash" character. If so,
kControlKeyFilterPassKey is returned. If not, the system alert sound is played and
kControlKeyFilterBlockKey is returned, meaning that the character is to be rejected.
editTextValidator
editTextValidator is the edit text validation function attached to the first edit
text control.
The call to GetControlData gets the text to be examined from the control into the
variable oldText. The next block sets the length byte in oldText to the actual number
of characters in the text, limited to 255 characters. The for loop then examines each
character and, if it is an alphabetic character, the space character, or the period
character, inserts it into the newText variable and increments a variable which is
eventually used to set the length byte of newText. When the if loop exits, the length
byte is set and SetControlData is called to put the replacement text into the control.
Finally, Draw1Control redraws the control.
GroupArrowsProgress.c
GroupArrowsProgress.c creates a movable modal dialog in which is demonstrated a checkbox
group box, a pop-up group box, little arrows, a disclosure triangle, asynchronous arrows,
and an indeterminate progress bar.
The checkbox group box contains a static text item and three radio buttons. The radio
buttons are embedded in a radio group. The pop-up group box contains two user panes.
Embedded in each user pane are a checkbox and a radio group. Embedded in each radio
group are two radio buttons.
The dialog item list used by the dialog created by GroupArrowsProgress.c is shown in the
following, in which the indentation represents the embedding hierarchy:
1. Push button primitive.
2. Group box control (kControlGroupBoxCheckboxProc variant).
3. Radio group control.
4. Radio button primitive.
5. Radio button primitive.
6. Radio button primitive.
7. Checkbox primitive.
8. Group box control(kControlGroupBoxPopupButtonProc variant).
9. User pane control with kControlSupportsEmbedding feature bit set (initial
value set to 2).
10. Radio group control
11. Radio button primitive.
12. Radio button primitive.
13. Checkbox primitive.
14. Static text primitive.
15. User pane control with kControlSupportsEmbedding feature bit set (initial
value set to 2).
16. Radio group control
17. Radio button primitive.
18. Radio button primitive.
19. Checkbox primitive.
20. Static text primitive.
21. Group box control (kControlGroupBoxSecondaryTextTitleProc variant).
22. Static text primitive.
23. Group box control (kControlGroupBoxSecondaryTextTitleProc variant).
24. Static text primitive.
25. Placard control.
26. Static text primitive.
27. Little arrows control.
28. Extract push button primitive.
29. Image well
30. Separator line
31. Disclosure triangle (kControlTriangleProc variant).
32. Static text primitive.
A second dialog item list resource, containing an asynchronous arrows control and a
progress bar control, is appended to the dialog when the disclosure triangle is clicked.
doTabEditClock
doTabEditClock creates the dialog, calls ModalDialog to handle events until the user hits
the OK push button, and then disposes of the dialog.
At the first two lines, if the Bevel Buttons, Image Wells, Picture Controls, and Icon
Controls window is open, it is explicitly deactivated.
The call to GetNewDialog creates the dialog and SetDialogDefaultItem establishes the OK
push button as the default push button.
The next two lines create routine descriptors for the application-defined event filter
function and an application-defined action function for the little arrows control. (The
event filter function is in the source code file Callbacks.c.)
The next block sets the initial value of the checkbox group box to 1 (checked).
The little arrows are used to set a (simulated) cache size, which is displayed in a
static text item overlayed on a placard item. The little arrows initial value is set in
the "CNTL' resource to 96. The first three lines of the next block extract this value,
convert it to a string and append the character "K". SetControlData is then called with
the kControlStaticTextTextTag to set this string in the static text item.
The second user pane in the pop-up group box is then hidden before the call to
ShowWindow, following which the ModalDialog loop is entered. Note that the UPP
associated with the application-defined event filter function is passed in the filterProc
parameter of ModalDialog.
If ModalDialog reports that the item hit was the checkbox group box's checkbox or the
pop-up group box's pop-up menu, application-defined functions are called to further
handle the hit.
if the item hit was one of the checkboxes within the pop-up group box, the control's
control value is set so that the control is checked if it was unchecked, or unchecked if
it was checked.
If the item hit was the disclosure triangle, an application-defined function is called to
further handle the hit.
If the item hit was the Extract push button, Draw1Control is called to redraw the image
well, thus erasing any previous text in the well, and an application-defined function is
called to ectract the control settings and draw them in the image well area.
Note that hits on the radio buttons will be handled automatically by the radio group
controls in which they are embedded. The radio group control will set the new control
values according to which radio button is hit, and will change the checked/unchecked
appearance of the radio buttons to match.
Note also that mouse-down events in the little arrows are detected and handled in the
event filter function. (See the source code file Callbacks.c.)
When the OK button is hit, the loop exits, DisposeDialog closes the dialog and disposes
of the associated memory, and the two previously created routine descriptors are disposed
of. In addition, the global variable which flags that the dialog was open is set to
false.
doCheckBoxGroupBox
doCheckBoxGroupBox further handles a hit in the checkbox group box's checkbox.
The first three lines flip the control's value; that is, if the control's value was 1
(checked), it is set to 0 (unchecked), and vice versa.
If the new value of the control is 0 (unchecked), the radio group and checkbox within the
group box are deactivated. Since the radio buttons are embedded in the radio group, they
will also be deactivated when the radio group is deactivated.
If the new value of the control is 1 (checked), the radio group and checkbox within the
group box are activated. Since the radio buttons are embedded in the radio group, they
will also be activated when the radio group is activated.
doPopupGroupBox
doPopupGroupBox further handles a hit in the pop-up group box's pop-up menu button.
The first two lines get the control's value, which represents the menu item chosen.
Depending on the item chosen, the appropriate user panes are hidden or shown, thus hiding
or showing all controls embedded in each user pane.
doAsynchronousAndProgress
doAsynchronousAndProgress further handles a hit in the disclosure triangle.
The first three lines flip the control's value; that is, if the control's value was 1
(expanded), it is set to 0 (collapsed), and vice versa.
If the new control value is 1 (expanded), GetResource is called to load the item list
resource containing the asynchronous arrows and progress bar items. AppendDITL is then
called to append these items to the end of the dialog's item list. The constant passed
in the third parameter of this call causes the dialog box to be expanded downwards to
accommodate the new items. SetControlData is then called with the
kControlProgressBarIndeterminateTag tag to make the progress bar an indeterminate
progress bar.
Not previously mentioned is the fact that the appended 'DITL' resource contains a static
text item, with not text, the function of which is simply to expand the dialog further
downwards to accommodate a move of the OK push button. The call to MoveControl moves the
OK push button to a position below the asynchronous arrows and progress bar.
Finally, SetControlData is called with the kControlStaticTextTextTag tag to change the
text in the static text field adjacent to the disclosure triangle. Draw1Control re-draws
the control to display the changed text.
If the new disclosure triangle control value is 0 (collapsed), the OK button is moved
back to its previous location, SizeWindow is called to resize the window to its previous
size, SetControlData is called with the kControlStaticTextTextTag tag to change the text
in the static text field adjacent to the disclosure triangle, and Draw1Control re-draws
the control to display the changed text.
doExtractCurrentStatus
doExtractCurrentStatus is called when the Extract push button is hit. It simply extracts
the values of the various controls, builds up strings based on those values, and draws
those strings in the image well area.
Note in the second last block that the value of the little arrows control represents the
current (simulated) cache size. The little arrows control value is set within the action
function arrowsActionFunction in the source code file Callbacks.c.
Sliders.c
Sliders.c creates a movable modal dialog box in which is demonstrated various slider
control variants and two simple user pane functions.
doSliderUserPane
doSliderUserPane creates the dialog, calls ModalDialog to handle events until the user
hits the OK push button, and then disposes of the dialog.
At the first two lines, if the Bevel Buttons, Image Wells, Picture Controls, and Icon
Controls window is open, it is explicitly deactivated.
The call to GetNewDialog creates the dialog and SetDialogDefaultItem establishes the OK
push button as the default push button.
The next three lines create routine descriptors for the application-defined event filter
function and two application-defined action functions for the live-feedback slider
variants, one for the two at top right of the dialog and one for the two horizontal
sliders. (The event filter function and the action functions are in the source code
file Callbacks.c.)
The next two blocks creates routine descriptors for two user pane functions (one a draw
function and one an activate function), and attach these functions to a user pane located
immediately to the right of the two horizontal sliders.
The next block assign handles to the first four sliders to global variables and call an
application-defined function to draw the respective control values in static text items
located immediately below the sliders.
The following four lines assign handles to the horizontal sliders to global variables and
assign a value based on the current slider control values to the red and blue fields of
two global variables of type RGBColor.
The call to ShowWindow makes the dialog visible before the ModalDialog loop is entered.
This loop executes until the OK button is hit, at which time DisposeDialog is called to
remove the dialog and dispose of its associated memory, the previously created routine
descriptors are disposed of, and the global variable which flags that the Sliders dialog
is open is assigned false.
doDrawSliderValues
doDrawSliderValue is called by doSliderUserPane to draw the initial control values of the
four top sliders in the static text fields immediately below the sliders.
The first line gets the control's value and converts it to a string. The next block
determines, on the basis of the received control handle, which is the target static text
item. SetControlData is then called with the kControlStaticTextTextTag tag to set the
text, and Draw1Control re-draws the static text control.
As will be seen, this function is also called from within the event filter function when
a mouse-down has been detected within the two non-live-scrolling sliders.
userPaneDrawFunction
userPaneDrawFunction will be called whenever an update event is received. This will
occur when the dialog is opened and, subsequently, when an overlaying window or help
balloon is removed from the area occupied by the user pane (to the immediate right of the
horizontal sliders).
The two calls to DrawThemeGenericWell draw two Appearance image well primitives to the
right of the horizontal sliders. The global variable gDrawActivated determines whether
the primitive is drawn with an activated or deactivated appearance.
If the global variable gDrawActivated indicates that the interior of the well should be
drawn, the foreground colour for each interior is set to that stored in global variables
and PaintRect is called to paint the interior in that colour. (As will be seen, the
value stored in these global variables is changed by the action function called while the
mouse button remains down in the slider's indicators.)
If gDrawActivated indicates that the interior of the well should be displayed with a
deactivated appearance, the interior is left as drawn by DrawThemeGenericWell, that is,
white.
userPaneActivateFunction
The kControlWantsActivate feature bit is set in the user pane on creation, that is, the
control's minimum value in the 'CNTL' resource is set to 16. This ensures that this
function will be called when the dialog receives activate events.
Depending on whether the dialog is about to be activated or deactivated, the global
variable gDrawActivated is set to true or false. As has been seen, this global variable
controls the way in which the image well primitive and the interior of the image well is
drawn.
TextBox.c
doAboutBox is called when the user chooses About Controls3... from the Apple menu. It
opens a movable modal dialog containing a standard and scrolling text box controls.
Callbacks.c
Callbacks.c contains the event filter function used by all movable modal dialogs and
three action functions, one for the little arrows, one for the live-feedback sliders at
top right of the dialog, and one for the horizontal live-feedback sliders.
eventFilter
The event filter function eventFilter is identical to the event filter function
introduced at Chapter 8 - Dialogs and Alerts except that it intercepts mouse-down events
in the little arrows and sliders and informs ModalDialog that it has handled those
events.
At the second and third if statements, if the Group Boxes, Arrows, and Progress Bar
dialog is currently open, and if the event is a mouse-down event, the location of the
mouse-down is extracted from the where field of the event structure and converted to the
local coordinates required by the following call to FindControl. If FindControl
determines that there is an enabled control under the mouse cursor, and if that control
is the little arrows control, TrackControl is called to handle all user interaction while
the mouse button remains down. While the mouse button remains down, TrackControl
continually calls the action function whose routine descriptor is pointed to by the UPP
passed in the third parameter. When the mouse button is released, the function exits
with true being returned to ModalDialog.
if, on the other hand, the Sliders and User Pane Functions dialog is open, and if the
event is a mouse-down event, and if FindControl reports an enabled control, and if that
control is one of the two non-live-feedback sliders, TrackControl is called to handle all
user interaction while the mouse button remains down. When the mouse button is released,
the application-defined function doDrawSliderValues is called to draw the new control
value in the static text item below the slider. Once again, the function then exits with
true being returned to ModalDialog.
If the mouse-down was in one of the two live-feedback sliders at the top right of the
dialog, TrackControl is called with a UPP to the first slider action function passed in
the third parameter.
If the mouse-down was in one of the two horizontal live-feedback sliders, TrackControl is
called with a UPP to the second slider action function passed in the third parameter.
arrowsActionFunction
arrowsActionFunction is the action function for the little arrows. It is called
continually by TrackControl while the mouse button remains down.
if the mouse cursor is still within the control, GetControlValue is called to get the
current control value. The function then switches according to the part code. If the
cursor is in the top arrow, the control's value is increased by 32 unless this would
cause the value to exceed the control's maximum value (set in the 'CNTL' resource to
7680). If the cursor is in the bottom arrow, the control's value is decreased by 32
unless this would cause the value to be lower that the control's minimum value (set in
the 'CNTL' resource to 96).
If the control's value was increased or decreased within the switch, SetControlValue is
called to set the new control value, and the final block sets the new text for the Cache
size static text item and re-draws the item.
sliderActionFunction1
sliderActionFunction1 is the action function for the live-feedback sliders at the top
right of the dialog. It is called continually by TrackControl while the mouse button
remains down.
GetControlValue gets the control's current value and NumToString converts it to a string
for display. The next line gets the pointer to the control's owning window required by
the call to GetDialogItemAsControl. The if block determines which of the two sliders the
mouse is down in. The last two lines set the text in the appropriate static text control
and redraw the control.
sliderActionFunction2
sliderActionFunction3 is the action function for the horizontal live-feedback sliders.
It is called continually by TrackControl while the mouse button remains down.
GetControlValue gets the control's current value. If the slider is the top horizontal
slider, the red field of the RGBColor global variable gRedColor is assigned a new value
based on the control's current value, and the local Rect variable is assigned the
coordinates of the image well at the right of the slider. If the slider is the bottom
horizontal slider, the blue field of the RGBColor global variable gBlueColor is assigned
a new value based on the control's current value, and the local Rect variable is assigned
the coordinates of the image well at the right of the slider.
Finally, PaintRect is called to paint the interior area of the relevant image well in the
new colour.
|