mirror of
https://github.com/aaronsgiles/JPEGView.git
synced 2024-06-06 21:29:27 +00:00
92bdb55672
These are the sources for the final official release of JPEGView for the Mac, back in 1994.
1 line
15 KiB
C
1 line
15 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
|
|
|
|
//=====================================================================================
|
|
// void IsDialogWindow(WindowPtr theWindow)
|
|
//
|
|
// Returns true if the window is a dialog window.
|
|
//
|
|
// External calls: none
|
|
//=====================================================================================
|
|
|
|
extern Boolean IsDialogWindow(WindowPtr theWindow)
|
|
{
|
|
return theWindow ? (WindowKind(theWindow) == dialogKind) : false;
|
|
}
|
|
|
|
/*
|
|
* CenterWindow(theWindow)
|
|
*
|
|
* Purpose: Determines where a centered dialog should be placed
|
|
* Inputs: theWindow = a pointer to the dialog window
|
|
* Returns: the centered location
|
|
*
|
|
*/
|
|
|
|
Point CenterWindow(WindowPtr theWindow)
|
|
{
|
|
short var = GetWVariant(theWindow), height = Height(&theWindow->portRect);
|
|
Point thePos;
|
|
Rect theRect;
|
|
|
|
if (var != dBoxProc) height += gTitleBarHeight;
|
|
switch (gThePrefs.openScreen) {
|
|
case osDeepest:
|
|
GetActiveRect(GetDeepMonitor(gThePrefs.pickColor), &theRect);
|
|
break;
|
|
case osLargest:
|
|
GetActiveRect(GetBigMonitor(gThePrefs.pickColor), &theRect);
|
|
break;
|
|
case osMain:
|
|
GetActiveRect(gMainMonitor, &theRect);
|
|
break;
|
|
}
|
|
thePos.h = Width(&theRect) - Width(&theWindow->portRect);
|
|
thePos.v = Height(&theRect) - height;
|
|
thePos.h /= 2;
|
|
thePos.v /= 3;
|
|
thePos.h += theRect.left;
|
|
thePos.v += theRect.top;
|
|
if (var != dBoxProc) thePos.v += gTitleBarHeight;
|
|
return thePos;
|
|
}
|
|
|
|
/*
|
|
* GetMouseGDRect(theRect)
|
|
*
|
|
* Purpose: Gets the Rect of the device where the mouse is
|
|
* Inputs: theRect = pointer to the rect to be filled
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void GetMouseGDRect(Rect *theRect)
|
|
{
|
|
GDHandle theDevice = GetDeviceList();
|
|
Point thePoint = GlobalMouse();
|
|
|
|
*theRect = qd.screenBits.bounds;
|
|
while (theDevice) {
|
|
if (TestDeviceAttribute(theDevice, screenDevice) &&
|
|
TestDeviceAttribute(theDevice, screenActive) &&
|
|
PtInRect(thePoint, &(*theDevice)->gdRect)) {
|
|
*theRect = (*theDevice)->gdRect;
|
|
if (theDevice == GetMainDevice()) theRect->top += GetMBarHeight();
|
|
}
|
|
theDevice = GetNextDevice(theDevice);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* MouseCenterRect(theRect)
|
|
*
|
|
* Purpose: Centers the given Rect on the screen where the mouse is
|
|
* Inputs: theRect = pointer to the rect to be filled
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void MouseCenterRect(Rect *theRect)
|
|
{
|
|
Point thePoint = GlobalMouse();
|
|
GDHandle theDevice;
|
|
Rect devRect;
|
|
|
|
MySetRect(&devRect, thePoint.h, thePoint.v, thePoint.h + 1, thePoint.v + 1);
|
|
theDevice = GetMaxDevice(&devRect);
|
|
if (theDevice) {
|
|
devRect = (*theDevice)->gdRect;
|
|
OffsetRect(theRect, (Width(&devRect) - Width(theRect)) / 2 + devRect.left - theRect->left,
|
|
(Height(&devRect) - Height(theRect)) / 3 + devRect.top - theRect->top);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* CenterAlert(id)
|
|
*
|
|
* Purpose: Loads and centers the given alert resource
|
|
* Inputs: id = the resource ID of the alert
|
|
* Returns: the ID, to be passed to Alert()
|
|
*
|
|
*/
|
|
|
|
short CenterAlert(short id)
|
|
{
|
|
Handle theHandle = GetResource('ALRT', id);
|
|
|
|
if (theHandle) {
|
|
HLock(theHandle);
|
|
MouseCenterRect((Rect *)*theHandle);
|
|
HUnlock(theHandle);
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/*
|
|
* CenterDialog(id)
|
|
*
|
|
* Purpose: Loads and centers the given dialog resource
|
|
* Inputs: id = the resource ID of the dialog
|
|
* Returns: the ID, to be passed to GetNewDialog()
|
|
*
|
|
*/
|
|
|
|
short CenterDialog(short id)
|
|
{
|
|
Handle theHandle = GetResource('DLOG', id);
|
|
|
|
if (theHandle) {
|
|
HLock(theHandle);
|
|
MouseCenterRect((Rect *)*theHandle);
|
|
HUnlock(theHandle);
|
|
}
|
|
return id;
|
|
}
|
|
|
|
/*
|
|
* CenterDialogWhere(id)
|
|
*
|
|
* Purpose: Loads and centers the given dialog resource
|
|
* Inputs: id = the resource ID of the dialog
|
|
* Returns: a point giving the location for the dialog
|
|
*
|
|
*/
|
|
|
|
Point CenterDialogWhere(short id)
|
|
{
|
|
Handle theHandle = GetResource('DLOG', id);
|
|
|
|
if (theHandle) {
|
|
HLock(theHandle);
|
|
MouseCenterRect((Rect *)*theHandle);
|
|
HUnlock(theHandle);
|
|
}
|
|
return *(Point *)*theHandle;
|
|
}
|
|
|
|
extern void UpdateParamText(StringPtr string1, StringPtr string2, StringPtr string3,
|
|
StringPtr string4)
|
|
{
|
|
static Str255 gOldString1 = "", gOldString4 = "";
|
|
WindowPtr theWindow = FWFrontWindow();
|
|
|
|
ParamText(string1, string2, string3, string4);
|
|
if (theWindow && GetWRefCon(theWindow) == kProgressDialogID) {
|
|
if (!EqualString(string1, gOldString1, true, true))
|
|
UpdateDialogItem(theWindow, progressText);
|
|
if (!EqualString(string4, gOldString4, true, true))
|
|
UpdateDialogItem(theWindow, progressText2);
|
|
}
|
|
BlockMove(string1, gOldString1, *string1 + 1);
|
|
BlockMove(string4, gOldString4, *string4 + 1);
|
|
}
|
|
|
|
extern short HandleDialogLetterKey(DialogPtr theDialog, char theChar)
|
|
{
|
|
short itemCount, itemType, theItem;
|
|
Handle itemHandle;
|
|
Str255 theTitle;
|
|
Rect itemRect;
|
|
long ticks;
|
|
|
|
if (theChar > 'a') theChar -= 'a' - 'A';
|
|
itemCount = CountDITL(theDialog);
|
|
for (theItem = 1; theItem <= itemCount; theItem++) {
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
if (itemType == (ctrlItem + btnCtrl)) {
|
|
GetCTitle((ControlHandle)itemHandle, theTitle);
|
|
if (theChar == theTitle[1]) {
|
|
HiliteControl((ControlHandle)itemHandle, true);
|
|
Delay(8, &ticks);
|
|
HiliteControl((ControlHandle)itemHandle, false);
|
|
return theItem;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
extern short HandleDialogCancelKey(DialogPtr theDialog)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
long ticks;
|
|
|
|
GetDItem(theDialog, 3, &itemType, &itemHandle, &itemRect);
|
|
if (itemType == (ctrlItem + btnCtrl)) {
|
|
HiliteControl((ControlHandle)itemHandle, true);
|
|
Delay(8, &ticks);
|
|
HiliteControl((ControlHandle)itemHandle, false);
|
|
return kDialogCancel;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
extern short HandleDialogOKKey(DialogPtr theDialog)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
long ticks;
|
|
|
|
GetDItem(theDialog, 1, &itemType, &itemHandle, &itemRect);
|
|
if (itemType == (ctrlItem + btnCtrl)) {
|
|
HiliteControl((ControlHandle)itemHandle, true);
|
|
Delay(8, &ticks);
|
|
HiliteControl((ControlHandle)itemHandle, false);
|
|
return kDialogOK;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* GenericFilter(theDialog, theEvent, itemHit)
|
|
*
|
|
* Purpose: Generic filter returns item 1 for return/enter, and item 3 for Cmd-.
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theEvent = pointer to an event record
|
|
* itemHit = the item number that was "hit"
|
|
* Returns: true if we want ModalDialog to continue processing the event
|
|
*
|
|
*/
|
|
|
|
pascal Boolean GenericFilter(DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
|
|
{
|
|
Boolean isCmdKey, isCancelKey, isOKKey, isDialogEvent = IsDialogEvent(theEvent);
|
|
short theItem = 0;
|
|
char theChar;
|
|
|
|
if ((theEvent->what == updateEvt) && ((WindowPtr)theEvent->message == FWFrontWindow()))
|
|
return false;
|
|
switch (theEvent->what) {
|
|
case activateEvt:
|
|
if (isDialogEvent) HandleActivateDialog(theEvent);
|
|
else HandleActivateEvent(theEvent);
|
|
break;
|
|
case updateEvt:
|
|
if (isDialogEvent) HandleUpdateDialog(theEvent);
|
|
else HandleUpdateEvent(theEvent);
|
|
break;
|
|
case diskEvt:
|
|
HandleDiskEvent(theEvent);
|
|
break;
|
|
case keyDown:
|
|
theChar = theEvent->message & charCodeMask;
|
|
isCmdKey = (theEvent->modifiers & cmdKey) != 0;
|
|
isCancelKey = (theChar == kEscapeChar) || (isCmdKey && theChar == '.');
|
|
isOKKey = (theChar == kReturnChar || theChar == kEnterChar);
|
|
if ((theChar >= 'A' && theChar <= 'Z') || (theChar >= 'a' && theChar <= 'z'))
|
|
theItem = HandleDialogLetterKey(theDialog, theChar);
|
|
else if (isCancelKey) theItem = HandleDialogCancelKey(theDialog);
|
|
else if (isOKKey) theItem = HandleDialogOKKey(theDialog);
|
|
break;
|
|
}
|
|
if (theItem) *itemHit = theItem;
|
|
return (theItem != 0);
|
|
}
|
|
|
|
/*
|
|
* OutlineOK(theDialog, theItem)
|
|
*
|
|
* Purpose: Generic handler to outline the default (OK) button
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = presumably the item number of the dummy user item
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
pascal void OutlineOK(DialogPtr theDialog, short theItem)
|
|
{
|
|
WindowPtr frontWindow = FWFrontWindow();
|
|
RGBColor grayColor, fgColor, bgColor;
|
|
ControlHandle itemHandle;
|
|
short itemType;
|
|
short diameter;
|
|
Rect itemRect;
|
|
|
|
PushPort();
|
|
MySetPort((CGrafPtr)theDialog);
|
|
GetDItem(theDialog, theItem - 1, &itemType, (Handle *)&itemHandle, &itemRect);
|
|
if ((diameter = (itemRect.bottom - itemRect.top) / 2) < 16) diameter = 16;
|
|
PenSize(3, 3);
|
|
InsetRect(&itemRect, -4, -4);
|
|
if ((*itemHandle)->contrlHilite == 255 || theDialog != frontWindow || gInBackground) {
|
|
GetBackColor(&bgColor);
|
|
GetForeColor(&fgColor);
|
|
grayColor = fgColor;
|
|
GetGray(GetGDevice(), &bgColor, &grayColor);
|
|
RGBForeColor(&grayColor);
|
|
FrameRoundRect(&itemRect, diameter, diameter);
|
|
RGBForeColor(&fgColor);
|
|
} else FrameRoundRect(&itemRect, diameter, diameter);
|
|
PopPort();
|
|
}
|
|
|
|
extern pascal void PopUpMenuBox(DialogPtr theDialog, short theItem)
|
|
{
|
|
RgnHandle minusRgn, oldClip;
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
if (minusRgn = NewRgn()) {
|
|
if (oldClip = NewRgn()) {
|
|
GetClip(oldClip);
|
|
ClipRect(&theDialog->portRect);
|
|
GetDItem(theDialog, theItem - 1, &itemType, &itemHandle, &itemRect);
|
|
RectRgn(minusRgn, &itemRect);
|
|
DiffRgn(theDialog->clipRgn, minusRgn, theDialog->clipRgn);
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
PenPat(&qd.gray);
|
|
PenSize(1, 1);
|
|
FrameRect(&itemRect);
|
|
PenPat(&qd.black);
|
|
SetClip(oldClip);
|
|
DisposeRgn(oldClip);
|
|
}
|
|
DisposeRgn(minusRgn);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* LineItem(theDialog, theItem)
|
|
*
|
|
* Purpose: Generic handler to draw a line in a dialog box
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = presumably the item number of the line item
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
pascal void LineItem(DialogPtr theDialog, short theItem)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
PushPort();
|
|
MySetPort((CGrafPtr)theDialog);
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
PenSize(1, 1);
|
|
MoveTo(itemRect.left, itemRect.top);
|
|
if ((itemRect.right - itemRect.left) < (itemRect.bottom - itemRect.top))
|
|
LineTo(itemRect.left, itemRect.bottom);
|
|
else
|
|
LineTo(itemRect.right, itemRect.top);
|
|
PopPort();
|
|
}
|
|
|
|
/*
|
|
* SetItemHandle(theDialog, theItem, newHandle)
|
|
*
|
|
* Purpose: Change the handle of a dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* newHandle = the handle we'd like to change to
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void SetItemHandle(DialogPtr theDialog, short theItem, Handle newHandle)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
SetDItem(theDialog, theItem, itemType, newHandle, &itemRect);
|
|
}
|
|
|
|
/*
|
|
* DisableDControl(theDialog, theItem)
|
|
*
|
|
* Purpose: Disables the control of a particular dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void DisableDControl(DialogPtr theDialog, short theItem)
|
|
{
|
|
PenState oldState;
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
PushPort();
|
|
MySetPort((CGrafPtr)theDialog);
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
itemType &= 0x7f;
|
|
if (itemType == editText || itemType == statText) {
|
|
Boolean bw = !(((CGrafPtr)theDialog)->portVersion & 0x8000) ||
|
|
(*((CGrafPtr)theDialog)->portPixMap)->pixelSize == 1;
|
|
RGBColor fgColor;
|
|
FontInfo theInfo;
|
|
Str255 theText;
|
|
|
|
if (itemRect.left > 8191) OffsetRect(&itemRect, -16384, 0);
|
|
HideDItem(theDialog, theItem);
|
|
GetIText(itemHandle, theText);
|
|
GetFontInfo(&theInfo);
|
|
TextMode(grayishTextOr);
|
|
MoveTo(itemRect.left + 1, itemRect.top + theInfo.ascent);
|
|
DrawString(theText);
|
|
TextMode(srcCopy);
|
|
if (itemType == editText) {
|
|
GetPenState(&oldState);
|
|
PenSize(1, 1);
|
|
PenMode(srcOr);
|
|
if (bw) PenPat(&qd.gray);
|
|
else {
|
|
RGBColor grayColor, bgColor;
|
|
GetBackColor(&bgColor);
|
|
GetForeColor(&fgColor);
|
|
grayColor = fgColor;
|
|
GetGray(GetGDevice(), &bgColor, &grayColor);
|
|
RGBForeColor(&grayColor);
|
|
}
|
|
InsetRect(&itemRect, -3, -3);
|
|
FrameRect(&itemRect);
|
|
if (!bw) RGBForeColor(&fgColor);
|
|
else SetPenState(&oldState);
|
|
}
|
|
} else HiliteControl((ControlHandle)itemHandle, 255);
|
|
PopPort();
|
|
}
|
|
|
|
/*
|
|
* EnableDControl(theDialog, theItem)
|
|
*
|
|
* Purpose: Enables the control of a particular dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void EnableDControl(DialogPtr theDialog, short theItem)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
PushPort();
|
|
MySetPort((CGrafPtr)theDialog);
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
itemType &= 0x7f;
|
|
if (itemType == editText || itemType == statText) ShowDItem(theDialog, theItem);
|
|
else HiliteControl((ControlHandle)itemHandle, 0);
|
|
PopPort();
|
|
}
|
|
|
|
/*
|
|
* SetDCtlValue(theDialog, theItem, theValue)
|
|
*
|
|
* Purpose: Sets the value of the control of a particular dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* theValue = the new value for that control
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void SetDCtlValue(DialogPtr theDialog, short theItem, short theValue)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
SetCtlValue((ControlHandle)itemHandle, theValue);
|
|
}
|
|
|
|
/*
|
|
* GetDCtlValue(theDialog, theItem, theValue)
|
|
*
|
|
* Purpose: Gets the value of the control of a particular dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* Returns: the value of the control
|
|
*
|
|
*/
|
|
|
|
short GetDCtlValue(DialogPtr theDialog, short theItem)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
return GetCtlValue((ControlHandle)itemHandle);
|
|
}
|
|
|
|
/*
|
|
* SetDIText(theDialog, theItem, theText)
|
|
*
|
|
* Purpose: Sets the text of an editable text dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* theText = a pointer to the new text
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void SetDIText(DialogPtr theDialog, short theItem, Str255 theText)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
SetIText(itemHandle, theText);
|
|
}
|
|
|
|
/*
|
|
* GetDIText(theDialog, theItem, theText)
|
|
*
|
|
* Purpose: Gets the text of an editable text dialog item
|
|
* Inputs: theDialog = pointer to the dialog
|
|
* theItem = the item number we're interested in
|
|
* theText = a pointer to the text field
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void GetDIText(DialogPtr theDialog, short theItem, Str255 theText)
|
|
{
|
|
Handle itemHandle;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
GetIText(itemHandle, theText);
|
|
}
|
|
|
|
void UpdateDialogItem(DialogPtr theDialog, short theItem)
|
|
{
|
|
Handle itemHandle;
|
|
RgnHandle theRgn;
|
|
short itemType;
|
|
Rect itemRect;
|
|
|
|
if (theRgn = NewRgn()) {
|
|
PushPort();
|
|
MySetPort((CGrafPtr)theDialog);
|
|
GetDItem(theDialog, theItem, &itemType, &itemHandle, &itemRect);
|
|
RectRgn(theRgn, &itemRect);
|
|
UpdateDialog(theDialog, theRgn);
|
|
PopPort();
|
|
DisposeRgn(theRgn);
|
|
}
|
|
}
|