MODULE; IMPORT Axis, BdrVBTClass, BorderedVBT, Filter, MouseSplit, Rect, Region, Shadow, ShadowPaint, VBT, VBTClass; REVEAL Private = BorderedVBT.T BRANDED OBJECT END; T = Public BRANDED OBJECT shadow: Shadow.T; style : Shadow.Style; OVERRIDES init := Init; rescreen := Rescreen; repaintBorder := RepaintBorder; END; PROCEDURE ShadowedVBT Init (v : T; ch : VBT.T; shadow: Shadow.T := NIL; style : Shadow.Style := Shadow.Style.Flat): T = BEGIN IF shadow = NIL THEN shadow := Shadow.None END; v.shadow := shadow; v.style := style; ComputeBSize(v); EVAL Filter.T.init(v, ch); RETURN v END Init; PROCEDURESet (v: T; shadow: Shadow.T) = BEGIN IF v.shadow.size # shadow.size THEN VBT.NewShape(v) END; v.shadow := shadow; VBT.Mark(v) END Set; PROCEDURESetStyle (v: T; style: Shadow.Style) = BEGIN IF v.style # style THEN v.style := style; VBT.Mark(v) END END SetStyle; PROCEDUREGet (v: T): Shadow.T = BEGIN RETURN v.shadow END Get; PROCEDUREGetStyle (v: T): Shadow.Style = BEGIN RETURN v.style END GetStyle; PROCEDUREComputeBSize (v: T) = VAR size: REAL; BEGIN size := ABS(v.shadow.size); IF NOT Shadow.Supported(v.shadow, v) THEN size := size / 2.0 END; FOR ax := FIRST(Axis.T) TO LAST(Axis.T) DO v.bSize[ax] := ROUND(VBT.MMToPixels(v, size, ax)); END; END ComputeBSize; PROCEDUREChDom (v: T): Rect.T = (* Compute child domain from v's domain and border sizes *) BEGIN WITH dh = v.bSize [Axis.T.Hor], dv = v.bSize [Axis.T.Ver] DO RETURN Rect.Change (VBT.Domain (v), dh, -dh, dv, -dv) END END ChDom; PROCEDURERescreen (v: T; READONLY cd: VBT.RescreenRec) = BEGIN ComputeBSize(v); VBT.NewShape(v); Filter.T.rescreen(v, cd) END Rescreen; PROCEDURERepaintBorder (v: T; READONLY clip: Rect.T) = (* repaint the part of v's border that lies within clip. LL = VBT.mu. *) BEGIN ShadowPaint.Border(v, Region.FromRect(clip), v.shadow, v.style, ChDom(v), VBT.Domain(v)); END RepaintBorder; BEGIN END ShadowedVBT.