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
10 KiB
C
1 line
10 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:
|
|
* gCommentsFontInfo = the font information for the comments window font (Geneva 9pt)
|
|
* gCommentsWindow = pointer to the statistics window
|
|
* gCommentsImage = handle of the image whose comments we're showing
|
|
* gCommentsTextEdit = handle to the TextEdit record
|
|
* gCommentsRect = the rect of the TextEdit record
|
|
*
|
|
*/
|
|
|
|
static WindowPtr gCommentsWindow = nil;
|
|
static FontInfo gCommentsFontInfo;
|
|
static ImageHandle gCommentsImage = (ImageHandle)-1;
|
|
static TEHandle gCommentsTextEdit = nil;
|
|
static Rect gCommentsRect = { 0, 0, 10, 400 };
|
|
|
|
/*
|
|
* OpenComments()
|
|
*
|
|
* Purpose: Creates and initializes the comments window
|
|
* Inputs: none
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
OSErr OpenComments(void)
|
|
{
|
|
Rect theRect, mainRect;
|
|
OSErr theErr = noErr;
|
|
Point where;
|
|
|
|
if (gCommentsWindow) {
|
|
if (!WindowVisible(gCommentsWindow)) FWShowWindow(gCommentsWindow);
|
|
return noErr;
|
|
}
|
|
if (!(gCommentsWindow = AllocateWindow())) return memFullErr;
|
|
PushPort();
|
|
MySetPort(nil);
|
|
if (gCommentsWindow = FWGetNewFloatingWindow(rCommentsWindow, (Ptr)gCommentsWindow,
|
|
(WindowPtr)-1)) {
|
|
MySetPort((CGrafPtr)gCommentsWindow);
|
|
TextFont(geneva);
|
|
TextSize(9);
|
|
TextMode(srcCopy);
|
|
TextFace(0);
|
|
GetFontInfo(&gCommentsFontInfo);
|
|
InsetRect(&gCommentsRect, 3, 0);
|
|
gCommentsTextEdit = TENew(&gCommentsRect, &gCommentsRect);
|
|
InsetRect(&gCommentsRect, -3, 0);
|
|
if (gCommentsTextEdit) {
|
|
(*gCommentsTextEdit)->txFont = geneva;
|
|
(*gCommentsTextEdit)->txSize = 9;
|
|
if (Width(&gThePrefs.commentsBounds) && Height(&gThePrefs.commentsBounds))
|
|
SizeWindow(gCommentsWindow, Width(&gThePrefs.commentsBounds),
|
|
Height(&gThePrefs.commentsBounds), false);
|
|
theRect = gCommentsWindow->portRect;
|
|
OffsetRect(&theRect, -theRect.left, -theRect.top);
|
|
if (gThePrefs.commentsBounds.top != gThePrefs.commentsBounds.bottom) {
|
|
gThePrefs.commentsBounds.right = gThePrefs.commentsBounds.left + Width(&theRect);
|
|
gThePrefs.commentsBounds.bottom = gThePrefs.commentsBounds.top + Height(&theRect);
|
|
}
|
|
GetActiveRect(gMainMonitor, &mainRect);
|
|
where.h = mainRect.right - kWindowBorderWidth - theRect.right;
|
|
where.v = mainRect.bottom - kWindowBorderHeight - theRect.bottom;
|
|
PlaceWindow(gCommentsWindow, &gThePrefs.commentsBounds, where);
|
|
DrawCommentsWindow();
|
|
gThePrefs.commentsOpen = true;
|
|
PopPort();
|
|
return noErr;
|
|
} else theErr = memFullErr;
|
|
} else theErr = memFullErr;
|
|
CloseComments();
|
|
PopPort();
|
|
return theErr;
|
|
}
|
|
|
|
/*
|
|
* CloseComments()
|
|
*
|
|
* Purpose: Closes the comment window
|
|
* Inputs: none
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void CloseComments(void)
|
|
{
|
|
PushPort();
|
|
MySetPort(nil);
|
|
if (gCommentsTextEdit) {
|
|
TEDispose(gCommentsTextEdit);
|
|
gCommentsTextEdit = nil;
|
|
}
|
|
if (gCommentsWindow) {
|
|
gThePrefs.commentsOpen = false;
|
|
SaveWindowPosition(gCommentsWindow, &gThePrefs.commentsBounds);
|
|
FWCloseWindow(gCommentsWindow);
|
|
DeallocateWindow(gCommentsWindow);
|
|
}
|
|
gCommentsWindow = nil;
|
|
gCommentsImage = (ImageHandle)-1;
|
|
PopPort();
|
|
}
|
|
|
|
/*
|
|
* NudgeComments(Rect *oldRect)
|
|
*
|
|
* Purpose: Nudges the comments window so it is fully visible on-screen
|
|
* Inputs: none
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void NudgeComments(Rect *oldRect)
|
|
{
|
|
Boolean top = false, left = false;
|
|
MonitorHandle theMonitor;
|
|
Rect theRect, monRect;
|
|
|
|
if (gCommentsWindow) {
|
|
theRect = gCommentsWindow->portRect;
|
|
GlobalRect(&theRect, gCommentsWindow);
|
|
GlobalRect(oldRect, gCommentsWindow);
|
|
if (theMonitor = GetMostDevice(&theRect)) {
|
|
GetActiveRect(theMonitor, &monRect);
|
|
monRect.top += 11; // account for titlebar -- contact from Inf. Windoid code
|
|
if ((oldRect->left - monRect.left) < (monRect.right - oldRect->right))
|
|
left = true;
|
|
if ((oldRect->top - monRect.top) < (monRect.bottom - oldRect->bottom))
|
|
top = true;
|
|
if (top)
|
|
OffsetRect(&theRect, 0, monRect.top + kWindowBorderHeight - theRect.top);
|
|
else OffsetRect(&theRect, 0, monRect.bottom - kWindowBorderHeight - theRect.bottom);
|
|
if (left)
|
|
OffsetRect(&theRect, monRect.left + kWindowBorderWidth - theRect.left, 0);
|
|
else OffsetRect(&theRect, monRect.right - kWindowBorderWidth - theRect.right, 0);
|
|
FWMoveWindow(gCommentsWindow, theRect.left, theRect.top, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* GetCommentsWindow()
|
|
*
|
|
* Purpose: Returns a pointer to the statistics window
|
|
* Inputs: none
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
WindowPtr GetCommentsWindow(void)
|
|
{
|
|
return gCommentsWindow;
|
|
}
|
|
|
|
/*
|
|
* DrawCommentsWindow()
|
|
*
|
|
* Purpose: Draws the statistics window
|
|
* Inputs: none
|
|
* Returns: nothing
|
|
*
|
|
*/
|
|
|
|
void DrawCommentsWindow(void)
|
|
{
|
|
short width, maxwidth = 110, start, end, i;
|
|
Boolean autoComments = (!gSlideShow && gThePrefs.autoComments) ||
|
|
(gSlideShow && (*gSlideOptions)->autoComments);
|
|
Rect theRect, tempRect, oldRect;
|
|
MonitorHandle theMonitor;
|
|
ImageHandle theImage;
|
|
WindowPtr theWindow;
|
|
Boolean wasVisible;
|
|
|
|
if (!gCommentsWindow) return;
|
|
wasVisible = WindowVisible(gCommentsWindow);
|
|
oldRect = gCommentsWindow->portRect;
|
|
PushPort();
|
|
MySetPort((CGrafPtr)gCommentsWindow);
|
|
for (theWindow = GetFirstWindow(); theWindow && !(theImage = FindImage(theWindow));
|
|
theWindow = NextWindow(theWindow));
|
|
if (autoComments && (!theImage || !(*theImage)->comments)) {
|
|
if ((!gSlideShow && !gCommentsOpen) || gSlideShow) {
|
|
PopPort();
|
|
CloseComments();
|
|
return;
|
|
}
|
|
}
|
|
if (theImage != gCommentsImage) {
|
|
FWHideWindow(gCommentsWindow);
|
|
gCommentsImage = theImage;
|
|
TESetSelect(0, 32767, gCommentsTextEdit);
|
|
TEDelete(gCommentsTextEdit);
|
|
TEScroll(0, (*gCommentsTextEdit)->viewRect.top - (*gCommentsTextEdit)->destRect.top,
|
|
gCommentsTextEdit);
|
|
if (theImage && (*theImage)->comments) {
|
|
HLock((*theImage)->comments);
|
|
TEInsert(*(*theImage)->comments, GetHandleSize((*theImage)->comments),
|
|
gCommentsTextEdit);
|
|
HUnlock((*theImage)->comments);
|
|
(*gCommentsTextEdit)->viewRect.bottom =
|
|
(*gCommentsTextEdit)->viewRect.top +
|
|
(*gCommentsTextEdit)->lineHeight *
|
|
(*gCommentsTextEdit)->nLines + gCommentsFontInfo.descent;
|
|
tempRect = gCommentsWindow->portRect;
|
|
GlobalRect(&tempRect, gCommentsWindow);
|
|
theMonitor = GetMostDevice(&tempRect);
|
|
GetActiveRect(theMonitor, &tempRect);
|
|
tempRect.top += 11 + 2 * kWindowBorderHeight;
|
|
if (Height(&(*gCommentsTextEdit)->viewRect) > Height(&tempRect))
|
|
(*gCommentsTextEdit)->viewRect.bottom =
|
|
(*gCommentsTextEdit)->viewRect.top + Height(&tempRect);
|
|
} else {
|
|
(*gCommentsTextEdit)->viewRect.bottom =
|
|
(*gCommentsTextEdit)->viewRect.top +
|
|
(*gCommentsTextEdit)->lineHeight + gCommentsFontInfo.descent;
|
|
TEInsert(&gString[strNoComments][1], *gString[strNoComments],
|
|
gCommentsTextEdit);
|
|
}
|
|
theRect = (*gCommentsTextEdit)->viewRect;
|
|
InsetRect(&theRect, -3, 0);
|
|
for (i = 0; i < (*gCommentsTextEdit)->nLines; i++) {
|
|
uchar *text;
|
|
start = (*gCommentsTextEdit)->lineStarts[i];
|
|
end = (*gCommentsTextEdit)->lineStarts[i + 1] - 1;
|
|
text = (uchar *)*(*gCommentsTextEdit)->hText + end;
|
|
while (*text < 0x20) text--, end--;
|
|
if (end > start) {
|
|
HLock((Handle)(*gCommentsTextEdit)->hText);
|
|
width = TextWidth(*(*gCommentsTextEdit)->hText, start, end - start + 1);
|
|
HUnlock((Handle)(*gCommentsTextEdit)->hText);
|
|
}
|
|
if (width > maxwidth) maxwidth = width;
|
|
}
|
|
SizeWindow(gCommentsWindow, maxwidth + 6, Height(&theRect), true);
|
|
if (autoComments) NudgeComments(&oldRect);
|
|
if (wasVisible) {
|
|
FWSelectWindow(gCommentsWindow);
|
|
FWShowWindow(gCommentsWindow);
|
|
}
|
|
}
|
|
PopPort();
|
|
}
|
|
|
|
void UpdateCommentsWindow(void)
|
|
{
|
|
Rect theRect;
|
|
|
|
if (!gCommentsWindow) return;
|
|
PushPort();
|
|
MySetPort((CGrafPtr)gCommentsWindow);
|
|
theRect = (*gCommentsTextEdit)->viewRect;
|
|
TEUpdate(&theRect, gCommentsTextEdit);
|
|
PopPort();
|
|
}
|
|
|
|
extern void HandleCommentsClick(EventRecord *theEvent)
|
|
{
|
|
if (gDragMgrPresent && WaitMouseMoved(theEvent->where)) {
|
|
RgnHandle theRgn = NewRgn(), tempRgn = NewRgn();
|
|
DragReference theDrag;
|
|
Handle textHandle;
|
|
Rect startRect;
|
|
OSErr theErr;
|
|
char hState;
|
|
|
|
if (theRgn && tempRgn) {
|
|
theErr = NewDrag(&theDrag);
|
|
if (theErr == noErr) {
|
|
textHandle = (Handle)TEGetText(gCommentsTextEdit);
|
|
hState = HGetState(textHandle);
|
|
HLock(textHandle);
|
|
AddDragItemFlavor(theDrag, (ItemReference)gCommentsTextEdit, 'TEXT', *textHandle, GetHandleSize(textHandle), 0);
|
|
HSetState(textHandle, hState);
|
|
startRect = (*gCommentsTextEdit)->viewRect;
|
|
SectRect(&startRect, &gCommentsWindow->portRect, &startRect);
|
|
GlobalRect(&startRect, gCommentsWindow);
|
|
RectRgn(theRgn, &startRect);
|
|
RectRgn(tempRgn, &startRect);
|
|
InsetRgn(tempRgn, 1, 1);
|
|
DiffRgn(theRgn, tempRgn, theRgn);
|
|
SetDragItemBounds(theDrag, (ItemReference)gCommentsTextEdit, &(*theRgn)->rgnBBox);
|
|
SetCursor(&qd.arrow);
|
|
theErr = TrackDrag(theDrag, theEvent, theRgn);
|
|
DisposeDrag(theDrag);
|
|
}
|
|
}
|
|
if (theRgn) DisposeRgn(theRgn);
|
|
if (tempRgn) DisposeRgn(tempRgn);
|
|
} else if (FrontWindow() != gCommentsWindow) SendMoveToFront(gCommentsWindow);
|
|
}
|
|
|
|
/*
|
|
* DoCommentsHelp(globalPt)
|
|
*
|
|
* Purpose: Pops up help for the comments 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 DoCommentsHelp(Point globalPt)
|
|
{
|
|
HMMessageRecord theRecord;
|
|
Point tip = { 0, 0 };
|
|
Rect aRect;
|
|
|
|
if (HMIsBalloon() || gInBackground) return;
|
|
PushPort();
|
|
SetPort(gCommentsWindow);
|
|
if (HMExtractHelpMsg(kHMRectListResType, rCommentsWindow, 1, kHMEnabledItem, &theRecord) == noErr) {
|
|
tip = globalPt;
|
|
aRect = gCommentsWindow->portRect;
|
|
GlobalRect(&aRect, gCommentsWindow);
|
|
HMShowBalloon(&theRecord, tip, &aRect, nil, 0, 0, kHMRegularWindow);
|
|
}
|
|
PopPort();
|
|
}
|