{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
module Brick.AttrMap
( AttrMap
, AttrName
, attrMap
, forceAttrMap
, forceAttrMapAllowStyle
, attrName
, attrNameComponents
, attrMapLookup
, setDefaultAttr
, getDefaultAttr
, applyAttrMappings
, mergeWithDefault
, mapAttrName
, mapAttrNames
)
where
import qualified Data.Semigroup as Sem
import Control.DeepSeq
import Data.Bits ((.|.))
import qualified Data.Map as M
import Data.Maybe (mapMaybe)
import Data.List (inits)
import GHC.Generics (Generic)
import Graphics.Vty (Attr(..), MaybeDefault(..), Style)
data AttrName = AttrName [String]
deriving (Int -> AttrName -> ShowS
[AttrName] -> ShowS
AttrName -> String
(Int -> AttrName -> ShowS)
-> (AttrName -> String) -> ([AttrName] -> ShowS) -> Show AttrName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AttrName -> ShowS
showsPrec :: Int -> AttrName -> ShowS
$cshow :: AttrName -> String
show :: AttrName -> String
$cshowList :: [AttrName] -> ShowS
showList :: [AttrName] -> ShowS
Show, ReadPrec [AttrName]
ReadPrec AttrName
Int -> ReadS AttrName
ReadS [AttrName]
(Int -> ReadS AttrName)
-> ReadS [AttrName]
-> ReadPrec AttrName
-> ReadPrec [AttrName]
-> Read AttrName
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS AttrName
readsPrec :: Int -> ReadS AttrName
$creadList :: ReadS [AttrName]
readList :: ReadS [AttrName]
$creadPrec :: ReadPrec AttrName
readPrec :: ReadPrec AttrName
$creadListPrec :: ReadPrec [AttrName]
readListPrec :: ReadPrec [AttrName]
Read, AttrName -> AttrName -> Bool
(AttrName -> AttrName -> Bool)
-> (AttrName -> AttrName -> Bool) -> Eq AttrName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AttrName -> AttrName -> Bool
== :: AttrName -> AttrName -> Bool
$c/= :: AttrName -> AttrName -> Bool
/= :: AttrName -> AttrName -> Bool
Eq, Eq AttrName
Eq AttrName =>
(AttrName -> AttrName -> Ordering)
-> (AttrName -> AttrName -> Bool)
-> (AttrName -> AttrName -> Bool)
-> (AttrName -> AttrName -> Bool)
-> (AttrName -> AttrName -> Bool)
-> (AttrName -> AttrName -> AttrName)
-> (AttrName -> AttrName -> AttrName)
-> Ord AttrName
AttrName -> AttrName -> Bool
AttrName -> AttrName -> Ordering
AttrName -> AttrName -> AttrName
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: AttrName -> AttrName -> Ordering
compare :: AttrName -> AttrName -> Ordering
$c< :: AttrName -> AttrName -> Bool
< :: AttrName -> AttrName -> Bool
$c<= :: AttrName -> AttrName -> Bool
<= :: AttrName -> AttrName -> Bool
$c> :: AttrName -> AttrName -> Bool
> :: AttrName -> AttrName -> Bool
$c>= :: AttrName -> AttrName -> Bool
>= :: AttrName -> AttrName -> Bool
$cmax :: AttrName -> AttrName -> AttrName
max :: AttrName -> AttrName -> AttrName
$cmin :: AttrName -> AttrName -> AttrName
min :: AttrName -> AttrName -> AttrName
Ord, (forall x. AttrName -> Rep AttrName x)
-> (forall x. Rep AttrName x -> AttrName) -> Generic AttrName
forall x. Rep AttrName x -> AttrName
forall x. AttrName -> Rep AttrName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AttrName -> Rep AttrName x
from :: forall x. AttrName -> Rep AttrName x
$cto :: forall x. Rep AttrName x -> AttrName
to :: forall x. Rep AttrName x -> AttrName
Generic, AttrName -> ()
(AttrName -> ()) -> NFData AttrName
forall a. (a -> ()) -> NFData a
$crnf :: AttrName -> ()
rnf :: AttrName -> ()
NFData)
instance Sem.Semigroup AttrName where
(AttrName [String]
as) <> :: AttrName -> AttrName -> AttrName
<> (AttrName [String]
bs) = [String] -> AttrName
AttrName ([String] -> AttrName) -> [String] -> AttrName
forall a b. (a -> b) -> a -> b
$ [String]
as [String] -> [String] -> [String]
forall a. Monoid a => a -> a -> a
`mappend` [String]
bs
instance Monoid AttrName where
mempty :: AttrName
mempty = [String] -> AttrName
AttrName []
mappend :: AttrName -> AttrName -> AttrName
mappend = AttrName -> AttrName -> AttrName
forall a. Semigroup a => a -> a -> a
(Sem.<>)
data AttrMap = AttrMap Attr (M.Map AttrName Attr)
| ForceAttr Attr
| ForceAttrAllowStyle Attr AttrMap
deriving (Int -> AttrMap -> ShowS
[AttrMap] -> ShowS
AttrMap -> String
(Int -> AttrMap -> ShowS)
-> (AttrMap -> String) -> ([AttrMap] -> ShowS) -> Show AttrMap
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AttrMap -> ShowS
showsPrec :: Int -> AttrMap -> ShowS
$cshow :: AttrMap -> String
show :: AttrMap -> String
$cshowList :: [AttrMap] -> ShowS
showList :: [AttrMap] -> ShowS
Show, (forall x. AttrMap -> Rep AttrMap x)
-> (forall x. Rep AttrMap x -> AttrMap) -> Generic AttrMap
forall x. Rep AttrMap x -> AttrMap
forall x. AttrMap -> Rep AttrMap x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AttrMap -> Rep AttrMap x
from :: forall x. AttrMap -> Rep AttrMap x
$cto :: forall x. Rep AttrMap x -> AttrMap
to :: forall x. Rep AttrMap x -> AttrMap
Generic, AttrMap -> ()
(AttrMap -> ()) -> NFData AttrMap
forall a. (a -> ()) -> NFData a
$crnf :: AttrMap -> ()
rnf :: AttrMap -> ()
NFData)
attrName :: String -> AttrName
attrName :: String -> AttrName
attrName = [String] -> AttrName
AttrName ([String] -> AttrName)
-> (String -> [String]) -> String -> AttrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[])
attrNameComponents :: AttrName -> [String]
attrNameComponents :: AttrName -> [String]
attrNameComponents (AttrName [String]
cs) = [String]
cs
attrMap :: Attr
-> [(AttrName, Attr)]
-> AttrMap
attrMap :: Attr -> [(AttrName, Attr)] -> AttrMap
attrMap Attr
theDefault [(AttrName, Attr)]
pairs = Attr -> Map AttrName Attr -> AttrMap
AttrMap Attr
theDefault ([(AttrName, Attr)] -> Map AttrName Attr
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(AttrName, Attr)]
pairs)
forceAttrMap :: Attr -> AttrMap
forceAttrMap :: Attr -> AttrMap
forceAttrMap = Attr -> AttrMap
ForceAttr
forceAttrMapAllowStyle :: Attr -> AttrMap -> AttrMap
forceAttrMapAllowStyle :: Attr -> AttrMap -> AttrMap
forceAttrMapAllowStyle = Attr -> AttrMap -> AttrMap
ForceAttrAllowStyle
mergeWithDefault :: Attr -> AttrMap -> Attr
mergeWithDefault :: Attr -> AttrMap -> Attr
mergeWithDefault Attr
_ (ForceAttr Attr
a) = Attr
a
mergeWithDefault Attr
_ (ForceAttrAllowStyle Attr
f AttrMap
_) = Attr
f
mergeWithDefault Attr
a (AttrMap Attr
d Map AttrName Attr
_) = Attr -> Attr -> Attr
combineAttrs Attr
d Attr
a
attrMapLookup :: AttrName -> AttrMap -> Attr
attrMapLookup :: AttrName -> AttrMap -> Attr
attrMapLookup AttrName
_ (ForceAttr Attr
a) = Attr
a
attrMapLookup AttrName
a (ForceAttrAllowStyle Attr
forced AttrMap
m) =
let result :: Attr
result = AttrName -> AttrMap -> Attr
attrMapLookup AttrName
a AttrMap
m
in Attr
forced { attrStyle = attrStyle forced `combineStyles` attrStyle result
}
attrMapLookup (AttrName []) (AttrMap Attr
theDefault Map AttrName Attr
_) = Attr
theDefault
attrMapLookup (AttrName [String]
ns) (AttrMap Attr
theDefault Map AttrName Attr
m) =
let results :: [Attr]
results = ([String] -> Maybe Attr) -> [[String]] -> [Attr]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\[String]
n -> AttrName -> Map AttrName Attr -> Maybe Attr
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ([String] -> AttrName
AttrName [String]
n) Map AttrName Attr
m) ([String] -> [[String]]
forall a. [a] -> [[a]]
inits [String]
ns)
in (Attr -> Attr -> Attr) -> Attr -> [Attr] -> Attr
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Attr -> Attr -> Attr
combineAttrs Attr
theDefault [Attr]
results
setDefaultAttr :: Attr -> AttrMap -> AttrMap
setDefaultAttr :: Attr -> AttrMap -> AttrMap
setDefaultAttr Attr
_ (ForceAttr Attr
a) = Attr -> AttrMap
ForceAttr Attr
a
setDefaultAttr Attr
newDefault (ForceAttrAllowStyle Attr
a AttrMap
m) =
Attr -> AttrMap -> AttrMap
ForceAttrAllowStyle Attr
a (Attr -> AttrMap -> AttrMap
setDefaultAttr Attr
newDefault AttrMap
m)
setDefaultAttr Attr
newDefault (AttrMap Attr
_ Map AttrName Attr
m) = Attr -> Map AttrName Attr -> AttrMap
AttrMap Attr
newDefault Map AttrName Attr
m
getDefaultAttr :: AttrMap -> Attr
getDefaultAttr :: AttrMap -> Attr
getDefaultAttr (ForceAttr Attr
a) = Attr
a
getDefaultAttr (ForceAttrAllowStyle Attr
_ AttrMap
m) = AttrMap -> Attr
getDefaultAttr AttrMap
m
getDefaultAttr (AttrMap Attr
d Map AttrName Attr
_) = Attr
d
combineAttrs :: Attr -> Attr -> Attr
combineAttrs :: Attr -> Attr -> Attr
combineAttrs (Attr MaybeDefault Style
s1 MaybeDefault Color
f1 MaybeDefault Color
b1 MaybeDefault Text
u1) (Attr MaybeDefault Style
s2 MaybeDefault Color
f2 MaybeDefault Color
b2 MaybeDefault Text
u2) =
MaybeDefault Style
-> MaybeDefault Color
-> MaybeDefault Color
-> MaybeDefault Text
-> Attr
Attr (MaybeDefault Style
s1 MaybeDefault Style -> MaybeDefault Style -> MaybeDefault Style
`combineStyles` MaybeDefault Style
s2)
(MaybeDefault Color
f1 MaybeDefault Color -> MaybeDefault Color -> MaybeDefault Color
forall a. MaybeDefault a -> MaybeDefault a -> MaybeDefault a
`combineMDs` MaybeDefault Color
f2)
(MaybeDefault Color
b1 MaybeDefault Color -> MaybeDefault Color -> MaybeDefault Color
forall a. MaybeDefault a -> MaybeDefault a -> MaybeDefault a
`combineMDs` MaybeDefault Color
b2)
(MaybeDefault Text
u1 MaybeDefault Text -> MaybeDefault Text -> MaybeDefault Text
forall a. MaybeDefault a -> MaybeDefault a -> MaybeDefault a
`combineMDs` MaybeDefault Text
u2)
combineMDs :: MaybeDefault a -> MaybeDefault a -> MaybeDefault a
combineMDs :: forall a. MaybeDefault a -> MaybeDefault a -> MaybeDefault a
combineMDs MaybeDefault a
_ (SetTo a
v) = a -> MaybeDefault a
forall v. v -> MaybeDefault v
SetTo a
v
combineMDs (SetTo a
v) MaybeDefault a
_ = a -> MaybeDefault a
forall v. v -> MaybeDefault v
SetTo a
v
combineMDs MaybeDefault a
_ MaybeDefault a
v = MaybeDefault a
v
combineStyles :: MaybeDefault Style -> MaybeDefault Style -> MaybeDefault Style
combineStyles :: MaybeDefault Style -> MaybeDefault Style -> MaybeDefault Style
combineStyles (SetTo Style
a) (SetTo Style
b) = Style -> MaybeDefault Style
forall v. v -> MaybeDefault v
SetTo (Style -> MaybeDefault Style) -> Style -> MaybeDefault Style
forall a b. (a -> b) -> a -> b
$ Style
a Style -> Style -> Style
forall a. Bits a => a -> a -> a
.|. Style
b
combineStyles MaybeDefault Style
_ (SetTo Style
v) = Style -> MaybeDefault Style
forall v. v -> MaybeDefault v
SetTo Style
v
combineStyles (SetTo Style
v) MaybeDefault Style
_ = Style -> MaybeDefault Style
forall v. v -> MaybeDefault v
SetTo Style
v
combineStyles MaybeDefault Style
_ MaybeDefault Style
v = MaybeDefault Style
v
applyAttrMappings :: [(AttrName, Attr)] -> AttrMap -> AttrMap
applyAttrMappings :: [(AttrName, Attr)] -> AttrMap -> AttrMap
applyAttrMappings [(AttrName, Attr)]
_ (ForceAttr Attr
a) = Attr -> AttrMap
ForceAttr Attr
a
applyAttrMappings [(AttrName, Attr)]
ms (AttrMap Attr
d Map AttrName Attr
m) = Attr -> Map AttrName Attr -> AttrMap
AttrMap Attr
d (([(AttrName, Attr)] -> Map AttrName Attr
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList [(AttrName, Attr)]
ms) Map AttrName Attr -> Map AttrName Attr -> Map AttrName Attr
forall k a. Ord k => Map k a -> Map k a -> Map k a
`M.union` Map AttrName Attr
m)
applyAttrMappings [(AttrName, Attr)]
ms (ForceAttrAllowStyle Attr
a AttrMap
m) = Attr -> AttrMap -> AttrMap
ForceAttrAllowStyle Attr
a ([(AttrName, Attr)] -> AttrMap -> AttrMap
applyAttrMappings [(AttrName, Attr)]
ms AttrMap
m)
mapAttrName :: AttrName -> AttrName -> AttrMap -> AttrMap
mapAttrName :: AttrName -> AttrName -> AttrMap -> AttrMap
mapAttrName AttrName
fromName AttrName
ontoName AttrMap
inMap =
[(AttrName, Attr)] -> AttrMap -> AttrMap
applyAttrMappings [(AttrName
ontoName, AttrName -> AttrMap -> Attr
attrMapLookup AttrName
fromName AttrMap
inMap)] AttrMap
inMap
mapAttrNames :: [(AttrName, AttrName)] -> AttrMap -> AttrMap
mapAttrNames :: [(AttrName, AttrName)] -> AttrMap -> AttrMap
mapAttrNames [(AttrName, AttrName)]
names AttrMap
inMap = ((AttrName, AttrName) -> AttrMap -> AttrMap)
-> AttrMap -> [(AttrName, AttrName)] -> AttrMap
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((AttrName -> AttrName -> AttrMap -> AttrMap)
-> (AttrName, AttrName) -> AttrMap -> AttrMap
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry AttrName -> AttrName -> AttrMap -> AttrMap
mapAttrName) AttrMap
inMap [(AttrName, AttrName)]
names