This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
phi/lib/Phi/Widgets/Clock.hs

91 lines
2.7 KiB
Haskell
Raw Permalink Normal View History

2011-08-21 21:40:31 +02:00
{-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances, StandaloneDeriving #-}
2011-07-14 20:21:30 +02:00
module Phi.Widgets.Clock ( ClockConfig(..)
, defaultClockConfig
, clock
) where
import Control.Concurrent
import Control.Monad
import Data.Typeable
import Data.Time.LocalTime
import Data.Time.Format
import Graphics.Rendering.Cairo
import Graphics.Rendering.Pango.Cairo
import Graphics.Rendering.Pango.Enums (PangoRectangle(..))
import Graphics.Rendering.Pango.Layout
import System.Locale
import Phi.Phi
import Phi.Types
import Phi.Widget
data ClockConfig = ClockConfig { clockFormat :: !String
, fontColor :: !Color
, lineSpacing :: !Double
, clockSize :: !Int
} deriving (Show, Eq)
2011-07-14 20:21:30 +02:00
defaultClockConfig :: ClockConfig
defaultClockConfig = ClockConfig "%R" (0, 0, 0, 1) 0 50
2011-09-08 19:15:23 +02:00
data Clock d = Clock !ClockConfig deriving (Show, Eq)
2011-07-14 20:21:30 +02:00
2011-08-21 21:40:31 +02:00
deriving instance Eq ZonedTime
data ClockState = ClockState !ZonedTime deriving (Show, Eq)
2011-07-14 22:50:03 +02:00
2011-08-12 03:18:46 +02:00
data ClockMessage = UpdateTime !ZonedTime deriving (Show, Typeable)
2011-07-14 22:50:03 +02:00
2011-09-08 19:15:23 +02:00
instance Display d => Widget (Clock d) ClockState (RenderCache ClockState) d where
2011-08-29 15:10:55 +02:00
initWidget (Clock _) phi _ _ = do
2011-07-14 20:21:30 +02:00
forkIO $ forever $ do
time <- getZonedTime
2011-07-14 22:50:03 +02:00
sendMessage phi $ UpdateTime time
2011-07-14 20:21:30 +02:00
sendMessage phi Repaint
threadDelay $ ceiling $ 1000000*(max 1 $ 60 - (todSec . localTimeOfDay . zonedTimeToLocalTime $ time))
2011-07-14 22:50:03 +02:00
time <- getZonedTime
return $ ClockState time
2011-08-21 21:39:26 +02:00
initCache (Clock config) = createRenderCache $ \(ClockState time) _ _ w h _ -> do
2011-08-21 21:39:26 +02:00
let (r, g, b, a) = fontColor config
str = formatTime defaultTimeLocale (clockFormat config) time
setSourceRGBA r g b a
layout <- createLayout ""
(_, PangoRectangle _ _ textWidth textHeight) <- liftIO $ do
layoutSetMarkup layout str
layoutSetAlignment layout AlignCenter
layoutSetSpacing layout $ lineSpacing config
layoutGetExtents layout
let scalef = min 1 ((fromIntegral w)/textWidth)
when (scalef < 1) $ do
scale scalef scalef
updateLayout layout
(_, PangoRectangle _ _ textWidth' textHeight') <- liftIO $ layoutGetExtents layout
moveTo (((fromIntegral w)/scalef - textWidth')/2) (((fromIntegral h)/scalef - textHeight')/2)
showLayout layout
2011-07-14 20:21:30 +02:00
minSize (Clock config) _ _ _ = clockSize config
2011-07-14 20:21:30 +02:00
render _ = renderCached
2011-07-14 22:50:03 +02:00
handleMessage _ priv m = case (fromMessage m) of
Just (UpdateTime time) -> ClockState time
_ -> priv
2011-07-14 20:21:30 +02:00
2011-09-08 19:15:23 +02:00
clock :: ClockConfig -> Clock d
2011-07-14 20:21:30 +02:00
clock config = do
2011-09-08 19:15:23 +02:00
Clock config