JPEGView/Source/C/CommentsWindow.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
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();
}