GraphPanel.mesa, Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by:
Sweetsun Chen, October 20, 1985 10:31:06 pm PDT
DIRECTORY
Buttons USING [ButtonProc, Create],
Containers USING [ChildXBound, --ChildYBound, --Create],
Convert USING [RopeFromInt, RopeFromReal],
ChoiceButtons USING [BuildEnumTypeSelection, SelectionNotifierProc],
Graph USING [Entity, ROPE, Viewer],
GraphConvert USING [AngleFromRope, JustifXFromRope, JustifYFromRope, MarkFromRope, OperandFromRope, RopeOfSlope],
GraphPrivate USING [CallWithLock, ControlAction, Controller, GraphAtomProc, GraphHandle, GraphProc, LockedAtomProc, Operate, PanelRemove, Resume, Update],
GraphUtil USING [GetIntField, HandleNotNil, RaiseError, SetIntField, SetToggleColor],
Imager USING [Font],
Labels USING [Create],
PopUpMenu USING [RequestSelection],
Rules USING [Create],
VFonts USING [EstablishFont],
ViewerOps USING [AddProp, FetchProp],
ViewerTools USING [MakeNewTextViewer, SetContents, SetSelection];
GraphPanel: CEDAR PROGRAM
IMPORTS Buttons, ChoiceButtons, Containers, Convert, GraphConvert, GraphPrivate, GraphUtil, Labels, PopUpMenu, VFonts, ViewerOps, ViewerTools
EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate, GraphUtil;
FlipToggleOnPanel: PUBLIC GraphAtomProc = {
flips the toggles on panel
IF HandleNotNil[handle] THEN { OPEN handle.controller;
SELECT atom FROM
$AutoDiv => auto[divisions] ← SetToggleColor[swDivisions, ~auto[divisions]];
$AutoBounds => auto[bounds] ← SetToggleColor[swBounds, ~auto[bounds]];
$Primary => caretOn[primary] ← SetToggleColor[swCaret[primary], ~caretOn[primary]];
$Secondary => caretOn[secondary] ← SetToggleColor[swCaret[secondary], ~caretOn[secondary]];
$Slope => slopeOn ← SetToggleColor[swSlope, ~slopeOn];
$TextCaret => caretOn[text] ← SetToggleColor[swCaret[text], ~caretOn[text]];
$TargetXOn => targetOn[x] ← SetToggleColor[swTarget[x], ~targetOn[x]];
$TargetYOn => targetOn[y] ← SetToggleColor[swTarget[y], ~targetOn[y]];
$GridX => gridOn[x] ← SetToggleColor[swGrid[x], ~gridOn[x]];
$GridY => gridOn[y] ← SetToggleColor[swGrid[y], ~gridOn[y]];
$Bold => boldOn ← SetToggleColor[swBold, boldOn];
$Italic => italicOn ← SetToggleColor[swItalic, ~italicOn];
ENDCASE => RaiseError[$UnknownAtom];
};
}; -- FlipToggleOnPanel
MakePanel: PUBLIC PROC [handle: GraphHandle] RETURNS [lastHeight: INTEGER] = {
Called by NewController, which should gurantee that handle and its refs are not nil, e.g., chart, graph, controller.
OPEN handle;
entryHeight: CARDINAL = 14;
twiceEntryHeight: CARDINAL = 24;
entryVSpace: CARDINAL = 6;
entryHSpace: CARDINAL = 10;
level1X: CARDINAL = 70;
level2X: CARDINAL = 20;
boldFont: Imager.Font ← VFonts.EstablishFont[family: "TimesRoman", size: 10, bold: TRUE];
mathFont: Imager.Font ← VFonts.EstablishFont[family: "Math", size: 10, bold: FALSE];
prev, panelViewer: Viewer;
NextX: PROC[] RETURNS [INTEGER] = {
RETURN[prev.wx + prev.ww + entryHSpace]};
EntryButton: PROC[name: ROPE, atom: ATOM, autoX: BOOLTRUE, x: INTEGER ← 0, proc: Buttons.ButtonProc ← EntryButtonProc]
RETURNS [Viewer] = {
prev ← Buttons.Create[
info: [
name: name,
parent: panelViewer,
wx: IF autoX THEN 0 ELSE x,
wy: lastHeight,
wh: entryHeight, -- default the width so that it will be computed for us
border: FALSE ],
clientData: atom,
font: boldFont,
proc: proc,
paint: FALSE];
ViewerOps.AddProp[prev, atom, handle];
RETURN[prev]
}; -- EntryButton
Toggle: PROC[name: ROPE, atom: ATOM, on, autoX: BOOLTRUE, x: INTEGER ← level1X]
RETURNS [viewer: Viewer, bool: BOOL] = {
prev ← Buttons.Create[
info: [
name: name,
parent: panelViewer,
wx: IF autoX THEN NextX[] ELSE x,
wy: lastHeight,
wh: entryHeight,
border: TRUE ],
clientData: atom,
proc: ToggleProc,
paint: FALSE];
ViewerOps.AddProp[prev, atom, handle];
RETURN[prev, SetToggleColor[prev, on, FALSE]]
}; -- Toggle
IntField: PROC [label, contents: ROPENIL, width: INTEGER ← 0, autoX: BOOLTRUE, x: INTEGER ← level1X, height: INTEGER ← entryHeight, scrollable: BOOLFALSE] RETURNS [viewer: Viewer] = {
RETURN[Field[label, contents, width, autoX, x, height, scrollable, IntFieldPrompt]];
};
Field: PROC [label, contents: ROPENIL, width: INTEGER ← 0, autoX: BOOLTRUE, x: INTEGER ← level1X, height: INTEGER ← entryHeight, scrollable: BOOLFALSE, prompt: Buttons.ButtonProc ← FieldPrompt] RETURNS [Viewer] = {
labelViewer: Viewer ← prev ← Buttons.Create[
info: [
name: label,
parent: panelViewer,
wx: IF autoX THEN NextX[] ELSE x,
wy: lastHeight,
wh: entryHeight,
border: FALSE ],
clientData: NIL,
proc: prompt,
paint: FALSE];
prev ← ViewerTools.MakeNewTextViewer[
info: [
parent: panelViewer,
wx: NextX[],
wy: lastHeight,
ww: width,
wh: height,
data: contents,
scrollable: scrollable,
border: FALSE],
paint: FALSE];
ViewerOps.AddProp[labelViewer, $Contents, prev];
ViewerOps.AddProp[prev, $Label, label];
RETURN[prev];
}; -- Field
Label: PROC[name: ROPENIL, width: INTEGER ← 0, autoX: BOOLTRUE, x: INTEGER ← 0, font: Imager.Font ← NIL] RETURNS [Viewer] = {
prev ← Labels.Create[
info: [
name: name,
parent: panelViewer,
wx: IF autoX THEN NextX[] ELSE x,
wy: lastHeight,
ww: width,
wh: entryHeight,
border: FALSE ],
font: font,
paint: FALSE];
RETURN[prev];
}; -- Label
OpButton: PROC[name: ROPE, atom: ATOM, autoX: BOOLTRUE, x: INTEGER ← 0, font: Imager.Font ← NIL]
RETURNS [Viewer] = {
prev ← Buttons.Create[
info: [
name: name,
parent: panelViewer,
wx: IF autoX THEN NextX[] ELSE x,
wy: lastHeight,
wh: entryHeight, -- default the width so that it will be computed for us
border: FALSE ],
clientData: atom,
proc: OperationProc,
font: font,
paint: FALSE];
ViewerOps.AddProp[prev, atom, handle];
RETURN[prev]
}; -- OpButton
panelViewer ← controller.panel ← Containers.Create[
info: [
wx: 0, wy: 0, ww: , wh: controller.panelHeight,
border: TRUE,
scrollable: TRUE,
parent: handle.controller.viewer
],
paint: FALSE
];
Containers.ChildXBound[controller.viewer, panelViewer];
Containers.ChildYBound[controller.viewer, panelViewer];
divisions
lastHeight ← entryVSpace;
[] ← EntryButton["Divisions:", $Divisions];
[controller.swDivisions, controller.auto[divisions]] ←
Toggle["Auto", $AutoDiv, graph.auto[divisions], FALSE, level1X];
controller.divX ← IntField["x:", Convert.RopeFromInt[graph.division[x]], 60];
controller.divY ← IntField["y:", Convert.RopeFromInt[graph.division[y]], 60];
bounds
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Bounds:", $Bounds];
[controller.swBounds, controller.auto[bounds]] ← Toggle["Auto", $AutoBounds, graph.auto[bounds], FALSE, level1X];
controller.xmin ← Field["xmin:", Convert.RopeFromReal[graph.bounds.xmin], 50];
controller.ymin ← Field["ymin:", Convert.RopeFromReal[graph.bounds.ymin], 50];
controller.xmax ← Field["xmax:", Convert.RopeFromReal[graph.bounds.xmax], 50];
controller.ymax ← Field["ymax:", Convert.RopeFromReal[graph.bounds.ymax], 50];
crosshairs
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Carets:", $Carets];
[controller.swCaret[primary], controller.caretOn[primary]] ←
Toggle["primary", $Primary, graph.caret[primary].on, FALSE, level1X];
controller.caretPlace[primary][x] ←
Field["x:", Convert.RopeFromReal[graph.caret[primary].place.x], 40];
controller.caretPlace[primary][y] ←
Field["y:", Convert.RopeFromReal[graph.caret[primary].place.y], 40];
[controller.swCaret[secondary], controller.caretOn[secondary]] ←
Toggle["secondary", $Secondary, graph.caret[secondary].on];
controller.caretPlace[secondary][x] ← Field[
"x:", Convert.RopeFromReal[graph.caret[secondary].place.x], 40];
controller.caretPlace[secondary][y] ← Field[
"y:", Convert.RopeFromReal[graph.caret[secondary].place.y], 40];
slope
lastHeight ← lastHeight + entryHeight;
[controller.swSlope, controller.slopeOn] ← Toggle["slope", $Slope, graph.showSlope, FALSE, level1X];
[] ← Label["between crosshairs ="];
controller.slope ← Label[
name: IF NOT graph.showSlope THEN NIL ELSE GraphConvert.RopeOfSlope[
graph.caret[primary].place, graph.caret[secondary].place],
width: 120];
text caret
lastHeight ← lastHeight + entryHeight;
[controller.swCaret[text], controller.caretOn[text]] ←
Toggle["text caret", $TextCaret, graph.caret[text].on, FALSE, level1X];
controller.caretPlace[text][x] ← Field[
"x:", Convert.RopeFromReal[graph.caret[text].place.x], 40];
controller.caretPlace[text][y] ← Field[
"y:", Convert.RopeFromReal[graph.caret[text].place.y], 40];
targets
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Targets:", $Targets];
[controller.swTarget[x], controller.targetOn[x]] ←
Toggle["x", $TargetXOn, graph.target[x].on, FALSE, level1X];
controller.targetWidth[x] ← Field["width:", Convert.RopeFromReal[graph.target[x].width], 40];
controller.targetColor[x] ← Field["color:", Convert.RopeFromInt[graph.target[x].colorIndex], 40];
controller.targetValue[x] ← Field["value:", Convert.RopeFromReal[graph.target[x].value], 200];
lastHeight ← lastHeight + entryHeight;
[controller.swTarget[y], controller.targetOn[y]] ←
Toggle["y", $TargetYOn, graph.target[y].on, FALSE, level1X];
controller.targetWidth[y] ← Field["width:", Convert.RopeFromReal[graph.target[y].width], 40];
controller.targetColor[y] ← Field["color:", Convert.RopeFromInt[graph.target[y].colorIndex], 40];
controller.targetValue[y] ← Field["value:", Convert.RopeFromReal[graph.target[y].value], 200];
grids
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Grids:", $Grids];
[controller.swGrid[x], controller.gridOn[x]] ←
Toggle["x", $GridX, graph.grids[x], FALSE, level1X];
[controller.swGrid[y], controller.gridOn[y]] ←
Toggle["x", $GridY, graph.grids[y]];
color
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Color(", $Color];
controller.colorIndex ← IntField["index:", "0", 40];
[] ← Label[name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.red ← Field["red:", Convert.RopeFromReal[graph.color[0].R], 40, FALSE, level2X];
controller.green ← Field["green:", Convert.RopeFromReal[graph.color[0].G], 40];
controller.blue ← Field["blue:", Convert.RopeFromReal[graph.color[0].B], 40];
font
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Font(", $Font];
controller.fontIndex ← IntField["index:", "0", 40];
[] ← Label[name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.fontFamily ← Field["family:", graph.font[0].family, 100, FALSE, level2X];
[controller.swBold, controller.boldOn] ← Toggle["bold", $Bold, graph.font[0].bold];
[controller.swItalic, controller.italicOn] ← Toggle["italic", $Italic, graph.font[0].italic];
controller.vFontSize ← IntField["screen size:", Convert.RopeFromInt[graph.font[0].vFontSize], 40];
controller.pFontScale ← Field["print scale:", Convert.RopeFromReal[graph.font[0].pFontScale], 100];
text
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton["Text(", $Text];
controller.textId ← IntField["id:", NIL, 70];
[] ← Label[name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.textContent ← Field["name:", NIL, 2000, FALSE, level2X];
Containers.ChildXBound[panelViewer, controller.textContent];
lastHeight ← lastHeight + entryHeight;
controller.textPlaceX ← Field["place x:", NIL, 60, FALSE, level2X];
controller.justifXRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: panelViewer,
x: NextX[], y: lastHeight,
title: "", buttonNames: LIST["left", "center", "right"],
default: "center", notifyClientProc: JustifXNotify, clientdata: handle,
style: menuSelection];
[] ← Label[name: "),", autoX: FALSE, x: controller.justifXRef.nextx];
controller.textPlaceY ← Field["y:", NIL, 60, FALSE, controller.justifXRef.nextx + 10];
controller.justifYRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: panelViewer,
x: NextX[], y: lastHeight,
title: "", buttonNames: LIST["top", "center", "bottom"],
default: "bottom", notifyClientProc: JustifYNotify, clientdata: handle,
style: menuSelection];
[] ← Label[name: "),", autoX: FALSE, x: controller.justifYRef.nextx];
lastHeight ← lastHeight + entryHeight;
controller.textColor ← IntField["color:", NIL, 40, FALSE, level2X];
controller.textFont ← IntField["font:", NIL, 40];
curve
lastHeight ← lastHeight + entryHeight;
[] ← EntryButton[name: "Curve(", atom: $Entity];
controller.entityId ← IntField["id:", NIL, 100];
[] ← Label[name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.entityName ← Field["name:", NIL, 2000, FALSE, level2X];
Containers.ChildXBound[panelViewer, controller.entityName];
lastHeight ← lastHeight + entryHeight;
controller.entityColor ← IntField["color:", NIL, 40, FALSE, level2X];
controller.entityWidth ← Field["width:", NIL, 100];
controller.markRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: panelViewer, x: NextX[], y: lastHeight, title: "mark:",
buttonNames: LIST["none", "round", "square", "diamond", "cross", "dollar", "percent"],
default: "none",
notifyClientProc: MarkNotify,
clientdata: handle,
borderOnButtons: FALSE,
style: flipThru];
[] ← FieldLabel["group id:", $EntityGroupId, FALSE, controller.markRef.nextx];
controller.entityGroupId ← Field[NIL, 40];
lastHeight ← lastHeight + entryHeight;
controller.entityValues ← Field[
label: "values:", contents: NIL, width: 2000, autoX: FALSE, x: level2X, height: twiceEntryHeight, scrollable: TRUE];
Containers.ChildXBound[panelViewer, controller.entityValues];
x
lastHeight ← lastHeight + twiceEntryHeight;
[] ← EntryButton[name: "X", atom: $XEntry];
controller.xValues ← Field[
label: "values:", contents: NIL, width: 2000, autoX: FALSE, x: level2X, height: twiceEntryHeight, scrollable: TRUE];
Containers.ChildXBound[panelViewer, controller.xValues];
curve group
lastHeight ← lastHeight + twiceEntryHeight;
[] ← EntryButton["Curve Group:", $Group];
[] ← FieldLabel["(id:", $GroupId];
controller.groupId ← Field[NIL, 20];
[] ← Label[")"];
lastHeight ← lastHeight + entryHeight;
[] ← FieldLabel["name:", $GroupName, FALSE, level2X];
controller.groupName ← Field[data: NIL, width: 2000];
Containers.ChildXBound[panelViewer, controller.groupName];
lastHeight ← lastHeight + entryHeight;
[] ← FieldLabel["x id:", $XId, FALSE, level2X];
controller.xId ← Field[data: NIL, width: 20];
lastHeight ← lastHeight + entryHeight;
[] ← FieldLabel["y id's:", $YId, FALSE, level2X];
controller.yIds ← Field[
data: NIL, width: 2000, height: twiceEntryHeight, scrollable: TRUE]
Containers.ChildXBound[panelViewer, controller.yIds];
crosssection
lastHeight ← lastHeight + twiceEntryHeight;
[] ← EntryButton["Cross-section(", $Crosssection];
controller.xsectionX ← Field["at x =", NIL, 100];
[] ← Label[name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.xsectionYs ← Field[label: "y's:", autoX: FALSE, x: level2X, width: 2000, height: twiceEntryHeight, scrollable: TRUE];
Containers.ChildXBound[panelViewer, controller.xsectionYs];
operations
lastHeight ← lastHeight + twiceEntryHeight;
[] ← OpButton["+", $Plus, FALSE, 0];
[] ← OpButton["-", $Minus];
[] ← OpButton[name: " ", atom: $Multiply, font: mathFont];
[] ← OpButton[name: "÷", atom: $Divide, font: mathFont];
[] ← OpButton[name: "±", atom: $Sign, font: mathFont];
[] ← OpButton["1/r", $Reciprocal];
[] ← OpButton["e", $Exponential];
[] ← OpButton["log", $Logarithm];
[] ← OpButton["ln", $NaturalLog];
[] ← OpButton[name: "", atom: $SqRt, font: mathFont];
[] ← OpButton["root", $Root];
[] ← OpButton["power", $Power];
[] ← OpButton["sin", $Sine];
[] ← OpButton["cos", $Cosine];
[] ← OpButton["tan", $Tangent];
[] ← OpButton["arctan", $ArcTan];
[] ← OpButton["Original", $Original];
operand
lastHeight ← lastHeight + entryHeight;
controller.operandRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: panelViewer,
x: level2X, y: lastHeight, title: "operand:", buttonNames: LIST["x", "y", "all y"],
default: "all y", notifyClientProc: OperandNotify, clientdata: handle,
style: menuSelection];
argument
controller.argument ← Field["argument:", NIL, 50, FALSE, controller.operandRef.nextx + entryHSpace];
angle
controller.angleRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: panelViewer, x: NextX[], y: lastHeight, title: "angle:",
buttonNames: LIST["degrees", "radians"], default: "radians",
notifyClientProc: AngleNotify, clientdata: handle, style: menuSelection];
rule
lastHeight ← lastHeight + entryHeight + entryVSpace;
prev ← Rules.Create[
info: [parent: panelViewer, wy: lastHeight, ww: 2000, wh: 1],
paint: FALSE];
Containers.ChildXBound[panelViewer, prev];
lastHeight ← lastHeight + 1; -- ← lastHeight + entryHeight;
}; -- MakePanel
EntryButtonProc: Buttons.ButtonProc -- PROC [parent: REF ANY, clientData: REF ANY ← NIL, mouseButton: MouseButton ← red, shift, control: BOOL ← FALSE] -- = {
atom: ATOMNARROW[clientData];
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[NARROW[parent], atom]];
IF HandleNotNil[handle] AND NOT shift THEN {
action: ControlAction ← noop;
IF shift THEN RETURN;
SELECT atom FROM
$Divisions, $Bounds, $Carets, $Targets, $Grids, $XEntry, $Color, $Font => {
SELECT mouseButton FROM
red => action ← IF control THEN update ELSE resume;
yellow => IF NOT control THEN SELECT PopUpMenu.RequestSelection[
"Options", LIST["Show", "Apply"], 1] FROM
1 => action ← resume;
2 => action ← update;
ENDCASE;
ENDCASE;
};
$Crosssection=> {
SELECT mouseButton FROM
red => IF NOT control THEN action ← resume;
yellow => IF NOT control THEN SELECT PopUpMenu.RequestSelection[
"Option", LIST["Show"], 1] FROM
1 => action ← resume;
ENDCASE;
ENDCASE;
};
$Text, $Entity => {
SELECT mouseButton FROM
red => action ← IF control THEN update ELSE resume;
yellow =>
IF NOT control THEN SELECT PopUpMenu.RequestSelection["Options",
LIST["Show", "Apply", "Remove"], 1] FROM
1 => action ← resume;
2 => action ← update;
3 => action ← remove;
ENDCASE;
blue => IF NOT control THEN action ← remove;
ENDCASE;
};
ENDCASE;
SELECT action FROM
resume => LockedAtomProc[handle, atom, Resume];
update => LockedAtomProc[handle, atom, Update];
remove => LockedAtomProc[handle, atom, PanelRemove];
noop => NULL;
ENDCASE => RaiseError[$UnknowAction];
};
}; -- EntryButtonProc
ToggleProc: Buttons.ButtonProc = {
atom: ATOMNARROW[clientData];
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[NARROW[parent], atom]];
LockedAtomProc[handle, atom, FlipToggleOnPanel];
}; -- ToggleProc
FieldPrompt: Buttons.ButtonProc = {
contentsViewer: Viewer ←
NARROW[ViewerOps.FetchProp[NARROW[parent], $Contents]];
IF mouseButton = blue THEN ViewerTools.SetContents[contentsViewer, NIL];
ViewerTools.SetSelection[contentsViewer];
}; -- FieldPrompt
IntFieldPrompt: Buttons.ButtonProc = {
contentsViewer: Viewer ←
NARROW[ViewerOps.FetchProp[NARROW[parent], $Contents]];
IF shift THEN {
msg: ROPE;
old: INT;
[msg, old] ← GetIntField[contentsViewer];
IF msg = NIL THEN {
SELECT mouseButton FROM
red => SetIntField[contentsViewer, old + 1];
blue => SetIntField[contentsViewer, old - 1];
ENDCASE => ViewerTools.SetSelection[contentsViewer];
};
}
ELSE {
SELECT mouseButton FROM
blue => ViewerTools.SetContents[contentsViewer, NIL];
ENDCASE;
ViewerTools.SetSelection[contentsViewer];
};
}; -- IntFieldPrompt
OperationProc: Buttons.ButtonProc = {
atom: ATOMNARROW[clientData];
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[NARROW[parent], atom]];
LockedAtomProc[handle, atom, Operate];
}; -- OperationProc
JustifXNotify: ChoiceButtons.SelectionNotifierProc = {
PROC [name: ROPE, clientdata: REF ANY]
handle: GraphHandle ← NARROW[clientdata];
IF HandleNotNil[handle] THEN {
proc: GraphProc = {
handle.controller.justifX ← GraphConvert.JustifXFromRope[name];
};
CallWithLock[handle, proc];
};
}; -- JustifXNotify
JustifYNotify: ChoiceButtons.SelectionNotifierProc = {
handle: GraphHandle ← NARROW[clientdata];
IF HandleNotNil[handle] THEN {
proc: GraphProc = {
handle.controller.justifY ← GraphConvert.JustifYFromRope[name];
};
CallWithLock[handle, proc];
};
}; -- JustifYNotify
MarkNotify: ChoiceButtons.SelectionNotifierProc = {
handle: GraphHandle ← NARROW[clientdata];
IF HandleNotNil[handle] THEN {
proc: GraphProc = {
handle.controller.mark ← GraphConvert.MarkFromRope[name];
};
CallWithLock[handle, proc];
};
}; -- MarkNotify
OperandNotify: ChoiceButtons.SelectionNotifierProc = {
handle: GraphHandle ← NARROW[clientdata];
IF HandleNotNil[handle] THEN {
proc: GraphProc = {
handle.controller.operand ← GraphConvert.OperandFromRope[name];
};
CallWithLock[handle, proc];
};
}; -- OperandNotify
AngleNotify: ChoiceButtons.SelectionNotifierProc = {
handle: GraphHandle ← NARROW[clientdata];
IF HandleNotNil[handle] THEN {
proc: GraphProc = {
handle.controller.angle ← GraphConvert.AngleFromRope[name];
};
CallWithLock[handle, proc];
};
}; -- AngleNotify
}.
LOG.
SChen, created at October 9, 1985 6:49:24 pm PDT.