summaryrefslogtreecommitdiffstats
path: root/lib/Phi/Border.hs
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-08-21 19:34:16 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-08-21 19:34:16 +0200
commit42c14fa1ca9d47ae32766aaa2aa995c684b7e9cb (patch)
tree7c12e75cf89573c2d3ecb8c0c4fcc4ccbc56b24d /lib/Phi/Border.hs
parentddca7c3ec59a5b7c62a11afe225de40edbde85ff (diff)
downloadphi-42c14fa1ca9d47ae32766aaa2aa995c684b7e9cb.tar
phi-42c14fa1ca9d47ae32766aaa2aa995c684b7e9cb.zip
Make render function return cachable surface slices
Diffstat (limited to 'lib/Phi/Border.hs')
-rw-r--r--lib/Phi/Border.hs67
1 files changed, 50 insertions, 17 deletions
diff --git a/lib/Phi/Border.hs b/lib/Phi/Border.hs
index c9b582e..c6e7531 100644
--- a/lib/Phi/Border.hs
+++ b/lib/Phi/Border.hs
@@ -53,19 +53,21 @@ defaultBorderConfig = BorderConfig { margin = simpleBorderWidth 0
, borderWeight = 1
}
-data Border w d = (Widget w d) => Border !BorderConfig !w
-deriving instance Show (Border w d)
-deriving instance Eq (Border w d)
+data Border w s c = (Widget w s c) => Border !BorderConfig !w
+deriving instance Show (Border w s c)
+deriving instance Eq (Border w s c)
-instance Eq d => Widget (Border w d) d where
+data BorderCache w s c = (Widget w s c) => BorderCache !c
+
+instance Eq s => Widget (Border w s c) s (BorderCache w s c) where
initWidget (Border _ w) = initWidget w
- minSize (Border config w) d height screen =
+ minSize (Border config w) s height screen =
case True of
_ | childSize == 0 -> 0
| otherwise -> max (borderH m+2*(bw+cr)) (childSize + borderH p + 2*bw + borderH m)
where
- childSize = minSize w d height' screen
+ childSize = minSize w s height' screen
m = margin config
bw = borderWidth config
@@ -75,9 +77,9 @@ instance Eq d => Widget (Border w d) d where
weight (Border config _) = borderWeight config
- layout (Border config w) d width height screen = case True of
- _ | width' > 0 -> layout w d width' height' screen
- | otherwise -> d
+ layout (Border config w) s width height screen = case True of
+ _ | width' > 0 -> layout w s width' height' screen
+ | otherwise -> s
where
m = margin config
bw = borderWidth config
@@ -86,18 +88,49 @@ instance Eq d => Widget (Border w d) d where
width' = width - borderH m - 2*bw - borderH p
height' = height - borderV m - 2*bw - borderV p
- render (Border config w) d x y width height screen = when (width > borderH m - 2*bw - borderH p) $ do
- drawBorder config 0 0 width height
- clip
- translate (fromIntegral dx) (fromIntegral dy)
- render w d (x+dx) (y+dy) width' height' screen
- return ()
+ render (Border config w) s x y width height screen = case () of
+ _ | (width > borderH m - 2*bw - borderH p) -> do
+ border <- createImageSurface FormatARGB32 width height
+ renderWith border $ do
+ setOperator OperatorClear
+ paint
+ setOperator OperatorOver
+ drawBorder config 0 0 width height
+ surfaces <- render w s (x+dx) (y+dy) width' height' screen
+ let surfaces' = (True, 0, Nothing):(map (\(updated, SurfaceSlice x surf) -> (updated, x+dx, Just surf)) surfaces)++[(True, width-rightWidth, Nothing)]
+ surfacesWidths = zipWith (\(updated, x, surf) (_, x', _) -> (updated, x, x'-x, surf)) surfaces' (tail surfaces' ++ [(False, width, Nothing)])
+ forM surfacesWidths $ \(updated, x, surfWidth, surf) -> do
+ surf' <- createImageSurface FormatARGB32 surfWidth height
+ renderWith surf' $ do
+ setOperator OperatorClear
+ paint
+ setOperator OperatorOver
+
+ save
+ translate (fromIntegral (-x)) 0
+ withPatternForSurface border setSource
+ paint
+ restore
+
+ case surf of
+ Just surface -> do
+ translate 0 (fromIntegral dy)
+ withPatternForSurface surface setSource
+ paint
+ Nothing -> return ()
+
+ return (updated, SurfaceSlice x surf')
+ | otherwise -> do
+ surface <- createImageSurface FormatARGB32 width height
+ return [(True, SurfaceSlice 0 surface)]
where
m = margin config
bw = borderWidth config
p = padding config
- dx = borderLeft m + bw + borderLeft p
+ leftWidth = borderLeft m + bw + borderLeft p
+ rightWidth = borderRight m + bw + borderRight p
+ dx = leftWidth
dy = borderTop m + bw + borderTop p
width' = width - borderH m - 2*bw - borderH p
height' = height - borderV m - 2*bw - borderV p
@@ -139,5 +172,5 @@ roundRectangle x y width height radius = do
arc (x + radius) (y + radius) radius pi (pi*3/2)
closePath
-border :: (Widget w d) => BorderConfig -> w -> Border w d
+border :: (Widget w s c) => BorderConfig -> w -> Border w s c
border = Border