ShowIPTool.mesa
Last Edited by: Ken Pier, August 28, 1985 3:08:24 pm PDT
DIRECTORY
BiScrollers, Buttons, Commander, Containers, FS, Geom2D, Imager, ImagerBackdoor, Interpress, IPMaster, IO, Menus, MessageWindow, Real, Rope, Rules, ShowIP, Sliders, ViewerClasses, ViewerOps, ViewerSpecs, ViewerTools;
ShowIPTool: CEDAR MONITOR
IMPORTS BiScrollers, Buttons, Commander, Containers, FS, Geom2D, Imager, ImagerBackdoor, Interpress, IPMaster, IO, Menus, MessageWindow, Real, Rope, Rules, Sliders, ViewerOps, ViewerSpecs, ViewerTools
EXPORTS ShowIP = BEGIN
Data: TYPE = ShowIP.Data;
DataRec: TYPE = ShowIP.DataRec;
ipPageSize: REAL = 11.0*72.0; -- points
visibleGrey: Imager.Color ← ImagerBackdoor.MakeStipple[122645B];
invisibleGrey: Imager.Color ← ImagerBackdoor.MakeStipple[100040B];
LProc: Interpress.LogProc = {
[master: OpenMaster, class: ErrorClass, code: ATOM, explanation: ROPE]
MessageWindow.Append[message: Rope.Concat["InterpressMaster Error: ", explanation], clearFirst: TRUE];
MessageWindow.Blink[];
};
CreateShowViewer: PUBLIC PROC[fileName: Rope.ROPE] RETURNS [ipViewer: ViewerClasses.Viewer] = {
data: Data;
curIndent, topLine: INTEGER ← 0;
button: Buttons.Button;
rule: Rules.Rule;
master: Interpress.OpenMaster;
master ← Interpress.Open[fileName: fileName, logProc: LProc, logData: NIL !
FS.Error => CONTINUE;
IPMaster.Error => { --ErrorDesc: TYPE ~ RECORD[code: ATOM, explanation: ROPE, index: INT ← 0]
MessageWindow.Append[message: Rope.Cat[error.explanation, " for ", fileName], clearFirst: TRUE];
MessageWindow.Blink[];
GOTO Quit;
};
Imager.Error => { --ErrorDesc: TYPE ~ RECORD [code: ATOM, explanation: ROPE]
MessageWindow.Append[message: Rope.Cat[error.explanation, " for ", fileName], clearFirst: TRUE];
MessageWindow.Blink[];
GOTO Quit;
};
];
IF master = NIL THEN { -- does this really stay NIL if FS.Error happens ?? You may want to handle this earlier in the caller
fileName ← Rope.Concat[fileName, ".ip"];
master ← Interpress.Open[fileName: fileName, logProc: LProc !
FS.Error => {
MessageWindow.Append[message: Rope.Cat["Can't open ShowIP viewer on ", fileName, " | "], clearFirst: TRUE];
MessageWindow.Append[message: error.explanation, clearFirst: FALSE];
MessageWindow.Blink[];
GOTO Quit;
};
IPMaster.Error => { --ErrorDesc: TYPE ~ RECORD[code: ATOM, explanation: ROPE, index: INT ← 0]
MessageWindow.Append[message: Rope.Cat[error.explanation, " for ", fileName], clearFirst: TRUE];
MessageWindow.Blink[];
GOTO Quit;
};
Imager.Error => { --ErrorDesc: TYPE ~ RECORD [code: ATOM, explanation: ROPE]
MessageWindow.Append[message: Rope.Cat[error.explanation, " for ", fileName], clearFirst: TRUE];
MessageWindow.Blink[];
GOTO Quit;
};
];
};
data ← NEW[ DataRec ← [ipMaster: master, pageNumber: 1, top: ipPageSize, height: 0.0, lastPageNumber: master.pages]]; -- pages IN [1..end]
data.ipContainer ← Containers.Create[
info: [
name: fileName,
iconic: TRUE,
menu: Menus.CopyMenu[BiScrollers.bsMenu],
data: data,
scrollable: FALSE],
paint: FALSE ];
button ← Buttons.Create[
info: [
name: "FirstPage",
wx: curIndent,
wy: topLine,
border: FALSE,
parent: data.ipContainer],
proc: FirstPage,
clientData: data,
documentation: "Left-click for the first page of the IP file",
paint: FALSE];
curIndent ← button.wx + button.ww;
button ← Buttons.Create[
info: [
name: "TurnPage",
wx: curIndent,
wy: topLine,
border: FALSE,
parent: data.ipContainer],
proc: TurnPage,
clientData: data,
documentation: "Left-click for next page; Right-click for previous page",
paint: FALSE];
curIndent ← button.wx + button.ww;
button ← Buttons.Create[
info: [
name: "LastPage",
wx: curIndent,
wy: topLine,
border: FALSE,
parent: data.ipContainer],
proc: LastPage,
clientData: data,
documentation: "Left-click for last page in IP file",
paint: FALSE];
curIndent ← button.wx + button.ww;
button ← Buttons.Create[
info: [
name: "Page",
wx: curIndent,
wy: topLine,
border: FALSE,
parent: data.ipContainer],
proc: PageNumber,
clientData: data,
documentation: "Left-click for selected page number",
paint: FALSE];
curIndent ← button.wx + button.ww;
data.pageNumberViewer ← ViewerTools.MakeNewTextViewer[
info: [
wx: curIndent,
wy: topLine+ViewerSpecs.windowBorderSize,
ww: 40,
wh: ViewerSpecs.scrollBarW+2*ViewerSpecs.windowBorderSize,
parent: data.ipContainer,
border: FALSE,
scrollable: FALSE],
paint: FALSE];
curIndent ← data.pageNumberViewer.wx + data.pageNumberViewer.ww;
data.pageNumberSlider ← Sliders.Create[
info: [
wx: curIndent,
wy: topLine,
ww: data.ipContainer.ww-curIndent,
wh: ViewerSpecs.scrollBarW+2*ViewerSpecs.windowBorderSize,
border: FALSE,
parent: data.ipContainer,
scrollable: FALSE],
filterProc: NormalizePageNumber,
sliderProc: PageNumberSlider,
orientation: horizontal,
foreground: visibleGrey,
background: invisibleGrey,
clientData: data,
paint: FALSE];
Containers.ChildXBound[data.ipContainer, data.pageNumberSlider];
rule ← Rules.Create[
info: [
parent: data.ipContainer,
wx: 0,
wy: topLine+ViewerSpecs.captionHeight+4*ViewerSpecs.windowBorderSize,
wh: ViewerSpecs.menuBarHeight]];
Containers.ChildXBound[data.ipContainer, rule];
data.ipViewer ← ipViewer ← bsStyle.CreateBiScroller[
class: ipBSClass,
info: [
parent: data.ipContainer,
wx: 0,
wy: topLine+ViewerSpecs.captionHeight+5*ViewerSpecs.windowBorderSize,
border: FALSE,
scrollable: FALSE,
data: data],
paint: FALSE ].QuaViewer[];
Containers.ChildXBound[data.ipContainer, data.ipViewer];
Containers.ChildYBound[data.ipContainer, data.ipViewer];
ViewerOps.PaintViewer[viewer: data.ipContainer, hint: all, clearClient: TRUE];
DeltaPage[data, 1];
EXITS
Quit => RETURN;
};
NormalizePageNumber: Sliders.FilterProc = TRUSTED {
data: Data ← NARROW[clientData];
RETURN [Real.FDiv[Real.RoundI[value*(data.lastPageNumber)], (data.lastPageNumber)]]
};
FirstPage: Buttons.ButtonProc = TRUSTED {
data: Data ← NARROW[clientData];
DeltaPage[data, 1];
};
TurnPage: Buttons.ButtonProc = TRUSTED {
data: Data ← NARROW[clientData];
where: INTIF mouseButton = red THEN +1 ELSE -1;
DeltaPage[data, MIN[MAX[data.pageNumber+where, 1], (data.lastPageNumber)]];
};
LastPage: Buttons.ButtonProc = TRUSTED {
data: Data ← NARROW[clientData];
DeltaPage[data, (data.lastPageNumber)];
};
PageNumber: Buttons.ButtonProc = TRUSTED {
data: Data ← NARROW[clientData];
stream: IO.STREAMIO.RIS[ViewerTools.GetContents[data.pageNumberViewer]];
where: INT ← stream.GetInt[];
DeltaPage[data, MIN[MAX[where, 1], (data.lastPageNumber)]];
};
PageNumberSlider: Sliders.SliderProc = TRUSTED {
data: Data ← NARROW[clientData];
SELECT reason FROM
abort => {
ViewerTools.SetContents[data.pageNumberViewer, IO.PutFR["%-g", IO.real[data.pageNumber]]];
};
move => {
ViewerTools.SetContents[data.pageNumberViewer, IO.PutFR["%-g", IO.real[Real.RoundI[(data.lastPageNumber)*value]]]];
};
set => {
DeltaPage[data, MIN[MAX[Real.RoundI[(data.lastPageNumber)*value], 1], (data.lastPageNumber)]];
};
ENDCASE;
};
IPPaint: ViewerClasses.PaintProc = TRUSTED {
[self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL];
data: Data ← NARROW[BiScrollers.ClientDataOfViewer[self]];
context.SetColor[Imager.black];
context.ScaleT[72.0/.0254]; -- points per meter
Interpress.DoPage[master: data.ipMaster, page: data.pageNumber, context: context];
};
IPDestroy: ENTRY ViewerClasses.DestroyProc = TRUSTED {
[self: Viewer] ;
data: Data ← NARROW[BiScrollers.ClientDataOfViewer[self]];
data.ipMaster ← NIL; -- Interpress.Close doesn't exist
};
DeltaPage: PROCEDURE [data: Data, newvalue: INT] = {
ViewerTools.SetContents[data.pageNumberViewer, IO.PutFR["%-g", IO.int[newvalue]]];
Sliders.SetContents[data.pageNumberSlider, Real.FDiv[newvalue, (data.lastPageNumber)]];
IF data.pageNumber=newvalue THEN RETURN;
data.pageNumber ← newvalue;
ViewerOps.PaintViewer[viewer: data.ipViewer, hint: all, clearClient: TRUE];
};
Break: PROC [char: CHAR] RETURNS [IO.CharClass] = {
IF char = '← OR char = '; THEN RETURN [break];
IF char = ' OR char = '  OR char = ', OR char = '\n THEN RETURN [sepr];
RETURN [other];
};
MakeShowIP: Commander.CommandProc = TRUSTED {
[cmd: Handle] RETURNS [result: REFNIL, msg: Rope.ROPENIL];
fileName: Rope.ROPENIL;
cis: IO.STREAMIO.RIS[cmd.commandLine];
may want to use more sophisticated fileNaming using CurrentWorkingDir. See Sil or IPViewerImpl for example.
fileName ← IO.GetTokenRope[cis, Break ! IO.EndOfStream => CONTINUE].token;
[] ← CreateShowViewer[fileName];
};
IPExtremaProc: PROC [clientData: REF ANY, direction: Geom2D.Vec] RETURNS [min, max: Geom2D.Vec] --BiScrollers.ExtremaProc-- = {
This proc is required by BiScrollers to return the extremes of the displayed data
area: Geom2D.Rect ← [x: 0.0, y: 0.0, w: 8.5*72.0, h: 11.0*72.0]; -- is this right ??
[min, max] ← Geom2D.ExtremaOfRect[r: area, n: direction];
};
bsStyle: BiScrollers.BiScrollerStyle ← BiScrollers.GetStyle[]; -- default gets BiScrollersButtonned
ipBSClass: BiScrollers.BiScrollerClass ← bsStyle.NewBiScrollerClass[[
flavor: $ShowIP,
extrema: IPExtremaProc,
paint: IPPaint,
destroy: IPDestroy,
mayStretch: TRUE, --OK to scale X and Y differently?
preserve: [X: 0, Y: 0] --this specifies point that stays fixed when viewer size changes
]];
Commander.Register[key: "ShowIP", proc: MakeShowIP, doc: "Show an Interpress Master in a viewer" ];
END.