{-# OPTIONS_GHC -Wno-orphans #-}
{-# Language
    TypeSynonymInstances,
    FlexibleInstances,
    MultiParamTypeClasses,
    FlexibleContexts,
    TypeFamilies #-}
-- | GUI (Graphical User Interface) elements are handy to change
-- the parameters of the sound in real time. It includes sliders,
-- knobs, rollers, buttons and other widgets.
--
-- A GUI element consists of two parts. They are view (how it looks)
-- and logic (what's going on with it). For example a slider can be
-- horizontal or vertical or green or yellow or small or big. It's the view
-- of the slider. And a slider can produce a continuous signal within the
-- given interval. It's a logic of the slider.
--
-- Let's talk about the view. The view is divided on two parts:
--
-- * where element is placed or Layout.
--
-- * all other  properties or just Properties.
--
-- The layout is defined with very simple functions. There are vertical and horizontal grouping
-- of the elements. We can scale the element within the group and include an empty
-- space in the group. Everything is aligned (see "Csound.Gui.Layout").
-- Other properties include colors, fonts (size and type), borders, specific properties
-- of the widgets (see "Csound.Gui.Props").
--
-- Let's consider the logic. The logic consists of three parts:
--
-- * what is consumed ('Csound.Gui.Output')
--
-- * what is produced ('Csound.Gui.Input')
--
-- * what's going on inside ('Csound.Gui.Inner')
--
-- A widget can react on values, produce values or do something useful.
-- There are special types of widgets:
--
-- * 'Csound.Gui.Source'  - they produce values only
--
-- * 'Csound.Gui.Sink'    - they consume values only
--
-- * 'Csound.Gui.Display' - something is going on inside them (for example, it can show a "hello world" message)
--
--
-- Widgets can be simple and compound. Simple widgets are primitive elements
-- (sliders, knobs, rollers, buttons). We have a special constructors that
-- produce simple widgets (see "Csound.Gui.Widget"). Compound widgets glue together
-- several widgets. That is the view contains several elements and all of them
-- involved in the logic of the widget.
--
--
module Csound.Control.Gui (
    -- * Gui
    Gui,
    Widget, Input, Output, Inner,
    Sink, Source, Display, SinkSource,
    widget, sink, source, display, sinkSource, sinkSlice, sourceSlice,
    mapSource, mapGuiSource,
    mhor, mver, msca,
    joinSource, fromSource, fromSourceSE, resizeSource,

    -- * Panels
    panel, win, panels, panelBy,
    keyPanel, keyWin, keyPanels, keyPanelBy,

    -- * Re-exports
    module Csound.Control.Gui.Layout,
    module Csound.Control.Gui.Props,
    module Csound.Control.Gui.Widget,

    -- * Lifters
    -- | An easy way to combine visuals for sound sources.
    hlifts, vlifts, gridLifts,

    lift1, hlift2, vlift2, hlift3, vlift3, hlift4, vlift4, hlift5, vlift5,

    -- ** Lifters with visual scaling
    hlifts', vlifts',

    hlift2', vlift2', hlift3', vlift3', hlift4', vlift4', hlift5', vlift5',

    -- * Monadic binds
    hbind, vbind, happly, vapply, hmapM, vmapM,
    hbind', vbind', happly', vapply', hmapM', vmapM', gridMapM
) where

import Control.Monad

import Csound.Typed

import Csound.Typed.Gui hiding (props)

import Csound.Control.Gui.Layout
import Csound.Control.Gui.Props hiding (props)
import Csound.Control.Gui.Widget

instance SigSpace a => SigSpace (Source a) where
    mapSig :: (Sig -> Sig) -> Source a -> Source a
mapSig Sig -> Sig
f = (a -> a) -> Source a -> Source a
forall a b. (a -> b) -> Source a -> Source b
mapSource ((Sig -> Sig) -> a -> a
forall a. SigSpace a => (Sig -> Sig) -> a -> a
mapSig Sig -> Sig
f)

instance (At Sig (SE Sig) a) => At Sig (SE Sig) (Source a) where
    type AtOut Sig (SE Sig) (Source a) = Source (AtOut Sig (SE Sig) a)
    at :: (Sig -> SE Sig) -> Source a -> AtOut Sig (SE Sig) (Source a)
at Sig -> SE Sig
f Source a
a = (a -> AtOut Sig (SE Sig) a)
-> Source a -> Source (AtOut Sig (SE Sig) a)
forall a b. (a -> b) -> Source a -> Source b
mapSource ((Sig -> SE Sig) -> a -> AtOut Sig (SE Sig) a
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig -> SE Sig
f) Source a
a

instance (At Sig2 Sig2 a) => At Sig2 Sig2 (Source a) where
    type AtOut Sig2 Sig2 (Source a) = Source (AtOut Sig2 Sig2 a)
    at :: (Sig2 -> Sig2) -> Source a -> AtOut Sig2 Sig2 (Source a)
at Sig2 -> Sig2
f Source a
a = (a -> AtOut Sig2 Sig2 a) -> Source a -> Source (AtOut Sig2 Sig2 a)
forall a b. (a -> b) -> Source a -> Source b
mapSource ((Sig2 -> Sig2) -> a -> AtOut Sig2 Sig2 a
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> Sig2
f) Source a
a

instance (At Sig2 (SE Sig2) a) => At Sig2 (SE Sig2) (Source a) where
    type AtOut Sig2 (SE Sig2) (Source a) = Source (AtOut Sig2 (SE Sig2) a)
    at :: (Sig2 -> SE Sig2) -> Source a -> AtOut Sig2 (SE Sig2) (Source a)
at Sig2 -> SE Sig2
f Source a
a = (a -> AtOut Sig2 (SE Sig2) a)
-> Source a -> Source (AtOut Sig2 (SE Sig2) a)
forall a b. (a -> b) -> Source a -> Source b
mapSource ((Sig2 -> SE Sig2) -> a -> AtOut Sig2 (SE Sig2) a
forall a b c. At a b c => (a -> b) -> c -> AtOut a b c
at Sig2 -> SE Sig2
f) Source a
a

-- | Creates a window with the given name, size and content
--
-- > win name (width, height) gui
win :: String -> (Int, Int) -> Gui -> SE ()
win :: String -> (Int, Int) -> Gui -> SE ()
win String
name (Int
x, Int
y) = String -> Maybe Rect -> Gui -> SE ()
panelBy String
name (Rect -> Maybe Rect
forall a. a -> Maybe a
Just (Rect -> Maybe Rect) -> Rect -> Maybe Rect
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> Int -> Rect
Rect Int
0 Int
0 Int
x Int
y)

keyWin :: String -> (Int, Int) -> Gui -> SE ()
keyWin :: String -> (Int, Int) -> Gui -> SE ()
keyWin String
name (Int
x, Int
y) = String -> Maybe Rect -> Gui -> SE ()
keyPanelBy String
name (Rect -> Maybe Rect
forall a. a -> Maybe a
Just (Rect -> Maybe Rect) -> Rect -> Maybe Rect
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int -> Int -> Rect
Rect Int
0 Int
0 Int
x Int
y)

-- | Hides the SE inside Source.
joinSource :: Source (SE a) -> Source a
joinSource :: Source (SE a) -> Source a
joinSource Source (SE a)
a = do
    (Gui
g, SE a
mv) <- Source (SE a)
a
    a
v <- SE a
mv
    (Gui, a) -> Source a
forall (m :: * -> *) a. Monad m => a -> m a
return (Gui
g, a
v)

fromSource :: Source a -> SE a
fromSource :: Source a -> SE a
fromSource Source a
a = do
    (Gui
gui, a
asig) <- Source a
a
    Gui -> SE ()
panel Gui
gui
    a -> SE a
forall (m :: * -> *) a. Monad m => a -> m a
return a
asig

fromSourceSE :: Source (SE a) -> SE a
fromSourceSE :: Source (SE a) -> SE a
fromSourceSE = SE (SE a) -> SE a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (SE (SE a) -> SE a)
-> (Source (SE a) -> SE (SE a)) -> Source (SE a) -> SE a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Source (SE a) -> SE (SE a)
forall a. Source a -> SE a
fromSource

-- | Resizes all default minimal sizes for all elements in the source.
-- It affects the total sizes of the widgets. So for example if our UI is too big
-- and it doesn't fir to the screen we can make it smaller by scaling:
--
-- > resizeSource (0.75, 0.5) uiSource
resizeSource :: (Double, Double) -> Source a -> Source a
resizeSource :: (Double, Double) -> Source a -> Source a
resizeSource (Double, Double)
scaleXY = (Gui -> Gui) -> Source a -> Source a
forall a. (Gui -> Gui) -> Source a -> Source a
mapGuiSource ((Gui -> Gui) -> Source a -> Source a)
-> (Gui -> Gui) -> Source a -> Source a
forall a b. (a -> b) -> a -> b
$ (Double, Double) -> Gui -> Gui
resizeGui (Double, Double)
scaleXY

----------------------------------------------------------------------------------
-- easy grouppings for GUIs

-- | Groups a list of Source-widgets. The visuals are horizontally aligned.
hlifts :: ([a] -> b) -> [Source a] -> Source b
hlifts :: ([a] -> b) -> [Source a] -> Source b
hlifts = ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
forall a b. ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts [Gui] -> Gui
hor

-- | Groups a list of Source-widgets. The visuals are vertically aligned.
vlifts :: ([a] -> b) -> [Source a] -> Source b
vlifts :: ([a] -> b) -> [Source a] -> Source b
vlifts = ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
forall a b. ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts [Gui] -> Gui
ver

-- | Groups a list of Source-widgets. The visuals are put on the grid.
-- The first argument is numer of elements i each row.
gridLifts :: Int -> ([a] -> b) -> [Source a] -> Source b
gridLifts :: Int -> ([a] -> b) -> [Source a] -> Source b
gridLifts Int
rowLength = ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
forall a b. ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts (Int -> [Gui] -> Gui
grid Int
rowLength)

-- | Groups a list of Source-widgets. The visuals are horizontally aligned.
-- It uses the list of proportions.
hlifts' :: [Double] -> ([a] -> b) -> [Source a] -> Source b
hlifts' :: [Double] -> ([a] -> b) -> [Source a] -> Source b
hlifts' [Double]
props = ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
forall a b. ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts ([Double] -> ([Gui] -> Gui) -> [Gui] -> Gui
applyProportionsToList [Double]
props [Gui] -> Gui
hor)

-- | Groups a list of Source-widgets. The visuals are vertically aligned.
-- It uses the list of proportions.
vlifts' :: [Double] -> ([a] -> b) -> [Source a] -> Source b
vlifts' :: [Double] -> ([a] -> b) -> [Source a] -> Source b
vlifts' [Double]
props = ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
forall a b. ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts ([Double] -> ([Gui] -> Gui) -> [Gui] -> Gui
applyProportionsToList [Double]
props [Gui] -> Gui
ver)

applyProportionsToList :: [Double] -> ([Gui] -> Gui) -> [Gui] -> Gui
applyProportionsToList :: [Double] -> ([Gui] -> Gui) -> [Gui] -> Gui
applyProportionsToList [Double]
props [Gui] -> Gui
f [Gui]
as = [Gui] -> Gui
f ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ (Double -> Gui -> Gui) -> [Double] -> [Gui] -> [Gui]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Double -> Gui -> Gui
sca ([Double]
props [Double] -> [Double] -> [Double]
forall a. [a] -> [a] -> [a]
++ Double -> [Double]
forall a. a -> [a]
repeat Double
1) [Gui]
as

genLifts :: ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts :: ([Gui] -> Gui) -> ([a] -> b) -> [Source a] -> Source b
genLifts [Gui] -> Gui
gf [a] -> b
f [Source a]
as = ([(Gui, a)] -> (Gui, b)) -> SE [(Gui, a)] -> Source b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, a)] -> (Gui, b)
phi (SE [(Gui, a)] -> Source b) -> SE [(Gui, a)] -> Source b
forall a b. (a -> b) -> a -> b
$ [Source a] -> SE [(Gui, a)]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [Source a]
as
    where
        phi :: [(Gui, a)] -> (Gui, b)
phi [(Gui, a)]
xs = ([Gui] -> Gui
gf [Gui]
gs, [a] -> b
f [a]
vs)
            where ([Gui]
gs, [a]
vs) = [(Gui, a)] -> ([Gui], [a])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Gui, a)]
xs


