home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************************
- * text.c
- *
- * Text Window Management Package
- *
- * ⌐1989, Motorola Inc. All rights reserved.
- ********************************************************************************/
-
-
- #include "applic.h"
- #include "window.h"
- #include "text.h"
-
-
- /* Create a window info handle with a text item
- */
- WindowPtr
- TextWindow (windID, top, left, isActive)
- register WORD windID;
- register WORD top, left;
- register Boolean isActive;
- {
- register WindowPtr theWindow;
- register InfoPtr infoPtr;
- Rect destRect, viewRect;
- GrafPtr savePort;
-
- if (theWindow = WindAllocate(windID, isActive)) {
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Setup the window graf port
- */
- infoPtr = (InfoPtr) GetWRefCon(theWindow);
- SetRect(&(infoPtr->offset), top, left, 100, 100);
- infoPtr->kind = wkText;
-
- TextFont(FONTNUM);
- TextSize(FONTSIZE);
-
- /* Create the TE and the scrollbar
- */
- viewRect = destRect = theWindow->portRect;
- infoPtr->item.text.teHdl = TENew(&destRect, &viewRect);
- infoPtr->item.text.scroll = NewControl(theWindow, &viewRect, "\pV", FALSE, 0, 0, 0, scrollBarProc, NULL);
-
- /* Fit into the window
- */
- TextAdjust(theWindow);
- TextWindReset(theWindow);
- TextActivate(isActive, theWindow);
-
- SetPort(savePort);
- }
-
- return theWindow;
- }
-
-
- /* Resize the text edit view rect and scroll bars for a text window
- */
- void
- TextAdjust (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register ControlHandle scrollHdl = infoPtr->item.text.scroll;
- register WORD scrollHeight, viewLines;
- Rect viewRect, windRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Resize the text view rectangle
- */
- viewRect = theWindow->portRect;
-
- viewRect.left += infoPtr->offset.left;
- viewRect.top += infoPtr->offset.top;
- viewRect.right -= SBAR_WIDTH;
-
- viewLines = (viewRect.bottom - viewRect.top) / (*teHdl)->lineHeight;
- viewRect.bottom = viewRect.top + (viewLines * (*teHdl)->lineHeight);
- (*teHdl)->viewRect = viewRect;
-
- /* Resize the text destination rectangle
- */
- (*teHdl)->destRect.right = viewRect.right;
- TECalText(teHdl);
-
- /* Resize the scroll bars
- */
- windRect = theWindow->portRect;
- scrollHeight = windRect.bottom - windRect.top + 3;
-
- HideControl(scrollHdl);
- MoveControl(scrollHdl, windRect.right - (SBAR_WIDTH - 1), windRect.top - 1);
-
- SizeControl(scrollHdl, SBAR_WIDTH, scrollHeight);
- ShowControl(scrollHdl);
-
- /* Recalculate and go
- */
- TextCalcScroll(theWindow);
- SetPort(savePort);
- }
-
-
- /* Clear a text window
- */
- void
- TextWindReset (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register Rect destRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Clear the text handle and selection
- */
- TESetText("\0", (long) 0L, teHdl);
- TESetSelect(0L, 0L, teHdl);
-
- /* Erase the display
- */
- EraseRect(&((*teHdl)->viewRect));
- InvalRect(&((*teHdl)->viewRect));
-
- /* Reinitialize the text destination rectangle, recalc and go
- */
- (*teHdl)->destRect = (*teHdl)->viewRect;
- TECalText(teHdl);
- TextCalcScroll(theWindow);
- SetPort(savePort);
- }
-
-
- /* TextActivate should be called in response to an activate or deactivate event,
- * and isActive is passed in to determine which of these
- */
- void
- TextActivate (isActive, theWindow)
- register Boolean isActive;
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- if (isActive) {
- if (teHdl != NULL) {
- TEActivate(teHdl);
-
- if ((*teHdl)->nLines > GetCRefCon(infoPtr->item.text.scroll))
- HiliteControl(infoPtr->item.text.scroll, 0);
- }
- }
- else {
- if (teHdl != NULL)
- TEDeactivate(teHdl);
-
- HiliteControl(infoPtr->item.text.scroll, 255);
- }
-
- SetPort(savePort);
- }
-
-
- /* TextUpdate should be called in response to an update event.
- */
- void
- TextUpdate (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register ControlHandle scrollHdl = infoPtr->item.text.scroll;
- register WORD linesInto = GetCtlValue(scrollHdl);
- register WORD scrollMax = GetCtlMax(scrollHdl);
- Rect viewRect = (*teHdl)->viewRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* TEUpdate screws up the last line if it is only a carriage return...
- * so we get to erase the last line before the update.
- */
- if (linesInto == scrollMax) {
- viewRect.top = viewRect.bottom - (2 * (*teHdl)->lineHeight);
- EraseRect(&viewRect);
- }
-
- TEUpdate(&theWindow->portRect, teHdl);
-
- if (theWindow == FrontWindow())
- TEActivate(teHdl);
- else
- TEDeactivate(teHdl);
-
- SetPort(savePort);
- }
-
-
- /* Write text into the desired debug window
- */
- void
- TextPutText (theText, theLen, theWindow)
- register char *theText;
- register LONG theLen;
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- TEInsert(theText, theLen, teHdl);
- TextCalcScroll(theWindow);
-
- SetPort(savePort);
- }
-
-
- /* Decide how to handle a mouse click in the content of a text window
- */
- void
- TextContent (theWindow, theMods, thePoint)
- register WindowPtr theWindow;
- register WORD theMods;
- register Point thePoint;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register WORD thePart;
- register Boolean isShift = FALSE;
- ControlHandle theControl;
-
- /* Determine if the point is in the text edit view rect
- */
- thePart = FindControl(thePoint, theWindow, &theControl);
-
- switch (thePart) {
- case 0: /* no control part hit */
- if ((theMods >> 4) & shiftKey)
- isShift = TRUE;
-
- TEClick(thePoint, isShift, teHdl);
- break;
-
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
- case inThumb:
- TextDoScroll(theWindow, theControl, thePart, thePoint);
- break;
-
- default:
- TrackControl(theControl, thePoint, (ProcPtr) (-1));
- }
- }
-
-
- /* Handle a mouse in a window╒s scrollbar
- */
- void
- TextDoScroll (theWindow, theControl, thePart, thePoint)
- register WindowPtr theWindow;
- register ControlHandle theControl;
- register WORD thePart;
- register Point thePoint;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register WORD lastVal, deltaVal;
-
- if (thePart == inThumb) {
- lastVal = GetCtlValue(theControl);
- thePart = TrackControl(theControl, thePoint, NULL);
- deltaVal = lastVal - GetCtlValue(theControl);
-
- /* If a change in scroll values exists, scroll that amount
- */
- if (deltaVal != 0)
- TextScroll(0, deltaVal, infoPtr->item.text.teHdl);
- }
- else
- TrackControl(theControl, thePoint, (ProcPtr) TextScrollProc);
- }
-
-
- /* Called by TrackControl for scrollbar events
- */
- pascal void
- TextScrollProc (theControl, thePart)
- register ControlHandle theControl;
- register WORD thePart;
- {
- register WindowPtr theWindow = (*theControl)->contrlOwner;
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register WORD cur_value, cur_max, cur_min, cur_delta;
-
- if (thePart != 0) {
- /* If it was actually in the control
- */
- switch (thePart) {
- case inUpButton:
- case inDownButton:
- /* one line */
- cur_delta = 1;
- break;
-
- case inPageUp:
- case inPageDown:
- /* one page */
- cur_delta = GetCRefCon(theControl);
- break;
- }
-
- if ((thePart == inDownButton) || (thePart == inPageDown))
- cur_delta = -cur_delta;
-
- /* Get value, max and min
- */
- cur_max = GetCtlMax(theControl);
- cur_min = GetCtlMin(theControl);
-
- cur_value = GetCtlValue(theControl);
- cur_delta = cur_value - cur_delta;
-
- if (cur_delta < 0)
- cur_delta = 0;
- else if (cur_delta > cur_max)
- cur_delta = cur_max;
-
- SetCtlValue(theControl, cur_delta);
-
- /* Calculate the real change
- */
- cur_delta = cur_value - cur_delta;
-
- if (cur_delta != 0)
- TextScroll(0, cur_delta, infoPtr->item.text.teHdl);
- }
- }
-
-
- /* Recalculate scrollbar values & state
- */
- void
- TextCalcScroll (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register ControlHandle scrollHdl = infoPtr->item.text.scroll;
- register WORD linesInto, scrollMax, delta, oldVal;
- register LONG viewLines;
- register Rect viewRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theWindow);
-
- /* Adjust the viewlines
- */
- viewRect = (*teHdl)->viewRect;
- viewLines = (viewRect.bottom - viewRect.top) / (*teHdl)->lineHeight;
- SetCRefCon(scrollHdl, viewLines);
-
- /* Adjust the min & max
- */
- scrollMax = (*teHdl)->nLines + 1 - viewLines;
-
- if (scrollMax < 0)
- scrollMax = 0;
-
- SetCtlMin(scrollHdl, 0);
- SetCtlMax(scrollHdl, scrollMax);
-
- /* Make the text sticky to the bottom of the viewRect
- */
- linesInto = (viewRect.top - (*teHdl)->destRect.top) / (*teHdl)->lineHeight;
- delta = linesInto - scrollMax;
-
- if ((delta > 0) || (scrollMax == 0)) {
- linesInto = scrollMax;
- oldVal = (*teHdl)->destRect.top;
- (*teHdl)->destRect.top = (*teHdl)->viewRect.top - (linesInto * (*teHdl)->lineHeight);
- TECalText(teHdl);
-
- if (oldVal != (*teHdl)->destRect.top)
- TextUpdate(theWindow);
- }
-
- SetCtlValue(scrollHdl, linesInto);
-
- /* Adjust the hilite
- */
- if (theWindow == FrontWindow()) {
- if (scrollMax > 0)
- HiliteControl(scrollHdl, 0);
- else
- HiliteControl(scrollHdl, 255);
- }
- }
-
-
- /* Scroll the text manually
- */
- void
- TextScroll (dh, dv, teHdl)
- register WORD dh;
- register WORD dv;
- register TEHandle teHdl;
- {
- /* Calculate the lineHeight
- */
- dv *= (*teHdl)->lineHeight;
-
- /* Adjust the destination rectangle
- */
- (*teHdl)->destRect.left += dh;
- (*teHdl)->destRect.right += dh;
-
- (*teHdl)->destRect.top += dv;
- (*teHdl)->destRect.bottom += dv;
-
- /* Redraw the text
- */
- TextUpdate((*teHdl)->inPort);
- }
-
-
- /* Scroll the text window to a specific location; changes the scroll bars
- * as well.
- */
- void
- TextScrollTo (h, v, theWindow)
- register WORD h;
- register WORD v;
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register ControlHandle scrollHdl = infoPtr->item.text.scroll;
- register WORD scrollMax = GetCtlMax(scrollHdl);
-
- /* Pin the max vertical
- */
- if (v > scrollMax)
- v = scrollMax;
-
- /* Adjust the destination rectangle
- */
- (*teHdl)->destRect.left = (*teHdl)->viewRect.left - h;
- (*teHdl)->destRect.top = (*teHdl)->viewRect.top - (v * (*teHdl)->lineHeight);
-
- /* Reset the scroll bar values and redraw the text
- */
- SetCtlValue(scrollHdl, v);
- TextUpdate(theWindow);
- }
-
-
- /* Scroll the end of the selection range into the view rectangle
- */
- void
- TextSelView (theWindow)
- register WindowPtr theWindow;
- {
- register InfoPtr infoPtr = (InfoPtr) GetWRefCon(theWindow);
- register TEHandle teHdl = infoPtr->item.text.teHdl;
- register ControlHandle scrollHdl = infoPtr->item.text.scroll;
- register WORD theLine, linesInto, viewLines;
-
- /* Find the line number of the end of selection range
- */
- for (theLine = (*teHdl)->nLines; theLine-- > 0; ) {
- if ((*teHdl)->selEnd >= (*teHdl)->lineStarts[theLine]) {
- /* See if the line is in view
- */
- linesInto = GetCtlValue(scrollHdl);
- viewLines = GetCRefCon(scrollHdl);
-
- /* If not, then let's take a little look-see at it
- */
- if ((theLine < linesInto) || (theLine >= (linesInto + viewLines)))
- TextScrollTo(0, theLine, theWindow);
-
- TextCalcScroll(theWindow);
- return;
- }
- }
- }
-