home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Garbo
/
Garbo.cdr
/
mac
/
source
/
luschsrc.sit
/
text.c
< prev
next >
Wrap
Text File
|
1990-05-23
|
12KB
|
507 lines
/********************************************************************************
* 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;
}
}
}