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
|
2011-08-21 05:38:37 +02:00
|
|
|
} 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
|
2011-08-21 05:38:37 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
2011-08-29 15:34:56 +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
|
|
|
|
2011-07-18 20:57:19 +02:00
|
|
|
minSize (Clock config) _ _ _ = clockSize config
|
2011-07-14 20:21:30 +02:00
|
|
|
|
2011-08-29 15:34:56 +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
|