---------------------------------------------------------------------------- -- | -- Module : XMonad.Util.Image -- Copyright : (c) 2010 Alejandro Serrano -- License : BSD-style (see xmonad/LICENSE) -- -- Maintainer : trupill@gmail.com -- Stability : unstable -- Portability : unportable -- -- Utilities for manipulating [[Bool]] as images -- ----------------------------------------------------------------------------- module XMonad.Util.Image ( -- * Usage: -- $usage Placement(..), iconPosition, drawIcon, ) where import XMonad import XMonad.Util.Font (stringToPixel,fi) -- | Placement of the icon in the title bar data Placement = OffsetLeft Int Int -- ^ An exact amount of pixels from the upper left corner | OffsetRight Int Int -- ^ An exact amount of pixels from the right left corner | CenterLeft Int -- ^ Centered in the y-axis, an amount of pixels from the left | CenterRight Int -- ^ Centered in the y-axis, an amount of pixels from the right deriving (Show, Read) -- $usage -- This module uses matrices of boolean values as images. When drawing them, -- a True value tells that we want the fore color, and a False value that we -- want the background color to be painted. -- In the module we suppose that those matrices are represented as [[Bool]], -- so the lengths of the inner lists must be the same. -- -- See "Xmonad.Layout.Decoration" for usage examples -- | Gets the ('width', 'height') of an image imageDims :: [[Bool]] -> (Int, Int) imageDims img = (length (head img), length img) -- | Return the 'x' and 'y' positions inside a 'Rectangle' to start drawing -- the image given its 'Placement' iconPosition :: Rectangle -> Placement -> [[Bool]] -> (Position,Position) iconPosition (Rectangle _ _ _ _) (OffsetLeft x y) _ = (fi x, fi y) iconPosition (Rectangle _ _ w _) (OffsetRight x y) icon = let (icon_w, _) = imageDims icon in (fi w - fi x - fi icon_w, fi y) iconPosition (Rectangle _ _ _ h) (CenterLeft x) icon = let (_, icon_h) = imageDims icon in (fi x, fi (h `div` 2) - fi (icon_h `div` 2)) iconPosition (Rectangle _ _ w h) (CenterRight x) icon = let (icon_w, icon_h) = imageDims icon in (fi w - fi x - fi icon_w, fi (h `div` 2) - fi (icon_h `div` 2)) -- | Converts an image represented as [[Bool]] to a series of points -- to be painted (the ones with True values) iconToPoints :: [[Bool]] -> [Point] iconToPoints icon = let labels_inside = map (zip (iterate (1+) 0)) icon filtered_inside = map (\l -> [x | (x, t) <- l, t]) labels_inside labels_outside = zip (iterate (1+) 0) filtered_inside in [Point x y | (y, l) <- labels_outside, x <- l] -- | Displaces a point ('a', 'b') along a vector ('x', 'y') movePoint :: Position -> Position -> Point -> Point movePoint x y (Point a b) = Point (a + x) (b + y) -- | Displaces a list of points along a vector 'x', 'y' movePoints :: Position -> Position -> [Point] -> [Point] movePoints x y points = map (movePoint x y) points -- | Draw an image into a X surface drawIcon :: (Functor m, MonadIO m) => Display -> Drawable -> GC -> String ->String -> Position -> Position -> [[Bool]] -> m () drawIcon dpy drw gc fc bc x y icon = do let (i_w, i_h) = imageDims icon fcolor <- stringToPixel dpy fc bcolor <- stringToPixel dpy bc io $ setForeground dpy gc bcolor io $ fillRectangle dpy drw gc x y (fi i_w) (fi i_h) io $ setForeground dpy gc fcolor io $ drawPoints dpy drw gc (movePoints x y (iconToPoints icon)) coordModeOrigin