Browse Source

Countdown timers can change colors and duration

master
Peter J. Jones 4 years ago
parent
commit
0a20e135bd

+ 6
- 0
src/Clockdown/Core/Action.hs View File

@@ -34,6 +34,12 @@ data Action = Tick
| NextWindow
-- ^ Focus the next window.

| TimeSucc
-- ^ Update the time in the focused window.

| TimePred
-- ^ Update the time in the focused window.

| Quit
-- ^ Quit the application.


+ 11
- 1
src/Clockdown/Core/Config.hs View File

@@ -68,6 +68,10 @@ defaultKeys =
, (([], RawKey 'q'), Quit)
, (([], RawKey '\t'), NextWindow)
, (([Shift], RawKey '\t'), PrevWindow)
, (([], RawKey '='), TimeSucc)
, (([], RawKey '+'), TimeSucc)
, (([], RawKey '-'), TimePred)
, (([], RawKey '_'), TimeSucc)
, (([], FKey 1), NewCountdown defaultCountdownName)
]

@@ -96,7 +100,13 @@ defaultCountdown :: (Text, Countdown)
defaultCountdown = (defaultCountdownName, countdown)
where
countdown :: Countdown
countdown = Countdown props 300 Nothing
countdown = Countdown { countProps = props
, countDoneColor = Just red
, countColorChange = 59
, countDuration = 300
, countEnd = Nothing
, countOrigColor = Nothing
}

