monomer-1.0.0.3: src/Monomer/Widgets/Singles/LabeledCheckbox.hs
{-|
Module : Monomer.Widgets.Singles.LabeledCheckbox
Copyright : (c) 2018 Francisco Vallarino
License : BSD-3-Clause (see the LICENSE file)
Maintainer : fjvallarino@gmail.com
Stability : experimental
Portability : non-portable
Labeled checkbox, used for interacting with boolean values with an associated
clickable label.
-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Strict #-}
module Monomer.Widgets.Singles.LabeledCheckbox (
-- * Configuration
LabeledCheckboxCfg,
-- * Constructors
labeledCheckbox,
labeledCheckbox_,
labeledCheckboxV,
labeledCheckboxV_,
labeledCheckboxD_
) where
import Control.Applicative ((<|>))
import Control.Lens (ALens', (&), (^.), (.~))
import Control.Monad
import Data.Default
import Data.Maybe
import Data.Text (Text)
import qualified Data.Sequence as Seq
import Monomer.Widgets.Containers.Base.LabeledItem
import Monomer.Widgets.Single
import Monomer.Widgets.Singles.Checkbox
import Monomer.Widgets.Singles.Label
import qualified Monomer.Lens as L
{-|
Configuration options for labeledCheckbox:
- Text related
- 'textLeft': places the label to the left of the checkbox.
- 'textRight': places the label to the right of the checkbox.
- 'textTop': places the label to the top of the checkbox.
- 'textBottom': places the label to the bottom of the checkbox.
- 'trimSpaces': whether to remove leading/trailing spaces in the caption.
- 'ellipsis': if ellipsis should be used for overflown text.
- 'multiline': if text may be split in multiple lines.
- 'maxLines': maximum number of text lines to show.
- 'resizeFactor': flexibility to have more or less spaced assigned.
- 'resizeFactorW': flexibility for more or less horizontal spaced assigned.
- 'resizeFactorH': flexibility for more or less vertical spaced assigned.
- Checkbox related
- 'checkboxMark': the type of checkbox mark.
- 'width': sets the max width/height of the checkbox.
- 'onFocus': event to raise when focus is received.
- 'onFocusReq': 'WidgetRequest' to generate when focus is received.
- 'onBlur': event to raise when focus is lost.
- 'onBlurReq': 'WidgetRequest' to generate when focus is lost.
- 'onChange': event to raise when the value changes/is clicked.
- 'onChangeReq': 'WidgetRequest' to generate when the value changes/is clicked.
-}
data LabeledCheckboxCfg s e = LabeledCheckboxCfg {
_lchTextSide :: Maybe RectSide,
_lchLabelCfg :: LabelCfg s e,
_lchCheckboxCfg :: CheckboxCfg s e
}
instance Default (LabeledCheckboxCfg s e) where
def = LabeledCheckboxCfg {
_lchTextSide = Nothing,
_lchLabelCfg = def,
_lchCheckboxCfg = def
}
instance Semigroup (LabeledCheckboxCfg s e) where
(<>) t1 t2 = LabeledCheckboxCfg {
_lchTextSide = _lchTextSide t2 <|> _lchTextSide t1,
_lchLabelCfg = _lchLabelCfg t1 <> _lchLabelCfg t2,
_lchCheckboxCfg = _lchCheckboxCfg t1 <> _lchCheckboxCfg t2
}
instance Monoid (LabeledCheckboxCfg s e) where
mempty = def
instance CmbTextLeft (LabeledCheckboxCfg s e) where
textLeft_ False = def
textLeft_ True = def {
_lchTextSide = Just SideLeft
}
instance CmbTextRight (LabeledCheckboxCfg s e) where
textRight_ False = def
textRight_ True = def {
_lchTextSide = Just SideRight
}
instance CmbTextTop (LabeledCheckboxCfg s e) where
textTop_ False = def
textTop_ True = def {
_lchTextSide = Just SideTop
}
instance CmbTextBottom (LabeledCheckboxCfg s e) where
textBottom_ False = def
textBottom_ True = def {
_lchTextSide = Just SideBottom
}
instance CmbTrimSpaces (LabeledCheckboxCfg s e) where
trimSpaces_ trim = def {
_lchLabelCfg = trimSpaces_ trim
}
instance CmbEllipsis (LabeledCheckboxCfg s e) where
ellipsis_ ellipsis = def {
_lchLabelCfg = ellipsis_ ellipsis
}
instance CmbMultiline (LabeledCheckboxCfg s e) where
multiline_ multi = def {
_lchLabelCfg = multiline_ multi
}
instance CmbMaxLines (LabeledCheckboxCfg s e) where
maxLines count = def {
_lchLabelCfg = maxLines count
}
instance CmbResizeFactor (LabeledCheckboxCfg s e) where
resizeFactor s = def {
_lchLabelCfg = resizeFactor s
}
instance CmbResizeFactorDim (LabeledCheckboxCfg s e) where
resizeFactorW w = def {
_lchLabelCfg = resizeFactorW w
}
resizeFactorH h = def {
_lchLabelCfg = resizeFactorH h
}
instance CmbCheckboxMark (LabeledCheckboxCfg s e) where
checkboxMark mark = def {
_lchCheckboxCfg = checkboxMark mark
}
checkboxSquare = checkboxMark CheckboxSquare
checkboxTimes = checkboxMark CheckboxTimes
instance CmbWidth (LabeledCheckboxCfg s e) where
width w = def {
_lchCheckboxCfg = width w
}
instance WidgetEvent e => CmbOnFocus (LabeledCheckboxCfg s e) e Path where
onFocus fn = def {
_lchCheckboxCfg = onFocus fn
}
instance CmbOnFocusReq (LabeledCheckboxCfg s e) s e Path where
onFocusReq req = def {
_lchCheckboxCfg = onFocusReq req
}
instance WidgetEvent e => CmbOnBlur (LabeledCheckboxCfg s e) e Path where
onBlur fn = def {
_lchCheckboxCfg = onBlur fn
}
instance CmbOnBlurReq (LabeledCheckboxCfg s e) s e Path where
onBlurReq req = def {
_lchCheckboxCfg = onBlurReq req
}
instance WidgetEvent e => CmbOnChange (LabeledCheckboxCfg s e) Bool e where
onChange fn = def {
_lchCheckboxCfg = onChange fn
}
instance CmbOnChangeReq (LabeledCheckboxCfg s e) s e Bool where
onChangeReq req = def {
_lchCheckboxCfg = onChangeReq req
}
-- | Creates a labeled checkbox using the given lens.
labeledCheckbox :: WidgetEvent e => Text -> ALens' s Bool -> WidgetNode s e
labeledCheckbox caption field = labeledCheckbox_ caption field def
-- | Creates a labeled checkbox using the given lens. Accepts config.
labeledCheckbox_
:: WidgetEvent e
=> Text
-> ALens' s Bool
-> [LabeledCheckboxCfg s e]
-> WidgetNode s e
labeledCheckbox_ caption field config = newNode where
newNode = labeledCheckboxD_ caption (WidgetLens field) config
-- | Creates a labeled checkbox using the given value and 'onChange' event
-- handler.
labeledCheckboxV
:: WidgetEvent e
=> Text
-> Bool
-> (Bool -> e)
-> WidgetNode s e
labeledCheckboxV caption value handler = newNode where
newNode = labeledCheckboxV_ caption value handler def
{-|
Creates a labeled checkbox using the given value and 'onChange' event handler.
Accepts config.
-}
labeledCheckboxV_
:: WidgetEvent e
=> Text
-> Bool
-> (Bool -> e)
-> [LabeledCheckboxCfg s e]
-> WidgetNode s e
labeledCheckboxV_ caption value handler config = newNode where
newConfig = onChange handler : config
newNode = labeledCheckboxD_ caption (WidgetValue value) newConfig
-- | Creates a labeled checkbox providing a 'WidgetData' instance and config.
labeledCheckboxD_
:: WidgetEvent e
=> Text
-> WidgetData s Bool
-> [LabeledCheckboxCfg s e]
-> WidgetNode s e
labeledCheckboxD_ caption widgetData configs = newNode where
config = mconcat configs
labelSide = fromMaybe SideLeft (_lchTextSide config)
labelCfg = _lchLabelCfg config
widget = checkboxD_ widgetData [_lchCheckboxCfg config]
newNode = labeledItem "labeledCheckbox" labelSide caption labelCfg widget