module Spacers where import LayoutRequest import Geometry import Utils(mapPair) import Alignment ---- Spacer types type Distance = Int ---- Primitive Spacers -- Fixed margins hMarginS, vMarginS :: Distance -> Distance -> Spacer hMarginS dLeft dRight = hvMarginS (pP dLeft 0) (pP dRight 0) vMarginS dTop dBottom = hvMarginS (pP 0 dTop) (pP 0 dBottom) hvMarginS :: Size -> Size -> Spacer hvMarginS dUpperLeft dBottomRight = S $ \ req -> let growth = dUpperLeft + dBottomRight in (mapLayoutRefs (+dUpperLeft) $ mapAdjLayoutSize (+growth) (+(-xcoord growth)) (+(-ycoord growth)) req, center' dUpperLeft growth) center p (Rect r s) = Rect (r+p) (s-(p+p)) center' offset shrink (Rect r s) = Rect (r+offset) (s-shrink) sepS :: Size -> Spacer sepS s = hvMarginS s s marginS :: Distance -> Spacer marginS d = sepS (diag d) -- Flexible margins leftS = hAlignS aLeft hCenterS = hAlignS aCenter rightS = hAlignS aRight vAlignS = flipS . hAlignS topS = flipS leftS vCenterS = flipS hCenterS bottomS = flipS rightS hvAlignS hpos vpos = hAlignS hpos `compS` vAlignS vpos centerS = vCenterS `compS` hCenterS hAlignS :: Alignment -> Spacer hAlignS hpos = S $ \ (Layout size@(Point rw _) fh fv wa ha rps wanted) -> let wa' w = wa (min rw w) hAlignR (Rect p@(Point x y) s@(Point aw ah)) = Rect (pP (x+spaceLeft) y) (pP rw' ah) where space = aw-rw' spaceLeft = scale hpos space rw' = min rw aw rw = xcoord (ha ah) in (Layout size False{-fh-} fv wa' ha rps wanted,hAlignR) marginHVAlignS sep halign valign = marginS sep `compS` hvAlignS halign valign --- Spacer operations spacerP :: Spacer -> Placer -> Placer spacerP (S spacer) (P placer) = P $ \ reqs -> let (req',placer2) = placer reqs (req'',spacer2) = spacer req' in (req'',placer2.spacer2) --flipS :: Spacer -> Spacer flipS = mapS flipS' where flipS' spacer = mapPair (flipReq,flipS2) . spacer . flipReq flipS2 spacer2 = flipRect.spacer2.flipRect mapS f (S sp) = S (f sp) --idS :: Spacer idS = S $ \ req -> (req,id) compS :: Spacer -> Spacer -> Spacer compS (S spa) (S spb) = S $ \ req -> let (req',spb2) = spb req (req'',spa2) = spa req' in (req'',spb2.spa2) sizeS,maxSizeS,minSizeS :: Size -> Spacer sizeS = resizeS . const maxSizeS = resizeS . pmin minSizeS = resizeS . pmax resizeS :: (Size->Size) -> Spacer resizeS = layoutModifierS . mapLayoutSize -- The above and below lines now mean the same --resizeS f = layoutModifierS (mapAdjLayoutSize f id id) noStretchS :: Bool -> Bool -> Spacer noStretchS fh fv = layoutModifierS lf where lf req = req { fixedh=fh, fixedv=fv } --noStretchS fh fv req = (mapLayout lf req ,id) -- where lf size _ _ wa ha rps = Layout size fh fv wa ha rps mapLayout f req = case req of Layout size fh fv wa ha rps wanted -> f size fh fv wa ha rps wanted --layoutModifierS :: (LayoutRequest -> LayoutRequest) -> Spacer layoutModifierS lf = S $ \ req -> (lf req,id)