module Glazier.Widget
( Widget(..)
, _window
, _gadget
, _window'
, _gadget'
, _Widget
, _Widget'
, _WrappingWidget
, _WrappingWidget'
, belowWidget
, underWidget
, overWidget
, aboveWidget
, mkWidget
, mkWidget'
, runWidget
, runWidget'
, statically
, dynamically
) where
import Control.Applicative
import Control.Lens
import Data.Functor.Apply
import Data.Maybe
import Data.Semigroup
import Glazier.Class
import Glazier.Gadget
import Glazier.Window
data Widget v m r a s n c = Widget
{ window :: WindowT s v m r
, gadget :: GadgetT a s n c
}
_window :: Lens (Widget v m r a s n c) (Widget v' m' r' a s n c) (WindowT s v m r) (WindowT s v' m' r')
_window = lens window (\(Widget _ g) w -> Widget w g)
_gadget :: Lens (Widget v m r a s n c) (Widget v m r a' s n' c') (GadgetT a s n c) (GadgetT a' s n' c')
_gadget = lens gadget (\(Widget w _) g -> Widget w g)
_window' :: Lens' (Widget v m r a s n c) (WindowT s v m r)
_window' = _window
_gadget' :: Lens' (Widget v m r a s n c) (GadgetT a s n c)
_gadget' = _gadget
_Widget :: Iso (Widget v m r a s n c) (Widget v' m' r' a' s' n' c')
(s -> v -> m (r, v), a -> s -> n (c, s)) (s' -> v' -> m' (r', v'), a' -> s' -> n' (c', s'))
_Widget = iso (\(Widget w g) -> (view _WindowT w, view _GadgetT g))
(\(w, g) -> Widget (review _WindowT w) (review _GadgetT g))
_Widget' :: Iso' (Widget v m r a s n c) (s -> v -> m (r, v), a -> s -> n (c, s))
_Widget' = _Widget
_WrappingWidget :: Iso (Widget v m r a s n c) (Widget v' m' r' a' s' n' c')
(WindowT s v m r, GadgetT a s n c) (WindowT s' v' m' r', GadgetT a' s' n' c')
_WrappingWidget = iso (\(Widget w g) -> (w, g))
(\(w, g) -> Widget w g)
_WrappingWidget' :: Iso' (Widget v m r a s n c) (WindowT s v m r, GadgetT a s n c)
_WrappingWidget' = _WrappingWidget
mkWidget :: (WindowT s v m r, GadgetT a s n c) -> Widget v m r a s n c
mkWidget = review _WrappingWidget
mkWidget' :: (s -> v -> m (r, v), a -> s -> n (c, s)) -> Widget v m r a s n c
mkWidget' = review _Widget
runWidget :: Widget v m r a s n c -> (WindowT s v m r, GadgetT a s n c)
runWidget = view _WrappingWidget
runWidget' :: Widget v m r a s n c -> (s -> v -> m (r, v), a -> s -> n (c, s))
runWidget' = view _Widget
belowWidget ::
((s -> v -> m (r, v), a -> s -> n (c, s))
-> (s' -> v' -> m' (r', v'), a' -> s' -> n' (c', s')))
-> Widget v m r a s n c -> Widget v' m' r' a' s' n' c'
belowWidget f = _Widget %~ f
underWidget ::
((WindowT s v m r, GadgetT a s n c)
-> (WindowT s' v' m' r', GadgetT a' s' n' c'))
-> Widget v m r a s n c -> Widget v' m' r' a' s' n' c'
underWidget f = _WrappingWidget %~ f
overWidget ::
(Widget v m r a s n c -> Widget v' m' r' a' s' n' c')
-> (WindowT s v m r, GadgetT a s n c)
-> (WindowT s' v' m' r', GadgetT a' s' n' c')
overWidget f = from _WrappingWidget %~ f
aboveWidget ::
(Widget v m r a s n c -> Widget v' m' r' a' s' n' c')
-> (s -> v -> m (r, v), a -> s -> n (c, s))
-> (s' -> v' -> m' (r', v'), a' -> s' -> n' (c', s'))
aboveWidget f = from _Widget %~ f
instance (Monad m, Monad n, Semigroup r, Semigroup c) => Semigroup (Widget v m r a s n c) where
w1 <> w2 = Widget
(window w1 <> window w2)
(gadget w1 <> gadget w2)
instance (Monad m, Monad n, Monoid r, Monoid c) => Monoid (Widget v m r a s n c) where
mempty = Widget mempty mempty
mappend w1 w2 = Widget
(window w1 `mappend` window w2)
(gadget w1 `mappend` gadget w2)
instance Functor n => Functor (Widget v m r a s n) where
fmap f (Widget w g) = Widget
w
(f <$> g)
instance (Monad m, Monad n, Monoid r) => Applicative (Widget v m r a s n) where
pure c = Widget mempty (pure c)
(Widget w1 fg) <*> (Widget w2 g) = Widget (w1 `mappend` w2) (fg <*> g)
statically :: (Monad n, Monoid c) => WindowT s v m r -> Widget v m r a s n c
statically w = Widget w mempty
dynamically :: (Monad m, Monoid r) => GadgetT a s n c -> Widget v m r a s n c
dynamically = Widget mempty
type instance Dispatched (Widget v m r a s n c) = Dispatched (GadgetT a s n c)
instance Monad n => Dispatch (Widget v m r a s n c) (Widget v m r b s n c) a b where
dispatch p w = Widget
(window w)
(dispatch p $ gadget w)
type instance Implanted (Widget v m r a s n c) =
PairMaybeFunctor (Implanted (WindowT s v m r))
(Implanted (GadgetT a s n c))
instance (Monad m, Monad n) => Implant (Widget v m r a s n c) (Widget v m r a t n c) s t where
implant l w = Widget
(implant (fstLensLike l) $ window w)
(implant (sndLensLike l) $ gadget w)
newtype PairMaybeFunctor f g a = PairMaybeFunctor { getPairMaybeFunctor :: (Maybe (f a), Maybe (g a)) }
instance (Functor f, Functor g) => Functor (PairMaybeFunctor f g) where
fmap f (PairMaybeFunctor (a, b)) = PairMaybeFunctor (fmap f <$> a, fmap f <$> b)
instance (Apply f, Apply g) => Apply (PairMaybeFunctor f g) where
(PairMaybeFunctor (a, b)) <.> (PairMaybeFunctor (c, d)) = PairMaybeFunctor (liftA2 (Data.Functor.Apply.<.>) a c, liftA2 (Data.Functor.Apply.<.>) b d)
instance (Applicative f, Applicative g) => Applicative (PairMaybeFunctor f g) where
pure a = PairMaybeFunctor (Just $ pure a, Just $ pure a)
(PairMaybeFunctor (a, b)) <*> (PairMaybeFunctor (c, d)) = PairMaybeFunctor (liftA2 (<*>) a c, liftA2 (<*>) b d)
instance (Contravariant f, Contravariant g) => Contravariant (PairMaybeFunctor f g) where
contramap f (PairMaybeFunctor (a, b)) = PairMaybeFunctor (contramap f <$> a, contramap f <$> b)
fstLensLike :: LensLike (PairMaybeFunctor f g) s t a b -> LensLike f s t a b
fstLensLike l f b = fromJust . fst . getPairMaybeFunctor $ l (\a -> PairMaybeFunctor (Just $ f a, Nothing)) b
sndLensLike :: LensLike (PairMaybeFunctor f g) s t a b -> LensLike g s t a b
sndLensLike l f b = fromJust . snd . getPairMaybeFunctor $ l (\a -> PairMaybeFunctor (Nothing, Just $ f a)) b