GraphMenus.mesa, Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by:
Sweetsun Chen, November 17, 1985 1:01:59 am PST
DIRECTORY
FS USING [ComponentPositions, Error, ExpandName],
Graph USING [BackgroundIndex, CaretIndex, ColorMap, ColorMode, EntityList, Error, GraphHandle, GraphProc, ROPE, Viewer],
GraphCleanUp USING [CleanUpEL, CleanUpHandle, CleanUpSDL],
GraphOps USING [Lock, Unlock],
GraphPrivate USING [CallWithLock, GetGraph, PaintAll, SaveGraph, ShowChart, ShowController, SwitchAuto, SwitchCaretVisibility, SwitchCaretBlinking, SwitchSlope, SwitchTarget, SwitchGrid, UserEditAllowed, WriteTextFile],
GraphUtil USING [BlinkMsg, ControllerNotNil, DataBounds, FileFromSelection, HandleFromViewer, HandleNotNil, Print, ReplaceFileExt, SetCursorForBackgroundIndex, UseCedarColors, UseDefaultColors, UseMyColors, WDirOfViewer],
Menus USING [AppendMenuEntry, CreateEntry, CreateMenu, GetNumberOfLines, Menu, MenuLine, MenuProc, MouseButton],
PopUpMenu USING [RequestSelection],
Rope USING [Find, IsEmpty, Substr],
Terminal USING [ColorCursorPresentation, Current, SetColorCursorPresentation, Virtual],
TiogaMenuOps USING [AllLevels, FewerLevels, FirstLevelOnly, MoreLevels],
TiogaOps USING [Jump, ViewerDoc],
ViewerBLT USING [ChangeNumberOfLines],
ViewerOps USING [FindViewer, MoveViewer, OpenIcon, SaveViewer, TopViewer],
ViewerTools USING [GetSelectionContents, MakeNewTextViewer];
GraphMenus: CEDAR PROGRAM
IMPORTS FS, Graph, GraphCleanUp, GraphOps, GraphPrivate, GraphUtil, Menus, PopUpMenu, Rope, Terminal, TiogaMenuOps, ViewerBLT, ViewerOps, ViewerTools
EXPORTS GraphPrivate = { OPEN Graph, GraphOps, GraphPrivate, GraphUtil;
Most of the menu procs in this module acquire the lock at the beginning of execution, and release it after execution. Exceptions: those calling procs in GraphEdit.
menus
ControllerMenus: PUBLIC PROC [] RETURNS [menu: Menus.Menu] = {
menu ← Menus.CreateMenu[2];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry[name: "Chart", proc: ShowChartProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry[name: "Spec", proc: ShowSpecProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry[name: "Values", proc: ShowXYsProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry[name: "Table", proc: ShowTableProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry[name: "Levels", proc: LevelsProc]];
switches
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "AutoDiv", proc: AutoDivisionsProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "AutoBounds", proc: AutoBoundsProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "Xhair1", proc: PrimXhairProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "Xhair2", proc: SecXhairProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "Slope", proc: SlopeProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "TextCaret", proc: TextCaretProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "TargetX", proc: TargetXProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "TargetY", proc: TargetYProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "GridX", proc: GridXProc], 1];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "GridY", proc: GridYProc], 1];
levels menus
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "FirstLevelOnly", proc: FirstLevelOnlyProc], 2];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "MoreLevels", proc: MoreLevelsProc], 2];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "FewerLevels", proc: FewerLevelsProc], 2];
Menus.AppendMenuEntry[
menu, Menus.CreateEntry[name: "AllLevels", proc: AllLevelsProc], 2];
}; -- ControllerMenus
menuprocs
ShowSpecProc: Menus.MenuProc = {
show up the spec panel
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF ControllerNotNil[handle.controller] THEN { OPEN handle.controller;
IF NOT specVisible THEN {
specVisible ← TRUE; -- rule always goes with spec.
xysVisible ← tableVisible ← FALSE;
ViewerOps.MoveViewer[viewer: rule, x: 0, y: 399, w: rule.ww, h: 1, paint: FALSE];
ViewerOps.MoveViewer[viewer: xys, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
IF table # NIL THEN ViewerOps.MoveViewer[
viewer: table, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
ViewerOps.MoveViewer[viewer: spec, x: 0, y: 0, w: viewer.ww, h: 400, paint: TRUE];
ViewerOps.PaintViewer[viewer: viewer, hint: client];
};
};
};
CallWithLock[handle, proc];
}; -- ShowSpecProc
ShowXYsProc: Menus.MenuProc = {
show up the XY values panel
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF ControllerNotNil[handle.controller] THEN { OPEN handle.controller;
IF NOT xysVisible THEN {
xysVisible ← TRUE;
specVisible ← tableVisible ← FALSE; -- rule always goes with spec.
ViewerOps.MoveViewer[viewer: spec, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
ViewerOps.MoveViewer[viewer: rule, x: 1000, y: 0, w: rule.ww, h: 1, paint: FALSE];
IF table # NIL THEN ViewerOps.MoveViewer[
viewer: table, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
ViewerOps.MoveViewer[viewer: xys, x: 0, y: 0, w: viewer.ww, h: 1000, paint: TRUE];
ViewerOps.PaintViewer[viewer: viewer, hint: client];
};
};
};
CallWithLock[handle, proc];
}; -- ShowXYsProc
ShowTableProc: Menus.MenuProc = {
show up the table of texts and curves
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF ControllerNotNil[handle.controller] THEN { OPEN handle.controller;
IF NOT tableVisible THEN {
tableVisible ← TRUE;
specVisible ← xysVisible ← FALSE; -- rule always goes with spec.
ViewerOps.MoveViewer[viewer: spec, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
ViewerOps.MoveViewer[viewer: rule, x: 1000, y: 0, w: rule.ww, h: 1, paint: FALSE];
ViewerOps.MoveViewer[viewer: xys, x: 1000, y: 0, w: 0, h: 0, paint: FALSE];
IF table # NIL THEN ViewerOps.MoveViewer[
viewer: table, x: 0, y: 0, w: viewer.ww, h: 1000, paint: TRUE];
ViewerOps.PaintViewer[viewer: viewer, hint: client];
};
};
};
CallWithLock[handle, proc];
}; -- ShowTableProc
ShowChartProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
Lock[handle];
handle.waitingGraph ← TRUE;
ShowChart[handle]; -- will unlock handle. - No more, 11/13/85.
Unlock[handle]; -- added this on 11/13/85.
}; -- ShowChartProc
LevelsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
IF HandleNotNil[handle] THEN {
Lock[handle]; { OPEN handle;
numLines: Menus.MenuLine ← Menus.GetNumberOfLines[controller.menu];
SELECT numLines FROM
2 => numLines ← 3;
3 => numLines ← 2;
ENDCASE => ERROR;
ViewerBLT.ChangeNumberOfLines[controller.viewer, numLines];
}; Unlock[handle];
};
}; -- SwitchesProc
SwitchIt: PROC [wasOn: BOOL, mouseButton: Menus.MouseButton, label: ROPE] RETURNS [BOOL] = {
RETURN[SELECT mouseButton FROM
red => NOT wasOn,
blue => wasOn,
ENDCASE => SELECT PopUpMenu.RequestSelection[
label: label, choice: LIST["on (red)", "off (blue)"], default: 1] FROM
1 => NOT wasOn,
2 => wasOn,
ENDCASE => FALSE];
}; -- SwitchIt
AutoDivisionsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
IF SwitchIt[graph.auto[divisions], mouseButton, "Auto Division"] THEN SwitchAuto[handle, divisions];
};
CallWithLock[handle, proc];
}; -- AutoDivisionsProc
AutoBoundsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
wasOn: BOOL ← graph.auto[bounds];
update, switchIt: BOOLTRUE;
SELECT mouseButton FROM
red => switchIt ← NOT wasOn;
blue => switchItwasOn;
ENDCASE => SELECT PopUpMenu.RequestSelection[
label: "Auto Bounds", choice: LIST["on (red)", "off (blue)"], default: 1] FROM
1 => switchIt ← NOT wasOn;
2 => switchItwasOn;
ENDCASE => switchIt ← update ← FALSE;
IF switchIt THEN SwitchAuto[handle, bounds]
ELSE IF update THEN {
graph.bounds ← DataBounds[graph.entityList];
IF chart.viewer # NIL THEN PaintAll[handle];
};
};
CallWithLock[handle, proc];
}; -- AutoBoundsProc
PrimXhairProc: Menus.MenuProc = {SwitchCaret[parent, mouseButton, primary, shift]};
SecXhairProc: Menus.MenuProc = {SwitchCaret[parent, mouseButton, secondary, shift]};
TextCaretProc: Menus.MenuProc = {SwitchCaret[parent, mouseButton, text, shift]};
SwitchCaret: PROC[parent: REF ANY, mouseButton: Menus.MouseButton, index: CaretIndex, shift: BOOL] = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
IF shift THEN {
IF SwitchIt[chart.caretState[index].toBlink, mouseButton, "Blinking"] THEN {
SwitchCaretBlinking[handle, index];
IF chart.caretState[index].toBlink AND NOT graph.caret[index].on THEN
SwitchCaretVisibility[handle, index];
}
}
ELSE IF SwitchIt[graph.caret[index].on, mouseButton, "Caret"] THEN SwitchCaretVisibility[handle, index];
};
CallWithLock[handle, proc];
}; -- SwitchCaret
SlopeProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
IF SwitchIt[graph.showSlope, mouseButton, "Slope"] THEN SwitchSlope[handle];
};
CallWithLock[handle, proc];
}; -- SlopeProc
TargetXProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF SwitchIt[handle.graph.target[x].on, mouseButton, "Target X"] THEN
SwitchTarget[handle, x]};
CallWithLock[handle, proc];
}; -- TargetXProc
TargetYProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF SwitchIt[handle.graph.target[y].on, mouseButton, "Target X"] THEN
SwitchTarget[handle, y]};
CallWithLock[handle, proc];
}; -- TargetYProc
GridXProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF SwitchIt[handle.graph.grids[x], mouseButton, "Vertical Grids"] THEN
SwitchGrid[handle, x]};
CallWithLock[handle, proc];
}; -- GridXProc
GridYProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {
IF SwitchIt[handle.graph.grids[y], mouseButton, "Horiz. Grids"] THEN
SwitchGrid[handle, y]};
CallWithLock[handle, proc];
}; -- GridYProc
FirstLevelOnlyProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {TiogaMenuOps.FirstLevelOnly[handle.controller.table]};
CallWithLock[handle, proc];
}; -- FirstLevelOnlyProc
MoreLevelsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {TiogaMenuOps.MoreLevels[handle.controller.table]};
CallWithLock[handle, proc];
}; -- MoreLevelsProc
FewerLevelsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {TiogaMenuOps.FewerLevels[handle.controller.table]};
CallWithLock[handle, proc];
}; -- FewerLevelsProc
AllLevelsProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = {TiogaMenuOps.AllLevels[handle.controller.table]};
CallWithLock[handle, proc];
}; -- AllLevelsProc
ChartMenus: PUBLIC PROC [] RETURNS [menu: Menus.Menu] = {
menu ← Menus.CreateMenu[];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Color", SetColorProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Cursor", SetCursorColorProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Background", SetBackgroundIndexProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Get", GetGraphProc]]; --, guarded: TRUE]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Merge", MergeGraphProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Store", PutGraphProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["List", ListGraphProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Interpress", InterpressProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Clear/Refresh", ClearRefreshProc]];
Menus.AppendMenuEntry
[menu, Menus.CreateEntry["Controller", ShowControllerProc]];
}; -- ChartMenus
menuprocs
SetColorProc: Menus.MenuProc = {
[parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL]
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
newColorMap: ColorMap;
newColorMode: ColorMode;
SELECT PopUpMenu.RequestSelection[
label: "Options",
choice: LIST[
"my colors",
"cedar default colors",
"graph default colors",
"my colors ← graph default",
"black and white"
],
default: 1] FROM
1 => {newColorMode ← color; newColorMap ← mine};
2 => {newColorMode ← color; newColorMap ← cedar};
3 => {newColorMode ← color; newColorMap ← default};
4 => {newColorMode ← color; newColorMap ← replace};
5 => {newColorMode ← bw; newColorMap ← colorMap};
ENDCASE => {newColorMode ← colorMode; newColorMap ← colorMap};
SetCursorForBackgroundIndex[backgroundIndex];
IF colorMode # newColorMode THEN {
colorMode ← newColorMode;
chart.viewer (parent) # nil
PaintAll[handle];
};
IF colorMap # newColorMap THEN {
colorMap ← newColorMap;
SELECT newColorMap FROM
mine => UseMyColors[handle];
cedar => UseCedarColors[];
default => UseDefaultColors[];
replace => UseDefaultColors[handle];
ENDCASE;
};
}; -- proc
CallWithLock[handle, proc];
}; -- SetColorProc
SetCursorColorProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
virtual: Terminal.Virtual ← Terminal.Current[];
SELECT PopUpMenu.RequestSelection[
label: "Options",
choice: LIST["black", "white"],
default: 1] FROM
1 => [] ← Terminal.SetColorCursorPresentation[virtual, onesAreBlack];
2 => [] ← Terminal.SetColorCursorPresentation[virtual, onesAreWhite];
ENDCASE => SetCursorForBackgroundIndex[backgroundIndex]; -- *
};
CallWithLock[handle, proc];
}; -- SetCursorColorProc
SetBackgroundIndexProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
newBkGndIndex: BackgroundIndex = SELECT PopUpMenu.RequestSelection[
label: "Options",
choice: LIST["white", "gray", "dark gray", "black"],
default: 1] FROM
1 => white,
2 => gray,
3 => darkGray,
4 => black,
ENDCASE => backgroundIndex;
IF backgroundIndex # newBkGndIndex THEN {
backgroundIndex ← newBkGndIndex;
SetCursorForBackgroundIndex[backgroundIndex];
PaintAll[handle];
};
};
CallWithLock[handle, proc];
}; -- SetBackgroundIndexProc
GetGraphProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
file, msg: ROPENIL;
[file, msg] ← SelectedFile[WDirOfViewer[chart.viewer], "graph"];
IF msg = NIL THEN {
SELECT PopUpMenu.RequestSelection[
label: "Confirm replacing data with", choice: LIST[file], default: 1] FROM
1 => {
handle ← GraphCleanUp.CleanUpHandle[handle, FALSE];
msg ← GetGraph[handle, file ! Error => {msg ← info; CONTINUE}];
};
ENDCASE;
};
IF msg # NIL THEN BlinkMsg[msg];
};
IF UserEditAllowed[handle] THEN CallWithLock[handle, proc];
}; -- GetGraphProc
SelectedFile: PROC [defaultWDir, defaultExt: ROPE] RETURNS [file, msg: ROPENIL] = {
try selected viewer first.
v: Viewer ← ViewerTools.GetSelectedViewer[];
IF v = NIL THEN msg ← hint
ELSE IF v.class.flavor = $Text THEN file ← v.file
file ← ViewerTools.GetSelectionContents[];
IF file.IsEmpty[] THEN msg ← "Please select a file name."
ELSE {
[file, ] ← FS.ExpandName[file, defaultWDir !
FS.Error => {msg ← error.explanation; CONTINUE}];
IF msg = NIL THEN IF file.Find["."] < 0 THEN file ← ReplaceFileExt[file, defaultExt];
};
}; -- SelectedFile
MergeGraphProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
file, msg: ROPENIL;
[file, msg] ← SelectedFile[WDirOfViewer[chart.viewer], "graph"];
IF msg = NIL THEN {
SELECT PopUpMenu.RequestSelection[
label: "Confirm merging data from", choice: LIST[file], default: 1] FROM
1 => msg ← GetGraph[handle, file ! Error => {msg ← info; CONTINUE}];
ENDCASE;
};
IF msg # NIL THEN BlinkMsg[msg];
};
IF UserEditAllowed[handle] THEN CallWithLock[handle, proc];
}; -- MergeGraphProc
ListGraphProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
file, msg: ROPENIL;
[file, msg] ← SelectedFile[WDirOfViewer[chart.viewer], "list"];
IF msg = NIL THEN {
SELECT PopUpMenu.RequestSelection[
label: "Confirm listing data in", choice: LIST[file], default: 1] FROM
1 => {
v: Viewer;
msg ← WriteTextFile[handle, file];
v ← ViewerOps.FindViewer[file];
IF v = NIL THEN {
v ← ViewerTools.MakeNewTextViewer[info: [name: file, file: file]];
ViewerOps.SaveViewer[v];
};
IF v.iconic THEN ViewerOps.OpenIcon[icon: v, bottom: FALSE]
ELSE ViewerOps.TopViewer[viewer: v];
};
ENDCASE;
};
IF msg # NIL THEN BlinkMsg[msg];
};
CallWithLock[handle, proc];
}; -- ListGraphProc
PutGraphProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
file, msg, viewerName: ROPE;
cp: FS.ComponentPositions;
[viewerName, cp, ] ← FS.ExpandName[handle.chart.viewer.name];
[file, msg] ← FileFromSelection[viewerName.Substr[0, cp.base.start]];
IF msg = NIL THEN {
IF file.Find["."] < 0 THEN file ← ReplaceFileExt[file, "graph"];
SELECT PopUpMenu.RequestSelection[
label: "Confirm file name", choice: LIST[file], default: 1] FROM
1 => msg ← SaveGraph[handle.chart.viewer, file
! Error => {msg ← info; CONTINUE}];
ENDCASE;
};
IF msg # NIL THEN BlinkMsg[msg];
};
CallWithLock[handle, proc];
}; -- PutGraphProc
InterpressProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
printingColorMode, colorModeSave: ColorMode;
okToPrint: BOOLTRUE;
SELECT PopUpMenu.RequestSelection[
label: "Options",
choice: LIST["color", "black and white"],
default: 1] FROM
1 => printingColorMode ← color;
2 => printingColorMode ← bw;
ENDCASE => {
BlinkMsg["You must choose either color or black-and-white."];
okToPrint ← FALSE;
};
IF okToPrint THEN {
colorModeSave ← colorMode;
colorMode ← printingColorMode;
Print[handle];
colorMode ← colorModeSave;
};
};
CallWithLock[handle, proc];
}; -- InterpressProc
ClearRefreshProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
proc: GraphProc = { OPEN handle;
SELECT PopUpMenu.RequestSelection[
label: "Options",
choice: LIST["refresh", "clear and refresh", "remove all curves"],
default: 1] FROM
1 => PaintAll[handle, FALSE];
2 => PaintAll[handle, TRUE];
3 => RemoveAllCurves[handle];
ENDCASE;
};
CallWithLock[handle, proc];
}; -- ClearRefreshProc
RemoveAllCurves: GraphProc = { OPEN handle;
clean up plotted curves from graph viewer.
FOR el: EntityList ← graph.entityList, el.rest UNTIL el = NIL DO
el.first.segments ← GraphCleanUp.CleanUpSDL[el.first.segments];
ENDLOOP;
graph.entityList ← GraphCleanUp.CleanUpEL[graph.entityList, FALSE];
PaintAll[handle, TRUE];
}; -- RemoveAllCurves
ShowControllerProc: Menus.MenuProc = {
handle: GraphHandle ← HandleFromViewer[NARROW[parent]];
IF UserEditAllowed[handle] THEN CallWithLock[handle, ShowController];
}; -- ShowControllerProc
}.
LOG.
SChen, create at October 9, 1985 6:41:19 pm PDT