Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
TEDocument.cp
/*------------------------------------------------------------------------------------------ |
Program: CPlusTESample 2.0 |
File: TEDocument.cp |
Uses: TEDocument.h |
TESample.h |
by Andrew Shebanow |
of Apple Macintosh Developer Technical Support |
Copyright © 1989-1990 Apple Computer, Inc. |
All rights reserved. |
------------------------------------------------------------------------------------------*/ |
// Mac Includes |
#ifndef __TYPES__ |
#include <Types.h> |
#endif |
#ifndef __QUICKDRAW__ |
#include <QuickDraw.h> |
#endif |
#ifndef __FONTS__ |
#include <Fonts.h> |
#endif |
#ifndef __EVENTS__ |
#include <Events.h> |
#endif |
#ifndef __CONTROLS__ |
#include <Controls.h> |
#endif |
#ifndef __WINDOWS__ |
#include <Windows.h> |
#endif |
#ifndef __MENUS__ |
#include <Menus.h> |
#endif |
#ifndef __TEXTEDIT__ |
#include <TextEdit.h> |
#endif |
#ifndef __DIALOGS__ |
#include <Dialogs.h> |
#endif |
#ifndef __MENUS__ |
#include <Menus.h> |
#endif |
#ifndef __DEVICES__ |
#include <Devices.h> |
#endif |
#ifndef __SCRAP__ |
#include <Scrap.h> |
#endif |
#ifndef __TOOLUTILS__ |
#include <ToolUtils.h> |
#endif |
#ifndef __MEMORY__ |
#include <Memory.h> |
#endif |
#ifndef __SEGLOAD__ |
#include <SegLoad.h> |
#endif |
#ifndef __FILES__ |
#include <Files.h> |
#endif |
#ifndef __OSUTILS__ |
#include <OSUtils.h> |
#endif |
#ifndef __TRAPS__ |
#include <Traps.h> |
#endif |
#ifndef __PACKAGES__ |
#include <Packages.h> |
#endif |
#ifndef __ERRORS__ |
#include <Errors.h> |
#endif |
#ifndef __TEDOCUMENT__ |
#include "TEDocument.h" |
#endif |
#ifndef __TESAMPLE__ |
#include "TESample.h" |
#endif |
// prototypes for functions that can't belong to TEDocument, but |
// which are closely tied into our documents |
pascal TEClickLoopUPP GetOldClickLoop(); |
pascal void PascalClickLoop(); |
pascal void CommonAction(ControlHandle control,short* amount); |
pascal void VActionProc(ControlHandle control,short part); |
pascal void HActionProc(ControlHandle control,short part); |
// this routine is written in Assembler, since it needs to tweak registers |
pascal void ASMCLICKLOOP(); |
// kTextMargin is the number of pixels we leave blank at the edge of the window. |
const short kTextMargin = 2; |
// kMaxDocWidth is an arbitrary number used to specify the width of the TERec's |
// destination rectangle so that word wrap and horizontal scrolling can be |
// demonstrated. |
const short kMaxDocWidth = 576; |
// kMinDocDim is used to limit the minimum dimension of a window when GrowWindow |
// is called. |
const short kMinDocDim = 64; |
// kMaxTELength is an arbitrary number used to limit the length of text in the TERec |
// so that various errors won't occur from too many characters being in the text. |
const short kMaxTELength = 32000; |
// kControlInvisible is used the same way to 'turn on' the control. |
const short kControlVisible = 0xFF; |
// ScrollBarAdjust, GrowBoxAdjust, and ScrollBar width are used in calculating |
// values for control positioning and sizing. |
const short kScrollbarAdjust = 15; |
const short kGrowboxAdjust = 15; |
const short kScrollbarWidth = 16; |
// kTESlop provides some extra security when pre-flighting edit commands. |
const short kTESlop = 1024; |
// kScrollTweek compensates for off-by-one requirements of the scrollbars |
// to have borders coincide with the growbox. |
const short kScrollTweek = 2; |
// kCrChar is used to match with a carriage return when calculating the |
// number of lines in the TextEdit record. kDelChar is used to check for |
// delete in keyDowns. |
const short kCrChar = 13; |
const short kDelChar = 8; |
// notice that we pass the resID parameter up to our base class, |
// which actually creates the window for us |
TEDocument::TEDocument(short resID) : TDocument(resID, kTEFileType) |
{ |
Boolean good; |
Rect destRect, viewRect; |
good = false; |
SetPort(fDocWindow); |
GetTERect(&viewRect); |
destRect = viewRect; |
destRect.right = destRect.left + kMaxDocWidth; |
fDocTE = TENew(&destRect, &viewRect); |
FailNIL(fDocTE); |
// set up TE record |
AdjustViewRect(); |
TEAutoView(true, fDocTE); |
// save and replace clickLoop |
fDocClick = (*fDocTE)->clickLoop; |
TEClickLoopUPP upp = NewTEClickLoopProc(&ASMCLICKLOOP); |
(*fDocTE)->clickLoop = upp; |
fDocVScroll = fDocHScroll = nil; |
// get vertical scrollbar |
TRY |
{ |
fDocVScroll = GetNewControl(rVScroll, fDocWindow); |
FailNILResource(fDocVScroll); |
fDocHScroll = GetNewControl(rHScroll, fDocWindow); |
FailNILResource(fDocHScroll); |
} |
RECOVER |
{ |
TEDispose(fDocTE); |
if (fDocVScroll) |
delete fDocVScroll; |
if (fDocHScroll) |
delete fDocHScroll; |
FailNewMessage(eNoWindow,gFailMessage,kTEDocErrStrings); |
} |
ENDTRY |
AdjustScrollValues(true); |
ShowWindow(fDocWindow); |
SelectWindow(fDocWindow); |
} |
TEDocument::~TEDocument() |
{ |
HideWindow(fDocWindow); |
if ( fDocTE != nil ) |
{ |
DisposeRoutineDescriptor((*fDocTE)->clickLoop); |
(*fDocTE)->clickLoop = NULL; |
TEDispose(fDocTE); // dispose the TEHandle if we got far enough to make one |
} |
if ( fDocVScroll != nil ) |
{ |
DisposeControl(fDocVScroll); |
} |
if ( fDocHScroll != nil ) |
{ |
DisposeControl(fDocHScroll); |
} |
// base class destructor will dispose of window |
} |
void TEDocument::DoZoom(short partCode) |
{ |
Rect tRect; |
tRect = fDocWindow->portRect; |
EraseRect(&tRect); |
ZoomWindow(fDocWindow, partCode, fDocWindow == FrontWindow()); |
AdjustScrollbars(true); // adjust, redraw anyway |
AdjustTE(); |
InvalRect(&tRect); // invalidate the whole content |
// the scrollbars were taken care of by AdjustScrollbars, so validate Õem |
tRect = (*fDocVScroll)->contrlRect; |
ValidRect(&tRect); |
tRect = (*fDocHScroll)->contrlRect; |
ValidRect(&tRect); |
} |
// Called when a mouseDown occurs in the grow box of an active window. |
void TEDocument::DoGrow(EventRecord* theEvent) |
{ |
long growResult; |
Rect tRect, tRect2; |
tRect = qd.screenBits.bounds; |
tRect.left = kMinDocDim; |
tRect.top = kMinDocDim; |
growResult = GrowWindow(fDocWindow, theEvent->where, &tRect); |
// see if it really changed size |
if ( growResult != 0 ) |
{ |
tRect = (*fDocTE)->viewRect; |
SizeWindow(fDocWindow, LoWord(growResult), HiWord(growResult), true); |
AdjustScrollbars(true); |
AdjustTE(); |
// calculate & validate the region that hasnÕt changed so it wonÕt get redrawn |
// Note: we copy rectangles so that we don't take address of object fields. |
tRect2 = (*fDocTE)->viewRect; |
(void) SectRect(&tRect, &tRect2, &tRect); |
tRect2 = fDocWindow->portRect; InvalRect(&tRect2); |
ValidRect(&tRect); |
tRect2 = (*fDocVScroll)->contrlRect; ValidRect(&tRect2); |
tRect2 = (*fDocHScroll)->contrlRect; ValidRect(&tRect2); |
} |
} |
void TEDocument::DoContent(EventRecord* theEvent) |
{ |
Point mouse; |
ControlHandle control; |
short part, value; |
Boolean shiftDown; |
Rect teRect; |
SetPort(fDocWindow); |
mouse = theEvent->where; // get the click position |
GlobalToLocal(&mouse); |
GetTERect(&teRect); |
if ( PtInRect(mouse, &teRect) ) |
{ |
// see if we need to extend the selection |
shiftDown = (theEvent->modifiers & shiftKey) != 0; // extend if Shift is down |
TEClick(mouse, shiftDown, fDocTE); |
} |
else |
{ |
part = FindControl(mouse, fDocWindow, &control); |
switch ( part ) |
{ |
case 0: |
// do nothing if not in a control |
break; |
case inThumb: |
value = GetControlValue(control); |
part = TrackControl(control, mouse, nil); |
if ( part != 0 ) |
{ |
value -= GetControlValue(control); |
// value now has CHANGE in value; if value changed, scroll |
if ( value != 0 ) |
if ( control == fDocVScroll ) |
TEScroll(0, value * (*fDocTE)->lineHeight, fDocTE); |
else TEScroll(value, 0, fDocTE); |
} |
break; |
default: // they clicked in an arrow, so track & scroll |
{ |
ControlActionUPP upp; |
if ( control == fDocVScroll ) |
upp = NewControlActionProc(VActionProc); |
else |
upp = NewControlActionProc(HActionProc); |
value = TrackControl(control, mouse, upp); |
DisposeRoutineDescriptor(upp); |
} |
break; |
} |
} |
} |
void TEDocument::DoKeyDown(EventRecord* theEvent) |
{ |
char key; |
if (theEvent->modifiers & cmdKey) // don't process command characters |
return; |
key = (char) (theEvent->message & charCodeMask); |
// we have a char. for our window; see if we are still below TextEditÕs |
// limit for the number of characters |
if ((key != kDelChar) && |
((*fDocTE)->teLength - ((*fDocTE)->selEnd - (*fDocTE)->selStart) + 1 >= kMaxTELength) ) |
Failure(eExceedChar,kTEDocErrStrings); |
TEKey(key, fDocTE); |
AdjustScrollbars(false); |
AdjustTE(); |
fDirty = true; |
} |
void TEDocument::DoActivate(Boolean becomingActive) |
{ |
if ( becomingActive ) |
{ |
RgnHandle tempRgn; |
RgnHandle clipRgn; |
Rect growRect; |
Rect tRect; |
// since we donÕt want TEActivate to draw a selection in an area where |
// weÕre going to erase and redraw, weÕll clip out the update region |
// before calling it. |
tempRgn = NewRgn(); |
clipRgn = NewRgn(); |
// save old update region |
CopyRgn(((WindowPeek) fDocWindow)->updateRgn, tempRgn); |
// put it in local coords |
OffsetRgn(tempRgn, fDocWindow->portBits.bounds.left, fDocWindow->portBits.bounds.top); |
GetClip(clipRgn); |
// subtract updateRgn from clipRgn |
DiffRgn(clipRgn, tempRgn, tempRgn); |
// make it the new clipRgn |
SetClip(tempRgn); |
TEActivate(fDocTE); |
// restore the full-blown clipRgn |
SetClip(clipRgn); |
// get rid of temp regions |
DisposeRgn(tempRgn); |
DisposeRgn(clipRgn); |
// the controls must be redrawn on activation: |
(*fDocVScroll)->contrlVis = kControlVisible; |
(*fDocHScroll)->contrlVis = kControlVisible; |
// copy rectangles to avoid unsafe object field references! |
tRect = (*fDocVScroll)->contrlRect; InvalRect(&tRect); |
tRect = (*fDocHScroll)->contrlRect; InvalRect(&tRect); |
// the growbox needs to be redrawn on activation: |
growRect = fDocWindow->portRect; |
// adjust for the scrollbars |
growRect.top = growRect.bottom - kScrollbarAdjust; |
growRect.left = growRect.right - kScrollbarAdjust; |
InvalRect(&growRect); |
} |
else |
{ |
TEDeactivate(fDocTE); |
// the controls must be hidden on deactivation: |
HideControl(fDocVScroll); |
HideControl(fDocHScroll); |
// we draw grow icon immediately, since we deactivate controls |
// immediately, and the update delay looks funny |
DrawGrowIcon(fDocWindow); |
} |
} |
void TEDocument::DoUpdate() |
{ |
BeginUpdate(fDocWindow); // this sets up the visRgn |
if ( ! EmptyRgn(fDocWindow->visRgn) ) // draw if updating needs to be done |
{ |
DrawWindow(); |
} |
EndUpdate(fDocWindow); |
} |
// calculate how much idle time we need |
unsigned long TEDocument::CalcIdle() |
{ |
if (HaveSelection()) |
return GetCaretTime(); |
else return kMaxSleepTime; // if we don't have a selection, we don't need to idle |
} |
// This is called whenever we get a null event et al. |
// It takes care of necessary periodic actions. For this program, |
// it calls TEIdle. |
void TEDocument::DoIdle() |
{ |
TEIdle(fDocTE); |
} // DoIdle |
// Draw the contents of an application window. |
void TEDocument::DrawWindow() |
{ |
Rect tRect; |
SetPort(fDocWindow); |
tRect = fDocWindow->portRect; |
EraseRect(&tRect); |
TEUpdate(&tRect, fDocTE); |
DrawControls(fDocWindow); |
DrawGrowIcon(fDocWindow); |
} // DrawWindow |
// Return a rectangle that is inset from the portRect by the size of |
// the scrollbars and a little extra margin. |
void TEDocument::GetTERect(Rect* teRect) |
{ |
*teRect = fDocWindow->portRect; |
InsetRect(teRect, kTextMargin, kTextMargin); // adjust for margin |
teRect->bottom = teRect->bottom - kScrollbarAdjust; // and for the scrollbars |
teRect->right = teRect->right - kScrollbarAdjust; |
} // GetTERect |
// setup a region which contains the visible text |
void TEDocument::GetVisTERgn(RgnHandle rgn) |
{ |
Rect teRect; |
teRect = (*fDocTE)->viewRect; // get a local copy of viewRect |
SetPort(fDocWindow); // make sure we have right port |
LocalToGlobal((Point*) &teRect.top); |
LocalToGlobal((Point*) &teRect.bottom); |
RectRgn(rgn, &teRect); |
// we temporarily change the portÕs origin to ÒglobalfyÓ the visRgn |
SetOrigin(-(fDocWindow->portBits.bounds.left), |
-(fDocWindow->portBits.bounds.top)); |
SectRgn(rgn, fDocWindow->visRgn, rgn); |
SetOrigin(0, 0); |
} // GetTERgn |
void TEDocument::ReadFromFile(short refNum) |
{ |
long curPos, size; |
Handle h; |
// determine how much data is available to read |
FailOSErr(GetFPos(refNum,&curPos)); |
FailOSErr(GetEOF(refNum,&size)); |
size -= curPos; |
// check for size > 32K |
if (size > kMaxTELength) |
Failure(eExceedChar,kTEDocErrStrings); |
// allocate a handle to store it in |
h = NewHandle(size); |
FailNIL(h); |
TRY |
{ |
FailOSErr(FSRead(refNum,&size,*h)); |
} |
RECOVER |
{ |
DisposeHandle(h); |
} |
ENDTRY |
// now make the text the current text |
SetPort(fDocWindow); |
HLock(h); |
TESetText(*h,size,fDocTE); |
DisposeHandle(h); |
// make sure everything is up to date |
Rect tRect = (*fDocTE)->viewRect; |
InvalRect(&tRect); |
AdjustTE(); |
AdjustScrollbars(false); |
} |
void TEDocument::WriteToFile(short refNum) |
{ |
Handle h; |
long size; |
// get COPY of TEHandle - doesn't alloc memory |
h = (Handle) TEGetText(fDocTE); |
size = GetHandleSize(h); |
FailOSErr(FSWrite(refNum,&size,*h)); |
} |
// Return boolean value indicating that there is or is not a |
// selection in the document |
Boolean TEDocument::HaveSelection() |
{ |
if ( (*fDocTE)->selStart < (*fDocTE)->selEnd ) |
return true; |
else return false; |
} |
// Update the TERec's view rect so that it is the greatest multiple of |
// the lineHeight that still fits in the old viewRect. |
void TEDocument::AdjustViewRect() |
{ |
TEPtr te; |
te = *fDocTE; |
te->viewRect.bottom = (((te->viewRect.bottom - te->viewRect.top) / te->lineHeight) |
* te->lineHeight) + te->viewRect.top; |
} // AdjustViewRect |
// Scroll the TERec around to match up to the potentially updated scrollbar |
// values. This is really useful when the window has been resized such that the |
// scrollbars became inactive but the TERec was already scrolled. |
void TEDocument::AdjustTE() |
{ |
TEPtr te; |
te = *fDocTE; |
TEScroll((te->viewRect.left - te->destRect.left) - GetControlValue(fDocHScroll), |
(te->viewRect.top - te->destRect.top) - |
(GetControlValue(fDocVScroll) * te->lineHeight), |
fDocTE); |
} // AdjustTE |
// Re-calculate the position and size of the viewRect and the scrollbars. |
// kScrollTweek compensates for off-by-one requirements of the scrollbars |
// to have borders coincide with the growbox. |
void TEDocument::AdjustScrollSizes() |
{ |
Rect teRect; |
GetTERect(&teRect); |
(*fDocTE)->viewRect = teRect; |
AdjustViewRect(); |
MoveControl(fDocVScroll, fDocWindow->portRect.right - kScrollbarAdjust, -1); |
SizeControl(fDocVScroll, kScrollbarWidth, |
fDocWindow->portRect.bottom - fDocWindow->portRect.top - |
kGrowboxAdjust + kScrollTweek); |
MoveControl(fDocHScroll, -1, fDocWindow->portRect.bottom - kScrollbarAdjust); |
SizeControl(fDocHScroll, |
fDocWindow->portRect.right - fDocWindow->portRect.left - |
kGrowboxAdjust + kScrollTweek, |
kScrollbarWidth); |
} // AdjustScrollSizes |
// Turn off the controls by jamming a zero into their contrlVis fields (HideControl erases them |
// and we don't want that). If the controls are to be resized as well, call the procedure to do that, |
// then call the procedure to adjust the maximum and current values. Finally re-enable the controls |
// by jamming a $FF in their contrlVis fields (ShowControl re-draws the control, which may not be |
// necessary). |
void TEDocument::AdjustScrollbars(Boolean needsResize) |
{ |
// First, turn visibility of scrollbars off so we wonÕt get unwanted redrawing |
(*fDocVScroll)->contrlVis = 0; |
(*fDocHScroll)->contrlVis = 0; |
if ( needsResize ) |
AdjustScrollSizes(); |
AdjustScrollValues(needsResize); |
// Now, restore visibility in case we never had to draw during adjustment |
(*fDocVScroll)->contrlVis = 0xff; |
(*fDocHScroll)->contrlVis = 0xff; |
} // AdjustScrollbars |
// Calculate the new control maximum value and current value, whether it is the horizontal or |
// vertical scrollbar. The vertical max is calculated by comparing the number of lines to the |
// vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document |
// width to the width of the viewRect. The current values are set by comparing the offset between |
// the view and destination rects. If necessary, redraw the control by calling ShowControl. |
void TEDocument::AdjustHV(Boolean isVert,Boolean mustRedraw) |
{ |
short value, lines, max; |
short oldValue, oldMax; |
TEPtr te; |
ControlHandle control; |
if (isVert) |
control = fDocVScroll; |
else control = fDocHScroll; |
oldValue = GetControlValue(control); |
oldMax = GetControlMaximum(control); |
te = *fDocTE; // point to TERec for convenience |
if ( isVert ) |
{ |
lines = te->nLines; |
// since nLines isnÕt right if the last character is a return, check for that case |
if ( *(*te->hText + te->teLength - 1) == kCrChar ) |
lines += 1; |
max = lines - ((te->viewRect.bottom - te->viewRect.top) / |
te->lineHeight); |
} |
else max = kMaxDocWidth - (te->viewRect.right - te->viewRect.left); |
if ( max < 0 ) |
max = 0; |
SetControlMaximum(control, max); |
// Must deref. after SetControlMaximum since, technically, it could draw and therefore move |
// memory. This is why we donÕt just do it once at the beginning. |
te = *fDocTE; |
if ( isVert ) |
value = (te->viewRect.top - te->destRect.top) / te->lineHeight; |
else value = te->viewRect.left - te->destRect.left; |
if ( value < 0 ) |
value = 0; |
else if ( value > max ) |
value = max; |
SetControlValue(control, value); |
// now redraw the control if asked to or if a setting changed |
if ( mustRedraw || (max != oldMax) || (value != oldValue) ) |
ShowControl(control); |
} // AdjustHV |
// Simply call the common adjust routine for the vertical and horizontal scrollbars. |
void TEDocument::AdjustScrollValues(Boolean mustRedraw) |
{ |
AdjustHV(true, mustRedraw); |
AdjustHV(false, mustRedraw); |
} // AdjustScrollValues |
TEClickLoopUPP TEDocument::GetClickLoop() |
{ |
return fDocClick; |
} |
TEHandle TEDocument::GetTEHandle() |
{ |
return fDocTE; |
} |
void TEDocument::DoCut() |
{ |
long total, contig; |
if (ZeroScrap() == noErr) |
{ |
PurgeSpace(&total, &contig); |
if ((*fDocTE)->selEnd - (*fDocTE)->selStart + kTESlop > contig) |
Failure(eNoSpaceCut,kTEDocErrStrings); |
TECut(fDocTE); |
fDirty = true; |
if (TEToScrap() != noErr) |
{ |
(void) ZeroScrap(); |
Failure(eNoCut,kTEDocErrStrings); |
} |
} |
AdjustScrollbars(false); |
AdjustTE(); |
} |
void TEDocument::DoCopy() |
{ |
if (ZeroScrap() == noErr) |
{ |
TECopy(fDocTE); // after copying, export the TE scrap |
if (TEToScrap() != noErr) |
{ |
ZeroScrap(); |
Failure(eNoCopy,kTEDocErrStrings); |
} |
} |
AdjustScrollbars(false); |
AdjustTE(); |
} |
void TEDocument::DoPaste() |
{ |
Handle aHandle; |
long oldSize, newSize; |
OSErr saveErr; |
if (TEFromScrap() != noErr) |
Failure(eNoPaste,kTEDocErrStrings); |
if ( TEGetScrapLength() + ((*fDocTE)->teLength - |
((*fDocTE)->selEnd - (*fDocTE)->selStart)) > kMaxTELength ) |
Failure(eExceedPaste,kTEDocErrStrings); |
aHandle = (Handle) TEGetText(fDocTE); |
oldSize = GetHandleSize(aHandle); |
newSize = oldSize + TEGetScrapLength() + kTESlop; |
// preflight the growth of the text handle for textedit, |
// since it will crash if it doesn't have enough memory |
SetHandleSize(aHandle, newSize); |
saveErr = MemError(); |
SetHandleSize(aHandle, oldSize); |
if (saveErr != noErr) |
Failure(eNoSpacePaste,kTEDocErrStrings); |
TEPaste(fDocTE); |
fDirty = true; |
AdjustScrollbars(false); |
AdjustTE(); |
} |
void TEDocument::DoClear() |
{ |
TEDelete(fDocTE); |
fDirty = true; |
AdjustScrollbars(false); |
AdjustTE(); |
} |
void TEDocument::DoSelectAll() |
{ |
long selSize = (*fDocTE)->teLength; |
TESetSelect(0,selSize,fDocTE); |
} |
/* |
Routines used by this class, which don't belong to the class since we use |
them as toolbox filter routines, and you cannot pass class methods as ProcPtrs. |
*/ |
// we refer back to the owning application so that we can get access to |
// the document list, to find the current document object. |
extern TESample* gTheApplication; |
// Common algorithm for pinning the value of a control. It returns the actual amount |
// the value of the control changed. |
pascal void CommonAction(ControlHandle control,short* amount) |
{ |
short value, max; |
value = GetControlValue(control); |
max = GetControlMaximum(control); |
*amount = value - *amount; |
if ( *amount <= 0 ) |
*amount = 0; |
else if ( *amount >= max ) |
*amount = max; |
SetControlValue(control, *amount); |
*amount = value - *amount; |
} // CommonAction |
// Determines how much to change the value of the vertical scrollbar by and how |
// much to scroll the TE record. |
pascal void VActionProc(ControlHandle control,short part) |
{ |
short amount; |
WindowPtr window; |
TEPtr te; |
TEDocument* doc; |
if ( part != 0 ) |
{ |
window = (*control)->contrlOwner; |
doc = (TEDocument*) (gTheApplication->DocList())->FindDoc(window); |
te = *(doc->GetTEHandle()); |
switch ( part ) |
{ |
case inUpButton: |
case inDownButton: // one line |
amount = 1; |
break; |
case inPageUp: // one page |
case inPageDown: |
amount = (te->viewRect.bottom - te->viewRect.top) / te->lineHeight; |
break; |
} |
if ( (part == inDownButton) || (part == inPageDown) ) |
amount = -amount; // reverse direction for a downer |
CommonAction(control, &amount); |
if ( amount != 0 ) |
TEScroll(0, amount * te->lineHeight, doc->GetTEHandle()); |
} |
} // VActionProc |
// Determines how much to change the value of the horizontal scrollbar by and how |
// much to scroll the TE record. |
pascal void HActionProc(ControlHandle control,short part) |
{ |
short amount; |
WindowPtr window; |
TEPtr te; |
TEDocument* doc; |
if ( part != 0 ) |
{ |
window = (*control)->contrlOwner; |
doc = (TEDocument*) (gTheApplication->DocList())->FindDoc(window); |
te = *(doc->GetTEHandle()); |
switch ( part ) |
{ |
case inUpButton: |
case inDownButton: // a few pixels |
amount = 4; |
break; |
case inPageUp: // a page |
case inPageDown: |
amount = te->viewRect.right - te->viewRect.left; |
break; |
} |
if ( (part == inDownButton) || (part == inPageDown) ) |
amount = -amount; // reverse direction |
CommonAction(control, &amount); |
if ( amount != 0 ) |
TEScroll(amount, 0, doc->GetTEHandle()); |
} |
} // VActionProc |
// Gets called from our assembly language routine, AsmClickLoop, which is in |
// turn called by the TEClick toolbox routine. Saves the windows clip region, |
// sets it to the portRect, adjusts the scrollbar values to match the TE scroll |
// amount, then restores the clip region. |
pascal void PascalClickLoop() |
{ |
RgnHandle region; |
WindowPtr wind; |
TEDocument* doc; |
wind = FrontWindow(); |
doc = (TEDocument*) (gTheApplication->DocList())->FindDoc(wind); |
region = NewRgn(); |
GetClip(region); // save clip |
ClipRect(&wind->portRect); |
doc->AdjustScrollValues(false); |
SetClip(region); // restore clip |
DisposeRgn(region); |
} // PascalClickLoop |
// Gets called from our assembly language routine, AsmClickLoop, which is in |
// turn called by the TEClick toolbox routine. It returns the address of the |
// default clickLoop routine that was put into the TERec by TEAutoView to |
// AsmClickLoop so that it can call it. |
pascal TEClickLoopUPP GetOldClickLoop() |
{ |
TEDocument* doc; |
doc = (TEDocument*) (gTheApplication->DocList())->FindDoc(FrontWindow()); |
if (doc == nil) |
return nil; |
return doc->GetClickLoop(); |
} // GetOldClickLoop |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14