-- | The shortcut for @mapSource@.
lift1 :: (a -> b) -> Source a -> Source b
lift1 :: (a -> b) -> Source a -> Source b
lift1 = (a -> b) -> Source a -> Source b
forall a b. (a -> b) -> Source a -> Source b
mapSource

lift2 :: (Gui -> Gui -> Gui) -> (a -> b -> c) -> Source a -> Source b -> Source c
lift2 :: (Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
lift2 Gui -> Gui -> Gui
gf a -> b -> c
f Source a
ma Source b
mb = Source c -> Source c
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source c -> Source c) -> Source c -> Source c
forall a b. (a -> b) -> a -> b
$ do
    (Gui
ga, a
a) <- Source a
ma
    (Gui
gb, b
b) <- Source b
mb
    (Gui, c) -> Source c
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, c) -> Source c) -> (Gui, c) -> Source c
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui
gf Gui
ga Gui
gb, a -> b -> c
f a
a b
b)

lift2' :: Double -> Double
  -> (Gui -> Gui -> Gui)
  -> (a -> b -> c)
  -> Source a -> Source b -> Source c
lift2' :: Double
-> Double
-> (Gui -> Gui -> Gui)
-> (a -> b -> c)
-> Source a
-> Source b
-> Source c
lift2' Double
a Double
b Gui -> Gui -> Gui
gf = (Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
forall a b c.
(Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
lift2 (Double -> Double -> (Gui -> Gui -> Gui) -> Gui -> Gui -> Gui
forall t. Double -> Double -> (Gui -> Gui -> t) -> Gui -> Gui -> t
tfm2 Double
a Double
b Gui -> Gui -> Gui
gf)
    where tfm2 :: Double -> Double -> (Gui -> Gui -> t) -> Gui -> Gui -> t
tfm2 Double
sa Double
sb Gui -> Gui -> t
gf' = \Gui
a' Gui
b' -> Gui -> Gui -> t
gf' (Double -> Gui -> Gui
sca Double
sa Gui
a') (Double -> Gui -> Gui
sca Double
sb Gui
b')

-- | Combines two sound sources. Visuals are aligned horizontally
-- and the sound sources a grouped with the given function.
hlift2 :: (a -> b -> c) -> Source a -> Source b -> Source c
hlift2 :: (a -> b -> c) -> Source a -> Source b -> Source c
hlift2 = (Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
forall a b c.
(Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
lift2 (\Gui
a Gui
b -> [Gui] -> Gui
hor [Gui
a, Gui
b])

-- | Combines two sound sources. Visuals are aligned vertically
-- and the sound sources a grouped with the given function.
vlift2 :: (a -> b -> c) -> Source a -> Source b -> Source c
vlift2 :: (a -> b -> c) -> Source a -> Source b -> Source c
vlift2 = (Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
forall a b c.
(Gui -> Gui -> Gui)
-> (a -> b -> c) -> Source a -> Source b -> Source c
lift2 (\Gui
a Gui
b -> [Gui] -> Gui
ver [Gui
a, Gui
b])

-- | It's just like the @hlift2@ but two more parameters change visual scaling of the widgets.
hlift2' :: Double -> Double -> (a -> b -> c) -> Source a -> Source b -> Source c
hlift2' :: Double
-> Double -> (a -> b -> c) -> Source a -> Source b -> Source c
hlift2' Double
sa Double
sb = Double
-> Double
-> (Gui -> Gui -> Gui)
-> (a -> b -> c)
-> Source a
-> Source b
-> Source c
forall a b c.
Double
-> Double
-> (Gui -> Gui -> Gui)
-> (a -> b -> c)
-> Source a
-> Source b
-> Source c
lift2' Double
sa Double
sb (\Gui
a Gui
b -> [Gui] -> Gui
hor [Gui
a, Gui
b])

-- | It's just like the @vlift2@ but two more parameters change visual scaling of the widgets.
vlift2' :: Double -> Double -> (a -> b -> c) -> Source a -> Source b -> Source c
vlift2' :: Double
-> Double -> (a -> b -> c) -> Source a -> Source b -> Source c
vlift2' Double
sa Double
sb = Double
-> Double
-> (Gui -> Gui -> Gui)
-> (a -> b -> c)
-> Source a
-> Source b
-> Source c
forall a b c.
Double
-> Double
-> (Gui -> Gui -> Gui)
-> (a -> b -> c)
-> Source a
-> Source b
-> Source c
lift2' Double
sa Double
sb (\Gui
a Gui
b -> [Gui] -> Gui
ver [Gui
a, Gui
b])

lift3 :: (Gui -> Gui -> Gui -> Gui) -> (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
lift3 :: (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3 Gui -> Gui -> Gui -> Gui
gf a -> b -> c -> d
f Source a
ma Source b
mb Source c
mc = Source d -> Source d
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source d -> Source d) -> Source d -> Source d
forall a b. (a -> b) -> a -> b
$ do
    (Gui
ga, a
a) <- Source a
ma
    (Gui
gb, b
b) <- Source b
mb
    (Gui
gc, c
c) <- Source c
mc
    (Gui, d) -> Source d
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, d) -> Source d) -> (Gui, d) -> Source d
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui -> Gui
gf Gui
ga Gui
gb Gui
gc, a -> b -> c -> d
f a
a b
b c
c)

lift3' :: Double -> Double -> Double
  -> (Gui -> Gui -> Gui -> Gui)
  -> (a -> b -> c -> d)
  -> Source a -> Source b -> Source c -> Source d
lift3' :: Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3' Double
sa Double
sb Double
sc Gui -> Gui -> Gui -> Gui
gf = (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
forall a b c d.
(Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3 (Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> Gui
-> Gui
-> Gui
-> Gui
forall t.
Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa Double
sb Double
sc Gui -> Gui -> Gui -> Gui
gf)
    where tfm3 :: Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa' Double
sb' Double
sc' Gui -> Gui -> Gui -> t
gf' = \Gui
a Gui
b Gui
c -> Gui -> Gui -> Gui -> t
gf' (Double -> Gui -> Gui
sca Double
sa' Gui
a) (Double -> Gui -> Gui
sca Double
sb' Gui
b) (Double -> Gui -> Gui
sca Double
sc' Gui
c)

-- | The same as @hlift2@ but for three sound sources.
hlift3 :: (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
hlift3 :: (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
hlift3 = (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
forall a b c d.
(Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3 (\Gui
a Gui
b Gui
c -> [Gui] -> Gui
hor [Gui
a, Gui
b, Gui
c])

-- | The same as @vlift2@ but for three sound sources.
vlift3 :: (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
vlift3 :: (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
vlift3 = (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
forall a b c d.
(Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3 (\Gui
a Gui
b Gui
c -> [Gui] -> Gui
ver [Gui
a, Gui
b, Gui
c])

-- | The same as @hlift2'@ but for three sound sources.
hlift3' :: Double -> Double -> Double -> (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
hlift3' :: Double
-> Double
-> Double
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
hlift3' Double
a Double
b Double
c = Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
forall a b c d.
Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3' Double
a Double
b Double
c (\Gui
a' Gui
b' Gui
c' -> [Gui] -> Gui
hor [Gui
a', Gui
b', Gui
c'])

-- | The same as @vlift2'@ but for three sound sources.
vlift3' :: Double -> Double -> Double -> (a -> b -> c -> d) -> Source a -> Source b -> Source c -> Source d
vlift3' :: Double
-> Double
-> Double
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
vlift3' Double
a Double
b Double
c = Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
forall a b c d.
Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d)
-> Source a
-> Source b
-> Source c
-> Source d
lift3' Double
a Double
b Double
c (\Gui
a' Gui
b' Gui
c' -> [Gui] -> Gui
ver [Gui
a', Gui
b', Gui
c'])

lift4 :: (Gui -> Gui -> Gui -> Gui -> Gui) -> (a -> b -> c -> d -> e) -> Source a -> Source b -> Source c -> Source d -> Source e
lift4 :: (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4 Gui -> Gui -> Gui -> Gui -> Gui
gf a -> b -> c -> d -> e
f Source a
ma Source b
mb Source c
mc Source d
md = Source e -> Source e
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source e -> Source e) -> Source e -> Source e
forall a b. (a -> b) -> a -> b
$ do
    (Gui
ga, a
a) <- Source a
ma
    (Gui
gb, b
b) <- Source b
mb
    (Gui
gc, c
c) <- Source c
mc
    (Gui
gd, d
d) <- Source d
md
    (Gui, e) -> Source e
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, e) -> Source e) -> (Gui, e) -> Source e
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui -> Gui -> Gui
gf Gui
ga Gui
gb Gui
gc Gui
gd, a -> b -> c -> d -> e
f a
a b
b c
c d
d)

lift4' :: Double -> Double -> Double -> Double
  -> (Gui -> Gui -> Gui -> Gui -> Gui)
  -> (a -> b -> c -> d -> e)
  -> Source a -> Source b -> Source c -> Source d -> Source e
lift4' :: Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4' Double
sa Double
sb Double
sc Double
sd Gui -> Gui -> Gui -> Gui -> Gui
gf = (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
forall a b c d e.
(Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4 (Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> Gui
-> Gui
-> Gui
-> Gui
-> Gui
forall t.
Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa Double
sb Double
sc Double
sd Gui -> Gui -> Gui -> Gui -> Gui
gf)
    where tfm3 :: Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa' Double
sb' Double
sc' Double
sd' Gui -> Gui -> Gui -> Gui -> t
gf' = \Gui
a Gui
b Gui
c Gui
d -> Gui -> Gui -> Gui -> Gui -> t
gf' (Double -> Gui -> Gui
sca Double
sa' Gui
a) (Double -> Gui -> Gui
sca Double
sb' Gui
b) (Double -> Gui -> Gui
sca Double
sc' Gui
c) (Double -> Gui -> Gui
sca Double
sd' Gui
d)

-- | The same as @hlift2@ but for four sound sources.
hlift4 :: (a -> b -> c -> d -> e) -> Source a -> Source b -> Source c -> Source d -> Source e
hlift4 :: (a -> b -> c -> d -> e)
-> Source a -> Source b -> Source c -> Source d -> Source e
hlift4 = (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
forall a b c d e.
(Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4 (\Gui
a Gui
b Gui
c Gui
d -> [Gui] -> Gui
hor [Gui
a, Gui
b, Gui
c, Gui
d])

-- | The same as @vlift2@ but for four sound sources.
vlift4 :: (a -> b -> c -> d -> e) -> Source a -> Source b -> Source c -> Source d -> Source e
vlift4 :: (a -> b -> c -> d -> e)
-> Source a -> Source b -> Source c -> Source d -> Source e
vlift4 = (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
forall a b c d e.
(Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4 (\Gui
a Gui
b Gui
c Gui
d -> [Gui] -> Gui
ver [Gui
a, Gui
b, Gui
c, Gui
d])

-- | The same as @hlift2'@ but for four sound sources.
hlift4' :: Double -> Double -> Double -> Double -> (a -> b -> c -> d -> e) -> Source a -> Source b -> Source c -> Source d -> Source e
hlift4' :: Double
-> Double
-> Double
-> Double
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
hlift4' Double
a Double
b Double
c Double
d = Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
forall a b c d e.
Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4' Double
a Double
b Double
c Double
d (\Gui
a' Gui
b' Gui
c' Gui
d' -> [Gui] -> Gui
hor [Gui
a', Gui
b', Gui
c', Gui
d'])

-- | The same as @vlift2'@ but for four sound sources.
vlift4' :: Double -> Double -> Double -> Double -> (a -> b -> c -> d -> e) -> Source a -> Source b -> Source c -> Source d -> Source e
vlift4' :: Double
-> Double
-> Double
-> Double
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
vlift4' Double
a Double
b Double
c Double
d = Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
forall a b c d e.
Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui)
-> (a -> b -> c -> d -> e)
-> Source a
-> Source b
-> Source c
-> Source d
-> Source e
lift4' Double
a Double
b Double
c Double
d (\Gui
a' Gui
b' Gui
c' Gui
d' -> [Gui] -> Gui
ver [Gui
a', Gui
b', Gui
c', Gui
d'])

lift5 :: (Gui -> Gui -> Gui -> Gui -> Gui -> Gui) -> (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
lift5 :: (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5 Gui -> Gui -> Gui -> Gui -> Gui -> Gui
gf a1 -> a2 -> a3 -> a4 -> a5 -> b
f Source a1
ma1 Source a2
ma2 Source a3
ma3 Source a4
ma4 Source a5
ma5 = Source b -> Source b
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source b -> Source b) -> Source b -> Source b
forall a b. (a -> b) -> a -> b
$ do
    (Gui
ga1, a1
a1) <- Source a1
ma1
    (Gui
ga2, a2
a2) <- Source a2
ma2
    (Gui
ga3, a3
a3) <- Source a3
ma3
    (Gui
ga4, a4
a4) <- Source a4
ma4
    (Gui
ga5, a5
a5) <- Source a5
ma5
    (Gui, b) -> Source b
forall (m :: * -> *) a. Monad m => a -> m a
return ((Gui, b) -> Source b) -> (Gui, b) -> Source b
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui -> Gui -> Gui -> Gui
gf Gui
ga1 Gui
ga2 Gui
ga3 Gui
ga4 Gui
ga5, a1 -> a2 -> a3 -> a4 -> a5 -> b
f a1
a1 a2
a2 a3
a3 a4
a4 a5
a5)

lift5' :: Double -> Double -> Double -> Double -> Double ->
  (Gui -> Gui -> Gui -> Gui -> Gui -> Gui) -> (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
lift5' :: Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5' Double
sa Double
sb Double
sc Double
sd Double
se Gui -> Gui -> Gui -> Gui -> Gui -> Gui
gf = (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
forall a1 a2 a3 a4 a5 b.
(Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5 (Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> Gui
-> Gui
-> Gui
-> Gui
-> Gui
-> Gui
forall t.
Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa Double
sb Double
sc Double
sd Double
se Gui -> Gui -> Gui -> Gui -> Gui -> Gui
gf)
    where tfm3 :: Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> t)
-> Gui
-> Gui
-> Gui
-> Gui
-> Gui
-> t
tfm3 Double
sa' Double
sb' Double
sc' Double
sd' Double
se' Gui -> Gui -> Gui -> Gui -> Gui -> t
gf' = \Gui
a Gui
b Gui
c Gui
d Gui
e -> Gui -> Gui -> Gui -> Gui -> Gui -> t
gf' (Double -> Gui -> Gui
sca Double
sa' Gui
a) (Double -> Gui -> Gui
sca Double
sb' Gui
b) (Double -> Gui -> Gui
sca Double
sc' Gui
c) (Double -> Gui -> Gui
sca Double
sd' Gui
d) (Double -> Gui -> Gui
sca Double
se' Gui
e)

-- | The same as @hlift2@ but for five sound sources.
hlift5 :: (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
hlift5 :: (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
hlift5 = (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
forall a1 a2 a3 a4 a5 b.
(Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5 (\Gui
a Gui
b Gui
c Gui
d Gui
e -> [Gui] -> Gui
hor [Gui
a, Gui
b, Gui
c, Gui
d, Gui
e])

-- | The same as @vlift2@ but for five sound sources.
vlift5 :: (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
vlift5 :: (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
vlift5 = (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
forall a1 a2 a3 a4 a5 b.
(Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5 (\Gui
a Gui
b Gui
c Gui
d Gui
e -> [Gui] -> Gui
ver [Gui
a, Gui
b, Gui
c, Gui
d, Gui
e])

-- | The same as @hlift2'@ but for five sound sources.
hlift5' :: Double -> Double -> Double -> Double -> Double -> (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
hlift5' :: Double
-> Double
-> Double
-> Double
-> Double
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
hlift5' Double
a Double
b Double
c Double
d Double
e = Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
forall a1 a2 a3 a4 a5 b.
Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5' Double
a Double
b Double
c Double
d Double
e (\Gui
a' Gui
b' Gui
c' Gui
d' Gui
e' -> [Gui] -> Gui
hor [Gui
a', Gui
b', Gui
c', Gui
d', Gui
e'])

-- | The same as @vlift2'@ but for five sound sources.
vlift5' :: Double -> Double -> Double -> Double -> Double -> (a1 -> a2 -> a3 -> a4 -> a5 -> b) -> Source a1 -> Source a2 -> Source a3 -> Source a4 -> Source a5 -> Source b
vlift5' :: Double
-> Double
-> Double
-> Double
-> Double
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
vlift5' Double
a Double
b Double
c Double
d Double
e = Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
forall a1 a2 a3 a4 a5 b.
Double
-> Double
-> Double
-> Double
-> Double
-> (Gui -> Gui -> Gui -> Gui -> Gui -> Gui)
-> (a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> Source a1
-> Source a2
-> Source a3
-> Source a4
-> Source a5
-> Source b
lift5' Double
a Double
b Double
c Double
d Double
e (\Gui
a' Gui
b' Gui
c' Gui
d' Gui
e' -> [Gui] -> Gui
ver [Gui
a', Gui
b', Gui
c', Gui
d', Gui
e'])

-- | Monadic bind with horizontal concatenation of visuals.
hbind :: Source a -> (a -> Source b) -> Source b
hbind :: Source a -> (a -> Source b) -> Source b
hbind = (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
hor [Gui
a, Gui
b])

-- | Monadic bind with vertical concatenation of visuals.
vbind :: Source a -> (a -> Source b) -> Source b
vbind :: Source a -> (a -> Source b) -> Source b
vbind = (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
ver [Gui
a, Gui
b])

-- | Monadic apply with horizontal concatenation of visuals.
happly :: (a -> Source b) -> Source a -> Source b
happly :: (a -> Source b) -> Source a -> Source b
happly = (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b) -> Source a -> Source b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Source a -> (a -> Source b) -> Source b)
 -> (a -> Source b) -> Source a -> Source b)
-> (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b)
-> Source a
-> Source b
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
hor [Gui
b, Gui
a])

-- | Monadic apply with vertical concatenation of visuals.
vapply :: (a -> Source b) -> Source a -> Source b
vapply :: (a -> Source b) -> Source a -> Source b
vapply = (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b) -> Source a -> Source b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Source a -> (a -> Source b) -> Source b)
 -> (a -> Source b) -> Source a -> Source b)
-> (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b)
-> Source a
-> Source b
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
ver [Gui
b, Gui
a])

-- | Monadic bind with horizontal concatenation of visuals.
-- It expects scaling factors for visuals as first two arguments.
hbind' :: Double -> Double -> Source a -> (a -> Source b) -> Source b
hbind' :: Double -> Double -> Source a -> (a -> Source b) -> Source b
hbind' Double
ka Double
kb = (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
hor [Double -> Gui -> Gui
sca Double
ka Gui
a, Double -> Gui -> Gui
sca Double
kb Gui
b])

-- | Monadic bind with vertical concatenation of visuals.
-- It expects scaling factors for visuals as first two arguments.
vbind' :: Double -> Double -> Source a -> (a -> Source b) -> Source b
vbind' :: Double -> Double -> Source a -> (a -> Source b) -> Source b
vbind' Double
ka Double
kb = (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
ver [Double -> Gui -> Gui
sca Double
ka Gui
a, Double -> Gui -> Gui
sca Double
kb Gui
b])

-- | Monadic apply with horizontal concatenation of visuals.
-- It expects scaling factors for visuals as first two arguments.
happly' :: Double -> Double -> (a -> Source b) -> Source a -> Source b
happly' :: Double -> Double -> (a -> Source b) -> Source a -> Source b
happly' Double
ka Double
kb = (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b) -> Source a -> Source b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Source a -> (a -> Source b) -> Source b)
 -> (a -> Source b) -> Source a -> Source b)
-> (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b)
-> Source a
-> Source b
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
hor [Double -> Gui -> Gui
sca Double
kb Gui
b, Double -> Gui -> Gui
sca Double
ka Gui
a])

-- | Monadic apply with vertical concatenation of visuals.
-- It expects scaling factors for visuals as first two arguments.
vapply' :: Double -> Double -> (a -> Source b) -> Source a -> Source b
vapply' :: Double -> Double -> (a -> Source b) -> Source a -> Source b
vapply' Double
ka Double
kb = (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b) -> Source a -> Source b
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Source a -> (a -> Source b) -> Source b)
 -> (a -> Source b) -> Source a -> Source b)
-> (Source a -> (a -> Source b) -> Source b)
-> (a -> Source b)
-> Source a
-> Source b
forall a b. (a -> b) -> a -> b
$ (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
forall a b.
(Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind (\Gui
a Gui
b -> [Gui] -> Gui
ver [Double -> Gui -> Gui
sca Double
kb Gui
b, Double -> Gui -> Gui
sca Double
ka Gui
a])


genBind :: (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind :: (Gui -> Gui -> Gui) -> Source a -> (a -> Source b) -> Source b
genBind Gui -> Gui -> Gui
gui Source a
ma a -> Source b
mf = Source b -> Source b
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source b -> Source b) -> Source b -> Source b
forall a b. (a -> b) -> a -> b
$ do
    (Gui
ga, a
a) <- Source a
ma
    (Gui
gb, b
b) <- a -> Source b
mf a
a
    (Gui, b) -> Source b
forall (m :: * -> *) a. Monad m => a -> m a
return (Gui -> Gui -> Gui
gui Gui
ga Gui
gb, b
b)

-- | Creates a list of sources with mapping a function and stacks them horizontally.
hmapM :: (a -> Source b) -> [a] -> Source [b]
hmapM :: (a -> Source b) -> [a] -> Source [b]
hmapM = ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
forall a b. ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM [Gui] -> Gui
hor

-- | Creates a list of sources with mapping a function and stacks them vertically.
vmapM :: (a -> Source b) -> [a] -> Source [b]
vmapM :: (a -> Source b) -> [a] -> Source [b]
vmapM = ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
forall a b. ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM [Gui] -> Gui
ver

-- | It's like @hmapM@ but we can supply the list of relative sizes.
hmapM' :: [Double] -> (a -> Source b) -> [a] -> Source [b]
hmapM' :: [Double] -> (a -> Source b) -> [a] -> Source [b]
hmapM' [Double]
ks = ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
forall a b. ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM (\[Gui]
xs -> [Gui] -> Gui
hor ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ (Double -> Gui -> Gui) -> [Double] -> [Gui] -> [Gui]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Double -> Gui -> Gui
sca [Double]
ks [Gui]
xs)

-- | It's like @hvapM@ but we can supply the list of relative sizes.
vmapM' :: [Double] -> (a -> Source b) -> [a] -> Source [b]
vmapM' :: [Double] -> (a -> Source b) -> [a] -> Source [b]
vmapM' [Double]
ks = ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
forall a b. ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM (\[Gui]
xs -> [Gui] -> Gui
ver ([Gui] -> Gui) -> [Gui] -> Gui
forall a b. (a -> b) -> a -> b
$ (Double -> Gui -> Gui) -> [Double] -> [Gui] -> [Gui]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Double -> Gui -> Gui
sca [Double]
ks [Gui]
xs)

-- | Creates a list of sources with mapping a function and puts them on the grid.
-- The first argument is the number of items in the row.
gridMapM :: Int -> (a -> Source b) -> [a] -> Source [b]
gridMapM :: Int -> (a -> Source b) -> [a] -> Source [b]
gridMapM Int
rowLength = ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
forall a b. ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM (Int -> [Gui] -> Gui
grid Int
rowLength)

genMapM :: ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM :: ([Gui] -> Gui) -> (a -> Source b) -> [a] -> Source [b]
genMapM [Gui] -> Gui
gui a -> Source b
f [a]
xs = Source [b] -> Source [b]
forall a. SE (Gui, Input a) -> SE (Gui, Input a)
source (Source [b] -> Source [b]) -> Source [b] -> Source [b]
forall a b. (a -> b) -> a -> b
$ do
    ([Gui]
gs, [b]
vs) <- ([(Gui, b)] -> ([Gui], [b])) -> SE [(Gui, b)] -> SE ([Gui], [b])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(Gui, b)] -> ([Gui], [b])
forall a b. [(a, b)] -> ([a], [b])
unzip (SE [(Gui, b)] -> SE ([Gui], [b]))
-> SE [(Gui, b)] -> SE ([Gui], [b])
forall a b. (a -> b) -> a -> b
$ (a -> Source b) -> [a] -> SE [(Gui, b)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> Source b
f [a]
xs
    (Gui, [b]) -> Source [b]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Gui] -> Gui
gui [Gui]
gs, [b]
vs)