-- file: IntTrackMisc.mesa -- edited by Brotz, December 19, 1980 10:53 AM -- edited by Levin, August 28, 1980 5:11 PM DIRECTORY Ascii, dsD: FROM "DisplayDefs", Editor, inD: FROM "InteractorDefs", intCommon: FROM "IntCommon", StreamDefs, tsD: FROM "TOCSelectionDefs", vmD: FROM "VirtualMgrDefs"; IntTrackMisc: PROGRAM IMPORTS dsD, inD, intC: intCommon, tsD, vmD EXPORTS inD = PUBLIC BEGIN OPEN inD; -- Handles tracking in the TOC and DM regions TOCTracker: PROCEDURE [tnp: TOCTextNbrPtr, trackerType: TrackerType] = -- Tracks cursor within the TOC text neighborhood. Chooses among three subneighborhood -- cursor trackers depending on the cursor's position. BEGIN x: ScreenXCoord; y: ScreenYCoord; xOffset, yOffset: INTEGER; DO [ , xOffset, yOffset] _ dsD.GetCursor[]; x _ cursorX^ + xOffset; y _ cursorY^ + yOffset; SELECT TRUE FROM (~intC.haveMailFile OR y ~IN [tnp.topY .. tnp.bottomY)) => RETURN; (x < lineBarLeftX) => TOCScrollBarTracker[tnp]; (x < leftMargin) => tsD.TOCTextTracker[tnp]; (x IN [markLeftX .. numberLeftX) AND trackerType = normal) => MarkTracker[tnp]; ENDCASE => dsD.ChangeCursor[charArrow]; IdleLoop[]; AcceptKeyboardInput[]; ENDLOOP; END; -- of TOCTracker -- TOCScrollBarTracker: PROCEDURE [tnp: TOCTextNbrPtr] = -- Sets cursor shape for scroll bar subneighborhood. Watches for button up and down and -- calls TOC scroll routines as appropriate. BEGIN state, newState: {neutral, up, down, continuousUp, continuousDown} _ neutral; x: ScreenXCoord; y: ScreenYCoord; startTime: CARDINAL; xOffset, yOffset: INTEGER; dsD.ChangeCursor[scroll]; [ , xOffset, yOffset] _ dsD.GetCursor[]; DO x _ cursorX^ + xOffset; y _ cursorY^ + yOffset; IF x >= lineBarLeftX OR y ~IN [tnp.topY .. tnp.bottomY) THEN RETURN; newState _ SELECT TRUE FROM MouseButton[left, down] => IF state = continuousUp THEN state ELSE up, MouseButton[right, down] => IF state = continuousDown THEN state ELSE down, ENDCASE => neutral; SELECT state FROM up => IF newState = neutral THEN ScrollUpTOC[y, tnp]; down => IF newState = neutral THEN ScrollDownTOC[y, tnp]; continuousUp => IF inD.realTimeClock^ - startTime >= intC.continuousScrollDelay THEN BEGIN startTime _ inD.realTimeClock^; ScrollUpTOC[tnp.topY, tnp]; END; continuousDown => IF inD.realTimeClock^ - startTime >= intC.continuousScrollDelay THEN BEGIN startTime _ inD.realTimeClock^; ScrollDownTOC[tnp.topY, tnp]; END; ENDCASE; SELECT TRUE FROM (state = newState AND (state = up OR state = down)) => IF intC.continuousScrollTimeOut # 0 AND inD.realTimeClock^ - startTime >= intC.continuousScrollTimeOut THEN BEGIN state _ IF state = up THEN continuousUp ELSE continuousDown; startTime _ inD.realTimeClock^ - intC.continuousScrollDelay; END; (newState # state) => BEGIN IF (state _ newState) # neutral THEN startTime _ inD.realTimeClock^; dsD.ChangeCursor [SELECT state FROM up => scrollUp, down => scrollDown, ENDCASE => scroll]; END; ENDCASE; IdleLoop[]; AcceptKeyboardInput[]; ENDLOOP; END; -- of TOCScrollBarTracker -- MarkTracker: PROCEDURE [tnp: TOCTextNbrPtr] = -- Tracks cursor within the mark subneighborhood. Watches for button up and down, -- indicates cocked state on screen, changes marks on screen and in TOCEntry. BEGIN state: {neutral, cocked} _ neutral; x: ScreenXCoord; y, markY: ScreenYCoord; xOffset, yOffset: INTEGER; markC, thisEntry: vmD.TOCIndex; newMarkChar: CHARACTER; toc: vmD.TOCFixedPart; keystream: StreamDefs.StreamHandle = intC.keystream; InvertMark: PROCEDURE = BEGIN dsD.InvertRectangle[markLeftX, numberLeftX, markY, markY + dsD.lineHeight]; END; -- of InvertMark -- dsD.ChangeCursor[charArrow]; [ , xOffset, yOffset] _ dsD.GetCursor[]; DO x _ cursorX^ + xOffset; y _ cursorY^ + yOffset; IF x ~IN [markLeftX .. numberLeftX) OR y ~IN [tnp.topY .. tnp.bottomY) THEN {IF state = cocked THEN InvertMark[]; RETURN}; SELECT state FROM neutral => IF MouseButton[left, down] AND ThisIsAFirstLine[y, tnp] THEN BEGIN thisEntry _ MapYToTOCIndex[y, tnp]; state _ cocked; markC _ thisEntry; [markY, ] _ MapTOCIndexToTopY[markC, tnp]; InvertMark[]; END; cocked => IF MouseButton[left, up] THEN BEGIN keystream.reset[keystream]; dsD.ClearRectangle[markLeftX, numberLeftX, markY, markY + dsD.lineHeight]; StartBlinkingCaret[markLeftX, markY + dsD.lineHeight / 2]; dsD.ChangeCursor[invisibleCursor]; -- Read in mark and display it -- WHILE keystream.endof[keystream] DO IdleLoop[]; ENDLOOP; dsD.ChangeCursor[charArrow]; StopBlinkingCaret[]; state _ neutral; vmD.GetTOCFixedPart[markC, @toc]; SELECT newMarkChar _ keystream.get[keystream] FROM Ascii.DEL, Editor.cancelCode => newMarkChar _ toc.mark; '? => {toc.seen _ FALSE; toc.mark _ ' }; ENDCASE => {toc.seen _ TRUE; toc.mark _ newMarkChar}; [] _ dsD.PutCharInBitMap[newMarkChar, markLeftX, markY, plainFace]; vmD.PutTOCFixedPart[markC, @toc]; IF CaretIsBlinking[] THEN SetCaretBlinking[intC.target.point, intC.target.mnp]; END ELSE -- left mouse button down, so track -- BEGIN thisEntry _ MapYToTOCIndex[y, tnp]; IF ThisIsAFirstLine[y, tnp] THEN BEGIN IF thisEntry # markC THEN BEGIN InvertMark[]; markC _ thisEntry; [markY, ] _ MapTOCIndexToTopY[markC, tnp]; InvertMark[]; END; END ELSE {InvertMark[]; state _ neutral}; END; ENDCASE; IdleLoop[]; AcceptKeyboardInput[]; ENDLOOP; END; -- of MarkTracker -- END. -- of IntTrackMisc --z20461(529)\f1