JPEGView/Source/C/StatisticsWindow.c
Aaron Giles 92bdb55672 JPEGView 3.3 for Macintosh
These are the sources for the final official release of JPEGView for the
Mac, back in 1994.
2015-02-05 00:18:10 -08:00

1 line
26 KiB
C

/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information. */
/* Contact email: mac@aarongiles.com */
/*********************************************************/
#if THINK_C
#include "THINK.Header"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif
/*
* Local variables:
* lStatFontInfo = the font information for the statistics window font (Geneva 9pt)
* lStatWindow = pointer to the statistics window
*
*/
static RgnHandle gStatRegion = nil;
static Ptr gStatRecord = nil;
static long gStatLength = 0;
static Rect gStatRect[strFreeMemory - strFileName + 2];
static ImageHandle gLastImage = (ImageHandle)-1;
static WindowPtr gStatWindow = nil;
static TEHandle gCreditsTE = nil;
static FontInfo gStatFontInfo;
static long gCreditsHeight;
/*
* OpenStats()
*
* Purpose: Creates and initializes the statistics window
* Inputs: none
* Returns: nothing
*
*/
OSErr OpenStats(void)
{
Handle textHandle, stylHandle;
Rect theRect, mainRect;
OSErr theErr = noErr;
LHHandle theLines;
Point where;
short i;
if (gStatWindow) {
if (!WindowVisible(gStatWindow)) FWShowWindow(gStatWindow);
return noErr;
}
if (!(gStatWindow = AllocateWindow())) return gIntError = errNoMemory, memFullErr;
PushPort();
MySetPort(nil);
if (gStatWindow = FWGetNewFloatingWindow(rStatWindow, (Ptr)gStatWindow, (WindowPtr)-1)) {
MySetPort((CGrafPtr)gStatWindow);
TextFont(geneva);
TextSize(9);
TextMode(srcCopy);
TextFace(bold);
GetFontInfo(&gStatFontInfo);
gStatFontInfo.widMax = StringWidth(gString[strDisplayedColors]) + 8;
SizeStats(true);
theRect = gStatWindow->portRect;
InsetRect(&theRect, 2, 2);
if (gCreditsTE = TEStylNew(&theRect, &gStatWindow->portRect)) {
if (textHandle = GetResource('TEXT', rCreditsText)) {
if (stylHandle = GetResource('styl', rCreditsText)) {
HLock(textHandle);
HLock(stylHandle);
TEStylInsert(*textHandle, GetHandleSize(textHandle),
(StScrpHandle)stylHandle, gCreditsTE);
ReleaseResource(stylHandle);
} else TEDispose(gCreditsTE), gCreditsTE = nil;
ReleaseResource(textHandle);
} else TEDispose(gCreditsTE), gCreditsTE = nil;
if (gCreditsTE) {
TESetJust(teCenter, gCreditsTE);
if ((*gCreditsTE)->lineHeight == -1 || (*gCreditsTE)->fontAscent == -1) {
theLines = (*GetStylHandle(gCreditsTE))->lhTab;
for (i = gCreditsHeight = 0; i < (*gCreditsTE)->nLines; i++)
gCreditsHeight += (*theLines)[i].lhHeight;
} else gCreditsHeight = (*gCreditsTE)->nLines * (*gCreditsTE)->lineHeight;
}
}
SizeStats(gThePrefs.statsZoomed);
theRect = gStatWindow->portRect;
OffsetRect(&theRect, -theRect.left, -theRect.top);
if (gThePrefs.statsBounds.top != gThePrefs.statsBounds.bottom) {
gThePrefs.statsBounds.right = gThePrefs.statsBounds.left + Width(&theRect);
gThePrefs.statsBounds.bottom = gThePrefs.statsBounds.top + Height(&theRect);
}
GetActiveRect(gMainMonitor, &mainRect);
where.h = mainRect.left + kWindowBorderWidth;
where.v = mainRect.bottom - kWindowBorderHeight - theRect.bottom;
PlaceWindow(gStatWindow, &gThePrefs.statsBounds, where);
gLastImage = (ImageHandle)-1;
gThePrefs.statsOpen = true;
} else gIntError = errNoMemory, theErr = memFullErr, DeallocateWindow(gStatWindow);
PopPort();
return theErr;
}
/*
* CloseStats()
*
* Purpose: Closes the statistics window
* Inputs: none
* Returns: nothing
*
*/
void CloseStats(void)
{
PushPort();
MySetPort(nil);
if (gCreditsTE) TEDispose(gCreditsTE), gCreditsTE = nil;
if (gStatWindow) {
gThePrefs.statsOpen = false;
SaveWindowPosition(gStatWindow, &gThePrefs.statsBounds);
FWCloseWindow(gStatWindow);
DeallocateWindow(gStatWindow);
}
gStatWindow = nil;
PopPort();
}
/*
* SizeStats(zoomed)
*
* Purpose: Sets the size of the statistics window appropriately
* Inputs: zoomed = true if the window is zoomed to its large size
* Returns: nothing
*
*/
void SizeStats(Boolean zoomed)
{
short line = gStatFontInfo.leading + gStatFontInfo.ascent + gStatFontInfo.descent;
short width, height;
width = 5 * gStatFontInfo.widMax / 2 + 20;
height = gStatFontInfo.leading + gStatFontInfo.descent;
if (zoomed) height += 15 * line;
else height += line;
SizeWindow(gStatWindow, width, height, false);
PushPort();
MySetPort((CGrafPtr)gStatWindow);
EraseRect(&gStatWindow->portRect);
DrawStatWindow();
PopPort();
}
/*
* ZoomStats(zoomed)
*
* Purpose: Toggles the zoomed state of the stats window
* Inputs: none
* Returns: nothing
*
*/
void ZoomStats(void)
{
gThePrefs.statsZoomed = !gThePrefs.statsZoomed;
SizeStats(gThePrefs.statsZoomed);
}
/*
* GetStatWindow()
*
* Purpose: Returns a pointer to the statistics window
* Inputs: none
* Returns: nothing
*
*/
WindowPtr GetStatWindow(void)
{
return gStatWindow;
}
/*
* SetStatistics()
*
* Purpose: Updates the statistics window
* Inputs: none
* Returns: nothing
*
*/
void SetStatistics(void)
{
if (gStatWindow) {
PushPort();
MySetPort((CGrafPtr)gStatWindow);
InvalRect(&gStatWindow->portRect);
PopPort();
}
if (GetCommentsWindow()) DrawCommentsWindow();
}
/*
* DrawStatWindow()
*
* Purpose: Draws the statistics window
* Inputs: none
* Returns: nothing
*
*/
void DrawStatWindow(void)
{
static Boolean gCreditsLast = false;
short vPos = gStatFontInfo.ascent + gStatFontInfo.leading;
ImageHandle theImage = nil;
WindowPtr theWindow;
if (!gStatRegion) gStatRegion = NewRgn();
else SetEmptyRgn(gStatRegion);
CalcVis((WindowPeek)gStatWindow);
for (theWindow = GetFirstWindow(); theWindow && !(theImage = FindImage(theWindow)); theWindow = NextWindow(theWindow));
if (theImage != gLastImage) gLastImage = theImage;
if (theImage && IsAboutBox(theImage)) {
if (gCreditsTE) {
TEUpdate(&gStatWindow->portRect, gCreditsTE);
gCreditsLast = true;
}
} else {
if (gCreditsLast) {
EraseRect(&gStatWindow->portRect);
gCreditsLast = false;
}
if (gThePrefs.statsZoomed) {
DrawStatFileName(theImage, &vPos);
DrawStatImageSize(theImage, &vPos);
DrawStatImageColors(theImage, &vPos);
DrawStatImageStatus(theImage, &vPos);
DrawStatCompression(theImage, &vPos);
DrawStatFileFormat(theImage, &vPos);
DrawStatImageLength(theImage, &vPos);
DrawStatDisplayedSize(theImage, &vPos);
DrawStatDisplayedColors(theImage, &vPos);
DrawStatDisplayQuality(theImage, &vPos);
DrawStatDisplayTime(theImage, &vPos);
DrawStatOffscreen(theImage, &vPos);
DrawStatFree(theImage, &vPos);
if (theImage && (gThePrefs.reminderCount == 10000)) gThePrefs.reminderCount = 0;
} else DrawStatSummary(theImage, &vPos);
}
if (GetCommentsWindow() && !gStatRecord) DrawCommentsWindow();
}
/*
* DrawStatSummary(theImage, vPos)
*
* Purpose: Draws a single-line summary for given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatSummary(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) {
AddString(theVal, gString[strSummary1]);
StuffString(theVal, 1, (*theImage)->file.name);
StuffNumber(theVal, 2, (GetHandleSize((*theImage)->data) + 1023L) >> 10);
StuffString(theVal, 3, (*theImage)->format->formatName);
StuffNumber(theVal, 4, Width(&(*theImage)->crect));
StuffNumber(theVal, 5, Height(&(*theImage)->crect));
StuffDepth(theVal, 6, (*theImage)->depth);
DrawStatItem(*vPos, -1, theVal);
} else {
long temp;
AddString(theVal, gString[strFreeMemory1]);
temp = (FreeMem() + 1023 - gMemSlop) >> 10;
if (temp < 0) temp = 0;
StuffNumber(theVal, 1, temp);
DrawStatItem(*vPos, strFreeMemory, theVal);
}
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatFileName(theImage, vPos)
*
* Purpose: Draws the file name of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatFileName(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) AddString(theVal, (*theImage)->file.name);
else if (gThePrefs.reminderCount > 20) gThePrefs.reminderCount = 10000;
DrawStatItem(*vPos, strFileName, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatImageSize(theImage, vPos)
*
* Purpose: Draws the size of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatImageSize(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) {
Rect theRect = (*theImage)->grect;
if (Cropped(theImage)) AddString(theVal, gString[strImageSize2]);
else AddString(theVal, gString[strImageSize1]);
StuffNumber(theVal, 1, Width(&(*theImage)->crect));
StuffNumber(theVal, 2, Height(&(*theImage)->crect));
StuffNumber(theVal, 3, Width(&theRect));
StuffNumber(theVal, 4, Height(&theRect));
}
DrawStatItem(*vPos, strImageSize, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatImageStatus(theImage, vPos)
*
* Purpose: Draws the status of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatImageStatus(ImageHandle theImage, short *vPos)
{
Str255 theVal;
Boolean comma;
theVal[0] = 0;
if (theImage) {
comma = false;
if (Banded(theImage)) {
AddString(theVal, gString[strBanded]);
comma = true;
}
if (Cropped(theImage)) {
if (comma) {
AddChar(theVal, gListSep);
AddChar(theVal, ' ');
}
AddString(theVal, gString[strCropped]);
comma = true;
}
if (Corrupt(theImage)) {
if (comma) {
AddChar(theVal, gListSep);
AddChar(theVal, ' ');
}
AddString(theVal, gString[strCorrupt]);
comma = true;
}
if (Aborted(theImage)) {
if (comma) {
AddChar(theVal, gListSep);
AddChar(theVal, ' ');
}
AddString(theVal, gString[strAborted]);
comma = true;
}
if (!comma) AddString(theVal, gString[strNormal]);
}
DrawStatItem(*vPos, strImageStatus, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatImageColors(theImage, vPos)
*
* Purpose: Draws the depth of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatImageColors(ImageHandle theImage, short *vPos)
{
Str255 theVal;
short i;
theVal[0] = 0;
if (theImage) {
i = (*theImage)->depth;
if ((((*theImage)->depth == 8) && ((*theImage)->compression == kJPEGCompression)) || (i > 32))
AddString(theVal, gString[strImageColors2]);
else AddString(theVal, gString[strImageColors1]);
StuffDepth(theVal, 1, i);
}
DrawStatItem(*vPos, strImageColors, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatCompression(theImage, vPos)
*
* Purpose: Draws the compression type of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatCompression(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage)
BlockMove((*theImage)->compressionDesc, theVal, *(*theImage)->compressionDesc + 1);
DrawStatItem(*vPos, strCompression, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatFileFormat(theImage, vPos)
*
* Purpose: Draws the file format of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatFileFormat(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) AddString(theVal, (*theImage)->format->formatName);
DrawStatItem(*vPos, strFileFormat, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatImageLength(theImage, vPos)
*
* Purpose: Draws the image size of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatImageLength(ImageHandle theImage, short *vPos)
{
long csize, psize;
Str255 theVal;
theVal[0] = 0;
if (theImage) {
csize = GetHandleSize((*theImage)->data) << 3;
if ((*theImage)->compression) {
psize = ((*theImage)->depth == 32) ? 24 : (*theImage)->depth;
psize *= (long)Height(&(*theImage)->grect) * (long)Width(&(*theImage)->grect);
if ((csize * 5L) > psize) {
AddString(theVal, gString[strImageLength2]);
if (csize > psize) StuffNumber(theVal, 2, 0);
else StuffNumber(theVal, 2, 100L * (psize - csize) / psize);
} else {
AddString(theVal, gString[strImageLength3]);
StuffNumber(theVal, 2, psize / csize);
}
} else AddString(theVal, gString[strImageLength1]);
csize = ((csize >> 3) + 1023L) >> 10;
StuffNumber(theVal, 1, csize);
}
DrawStatItem(*vPos, strImageLength, theVal);
*vPos += (gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent) << 1;
}
/*
* DrawStatDisplayedSize(theImage, vPos)
*
* Purpose: Draws the displayed size of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatDisplayedSize(ImageHandle theImage, short *vPos)
{
long scaleX, scaleY;
Str255 theVal;
theVal[0] = 0;
if (theImage) {
if (!EqualSizeRect(&(*theImage)->wrect, &(*theImage)->crect)) {
scaleX = 200L * (long)Width(&(*theImage)->wrect) / Width(&(*theImage)->crect);
scaleX = (scaleX + 1) >> 1;
scaleY = 200L * (long)Height(&(*theImage)->wrect) / Height(&(*theImage)->crect);
scaleY = (scaleY + 1) >> 1;
if (abs(scaleX - scaleY) <= 1) {
AddString(theVal, gString[strDisplayedSize2]);
StuffNumber(theVal, 3, (scaleX + scaleY) / 2);
} else {
AddString(theVal, gString[strDisplayedSize3]);
StuffNumber(theVal, 3, scaleX);
StuffNumber(theVal, 4, scaleY);
}
} else AddString(theVal, gString[strDisplayedSize1]);
StuffNumber(theVal, 1, Width(&(*theImage)->wrect));
StuffNumber(theVal, 2, Height(&(*theImage)->wrect));
}
DrawStatItem(*vPos, strDisplayedSize, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatDisplayedColors(theImage, vPos)
*
* Purpose: Draws the displayed colors of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatDisplayedColors(ImageHandle theImage, short *vPos)
{
Str255 theVal;
short depth;
theVal[0] = 0;
if (theImage) {
depth = (*(*theImage)->dmon)->depth;
if (depth < 4 || depth > 8) {
if (Dithered(theImage)) AddString(theVal, gString[strDisplayedColors1]);
else AddString(theVal, gString[strDisplayedColors2]);
StuffDepth(theVal, 1, depth);
} else {
switch ((*theImage)->npalette) {
case plSys:
if (Dithered(theImage)) AddString(theVal, gString[strSystemColors1]);
else AddString(theVal, gString[strSystemColors2]);
break;
case plGrey:
if (Dithered(theImage)) AddString(theVal, gString[strGrayscales1]);
else AddString(theVal, gString[strGrayscales2]);
break;
case plImage:
if (Dithered(theImage)) AddString(theVal, gString[strImageColorsX1]);
else AddString(theVal, gString[strImageColorsX2]);
break;
case plQuant:
if (Dithered(theImage)) AddString(theVal, gString[strReducedColors1]);
else AddString(theVal, gString[strReducedColors2]);
break;
default:
if (Dithered(theImage)) AddString(theVal, gString[strDisplayedColors1]);
else AddString(theVal, gString[strDisplayedColors2]);
break;
}
StuffDepth(theVal, 1, depth);
}
}
DrawStatItem(*vPos, strDisplayedColors, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatDisplayQuality(theImage, vPos)
*
* Purpose: Draws the display quality of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatDisplayQuality(ImageHandle theImage, short *vPos)
{
Str255 theVal;
short depth;
theVal[0] = 0;
if (theImage) {
depth = (*(*theImage)->dmon)->depth;
if ((depth > 8) || ((depth == 8) &&
((*theImage)->npalette != plSys) && ((*theImage)->npalette != plGrey))) {
if ((*theImage)->depth >= 24) {
switch ((*theImage)->quality) {
case iqVHigh: AddString(theVal, gString[strVeryHigh]); break;
case iqHigh: if (depth < 24) {
AddString(theVal, gString[strHigh]); break;
}
case iqMedium: AddString(theVal, gString[strNormal]); break;
default: AddString(theVal, gString[strNA]);
}
} else AddString(theVal, gString[strNA]);
} else AddString(theVal, gString[strNA]);
}
DrawStatItem(*vPos, strDisplayQuality, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatDisplayTime(theImage, vPos)
*
* Purpose: Draws the display time of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatDisplayTime(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) {
if ((*theImage)->dtime) {
AddString(theVal, gString[strDisplayTime1]);
StuffNumber(theVal, 1, ((*theImage)->dtime + 50L) / 1000L);
StuffNumber(theVal, 2, (((*theImage)->dtime + 50L) / 100L) % 10L);
} else AddString(theVal, gString[strNA]);
}
DrawStatItem(*vPos, strDisplayTime, theVal);
*vPos += gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent;
}
/*
* DrawStatOffscreen(theImage, vPos)
*
* Purpose: Draws the gworld size of the given image
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatOffscreen(ImageHandle theImage, short *vPos)
{
Str255 theVal;
theVal[0] = 0;
if (theImage) {
if ((*theImage)->gworld) {
if (GWOrigSize(theImage)) AddString(theVal, gString[strOffscreenBitmap2]);
else AddString(theVal, gString[strOffscreenBitmap1]);
StuffNumber(theVal, 1, (GWorldSize((*theImage)->gworld) + 1023L) >> 10);
} else AddString(theVal, gString[strNoBitmap]);
}
DrawStatItem(*vPos, strOffscreenBitmap, theVal);
*vPos += (gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent) << 1;
}
/*
* DrawStatFree(theImage, vPos)
*
* Purpose: Draws the amount of free memory left
* Inputs: theImage = pointer to the image record
* vPos = pointer to the vertical position of the item
* Returns: nothing
*
*/
void DrawStatFree(ImageHandle theImage, short *vPos)
{
#if applec
#pragma unused(theImage)
#endif
Str255 theVal;
long temp;
theVal[0] = 0;
temp = (FreeMem() + 1023 - gMemSlop) >> 10;
if (temp < 0) temp = 0;
AddString(theVal, gString[strFreeMemory1]);
StuffNumber(theVal, 1, temp);
DrawStatItem(*vPos, strFreeMemory, theVal);
*vPos += (gStatFontInfo.ascent + gStatFontInfo.leading + gStatFontInfo.descent) << 1;
}
/*
* DrawStatItem()
*
* Purpose: Draws a given string in the statistics window, clearing off any old text
* Inputs: vPos = the vertical position of the item
* item = the item number
* theNum = the new value of the item
* Returns: nothing
*
*/
void DrawStatItem(short vPos, short item, StringPtr theNum)
{
short rectItem = gThePrefs.statsZoomed ? item - strFileName : 0;
uchar *theName;
Rect theRect;
gStatRect[rectItem].top = vPos - gStatFontInfo.ascent - gStatFontInfo.leading;
gStatRect[rectItem].bottom = vPos + gStatFontInfo.descent;
if (gThePrefs.statsZoomed) {
TextFace(bold);
gStatRect[rectItem].left = gStatFontInfo.widMax - StringWidth(gString[item]);
MoveTo(gStatRect[rectItem].left, vPos);
if (gStatRecord) BlockMove(&gString[item][1], &gStatRecord[gStatLength], *gString[item]), gStatLength += *gString[item];
else DrawString(gString[item]);
} else {
gStatRect[rectItem].left = 3;
TextFace(bold);
MoveTo(gStatRect[rectItem].left, vPos);
if (item != -1) {
if (gStatRecord) BlockMove(&gString[item][1], &gStatRecord[gStatLength], *gString[item]), gStatLength += *gString[item];
else DrawString(gString[item]);
} else {
short oldLen = *theNum;
theName = theNum++;
*theName = 1;
while (*theNum++ != ':') (*theName)++;
*theNum = oldLen - *theName - 1;
if (gStatRecord) BlockMove(&theName[1], &gStatRecord[gStatLength], *theName), gStatLength += *theName;
else DrawString(theName);
}
if (gStatRecord) gStatRecord[gStatLength++] = ' ';
else DrawChar(' ');
}
if (gThePrefs.statsZoomed) theRect.left = gStatFontInfo.widMax + 3;
else if (item == -1) theRect.left = 3 + StringWidth(theName) + CharWidth(' ');
else theRect.left = 3 + StringWidth(gString[item]) + CharWidth(' ');
theRect.right = gStatWindow->portRect.right;
theRect.top = vPos - gStatFontInfo.ascent;
theRect.bottom = vPos + gStatFontInfo.descent;
if (theNum[0]) {
TextFace(normal);
MoveTo(theRect.left, vPos);
if (gStatRecord) BlockMove(&theNum[1], &gStatRecord[gStatLength], *theNum), gStatLength += *theNum;
else DrawString(theNum);
theRect.left += StringWidth(theNum);
} else if (gThePrefs.reminderCount == 10000) {
TextFace(normal);
if (!gStatRecord) EraseRect(&theRect);
theRect.left += (Width(&theRect) - StringWidth(gString[strNagMessages + item])) >> 1;
MoveTo(theRect.left, vPos);
if (gStatRecord) BlockMove(&gString[strNagMessages + item][1], &gStatRecord[gStatLength], *gString[strNagMessages + item]),
gStatLength += *gString[strNagMessages + item];
else DrawString(gString[strNagMessages + item]);
theRect.left = theRect.right;
} else theRect.left = gStatFontInfo.widMax;
gStatRect[rectItem].right = theRect.left;
if (!gStatRecord) EraseRect(&theRect);
if (gStatRecord) gStatRecord[gStatLength++] = '\r';
if (gStatRegion) {
RgnHandle tempRgn = NewRgn();
if (tempRgn) {
RectRgn(tempRgn, &gStatRect[rectItem]);
UnionRgn(gStatRegion, tempRgn, gStatRegion);
DisposeRgn(tempRgn);
}
}
}
extern void IdleCredits(void)
{
ImageHandle theImage = nil;
WindowPtr theWindow;
if (!gStatWindow) return;
for (theWindow = GetFirstWindow(); theWindow && !(theImage = FindImage(theWindow));
theWindow = NextWindow(theWindow));
if (theImage && IsAboutBox(theImage) && gCreditsTE) {
PushPort();
MySetPort((CGrafPtr)gStatWindow);
CalcVis((WindowPeek)gStatWindow);
if (((*gCreditsTE)->viewRect.top - (*gCreditsTE)->destRect.top) >= gCreditsHeight)
TEScroll(0, (*gCreditsTE)->viewRect.top - (*gCreditsTE)->destRect.top, gCreditsTE);
else TEScroll(0, -1, gCreditsTE);
PopPort();
}
}
extern void HandleStatClick(EventRecord *theEvent)
{
Point localPt = theEvent->where;
PushPort();
MySetPort((CGrafPtr)gStatWindow);
GlobalToLocal(&localPt);
PopPort();
if (gStatRegion && PtInRgn(localPt, gStatRegion) && gDragMgrPresent && WaitMouseMoved(theEvent->where)) {
RgnHandle theRgn = NewRgn(), tempRgn = NewRgn();
DragReference theDrag;
char statText[1024];
OSErr theErr;
if (theRgn && tempRgn) {
theErr = NewDrag(&theDrag);
if (theErr == noErr) {
gStatRecord = statText;
gStatLength = 0;
PushPort();
MySetPort((CGrafPtr)gStatWindow);
DrawStatWindow();
PopPort();
gStatRecord = nil;
AddDragItemFlavor(theDrag, (ItemReference)statText, 'TEXT', statText, gStatLength, 0);
CopyRgn(gStatRegion, theRgn);
GlobalRgn(theRgn, gStatWindow);
CopyRgn(theRgn, tempRgn);
InsetRgn(tempRgn, 1, 1);
DiffRgn(theRgn, tempRgn, theRgn);
SetDragItemBounds(theDrag, (ItemReference)statText, &(*theRgn)->rgnBBox);
SetCursor(&qd.arrow);
theErr = TrackDrag(theDrag, theEvent, theRgn);
DisposeDrag(theDrag);
}
}
if (theRgn) DisposeRgn(theRgn);
if (tempRgn) DisposeRgn(tempRgn);
} else if (FrontWindow() != gStatWindow) SendMoveToFront(gStatWindow);
}
/*
* DoStatsHelp(globalPt)
*
* Purpose: Pops up help for the statistics windoid; needed because it should be displayed even
* if it's not "active"
* Inputs: globalPt = point, in global coordinates, where the mouse is
* Returns: nothing
*
*/
void DoStatsHelp(Point globalPt)
{
static Boolean gLastWasGeneric = false;
Boolean balloonUp = HMIsBalloon();
HMMessageRecord theRecord;
short index = 1, line;
ImageHandle theImage;
Point tip = { 0, 0 };
WindowPtr theWindow;
Rect aRect;
if ((balloonUp && !gLastWasGeneric) || gInBackground) return;
PushPort();
MySetPort((CGrafPtr)gStatWindow);
GlobalToLocal(&globalPt);
for (theWindow = GetFirstWindow(); theWindow && !(theImage = FindImage(theWindow));
theWindow = NextWindow(theWindow));
if (theImage && IsAboutBox(theImage)) index = 2;
else if (gThePrefs.statsZoomed) {
index = 3;
for (line = 0; line <= (strFreeMemory - strFileName); line++)
if (PtInRect(globalPt, &gStatRect[line])) {
index = line + 4;
break;
}
} else index = 1;
if (gLastWasGeneric && index <= 3 && balloonUp) {
PopPort();
return;
}
if (gLastWasGeneric = (index <= 3)) aRect = gStatWindow->portRect;
else aRect = gStatRect[line];
if (balloonUp) HMRemoveBalloon();
if (HMExtractHelpMsg(kHMRectListResType, rStatWindow, index, kHMEnabledItem, &theRecord) == noErr) {
tip.h = aRect.right;
tip.v = aRect.top + Height(&aRect) / 2;
LocalToGlobal(&tip);
GlobalRect(&aRect, gStatWindow);
HMShowBalloon(&theRecord, tip, &aRect, nil, 0, 0, kHMRegularWindow);
}
PopPort();
}