monomer-1.6.0.0: src/Monomer/Widgets/Animation/Fade.hs
{-|
Module : Monomer.Widgets.Animation.Fade
Copyright : (c) 2018 Francisco Vallarino
License : BSD-3-Clause (see the LICENSE file)
Maintainer : fjvallarino@gmail.com
Stability : experimental
Portability : non-portable
Fade animation widget. Wraps a child widget whose content will be animated.
Messages:
- Accepts an 'AnimationMsg', used to control the state of the animation.
-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE Strict #-}
module Monomer.Widgets.Animation.Fade (
-- * Configuration
FadeCfg,
-- * Constructors
animFadeIn,
animFadeIn_,
animFadeOut,
animFadeOut_
) where
import Control.Lens ((&), (.~))
import Data.Default
import Data.Maybe
import Monomer.Widgets.Container
import Monomer.Widgets.Animation.Transform
import qualified Monomer.Lens as L
{-|
Configuration options for fade:
- 'autoStart': whether the first time the widget is added, animation should run.
- 'duration': how long the animation lasts in ms.
- 'onFinished': event to raise when animation is complete.
- 'onFinishedReq': 'WidgetRequest' to generate when animation is complete.
-}
newtype FadeCfg s e = FadeCfg {
_fdcTransformCfg :: TransformCfg s e
} deriving (Eq, Show)
instance Default (FadeCfg s e) where
def = FadeCfg {
_fdcTransformCfg = def
}
instance Semigroup (FadeCfg s e) where
(<>) fc1 fc2 = FadeCfg {
_fdcTransformCfg = _fdcTransformCfg fc1 <> _fdcTransformCfg fc2
}
instance Monoid (FadeCfg s e) where
mempty = def
instance CmbAutoStart (FadeCfg s e) where
autoStart_ start = def {
_fdcTransformCfg = autoStart_ start
}
instance CmbDuration (FadeCfg s e) Millisecond where
duration dur = def {
_fdcTransformCfg = duration dur
}
instance WidgetEvent e => CmbOnFinished (FadeCfg s e) e where
onFinished handler = def {
_fdcTransformCfg = onFinished handler
}
instance CmbOnFinishedReq (FadeCfg s e) s e where
onFinishedReq req = def {
_fdcTransformCfg = onFinishedReq req
}
-- | Animates a widget from not visible state to fully visible.
animFadeIn
:: WidgetEvent e
=> WidgetNode s e -- ^ The child node.
-> WidgetNode s e -- ^ The created animation container.
animFadeIn managed = animFadeIn_ def managed
-- | Animates a widget from not visible state to fully visible. Accepts config.
animFadeIn_
:: WidgetEvent e
=> [FadeCfg s e] -- ^ The config options.
-> WidgetNode s e -- ^ The child node.
-> WidgetNode s e -- ^ The created animation container.
animFadeIn_ configs managed = makeNode configs managed True
& L.info . L.widgetType .~ "animFadeIn"
-- | Animates a widget from visible state to not visible.
animFadeOut
:: WidgetEvent e
=> WidgetNode s e -- ^ The child node.
-> WidgetNode s e -- ^ The created animation container.
animFadeOut managed = animFadeOut_ def managed
-- | Animates a widget from visible state to not visible. Accepts config.
animFadeOut_
:: WidgetEvent e
=> [FadeCfg s e] -- ^ The config options.
-> WidgetNode s e -- ^ The child node.
-> WidgetNode s e -- ^ The created animation container.
animFadeOut_ configs managed = makeNode configs managed False
& L.info . L.widgetType .~ "animFadeOut"
makeNode
:: WidgetEvent e
=> [FadeCfg s e]
-> WidgetNode s e
-> Bool
-> WidgetNode s e
makeNode configs managed isFadeIn = node where
node = animTransform_ [_fdcTransformCfg] f managed
f t _ = [animGlobalAlpha $ alpha t]
alpha t = if isFadeIn
then (currStep t)
else 1-(currStep t)
currStep t = clampAlpha $ t/(fromIntegral dur)
dur = fromMaybe 500 _tfcDuration
TransformCfg{..} = _fdcTransformCfg
FadeCfg{..} = mconcat configs