home *** CD-ROM | disk | FTP | other *** search
INI File | 1988-09-10 | 10.9 KB | 388 lines |
- [Dialog management in Think C 3.0]
-
- I picked this up from Paul DuBois' BlobMgrDemo source a while back, and
- slightly enhanced it to handle the Return or Enter keys and to highlight
- the default OK button. This works under Think's LightSpeed C. It's
- public domain code.
-
- ---
- /*
- Present a dialog box with a text rectangle, a scroll bar, and an OK
- button. This can be used as a help dialog. Pass in a dialog
- resource number and a handle to the text. The dialog should
- have the OK button as the first item, and user items for the
- second and third items. The second is the rect in which the
- control is drawn, the third is the rect in which text is drawn.
- Only the OK button should be enabled.
-
- The text handle should be locked before calling TextDlog and
- unlocked after.
-
- Original author: dubois@uwmacc.UUCP (Paul DuBois)
- with a few changes & cleanup by: blob@apple.com (Brian Bechtel)
- */
-
- #include <EventMgr.h>
- #include <DialogMgr.h>
- #include <ControlMgr.h>
-
-
- #define nil 0L
-
- #define ETX 03 /* Enter key */
- #define CR 13 /* Return key */
-
- enum /* item numbers */
- {
- OKButton = 1,
- scrollBarUser,
- textRectUser
- };
-
- static ControlHandle theScroll;
- static Boolean needScroll; /* true if need scroll bar */
- static int curLine;
- static int halfPage;
- static TEHandle teHand;
-
-
-
- /************************************************************************
- *
- * Function: HighLightDefault
- *
- * Purpose: highlight the default button in a dialog
- *
- * Returns: nothing
- *
- * Side Effects: standard box is drawn around highlight box
- *
- * Description: draws the heavy rounded box around the OK button,
- * so that the user knows that hitting enter or return
- * is the same as pressing the OK button.
- *
- ************************************************************************/
- static void
- HighLightDefault(dPtr)
- DialogPtr dPtr;
- {
- int unusedItemType;
- Handle unusedItemHandle;
- Rect box;
- PenState p;
-
- /* This next little piece of code puts the default heavy rounded
- box around the "OK" button, so the user knows that pressing
- return is the same as hitting "OK"
- */
- SetPort(dPtr); /* without this, can't highlite OK */
- GetDItem(dPtr, OKButton, &unusedItemType, &unusedItemHandle, &box);
- GetPenState(&p);
- PenSize(3,3);
- InsetRect(&box, -4, -4);
- FrameRoundRect(&box, 16, 16);
- PenSize(p.pnSize.h, p.pnSize.v);
- }
-
- /************************************************************************
- *
- * Function: DrawScroll
- *
- * Purpose: draw scroll bar user item
- *
- * Returns: nothing
- *
- * Side Effects: draws scroll bar user item
- *
- * Description: if we need to scroll, show the control.
- *
- ************************************************************************/
- static pascal void DrawScroll (theDialog, itemNo)
- DialogPtr theDialog;
- int itemNo;
- {
- if (needScroll)
- ShowControl (theScroll);
- }
-
-
- /*
- Proc for drawing text display user item.
- */
-
-
- /************************************************************************
- *
- * Function: DrawTextRect
- *
- * Purpose: draw text display user item
- *
- * Returns: nothing
- *
- * Side Effects: shows the text
- *
- * Description: Get the rectangle for our text. If we need to scroll,
- * frame the rectangle so that it will look correct.
- * Get the view rectangle of our text rectangle, and do
- * a TEUpdate so that text edit will properly handle
- * updating the rectangle.
- *
- ************************************************************************/
- static pascal void DrawTextRect (theDialog, itemNo)
- DialogPtr theDialog;
- int itemNo;
- {
- Rect r;
- int itemType;
- Handle itemHandle;
-
- GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
- if (needScroll)
- FrameRect (&r);
- r = (**teHand).viewRect;
- TEUpdate (&r, teHand);
- }
-
-
- /************************************************************************
- *
- * Function: DoScroll
- *
- * Purpose: scroll to correct position
- *
- * Returns: nothing.
- *
- * Side Effects: text is scrolled to new position
- *
- * Description:
- * Scroll to the correct position. lDelta is the
- * amount to CHANGE the current scroll setting by.
- *
- ************************************************************************/
- static void
- DoScroll (lDelta)
- int lDelta;
- {
- int newLine;
-
- newLine = curLine + lDelta;
- if (newLine < 0) newLine = 0;
- if (newLine > GetCtlMax (theScroll)) newLine = GetCtlMax (theScroll);
- SetCtlValue (theScroll, newLine);
- lDelta = (curLine - newLine ) * (**teHand).lineHeight;
- TEScroll (0, lDelta, teHand);
- curLine = newLine;
- }
-
-
-
- /************************************************************************
- *
- * Function: __TrackScroll
- *
- * Purpose: track the scrolling
- *
- * Returns: nothing
- *
- * Side Effects: scrolling
- *
- * Description: get the control part that we're in. If we're still
- * in the same part, we're going to scroll. Check what
- * kind of part we're in, and set our delta accordingly.
- * Call DoScroll to actually handle the scrolling.
- *
- ************************************************************************/
- static pascal void __TrackScroll (theScroll, partCode)
- ControlHandle theScroll;
- int partCode;
- {
- int lDelta;
-
- if (partCode == GetCRefCon (theScroll)) /* still in same part? */
- {
- switch (partCode)
- {
- case inUpButton: lDelta = -1; break;
- case inDownButton: lDelta = 1; break;
- case inPageUp: lDelta = -halfPage; break;
- case inPageDown: lDelta = halfPage; break;
- }
- DoScroll (lDelta);
- }
- }
-
-
- /*
- Filter to handle hits in scroll bar
- */
-
-
- /************************************************************************
- *
- * Function: TextFilter
- *
- * Purpose: filter to handle hits in scroll bar
- *
- * Returns: false (indicating we should continue within our
- * modal dialog)
- *
- * Side Effects: May scroll the text
- *
- * Description: We're being called as part of a ModalDialog call.
- * Check what kind of event activated us. If it was a
- * mouseDown, handle it. If we were in the thumb, track
- * the thumb, otherwise scroll the indicated amount.
- *
- ************************************************************************/
- static pascal Boolean TextFilter (theDialog, theEvent, itemHit)
- DialogPtr theDialog;
- EventRecord *theEvent;
- int *itemHit;
- {
- Point thePoint;
- int thePart;
- Boolean result;
-
- result = false;
- switch (theEvent->what)
- {
- case mouseDown:
- thePoint = theEvent->where;
- GlobalToLocal (&thePoint);
- thePart = TestControl (theScroll, thePoint);
- if (thePart == inThumb)
- {
- (void) TrackControl (theScroll, thePoint, nil);
- DoScroll (GetCtlValue (theScroll) - curLine);
- }
- else if (thePart != 0)
- {
- SetCRefCon (theScroll, (long) thePart);
- (void) TrackControl (theScroll, thePoint, __TrackScroll);
- }
- break;
- case keyDown:
- if ((theEvent->message & charCodeMask) == ETX)
- {
- *itemHit = 1;
- result = true;
- }
- if ((theEvent->message & charCodeMask) == CR)
- {
- *itemHit = 1;
- result = true;
- }
- break;
- case updateEvt:
- case activateEvt:
- HighLightDefault(theDialog);
- break;
- }
- return (result);
- }
-
-
-
- /************************************************************************
- *
- * Function: TextDialog
- *
- * Purpose: put up text dialog with optional scroll bar
- *
- * Returns: nothing
- *
- * Side Effects: none
- *
- * Description: Pass in a dialog number, a handle to the text to
- * display, a font number, font size, and a boolean
- * indicating whether you want the text to wrap or not.
- *
- * The dialog referenced by dlogNum should have the
- * OK button as the first item, and user items for the
- * second and third items. The second is the rect in
- * which the control is drawn, the third is the rect in
- * which text is drawn. Only the OK button should be
- * enabled.
- *
- * The text handle should be locked before calling us,
- * and unlocked afterwards.
- *
- * Of course, the font number and size should exist in
- * the current system, or it will default to something
- * ugly.
- *
- ************************************************************************/
- void
- TextDialog (dlogNum, textHandle, fontNum, fontSize, wrap)
- int dlogNum;
- Handle textHandle;
- int fontNum;
- int fontSize;
- Boolean wrap;
- {
- GrafPtr oldPort;
- DialogPtr theDialog;
- int itemNo;
- int itemType;
- Handle itemHandle;
- Rect r;
- int scrollLines;
- int viewLines;
- Handle oldHText;
- ProcPtr filterProc = nil;
-
- GetPort (&oldPort);
- theDialog = GetNewDialog (dlogNum, nil, -1L);
-
- GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
- SetDItem (theDialog, textRectUser, itemType, DrawTextRect, &r);
- /*
- incorporate text into a TERec.
- */
- SetPort (theDialog);
- TextFont (fontNum);
- TextSize (fontSize);
-
- InsetRect (&r, 4, 4);
- teHand = TENew (&r, &r);
- if (!wrap)
- (**teHand).crOnly = -1;
- oldHText = (**teHand).hText; /* save this. restore later */
- (**teHand).hText = textHandle;
- TECalText (teHand);
- viewLines = (r.bottom - r.top) / (**teHand).lineHeight;
- scrollLines = (**teHand).nLines - viewLines;
- needScroll = (scrollLines > 0);
- GetDItem (theDialog, scrollBarUser, &itemType, &itemHandle, &r);
- SetDItem (theDialog, scrollBarUser, itemType, DrawScroll, &r);
- if (needScroll)
- {
- theScroll = NewControl (theDialog, &r, "\p", false, 0, 0, 0,
- scrollBarProc, nil);
- SetCtlMax (theScroll, scrollLines);
- halfPage = viewLines / 2;
- curLine = 0;
- filterProc = (ProcPtr) TextFilter;
- }
-
- ShowWindow (theDialog);
-
- do {
- ModalDialog (filterProc, &itemNo);
- } while (itemNo != OKButton);
-
- /*
- restore hText field of TE record before disposing of it.
- */
- (**teHand).hText = oldHText;
- TEDispose (teHand);
-
- if (needScroll)
- DisposeControl (theScroll);
- SetPort (oldPort);
- DisposDialog(theDialog);
- }
- ---
-
-
-