{-# OPTIONS_GHC -Wno-redundant-constraints #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} module Glazier.React.Widget where import Control.Lens import Control.Monad.Except import Data.Bifunctor import Data.Diverse.Lens import Data.Diverse.Profunctor import Glazier.Command.Exec import Glazier.React.Entity import Glazier.React.Gadget import Glazier.React.Scene import Glazier.React.Window -- | A 'Widget' is a 'Gadget' that fires 'Either' a 'Window' or a value. type Widget cmd p s a = ExceptT (Window s ()) (Gadget cmd p s) a -- | Use this function to verify at compile time that the first widget doesn't -- require any @AsFacet (IO cmd) cmd@. noIOWidget :: Widget (NoIOCmd cmd) s s a -> Widget cmd s s a -> Widget cmd s s a noIOWidget _ = id magnifyWidget :: Traversal' t s -> ExceptT (Window s ()) (Gadget cmd p s) a -> ExceptT (Window t ()) (Gadget cmd p t) a magnifyWidget l wid = ExceptT $ (first (magnifiedScene l)) <$> (magnifiedEntity l (runExceptT wid)) -- | Convert a 'Gadget' into a 'Widget' widget :: Gadget cmd p s (Either (Window s ()) a) -> Widget cmd p s a widget = ExceptT runWidget :: Widget cmd p s a -> Gadget cmd p s (Either (Window s ()) a) runWidget = runExceptT mapWidget :: (Gadget cmd p s (Either (Window s ()) a) -> Gadget cmd p' s' (Either (Window s' ()) b)) -> Widget cmd p s a -> Widget cmd p' s' b mapWidget = mapExceptT display :: Window s () -> Widget cmd p s a display = throwError overWindow :: (Window s () -> Window s ()) -> Widget cmd p s a -> Widget cmd p s a overWindow = withExceptT overWindow2 :: (Window s () -> Window s () -> Window s ()) -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a overWindow2 f x y = withWindow x $ \x' -> withWindow y $ \y' -> display $ f x' y' overWindow3 :: (Window s () -> Window s () -> Window s () -> Window s ()) -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a overWindow3 f x y z = withWindow x $ \x' -> withWindow y $ \y' -> withWindow z $ \z' -> display $ f x' y' z' -- overWindow4 :: (Window s () -> Window s () -> Window s () -> Window s () -> Window s ()) -- -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -- overWindow4 f x y z a = withWindow x $ -- \x' -> withWindow y $ -- \y' -> withWindow z $ -- \z' -> withWindow a $ -- \a' -> display $ f x' y' z' a' -- overWindow5 :: (Window s () -> Window s () -> Window s () -> Window s () -> Window s () -> Window s ()) -- -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -- overWindow5 f x y z a b = withWindow x $ -- \x' -> withWindow y $ -- \y' -> withWindow z $ -- \z' -> withWindow a $ -- \a' -> withWindow b $ -- \b' -> display $ f x' y' z' a' b' overWindow2' :: ( ChooseBoth x1 x2 ys) => (Window s () -> Window s () -> Window s ()) -> Widget cmd p s (Which x1) -> Widget cmd p s (Which x2) -> Widget cmd p s (Which ys) overWindow2' f x1 x2 = overWindow2 f (diversify <$> x1) (diversify <$> x2) overWindow3' :: ( Diversify x1 ys , Diversify x2 ys , Diversify x3 ys , ys ~ AppendUnique x1 (AppendUnique x2 x3)) => (Window s () -> Window s () -> Window s () -> Window s ()) -> Widget cmd p s (Which x1) -> Widget cmd p s (Which x2) -> Widget cmd p s (Which x3) -> Widget cmd p s (Which ys) overWindow3' f x1 x2 x3 = overWindow3 f (diversify <$> x1) (diversify <$> x2) (diversify <$> x3) -- overWindow4' :: -- ( Diversify x1 ys -- , Diversify x2 ys -- , Diversify x3 ys -- , Diversify x4 ys -- , ys ~ AppendUnique x1 (AppendUnique x2 (AppendUnique x3 x4))) -- => (Window s () -> Window s () -> Window s () -> Window s () -> Window s ()) -- -> Widget cmd p s (Which x1) -> Widget cmd p s (Which x2) -> Widget cmd p s (Which x3) -> Widget cmd p s (Which x4) -- -> Widget cmd p s (Which ys) -- overWindow4' f x1 x2 x3 x4 = overWindow4 f -- (diversify <$> x1) -- (diversify <$> x2) -- (diversify <$> x3) -- (diversify <$> x4) -- overWindow5' :: -- ( Diversify x1 ys -- , Diversify x2 ys -- , Diversify x3 ys -- , Diversify x4 ys -- , Diversify x5 ys -- , ys ~ AppendUnique x1 (AppendUnique x2 (AppendUnique x3 (AppendUnique x4 x5)))) -- => (Window s () -> Window s () -> Window s () -> Window s () -> Window s () -> Window s ()) -- -> Widget cmd p s (Which x1) -> Widget cmd p s (Which x2) -> Widget cmd p s (Which x3) -- -> Widget cmd p s (Which x4) -> Widget cmd p s (Which x5) -> Widget cmd p s (Which ys) -- overWindow5' f x1 x2 x3 x4 x5 = overWindow5 f -- (diversify <$> x1) -- (diversify <$> x2) -- (diversify <$> x3) -- (diversify <$> x4) -- (diversify <$> x5) withWindow :: Widget cmd p s a -> (Window s () -> Widget cmd p s a) -> Widget cmd p s a withWindow = catchError withWindow' :: (ChooseBoth xs ys zs) => Widget cmd p s (Which xs) -> (Window s () -> Widget cmd p s (Which ys)) -> Widget cmd p s (Which zs) withWindow' m f = withWindow (diversify <$> m) (fmap diversify . f) -- withWindow2 :: Widget cmd p s a -> Widget cmd p s a -- -> (Window s () -> Window s () -> Widget cmd p s a) -- -> Widget cmd p s a -- withWindow2 x y f = withWindow x $ \x' -> withWindow y $ \y' -> f x' y' -- withWindow3 :: Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -- -> (Window s () -> Window s () -> Window s () -> Widget cmd p s a) -- -> Widget cmd p s a -- withWindow3 x y z f = withWindow x $ \x' -> withWindow y $ \y' -> withWindow z $ \z' -> f x' y' z' -- windowWith :: (Window s () -> Widget cmd p s a) -> Widget cmd p s a -> Widget cmd p s a -- windowWith = flip withWindow -- windowWith2 :: (Window s () -> Window s () -> Widget cmd p s a) -- -> Widget cmd p s a -> Widget cmd p s a -- -> Widget cmd p s a -- windowWith2 f x y = withWindow2 x y f -- windowWith3 :: (Window s () -> Window s () -> Window s () -> Widget cmd p s a) -- -> Widget cmd p s a -> Widget cmd p s a -> Widget cmd p s a -- -> Widget cmd p s a -- windowWith3 f x y z = withWindow3 x y z f -- withWindow2' :: -- ( Diversify x1 zs -- , Diversify x2 zs -- , Diversify ys zs -- , zs ~ AppendUnique x1 (AppendUnique x2 ys)) -- not redunant contraint -- => Widget cmd p s (Which x1) -- -> Widget cmd p s (Which x2) -- -> (Window s () -> Window s () -> Widget cmd p s (Which ys)) -- -> Widget cmd p s (Which zs) -- withWindow2' x y f = withWindow2 (diversify <$> x) (diversify <$> y) (\x' y' -> fmap diversify $ f x' y') -- withWindow3' :: -- ( Diversify x1 zs -- , Diversify x2 zs -- , Diversify x3 zs -- , Diversify ys zs -- , zs ~ AppendUnique x1 (AppendUnique x2 (AppendUnique x3 ys))) -- not redunant contraint -- => Widget cmd p s (Which x1) -- -> Widget cmd p s (Which x2) -- -> Widget cmd p s (Which x3) -- -> (Window s () -> Window s () -> Window s () -> Widget cmd p s (Which ys)) -- -> Widget cmd p s (Which zs) -- withWindow3' x y z f = withWindow3 (diversify <$> x) (diversify <$> y) (diversify <$> z) -- (\x' y' z' -> fmap diversify $ f x' y' z') -- windowWith' :: (ChooseBoth xs ys zs) -- => (Window s () -> Widget cmd p s (Which ys)) -- -> Widget cmd p s (Which xs) -- -> Widget cmd p s (Which zs) -- windowWith' f m = withWindow' m f -- windowWith2' :: -- ( Diversify x1 zs -- , Diversify x2 zs -- , Diversify ys zs -- , zs ~ AppendUnique x1 (AppendUnique x2 ys)) -- not redunant contraint -- => (Window s () -> Window s () -> Widget cmd p s (Which ys)) -- -> Widget cmd p s (Which x1) -- -> Widget cmd p s (Which x2) -- -> Widget cmd p s (Which zs) -- windowWith2' f x y = withWindow2' x y f -- windowWith3' :: -- ( Diversify x1 zs -- , Diversify x2 zs -- , Diversify x3 zs -- , Diversify ys zs -- , zs ~ AppendUnique x1 (AppendUnique x2 (AppendUnique x3 ys))) -- not redunant contraint -- => (Window s () -> Window s () -> Window s () -> Widget cmd p s (Which ys)) -- -> Widget cmd p s (Which x1) -- -> Widget cmd p s (Which x2) -- -> Widget cmd p s (Which x3) -- -> Widget cmd p s (Which zs) -- windowWith3' f x y z = withWindow3' x y z f