Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/NewAppletDialog.cp
/* |
* NewAppletDialog.cp |
*/ |
#include "NewAppletDialog.h" |
#include "StringListResource.h" |
const cAppletDialog = 1129; |
const cAddEditDialog = 1130; |
enum AppletItems { |
eAddItem = 3, |
eChooseLabel, |
eListArea, |
eURLArea, |
eEditButton, |
eDeleteButton, |
eRandomCheckbox |
}; |
enum AddEditItems { |
eNameLabel = 3, |
eURLLabel, |
eNameText, |
eURLText |
}; |
struct FontSaver { |
short saveFace, saveSize, saveFont; |
}; |
static void setupDialogFont(DialogPtr dialog, short fontSize, FontSaver* saver) |
{ |
SetPort(dialog); |
TextFont(geneva); |
TextFace(normal); |
TextSize(fontSize); |
saver->saveFont = dialog->txFont; |
saver->saveSize = dialog->txSize; |
saver->saveFace = dialog->txFace; |
} |
static void restoreDialogFont(FontSaver* saver) |
{ |
TextFont(saver->saveFont); |
TextFace(saver->saveFace); |
TextSize(saver->saveSize); |
} |
/* |
* doAddDialog |
*/ |
static void setEditTextItem(DialogPtr dialog, int ixItem, Str255 text) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect); |
SetIText(itemHandle, text); |
} |
static void getEditTextItem(DialogPtr dialog, int ixItem, Str255 text) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect); |
GetIText(itemHandle, text); |
} |
static Boolean doAddDialog(Str255 itemLabel, Str255 itemURL) |
{ |
Boolean result = false; |
DialogPtr dialog = GetNewDialog(cAddEditDialog, nil, WindowPtr(-1)); |
if (dialog) { |
SetDialogDefaultItem(dialog, ok); |
SetDialogCancelItem(dialog, cancel); |
SetDialogTracksCursor(dialog, true); |
setEditTextItem(dialog, eNameText, itemLabel); |
setEditTextItem(dialog, eURLText, itemURL); |
SelIText(dialog, eNameText, 0, 32767); |
short itemHit; |
Boolean continueLoop = true; |
ShowWindow(dialog); |
do { |
ModalDialog(nil, &itemHit); |
switch (itemHit) { |
case ok: |
continueLoop = false; |
getEditTextItem(dialog, eNameText, itemLabel); |
getEditTextItem(dialog, eURLText, itemURL); |
result = true; |
break; |
case cancel: |
continueLoop = false; |
break; |
case eNameLabel: |
SelIText(dialog, eNameText, 0, 32767); |
break; |
case eURLLabel: |
SelIText(dialog, eURLText, 0, 32767); |
break; |
} |
} while (continueLoop); |
DisposeDialog(dialog); |
} |
return result && itemLabel[0] > 0 && itemURL[0] > 0; |
} |
/* |
* newAppletDialog |
*/ |
static ListHandle theList; |
static UserItemUPP theListUPP = nil; |
static UserItemUPP theURLUPP = nil; |
static Handle theLabelTexts; |
static Handle theURLTexts; |
static long theCurrentItem = 0; |
static Boolean theRandomSet; |
static void selectItem(int ixCell) |
{ |
Cell cell = { 0, 0 }; |
while (LGetSelect(true, &cell, theList)) { |
LSetSelect(false, cell, theList); |
} |
cell.v = ixCell; |
LSetSelect(true, cell, theList); |
LAutoScroll(theList); |
} |
static void addToList(Str255 itemLabel, Str255 itemURL) |
{ |
Cell cell; |
cell.h = 0; |
cell.v = LAddRow(1, -1, theList); |
LSetCell(&itemLabel[1], itemLabel[0], cell, theList); |
PtrAndHand(itemLabel, theLabelTexts, 256); |
PtrAndHand(itemURL, theURLTexts, 256); |
selectItem(cell.v); |
} |
static void getCurrentItem(StringPtr itemLabel, StringPtr itemURL) |
{ |
if (theCurrentItem == -1) { |
if (itemLabel != nil) |
itemLabel[0] = 0; |
if (itemURL != nil) |
itemURL[0] = 0; |
} else { |
if (itemLabel) |
BlockMoveData(*theLabelTexts + (256 * theCurrentItem), itemLabel, 256); |
if (itemURL) |
BlockMoveData(*theURLTexts + (256 * theCurrentItem), itemURL, 256); |
} |
} |
static void updateURLArea(DialogPtr dialog, Boolean justDoIt) |
{ |
Cell cell = { 0, 0 }; |
short newIndex; |
if (! LGetSelect(true, &cell, theList)) |
newIndex = -1; |
else |
newIndex = cell.v; |
if (newIndex != theCurrentItem || justDoIt) { |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, eURLArea, &itemType, &itemHandle, &itemRect); |
InsetRect(&itemRect, 1, 1); |
InvalRect(&itemRect); |
} |
theCurrentItem = newIndex; |
} |
static void deleteCurrentItem(DialogPtr dialog) |
{ |
if (theCurrentItem != -1) { |
Munger(theLabelTexts, (256 * theCurrentItem), nil, 256, Ptr(-1), 0); |
Munger(theURLTexts, (256 * theCurrentItem), nil, 256, Ptr(-1), 0); |
Cell cell; |
cell.h = 0; |
cell.v = theCurrentItem; |
LDelRow(1, theCurrentItem, theList); |
theCurrentItem--; |
if (theCurrentItem < 0) |
theCurrentItem = 0; |
selectItem(theCurrentItem); |
updateURLArea(dialog, true); |
} |
} |
static void setCurrentItem(DialogPtr dialog, StringPtr itemLabel, StringPtr itemURL) |
{ |
Cell cell; |
cell.h = 0; |
cell.v = theCurrentItem; |
LSetCell(&itemLabel[1], itemLabel[0], cell, theList); |
BlockMoveData(itemLabel, *theLabelTexts + (256 * theCurrentItem), 256); |
BlockMoveData(itemURL, *theURLTexts + (256 * theCurrentItem), 256); |
updateURLArea(dialog, true); |
} |
static pascal void _ListProc(DialogPtr dialog, short itemNumber) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, itemNumber, &itemType, &itemHandle, &itemRect); |
FontSaver saver; |
setupDialogFont(dialog, 12, &saver); |
MoveTo(itemRect.right, itemRect.top - 1); |
LineTo(itemRect.left, itemRect.top - 1); |
LineTo(itemRect.left, itemRect.bottom); |
LineTo(itemRect.right, itemRect.bottom); |
LUpdate(dialog->visRgn, theList); |
restoreDialogFont(&saver); |
} |
static pascal void _URLProc(DialogPtr dialog, short itemNumber) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, itemNumber, &itemType, &itemHandle, &itemRect); |
FontSaver saver; |
setupDialogFont(dialog, 9, &saver); |
FrameRect(&itemRect); |
InsetRect(&itemRect, 1, 1); |
EraseRect(&itemRect); |
MoveTo(itemRect.left + 2, itemRect.bottom - 3); |
Str255 url; |
getCurrentItem(nil, url); |
DrawString(url); |
restoreDialogFont(&saver); |
} |
static void setupUserItems(DialogPtr dialog) |
{ |
/* |
* Others... |
*/ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
FontSaver saver; |
setupDialogFont(dialog, 12, &saver); |
/* |
* List |
*/ |
GetDItem(dialog, eListArea, &itemType, &itemHandle, &itemRect); |
Rect rBounds = { 0, 0, 0, 1 }; |
Point cellBounds = { 0, 0 }; |
Rect listRect; |
listRect = itemRect; |
listRect.left += 1; |
listRect.right -= 16; |
theList = LNew(&listRect, &rBounds, cellBounds, 0, dialog, false, false, false, true); |
(**theList).selFlags = lOnlyOne; |
if (theListUPP == nil) |
theListUPP = NewUserItemProc(_ListProc); |
SetDItem(dialog, eListArea, itemType, Handle(theListUPP), &itemRect); |
LDoDraw(true, theList); |
/* |
* URL label |
*/ |
GetDItem(dialog, eURLArea, &itemType, &itemHandle, &itemRect); |
if (theURLUPP == nil) |
theURLUPP = NewUserItemProc(_URLProc); |
SetDItem(dialog, eURLArea, itemType, Handle(theURLUPP), &itemRect); |
restoreDialogFont(&saver); |
} |
static short openPrefsFile() |
{ |
FSSpec spec; |
short vRefNum; |
long parID; |
FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &vRefNum, &parID); |
if (FSMakeFSSpec(vRefNum, parID, "\pApplet Screen Saver Prefs", &spec) == fnfErr) { |
FSpCreateResFile(&spec, 'WARZ', 'PREF', 0); |
} |
return FSpOpenResFile(&spec, fsRdWrPerm); |
} |
static void addToGlobals(Str255 itemLabel, Str255 itemURL) |
{ |
PtrAndHand(itemLabel, theLabelTexts, 256); |
PtrAndHand(itemURL, theURLTexts, 256); |
} |
static void getGlobals() |
{ |
short fRefNum = openPrefsFile(); |
if (fRefNum != -1) { |
theLabelTexts = GetResource('STNG', 128); |
theURLTexts = GetResource('STNG', 129); |
if (theLabelTexts != nil) |
DetachResource(theLabelTexts); |
if (theURLTexts != nil) |
DetachResource(theURLTexts); |
Handle hRandom = GetResource('RAND', 128); |
if (hRandom == nil) |
theRandomSet = false; |
else { |
theRandomSet = **hRandom != 0; |
ReleaseResource(hRandom); |
} |
Handle hItem = GetResource('SELE', 128); |
if (hItem == nil) |
theCurrentItem = 0; |
else { |
theCurrentItem = *(long*) *hItem; |
ReleaseResource(hItem); |
} |
CloseResFile(fRefNum); |
} |
if (theLabelTexts == nil || theURLTexts == nil) { |
theLabelTexts = NewHandle(0); |
theURLTexts = NewHandle(0); |
#if 0 |
#define XX(a,b) \ |
addToGlobals("\p" a, "\p" b) |
XX("Earthweb's Netris", "http://www.earthweb.com/java/Netris/index.html"); |
XX("Rusotto's ZCode Interpreter", "http://www.pond.com/~russotto/zplet/minizork.html"); |
XX("HypnoVista Splash", "http://www.hypno.com/javabeta/fromandy/splash/splash.html"); |
XX("HypnoVista Bongo Dude", "http://www.hypno.com/javabeta/bongo/bongo.html"); |
XX("HypnoVista Running Man", "http://www.hypno.com/javabeta/runner/file.html"); |
XX("HypnoVista Hacker", "http://www.hypno.com/javabeta/hacker/file.html"); |
XX("HypnoVista Fish", "http://www.hypno.com/javabeta/fish/file.html"); |
XX("Circus Animations", "http://circus.compuware.com/"); |
XX("At a Distance (Game)", "http://www.cs.cmu.edu/afs/andrew/usr/scier/www/AtADistance.html"); |
XX("CERN Accelerator Watch", "http://hpslweb.cern.ch/teletext/java/view110-java.html"); |
XX("Sun Golf", "http://www.sun.nl/SunOpenGame/Course1.html"); |
XX("Sieve Benchmark", "http://rsb.info.nih.gov/nih-image/Java/Benchmarks/Sieve.html"); |
XX("FrogPond", "http://sepwww.stanford.edu/sep/krl/FrogPond/FrogPond.html"); |
XX("Bounce Simulator", "http://www.chem.uci.edu/instruction/applets/bounce.html"); |
XX("Atmosphere Simulator", "http://www.chem.uci.edu/instruction/applets/canonical.html"); |
#endif |
StringListResource defaultNames(0); |
StringListResource defaultURLs(1); |
StringPtr names = defaultNames.First(); |
StringPtr urls = defaultURLs.First(); |
while (names && urls) { |
addToGlobals(names, urls); |
names = defaultNames.Next(); |
urls = defaultURLs.Next(); |
} |
#undef XX |
} |
} |
static void disposeGlobals() |
{ |
DisposeHandle(theLabelTexts); |
theLabelTexts = nil; |
DisposeHandle(theURLTexts); |
theURLTexts = nil; |
theList = nil; |
} |
static void setRandomCheckbox(DialogPtr dialog) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, eRandomCheckbox, &itemType, &itemHandle, &itemRect); |
SetControlValue(ControlHandle(itemHandle), theRandomSet? 1 : 0); |
} |
static void addItems(DialogPtr dialog) |
{ |
int ctCells = GetHandleSize(theLabelTexts) / sizeof(Str255); |
Cell cell; |
cell.h = 0; |
LAddRow(ctCells, -1, theList); |
HLock(theLabelTexts); |
char* p = *theLabelTexts; |
for (cell.v = 0; cell.v < ctCells; cell.v++) { |
LSetCell(&p[1], p[0], cell, theList); |
p += 256; |
} |
setRandomCheckbox(dialog); |
} |
static void updateResource(OSType type, short id, Handle newResource) |
{ |
Handle hToss = GetResource(type, id); |
if (hToss != nil) { |
RmveResource(hToss); |
DisposeHandle(hToss); |
} |
AddResource(newResource, type, id, "\p"); |
WriteResource(newResource); |
DetachResource(newResource); |
} |
static void writeResources() |
{ |
short fRefNum = openPrefsFile(); |
if (fRefNum == -1) |
return; |
updateResource('STNG', 128, theLabelTexts); |
updateResource('STNG', 129, theURLTexts); |
Handle hRandom = NewHandle(1); |
if (hRandom) { |
**hRandom = theRandomSet; |
updateResource('RAND', 128, hRandom); |
DisposeHandle(hRandom); |
} |
Handle hItem = NewHandle(sizeof(long)); |
if (hItem) { |
*(long*) *hItem = theCurrentItem; |
updateResource('SELE', 128, hItem); |
DisposeHandle(hItem); |
} |
CloseResFile(fRefNum); |
} |
/* |
* FilterProc |
*/ |
static ModalFilterUPP theStdFilterProc; |
static ModalFilterUPP theFilterProc = nil; |
static pascal Boolean _ModalFilter(DialogPtr theDialog, EventRecord *eve, short *itemHit) |
{ |
Boolean result = false; |
*itemHit = -1; |
switch (eve->what) { |
case mouseDown: { |
Point localPos = eve->where; |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(theDialog, eListArea, &itemType, &itemHandle, &itemRect); |
FontSaver saver; |
setupDialogFont(theDialog, 12, &saver); |
GlobalToLocal(&localPos); |
if (PtInRect(localPos, &itemRect)) { |
if (LClick(localPos, eve->modifiers, theList)) { |
*itemHit = eListArea; |
result = true; |
} |
updateURLArea(theDialog, false); |
} |
restoreDialogFont(&saver); |
} break; |
case keyDown: { |
char ch = eve->message & charCodeMask; |
if ((ch == 'c' || ch == 'C' || ch == '' || ch == '') && (eve->modifiers & cmdKey) != 0) { |
Str255 itemURL; |
// if cmd-key, just copy the selected one. If option, copy all |
if ((eve->modifiers & optionKey) != 0) { |
Handle hText = NewHandle(0); |
int ctItems = GetHandleSize(theURLTexts) / 256; |
HLock(theURLTexts); |
char* p = *theURLTexts; |
for (int i = 0; i < ctItems; i++) { |
PtrAndHand(&p[1], hText, p[0]); |
PtrAndHand("\r", hText, 1); |
p += 256; |
} |
HUnlock(theURLTexts); |
HLock(hText); |
ZeroScrap(); |
PutScrap(GetHandleSize(hText), 'TEXT', *hText); |
DisposeHandle(hText); |
} else { |
getCurrentItem(nil, itemURL); |
if (itemURL[0] > 0) { |
ZeroScrap(); |
PutScrap(itemURL[0], 'TEXT', &itemURL[1]); |
} |
} |
} else { |
int newSel = theCurrentItem; |
result = true; |
switch (ch) { |
case 30: // up |
newSel--; |
break; |
case 31: // down |
newSel++; |
break; |
case 1: // home |
newSel = 0; |
break; |
case 4: // end |
newSel = (**theList).dataBounds.bottom; |
break; |
case 11: { // pup |
Rect* rView = &(**theList).rView; |
Point pp = (**theList).cellSize; |
newSel -= ((rView->bottom - rView->top) / pp.v) - 1; |
} break; |
case 12: { // pdown |
Rect* rView = &(**theList).rView; |
Point pp = (**theList).cellSize; |
newSel += ((rView->bottom - rView->top) / pp.v) - 1; |
} break; |
default: |
result = false; |
} |
if (result == true) { |
if (newSel < 0) |
newSel = 0; |
if (newSel >= (**theList).dataBounds.bottom) |
newSel = (**theList).dataBounds.bottom - 1; |
if (newSel != theCurrentItem) { |
FontSaver saver; |
setupDialogFont(theDialog, 12, &saver); |
selectItem(newSel); |
*itemHit = -1; |
updateURLArea(theDialog, false); |
restoreDialogFont(&saver); |
} |
} |
} |
} break; |
} |
if (result == false && theStdFilterProc != nil) |
result = CallModalFilterProc(theStdFilterProc, theDialog, eve, itemHit); |
return result; |
} |
static void hiliteDialogControl(DialogPtr dialog, short ixItem) |
{ |
short itemType; |
Rect itemRect; |
Handle itemHandle; |
GetDItem(dialog, ixItem, &itemType, &itemHandle, &itemRect); |
HiliteControl(ControlHandle(itemHandle), inButton); |
long actual; Delay(GetDblTime() / 3, &actual); |
HiliteControl(ControlHandle(itemHandle), 0); |
} |
void newAppletDialog() |
{ |
Str255 itemLabel; |
Str255 itemURL; |
Boolean doRunApplet = nil; |
DialogPtr dialog = GetNewDialog(cAppletDialog, nil, WindowPtr(-1)); |
if (dialog) { |
getGlobals(); |
GetStdFilterProc(&theStdFilterProc); |
if (theFilterProc == nil) |
theFilterProc = NewModalFilterProc(_ModalFilter); |
setupUserItems(dialog); |
addItems(dialog); |
SetDialogDefaultItem(dialog, ok); |
SetDialogCancelItem(dialog, cancel); |
short itemHit; |
Boolean continueLoop = true; |
selectItem(theCurrentItem); |
ShowWindow(dialog); |
do { |
ModalDialog(theFilterProc, &itemHit); |
switch (itemHit) { |
case eListArea: |
hiliteDialogControl(dialog, ok); |
// fall through |
case ok: |
if (theCurrentItem != -1) { |
getCurrentItem(nil, itemURL); |
doRunApplet = true; |
} |
HideWindow(dialog); |
writeResources(); |
// fall through |
case cancel: |
continueLoop = false; |
break; |
case eRandomCheckbox: |
theRandomSet = ! theRandomSet; |
setRandomCheckbox(dialog); |
break; |
case eAddItem: { |
itemLabel[0] = 0; |
itemURL[0] = 0; |
if (doAddDialog(itemLabel, itemURL)) { |
addToList(itemLabel, itemURL); |
updateURLArea(dialog, true); |
} |
} break; |
case eEditButton: { |
getCurrentItem(itemLabel, itemURL); |
if (doAddDialog(itemLabel, itemURL)) { |
setCurrentItem(dialog, itemLabel, itemURL); |
} |
} break; |
case eDeleteButton: { |
deleteCurrentItem(dialog); |
} break; |
} |
} while (continueLoop); |
// dispose other user items? |
LDispose(theList); |
DisposeDialog(dialog); |
disposeGlobals(); |
} |
} |
void getSelectedURL(Str255 urlString, Str255 urlName) |
{ |
urlString[0] = 0; |
getGlobals(); |
if (theURLTexts != nil) { |
int ctItems = GetHandleSize(theURLTexts) / 256; |
if (ctItems > 0) { |
int ixSelected; |
if (theRandomSet) |
ixSelected = (Random() & 0x7fff) % ctItems; |
else |
ixSelected = theCurrentItem; |
if (ixSelected < 0) |
ixSelected = 0; |
if (ixSelected >= ctItems) |
ixSelected = ctItems - 1; |
BlockMoveData(*theLabelTexts + ixSelected * 256, urlName, 256); |
BlockMoveData(*theURLTexts + ixSelected * 256, urlString, 256); |
} |
} |
if (urlString[0] == 0) { |
static const unsigned char cDefault[] = "\phttp://www.hypno.com/javabeta/fromandy/splash/splash.html"; |
static const unsigned char cDefaultName[] = "\pEmergency default module."; |
BlockMoveData(cDefault, urlString, cDefault[0] + 1); |
BlockMoveData(cDefaultName, urlName, cDefaultName[0] + 1); |
} |
disposeGlobals(); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14