The Tiler abstraction is intended used by programmers that want to create their own layout functions. As an example, here is the definition of the padW combinator from the Haggis library, which adds external padding to a component:
padW :: Size -> DisplayHandle -> DisplayHandle
padW (padx,pady) dh dc =
dh dc >>= \ch ->
getGeometry ch >>= \child_geo ->
let
{-
resize function - subtract the padding
in both directions and let the padded
component have what's left.
-}
resize sz@(w,h) geo =
let
rect = Rect padx pady (w-padx) (h-pady)
in
return [(rect,child_geo,ch)]
{-
computing initial size of combinator bounding
box and padded component
-}
initialSize =
let
(natw,nath) = getGeoNatSize child_geo
natw' = natw + 2*padx
nath' = nath + 2*pady
centre_geo = augmentGeo (2*padx,2*pady) child_geo
child_extent = Rect padx pady natw nath
in
return ((natw',nath'),
centre_geo,
[(child_extent,child_geo,ch)])
{-
Iterating over the tiler components is easy as
there's only one!
-}
iterate f =
getSize ch >>= \ (w,h) ->
f (Rect padx pady w h,child_geo,ch)
{-
Check if we have a hit inside the padded component.
-}
pick pnt =
getSize ch >>= \ (w,h) ->
if pointInRect (Rect padx pady w h) pnt then
return (Just (Rect padx pady w h,child_geo,ch))
else
return Nothing
methods =
(resize,
pick,
initialSize,
iterate)
in
mkTiler methods dc >>= \ (_,dh) ->
dh
Having specified the layout functionality in the functions resize and initialSize, the Tiler takes over and manages the interaction with the rest of the Haggis world. To test if the above code really, here's a little test program:
module Main(main) where import Haggis main :: IO () main = mkDC [] >>= \dc -> glyph (withColour red $ fillSolid $ square 30) dc >>= \(_,dh) -> realiseDH dc (padW (10,20) dh)
