<> <> <> <<>> DIRECTORY Abutters, Buttons USING [ButtonProc, Create], Convert USING [RealFromRope], Imager USING [MaskVector, SetStrokeWidth], ImagerBackdoor USING [GetReal], IO, Real USING [CompareREAL], RedBlackTree, --using lots... Rope USING [Equal, ROPE], Trc, Vector2 USING [InlineAdd, Length, Sub, VEC], ViewerClasses USING [Viewer, ViewerRec], ViewerOps, ViewerTools; TrcManualImpl: CEDAR PROGRAM IMPORTS Abutters, Buttons, Convert, Imager, ImagerBackdoor, IO, Real, RedBlackTree, Rope, Trc, Vector2, ViewerOps, ViewerTools ~ BEGIN ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector2.VEC; margin: NAT ~ 10; ManualInstance: TYPE ~ REF ManualInstanceRep; ManualInstanceRep: TYPE ~ RECORD [ xScale, yScale: REAL _ 1.0, pins: RedBlackTree.Table _ RedBlackTree.Create[getKey: TrcManualGet, compare: TrcManualCompare] ]; Pin: TYPE ~ REF PinRep; PinRep: TYPE ~ RECORD [ vec: Vector2.VEC ]; ManualControlData: TYPE ~ REF ManualControlDataRep; ManualControlDataRep: TYPE ~ RECORD [ container, childControl: ViewerClasses.Viewer _ NIL, trc: Trc.TRC _ NIL, y: INTEGER ]; ManualFcn: Trc.Fcn = { <<[trc: TRC, a: REAL] RETURNS [b: REAL]>> VecFromRef: PROC [ref: REF] RETURNS [vec: VEC] ~ { WITH ref SELECT FROM p: Pin => RETURN [p^]; --This will return NIL as well ENDCASE => ERROR; }; instance: ManualInstance ~ NARROW[trc.instance]; left, equal, right: REF; [left, equal, right] _ RedBlackTree.Lookup3[self: instance.pins, lookupKey: RealToRef[a]]; SELECT TRUE FROM equal#NIL => RETURN [VecFromRef[equal].y]; left=NIL AND right=NIL => RETURN [a]; left=NIL => RETURN [NARROW[right, Pin].y]; right=NIL => RETURN [NARROW[left, Pin].y] ENDCASE => { --We're between two pins, at least one of which is a fixed Pin. vLeft: VEC ~ VecFromRef[left]; vRight: VEC ~ VecFromRef[right]; alpha: REAL ~ (a-vLeft.x)/(vRight.x-vLeft.x); RETURN [(alpha*(vRight.y) + (1.0-alpha)*(vLeft.y))] }; }; ManualBackground: Trc.BackgroundProc = { <<[trc: TRC, context: Imager.Context, rectangle: ImagerTransformation.Rectangle, whatChanged: REF _ NIL]>> Mark: PROC [vec: VEC] ~ INLINE { Imager.MaskVector[context: context, p1: vec.InlineAdd[[-d,-d]], p2: vec.InlineAdd[[d,d]]]; Imager.MaskVector[context: context, p1: vec.InlineAdd[[d,-d]], p2: vec.InlineAdd[[-d,d]]]; }; instance: ManualInstance ~ NARROW[trc.instance]; w: REAL ~ ImagerBackdoor.GetReal[context: context, key: strokeWidth]; d: REAL ~ 3*w; Imager.SetStrokeWidth[context: context, strokeWidth: w/2]; IF whatChanged=NIL THEN { XMarksTheSpot: RedBlackTree.EachNode = { <<[data: RedBlackTree.UserData] RETURNS [stop: BOOL _ FALSE]>> WITH data SELECT FROM pin: Pin => Mark[pin^]; ENDCASE => ERROR; }; RedBlackTree.EnumerateIncreasing[self: instance.pins, procToApply: XMarksTheSpot]; } ELSE { WITH whatChanged SELECT FROM atom: ATOM => NULL; --Somebody has us layered ENDCASE => ERROR; }; }; ManualPickle: Trc.PickleProc = { <<[trc: TRC, stream: STREAM, indentation: ROPE _ NIL]>> instance: ManualInstance ~ NARROW[trc.instance]; IO.PutRope[self: stream, r: " {"]; PutValuesToStream[instance, stream, indentation]; IO.PutF[stream: stream, format: "\n%g}", v1: [rope[indentation]]]; }; ManualDepickle: Trc.DepickleProc = { <<[class: Trc.Class, stream: STREAM] RETURNS [trc: TRC]>> instance: ManualInstance ~ NEW[ManualInstanceRep]; token: ROPE; <> trc _ NEW[Trc.TRCRep _ [class: class, instance: instance, listener: NIL]]; IF ~IO.GetCedarTokenRope[stream: stream].token.Equal["{"] THEN ERROR; <<[tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream];>> <> <> <<[tokenKind: tokenKind, token: token] _ IO.GetCedarTokenRope[stream: stream];>> <