-- ALEDisp.mesa
-- Edited by Sweet, September 29, 1980 2:43 PM
DIRECTORY
ALEOps,
DisplayDefs USING [DestroyDisplay],
Inline,
KeyDefs USING [KeyBits, Keys],
MiscDefs USING [DestroyFakeModule],
SegmentDefs,
Storage USING [Node],
StringDefs,
UserTerminal USING [SetState],
UserTerminalOps USING [SetBitmapBox, StartUserTerminal],
Window,
WindowFont,
WindowOps;
ALEDisp: PROGRAM IMPORTS ALEOps, DisplayDefs, Inline, MiscDefs, SegmentDefs, Storage, StringDefs, UserTerminal, UserTerminalOps, Window, WindowFont
EXPORTS ALEOps =
BEGIN OPEN ALEOps;
feedbackWindow, frameWindow, pictureWindow: PUBLIC Window.Handle;
originWindow, sourceWindow, destWindow, upperWindow, lowerWindow:
PUBLIC Window.Handle;
upperIn, lowerIn: BOOLEAN ← FALSE;
MarksOut: PUBLIC PROC =
BEGIN
IF ~originWindow.notInTree THEN Window.RemoveFromTree[originWindow];
IF ~sourceWindow.notInTree THEN Window.RemoveFromTree[sourceWindow];
IF ~destWindow.notInTree THEN Window.RemoveFromTree[destWindow];
IF upperWindow.notInTree THEN upperIn ← FALSE
ELSE {upperIn ← TRUE; Window.RemoveFromTree[upperWindow]};
IF lowerWindow.notInTree THEN lowerIn ← FALSE
ELSE {lowerIn ← TRUE; Window.RemoveFromTree[lowerWindow]};
END;
MarksIn: PUBLIC PROC =
BEGIN
IF originWindow.notInTree THEN
{originWindow.sibling ← NIL; Window.InsertIntoTree[originWindow]};
IF destWindow.notInTree THEN
{destWindow.sibling ← originWindow; Window.InsertIntoTree[destWindow]};
IF sourceWindow.notInTree THEN
BEGIN
sourceWindow.sibling ← destWindow;
Window.InsertIntoTree[sourceWindow];
END;
IF lowerIn AND lowerWindow.notInTree THEN
BEGIN
lowerWindow.sibling ← sourceWindow;
Window.InsertIntoTree[lowerWindow];
END;
IF upperIn AND upperWindow.notInTree THEN
BEGIN
upperWindow.sibling ← IF lowerIn THEN lowerWindow ELSE sourceWindow;
Window.InsertIntoTree[upperWindow];
END;
END;
originValueBox, sourceValueBox, destValueBox, textBox: PUBLIC Window.Box;
Disjoint: PUBLIC PROC [b1, b2: POINTER TO Window.Box] RETURNS [BOOLEAN] =
BEGIN
IF b1.place.x + b1.dims.w < b2.place.x OR
b1.place.y + b1.dims.h < b2.place.y OR
b2.place.x + b2.dims.w < b1.place.x OR
b2.place.y + b2.dims.h < b1.place.y THEN RETURN [TRUE];
RETURN [FALSE];
END;
Inside: PUBLIC PROC [place: Window.Place, box: POINTER TO Window.Box]
RETURNS [BOOLEAN] =
BEGIN
RETURN [(place.x - box.place.x) IN [0..box.dims.w] AND
(place.y - box.place.y) IN [0..box.dims.h]];
END;
ZoomDetail: PUBLIC PROC [pos1, pos2: APosition] =
BEGIN
mag: [0..4];
upper, lower: APosition;
xDist, yDist: ADistance;
cplace: Window.Place;
upper ← [x: MIN[pos1.x, pos2.x], y: MIN[pos1.y, pos2.y]];
lower ← [x: MAX[pos1.x, pos2.x], y: MAX[pos1.y, pos2.y]];
IF ~upperWindow.notInTree THEN Window.RemoveFromTree[upperWindow];
IF ~lowerWindow.notInTree THEN Window.RemoveFromTree[lowerWindow];
cornerPos ← ARoundToInch[upper];
mag ← state.minMagnify;
xDist ← lower.x - cornerPos.x;
yDist ← lower.y - cornerPos.y;
WHILE mag < 4 AND
DotsForADistance[xDist, mag+1] <= FrameBox.dims.w AND
DotsForADistance[yDist, mag+1] <= FrameBox.dims.h DO
mag ← mag + 1;
ENDLOOP;
IF mag # state.magnify THEN
Window.InvalidateBox[pictureWindow, [PicturePlace[cornerPos], FrameBox.dims]];
state.magnify ← mag;
cplace ← PicturePlace[cornerPos];
Window.Slide[pictureWindow, [x: -cplace.x, y: -cplace.y]];
ASetOriginPos[GetOriginPos[FALSE]];
ASetSourcePos[Absolute[GetSourcePos[FALSE]]];
ASetDestPos[Absolute[GetDestPos[FALSE]]];
END;
SlideCorner: PUBLIC PROC [pos: APosition] =
BEGIN
cplace: Window.Place;
IF ~upperWindow.notInTree THEN Window.RemoveFromTree[upperWindow];
cornerPos ← ARoundToInch[pos];
cplace ← PicturePlace[cornerPos];
Window.Slide[pictureWindow, [x: -cplace.x, y: -cplace.y]];
ASetOriginPos[GetOriginPos[FALSE]];
ASetSourcePos[Absolute[GetSourcePos[FALSE]]];
ASetDestPos[Absolute[GetDestPos[FALSE]]];
END;
ZoomGlobal: PUBLIC PROC =
BEGIN
IF state.magnify # state.minMagnify THEN
Window.DisplayWhite[pictureWindow, [[0,0], FrameBox.dims]];
Window.Slide[pictureWindow, [0,0]];
cornerPos ← [0,0];
IF state.magnify # state.minMagnify THEN
Window.InvalidateBox[pictureWindow, [[0,0], FrameBox.dims]];
state.magnify ← state.minMagnify;
ASetOriginPos[GetOriginPos[FALSE]];
ASetSourcePos[Absolute[GetSourcePos[FALSE]]];
ASetDestPos[Absolute[GetDestPos[FALSE]]];
END;
DisplayFeedback: PROC [window: Window.Handle] =
BEGIN
window.clearingNotRequired ← TRUE;
Window.EnumerateInvalidBoxes[window, DisplayFeedbackBox];
END;
Whiten: PROC [window: Window.Handle] =
BEGIN
DoIt: PROC [window: Window.Handle, box: Window.Box] RETURNS [Window.Box] =
{Window.DisplayWhite[window, box]; RETURN[box]};
Window.EnumerateInvalidBoxes[window, DoIt];
END;
DisplayFeedbackBox: PROC [window: Window.Handle, box: Window.Box]
RETURNS [Window.Box] =
BEGIN
StripeBox: Window.Box ← [
[x: 0, y: FeedbackBox.dims.h-2],
[w: FeedbackBox.dims.w, h: 1]];
IF ~Disjoint[@box, @originValueBox] THEN DisplayOriginValue[];
IF ~Disjoint[@box, @sourceValueBox] THEN DisplaySourceValue[];
IF ~Disjoint[@box, @destValueBox] THEN DisplayDestValue[];
IF ~Disjoint[@box, @StripeBox] THEN
Window.DisplayBlack[window, StripeBox];
IF ~Disjoint[@box, @textBox] THEN PaintText[];
RETURN [[[0,0], window.box.dims]];
END;
DisplayOriginValue: PROC =
BEGIN
Window.DisplayData[
window: feedbackWindow,
box: [[x: -3, y: iconY], [16, 16]],
data: @Cursors[origin],
wpl: 1,
bbop: replace];
PaintValue[[x: 11 + 5, y: textY], LOOPHOLE[GetOriginPos[TRUE]]];
END;
DisplaySourceValue: PROC =
BEGIN
Window.DisplayData[
window: feedbackWindow,
box: [[x: sourceValueBox.place.x-1, y: iconY], [16, 16]],
data: @Cursors[source],
wpl: 1,
bbop: replace];
PaintValue[[x: sourceValueBox.place.x+8+5, y: textY], GetSourcePos[TRUE]];
END;
DisplayDestValue: PROC =
BEGIN
Window.DisplayData[
window: feedbackWindow,
box: [[x: destValueBox.place.x-8, y: iconY], [16, 16]],
data: @Cursors[dest],
wpl: 1,
bbop: replace];
PaintValue[[x: destValueBox.place.x+8+5, y: textY], GetDestPos[TRUE]];
END;
PaintValue: PROC [place: Window.Place, pos: RPosition] =
BEGIN OPEN StringDefs;
s: STRING ← [25];
AppendString[s, "x:"L];
AppendDistance[s, pos.x];
AppendString[s, " y:"L];
AppendDistance[s, pos.y];
[] ← Window.DisplayString[
window: feedbackWindow,
s: s,
place: place,
bbop: replace];
END;
AppendDistance: PROC [s: STRING, dist: ADistance] =
BEGIN
ns: STRING ← [10];
a, i: LONG CARDINAL;
f: CARDINAL;
a ← ABS[dist];
i ← a / 16;
f ← CARDINAL[Inline.LowHalf[a]] MOD 16;
StringDefs.AppendLongDecimal[ns,
IF dist > 0 THEN i ELSE -LOOPHOLE[i, LONG INTEGER]];
THROUGH [ns.length..4) DO StringDefs.AppendChar[s, ' ] ENDLOOP;
StringDefs.AppendString[s, ns];
IF f = 0 THEN StringDefs.AppendString[s, " "L]
ELSE
BEGIN
StringDefs.AppendChar[s, '-];
ns.length ← 0;
StringDefs.AppendDecimal[ns, f];
IF ns.length < 2 THEN StringDefs.AppendChar[s, ' ];
StringDefs.AppendString[s, ns];
END;
END;
textY, iconY, valueHeight: INTEGER;
DisplayPicture: PROC [window: Window.Handle] =
BEGIN
Window.EnumerateInvalidBoxes[window, DisplayPictureBox];
IF state.displayTicks THEN DisplayBoxTicks[TRUE];
END;
DisplayPictureBox: PROC [window: Window.Handle, box: Window.Box]
RETURNS [Window.Box] =
BEGIN
aBox: ABox ← ABoxForBox[box];
keys: POINTER TO KeyDefs.KeyBits = KeyDefs.Keys;
ThisPoint: PointScan =
BEGIN
IF pth.selected THEN
BEGIN
pBox: Window.Box ← BoxForPoint[p];
IF ~Disjoint[@pBox, @box] THEN
BEGIN
pPlace: Window.Place = PicturePlace[pth.pos];
Window.DisplayData[
window: pictureWindow,
box: [[pPlace.x-8, pPlace.y-8], [16, 16]],
data: @Cursors[selPt],
wpl: 1];
END;
END;
END;
ThisLine: LineScan =
BEGIN
DisplayLine[l, BoxForLine[l]];
RETURN[FALSE];
END;
ThisLabel: LabelScan =
BEGIN
labelBox: Window.Box ← BoxForLabel[lb];
IF ~Disjoint[@labelBox, @box] THEN PaintLabel[lb];
RETURN[FALSE];
END;
[] ← LinesInABox[@aBox, ThisLine];
IF state.showingLabels THEN
[] ← AllLabels[ThisLabel];
[] ← SelectedPoints[ThisPoint];
RETURN [box];
END;
tickSpace: ARRAY [-3..4] OF ADistance = [
16*128, 16*96, 16*48, 16*24, 16*12, 16*6, 16*3, 8*3];
Triple: TYPE = RECORD [a,b,c: CARDINAL];
tickMarks: ARRAY [0..12] OF Triple ← ALL[[100000B, 200B, 0]];
DisplayBoxTicks: PUBLIC PROC [on: BOOLEAN] =
BEGIN
space: ADistance = tickSpace[state.magnify];
cPlace: Window.Place = PicturePlace[cornerPos];
rcp: RPosition = Relative[cornerPos];
rft: RPosition = [
x: ((rcp.x)/space)*space,
y: ((rcp.y)/space) * space];
tickStart: Window.Place ← PicturePlace[Absolute[rft]];
tbox: Window.Box ← [
tickStart,
[w: FrameBox.dims.w + cPlace.x - tickStart.x, h: 1]];
lastY: INTEGER = cPlace.y + FrameBox.dims.h;
WHILE tbox.place.y < lastY DO
Window.DisplayData[
window: pictureWindow,
data: BASE[tickMarks],
bbop: IF on THEN paint ELSE erase,
wpl: 40,
box: tbox];
tbox.place.y ← tbox.place.y + 24;
ENDLOOP;
END;
DisplayOrigin: PROC [window: Window.Handle] =
BEGIN
Window.DisplayOffsetData[
window: window,
box: [[0,0], window.box.dims],
data: @Cursors[origin] + 3,
wpl: 1,
offset: 3,
bbop: replace];
END;
DisplaySource: PROC [window: Window.Handle] =
BEGIN
Window.DisplayOffsetData[
window: window,
box: [[0,0], window.box.dims],
data: @Cursors[source] + 4,
wpl: 1,
offset: 1,
bbop: replace];
END;
DisplayDest: PROC [window: Window.Handle] =
BEGIN
Window.DisplayOffsetData[
window: window,
box: [[0,0], window.box.dims],
data: @Cursors[dest] + 4,
wpl: 1,
offset: 8,
bbop: replace];
END;
DisplayUpper: PROC [window: Window.Handle] =
BEGIN
Window.DisplayOffsetData[
window: window,
box: [[0,0], window.box.dims],
data: @Cursors[upper] + 8,
wpl: 1,
offset: 8,
bbop: replace];
END;
DisplayLower: PROC [window: Window.Handle] =
BEGIN
Window.DisplayOffsetData[
window: window,
box: [[0,0], window.box.dims],
data: @Cursors[lower] + 1,
wpl: 1,
offset: 1,
bbop: replace];
END;
root: Window.Object ← [];
StartDisplay: PUBLIC PROC =
BEGIN
DisplayDefs.DestroyDisplay[];
UserTerminalOps.StartUserTerminal[FALSE];
Window.DefineRoot[window: @root, grey:, bitmapExists: FALSE];
[] ← UserTerminalOps.SetBitmapBox[BitmapBox];
[] ← UserTerminal.SetState[off];
Window.DefineRoot[window: @root, grey:[0,0,0,0], bitmapExists: TRUE];
[] ← UserTerminal.SetState[on];
LoadFont[];
feedbackWindow ← Storage.Node[SIZE[Window.Object]];
frameWindow ← Storage.Node[SIZE[Window.Object]];
pictureWindow ← Storage.Node[SIZE[Window.Object]];
originWindow ← Storage.Node[
SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] +
SIZE[Window.MinusLandBitmapUnder];
sourceWindow ← Storage.Node[
SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] +
SIZE[Window.MinusLandBitmapUnder];
destWindow ← Storage.Node[
SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] +
SIZE[Window.MinusLandBitmapUnder];
upperWindow ← Storage.Node[
SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] +
SIZE[Window.MinusLandBitmapUnder];
lowerWindow ← Storage.Node[
SIZE[Window.Object] + SIZE[Window.MinusLandBitmapUnder]] +
SIZE[Window.MinusLandBitmapUnder];
feedbackWindow↑ ← [
parent: Window.rootWindow,
sibling: frameWindow,
box: FeedbackBox,
display: DisplayFeedback,
boxesCount: one];
frameWindow↑ ← [
parent: Window.rootWindow,
child: pictureWindow,
box: FrameBox,
display: Whiten];
pictureWindow↑ ← [
parent: frameWindow,
child: originWindow,
boxesCount: one,
box: PictureBox,
display: DisplayPicture];
originWindow↑ ← [
parent: pictureWindow,
box: originBox,
display: DisplayOrigin,
underVariant: TRUE,
clearingNotRequired: TRUE,
boxesCount: none];
[] ← Window.SetBitmapUnder[
originWindow, Storage.Node[Window.WordsForBitmapUnder[originWindow]]];
sourceWindow↑ ← [
parent: pictureWindow,
box: sourceBox,
display: DisplaySource,
underVariant: TRUE,
clearingNotRequired: TRUE,
boxesCount: none];
[] ← Window.SetBitmapUnder[
sourceWindow, Storage.Node[Window.WordsForBitmapUnder[sourceWindow]]];
destWindow↑ ← [
parent: pictureWindow,
box: destBox,
display: DisplayDest,
underVariant: TRUE,
clearingNotRequired: TRUE,
boxesCount: none];
[] ← Window.SetBitmapUnder[
destWindow, Storage.Node[Window.WordsForBitmapUnder[destWindow]]];
upperWindow↑ ← [
parent: pictureWindow,
box: upperBox,
display: DisplayUpper,
underVariant: TRUE,
clearingNotRequired: TRUE,
boxesCount: none];
[] ← Window.SetBitmapUnder[
upperWindow, Storage.Node[Window.WordsForBitmapUnder[sourceWindow]]];
lowerWindow↑ ← [
parent: pictureWindow,
box: lowerBox,
display: DisplayLower,
underVariant: TRUE,
clearingNotRequired: TRUE,
boxesCount: none];
[] ← Window.SetBitmapUnder[
lowerWindow, Storage.Node[Window.WordsForBitmapUnder[destWindow]]];
-- get ready to display pos values
textY ← 2; iconY ← textY + WindowFont.FontHeight[]/2 - 8;
valueHeight ← MAX[WindowFont.FontHeight[], 11];
originValueBox ← [
[x: 0, y: 0], [w: FeedbackBox.dims.w/3, h: valueHeight]];
sourceValueBox ← [
[x: FeedbackBox.dims.w/3, y: 0],
[w: FeedbackBox.dims.w/3, h: valueHeight]];
destValueBox ← [
[x: (2*FeedbackBox.dims.w)/3, y: 0],
[w: FeedbackBox.dims.w/3, h: valueHeight]];
textBox ← [
[x: 0, y: valueHeight + 1],
[w: FeedbackBox.dims.w, h: WindowFont.FontHeight[]]];
Window.InsertIntoTree[frameWindow];
Window.InsertIntoTree[feedbackWindow];
Window.ValidateTree[];
END;
fontAscent, smallFontAscent, largeFontAscent: PUBLIC INTEGER;
smallFont, largeFont: PUBLIC WindowFont.Handle;
LoadFont: PROC =
BEGIN OPEN SegmentDefs;
font: WindowFont.Handle ← Storage.Node[SIZE[WindowFont.Object]];
fsb: WindowOps.Strike;
fseg: FileSegmentHandle ← MiscDefs.DestroyFakeModule[
LOOPHOLE[ALEOps.Gacha10]].seg;
MakeSwappedIn[seg: fseg, info: HardUp];
font.address ← fsb ← SegmentAddress[fseg];
fontAscent ← fsb.body.ascent;
font.swapper ← NIL;
WindowFont.Initialize[font];
WindowFont.SetDefault[font];
font ← Storage.Node[SIZE[WindowFont.Object]];
fseg ← MiscDefs.DestroyFakeModule[
LOOPHOLE[ALEOps.Helvetica8]].seg;
MakeSwappedIn[seg: fseg, info: HardUp];
font.address ← fsb ← SegmentAddress[fseg];
smallFontAscent ← fsb.body.ascent;
font.swapper ← NIL;
WindowFont.Initialize[font];
smallFont ← font;
font ← Storage.Node[SIZE[WindowFont.Object]];
fseg ← MiscDefs.DestroyFakeModule[
LOOPHOLE[ALEOps.Helvetica14]].seg;
MakeSwappedIn[seg: fseg, info: HardUp];
font.address ← fsb ← SegmentAddress[fseg];
largeFontAscent ← fsb.body.ascent;
font.swapper ← NIL;
WindowFont.Initialize[font];
largeFont ← font;
SetupLand[];
END;
END.