GraphPanel.mesa, Copyright © 1985 by Xerox Corporation. All rights reserved.
Last Edited by:
Sweetsun Chen, November 15, 1985 6:12:12 pm PST
DIRECTORY
Buttons USING [ButtonProc, Create],
Containers USING [ChildXBound, ChildYBound, Create],
Convert USING [RopeFromInt, RopeFromReal],
ChoiceButtons USING [BuildEnumTypeSelection, SelectionNotifierProc],
Graph USING [ControlAction, Controller, Entity, GraphHandle, GraphProc, ROPE, Viewer],
GraphConvert USING [AngleFromRope, JustifXFromRope, JustifYFromRope, MarkFromRope, OperandFromRope, RopeOfSlope],
GraphPrivate USING [CallWithLock, GraphAtomProc, GraphPlaceProc, LockedAtomProc, Operate, SpecRemove, ResumeFromPanel, Update, UserEditAllowed],
GraphUtil USING [ControllerViewerExits, GetIntField, HandleNotNil, RaiseError, SetIntField, SetToggleColor],
Imager USING [Font],
Labels USING [Create, Set],
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, Rules, VFonts, ViewerOps, ViewerTools
EXPORTS GraphPrivate = { OPEN Graph, GraphPrivate, GraphUtil;
entryHeight: CARDINAL = 14;
twiceEntryHeight: CARDINAL = 24;
entryVSpace: CARDINAL = 6;
entryHSpace: CARDINAL = 2;
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];
FlipToggle: PUBLIC GraphAtomProc = {
flips the toggles on spec
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];
};
}; -- FlipToggle
MakeSpec: PUBLIC GraphPlaceProc = { OPEN handle;
Called by NewController, which should gurantee that handle and its refs are not nil, e.g., chart, graph, controller.
SpecEntry: PROC[name: ROPE, atom: ATOM, autoX: BOOLTRUE, x: INTEGER ← 0] = {
prev ← Buttons.Create[
info: [
name: name,
parent: spec,
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: SpecEntryProc,
paint: FALSE];
ViewerOps.AddProp[prev, atom, handle];
}; -- SpecEntry
Toggle: PROC[name: ROPE, atom: ATOM, on, autoX: BOOLTRUE, x: INTEGER ← level1X]
RETURNS [viewer: Viewer, bool: BOOL] = {
prev ← Buttons.Create[
info: [
name: name,
parent: spec,
wx: IF autoX THEN NextX[prev] 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
prev, spec: Viewer;
lastHeight: INTEGER ← entryVSpace;
spec ← controller.spec ← Containers.Create[
info: [
wx: sx, wy: sy, ww: , wh: 400,
border: FALSE,
scrollable: TRUE,
parent: controller.viewer
],
paint: FALSE
];
Containers.ChildXBound[controller.viewer, spec];
Containers.ChildYBound[controller.viewer, spec];
divisions
SpecEntry["Divisions:", $Divisions];
[controller.swDivisions, controller.auto[divisions]] ← Toggle[
"Auto", $AutoDiv, graph.auto[divisions], FALSE, level1X];
controller.divX ← prev ← IntField[prev, spec, lastHeight,
"x:", Convert.RopeFromInt[graph.division[x]], 60];
controller.divY ← prev ← IntField[prev, spec, lastHeight,
"y:", Convert.RopeFromInt[graph.division[y]], 60];
bounds
lastHeight ← lastHeight + entryHeight;
SpecEntry["Bounds:", $Bounds];
[controller.swBounds, controller.auto[bounds]] ← Toggle[
"Auto", $AutoBounds, graph.auto[bounds], FALSE, level1X];
controller.xmin ← prev ← Field[prev, spec, lastHeight,
"xmin:", Convert.RopeFromReal[graph.bounds.xmin], 50];
controller.xmax ← prev ← Field[prev, spec, lastHeight,
"xmax:", Convert.RopeFromReal[graph.bounds.xmax], 50];
controller.ymin ← prev ← Field[prev, spec, lastHeight,
"ymin:", Convert.RopeFromReal[graph.bounds.ymin], 50];
controller.ymax ← prev ← Field[prev, spec, lastHeight,
"ymax:", Convert.RopeFromReal[graph.bounds.ymax], 50];
crosshairs
lastHeight ← lastHeight + entryHeight;
SpecEntry["Carets:", $Carets];
[controller.swCaret[primary], controller.caretOn[primary]] ← Toggle[
"primary", $Primary, graph.caret[primary].on, FALSE, level1X];
controller.caretPlace[primary][x] ← prev ← Field[prev, spec, lastHeight,
"x:", Convert.RopeFromReal[graph.caret[primary].place.x], 40];
controller.caretPlace[primary][y] ← prev ← Field[prev, spec, lastHeight,
"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] ← prev ← Field[prev, spec, lastHeight,
"x:", Convert.RopeFromReal[graph.caret[secondary].place.x], 40];
controller.caretPlace[secondary][y] ← prev ← Field[prev, spec, lastHeight,
"y:", Convert.RopeFromReal[graph.caret[secondary].place.y], 40];
slope
lastHeight ← lastHeight + entryHeight;
[controller.swSlope, controller.slopeOn] ← Toggle[
"slope", $Slope, graph.showSlope, FALSE, level1X];
prev ← Label[prev, spec, lastHeight, "between crosshairs ="];
controller.slope ← prev ← Label[prev: prev, parent: spec, lastHeight: lastHeight,
name: IF graph.showSlope THEN GraphConvert.RopeOfSlope[
graph.caret[primary].place, graph.caret[secondary].place]
ELSE NIL,
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] ← prev ← Field[prev, spec, lastHeight,
"x:", Convert.RopeFromReal[graph.caret[text].place.x], 40];
controller.caretPlace[text][y] ← prev ← Field[prev, spec, lastHeight,
"y:", Convert.RopeFromReal[graph.caret[text].place.y], 40];
targets
lastHeight ← lastHeight + entryHeight;
SpecEntry["Targets:", $Targets];
[controller.swTarget[x], controller.targetOn[x]] ←
Toggle["x", $TargetXOn, graph.target[x].on, FALSE, level1X];
controller.targetWidth[x] ← prev ← Field[prev, spec, lastHeight,
"width:", Convert.RopeFromReal[graph.target[x].width], 40];
controller.targetColor[x] ← prev ← Field[prev, spec, lastHeight,
"color:", Convert.RopeFromInt[graph.target[x].colorIndex], 40];
controller.targetValue[x] ← prev ← Field[prev, spec, lastHeight,
"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] ← prev ← Field[prev, spec, lastHeight,
"width:", Convert.RopeFromReal[graph.target[y].width], 40];
controller.targetColor[y] ← prev ← Field[prev, spec, lastHeight,
"color:", Convert.RopeFromInt[graph.target[y].colorIndex], 40];
controller.targetValue[y] ← prev ← Field[prev, spec, lastHeight,
"value:", Convert.RopeFromReal[graph.target[y].value], 200];
grids
lastHeight ← lastHeight + entryHeight;
SpecEntry["Grids:", $Grids];
[controller.swGrid[x], controller.gridOn[x]] ← Toggle[
"x", $GridX, graph.grids[x], FALSE, level1X];
[controller.swGrid[y], controller.gridOn[y]] ← Toggle[
"y", $GridY, graph.grids[y]];
color
lastHeight ← lastHeight + entryHeight;
SpecEntry["Color(", $Color];
controller.colorIndex ← prev ← IntField[prev, spec, lastHeight, "index:", "0", 40];
prev ← Label[prev: prev, parent: spec, lastHeight: lastHeight, name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.red ← prev ← Field[prev, spec, lastHeight,
"red:", Convert.RopeFromReal[graph.color[0].R], 40, FALSE, level2X];
controller.green ← prev ← Field[prev, spec, lastHeight,
"green:", Convert.RopeFromReal[graph.color[0].G], 40];
controller.blue ← prev ← Field[prev, spec, lastHeight,
"blue:", Convert.RopeFromReal[graph.color[0].B], 40];
font
lastHeight ← lastHeight + entryHeight;
SpecEntry["Font(", $Font];
controller.fontIndex ← prev ← IntField[prev, spec, lastHeight, "index:", "0", 40];
prev ← Label[prev: prev, parent: spec, lastHeight: lastHeight, name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.fontFamily ← prev ← Field[prev, spec, lastHeight,
"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 ← prev ← IntField[prev, spec, lastHeight,
"screen size:", Convert.RopeFromInt[graph.font[0].vFontSize], 40];
controller.pFontScale ← prev ← Field[prev, spec, lastHeight,
"print scale:", Convert.RopeFromReal[graph.font[0].pFontScale], 100];
text
lastHeight ← lastHeight + entryHeight;
SpecEntry["Text(", $Text];
controller.textId ← prev ← IntField[prev, spec, lastHeight, "id:", NIL, 70];
prev ← Label[prev: prev, parent: spec, lastHeight: lastHeight, name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.textContent ← prev ← Field[prev, spec, lastHeight, "name:", NIL, 2000, FALSE, level2X];
Containers.ChildXBound[spec, controller.textContent];
lastHeight ← lastHeight + entryHeight;
controller.textPlaceX ← prev ← Field[prev, spec, lastHeight, "place x:", NIL, 60, FALSE, level2X];
controller.justifXRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: spec,
x: NextX[prev], 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 ← prev ← Field[prev, spec, lastHeight,
"y:", NIL, 60, FALSE, controller.justifXRef.nextx + 10];
controller.justifYRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: spec,
x: NextX[prev], 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 ← prev ← IntField[prev, spec, lastHeight, "color:", NIL, 40, FALSE, level2X];
controller.textFont ← prev ← IntField[prev, spec, lastHeight, "font:", NIL, 40];
controller.textRotation ← prev ← Field[prev, spec, lastHeight, "rotation:", NIL, 60];
curve
lastHeight ← lastHeight + entryHeight;
SpecEntry["Curve(", $Entity];
controller.entityId ← prev ← IntField[prev, spec, lastHeight, "id:", NIL, 100];
prev ← Label[prev: prev, parent: spec, lastHeight: lastHeight, name: "):", font: boldFont];
lastHeight ← lastHeight + entryHeight;
controller.entityName ← prev ← Field[prev, spec, lastHeight,
"name:", NIL, 1000, FALSE, level2X];
Containers.ChildXBound[spec, controller.entityName];
lastHeight ← lastHeight + entryHeight;
controller.entityCmt ← prev ← Field[prev, spec, lastHeight,
"comment:", NIL, 1000, FALSE, level2X];
Containers.ChildXBound[spec, controller.entityCmt];
lastHeight ← lastHeight + entryHeight;
controller.entityColor ← prev ← IntField[prev, spec, lastHeight,
"color:", NIL, 40, FALSE, level2X];
controller.entityWidth ← prev ← Field[prev, spec, lastHeight, "width:", NIL, 100];
controller.markRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: spec, x: NextX[prev], 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];
curve group
lastHeight ← lastHeight + twiceEntryHeight;
[] ← SpecEntry["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[spec, 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[spec, controller.yIds];
rule
lastHeight ← lastHeight + entryHeight + entryVSpace;
prev ← Rules.Create[
info: [parent: spec, wy: 400, ww: 1000, wh: 1],
paint: FALSE];
Containers.ChildXBound[spec, prev];
}; -- MakeSpec
MakeRule: PUBLIC GraphPlaceProc = { OPEN handle;
Called by NewController, which should gurantee that handle and its refs are not nil.
controller.rule ← Rules.Create[
info: [parent: controller.viewer, wx: sx, wy: sy, ww: 1000, wh: 1],
paint: FALSE];
Containers.ChildXBound[controller.viewer, controller.rule];
}; -- MakeRule
MakeXYValues: PUBLIC GraphPlaceProc = { OPEN handle;
Called by NewController, which should gurantee that handle and its refs are not nil, e.g., chart, graph, controller.
OpButton: PROC[name: ROPE, atom: ATOM, autoX: BOOLTRUE, x: INTEGER ← 0, font: Imager.Font ← boldFont] = {
prev ← Buttons.Create[
info: [
name: name,
parent: xys,
wx: IF autoX THEN NextX[prev] 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];
}; -- OpButton
ValuesEntry: PROC[name: ROPE, proc: Buttons.ButtonProc ← NIL] = {
prev ← Buttons.Create[
info: [
name: name,
parent: xys,
wx: NextX[prev],
wy: lastHeight,
wh: entryHeight, -- default the width so that it will be computed for us
border: FALSE ],
clientData: handle,
font: boldFont,
proc: proc,
paint: FALSE];
}; -- ValuesEntry
prev, xys: Viewer ← NIL;
lastHeight: INTEGER ← entryVSpace;
xys ← controller.xys ← Containers.Create[
info: [
wx: sx, wy: sy, ww: 1000, wh: 1000,
border: FALSE,
scrollable: FALSE,
parent: controller.viewer
],
paint: FALSE
];
Containers.ChildXBound[controller.viewer, xys];
Containers.ChildYBound[controller.viewer, xys];
<Line 1>
title
prev ← Label[prev, xys, lastHeight, "Math operations", 0, FALSE, 0];
operand
controller.operandRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: xys,
x: NextX[prev], y: lastHeight, title: "operand:",
buttonNames: LIST["selected y", "plotted y's", "x"], default: "selected y",
notifyClientProc: OperandNotify, clientdata: handle,
style: menuSelection];
resume values
OpButton["Resume", $Original, FALSE, controller.operandRef.nextx + 20];
<Line 2>
unary operations
lastHeight ← lastHeight + entryHeight;
OpButton[name: "±", atom: $Sign, autoX: FALSE, x: 0, font: mathFont];
OpButton["abs", $Abs];
OpButton["1/r", $Reciprocal];
OpButton["e", $Exponential];
OpButton["ln", $NaturalLog];
OpButton["db", $DB];
OpButton["sqrt", $SqRt];
OpButton["sin", $Sine];
OpButton["cos", $Cosine];
OpButton["tan", $Tangent];
OpButton["atan", $ArcTan];
angle
controller.angleRef ← ChoiceButtons.BuildEnumTypeSelection[
viewer: xys, x: 300, y: lastHeight, title: "angle:",
buttonNames: LIST["degrees", "radians"], default: "radians",
notifyClientProc: AngleNotify, clientdata: handle, style: menuSelection];
<Line 3>
binary operations
lastHeight ← lastHeight + entryHeight;
OpButton["+", $Plus, FALSE, 0];
OpButton["-", $Minus];
OpButton[name: " ", atom: $Multiply, font: mathFont];
OpButton[name: "÷", atom: $Divide, font: mathFont];
OpButton["log", $Logarithm];
OpButton["root", $Root];
OpButton["power", $Power];
argument
controller.argument ← prev ← Field[prev, xys, lastHeight, "argument:", NIL, 50, FALSE, 300];
rule
lastHeight ← lastHeight + entryHeight + entryVSpace;
prev ← Rules.Create[info: [parent: xys, wy: lastHeight, ww: 0, wh: 1], paint: FALSE];
Containers.ChildXBound[xys, prev];
xy values
lastHeight ← lastHeight + entryVSpace;
controller.xyLabel ← prev ← Label[prev, xys, lastHeight, NIL, 15, FALSE, 0, mathFont];
prev ← Label[prev, xys, lastHeight, "Values of", 0, FALSE, entryHSpace];
controller.xyLabel ← prev ← Labels.Create[
info: [name: NIL, parent: xys, border: TRUE,
wx: NextX[prev], wy: lastHeight, ww: 17, wh: entryHeight],
font: mathFont, paint: FALSE];
ValuesEntry["curve(", XYEntryProc];
controller.idOfy ← prev ← IntField[prev, xys, lastHeight, "id:", NIL, 90];
prev ← Label[prev: prev, parent: xys, lastHeight: lastHeight, name: ") ", font: boldFont];
crosssection
lastHeight ← lastHeight + entryHeight;
controller.xsecLabel ← prev ← Label[prev, xys, lastHeight, NIL, 15, FALSE, 0, mathFont];
controller.xsecLabel ← prev ← Labels.Create[
info: [name: NIL, parent: xys, border: TRUE,
wx: NextX[prev], wy: lastHeight, ww: 17, wh: entryHeight],
font: mathFont, paint: FALSE];
ValuesEntry["Cross-section(", XsecEntryProc];
controller.xat ← prev ← Field[prev, xys, lastHeight, "at x =", NIL, 90];
prev ← Label[prev: prev, parent: xys, lastHeight: lastHeight, name: ")", font: boldFont];
values
lastHeight ← lastHeight + entryHeight + entryVSpace;
controller.values ← ViewerTools.MakeNewTextViewer[
info: [
parent: xys,
wx: 0,
wy: lastHeight,
ww: 1000,
wh: 1000,
data: NIL,
scrollable: TRUE,
border: FALSE],
paint: FALSE];
Containers.ChildXBound[xys, controller.values];
Containers.ChildYBound[xys, controller.values];
}; -- MakeXYValues
NextX: PROC[prev: Viewer] RETURNS [INTEGER] = {
RETURN[IF prev = NIL THEN 0 ELSE prev.wx + prev.ww + entryHSpace]};
SpecEntryProc: 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] THEN {
action: ControlAction ← noop;
SELECT atom FROM
$Divisions, $Bounds, $Carets, $Targets, $Grids, $Color, $Font => {
IF NOT shift THEN 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;
};
$Text => {
IF NOT shift THEN 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;
};
$Entity => {
SELECT mouseButton FROM
red => {
IF control THEN {
action ← update;
IF shift THEN atom ← $EntityAndValues;
}
ELSE action ← resume;
};
yellow =>
IF NOT control THEN SELECT PopUpMenu.RequestSelection["Options",
LIST["Show", "Set spec", "Set spec and values", "Remove"], 1] FROM
1 => action ← resume;
2 => action ← update;
3 => {action ← update; atom ← $EntityAndValues};
4 => action ← remove;
ENDCASE;
blue => IF NOT control THEN action ← remove;
ENDCASE;
};
ENDCASE;
IF NOT UserEditAllowed[handle] THEN IF (atom = $Entity OR atom = $EntityAndValues) AND action # resume THEN RETURN;
SELECT action FROM
resume => LockedAtomProc[handle, atom, ResumeFromPanel];
update => LockedAtomProc[handle, atom, Update];
remove => LockedAtomProc[handle, atom, SpecRemove];
noop => NULL;
ENDCASE => RaiseError[$UnknowAction];
};
}; -- SpecEntryProc
ToggleProc: Buttons.ButtonProc = {
atom: ATOMNARROW[clientData];
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[NARROW[parent], atom]];
LockedAtomProc[handle, atom, FlipToggle];
}; -- ToggleProc
SetEntryPointer: PROC [handle: GraphHandle, v: Viewer] = {
OPEN handle.controller; -- make sure handle and controller not nil before calling.
Labels.Set[xyLabel, IF v = xyLabel THEN "" ELSE NIL];
Labels.Set[xsecLabel, IF v = xsecLabel THEN "" ELSE NIL];
}; -- SetEntryPointer
XYEntryProc: Buttons.ButtonProc -- PROC [parent: REF ANY, clientData: REF ANY ← NIL, mouseButton: MouseButton ← red, shift, control: BOOL ← FALSE] -- = {
handle: GraphHandle ← NARROW[clientData];
IF ControllerViewerExits[handle] AND NOT shift THEN { OPEN handle.controller;
action: ControlAction ← noop;
atom: ATOM ← $XYValues;
SetEntryPointer[handle, xyLabel];
SELECT mouseButton FROM
red => {
IF control THEN {
action ← update;
SELECT PopUpMenu.RequestSelection[
"Options", LIST["Set y values", "Set x values", "Set x and y values"], 1] FROM
1 => atom ← $YValues;
2 => atom ← $XValues;
3 => NULL; -- atom ← $XYValues;
ENDCASE => action ← noop;
}
ELSE action ← resume;
};
yellow => IF NOT control THEN {
action ← update;
SELECT PopUpMenu.RequestSelection[
"Options", LIST["Show x and y values", "Set y values", "Set x values", "Set x and y values"], 1] FROM
1 => action ← resume;
2 => atom ← $YValues;
3 => atom ← $XValues;
4 => NULL; -- atom ← $XYValues;
ENDCASE => action ← noop;
SELECT PopUpMenu.RequestSelection[
"Options", LIST["Show x and y values", "Set x and/or y values"], 1] FROM
1 => action ← resume;
2 => action ← update;
ENDCASE => action ← noop;
};
ENDCASE;
IF NOT UserEditAllowed[handle] THEN IF action = update THEN RETURN;
SELECT action FROM
resume => LockedAtomProc[handle, atom, ResumeFromPanel];
update => LockedAtomProc[handle, atom, Update];
noop => NULL;
ENDCASE => RaiseError[$UnknowAction];
};
}; -- XYEntryProc
XsecEntryProc: Buttons.ButtonProc -- PROC [parent: REF ANY, clientData: REF ANY ← NIL, mouseButton: MouseButton ← red, shift, control: BOOL ← FALSE] -- = {
handle: GraphHandle ← NARROW[clientData];
IF ControllerViewerExits[handle] AND NOT shift THEN { OPEN handle.controller;
action: ControlAction ← noop;
SetEntryPointer[handle, xsecLabel];
SELECT mouseButton FROM
red => IF NOT control THEN action ← resume;
yellow => IF NOT control THEN SELECT PopUpMenu.RequestSelection[
"Option", LIST["Show values for plotted curves at specified x"], 1] FROM
1 => action ← resume;
ENDCASE => action ← noop;
ENDCASE;
SELECT action FROM
resume => LockedAtomProc[handle, $Xsection, ResumeFromPanel];
ENDCASE;
};
}; -- XsecEntryProc
IntField: PROC [prev, parent: Viewer, lastHeight: INTEGER, label, contents: ROPENIL, width: INTEGER ← 0, autoX: BOOLTRUE, x: INTEGER ← level1X, height: INTEGER ← entryHeight, scrollable: BOOLFALSE] RETURNS [viewer: Viewer] = {
RETURN[Field[prev, parent, lastHeight, label, contents, width, autoX, x, height, scrollable, IntFieldPrompt]];
};
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
Field: PROC [prev, parent: Viewer, lastHeight: INTEGER, 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: parent,
wx: IF autoX THEN NextX[prev] ELSE x,
wy: lastHeight,
wh: entryHeight,
border: FALSE ],
clientData: NIL,
proc: prompt,
paint: FALSE];
prev ← ViewerTools.MakeNewTextViewer[
info: [
parent: parent,
wx: NextX[prev],
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
FieldPrompt: Buttons.ButtonProc = {
contentsViewer: Viewer ←
NARROW[ViewerOps.FetchProp[NARROW[parent], $Contents]];
IF mouseButton = blue THEN ViewerTools.SetContents[contentsViewer, NIL];
ViewerTools.SetSelection[contentsViewer];
}; -- FieldPrompt
Label: PROC[prev, parent: Viewer, lastHeight: INTEGER, name: ROPENIL, width: INTEGER ← 0, autoX: BOOLTRUE, x: INTEGER ← 0, font: Imager.Font ← NIL] RETURNS [Viewer] = {
prev ← Labels.Create[
info: [
name: name,
parent: parent,
wx: IF autoX THEN NextX[prev] ELSE x,
wy: lastHeight,
ww: width,
wh: entryHeight,
border: FALSE ],
font: font,
paint: FALSE];
RETURN[prev];
}; -- Label
OperationProc: Buttons.ButtonProc = {
atom: ATOMNARROW[clientData];
handle: GraphHandle ← NARROW[ViewerOps.FetchProp[NARROW[parent], atom]];
IF UserEditAllowed[handle] THEN 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.