2011-07-14 22:50:03 +02:00
|
|
|
{-# LANGUAGE TypeFamilies, DeriveDataTypeable #-}
|
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
|
|
|
|
|
|
|
|
defaultClockConfig :: ClockConfig
|
|
|
|
defaultClockConfig = ClockConfig "%R" (0, 0, 0, 1) 0 50
|
|
|
|
|
|
|
|
data Clock = Clock ClockConfig deriving Show
|
|
|
|
|
2011-07-14 22:50:03 +02:00
|
|
|
data ClockState = ClockState ZonedTime deriving Show
|
|
|
|
|
|
|
|
data ClockMessage = UpdateTime ZonedTime deriving (Show, Typeable)
|
|
|
|
|
2011-07-14 20:21:30 +02:00
|
|
|
instance WidgetClass Clock where
|
2011-07-14 22:50:03 +02:00
|
|
|
type WidgetData Clock = ClockState
|
2011-07-14 20:21:30 +02:00
|
|
|
|
|
|
|
initWidget (Clock _) phi _ = do
|
|
|
|
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-07-14 20:21:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
minSize (Clock config ) = clockSize config
|
|
|
|
|
2011-07-16 15:55:31 +02:00
|
|
|
render (Clock config) (ClockState time) w h _ = do
|
2011-07-14 20:21:30 +02:00
|
|
|
time <- liftIO getZonedTime
|
|
|
|
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 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
|
|
|
|
|
|
|
clock :: ClockConfig -> Widget
|
|
|
|
clock config = do
|
|
|
|
Widget $ Clock config
|