FILE: RoseDisplayOps.Mesa
Last Edited by: Spreitzer, July 13, 1984 11:16:53 pm PDT
Last Edited by: Barth, June 9, 1983 11:19 am
DIRECTORY AMBridge, AMTypes, Atom, Buttons, HierarchicalDisplays, IO, Labels, List, MessageWindow, OrderedSymbolTableRef, PrincOps, PrincOpsUtils, Process, Rope, RoseConditions, RoseCreate, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerClasses, ViewerIO, ViewerOps, ViewerTools, ViewRec;
RoseDisplayOps:
MONITOR
IMPORTS AMBridge, AMTypes, Atom, Buttons, HierarchicalDisplays, IO, List, MessageWindow, OrderedSymbolTableRef, PrincOpsUtils, Process, Rope, RoseConditions, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerIO, ViewerOps, ViewerTools, ViewRec
EXPORTS RoseDisplayInsides =
BEGIN OPEN RoseDisplayInsides;
IncrementalCondition: TYPE = RoseConditions.IncrementalCondition;
NamedCondition: TYPE = REF NamedConditionRep;
NamedConditionRep:
TYPE =
RECORD [
name: ROPE,
cond: Condition,
ic: IncrementalCondition ← NIL,
posted, postedIncrementally: BOOLEAN ← FALSE
];
leafProp: PUBLIC ATOM ← Atom.MakeAtom["January 6, 1984 9:19 pm Spreitzer"];
treeHandler: ViewRec.SimpleHandler ←
NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseTree,
Max: MaxTree]];
treeNodeListHandler: ViewRec.SimpleHandler ←
NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseTreeNodeList,
Max: MaxTreeNodeList]];
stHandler: ViewRec.SimpleHandler ←
NEW [ViewRec.SimpleHandlerRep ← [
UnParse: UnParseST,
Max: MaxST]];
nodeAsNode: REF Node ← NEW [Node ← NIL];
nodeAsTV: AMTypes.TypedVariable ← AMBridge.TVForReferent[nodeAsNode];
treeAsTree: REF TreeNode ← NEW [TreeNode ← NIL];
treeAsTV: AMTypes.TypedVariable ← AMBridge.TVForReferent[treeAsTree];
tnlAsTNL: REF TreeNodeList ← NEW [TreeNodeList ← NIL];
tnlAsTV: AMTypes.TypedVariable ← AMBridge.TVForReferent[tnlAsTNL];
stAsST: REF SymbolTable ← NEW [SymbolTable ← NIL];
stAsTV: AMTypes.TypedVariable ← AMBridge.TVForReferent[stAsST];
UnParseTree: ViewRec.UnParseProc =
CHECKED
BEGIN
AMTypes.Assign[lhs: treeAsTV, rhs: tv];
asRope ← Trees.Format[who: treeAsTree^, style: Algebraic];
END;
MaxTree: ViewRec.MaxProc =
CHECKED
{RETURN [lines: 2, maxWidthNeeded: 1024]};
RecognizeTree: ViewRec.Recognizer =
CHECKED
{RETURN [TRUE, treeHandler, NIL]};
UnParseTreeNodeList: ViewRec.UnParseProc =
CHECKED
BEGIN
AMTypes.Assign[lhs: tnlAsTV, rhs: tv];
asRope ← NIL;
FOR tnl: TreeNodeList ← tnlAsTNL^, tnl.rest
WHILE tnl #
NIL
DO
this: ROPE ← Trees.Format[who: tnl.first, style: Algebraic];
asRope ← IF asRope = NIL THEN this ELSE asRope.Cat[", ", this];
ENDLOOP;
asRope ← Rope.Cat["(", asRope, ")"];
END;
MaxTreeNodeList: ViewRec.MaxProc =
CHECKED
{RETURN [lines: 3, maxWidthNeeded: 1024]};
RecognizeTreeNodeList: ViewRec.Recognizer =
CHECKED
{RETURN [TRUE, treeNodeListHandler, NIL]};
UnParseST: ViewRec.UnParseProc =
CHECKED
BEGIN
EatIt:
SAFE
PROC [asAny:
REF
ANY]
RETURNS [abort:
BOOLEAN] =
CHECKED
BEGIN
nc: NamedCondition ← NARROW[asAny];
abort ← FALSE;
IF asRope # NIL THEN asRope ← asRope.Concat["\n"];
asRope ← asRope.Cat[nc.name, "(",
IF nc.posted
THEN "p"
ELSE ""].Cat[
IF nc.postedIncrementally THEN "i" ELSE "", "): ",
Trees.Format[who: nc.cond, style: Algebraic]];
END;
AMTypes.Assign[lhs: stAsTV, rhs: tv];
asRope ← NIL;
stAsST^.EnumerateIncreasing[EatIt];
END;
MaxST: ViewRec.MaxProc =
CHECKED
{RETURN [lines: 5, maxWidthNeeded: 1024]};
RecognizeST: ViewRec.Recognizer =
CHECKED
{RETURN [TRUE, stHandler, NIL]};
CompareNamedConditions: OrderedSymbolTableRef.CompareProc =
CHECKED
BEGIN
k1, k2: ROPE;
k1 ←
WITH r1
SELECT
FROM
nc: NamedCondition => nc.name,
r: ROPE => r,
ENDCASE => ERROR;
k2 ←
WITH r2
SELECT
FROM
nc: NamedCondition => nc.name,
r: ROPE => r,
ENDCASE => ERROR;
RETURN [k1.Compare[k2]];
END;
Pack:
PROC [display: Display] = {
IF display.mucking > 0 THEN display.rv.DisplayMessage["Not now"]
ELSE HierarchicalDisplays.Pack[display.rootDisplay]};
LookForChange: HierarchicalDisplays.ChildNotifyProc
--PROC [child: Child]-- =
TRUSTED
BEGIN
WITH child
SELECT
FROM
leaf: HierarchicalDisplays.Leaf =>
IF
ISTYPE[leaf.instanceData, NodeElt]
THEN
BEGIN
ne: NodeElt ← NARROW[leaf.instanceData];
IF NOT ne.changed THEN RETURN;
ne.changed ← FALSE;
SELECT ne.parent.display.ctlPanel.mode
FROM
Value =>
BEGIN
ViewerTools.SetContents[
leaf.value,
ne.format.FormatValue[
ne.node,
ne.format,
ne.node.ValWP[]]];
leaf.value.newVersion ← FALSE;
IF ne.badString
THEN
BEGIN
Buttons.SetDisplayStyle[button: leaf.nameButton, style: $BlackOnWhite];
ne.badString ← FALSE;
END;
END;
Test => NULL;
ENDCASE => ERROR;
END;
in: HierarchicalDisplays.InternalNode =>
BEGIN
cb: CellBrowser ← NARROW[in.instanceData];
IF cb.changed
THEN
BEGIN
Buttons.SetDisplayStyle[
child.nameButton,
IF cb.cell.realCellStuff.schedNext = RoseTypes.notInCellList
THEN $BlackOnWhite
ELSE IF cb.cell = cb.cell.parent.CellToStr[].schedFirst
THEN $WhiteOnBlack
ELSE $BlackOnGrey];
cb.changed ← FALSE;
END;
END;
ENDCASE => ERROR;
END;
LookForChanges:
SAFE
PROC [] =
CHECKED BEGIN
HierarchicalDisplays.EnumerateChildren[LookForChange];
END;
longing: INTEGER ← 0;
NoticeStart:
ENTRY RoseTypes.NotifyProc =
CHECKED
{IF (longing ← longing + 1) > 0 THEN trackChanges ← longIncremental};
NoticeStop:
ENTRY RoseTypes.NotifyProc =
CHECKED
{
IF (longing ← longing - 1) < 1
AND
NOT trackChanges
THEN
{LookForChanges[]; trackChanges ← TRUE}};
NoticeDisplayStart:
ENTRY RoseTypes.NotifyProc =
CHECKED
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Running};
NoticeDisplayInterrupt:
ENTRY RoseTypes.NotifyProc =
CHECKED
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Interrupted};
NoticeDisplayStop:
ENTRY RoseTypes.NotifyProc =
CHECKED
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Idle};
ActivityLogNotify:
ENTRY
SAFE
PROC [clientData:
REF
ANY]
--ViewRec.NotifyClientProc-- =
CHECKED BEGIN
display: Display ← NARROW[clientData];
log: BOOL ← display.ctlPanel.logActivity;
IF log # display.loggingActivity
THEN {
IF log
THEN {
RoseEvents.AddWatcher[$SimpleChanged, [NotifyActivity, display]];
RoseEvents.AddWatcher[$NewSpecialSwitchInstructions, [NotifyActivity, display]];
}
ELSE {
RoseEvents.RemoveWatcher[$SimpleChanged, [NotifyActivity, display]];
RoseEvents.RemoveWatcher[$NewSpecialSwitchInstructions, [NotifyActivity, display]];
};
display.loggingActivity ← log};
END;
NotifyActivity:
SAFE
PROC [event:
ATOM, watched, watcherData, arg:
REF
ANY]
--RoseTypes.NotifyProc-- =
CHECKED BEGIN
display: Display ← NARROW[watcherData];
ar: RoseRun.ActivityReport ← NARROW[arg];
display.log.PutF["%g.%g(=%g.%g)", IO.rope[LongName[ar.socket.cell]], IO.rope[ar.socket.cell.class.ports[ar.socket.index].name], IO.rope[LongName[ar.node.cellIn]], IO.rope[ar.node.name]];
SELECT event
FROM
$SimpleChanged => {
fmt: RoseTypes.Format ← ar.node.type.procs.GetFormat[ar.node.type, ""];
display.log.PutF[" ← %g\n", IO.rope[fmt.FormatValue[ar.node, fmt, RoseTypes.SocketToWP[ar.socket]]]];
};
$NewSpecialSwitchInstructions => display.log.PutRope[" got new instructions\n"];
ENDCASE => ERROR;
END;
LongName:
SAFE
PROC [cell: Cell]
RETURNS [ln:
ROPE] =
CHECKED {
ln ← cell.name;
FOR cell ← cell.parent, cell.parent
WHILE cell #
NIL
DO
ln ← cell.name.Cat[".", ln];
ENDLOOP};
NotifyNodeUD:
PUBLIC
SAFE
PROC [event:
ATOM, watched, watcherData, arg:
REF
ANY]
--RoseTypes.NotifyProc-- =
CHECKED
BEGIN
node: Node ← NARROW[watched];
cell: Cell ← NARROW[arg];
display: Display ← NARROW[watcherData];
fmt: RoseTypes.Format ← node.type.procs.GetFormat[node.type, "UD"];
IF event # $NewNodeUD THEN ERROR;
display.log.PutF["New UD for %g", IO.rope[LongName[node.cellIn].Cat[".", node.name]]];
IF cell # NIL THEN display.log.PutF[" from %g", IO.rope[LongName[cell]]];
IF fmt # NIL THEN display.log.PutF[":%g", IO.rope[fmt.FormatValue[node, fmt, NIL]]];
display.log.PutRope["\n"];
END;
IncrNotify:
ENTRY
SAFE
PROC [clientData:
REF
ANY]
--ViewRec.NotifyClientProc-- =
CHECKED BEGIN
display: Display ← NARROW[clientData];
IF display.ctlPanel.incrementalDisplay = longIncremental THEN RETURN;
longIncremental ← display.ctlPanel.incrementalDisplay;
IF longing > 0
AND trackChanges # longIncremental
THEN
{IF (trackChanges ← longIncremental) THEN LookForChanges[]};
RoseEvents.Notify[event: setIncrementalDisplay, handleAborted: TRUE];
END;
longIncremental: BOOLEAN ← FALSE;
trackChanges: BOOLEAN ← TRUE;
setIncrementalDisplay: ATOM ← Atom.MakeAtom["Spreitzer January 6, 1984 9:19 pm"];
NoticeSetIncrementalDisplay: RoseTypes.NotifyProc =
CHECKED BEGIN
display: Display ← NARROW[watcherData];
display.ctlPanel.incrementalDisplay ← longIncremental;
END;
TiogaNoticeEdit: TiogaOps.CommandProc
--PROC [viewer: Viewer ← NIL] RETURNS [recordAtom: BOOL ← TRUE, quit: BOOL ← FALSE]-- =
TRUSTED
BEGIN
asAny: REF ANY ← ViewerOps.FetchProp[viewer: viewer, prop: leafProp];
IF (IF asAny = NIL THEN TRUE ELSE NOT ISTYPE[asAny, HierarchicalDisplays.Leaf]) THEN RETURN [recordAtom: FALSE, quit: FALSE];
recordAtom ← FALSE; quit ← TRUE;
[] ← NoticeEdit[NARROW[asAny]];
END;
NoticeEdit:
PROC [leaf: HierarchicalDisplays.Leaf]
RETURNS [success:
BOOLEAN] =
BEGIN
ne: NodeElt ← NARROW[leaf.instanceData];
SELECT ne.parent.display.ctlPanel.mode
FROM
Value =>
BEGIN
ModifyIt: RoseRun.ModifyProc
--PROC [cell: Cell] RETURNS [subtle: BOOLEAN ← FALSE]-- =
CHECKED
BEGIN
ts: IO.STREAM ← IO.RIS[ViewerTools.GetContents[leaf.value]];
wp ← ne.node.ValWP[];
success ← ne.format.ParseValue[ne.node, ne.format, wp, ts];
ts.Close[];
END;
wp: RoseTypes.WordPtr;
IF ne.node.visible.cell = NIL THEN ERROR;
ViewerTools.InhibitUserEdits[leaf.value];
IF ne.node.type.simple
THEN
RoseRun.AllowToModify[cell: ne.node.visible.cell, modifier: ModifyIt, mayRescheduleSelf: TRUE]
ELSE {
[] ← ModifyIt[NIL];
IF success THEN RoseRun.ValueChanged[ne.node]};
Buttons.SetDisplayStyle[leaf.nameButton, IF success THEN $BlackOnWhite ELSE $WhiteOnBlack];
IF success
THEN
BEGIN
leaf.value.newVersion ← FALSE;
--VT.SetContents[leaf.value, ne.format.FormatValue[ne.node.type, ne.format, wp]];--
END;
ViewerTools.EnableUserEdits[leaf.value];
IF NOT success THEN leaf.value.newVersion ← TRUE;
END;
Test =>
BEGIN
tp: RoseTypes.NodeTestProc;
td: REF ANY;
ts: IO.STREAM;
ViewerTools.InhibitUserEdits[leaf.value];
ts ← IO.RIS[ViewerTools.GetContents[leaf.value]];
[success, tp, td] ← ne.format.ParseTest[ne.node.type, ne.format, ts];
ts.Close[];
Buttons.SetDisplayStyle[leaf.nameButton, IF success THEN $BlackOnWhite ELSE $WhiteOnBlack];
IF success
THEN
BEGIN
ne.testData ← td;
ne.testProc ← tp;
--VT.SetContents[leaf.value, ne.format.FormatTest[ne.node.type, ne.format, tp, td]];--
leaf.value.newVersion ← FALSE;
END;
ViewerTools.EnableUserEdits[leaf.value];
IF NOT success THEN leaf.value.newVersion ← TRUE;
END;
ENDCASE => ERROR;
ne.badString ← NOT success;
END;
NoticeEdits:
PROC [display: Display]
RETURNS [
AOK:
BOOLEAN] =
BEGIN
Notice: HierarchicalDisplays.ChildNotifyProc =
TRUSTED
BEGIN
IF NOT NoticeEdit[NARROW[child]] THEN AOK ← FALSE;
END;
AOK ← TRUE;
HierarchicalDisplays.EnumerateChildren[to: Notice, internals: FALSE, changedOnly: TRUE];
END;
Interrupt: PROC [display: Display] = {RoseRun.stop ← TRUE};
Disable:
PROC [display: Display]
RETURNS [ok:
BOOL] =
BEGIN
fh: PrincOps.FrameHandle ← display.stopped;
ok ← (fh # NIL) AND RoseRun.DisableThisStop[fh];
END;
Proceed:
PROC [display: Display] =
BEGIN
Inner:
ENTRY
PROC = {
display.stopResponse ← Resume;
display.ctlPanel.status ← Running;
BROADCAST display.notice;
};
IF NoticeEdits[display] THEN Inner[];
END;
Abort:
PROC [display: Display] =
BEGIN
Inner:
ENTRY
PROC = {
display.stopResponse ← Abort;
display.ctlPanel.status ← Running;
BROADCAST display.notice;
};
IF NoticeEdits[display] THEN Inner[];
END;
GetStopResponse:
SAFE
PROC [display: Display, msg:
ROPE, data:
REF
ANY]
RETURNS [sr: StopResponse] =
CHECKED
BEGIN
RoseEvents.Notify[event: $Interrupt, handleAborted: TRUE];
sr ← ReallyGetStopResponse[display, msg, data];
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
END;
ReallyGetStopResponse:
ENTRY
SAFE
PROC [display: Display, msg:
ROPE, data:
REF
ANY]
RETURNS [sr: StopResponse] =
CHECKED
BEGIN ENABLE UNWIND => {};
IF display.ctlPanel.status # Interrupted THEN ERROR;
TRUSTED {display.stopped ← PrincOpsUtils.MyLocalFrame[]};
display.rv.DisplayMessage[msg];
WHILE display.ctlPanel.status = Interrupted
DO
WAIT display.notice;
ENDLOOP;
RoseRun.stop ← FALSE;
sr ← display.stopResponse;
display.stopped ← NIL;
END;
Run:
PROC [display: Display] =
BEGIN
IF NOT NoticeEdits[display] THEN RETURN;
RoseEvents.Notify[event: $Start, handleAborted:
TRUE];
BEGIN
ENABLE
BEGIN
RoseTypes.Stop =>
CHECKED
BEGIN
SELECT GetStopResponse[display, msg, data]
FROM
Resume => RESUME;
Abort => ERROR ABORTED;
ENDCASE => ERROR;
END;
UNWIND => RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
IF display.type = Ordinary THEN RoseRun.Run[display.sim] ELSE RoseRun.Test[sim: display.sim, cth: display.cth, parms: display.parms];
END;
RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
SingleStep:
PROC [display: Display]
RETURNS [stepType: RoseRun.StepType] =
BEGIN
IF display.type = Test
THEN {display.rv.DisplayMessage["Can't single-step a CellTest"]; RETURN};
IF NOT NoticeEdits[display] THEN RETURN;
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
stepType ← RoseRun.StepSim[display.sim
!RoseTypes.Stop =>
CHECKED
BEGIN
SELECT GetStopResponse[display, msg, data]
FROM
Resume => RESUME;
Abort => ERROR ABORTED;
ENDCASE => ERROR;
END;
UNWIND => RoseEvents.Notify[event: $Stop, handleAborted: TRUE]];
RoseEvents.Notify[event: $Stop, handleAborted: TRUE];
END;
PathNameToPath:
PROC [pathName:
ROPE]
RETURNS [path:
LIST
OF
ROPE] =
BEGIN
dotIndex: INT;
last: LIST OF ROPE ← LIST[pathName];
path ← last;
WHILE (dotIndex ← last.first.Find["."]) >= 0
DO
last.rest ← LIST[last.first.Substr[dotIndex+1, last.first.Length[] - (dotIndex+1)]];
last.first ← last.first.Substr[0, dotIndex];
last ← last.rest;
ENDLOOP;
END;
SetMode:
PROC [display: Display, mode: DisplayMode] =
BEGIN
SetValue: HierarchicalDisplays.ChildNotifyProc =
TRUSTED
BEGIN
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
WITH leaf.instanceData
SELECT
FROM
ne: NodeElt =>
BEGIN
val: ROPE ← ne.format.FormatValue[ne.node, ne.format, ne.node.ValWP[]];
ViewerTools.InhibitUserEdits[leaf.value];
ViewerTools.SetContents[leaf.value, val];
leaf.value.newVersion ← FALSE;
ViewerTools.EnableUserEdits[leaf.value];
Buttons.SetDisplayStyle[leaf.nameButton, $BlackOnWhite];
ne.badString ← FALSE;
END;
cs: CellState => NULL;
ENDCASE => ERROR;
END;
SetTest: HierarchicalDisplays.ChildNotifyProc =
TRUSTED
BEGIN
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
WITH leaf.instanceData
SELECT
FROM
ne: NodeElt =>
BEGIN
val: ROPE ← ne.format.FormatTest[ne.node.type, ne.format, ne.testProc, ne.testData];
ViewerTools.InhibitUserEdits[leaf.value];
ViewerTools.SetContents[leaf.value, val];
leaf.value.newVersion ← FALSE;
ViewerTools.EnableUserEdits[leaf.value];
Buttons.SetDisplayStyle[leaf.nameButton, $BlackOnWhite];
ne.badString ← FALSE;
END;
cs: CellState => NULL;
ENDCASE => ERROR;
END;
HierarchicalDisplays.EnumerateChildren[to: IF mode = Value THEN SetValue ELSE SetTest, internals: FALSE];
END;
ModeNotify: ViewRec.NotifyClientProc =
TRUSTED
{display: Display ← NARROW[clientData];
SetMode[display, display.ctlPanel.mode]};
ClearStack:
PROC [display: Display] =
{display.ctlPanel.conditionStack ← NIL};
ClearCondition:
PROC [display: Display] =
{display.ctlPanel.condition ← NIL};
GetCondition:
PROC [display: Display]
RETURNS [nc: NamedCondition] =
BEGIN
name: ROPE ← ViewerTools.GetSelectionContents[];
asAny: REF ANY;
IF name.Length[] < 1 THEN RETURN [NIL];
asAny ← display.ctlPanel.conditions.Lookup[name];
nc ← NARROW[asAny];
END;
PostCondition:
PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF nc.posted THEN {display.rv.DisplayMessage["Already posted!"]; RETURN};
nc.posted ← TRUE;
RoseConditions.PostOnCell[
cell: display.rootCell,
condition: nc.cond];
ViewRec.RedisplayElt[display.conditionsHandle];
END;
RemoveCondition:
PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
RoseConditions.UnPostOnCell[
cell: display.rootCell,
condition: nc.cond];
nc.posted ← FALSE;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
PostIncremental:
PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF nc.postedIncrementally THEN {display.rv.DisplayMessage["Already posted incrementally!"]; RETURN};
nc.postedIncrementally ← TRUE;
nc.ic ← RoseConditions.PostIncrementally[nc.cond];
ViewRec.RedisplayElt[display.conditionsHandle];
END;
RemoveIncremental:
PROC [display: Display] =
BEGIN
nc: NamedCondition ← GetCondition[display];
IF nc = NIL THEN {display.rv.DisplayMessage["Select a condition name"]; RETURN};
IF NOT nc.postedIncrementally THEN {display.rv.DisplayMessage["Not posted incrementally!"]; RETURN};
RoseConditions.UnPostIncrementally[nc.ic];
nc.ic ← NIL;
nc.postedIncrementally ← FALSE;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
AddNamedCondition:
PROC [display: Display, name:
ROPE] =
BEGIN
nc: NamedCondition;
nc ←
NEW [NamedConditionRep ← [
name: name,
cond: display.ctlPanel.condition]];
IF nc.cond = NIL THEN {display.rv.DisplayMessage["empty condition!"]; RETURN};
IF name.Length[] < 1 THEN {display.rv.DisplayMessage["empty name!"]; RETURN};
IF display.ctlPanel.conditions.Lookup[name] # NIL THEN {display.rv.DisplayMessage["already exists!"]; RETURN};
display.ctlPanel.conditions.Insert[nc];
display.ctlPanel.condition ← NIL;
ViewRec.RedisplayElt[display.conditionsHandle];
END;
DeleteNamedCondition:
PROC [display: Display, name:
ROPE ] =
BEGIN
old: REF ANY;
IF name.Length[] < 1 THEN {display.rv.DisplayMessage["empty name!"]; RETURN};
IF display.ctlPanel.conditions.Lookup[name] = NIL THEN {display.rv.DisplayMessage["not found"]; RETURN};
IF (old ← display.ctlPanel.conditions.Delete[name]) = NIL THEN ERROR;
END;
NewDisplay:
PROC [sim: RoseTypes.Simulation, info: ViewerClasses.ViewerRec ← [], cth: RoseTypes.CellTestHandle ←
NIL, paint:
BOOLEAN ←
TRUE]
RETURNS [display: Display] =
BEGIN
OtherStuff: ViewRec.OtherStuffProc
--PROC [in: Viewer] RETURNS [stuff: LIST OF Viewer]-- =
CHECKED
BEGIN
stuff ←
IF display.type = Test
THEN
LIST[ViewRec.RVQuaViewer[ViewRec.ViewRef[
agg: display.parms ← NEW [RoseRun.TestParmsRep ← []],
createOptions: [mayInitiateRelayout: FALSE, feedBackHeight: 0],
viewerInit: [parent: in],
paint: FALSE]]]
ELSE NIL;
END;
rvv: Viewer;
ctlPanel: ControlPanel ←
NEW [ControlPanelRep ← [
conditions: OrderedSymbolTableRef.CreateTable[CompareNamedConditions],
incrementalDisplay: longIncremental,
Pack: Pack,
NoticeEdits: NoticeEdits,
Run: Run,
SingleStep: SingleStep,
Interrupt: Interrupt,
Disable: Disable,
Proceed: Proceed,
Abort: Abort,
ClearStack: ClearStack,
ClearCondition: ClearCondition,
Or: Or,
PostCondition: PostCondition,
RemoveCondition: RemoveCondition,
PostIncremental: PostIncremental,
RemoveIncremental: RemoveIncremental,
AddNamedCondition: AddNamedCondition,
DeleteNamedCondition: DeleteNamedCondition,
Save: Save,
Restore: Restore]];
display ←
NEW [DisplayRep ← [
sim: sim,
rootCell: sim.root,
cth: cth,
type: IF cth = NIL THEN Ordinary ELSE Test,
ctlPanel: ctlPanel,
log: ViewerIO.CreateViewerStreams[name: sim.root.name.Concat[" log"]].out,
conditionHandle: NIL,
conditionsHandle: NIL,
rootDisplay: HierarchicalDisplays.CreateRoot[
viewerInit: [
parent: NIL,
iconic: FALSE,
scrollable: TRUE,
name: sim.root.name.Cat[".display"]],
paint: paint],
rv: NIL]];
display.rv ← ViewRec.ViewRef[
agg: ctlPanel,
specs: ViewRec.BindingListAppend[
LIST[
["mode", Notify[notify: ModeNotify, clientData: display]],
["incrementalDisplay", Notify[notify: IncrNotify, clientData: display]],
["logActivity", Notify[notify: ActivityLogNotify, clientData: display]],
["conditionStack", TryRecognizer[RecognizeTreeNodeList]],
["condition", TryRecognizer[RecognizeTree]],
["conditions", TryRecognizer[RecognizeST]],
["status", Value[val: NIL, visible: TRUE, dontAssign: TRUE]] ] ,
ViewRec.BindAllOfATypeFromRefs[rec: ctlPanel, handle: NEW [Display ← display]] ],
otherStuff: OtherStuff,
createOptions: [exclusiveProcs: FALSE],
viewerInit: [parent: NIL, iconic: FALSE, scrollable: TRUE, name: sim.root.name.Cat[".ops"]],
paint: paint];
rvv ← ViewRec.RVQuaViewer[display.rv];
display.conditionHandle ← display.rv.GetEltHandle[LIST["condition"]];
display.conditionsHandle ← display.rv.GetEltHandle[LIST["conditions"]];
Process.InitializeCondition[
condition: @display.notice,
ticks: Process.SecondsToTicks[5]];
RoseEvents.AddWatcher[event: setIncrementalDisplay, watcher: [NoticeSetIncrementalDisplay, display]];
RoseEvents.AddWatcher[event: $Stop, watcher: [NoticeDisplayStop, display]];
RoseEvents.AddWatcher[event: $Interrupt, watcher: [NoticeDisplayInterrupt, display]];
RoseEvents.AddWatcher[event: $Start, watcher: [NoticeDisplayStart, display]];
END;
cellClass:
PUBLIC HierarchicalDisplays.ChildClass ←
NEW [HierarchicalDisplays.ChildClassRep ← [
buttonProc: DullButtonProc,
NotifyOnRemove: NoticeCellRemoval]];
nodeClass:
PUBLIC HierarchicalDisplays.ChildClass ←
NEW [HierarchicalDisplays.ChildClassRep ← [
buttonProc: DullButtonProc,
NotifyOnRemove: NoticeNodeRemoval]];
DullButtonProc: Buttons.ButtonProc =
TRUSTED
BEGIN
leaf: HierarchicalDisplays.Leaf;
ne: NodeElt;
IF (
IF clientData =
NIL
THEN
TRUE
ELSE
NOT
ISTYPE[clientData, HierarchicalDisplays.Leaf])
THEN
BEGIN
MessageWindow.Append[message: "Don't do that", clearFirst: TRUE];
RETURN;
END;
leaf ← NARROW[clientData];
ne ← NARROW[leaf.instanceData];
SELECT mouseButton
FROM
red => ViewerTools.SetSelection[leaf.value];
yellow => IF control THEN SetFormat[ne, leaf] ELSE AddAnd[ne, shift];
blue => IF control THEN TellFormat[ne] ELSE AddOr[ne, shift];
ENDCASE => ERROR;
END;
TellFormat:
PROC [ne: NodeElt] =
BEGIN
ne.org.display.rv.DisplayMessage[ViewRec.clearMessagePlace];
ne.org.display.rv.DisplayMessage[IO.PutFR[
"Current format is %g, choices are %g",
IO.refAny[ne.format.key],
IO.refAny[ne.node.type.procs.ListFormats[ne.node.type]]]];
END;
SetFormat:
PROC [ne: NodeElt, leaf: HierarchicalDisplays.Leaf] =
BEGIN
fmtKey: ROPE ← ViewerTools.GetSelectionContents[];
fmt: RoseTypes.Format ← ne.node.type.procs.GetFormat[ne.node.type, fmtKey];
IF fmt #
NIL
THEN {
ne.format ← fmt;
TellFormat[ne];
NotifyNodeView[$NewFormat, ne.node, leaf, NIL];
ViewerOps.MoveViewer[viewer: leaf.value,
x: leaf.value.wx, y: leaf.value.wy,
w: ne.format.MaxWidth[ne.node.type, ne.format, VFonts.defaultFont] + 20,
h: leaf.value.wh, paint: FALSE];
}
ELSE {
ne.org.display.rv.DisplayMessage[ViewRec.clearMessagePlace];
ne.org.display.rv.DisplayMessage[
IO.PutFR[
"Format %g unrecognized",
IO.refAny[fmtKey]]]};
END;
AddOr:
PROC [ne: NodeElt, invert:
BOOLEAN] =
BEGIN
display: Display ← ne.org.display;
nt: RoseConditions.NodeTest ←
NEW [RoseConditions.NodeTestRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
cell: ne.org.socket.cell,
testData: ne.testData,
testProc: ne.testProc]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.testProc = NIL THEN {display.rv.DisplayMessage["invalid test"]; RETURN};
IF invert THEN leaf ← Trees.Not[leaf];
Push[display, Pop[display].Or[display.ctlPanel.condition]];
display.ctlPanel.condition ← leaf;
END;
AddAnd:
PROC [ne: NodeElt, invert:
BOOLEAN] =
BEGIN
display: Display ← ne.org.display;
nt: RoseConditions.NodeTest ←
NEW [RoseConditions.NodeTestRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
cell: ne.org.socket.cell,
testData: ne.testData,
testProc: ne.testProc]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.testProc = NIL THEN {display.rv.DisplayMessage["invalid test"]; RETURN};
IF invert THEN leaf ← Trees.Not[leaf];
display.ctlPanel.condition ← Trees.And[display.ctlPanel.condition, leaf];
ViewRec.RedisplayElt[display.conditionHandle];
END;
NoticeCellRemoval: HierarchicalDisplays.ChildNotifyProc =
CHECKED
BEGIN
cb: CellBrowser ← NARROW[child.instanceData];
cb.cell.props ← List.PutAssoc[key: cb.display, val: NIL, aList: cb.cell.props];
IF cb.cell.type = Real THEN RoseEvents.RemoveWatcher[watched: cb.cell, event: $Schedule, watcher: [NotifyCellView, child]];
END;
NoticeNodeRemoval: HierarchicalDisplays.ChildNotifyProc =
TRUSTED
BEGIN
ne: NodeElt ← NARROW[child.instanceData];
displays: NodeDisplayList ← NARROW[List.Assoc[key: nodeDisplaysProp, aList: ne.node.props]];
nd: NodeDisplay;
found: BOOLEAN;
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
[displays, nd, found] ← NDLSearch[ndl: displays, org: ne.org, remove: TRUE];
IF (IF found THEN nd.dc # child ELSE TRUE) THEN ERROR;
ne.node.props ← List.PutAssoc[key: nodeDisplaysProp, val: displays, aList: ne.node.props];
RoseEvents.RemoveWatcher[watched: ne.node, watcher: [NotifyNodeView, leaf], event: $ChangeEarly];
END;
NotifyNodeView:
PUBLIC RoseTypes.NotifyProc =
TRUSTED
BEGIN
node: Node ← NARROW[watched];
leaf: HierarchicalDisplays.Leaf ← NARROW[watcherData];
ne: NodeElt ← NARROW[leaf.instanceData];
v: Viewer ← leaf.value;
val: ROPE;
IF ne.org.display.ctlPanel.mode # Value THEN RETURN;
IF NOT trackChanges THEN {ne.changed ← TRUE; RETURN};
IF ne.badString
THEN
BEGIN
Buttons.SetDisplayStyle[button: leaf.nameButton, style: $BlackOnWhite];
ne.badString ← FALSE;
END;
val ← ne.format.FormatValue[node, ne.format, node.ValWP[]];
ViewerTools.SetContents[v, val];
END;
NotifyCellView:
PUBLIC RoseTypes.NotifyProc =
TRUSTED
BEGIN
cell: Cell ← NARROW[watched];
dc: HierarchicalDisplays.Child ← NARROW[watcherData];
IF trackChanges THEN Buttons.SetDisplayStyle[dc.nameButton, IF cell.realCellStuff.schedNext = RoseTypes.notInCellList THEN $BlackOnWhite ELSE IF cell = cell.parent.CellToStr[].schedFirst THEN $WhiteOnBlack ELSE $BlackOnGrey]
ELSE NARROW[dc.instanceData, CellBrowser].changed ← TRUE;
END;
Or:
PROC [display: Display] =
{display.ctlPanel.condition ← Pop[display].Or[display.ctlPanel.condition]};
Push:
PUBLIC
PROC [display: Display, cond: Condition] =
{display.ctlPanel.conditionStack ← CONS[cond, display.ctlPanel.conditionStack]};
Pop:
PUBLIC
PROC [display: Display]
RETURNS [cond: Condition] =
BEGIN
IF display.ctlPanel.conditionStack = NIL THEN RETURN [NIL];
cond ← display.ctlPanel.conditionStack.first;
display.ctlPanel.conditionStack ← display.ctlPanel.conditionStack.rest;
END;
Save:
PROC [display: Display, fileName:
ROPE]
RETURNS [errMsg:
ROPE] =
{IF NOT NoticeEdits[display] THEN RETURN ["Invalid edits not yet fixed"];
errMsg ← RoseStateIO.Save[display.rootCell, fileName]};
Restore:
PROC [display: Display, fileName:
ROPE]
RETURNS [errMsg:
ROPE] =
{errMsg ← RoseStateIO.Restore[display.rootCell, fileName]};
Setup:
PROC =
BEGIN
TiogaOps.RegisterCommand[name: $InsertLineBreak, proc: TiogaNoticeEdit];
RoseEvents.AddWatcher[event: $Stop, watcher: [NoticeStop]];
RoseEvents.AddWatcher[event: $Interrupt, watcher: [NoticeStop]];
RoseEvents.AddWatcher[event: $Start, watcher: [NoticeStart]];
END;
Setup[];
END.