DIRECTORY Buttons, Commander, Containers, FS, Imager, ImagerBackdoor, IO, MessageWindow, Real, Rope, Rules, ShowPD, PDFileFormat, PDFileReader, PDReaderPage, Process, Sliders, ViewerClasses, ViewerOps, ViewerSpecs, ViewerTools, ImagerPixelMap; ShowPDTool: CEDAR MONITOR IMPORTS Buttons, Commander, Containers, FS, Imager, ImagerBackdoor, IO, MessageWindow, PDFileReader, PDReaderPage, Process, Real, Rope, Rules, Sliders, ViewerOps, ViewerSpecs, ViewerTools, ImagerPixelMap EXPORTS ShowPD = BEGIN pdViewerClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec]; ShowData: TYPE = ShowPD.ShowData; ShowDataRec: TYPE = ShowPD.ShowDataRec; pdPageSize: REAL = 11.0*72.0; -- points screenResolution: REAL = 72.0; viewerOverheadSize: INT = (ViewerSpecs.captionHeight + ViewerSpecs.menuHeight + ViewerSpecs.menuBarHeight + ViewerSpecs.windowBorderSize*2); visibleGrey: Imager.Color _ ImagerBackdoor.MakeStipple[122645B]; invisibleGrey: Imager.Color _ ImagerBackdoor.MakeStipple[100040B]; CreateShowViewer: PUBLIC PROC[fileName: Rope.ROPE, reduction: REAL _ 1.0] RETURNS[pdViewer: ViewerClasses.Viewer] = TRUSTED { myShowData: ShowData; curIndent: INTEGER _ 0; topLine: INTEGER _ 0; button: Buttons.Button; rule: Rules.Rule; file: PDFileReader.Handle_NIL; file _ PDFileReader.Open[fileName ! FS.Error => CONTINUE; PDFileReader.Error => { MessageWindow.Append[message: Rope.Cat[description, " for ", fileName], clearFirst: TRUE]; MessageWindow.Blink[]; GOTO Quit; }; PDFileReader.Warning => { MessageWindow.Append[message: Rope.Cat[description, " for ", fileName], clearFirst: TRUE]; MessageWindow.Blink[]; GOTO Quit; }; ]; IF file = NIL THEN { fileName _ Rope.Concat[fileName, ".pd"]; file _ PDFileReader.Open[fileName ! FS.Error => { MessageWindow.Append[message: Rope.Cat["Can't open ShowPD viewer on ", fileName, " | "], clearFirst: TRUE]; MessageWindow.Append[message: error.explanation, clearFirst: FALSE]; MessageWindow.Blink[]; GOTO Quit; }; PDFileReader.Error => { MessageWindow.Append[message: Rope.Cat[description, " for ", fileName], clearFirst: TRUE]; MessageWindow.Blink[]; GOTO Quit; }; PDFileReader.Warning => { MessageWindow.Append[message: Rope.Cat[description, " for ", fileName], clearFirst: TRUE]; MessageWindow.Blink[]; GOTO Quit; }; ]; }; myShowData _ NEW[ ShowDataRec _ [show: file, pageNumber: 1, top: pdPageSize, height: 0.0]]; [myShowData.pageStructure, myShowData.lastPageNumber] _ PDReaderPage.GetPageStructure[file]; myShowData.scaleFactor _ screenResolution/(file.herald.fResolution*reduction); myShowData.pdContainer _ Containers.Create[ info: [ name: fileName, iconic: TRUE, data: myShowData, scrollable: FALSE], paint: FALSE ]; button _ Buttons.Create[ info: [ name: "FirstPage", wx: curIndent, wy: topLine, border: FALSE, parent: myShowData.pdContainer], proc: FirstPage, clientData: myShowData, documentation: "Left-click for the first page of the PD file", paint: FALSE]; curIndent _ button.wx + button.ww; button _ Buttons.Create[ info: [ name: "TurnPage", wx: curIndent, wy: topLine, border: FALSE, parent: myShowData.pdContainer], proc: TurnPage, clientData: myShowData, 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: myShowData.pdContainer], proc: LastPage, clientData: myShowData, documentation: "Left-click for last page in PD file", paint: FALSE]; curIndent _ button.wx + button.ww; button _ Buttons.Create[ info: [ name: "Page", wx: curIndent, wy: topLine, border: FALSE, parent: myShowData.pdContainer], proc: PageNumber, clientData: myShowData, documentation: "Left-click for selected page number", paint: FALSE]; curIndent _ button.wx + button.ww; myShowData.pageNumberViewer _ ViewerTools.MakeNewTextViewer[ info: [ wx: curIndent, wy: topLine+ViewerSpecs.windowBorderSize, ww: 40, wh: ViewerSpecs.scrollBarW+2*ViewerSpecs.windowBorderSize, parent: myShowData.pdContainer, border: FALSE, scrollable: FALSE], paint: FALSE]; curIndent _ myShowData.pageNumberViewer.wx + myShowData.pageNumberViewer.ww; myShowData.pageNumberSlider _ Sliders.Create[ info: [ wx: curIndent, wy: topLine, ww: myShowData.pdContainer.ww-curIndent, wh: ViewerSpecs.scrollBarW+2*ViewerSpecs.windowBorderSize, border: FALSE, parent: myShowData.pdContainer, scrollable: FALSE], filterProc: NormalizePageNumber, sliderProc: PageNumberSlider, orientation: horizontal, foreground: visibleGrey, background: invisibleGrey, clientData: myShowData, paint: FALSE]; Containers.ChildXBound[myShowData.pdContainer, myShowData.pageNumberSlider]; rule _ Rules.Create[ info: [ parent: myShowData.pdContainer, wx: 0, wy: topLine+ViewerSpecs.captionHeight+4*ViewerSpecs.windowBorderSize, wh: ViewerSpecs.menuBarHeight]]; Containers.ChildXBound[myShowData.pdContainer, rule]; myShowData.pdViewer _ pdViewer _ ViewerOps.CreateViewer[ flavor: $PD, info: [ name: fileName, parent: myShowData.pdContainer, wx: 0, wy: topLine+ViewerSpecs.captionHeight+5*ViewerSpecs.windowBorderSize, border: FALSE, scrollable: TRUE, data: myShowData], paint: FALSE ]; Containers.ChildXBound[myShowData.pdContainer, myShowData.pdViewer]; Containers.ChildYBound[myShowData.pdContainer, myShowData.pdViewer]; ViewerOps.PaintViewer[viewer: myShowData.pdContainer, hint: all]; DeltaPage[myShowData, 1]; EXITS Quit => RETURN; }; NormalizePageNumber: Sliders.FilterProc = TRUSTED { my: ShowData _ NARROW[clientData]; RETURN [Real.FDiv[Real.RoundI[value*(my.lastPageNumber)], (my.lastPageNumber)]] }; FirstPage: Buttons.ButtonProc = TRUSTED { my: ShowData _ NARROW[clientData]; DeltaPage[my, 1]; my.abortPainting_TRUE; Process.Detach[FORK PaintIt[my.pdViewer, my, pdPageSize]]; }; TurnPage: Buttons.ButtonProc = TRUSTED { my: ShowData _ NARROW[clientData]; where: INT _ IF mouseButton = red THEN +1 ELSE -1; DeltaPage[my, MIN[MAX[my.pageNumber+where, 1], (my.lastPageNumber)]]; my.abortPainting_TRUE; Process.Detach[FORK PaintIt[my.pdViewer, my, pdPageSize]]; }; LastPage: Buttons.ButtonProc = TRUSTED { my: ShowData _ NARROW[clientData]; DeltaPage[my, (my.lastPageNumber)]; my.abortPainting_TRUE; Process.Detach[FORK PaintIt[my.pdViewer, my, pdPageSize]]; }; PageNumber: Buttons.ButtonProc = TRUSTED { my: ShowData _ NARROW[clientData]; stream: IO.STREAM _ IO.RIS[ViewerTools.GetContents[my.pageNumberViewer]]; where: INT _ stream.GetInt[]; DeltaPage[my, MIN[MAX[where, 1], (my.lastPageNumber)]]; my.abortPainting_TRUE; Process.Detach[FORK PaintIt[my.pdViewer, my, pdPageSize]]; }; PageNumberSlider: Sliders.SliderProc = TRUSTED { my: ShowData _ NARROW[clientData]; SELECT reason FROM abort => { ViewerTools.SetContents[my.pageNumberViewer, IO.PutFR["%-g", IO.real[my.pageNumber]]]; }; move => { ViewerTools.SetContents[my.pageNumberViewer, IO.PutFR["%-g", IO.real[Real.RoundI[(my.lastPageNumber)*value]]]]; }; set => { DeltaPage[my, MIN[MAX[Real.RoundI[(my.lastPageNumber)*value], 1], (my.lastPageNumber)]]; my.abortPainting_TRUE; Process.Detach[FORK PaintIt[my.pdViewer, my, pdPageSize]]; }; ENDCASE; }; PDPaint: ViewerClasses.PaintProc = TRUSTED { bbox: Imager.Rectangle; showData: ShowData _ NARROW[self.data]; herald: PDFileFormat.Herald_showData.show.herald; IF showData.clearClient THEN RETURN; --dummy call to clear the viewer WITH whatChanged SELECT FROM handle: PDReaderPage.Handle => { scaleFactor: REAL _ showData.scaleFactor; context.TranslateT[[0, self.ch-showData.top]]; IF herald.imageSSize 0 THEN { context.SetColor[Imager.black]; ImagerBackdoor.DrawBits[context: context, base: handle.pixelMap.refRep.pointer, wordsPerLine: handle.pixelMap.refRep.rast, sMin: t.sMin, fMin: t.fMin, fSize: t.fSize, sSize: t.sSize, tx: w.fMin, ty: herald.imageSSize-w.sMin+w.sSize]; }; } ELSE showData.abortPainting_TRUE; --abort my own painting !! }; ENDCASE => { showData.abortPainting_TRUE; --abort clients painting Process.Detach[FORK PaintIt[self: self, data: showData, newvalue: showData.top]]; }; }; -- PDPaint PDScroll: ViewerClasses.ScrollProc = TRUSTED { my: ShowData _ NARROW[self.data]; my.height _ self.ch; SELECT op FROM query => RETURN [ top: Real.Fix[(1.0-my.top/pdPageSize)*100.0], bottom: Real.Fix[(1.0-(my.top-my.height)/pdPageSize)*100.0]]; up => IF my.top > my.height THEN { my.abortPainting_TRUE; Process.Detach[FORK PaintIt[self, my, MAX[my.top-amount, my.height]]]; }; down => IF my.top < pdPageSize THEN { my.abortPainting_TRUE; Process.Detach[FORK PaintIt[self, my, MIN[my.top+amount, pdPageSize]]]; }; thumb => { my.abortPainting_TRUE; Process.Detach[FORK PaintIt[self, my, MAX[MIN[(100-amount)*pdPageSize/100, pdPageSize], my.height]]]; }; ENDCASE => ERROR; }; -- PDScroll PDDestroy: ViewerClasses.DestroyProc = TRUSTED { showData: ShowData _ NARROW[self.data]; showData.abortPainting_TRUE; --can't be SURE this will stop reading stream Process.Detach[FORK PDDestroyInterlocked[showData]]; }; -- PDDestroy PDDestroyInterlocked: ENTRY PROCEDURE [showData: ShowData] = { PDFileReader.Close[handle: showData.show]; }; -- PDDestroy PaintIt: ENTRY PROCEDURE [self: ViewerClasses.Viewer, data: ShowData, newvalue: REAL] = { page: PDReaderPage.PageRecRef; DeltaTop[data, newvalue]; page _ PDReaderPage.ResetToPage[data: data]; data.abortPainting_FALSE; --may be set true later by Viewers IF page#NIL THEN []_PDReaderPage.InterpretPage[handle: data.show, viewer: self, pages: data.pageStructure]; }; DeltaPage: PROCEDURE [data: ShowData, newvalue: INT] = { data.pageNumber _ newvalue; ViewerTools.SetContents[data.pageNumberViewer, IO.PutFR["%-g", IO.int[newvalue]]]; Sliders.SetContents[data.pageNumberSlider, Real.FDiv[newvalue, (data.lastPageNumber)]]; }; DeltaTop: PROCEDURE [data: ShowData, newvalue: REAL] = { data.top _ newvalue; }; 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]; }; MakeShowPD: Commander.CommandProc = TRUSTED { reduction: REAL _ 1; fileName: Rope.ROPE _ NIL; cis: IO.STREAM _ IO.RIS[cmd.commandLine]; fileName _ IO.GetTokenRope[cis, Break ! IO.EndOfStream => CONTINUE].token; reduction _ IO.GetReal[cis ! IO.EndOfStream, IO.Error => CONTINUE]; [] _ CreateShowViewer[fileName, reduction]; }; -- MakeShowPD pdViewerClass.paint _ PDPaint; pdViewerClass.destroy _ PDDestroy; pdViewerClass.scroll _ PDScroll; ViewerOps.RegisterViewerClass[$PD, pdViewerClass]; Commander.Register[ key: "ShowPD", proc: MakeShowPD, doc: "Show a PD file in a Viewer" ]; END. -- ShowPDTool. fShowPDTool.mesa Last Edited by: Ken Pier, July 11, 1985 3:08:54 pm PDT Michael Plass, March 13, 1984 2:23:30 pm PST --PaintProc: TYPE = PROC [self: Viewer, context: Imager.Context, whatChanged: REF ANY, clear: BOOL]; --DestroyProc: TYPE = PROC [self: Viewer] ; CommandProc: TYPE = PROC [cmd: Handle] RETURNS [result: REF _ NIL, msg: Rope.ROPE _ NIL]; Κ ΅– "Cedar" style˜Icodešœ™™6K™,—šΟk ˜ Kšœœœ«˜ι—šΟa œœ˜Kšœ!œœ…˜ΛKšœ ˜K˜Kšœ+œ˜MK˜Kšœ œ˜!Kšœ œ˜'K˜Kšœ œΟc ˜'Kšœœ˜Kšœœu˜ŒKšœ@˜@KšœB˜BK˜šΟnœœœœ œœ#œ˜}Kšœ˜Kšœ œ˜Kšœ œ˜K˜K˜Kšœœ˜šœ#˜#Kšœ œ˜šœ˜KšœUœ˜[Kšœ˜Kšœ˜ Kšœ˜—šœ˜KšœUœ˜[Kšœ˜Kšœ˜ Kšœ˜—Kšœ˜—šœœœ˜Kšœ(˜(šœ#˜#šœ ˜ Kšœeœ˜kKšœ=œ˜DKšœ˜Kšœ˜ Kšœ˜—šœ˜KšœUœ˜[Kšœ˜Kšœ˜ Kšœ˜—šœ˜KšœUœ˜[Kšœ˜Kšœ˜ Kšœ˜—Kšœ˜—K˜—K˜Kšœ œK˜[Kšœ\˜\KšœN˜NK˜šœ+˜+šœ˜Kšœ˜Kšœœ˜ Kšœ˜Kšœ œ˜—Kšœœ˜—K˜šœ˜šœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœœ˜Kšœ ˜ —Kšœ˜Kšœ˜Kšœ>˜>Kšœœ˜—K˜"K˜šœ˜šœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœœ˜Kšœ ˜ —Kšœ˜Kšœ˜KšœI˜IKšœœ˜—Kšœ"˜"K˜šœ˜šœ˜Kšœ˜Kšœ˜Kšœ ˜ Kšœœ˜Kšœ ˜ —Kšœ˜Kšœ˜Kšœ5˜5Kšœœ˜—Kšœ"˜"K˜šœ˜šœ˜Kšœ ˜ Kšœ˜Kšœ ˜ Kšœœ˜Kšœ ˜ —Kšœ˜Kšœ˜Kšœ5˜5Kšœœ˜—Kšœ"˜"K˜šœ<˜<šœ˜Kšœ˜Kšœ)˜)Kšœ˜Kšœ:˜:Kšœ˜Kšœœ˜Kšœ œ˜—Kšœœ˜—KšœL˜LK˜šœ-˜-šœ˜Kšœ˜Kšœ ˜ Kšœ(˜(Kšœ:˜:Kšœœ˜Kšœ˜Kšœ œ˜—K˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ˜—KšœL˜LK˜˜˜Kšœ˜K˜KšœE˜EKšœ ˜ ——Kšœ5˜5K˜šœ8˜8Kšœ ˜ šœ˜Kšœ˜Kšœ˜Kšœ˜KšœE˜EKšœœ˜Kšœ œ˜Kšœ˜—Kšœœ˜—KšœD˜DKšœD˜DK•StartOfExpansionw[viewer: ViewerClasses.Viewer, hint: ViewerOps.PaintHint, clearClient: BOOL _ TRUE, whatChanged: REF ANY _ NIL]šœA˜AK˜K˜š˜Kšœœ˜—Kšœ˜—K˜šžœœ˜3Kšœœ ˜"KšœI˜OK˜—šž œœ˜)Kšœœ ˜"Kšœ˜Kšœœ˜Kšœœ'˜:K˜—šžœœ˜(Kšœœ ˜"Kš œœœœœ˜2Kšœœœ0˜EKšœœ˜Kšœœ'˜:K˜—šžœœ˜(Kšœœ ˜"Kšœ#˜#Kšœœ˜Kšœœ'˜:K˜—šž œœ˜*Kšœœ ˜"Kš œœœœœ/˜IKšœœ˜Kšœœœ"˜7Kšœœ˜Kšœœ'˜:K˜—šžœœ˜0Kšœœ ˜"šœ˜šœ ˜ Kšœ-œœ˜VKšœ˜—šœ ˜ Kšœ-œœ0˜oKšœ˜—šœ˜KšœœœC˜XKšœœ˜Kšœœ'˜:Kšœ˜—Kšœ˜—K˜—K™KšŸž ŸY™dšžœœ˜,Kšœ˜Kšœœ ˜'Kšœ1˜1KšœœœŸ ˜Ešœ œ˜šœ ˜ Kšœ œ˜)Kšœ.˜.šœ%œŸ˜EKšœ7˜7Kšœ˜K˜—Kšœ˜Kšœ)˜)šœ7œ˜?Kšœ-˜-Kšœ=˜=šœ œ˜Kšœ˜Kšœι˜ιKšœ˜—K˜—KšœœŸ˜˜QK˜——KšœŸ ˜—šžœœ˜.Kšœœ ˜!K˜šœ˜šœ œ˜Kšœ-˜-Kšœ=˜=—šœœœ˜"Kšœœ˜Kšœœœ˜FKšœ˜—šœœœ˜%Kšœœ˜Kšœœœ˜GKšœ˜—šœ ˜ Kšœœ˜Kšœœœœ8˜eKšœ˜—Kšœœ˜—KšœŸ ˜—K˜Kš  œœœ™+šž œœ˜0Kšœœ ˜'KšœœŸ-˜JKšœœ!˜4KšœŸ ˜—šΠanœœ œ˜?Kšœ*˜*KšœŸ ˜—š œœ œ8œ˜YKšœ˜Kšœ˜Kšœ,˜,KšœœŸ"˜