{-# LANGUAGE CPP #-} module Placers(linearP, verticalP, horizontalP, horizontalP', verticalP') where import Geometry import LayoutDir import LayoutRequest import Spacers(Distance(..)) import Data.List(mapAccumL) import Utils(part) import Defaults(defaultSep) import Maptrace(ctrace) -- debugging --import NonStdTrace(trace) import IntMemo #ifndef __HBC__ #define fromInt fromIntegral #endif horizontalP = horizontalP' defaultSep verticalP = verticalP' defaultSep horizontalP' = linearP Horizontal verticalP' = linearP Vertical linearP :: LayoutDir -> Distance -> Placer linearP ld sep = P $ linearP' ld sep linearP' ld sep [] = ctrace "linearP" ("linearP "++show ld++" []") $ (plainLayout 1 (ld==Horizontal) (ld==Vertical),\ r -> []) linearP' ld sep requests = let minsizes = map minsize requests totis = sep * (max 0 (length requests - 1)) h = max 0 (h'-sep) -- totis + sum (map (xc ld) minsizes) (h',rpss) = mapAccumL adjust 0 requests where adjust x (Layout {minsize=rsz,refpoints=rps}) = (x+rw+sep,map adj1 rps) where adj1 p = mkp ld (x+xc ld p) (yc ld p) rw = xc ld rsz v = (maximum . (0:) . map (yc ld)) minsizes line2 gotr = let goth = (fromInt . xc ld . rectsize) gotr - fromInt totis gotv = (yc ld . rectsize) gotr startx = (fromInt . xc ld . rectpos) gotr starty = (yc ld . rectpos) gotr #if 0 -- Old solution requests' = requests #else -- New, experimental solution: requests' = map req' requests where req' req = req {minsize=adj gotv} where adj=orthogonal ld (wAdj req) (hAdj req) #endif (fih, flh) = part (fixh ld) requests' fixedh' = (fromInt . sum . map (xc ld . minsize)) fih floath = (fromInt . sum . map (xc ld . minsize)) flh fixedR = if floath > 0.0 then 1.0 else goth / fixedh' floatR = if floath == 0.0 then 1.0 else (goth - fixedh') / floath rR' req = if fixh ld req then fixedR else floatR pl x req = let width = (fromInt . xc ld . minsize) req * rR' req in (x + width + fromInt sep, Rect (mkp ld (truncate x) starty) (mkp ld (truncate width) gotv)) in snd (mapAccumL pl startx requests') (fh',fv') = vswap ld (allf and fixh,allf or fixv) rps' = concat rpss --concatMap refpoints requests allf conn fix = conn (map (fix ld) requests) req0 = refpLayout (mkp ld h v) fh' fv' rps' req = case ld of Horizontal -> req0 { hAdj=memoInt ha } where ha h = Point (totis+sum ws) h where ws = map (xcoord . flip hAdj h) requests Vertical -> req0 { wAdj=memoInt wa } where wa w = Point w (totis+sum hs) where hs = map (ycoord . flip wAdj w) requests in (req,line2) #ifdef __NHC__ fromInt = fromIntegral #endif