{-|
A Grapefruit example which demonstrates the use of incremental signals and container views.
A list of kinds of fruit is displayed. Below this list, there are several buttons for
manipulating the list. The changing list is represented by an incremental signal over sequences.
Note that not every list manipulation is applicable at every time. If you select a
non-applicable operation, you get a runtime error. This is caused by the generic checking for
incremental signals which is provided by the 'iSignal' function.
-}moduleExamples.Grapefruit.ListView(mainCircuit)where-- ControlimportControl.ApplicativeasApplicativeimportControl.ArrowasArrow-- DataimportData.FoldableasFoldableimportData.SequenceasSeqimportData.FractionasFractionimportData.Colour.RGBSpaceasRGBSpaceimportData.RecordasRecord-- FRP.GrapefruitimportFRP.Grapefruit.Signal.DiscreteasDSignalimportFRP.Grapefruit.Signal.IncrementalasISignalimportFRP.Grapefruit.Signal.Incremental.SequenceasSeqISignal-- Graphics.UI.GrapefruitimportGraphics.UI.Grapefruit.ItemasUIItemhiding(box)importGraphics.UI.Grapefruit.CircuitasUICircuitimportGraphics.UI.Grapefruit.Backend.BasicasBasicUIBackendimportGraphics.UI.Grapefruit.Backend.ContainerasContainerUIBackend-- |The circuit describing the whole application.mainCircuit::(ContainerUIBackenduiBackend)=>UICircuitWindowuiBackendera()(DSignalera())mainCircuit=proc_->doX:&Closure:=closure`With`X`With`_<-mainWindow-<X:&Title:=pure"List view"`With`X`With`()returnA-<closurewheremainWindow=window`with`boxVertical`with`contentcontent::(ContainerUIBackenduiBackend)=>UICircuitWidgetuiBackendera()()content=proc_->dorecletfruits=ISignal.construct(Seq.singletonGrapefruit)(fmap(Diff.Seq.singleton)atomicFruitDiffs)atomicFruitDiffs=DSignal.unions[insertions,deletions,shifts,updates]cols=ISignal.construct(Seq.fromList[nameCol,tastinessCol])(fmap(Diff.Seq.singleton)atomicColDiffs)nameCol=Column"name"nameDisplaytextCellnameDisplay=\fruit->TextCellDisplay(namefruit)(colorfruit)tastinessCol=Column"tastiness"tastinessDisplayprogressCelltastinessDisplay=\fruit->ProgressCellDisplay(tastinessfruit)NothingatomicColDiffs=colSwaps_<-display-<(fruits,cols)insertions<-inserter-<()deletions<-deleter-<()shifts<-shifter-<()updates<-updater-<()colSwaps<-colSwapper-<()returnA-<()display::(ContainerUIBackenduiBackend)=>UICircuitWidgetuiBackendera(ISignalera(SeqFruit),ISignalera(Seq(ColumnuiBackendFruit)))()display=proc(fruits,cols)->doX:&Selection:=selection<-justlistView-<X:&Elements:=fruits:&Columns:=colsX<-justlabel-<X:&Text:=fmap(show.toList)selectionreturnA-<()inserter::(BasicUIBackenduiBackend)=>UICircuitWidgetuiBackendera()(DSignalera(AtomicDiffFruit))inserter=proc_->doX:&Push:=push<-justpushButton-<X:&Text:=pure("Insert an apple "++"at the beginning")returnA-<Insertion0(Seq.singletonApple)<$pushdeleter::(BasicUIBackenduiBackend)=>UICircuitWidgetuiBackendera()(DSignalera(AtomicDiffFruit))deleter=proc_->doX:&Push:=push<-justpushButton-<X:&Text:=pure"Delete the second element"returnA-<Deletion11<$pushshifter::(BasicUIBackenduiBackend)=>UICircuitWidgetuiBackendera()(DSignalera(AtomicDiffFruit))shifter=proc_->doX:&Push:=push<-justpushButton-<X:&Text:=pure"Swap the first two elements"returnA-<Shift011<$pushupdater::(BasicUIBackenduiBackend)=>UICircuitWidgetuiBackendera()(DSignalera(AtomicDiffFruit))updater=proc_->doX:&Push:=push<-justpushButton-<X:&Text:=pure("Replace the third element "++"with a banana")returnA-<Update2(Seq.singletonBanana)<$pushcolSwapper::(BasicUIBackenduiBackend)=>UICircuitWidgetuiBackendera()(DSignalera(AtomicDiff(ColumnuiBackendFruit)))colSwapper=proc_->doX:&Push:=push<-justpushButton-<X:&Text:=pure"Swap columns"returnA-<Shift011<$pushdataFruit=Grapefruit|Apple|Bananaderiving(Show)name::Fruit->StringnameGrapefruit="grapefruit"nameApple="apple"nameBanana="banana"tastiness::Fruit->FractiontastinessGrapefruit=Fraction.fromPercentage100tastinessApple=Fraction.fromPercentage25tastinessBanana=Fraction.fromPercentage50color::Fruit->RGBFractioncolorGrapefruit=RGB(fromFactor1)(fromFactor0.8)(fromFactor0)colorApple=RGB(fromFactor1)(fromFactor0)(fromFactor0)colorBanana=RGB(fromFactor1)(fromFactor1)(fromFactor0)