MintDisplayImpl.mesa
Copyright (C) 1986 by Xerox Corporation. All rights reserved.
Christian LeCocq August 1, 1986 3:33:31 pm PDT
DIRECTORY
Imager
Imager USING [Context, SetColor, ColorOperator, MaskRectangle, SetFont, SetStrokeWidth, MaskStroke, MaskVector, RotateT, TranslateT, Color, Font, SetXY, ShowRope, PathProc],
ImagerBackdoor USING [GetBounds],
ImagerColor USING [ColorFromRGB],
ImagerColorOperator USING [RGBLinearColorModel],
ImagerFont USING [Scale, Find],
ImagerInterpress USING [Ref, Create, DeclareColorOperator, DeclareFont, DoPage, Close],
Draw2d,
Viewers
Containers USING [Container, Create, ChildXBound, ChildYBound],
Menus USING [Menu, CreateMenu, AppendMenuEntry, CreateEntry, MouseButton],
ViewerClasses USING [Viewer, ViewerRec, ViewerClass, ViewerClassRec, NotifyProc, PaintProc, DestroyProc, ScrollProc, HScrollProc],
ViewerOps USING [CreateViewer, PaintViewer, RegisterViewerClass],
TIPUser USING [InstantiateNewTIPTable ,TIPScreenCoords],
Icons USING [NewIconFromFile],
others
IO USING [PutFR, real],
Convert USING [RopeFromInt],
Process USING [Detach],
Vector2 USING [VEC],
Rope USING [ROPE, Cat, Equal],
Real USING [FixI, Fix],
MessageWindow USING [Append],
MintDisplay;
MintDisplayImpl: CEDAR MONITOR
IMPORTS
Imager,
ImagerColor,
ImagerColorOperator,
ImagerInterpress,
ImagerFont,
ImagerBackdoor,
Draw2d,
IO,
Convert,
Containers,
Menus,
MessageWindow,
ViewerOps,
TIPUser,
Rope,
Real,
Icons
EXPORTS MintDisplay
~ BEGIN OPEN MintDisplay;
defaultScalex: REAL ← 0.01;
currentFont: Imager.Font ← ImagerFont.Find["Xerox/TiogaFonts/Helvetica12B"];
pressFont: Imager.Font ← ImagerFont.Scale[ImagerFont.Find["Xerox/PressFonts/Helvetica-brr"], 12.0];
pressScale: REAL ← 0.0002;
fineStroke: REAL ← 1.0;
coarseStroke: REAL ← 3.0;
timeScale: REAL ← 1000.0;
valueForTrue: REAL ← 2500.10; -- instead of 2500.0 to avoid 5000.0 -> "logical 2"
Init: PROC ~ {
mintQPictureClass: ViewerClasses.ViewerClass; -- Declare type
mintQPictureClass ← NEW [-- Get record and fill it with procedure names
ViewerClasses.ViewerClassRec ← [ 
notify: NotifyProc,  -- procedure to respond to input events (from TIP table)
paint: PaintProc,   -- procedure called when viewer contents must be repainted
destroy: DestroyProc, -- procedure to clean up when done
scroll: VScrollProc,  -- procedure to respond to vertical scroll bar hits
hscroll: HScrollProc,  -- procedure to respond to horizontal scroll bar hits
       -- Tip table (translates mouse events to commands)
tipTable: TIPUser.InstantiateNewTIPTable["QuickViewer.TIP"],
cursor: crossHairsCircle -- cursor when mouse is in viewer
]
];
ViewerOps.RegisterViewerClass[$MintQViewer, mintQPictureClass];-- Register with viewers
TRUSTED { Process.Detach[FORK ButtonPasser]; };  -- Start up button event monitor     
};
BuildViewer: PUBLIC PROC[viewerTitle: Rope.ROPE] RETURNS[viewer: Viewer] ~ {
menu: Menus.Menu;
container: Containers.Container;
graphState: State ← NEW[StateRep ← []];
graphData: ViewerData ← NEW[ViewerDataRec];
menu ← Menus.CreateMenu[];
Menus.AppendMenuEntry[
menu: menu,      -- enter "Reset" button
entry: Menus.CreateEntry[
name: "Reset",
proc: SetDefaults,
clientData: graphData,
documentation: "Reset graphViewer"
]
];
Menus.AppendMenuEntry[
menu: menu,      -- enter "Mag" button
entry: Menus.CreateEntry[
name: "Mag",
proc: MagOnOff,
clientData: graphData,
documentation: "Mag switch"
]
];
Menus.AppendMenuEntry[
menu: menu,      -- enter "Axis" button
entry: Menus.CreateEntry[
name: "Axis",
proc: TimeAxisBut,
clientData: graphData,
documentation: "Mag switch"
]
];
Menus.AppendMenuEntry[
menu: menu,      -- enter "sizeX" button
entry: Menus.CreateEntry[
name: "sizeX",
proc: ScaleX,
clientData: graphData,
documentation: "Zoom x2"
]
];
Menus.AppendMenuEntry[
menu: menu,      -- enter "MagSizeX" button
entry: Menus.CreateEntry[
name: "MagSizeX",
proc: MagScaleX,
clientData: graphData,
documentation: "Zoom x2mag"
]
];
Menus.AppendMenuEntry[
menu: menu,      -- enter "sizeY" button
entry: Menus.CreateEntry[
name: "sizeY",
proc: ScaleY,
clientData: graphData,
documentation: "Zoom :2mag"
]
];
container ← Containers.Create[
info: [
name: viewerTitle,      -- define outer viewer
menu: menu,
iconic: TRUE,
icon: Icons.NewIconFromFile["Mint.icons", 3],
column: left,
scrollable: FALSE
]
];
                     
viewer ← ViewerOps.CreateViewer[   -- define graphics area
flavor: $MintQViewer,
info: [
parent: container,
wx: 0, wy: 0,      -- position WRT parent
ww: container.ww,    -- CHildXBound below
wh: container.wh,    -- CHildXBound below
name: "Oscilloscope",
caption: FALSE,
scrollable: TRUE,
hscrollable: TRUE,
data: graphData
],
paint: FALSE
];
Containers.ChildXBound[container, viewer];
Containers.ChildYBound[container, viewer];
graphData.xMax ← MAX[viewer.cw,10.0];  -- this dirty hack because
graphData.yMax ← MAX[viewer.ch,10.0];  -- cw and ch seems to be zero at that point ???
ViewerOps.PaintViewer[container, all];  -- load up the viewer (paint it)
};
PaintProc: ViewerClasses.PaintProc ~ {       -- repaint screen for updates
PROC [self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL]
dc: Imager.Context ~ context;
viewerData: ViewerData ~ NARROW[self.data];
SELECT whatChanged FROM
NIL  => {             -- window resized, redraw
ReDraw[self];
};
ENDCASE => {           -- call path for DrawInViewer
NARROW[whatChanged, REF PROC[Imager.Context]]^[context];
};
}; 
DrawInViewer: PROCEDURE [viewer: Viewer, proc: PROC [Imager.Context]] ~ {
Pass procedure to PaintProc
drawProc: REF PROC[Imager.Context] ← NIL;
TRUSTED { drawProc ← NEW[PROC[Imager.Context] ← proc]; };
ViewerOps.PaintViewer[
viewer: viewer,-- pass record to viewer painter
hint: client,
whatChanged: drawProc,
clearClient: FALSE
];
};
SetDefaults: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ {
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
viewerData.xTranslation ← 0.0;
XScaleDisplayValues[viewerData.displayList, defaultScalex/viewerData.scalex, viewerData];
viewerData.scalex ← defaultScalex;
viewerData.magOn ← FALSE;
ReDraw[viewer];
};
TimeAxisBut: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ { 
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
TimeAxis[timeScale, viewer, red];
};
ScaleX: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ {
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
alpha: REAL ← 2.0;
IF mouseButton=yellow THEN RETURN;
IF mouseButton=blue THEN alpha ← 0.5;
viewerData.scalex ← alpha*viewerData.scalex;  -- Zoom alpha
XScaleDisplayValues[viewerData.displayList, alpha, viewerData];
ReDraw[viewer];
};
MagScaleX: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ {
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
alpha: REAL ← 2.0;
IF mouseButton=yellow THEN RETURN;
IF mouseButton=blue THEN alpha ← 0.5;
viewerData.magScale ← alpha*viewerData.magScale;
XScaleDisplayValues[viewerData.magDisplayList, alpha, viewerData];
ReDraw[viewer];
};
ScaleY: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ {
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
alpha: REAL ← 2.0;
IF mouseButton=yellow THEN RETURN;
IF mouseButton=blue THEN alpha ← 0.5;
viewerData.scaley ← alpha*viewerData.scaley;
viewerData.inter ← alpha*viewerData.inter;
YScaleDisplayValues[viewerData.displayList, alpha, viewerData];
YScaleDisplayValues[viewerData.magDisplayList, alpha, viewerData];
ReDraw[viewer];
};
MagOnOff: PROCEDURE [parent: REF ANY, clientData: REF ANY, mouseButton: Menus.MouseButton, shift, control: BOOL] ~ { 
viewerData: ViewerData ~ NARROW[clientData];
container: Viewer ~ NARROW[parent];
viewer: Viewer ~ container.child;
viewerData.magOn ← ~viewerData.magOn;
ReDraw[viewer];
};
XScaleDisplayValues: PROCEDURE [displayList: DisplayList, alpha: REAL, viewerData: ViewerData] ~ {
viewerData.xMin ← displayList.first.list.first.x;
viewerData.xMax ← displayList.first.list.first.x;
FOR dList: DisplayList ← displayList, dList.rest UNTIL dList=NIL DO
FOR ilist: VecList ← dList.first.list, ilist.rest UNTIL ilist=NIL DO
ilist.first.x ← alpha*ilist.first.x;
viewerData.xMin ← MIN[viewerData.xMin, ilist.first.x];
viewerData.xMax ← MAX[viewerData.xMax, ilist.first.x];
ENDLOOP;
ENDLOOP;
};
YScaleDisplayValues: PROCEDURE [displayList: DisplayList, alpha: REAL, viewerData: ViewerData] ~ {
n: INT ← 0;
viewerData.yMin ← displayList.first.list.first.y;
viewerData.yMax ← displayList.first.list.first.y;
FOR dList: DisplayList ← displayList, dList.rest UNTIL dList=NIL DO
n ← n+1;
FOR ilist: VecList ← dList.first.list, ilist.rest UNTIL ilist=NIL DO
ilist.first.y ← alpha*ilist.first.y;
viewerData.yMin ← MIN[viewerData.yMin, ilist.first.y];
viewerData.yMax ← MAX[viewerData.yMax, ilist.first.y];
ENDLOOP;
ENDLOOP;
viewerData.yMax ← viewerData.yMax+n*viewerData.inter;
};
NotifyProc: ViewerClasses.NotifyProc ~ {
NotifyProc ~ PROC[self: Viewer, input: LIST OF REF ANY]
viewerData: ViewerData ~ NARROW[self.data];
x, y, t: REAL;
IF ISTYPE[input.first, TIPUser.TIPScreenCoords] -- If input is coords from mouse
THEN {
mousePlace: TIPUser.TIPScreenCoords ← NARROW[input.first];
x ← mousePlace.mouseX;
y ← mousePlace.mouseY;
IF ISTYPE[input.rest.first, ATOM] AND (gotaNewOne = FALSE ) THEN {
IF ISTYPE[input.rest.first, ATOM] THEN {
buttonName: ATOMNARROW[input.rest.first];
shft, ctrl: BOOLEANFALSE;  
restOfInput: LIST OF REF ANY ← input.rest.rest;
WHILE restOfInput # NIL DO
SELECT NARROW[restOfInput.first, ATOM] FROM
$Shift => shft ← TRUE;
$Ctrl => ctrl ← TRUE;
ENDCASE;  -- ignore anything else
restOfInput ← restOfInput.rest;
ENDLOOP;
ButtonMonitor[self, buttonName, ctrl, shft];
SELECT buttonName FROM
$LeftButton => {
IF viewerData.magOn THEN t ← (x-viewerData.magOr)/viewerData.magScale
ELSE t ← (x-viewerData.xTranslation)/viewerData.scalex;
DrawRope[[x, y], IO.PutFR["t:%d", IO.real[t]], self, red];
};
$MiddleButton => {};
$RightButton => {
IF ~viewerData.magOn THEN {
viewerData.magOr ← (x-viewerData.xTranslation)/viewerData.scalex;
ReDraw[self];
};
};
$LeftHeld => {};
$MiddleHeld => {};
$RightHeld => {};
ENDCASE;
};
};
};
DestroyProc: ViewerClasses.DestroyProc ~ {
Clean up on exit (viewer destroyed)
This will be called when the viewer is destroyed
MessageWindow.Append["MintDisplay Exited",TRUE]; -- say goodbye
};
VScrollProc: ViewerClasses.ScrollProc ~ {    
Acts on scrollbar mouse hits
ScrollProc ~ PROC[self: Viewer, op: ScrollOp, amount: INTEGER]
    RETURNS[top, bottom: INTEGER ← LAST[INTEGER]];
ScrollOp: TYPE = {query, up, down, thumb}
selfData: ViewerData ~ NARROW[self.data];
SELECT op FROM
up => {
selfData.yTranslation ← MIN[selfData.yTranslation + amount, selfData.yMin+self.ch];
};
down => {
selfData.yTranslation ← MAX[selfData.yTranslation - amount, -selfData.yMax];
};
thumb => {
selfData.yTranslation ← amount * (selfData.yMax - selfData.yMin)/100.0;
};
query => {
top ← MAX[0, Real.FixI[100.0*(selfData.yMax + selfData.yTranslation - self.ch) /(selfData.yMax - selfData.yMin)]];
bottom ← MIN[100, Real.FixI[100.0*(selfData.yMax + selfData.yTranslation) /(selfData.yMax - selfData.yMin)]];
RETURN;
};
ENDCASE;
ReDraw[self];
};
HScrollProc: ViewerClasses.HScrollProc ~ {    
Acts on hscrollbar mouse hits
HScrollProc ~ PROC[self: Viewer, op: HScrollOp, amount: INTEGER]
    RETURNS[
left, right: INTEGER ← LAST[INTEGER]];
HScrollOp: TYPE = {query, left, right, thumb}
selfData: ViewerData ~ NARROW[self.data];
IF selfData.magOn THEN {
SELECT op FROM
right => {
selfData.magOr ← MIN[selfData.magOr + amount, selfData.xMin*selfData.magScale/selfData.scalex + self.cw];
};
left => {
selfData.magOr ← MAX[selfData.magOr - amount, -selfData.xMax*selfData.magScale/selfData.scalex];
};
thumb => {
selfData.magOr ← - amount * (selfData.xMax-selfData.xMin)*0.01 - selfData.xMin;
};
query => {
left ← MAX[0, Real.FixI[100.0*(-selfData.magOr - selfData.xMin) / (selfData.xMax-selfData.xMin)]];
right ← MIN[100, Real.FixI[100.0*(-selfData.magOr - selfData.xMin + self.cw*selfData.scalex/selfData.magScale) /(selfData.xMax - selfData.xMin)]];
RETURN;
};
ENDCASE;
}
ELSE {
SELECT op FROM
right => {
selfData.xTranslation ← MIN[selfData.xTranslation + amount, selfData.xMin + self.cw];
};
left => {
selfData.xTranslation ← MAX[selfData.xTranslation - amount, -selfData.xMax];
};
thumb => {
selfData.xTranslation ← - amount * (selfData.xMax-selfData.xMin)*0.01 - selfData.xMin;
};
query => {
left ← MAX[0, Real.FixI[100.0*(-selfData.xTranslation - selfData.xMin) / (selfData.xMax-selfData.xMin)]];
right ← MIN[100, Real.FixI[100.0*(-selfData.xTranslation - selfData.xMin + self.cw) /(selfData.xMax - selfData.xMin)]];
RETURN;
};
ENDCASE;
};
ReDraw[self];
};
DrawVect: PUBLIC PROC [or: VEC, ex: VEC, viewer: Viewer, color: Imager.Color] ~ {
DoDrawVect: PROC [context: Imager.Context] ~ {
Imager.SetColor[context, color];
Imager.MaskVector[context, [or.x+viewerData.xTranslation, or.y+viewerData.yTranslation], [ex.x+viewerData.xTranslation, ex.y+viewerData.yTranslation]];
};
viewerData: ViewerData ~ NARROW[viewer.data];
DrawInViewer[viewer, DoDrawVect];-- ask the viewer procs to call you back
};
DrawRope: PUBLIC PROC[pos: VEC, rope: Rope.ROPE, viewer: Viewer, color: Imager.Color] ~ {
DoDrawRope: PROC [context: Imager.Context] ~ {
ShowRope[pos.x, pos.y, rope, context, color];
};
DrawInViewer[viewer, DoDrawRope];-- ask the viewer procs to call you back
};
DrawVectAbs: PROC [or: VEC, ex: VEC, viewer: Viewer, color: Imager.Color] ~ {
DoDrawVectAbs: PROC [context: Imager.Context] ~ {
Imager.SetColor[context, color];
Imager.MaskVector[context, or, ex];
};
viewerData: ViewerData ~ NARROW[viewer.data];
DrawInViewer[viewer, DoDrawVectAbs];-- ask the viewer procs to call you back
};
TimeAxis: PUBLIC PROC [unit: REAL, viewer: Viewer, color: Imager.Color] ~ {
DoTimeAxis: PROC [context: Imager.Context] ~ {
Path: Imager.PathProc ~ {
FOR n:INT IN [n1..n2] DO
moveTo[[x+orx+n*50.0, y]];
lineTo[[x+orx+n*50.0, y+10]];
ENDLOOP;
};
Imager.SetColor[context, color];
Imager.MaskStroke[context, Path];
Imager.SetFont[context, currentFont];
tscale ← 1/(tscale*unit);
FOR n:INT IN [n1..n2] DO
Imager.SetXY[context, [x+orx+n*50.0, y-10.0]];
Imager.ShowRope[context, IO.PutFR["%d", IO.real[x+n*50.0*tscale]]];
ENDLOOP;
};
viewerData: ViewerData ~ NARROW[viewer.data];
tscale, orx, x, y: REAL;
n1, n2: INT;
x ← 0.0;
y ← viewer.ch*0.5;
IF viewerData.magOn THEN {
orx ← -viewerData.magOr*viewerData.magScale - viewerData.xTranslation;
tscale ← viewerData.magScale
}
ELSE {
orx ← viewerData.xTranslation;
tscale ← viewerData.scalex
};
n1 ← Real.Fix[-orx/50.0];
n2 ← Real.Fix[(viewer.cw-orx)/50.0];
DrawInViewer[viewer, DoTimeAxis];
};
WriteList: PROC [orx, ory: REAL, vecList: VecList, context: Imager.Context, color: Imager.Color, radix: REAL ← 1.0, firstx, lastx: REAL] ~ {
x1, y1: REAL;
y2: REAL;
n: INT;
IF vecList=NIL THEN RETURN;
Imager.SetColor[context, color];
y1ory;
y2 ← y1+10.0;
FOR ilist: VecList ← vecList, ilist.rest UNTIL ilist=NIL DO
x1 ← orx+ilist.first.x;
IF x1>lastx THEN LOOP;
IF x1<firstx THEN RETURN;
n ← Real.Fix[ilist.first.y/radix];
Draw2d.Solid[context, [x1, y1], [x1, y2]];
ShowRope[x1 - 2.0, y2+5.0, Convert.RopeFromInt[n, 16, FALSE], context, color];
ENDLOOP;
};
DrawList: PROC [orx, ory: REAL, vecList: VecList, context: Imager.Context, color: Imager.Color, firstx, lastx: REAL] ~ {
Path: Imager.PathProc ~ {
x, y: REAL;
x ← orx+vecList.first.x;
y ← ory+vecList.first.y;
moveTo[[x, y]];
FOR ilist: VecList ← vecList.rest, ilist.rest UNTIL ilist=NIL DO
x ← orx+ilist.first.x;
y ← ory+ilist.first.y;
lineTo[[x, y]];
IF x<firstx THEN RETURN;
ENDLOOP;
};
IF vecList=NIL THEN RETURN;
IF vecList.rest#NIL THEN
UNTIL vecList.rest.first.x<lastx OR vecList.rest.rest=NIL DO vecList ← vecList.rest ENDLOOP;
Imager.SetColor[context, color];
Imager.MaskStroke[context, Path]; --MaskStroke Version
};
DrawList: PROC [orx, ory: REAL, vecList: VecList, context: Imager.Context, color: Imager.Color, firstx, lastx: REAL] ~ {
x1, y1: REAL;
x2, y2: REAL;
IF vecList=NIL THEN RETURN;
Imager.SetColor[context, color];
x1 ← orx+vecList.first.x;
y1 ← ory+vecList.first.y;
FOR ilist: VecList ← vecList.rest, ilist.rest UNTIL ilist=NIL DO
x2 ← orx+ilist.first.x;
y2 ← ory+ilist.first.y;
Draw2d.Solid[context, [x1, y1], [x2, y2]];
x1 ← x2;
y1 ← y2;
ENDLOOP; -- MaskVector Version
};
ShowRope: PROC[x, y: REAL, rope: Rope.ROPE, context: Imager.Context, color: Imager.Color] ~ {
IF rope=NIL THEN RETURN;
Imager.SetColor[context, color];
Imager.SetFont[context, currentFont];
Imager.SetXY[context, [x, y]];
Imager.ShowRope[context, rope];
};
ReDraw: PUBLIC PROC [viewer: Viewer] ~ {
DrawToScreen: PROC [context: Imager.Context] ~ {
or: VEC;
or.y ← viewerData.yTranslation;
Imager.SetColor[context, white]; -- set color to white
Imager.MaskRectangle[context, ImagerBackdoor.GetBounds[context]]; -- fill screen
IF viewerData.magOn THEN {
or.x ← -viewerData.magOr*viewerData.magScale - viewerData.xTranslation;
displayList ← viewerData.magDisplayList;
}
ELSE {
magPos: VEC ← [viewerData.scalex*viewerData.magOr+viewerData.xTranslation, 0.0];
Imager.SetColor[context, blue];
Draw2d.Solid[context, magPos, [magPos.x, magPos.y+ 750.0]];
magPos.x ← magPos.x+viewer.cw*viewerData.scalex/viewerData.magScale;
Draw2d.Solid[context, magPos, [magPos.x, magPos.y+ 750.0]];
or.x ← viewerData.xTranslation;
displayList ← viewerData.displayList;
};
FOR dList: DisplayList ← displayList, dList.rest UNTIL dList=NIL DO
IF or.y>-viewerData.inter THEN { --simplified clipping
Imager.SetColor[context, green];
Draw2d.Solid[context, [0.0, or.y], [1000.0, or.y]];
ShowRope[0.0, or.y + viewerData.inter*0.5, dList.first.name, context, blue];
IF dList.first.analog THEN DrawList[or.x, or.y, dList.first.list, context, black, 0.0, viewer.cw]
ELSE WriteList[or.x, or.y, dList.first.list, context, black, radix, 0.0, viewer.cw];
};
or.y ← viewerData.inter + or.y;
IF or.y>viewer.ch THEN RETURN;
ENDLOOP;
};
viewerData: ViewerData ~ NARROW[viewer.data];
displayList: DisplayList;
radix: REAL ← valueForTrue*viewerData.scaley;
IF viewerData.displayList=NIL THEN RETURN;
DrawInViewer[viewer, DrawToScreen];
};
ProduceIPMaster: PUBLIC PROC [viewer: Viewer] ~ {
DrawToIP: PROC [context: Imager.Context] ~ {
Called back by the Interpress machinery.
Path: Imager.PathProc ~ {
x, y: REAL;
x ← dRec.or.x+dRec.list.first.x;
y ← yGraph+dRec.or.y+dRec.list.first.y;
moveTo[[x+viewerData.xTranslation, y+viewerData.yTranslation]];
FOR ilist: VecList ← dRec.list.rest, ilist.rest UNTIL ilist=NIL DO
x ← dRec.or.x+ilist.first.x;
y ← yGraph+dRec.or.y+ilist.first.y;
lineTo[[x+viewerData.xTranslation, y+viewerData.yTranslation]];
ENDLOOP;
};
yGraph: REAL ← 0.0;
dRec: DisplayListRec;
Imager.TranslateT[context, [viewer.cw, -10.0]];
Imager.RotateT[context, 90.0];
FOR dList: DisplayList ← viewerData.displayList, dList.rest UNTIL dList=NIL DO
dRec ← dList.first;
Imager.SetStrokeWidth[context, fineStroke];
Imager.SetColor[context, green];
Imager.MaskVector[context, [0.0, yGraph+viewerData.yTranslation+dRec.or.y], [750.0, yGraph+viewerData.yTranslation+dRec.or.y]];
Imager.SetStrokeWidth[context, coarseStroke];
Imager.SetColor[context, black];
Imager.MaskStroke[context, Path];
Imager.SetColor[context, blue];
Imager.SetFont[context, pressFont];
Imager.SetXY[context, [0.0, yGraph+dRec.or.y + 0.5*viewerData.inter]];
Imager.ShowRope[context, dRec.name];
yGraphyGraph+viewerData.inter;
ENDLOOP;
}; -- DrawToIP
viewerData: ViewerData ~ NARROW[viewer.data];
fileName: Rope.ROPE ← Rope.Cat["///Temp/Mint/", "Dummy", ".interpress"];
ip: ImagerInterpress.Ref ← ImagerInterpress.Create[fileName];
rgbLinear: Imager.ColorOperator ~ ImagerColorOperator.RGBLinearColorModel[255];
ImagerInterpress.DeclareColorOperator[ip, rgbLinear];
ImagerInterpress.DeclareFont[ip, pressFont];
ImagerInterpress.DoPage[ip, DrawToIP, pressScale];
ImagerInterpress.Close[ip];
MessageWindow.Append[Rope.Cat[fileName, " created"],TRUE];
};
UpdateDisplay: PUBLIC PROC [displayList: DisplayList, viewer: Viewer] ~ {
Updates the data and the display.
x, xMag, y :REAL;
vl1, vl2: VecList;
viewerData: ViewerData ~ NARROW[viewer.data];
FOR idisplayList: DisplayList ← displayList, idisplayList.rest UNTIL idisplayList=NIL DO
vDisplayList: DisplayList ← viewerData.displayList;
mDisplayList: DisplayList ← viewerData.magDisplayList;
UNTIL vDisplayList=NIL DO
IF Rope.Equal[vDisplayList.first.name, idisplayList.first.name] THEN {
IF ~Rope.Equal[mDisplayList.first.name, idisplayList.first.name] THEN ERROR; -- both orders are no longer =
vDisplayList.first.list ← CONS[[0.0, 0.0], vDisplayList.first.list];
vl1 ← vDisplayList.first.list;
mDisplayList.first.list ← CONS[[0.0, 0.0], mDisplayList.first.list];
vl2 ← mDisplayList.first.list;
FOR iVecList: VecList ← idisplayList.first.list, iVecList.rest UNTIL iVecList=NIL DO
x ← viewerData.scalex*iVecList.first.x;
xMag ← viewerData.magScale*iVecList.first.x;
y ← viewerData.scaley*iVecList.first.y;
vl1.rest ← CONS[[x: x, y: y], vl1.rest]; -- add before the old 1st el of the list
vl1 ← vl1.rest;
vl2.rest ← CONS[[x: xMag, y: y], vl2.rest]; -- add before the old 1st el of the list
vl2 ← vl2.rest;
ENDLOOP;
vDisplayList.first.list ← vDisplayList.first.list.rest;
mDisplayList.first.list ← mDisplayList.first.list.rest;
EXIT;
};
vDisplayList ← vDisplayList.rest;
mDisplayList ← mDisplayList.rest;
ENDLOOP;
ENDLOOP;
};
LoadDisplay: PUBLIC PROC [displayList: DisplayList, viewer: Viewer] ~ {
copies and scales the input display list in the viewer data field, and displays it.
x, xMag, y :REAL;
vl1, vl2: VecList;
viewerData: ViewerData ~ NARROW[viewer.data];
displayListRec: DisplayListRec;
magDisplayListRec: DisplayListRec;
displayListRec.or ← [0.0, 0.0];
magDisplayListRec.or ← [0.0, 0.0];
viewerData.displayList ← NIL;
viewerData.magDisplayList ← NIL;
FOR idisplayList: DisplayList ← displayList, idisplayList.rest UNTIL idisplayList=NIL DO
displayListRec.name ← idisplayList.first.name;
displayListRec.analog ← idisplayList.first.analog;
magDisplayListRec.name ← idisplayList.first.name;
magDisplayListRec.analog ← idisplayList.first.analog;
displayListRec.list ← LIST[[0.0, 0.0]]; --dummy first el
vl1 ← displayListRec.list; -- pointer to the last el of list
magDisplayListRec.list ← LIST[[0.0, 0.0]]; -- same things
vl2 ← magDisplayListRec.list;
FOR iVecList: VecList ← idisplayList.first.list, iVecList.rest UNTIL iVecList=NIL DO
x ← viewerData.scalex*iVecList.first.x;
xMag ← viewerData.magScale*iVecList.first.x;
y ← viewerData.scaley*iVecList.first.y;
vl1.rest ← LIST[[x: x, y: y]]; -- add to the end of the list
vl1 ← vl1.rest;
vl2.rest ← LIST[[x: xMag, y: y]];
vl2 ← vl2.rest;
ENDLOOP;
displayListRec.list ← displayListRec.list.rest; --remove the dummy 1st el
magDisplayListRec.list ← magDisplayListRec.list.rest;
viewerData.displayList ← CONS[displayListRec, viewerData.displayList];
viewerData.magDisplayList ← CONS[magDisplayListRec, viewerData.magDisplayList];
ENDLOOP;
ReDraw[viewer];
};
black: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 0.0, G: 0.0, B: 0.0 ] ];
white: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 1.0, G: 1.0, B: 1.0 ] ];
red: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 1.0, G: 0.0, B: 0.0 ] ];
green: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 0.0, G: 1.0, B: 0.0 ] ];
blue: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 0.0, G: 0.0, B: 1.0 ] ];
puce: PUBLIC Imager.Color ← ImagerColor.ColorFromRGB[ [ R: 0.5, G: 0.2, B: 0.4 ] ];
Init[];
END.