MessageWindowImpl.mesa
McGregor on September 10, 1982 10:41 am
Maxwell, February 14, 1983 10:22 am
Paul Rovner, June 16, 1983 8:53 am
Russ Atkinson, November 18, 1983 1:30 pm
DIRECTORY
CedarVersion USING [major, minor, patch],
Graphics
USING [black, Context, DrawBox, GetBounds, PaintMode, SetColor, SetCP, SetPaintMode,
white],
GraphicsOps USING [DrawText],
InputFocus
USING [CaptureButtons, PopInputFocus, PushInputFocus, ReleaseButtons,
SetInputFocus],
IO USING [PutFR, PutR],
Interminal USING [terminal],
MessageWindow,
Process USING [MsecToTicks, Pause],
Rope USING [Fetch, FromRefText, ROPE, Size],
Runtime USING [GetBcdTime],
TIPUser USING [InstantiateNewTIPTable],
Terminal USING [BlinkBWDisplay],
VFonts USING [defaultGFont],
ViewerClasses,
ViewerLocks USING [CallUnderWriteLock, Wedged],
ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass],
ViewerSpecs,
WindowManager USING [UnWaitCursor, WaitCursor];
MessageWindowImpl: CEDAR MONITOR
IMPORTS --CedarVersion,-- Graphics, GraphicsOps, --IO,-- InputFocus, Interminal, Process, Rope, --Runtime,-- TIPUser, Terminal, VFonts, ViewerLocks, ViewerOps, WindowManager
EXPORTS MessageWindow =
BEGIN
messageWindow: PUBLIC ViewerClasses.Viewer;
mode: {none, input, confirm} ← none;
ready: BOOLEAN ← FALSE;
confirm: BOOLEAN;
inputReady: CONDITION;
empty: BOOLEAN ← TRUE;
maxLength: INTEGER = 120;
static: REF TEXT ← NEW[TEXT[maxLength]];
typein: REF TEXT ← NEW[TEXT[maxLength]];
Clear:
PUBLIC
PROC = {
IF empty OR messageWindow=NIL OR mode#none THEN RETURN;
ViewerLocks.CallUnderWriteLock[LockedClear, messageWindow
! ViewerLocks.Wedged => CONTINUE]};
LockedClear:
PROC = {
static.length ← typein.length ← 0; empty ← TRUE;
ViewerOps.PaintViewer[viewer: messageWindow, hint: client, whatChanged: $Clear]};
Append:
PUBLIC
PROC [message: Rope.
ROPE, clearFirst:
BOOLEAN ←
FALSE] =
BEGIN
LockedAppend:
PROC = {
IF clearFirst THEN static.length ← typein.length ← 0;
FOR n:
LONG
INTEGER
IN [0..Rope.Size[message])
DO
IF static.length >= maxLength THEN EXIT;
static[static.length] ← Rope.Fetch[message, n];
static.length ← static.length + 1;
ENDLOOP;
ViewerOps.PaintViewer[messageWindow, client, TRUE, $Append];
empty ← FALSE};
IF messageWindow=NIL OR mode#none THEN RETURN;
ViewerLocks.CallUnderWriteLock[LockedAppend, messageWindow
! ViewerLocks.Wedged => CONTINUE];
END;
Blink:
PUBLIC
PROC =
BEGIN
IF messageWindow=NIL THEN RETURN;
THROUGH [0..6)
DO
ViewerOps.PaintViewer[messageWindow, client, FALSE, $Invert];
Process.Pause[Process.MsecToTicks[150]];
ENDLOOP;
END;
ReadFrom:
PUBLIC
ENTRY
PROC
RETURNS [message: Rope.
ROPE] =
BEGIN
IF messageWindow=NIL OR mode#none THEN RETURN[""];
mode ← input;
typein.length ← 0;
InputFocus.PushInputFocus[messageWindow];
InputFocus.CaptureButtons[MessageWindowNotify, messageWindowClass.tipTable,
messageWindow];
WindowManager.WaitCursor[typeKey];
UNTIL ready=TRUE DO WAIT inputReady; ENDLOOP;
InputFocus.PopInputFocus[];
ready ← FALSE;
mode ← none;
WindowManager.UnWaitCursor[];
empty ← FALSE;
RETURN[Rope.FromRefText[typein]];
END;
nextInLine: CONDITION;
Confirm:
PUBLIC
ENTRY PROC [prompt: Rope.
ROPE ←
NIL]
RETURNS [
BOOLEAN] =
BEGIN
WHILE mode#none DO WAIT nextInLine; ENDLOOP; -- wait in line
InputFocus.CaptureButtons[MessageWindowNotify, messageWindowClass.tipTable,
messageWindow];
InputFocus.SetInputFocus[];
mode ← confirm;
typein.length ← 0;
WindowManager.WaitCursor[confirm];
IF prompt#
NIL
THEN
BEGIN
static.length ← 0;
FOR n:
LONG
INTEGER
IN [0..Rope.Size[prompt])
DO
IF static.length >= maxLength THEN ERROR;
static[static.length] ← Rope.Fetch[prompt, n];
static.length ← static.length + 1;
ENDLOOP;
ViewerOps.PaintViewer[messageWindow, client, FALSE, $Append];
END;
UNTIL ready=TRUE DO WAIT inputReady; ENDLOOP;
InputFocus.ReleaseButtons[];
ready ← FALSE;
WindowManager.UnWaitCursor[];
static.length ← 0;
ViewerOps.PaintViewer[messageWindow, client, TRUE, $Clear];
empty ← FALSE;
mode ← none;
NOTIFY nextInLine;
RETURN[confirm];
END;
Destroy: PUBLIC PROC = BEGIN
IF messageWindow#NIL THEN ViewerOps.DestroyViewer[messageWindow];
messageWindow ← NIL;
ERROR; -- no longer implemented
END;
PostReleaseVersion: PROC = BEGIN OPEN CedarVersion;
version: Rope.ROPE ← Rope.Cat[IO.PutR[IO.card[major]], ".", IO.PutR[IO.card[minor]]];
patchVersion: Rope.ROPE ← IF patch=0 THEN NIL ELSE Rope.Cat[".", IO.PutR[IO.card[patch]]];
timeLen: INT = 9; shortened to trim off time
cedarLen: INT = 6+3+(IF patch=0 THEN 0 ELSE IF patch>9 THEN 3 ELSE 2)+12;
cedarMsg: Rope.ROPE ← Rope.Cat["Cedar ", version, patchVersion, " release of %t"];
Append[Rope.Substr[IO.PutFR[cedarMsg,
IO.time[Runtime.GetBcdTime[]]], 0, cedarLen+timeLen], TRUE];
Append[" ... "];
END;
MessageWindowPaint:
PRIVATE ViewerClasses.PaintProc =
BEGIN
OPEN Graphics;
IF whatChanged = $Invert
THEN
BEGIN
old: PaintMode ← SetPaintMode[context, invert];
DrawBox[context, GetBounds[context]];
END
ELSE
BEGIN
bottomOffset: REAL = 3;
leftOffset: REAL = 2;
IF ~clear
THEN
BEGIN
SetColor[context, white];
DrawBox[context, GetBounds[context]];
SetColor[context, black];
END;
SetCP[context, leftOffset, bottomOffset];
GraphicsOps.DrawText[self: context, text: static, font: VFonts.defaultGFont];
GraphicsOps.DrawText[self: context, text: typein, font: VFonts.defaultGFont]
END;
END;
MessageWindowNotify:
PRIVATE ENTRY ViewerClasses.NotifyProc =
BEGIN
FOR l:
LIST
OF
REF
ANY ← input, l.rest
UNTIL l=
NIL
DO
IF mode = input
THEN
WITH l.first
SELECT
FROM
c:
REF
CHARACTER =>
IF c^=15C
OR c^=33C
THEN
BEGIN
ready ← TRUE;
NOTIFY inputReady;
END
ELSE BEGIN
IF c^=10C
OR c^=01C
OR c^=177C
THEN
BEGIN
typein.length ←
IF c^=177C
THEN 0
ELSE
MAX[typein.length, 1]-1;
END
ELSE
BEGIN
IF typein.length >= maxLength THEN ERROR;
typein[typein.length] ← c^;
typein.length ← typein.length + 1;
END;
ViewerOps.PaintViewer[messageWindow, client, FALSE, $Append];
END;
ENDCASE => TRUSTED {Interminal.terminal.BlinkBWDisplay[]}
ELSE
IF mode=confirm
THEN
WITH l.first
SELECT
FROM
c:
REF
CHARACTER =>
SELECT c^
FROM
'y,'Y,15C,33C =>
BEGIN
ready ← confirm ← TRUE;
NOTIFY inputReady;
END;
'n,'N,177C =>
BEGIN
confirm ← FALSE;
ready ← TRUE;
NOTIFY inputReady;
END;
ENDCASE => TRUSTED {Interminal.terminal.BlinkBWDisplay[]};
a:
ATOM =>
SELECT a
FROM
$Yes =>
BEGIN
ready ← confirm ← TRUE;
NOTIFY inputReady;
END;
$No =>
BEGIN
confirm ← FALSE;
ready ← TRUE;
NOTIFY inputReady;
END;
ENDCASE => TRUSTED {Interminal.terminal.BlinkBWDisplay[]};
ENDCASE => ERROR
ELSE IF l.first=$Yes THEN LockedClear[];
ENDLOOP;
END;
MessageWindowModify:
PRIVATE ENTRY ViewerClasses.ModifyProc =
BEGIN
[self: Viewer, change: ModifyAction]
might want to start a caret someday
END;
messageWindowClass: ViewerClasses.ViewerClass ←
NEW[ViewerClasses.ViewerClassRec ← [
paint: MessageWindowPaint,
notify: MessageWindowNotify,
modify: MessageWindowModify,
tipTable: TIPUser.InstantiateNewTIPTable["MessageWindow.tip"]
]];
ViewerOps.RegisterViewerClass[$MessageWindow, messageWindowClass];
messageWindow ← ViewerOps.CreateViewer[$MessageWindow, [name: "MW",
wy: ViewerSpecs.screenH-ViewerSpecs.messageWindowHeight,
ww: ViewerSpecs.messageWindowWidth, wh: ViewerSpecs.messageWindowHeight,
column: static]
];
PostReleaseVersion[];
END.