props :: Properties
props = Properties { propName = defaultCountdownName

+ 66
- 7
src/Clockdown/Core/Countdown.hs View File

@@ -13,6 +13,7 @@ the LICENSE file.
module Clockdown.Core.Countdown
( Countdown (..)
, countDownStart
, countDownTick
, countDownDigitalDisplay
, countDownSucc
, countDownPred
@@ -26,12 +27,18 @@ import Data.Time
-- Local imports:
import qualified Clockdown.Core.Digital.Display as Digital
import Clockdown.Core.Properties
import Clockdown.Core.Color

--------------------------------------------------------------------------------
data Countdown = Countdown
{ countProps :: Properties -- ^ Properties.
, countDuration :: Int -- ^ Number of seconds.
, countEnd :: Maybe UTCTime -- ^ Only set after countdown is running.
{ countProps :: Properties -- ^ Properties.
, countDoneColor :: Maybe Color -- ^ Main color when done.
, countColorChange :: Int -- ^ When to change colors.
, countDuration :: Int -- ^ Number of seconds.

-- The following fields are not user settable.
, countEnd :: Maybe UTCTime -- ^ Only set after countdown is running.
, countOrigColor :: Maybe Color -- ^ Original property color.
}

--------------------------------------------------------------------------------
@@ -41,6 +48,42 @@ countDownStart t c = c { countEnd = Just endTime }
endTime :: UTCTime
endTime = addUTCTime (fromInteger . toInteger $ countDuration c) t

--------------------------------------------------------------------------------
-- | Update a countdown. May change colors. The code is screaming
-- out for refactoring via lens. Either way, I'd like to change this
-- code so that it actually just fires off an action and then create
-- an action called "ChangeColor".
countDownTick :: UTCTime -> Countdown -> Countdown
countDownTick t c
| countDownSecondsLeft c t <= countColorChange c = changeColor
| otherwise = restoreColor

where
changeColor :: Countdown
changeColor = case (countDoneColor c, countOrigColor c) of
-- We can change the color.
(Just color, Nothing) -> c { countProps = newColor color
, countOrigColor = Just oldColor
}
-- Leave things alone.
(_, _) -> c

restoreColor :: Countdown
restoreColor = case countOrigColor c of
-- The color was changed, restore it.
Just color -> c { countProps = newColor color
, countOrigColor = Nothing
}

-- Original color still intact.
Nothing -> c

newColor :: Color -> Properties
newColor color = (countProps c) {propColor = color}

oldColor :: Color
oldColor = propColor (countProps c)

--------------------------------------------------------------------------------
countDownDigitalDisplay :: Countdown -> UTCTime -> Digital.Display
countDownDigitalDisplay c t = Digital.digitalCountDown (countDownSecondsLeft c t)
@@ -53,11 +96,25 @@ countDownSecondsLeft c t =
Nothing -> 0

--------------------------------------------------------------------------------
countDownSucc :: Countdown -> Countdown
countDownSucc = undefined
-- | Add one minute to the countdown.
countDownSucc :: UTCTime -> Countdown -> Countdown
countDownSucc t c = countDownTick t $ c { countEnd = newEnd }
where
newEnd :: Maybe UTCTime
newEnd = case countEnd c of
Nothing -> Nothing
Just t'
| countDownSecondsLeft c t <= 0 -> Just (addUTCTime 60 t)
| otherwise -> Just (addUTCTime 60 t')

--------------------------------------------------------------------------------
countDownPred :: Countdown -> Countdown
countDownPred = undefined
-- | Remove one minute from the countdown.
countDownPred :: UTCTime -> Countdown -> Countdown
countDownPred t c = countDownTick t $ c { countEnd = newEnd }
where
newEnd :: Maybe UTCTime
newEnd = case countEnd c of
Nothing -> Nothing
Just t'
| countDownSecondsLeft c t > 0 -> Just (addUTCTime (-60) t')
| otherwise -> Just t'

+ 6
- 0
src/Clockdown/Core/Dispatch.hs View File

@@ -48,6 +48,12 @@ dispatch (t, a) = do
NewCountdown name ->
countdown t name

TimeSucc ->
put (withFocused windows $ windowSucc t)

TimePred ->
put (withFocused windows $ windowPred t)

Quit ->
return ()


+ 6
- 0
src/Clockdown/Core/Stack.hs View File

@@ -14,6 +14,7 @@ the LICENSE file.
module Clockdown.Core.Stack
( Stack
, stack
, withFocused
, push
, pop
, focus
@@ -34,6 +35,11 @@ instance Functor Stack where
stack :: a -> Stack a
stack x = Stack [] x []

--------------------------------------------------------------------------------
-- | Apply a function to the focused element.
withFocused :: Stack a -> (a -> a) -> Stack a
withFocused (Stack a b c) f = Stack a (f b) c

--------------------------------------------------------------------------------
-- | Push an item onto the end of the stack and focus it.
push :: a -> Stack a -> Stack a

+ 7
- 7
src/Clockdown/Core/Window.hs View File

@@ -49,7 +49,7 @@ newCountDownWindow t c = windowTick t $ CountdownWin (countDownStart t c)
--------------------------------------------------------------------------------
windowTick :: UTCTime -> Window -> Window
windowTick _ (ClockWin c) = ClockWin c -- No ticking necessary.
windowTick _ (CountdownWin c) = CountdownWin c -- FIXME:
windowTick t (CountdownWin c) = CountdownWin (countDownTick t c)

--------------------------------------------------------------------------------
-- | Convert a window into a digital display.
@@ -65,12 +65,12 @@ windowProperties (CountdownWin c) = countProps c

--------------------------------------------------------------------------------
-- | Move the time shown in a window forward by some amount.
windowSucc :: Window -> Window
windowSucc (ClockWin c) = ClockWin (clockSucc c)
windowSucc (CountdownWin c) = CountdownWin (countDownSucc c)
windowSucc :: UTCTime -> Window -> Window
windowSucc _ (ClockWin c) = ClockWin (clockSucc c)
windowSucc t (CountdownWin c) = CountdownWin (countDownSucc t c)

--------------------------------------------------------------------------------
-- | Move the time show in a window backward by some amount.
windowPred :: Window -> Window
windowPred (ClockWin c) = ClockWin (clockPred c)
windowPred (CountdownWin c) = CountdownWin (countDownPred c)
windowPred :: UTCTime -> Window -> Window
windowPred _ (ClockWin c) = ClockWin (clockPred c)
windowPred t (CountdownWin c) = CountdownWin (countDownPred t c)

Loading…
Cancel
Save