<> <> <> DIRECTORY Args, CedarProcess, ColorTrixBasics, ColorTrixFile, ColorTrixPrivate, Commander, Controls, ImagerPixelMap, Process, Real, Rope, Terminal; ColorTrixCommandsImplC: CEDAR PROGRAM IMPORTS Args, CedarProcess, ColorTrixBasics, ColorTrixFile, Controls, Process, Real, Terminal EXPORTS ColorTrixPrivate ~ BEGIN ROPE: TYPE ~ Rope.ROPE; PixelMap: TYPE ~ ColorTrixBasics.PixelMap; PixelMapMisc: TYPE ~ ColorTrixBasics.PixelMapMisc; DeviceRectangle: TYPE ~ ImagerPixelMap.DeviceRectangle; MovieData: TYPE ~ REF MovieDataRec; MovieDataRec: TYPE ~ MONITORED RECORD [ x, y, w, h, nFrames: NAT _ 0, nRows, nCols: NAT _ 0, speed, frame: Controls.Control _ NIL, outer: Controls.Viewer _ NIL, outerData: Controls.OuterData _ NIL, frames, show, save: PixelMapMisc, now: REAL _ 0.0, nFrame: INTEGER _ 0, pause, pauseSave: BOOL _ FALSE, bounce: BOOL _ FALSE, forward, forwardSave: BOOL _ TRUE ]; CtMovie: PUBLIC Commander.CommandProc ~ { ok: BOOL; x, y, w, h, nFrames, clear, name: Args.Arg; [ok, x, y, w, h, nFrames, clear, name] _ Args.ArgsGet[cmd, "%iiiii-clear%b-name%s"]; IF NOT ok THEN RETURN[$Failure, NIL] ELSE { cd: PixelMapMisc _ ColorTrixBasics.GetColorDisplayPmMisc[]; m: MovieData _ NEW[MovieDataRec]; m.x _ x.int; m.y _ y.int; m.w _ w.int; m.h _ h.int; m.nFrames _ nFrames.int; m.show _ ColorTrixBasics.SetPmMiscWindow[cd, (cd.w-m.w)/2, (cd.h-m.h)/2, m.w, m.h]; IF name.ok THEN { m.frames _ ColorTrixFile.ReadFile[name.rope]; [m.nCols, m.nRows] _ NRowsCols[m.frames, m.nFrames, m.x, m.w]; } ELSE { [m.nCols, m.nRows] _ NRowsCols[cd, m.nFrames, m.x, m.w]; cd _ ColorTrixBasics.SetPmMiscWindow[ cd, 0, 0, m.nCols*m.w, MIN[cd.h, m.nRows*m.h]]; m.frames _ ColorTrixBasics.CreatePmMisc[cd.bpp, cd.x, cd.y, cd.w, cd.h]; ColorTrixBasics.CopyPmMisc[cd, m.frames]; }; m.speed _ Controls.NewControl["Speed", hSlider, m, -1.0, 1.0, 0.1,,,,,,,,,,,, LIST[[0.0, 0.0]]]; m.frame _ Controls.NewControl["Frame", hSlider, m, 0, nFrames.int-1,0, Frame,,TRUE]; m.outer _ Controls.OuterViewer[ data: m, column: right, name: "Ct Movie", destroyProc: DestroyProc, controls: LIST[m.speed, m.frame], buttons: LIST [["Forward", Forward], ["Bounce-Off", Bounce], ["Pause", Pause]] ]; m.outerData _ NARROW[m.outer.data]; IF clear.ok AND clear.bool THEN ColorTrixBasics.FillPmMisc[cd]; ColorTrixBasics.CopyPmMisc[m.show, m.save _ ColorTrixBasics.CreatePmMisc[cd.bpp, m.show.x, m.show.y, m.show.w, m.show.h]]; TRUSTED {Process.Detach[FORK Movie[m]]}; }; }; NRowsCols: PROC [pm: PixelMapMisc, nFrames, x, w: NAT] RETURNS [nCols, nRows: NAT] ~ { nCols _ MIN[nFrames, (pm.w-x)/w]; nRows _ nFrames/nCols+MIN[1, nFrames MOD nCols]; }; DestroyProc: Controls.DestroyProc ~ {NARROW[outerData.data, MovieData].pause _ FALSE}; ShowNFrame: PROC [m: MovieData] ~ { SetNFrame[m]; Terminal.WaitForBWVerticalRetrace[Terminal.Current[]]; ColorTrixBasics.CopyClippedPmMisc[ m.frames, m.show, m.x+(m.nFrame MOD m.nCols)*m.w, m.y+(m.nFrame/m.nCols)*m.h, m.w, m.h]; IF NOT m.pause THEN Controls.SetSliderDialValue[m.frame, m.nFrame]; }; SetNFrame: PROC [m: MovieData] ~ { IF (m.nFrame _ Real.RoundI[m.now]) IN [0..m.nFrames) THEN RETURN; IF m.bounce THEN { m.forward _ NOT m.forward; m.nFrame _ IF m.nFrame < 0 THEN 0 ELSE m.nFrames-1; } ELSE { IF m.nFrame >= m.nFrames THEN m.now _ m.nFrame _ 0; IF m.nFrame < 0 THEN m.now _ m.nFrame _ m.nFrames-1; }; }; Frame: Controls.ControlProc ~ { m: MovieData ~ NARROW[control.data]; IF control.mouse.state = down THEN {m.pauseSave _ m.pause; m.pause _ TRUE}; m.now _ control.value; ShowNFrame[m]; IF control.mouse.state = up THEN m.pause _ m.pauseSave; }; Movie: PROC [m: MovieData] ~ { CedarProcess.SetPriority[background]; WHILE NOT m.outerData.destroyed DO IF m.pause THEN {Process.Pause[Process.MsecToTicks[150]]; LOOP}; m.now _ m.now+(IF m.forward THEN m.speed.value ELSE -m.speed.value); ShowNFrame[m]; ENDLOOP; ColorTrixBasics.CopyPmMisc[m.save, m.show]; }; Pause: Controls.ClickProc ~ { m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data]; m.pause _ NOT m.pause; Controls.ButtonStyle[ m.outerData, "Pause", IF m.pause THEN $WhiteOnBlack ELSE $BlackOnWhite]; }; Bounce: Controls.ClickProc ~ { m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data]; Controls.ButtonToggle[m.outerData, m.bounce _ NOT m.bounce, "Bounce-On", "Bounce-Off"]; IF m.bounce THEN m.forwardSave _ m.forward ELSE m.forward _ m.forwardSave; }; Forward: Controls.ClickProc ~ { m: MovieData ~ NARROW[NARROW[clientData, Controls.OuterData].data]; m.forward _ m.forwardSave _ NOT m.forward; Controls.ButtonToggle[m.outerData, m.forward, "Forward", "Reverse"]; }; <<>> END.