FILE: RoseDisplayOps.Mesa
Last Edited by: Spreitzer, July 11, 1985 10:31:59 pm PDT
Last Edited by: Barth, June 9, 1983 11:19 am
Last Edited by: Gasbarro, July 17, 1984 3:57:59 pm PDT
DIRECTORY AMBridge, AMTypes, Asserting, Atom, Basics, Buttons, HierarchicalDisplays, Icons, IO, Labels, MessageWindow, PrincOps, PrincOpsUtils, Process, RedBlackTree, Rope, RoseConditions, RoseCreate, RoseDisplayInsides, RoseEvents, RoseRun, RoseStateIO, RoseTypes, TiogaOps, Trees, VFonts, ViewerClasses, ViewerIO, ViewerOps, ViewerTools, ViewRec;
RoseDisplayOps:
CEDAR
MONITOR
IMPORTS AMBridge, AMTypes, Asserting, Atom, Buttons, HierarchicalDisplays, Icons, IO, MessageWindow, PrincOpsUtils, Process, RedBlackTree, Rope, RoseConditions, RoseCreate, 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
];
displayIcon: Icons.IconFlavor ← Icons.NewIconFromFile["Rosemary.icons", 0];
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 ← TVfR[nodeAsNode];
treeAsTree: REF TreeNode ← NEW [TreeNode ← NIL];
treeAsTV: AMTypes.TypedVariable ← TVfR[treeAsTree];
tnlAsTNL: REF TreeNodeList ← NEW [TreeNodeList ← NIL];
tnlAsTV: AMTypes.TypedVariable ← TVfR[tnlAsTNL];
stAsST: REF SymbolTable ← NEW [SymbolTable ← NIL];
stAsTV: AMTypes.TypedVariable ← TVfR[stAsST];
TVfR:
PROC [r:
REF
ANY]
RETURNS [tv: AMTypes.TypedVariable] =
TRUSTED {tv ← AMBridge.TVForReferent[r]};
UnParseTree: ViewRec.UnParseProc =
BEGIN
AMTypes.Assign[lhs: treeAsTV, rhs: tv];
asRope ← Trees.Format[who: treeAsTree^, style: Algebraic];
END;
MaxTree: ViewRec.MaxProc =
{RETURN [lines: 2, maxWidthNeeded: 1024]};
RecognizeTree: ViewRec.Recognizer =
{RETURN [TRUE, treeHandler, NIL]};
UnParseTreeNodeList: ViewRec.UnParseProc =
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 =
{RETURN [lines: 3, maxWidthNeeded: 1024]};
RecognizeTreeNodeList: ViewRec.Recognizer =
{RETURN [TRUE, treeNodeListHandler, NIL]};
UnParseST: ViewRec.UnParseProc =
BEGIN
EatIt:
PROC [asAny:
REF
ANY]
RETURNS [abort:
BOOLEAN] =
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 =
{RETURN [lines: 5, maxWidthNeeded: 1024]};
RecognizeST: ViewRec.Recognizer =
{RETURN [TRUE, stHandler, NIL]};
GetNamedConditionKey:
PROC [data:
REF
ANY]
RETURNS [key:
ROPE]
--RedBlackTree.GetKey-- =
{nc: NamedCondition ← NARROW[data]; key ← nc.name};
CompareNamedConditions:
PROC [k, data:
REF
ANY]
RETURNS [c: Basics.Comparison]
--RedBlackTree.Compare-- =
BEGIN
s1: ROPE ← NARROW[k];
s2: ROPE ← GetNamedConditionKey[data];
c ← s1.Compare[s2];
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]-- =
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, FormatNE[ne]];
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 RoseEvents.NotifyProc =
{IF (longing ← longing + 1) > 0 THEN trackChanges ← longIncremental};
NoticeStop:
ENTRY RoseEvents.NotifyProc =
{
IF (longing ← longing - 1) < 1
AND
NOT trackChanges
THEN
{LookForChanges[]; trackChanges ← TRUE}};
NoticeDisplayStart:
ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Running};
NoticeDisplayInterrupt:
ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Interrupted};
NoticeDisplayStop:
ENTRY RoseEvents.NotifyProc =
{display: Display ← NARROW[watcherData]; display.ctlPanel.status ← Idle};
activityNames:
ARRAY LogSubject
OF
LIST
OF
ATOM = [
nodeValueChanges: LIST[$ChangeEarly],
switchComputationSteps: LIST[$Perturbed, $Found, $NewNodeQ, $NewNodeUD]
];
LoggingNotify:
ENTRY
PROC [clientData:
REF
ANY]
--ViewRec.NotifyClientProc-- =
BEGIN
display: Display ← NARROW[clientData];
logging: Logging ← display.ctlPanel.logging;
FOR ls: LogSubject
IN LogSubject
DO
IF logging[ls] # display.logging[ls]
THEN {
FOR la:
LIST
OF
ATOM ← activityNames[ls], la.rest
WHILE la #
NIL
DO
(
IF logging[ls]
THEN RoseEvents.AddWatcher
ELSE RoseEvents.RemoveWatcher)[
event: la.first,
watcher: [NotifyActivity, display],
watched: RoseEvents.all
];
ENDLOOP;
display.logging[ls] ← logging[ls];
};
ENDLOOP;
END;
NotifyActivity:
PUBLIC
PROC [event:
ATOM, watched, watcherData, arg:
REF
ANY]
--RoseEvents.NotifyProc-- =
BEGIN
display: Display ← NARROW[watcherData];
node: Node ← NARROW[watched];
agitator: RoseTypes.Slot ← IF arg = NIL THEN RoseTypes.nilSlot ELSE NARROW[arg, RoseRun.SlotRef]^;
agName:
ROPE ←
IF agitator # RoseTypes.nilSlot
THEN Rope.Cat[
RoseCreate.LongCellName[agitator.cell],
".",
agitator.cell.realCellStuff.effectivePorts[agitator.effectivePortIndex].name
]
ELSE NIL;
nodeName: ROPE ← RoseCreate.LongNodeName[node];
fmtName, opName: ROPE ← NIL;
fmt: RoseTypes.Format ← NIL;
SELECT event
FROM
$ChangeEarly, $ChangeLate => {fmtName ← ""; opName ← "←"};
$Perturbed => opName ← "Perturbed";
$Found => opName ← "Found";
$NewNodeQ => {opName ← "←Q"; IF node.significances[inImpl] THEN fmtName ← "QUD"};
$NewNodeUD => {opName ← "←UD"; IF node.significances[inImpl] THEN fmtName ← "QUD"};
ENDCASE => ERROR;
display.log.PutRope[nodeName.Cat[" ", opName]];
IF fmtName # NIL THEN fmt ← node.type.procs.GetFormat[node.type, fmtName];
IF fmt # NIL THEN display.log.PutRope[Rope.Cat[" ", fmt.FormatValue[node, fmt, node.valPtr]]];
IF agName # NIL THEN display.log.PutRope[Rope.Cat[" by ", agName]];
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: RoseEvents.NotifyProc =
CHECKED BEGIN
display: Display ← NARROW[watcherData];
display.ctlPanel.incrementalDisplay ← longIncremental;
END;
TiogaNoticeEdit:
PROC [viewer: Viewer ←
NIL]
RETURNS [recordAtom:
BOOL ←
TRUE, quit:
BOOL ←
FALSE]
--TiogaOps.CommandProc-- =
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
ts: IO.STREAM;
IF ne.node.valPtr = RoseTypes.nilPtr THEN ERROR;
ViewerTools.InhibitUserEdits[leaf.value];
ts ← IO.RIS[ViewerTools.GetContents[leaf.value]];
success ← ne.format.ParseValue[ne.node, ne.format, NCOPtr[ne.node, ne.org.circ], ts];
ts.Close[];
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
test: RoseTypes.NodeTest;
ts: IO.STREAM;
ViewerTools.InhibitUserEdits[leaf.value];
ts ← IO.RIS[ViewerTools.GetContents[leaf.value]];
[success, test] ← 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.test ← test;
--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;
FormatNE:
PUBLIC
PROC [ne: NodeElt]
RETURNS [rope:
ROPE] = {
rope ←
SELECT ne.org.display.ctlPanel.mode
FROM
Value => ne.format.FormatValue[
ne.node,
ne.format,
NCOPtr[ne.node, ne.org.circ]],
Test => ne.format.FormatTest[
ne.node.type,
ne.format,
ne.test],
ENDCASE => ERROR;
};
NCOPtr:
PUBLIC
PROC [n: Node, nco: NodeCircuitOrigin]
RETURNS [p: Ptr] =
{p ← n.valPtr};
NoticeEdits:
PROC [display: Display]
RETURNS [
AOK:
BOOLEAN] =
BEGIN
Notice: HierarchicalDisplays.ChildNotifyProc =
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:
PROC [display: Display, msg:
ROPE, data:
REF
ANY]
RETURNS [sr: StopResponse] =
BEGIN
RoseEvents.Notify[event: $Interrupt, handleAborted: TRUE];
sr ← ReallyGetStopResponse[display, msg, data];
RoseEvents.Notify[event: $Start, handleAborted: TRUE];
END;
ReallyGetStopResponse:
ENTRY
PROC [display: Display, msg:
ROPE, data:
REF
ANY]
RETURNS [sr: StopResponse] =
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 =>
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, 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 =>
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 =
BEGIN
leaf: HierarchicalDisplays.Leaf ← NARROW[child];
WITH leaf.instanceData
SELECT
FROM
ne: NodeElt =>
BEGIN
val: ROPE ← FormatNE[ne];
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 =
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.test];
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 =
{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.PostOnSettle[
sim: display.sim,
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.UnPostOnSettle[
sim: display.sim,
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, nc.name];
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;
MakeInterface:
PROC [sim: RoseTypes.Simulation] = {
[] ← BrowseDisplay[
display: NewDisplay[sim, [iconic: FALSE]],
info: [iconic: FALSE]
];
};
NewDisplay:
PUBLIC
PROC [sim: RoseTypes.Simulation, info: ViewerClasses.ViewerRec ← [], paint:
BOOLEAN ←
TRUE]
RETURNS [display: Display] =
BEGIN
OtherStuff: ViewRec.OtherStuffProc
--PROC [in: Viewer] RETURNS [stuff: LIST OF Viewer]-- =
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: RedBlackTree.Create[GetNamedConditionKey, 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: sim.cth,
type: IF sim.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"],
icon: displayIcon
],
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]],
["logging", Group[sublist:
LIST[
[NEW [INT ← 1], Notify[notify: LoggingNotify, clientData: display]],
[NEW [INT ← 2], Notify[notify: LoggingNotify, 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: [maxEltsHeight: 100, 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"]];
TRUSTED {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 =
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]]]];
oldFmtKey ← oldFmtKey;
END;
oldFmtKey: ROPE ← "?there was no old format key?";
SetFormat:
PROC [ne: NodeElt, leaf: HierarchicalDisplays.Leaf] =
BEGIN
fmtKey: ROPE ← ViewerTools.GetSelectionContents[];
fmt: RoseTypes.Format;
IF fmtKey.Length[] = 0 THEN fmtKey ← oldFmtKey;
fmt ← 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]]]};
oldFmtKey ← fmtKey;
END;
AddOr:
PROC [ne: NodeElt, invert:
BOOLEAN] =
BEGIN
display: Display ← ne.org.display;
nt: RoseConditions.NodeTester ←
NEW [RoseConditions.NodeTesterRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
test: ne.test]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.test.proc = 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.NodeTester ←
NEW [RoseConditions.NodeTesterRep ← [
node: ne.node,
nodeName: ne.name,
nodeFormat: ne.format,
test: ne.test]];
leaf: TreeNode ← Trees.Leaf[nt, RoseConditions.test];
IF nt.test.proc = 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 =
BEGIN
cb: CellBrowser ← NARROW[child.instanceData];
cb.cell.other ← Asserting.AssertFn1[fn: cb.display, val: NIL, inAdditionTo: cb.cell.other];
IF cb.cell.substantiality = Real THEN RoseEvents.RemoveWatcher[watched: cb.cell, event: $Schedule, watcher: [NotifyCellView, child]];
END;
NoticeNodeRemoval: HierarchicalDisplays.ChildNotifyProc =
BEGIN
ne: NodeElt ← NARROW[child.instanceData];
displays: NodeDisplayList ← NARROW[Asserting.FnVal[fn: nodeDisplaysProp, from: ne.node.other]];
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.other ← Asserting.AssertFn1[fn: nodeDisplaysProp, val: displays, inAdditionTo: ne.node.other];
RoseEvents.RemoveWatcher[watched: ne.node, watcher: [NotifyNodeView, leaf], event: $ChangeEarly];
END;
NotifyNodeView:
PUBLIC RoseEvents.NotifyProc =
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 ← FormatNE[ne];
ViewerTools.SetContents[v, val];
END;
NotifyCellView:
PUBLIC RoseEvents.NotifyProc =
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"];
TRUSTED {errMsg ← RoseStateIO.Save[display.rootCell, fileName]}};
Restore:
PROC [display: Display, fileName:
ROPE]
RETURNS [errMsg:
ROPE] =
TRUSTED {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.