packages feed

threepenny-editors 0.5.1 → 0.5.2

raw patch · 6 files changed

+328/−169 lines, 6 filesdep +haskell-src-extsdep ~basedep ~threepenny-guinew-component:exe:parserPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: haskell-src-exts

Dependency ranges changed: base, threepenny-gui

API changes (from Hackage documentation)

- Graphics.UI.Threepenny.Editors: Editor :: Tidings a -> editorElement -> Editor editorElement a
- Graphics.UI.Threepenny.Editors: [_editorElement] :: Editor editorElement a -> editorElement
- Graphics.UI.Threepenny.Editors: [_editorTidings] :: Editor editorElement a -> Tidings a
- Graphics.UI.Threepenny.Editors: createEditor :: Renderable w => EditorFactory a w b -> Behavior a -> UI (Editor Element b)
- Graphics.UI.Threepenny.Editors: data EditorFactory a el b
- Graphics.UI.Threepenny.Editors: editorElement :: Lens (Editor el a) (Editor el' a) el el'
- Graphics.UI.Threepenny.Editors.Types: EF :: (Behavior a -> UI (Editor el b)) -> EditorFactory a el b
- Graphics.UI.Threepenny.Editors.Types: [_editorElement] :: Editor editorElement a -> editorElement
- Graphics.UI.Threepenny.Editors.Types: [_editorTidings] :: Editor editorElement a -> Tidings a
- Graphics.UI.Threepenny.Editors.Types: [runEF] :: EditorFactory a el b -> Behavior a -> UI (Editor el b)
- Graphics.UI.Threepenny.Editors.Types: applyEF :: (el1 -> el2 -> el) -> EditorFactory in_ el1 (a -> b) -> EditorFactory in_ el2 a -> EditorFactory in_ el b
- Graphics.UI.Threepenny.Editors.Types: createEditor :: Renderable w => EditorFactory a w b -> Behavior a -> UI (Editor Element b)
- Graphics.UI.Threepenny.Editors.Types: data Editor editorElement a
- Graphics.UI.Threepenny.Editors.Types: dimapEF :: (a' -> a) -> (b -> b') -> EditorFactory a el b -> EditorFactory a' el b'
- Graphics.UI.Threepenny.Editors.Types: editorElement :: Lens (Editor el a) (Editor el' a) el el'
- Graphics.UI.Threepenny.Editors.Types: instance Data.Biapplicative.Biapplicative (Graphics.UI.Threepenny.Editors.Types.EditorFactory a)
- Graphics.UI.Threepenny.Editors.Types: instance Data.Bifunctor.Bifunctor (Graphics.UI.Threepenny.Editors.Types.EditorFactory a)
- Graphics.UI.Threepenny.Editors.Types: instance Data.Bifunctor.Bifunctor Graphics.UI.Threepenny.Editors.Types.Editor
- Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Functor (Graphics.UI.Threepenny.Editors.Types.Editor editorElement)
- Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Functor (Graphics.UI.Threepenny.Editors.Types.EditorFactory a el)
- Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Monoid el => GHC.Base.Applicative (Graphics.UI.Threepenny.Editors.Types.EditorFactory a el)
- Graphics.UI.Threepenny.Editors.Types: instance Graphics.UI.Threepenny.Core.Widget el => Graphics.UI.Threepenny.Core.Widget (Graphics.UI.Threepenny.Editors.Types.Editor el a)
- Graphics.UI.Threepenny.Editors.Types: lmapEF :: (a' -> a) -> EditorFactory a el b -> EditorFactory a' el b
- Graphics.UI.Threepenny.Editors.Types: newtype EditorFactory a el b
- Graphics.UI.Threepenny.Editors.Types: renderEditor :: Renderable w => Editor w a -> UI (Editor Element a)
+ Graphics.UI.Threepenny.Editors: GenericWidget :: Tidings a -> control -> GenericWidget control a
+ Graphics.UI.Threepenny.Editors: [_widgetControl] :: GenericWidget control a -> control
+ Graphics.UI.Threepenny.Editors: [_widgetTidings] :: GenericWidget control a -> Tidings a
+ Graphics.UI.Threepenny.Editors: create :: Editor a el b -> Behavior a -> UI (GenericWidget el b)
+ Graphics.UI.Threepenny.Editors: data GenericWidget control a
+ Graphics.UI.Threepenny.Editors: dimapE :: (a' -> a) -> (b -> b') -> Editor a el b -> Editor a' el b'
+ Graphics.UI.Threepenny.Editors: lmapE :: (a' -> a) -> Editor a el b -> Editor a' el b
+ Graphics.UI.Threepenny.Editors: widgetControl :: forall control_asaT a_asaU control_asnj. Lens (GenericWidget control_asaT a_asaU) (GenericWidget control_asnj a_asaU) control_asaT control_asnj
+ Graphics.UI.Threepenny.Editors: widgetTidings :: forall control_asaT a_asaU a_asnk. Lens (GenericWidget control_asaT a_asaU) (GenericWidget control_asaT a_asnk) (Tidings a_asaU) (Tidings a_asnk)
+ Graphics.UI.Threepenny.Editors.Types: GenericWidget :: Tidings a -> control -> GenericWidget control a
+ Graphics.UI.Threepenny.Editors.Types: [_widgetControl] :: GenericWidget control a -> control
+ Graphics.UI.Threepenny.Editors.Types: [_widgetTidings] :: GenericWidget control a -> Tidings a
+ Graphics.UI.Threepenny.Editors.Types: [create] :: Editor a el b -> Behavior a -> UI (GenericWidget el b)
+ Graphics.UI.Threepenny.Editors.Types: applyE :: (el1 -> el2 -> el) -> Editor in_ el1 (a -> b) -> Editor in_ el2 a -> Editor in_ el b
+ Graphics.UI.Threepenny.Editors.Types: data GenericWidget control a
+ Graphics.UI.Threepenny.Editors.Types: dimapE :: (a' -> a) -> (b -> b') -> Editor a el b -> Editor a' el b'
+ Graphics.UI.Threepenny.Editors.Types: instance Data.Biapplicative.Biapplicative (Graphics.UI.Threepenny.Editors.Types.Editor a)
+ Graphics.UI.Threepenny.Editors.Types: instance Data.Bifunctor.Bifunctor (Graphics.UI.Threepenny.Editors.Types.Editor a)
+ Graphics.UI.Threepenny.Editors.Types: instance Data.Bifunctor.Bifunctor Graphics.UI.Threepenny.Editors.Types.GenericWidget
+ Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Functor (Graphics.UI.Threepenny.Editors.Types.Editor a el)
+ Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Functor (Graphics.UI.Threepenny.Editors.Types.GenericWidget control)
+ Graphics.UI.Threepenny.Editors.Types: instance GHC.Base.Monoid el => GHC.Base.Applicative (Graphics.UI.Threepenny.Editors.Types.Editor a el)
+ Graphics.UI.Threepenny.Editors.Types: instance Graphics.UI.Threepenny.Core.Widget el => Graphics.UI.Threepenny.Core.Widget (Graphics.UI.Threepenny.Editors.Types.GenericWidget el a)
+ Graphics.UI.Threepenny.Editors.Types: instance Graphics.UI.Threepenny.Editors.Layout.Renderable el => Graphics.UI.Threepenny.Editors.Layout.Renderable (Graphics.UI.Threepenny.Editors.Types.GenericWidget el a)
+ Graphics.UI.Threepenny.Editors.Types: liftElement :: UI el -> Editor a el ()
+ Graphics.UI.Threepenny.Editors.Types: lmapE :: (a' -> a) -> Editor a el b -> Editor a' el b
+ Graphics.UI.Threepenny.Editors.Types: newtype Editor a el b
+ Graphics.UI.Threepenny.Editors.Types: widgetControl :: forall control_asaT a_asaU control_asnj. Lens (GenericWidget control_asaT a_asaU) (GenericWidget control_asnj a_asaU) control_asaT control_asnj
+ Graphics.UI.Threepenny.Editors.Types: widgetTidings :: forall control_asaT a_asaU a_asnk. Lens (GenericWidget control_asaT a_asaU) (GenericWidget control_asaT a_asnk) (Tidings a_asaU) (Tidings a_asnk)
+ Graphics.UI.Threepenny.Editors.Validation: Invalid :: String -> ValidationResult
+ Graphics.UI.Threepenny.Editors.Validation: Ok :: ValidationResult
+ Graphics.UI.Threepenny.Editors.Validation: class Validable a
+ Graphics.UI.Threepenny.Editors.Validation: data ValidationResult
+ Graphics.UI.Threepenny.Editors.Validation: instance GHC.Show.Show Graphics.UI.Threepenny.Editors.Validation.ValidationResult
+ Graphics.UI.Threepenny.Editors.Validation: isValid :: Validable a => a -> Bool
+ Graphics.UI.Threepenny.Editors.Validation: updateIfValid :: Validable a => a -> a -> a
+ Graphics.UI.Threepenny.Editors.Validation: validate :: Validable a => a -> ValidationResult
- Graphics.UI.Threepenny.Editors: (*-) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (*-) :: UI Element -> Editor s Layout a -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: (*|) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (*|) :: UI Element -> Editor s Layout a -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: (-*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (-*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: (-*-) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (-*-) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: (|*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (|*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: (|*|) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors: (|*|) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- Graphics.UI.Threepenny.Editors: construct :: Renderable m => EditorFactory a m b -> EditorFactory a Layout b
+ Graphics.UI.Threepenny.Editors: construct :: Renderable m => Editor a m b -> Editor a Layout b
- Graphics.UI.Threepenny.Editors: contents :: Editor el a -> Behavior a
+ Graphics.UI.Threepenny.Editors: contents :: GenericWidget el a -> Behavior a
- Graphics.UI.Threepenny.Editors: data Editor editorElement a
+ Graphics.UI.Threepenny.Editors: data Editor a el b
- Graphics.UI.Threepenny.Editors: edited :: Editor el a -> Event a
+ Graphics.UI.Threepenny.Editors: edited :: GenericWidget el a -> Event a
- Graphics.UI.Threepenny.Editors: editor :: (Editable a, Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a), EditorWidget a ~ Layout) => EditorFactory a (EditorWidget a) a
+ Graphics.UI.Threepenny.Editors: editor :: (Editable a, Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a), EditorWidget a ~ Layout) => Editor a (EditorWidget a) a
- Graphics.UI.Threepenny.Editors: editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)
+ Graphics.UI.Threepenny.Editors: editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- Graphics.UI.Threepenny.Editors: editorGeneric :: forall a. (Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a)) => EditorFactory a Layout a
+ Graphics.UI.Threepenny.Editors: editorGeneric :: forall a. (Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a)) => Editor a Layout a
- Graphics.UI.Threepenny.Editors: editorGenericSimple :: forall a xs. (Generic a, HasDatatypeInfo a, All Editable xs, Code a ~ '[xs]) => EditorFactory a Layout a
+ Graphics.UI.Threepenny.Editors: editorGenericSimple :: forall a xs. (Generic a, HasDatatypeInfo a, All Editable xs, Code a ~ '[xs]) => Editor a Layout a
- Graphics.UI.Threepenny.Editors: editorIdentity :: EditorFactory a el a -> EditorFactory (Identity a) el (Identity a)
+ Graphics.UI.Threepenny.Editors: editorIdentity :: Editor a el a -> Editor (Identity a) el (Identity a)
- Graphics.UI.Threepenny.Editors: editorJust :: EditorFactory (Maybe b) el (Maybe b) -> EditorFactory b el b
+ Graphics.UI.Threepenny.Editors: editorJust :: Editor (Maybe b) el (Maybe b) -> Editor b el b
- Graphics.UI.Threepenny.Editors: editorReadShow :: (Read a, Show a) => EditorFactory (Maybe a) TextEntry (Maybe a)
+ Graphics.UI.Threepenny.Editors: editorReadShow :: (Read a, Show a) => Editor (Maybe a) TextEntry (Maybe a)
- Graphics.UI.Threepenny.Editors: editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)
+ Graphics.UI.Threepenny.Editors: editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- Graphics.UI.Threepenny.Editors: editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, EditorFactory a el a)] -> (a -> tag) -> EditorFactory a Layout a
+ Graphics.UI.Threepenny.Editors: editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, Editor a el a)] -> (a -> tag) -> Editor a Layout a
- Graphics.UI.Threepenny.Editors: editorUnit :: EditorFactory b Element b
+ Graphics.UI.Threepenny.Editors: editorUnit :: Editor b Element b
- Graphics.UI.Threepenny.Editors: field :: Renderable m => String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out Layout a
+ Graphics.UI.Threepenny.Editors: field :: Renderable m => String -> (out -> inn) -> Editor inn m a -> Editor out Layout a
- Graphics.UI.Threepenny.Editors: fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out m' a
+ Graphics.UI.Threepenny.Editors: fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> Editor inn m a -> Editor out m' a
- Graphics.UI.Threepenny.Editors: someEditor :: Editable a => EditorFactory a Layout a
+ Graphics.UI.Threepenny.Editors: someEditor :: Editable a => Editor a Layout a
- Graphics.UI.Threepenny.Editors: withLayout :: (layout -> layout') -> EditorFactory a layout b -> EditorFactory a layout' b
+ Graphics.UI.Threepenny.Editors: withLayout :: (layout -> layout') -> Editor a layout b -> Editor a layout' b
- Graphics.UI.Threepenny.Editors: withSomeWidget :: Renderable w => EditorFactory a w b -> EditorFactory a Layout b
+ Graphics.UI.Threepenny.Editors: withSomeWidget :: Renderable w => Editor a w b -> Editor a Layout b
- Graphics.UI.Threepenny.Editors.Types: (*-) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (*-) :: UI Element -> Editor s Layout a -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: (*|) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (*|) :: UI Element -> Editor s Layout a -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: (-*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (-*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: (-*-) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (-*-) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: (|*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (|*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: (|*|) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a
+ Graphics.UI.Threepenny.Editors.Types: (|*|) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- Graphics.UI.Threepenny.Editors.Types: Editor :: Tidings a -> editorElement -> Editor editorElement a
+ Graphics.UI.Threepenny.Editors.Types: Editor :: (Behavior a -> UI (GenericWidget el b)) -> Editor a el b
- Graphics.UI.Threepenny.Editors.Types: construct :: Renderable m => EditorFactory a m b -> EditorFactory a Layout b
+ Graphics.UI.Threepenny.Editors.Types: construct :: Renderable m => Editor a m b -> Editor a Layout b
- Graphics.UI.Threepenny.Editors.Types: contents :: Editor el a -> Behavior a
+ Graphics.UI.Threepenny.Editors.Types: contents :: GenericWidget el a -> Behavior a
- Graphics.UI.Threepenny.Editors.Types: edit :: (a' -> a) -> EditorFactory a el b -> EditorFactory a' el b
+ Graphics.UI.Threepenny.Editors.Types: edit :: (a' -> a) -> Editor a el b -> Editor a' el b
- Graphics.UI.Threepenny.Editors.Types: edited :: Editor el a -> Event a
+ Graphics.UI.Threepenny.Editors.Types: edited :: GenericWidget el a -> Event a
- Graphics.UI.Threepenny.Editors.Types: editorCheckBox :: EditorFactory Bool Element Bool
+ Graphics.UI.Threepenny.Editors.Types: editorCheckBox :: Editor Bool Element Bool
- Graphics.UI.Threepenny.Editors.Types: editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)
+ Graphics.UI.Threepenny.Editors.Types: editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- Graphics.UI.Threepenny.Editors.Types: editorFactoryElement :: Setter (EditorFactory a el b) (EditorFactory a el' b) el el'
+ Graphics.UI.Threepenny.Editors.Types: editorFactoryElement :: Setter (Editor a el b) (Editor a el' b) el el'
- Graphics.UI.Threepenny.Editors.Types: editorFactoryInput :: Setter (EditorFactory a el b) (EditorFactory a' el b) a' a
+ Graphics.UI.Threepenny.Editors.Types: editorFactoryInput :: Setter (Editor a el b) (Editor a' el b) a' a
- Graphics.UI.Threepenny.Editors.Types: editorFactoryOutput :: Setter (EditorFactory a el b) (EditorFactory a el b') b b'
+ Graphics.UI.Threepenny.Editors.Types: editorFactoryOutput :: Setter (Editor a el b) (Editor a el b') b b'
- Graphics.UI.Threepenny.Editors.Types: editorIdentity :: EditorFactory a el a -> EditorFactory (Identity a) el (Identity a)
+ Graphics.UI.Threepenny.Editors.Types: editorIdentity :: Editor a el a -> Editor (Identity a) el (Identity a)
- Graphics.UI.Threepenny.Editors.Types: editorJust :: EditorFactory (Maybe b) el (Maybe b) -> EditorFactory b el b
+ Graphics.UI.Threepenny.Editors.Types: editorJust :: Editor (Maybe b) el (Maybe b) -> Editor b el b
- Graphics.UI.Threepenny.Editors.Types: editorReadShow :: (Read a, Show a) => EditorFactory (Maybe a) TextEntry (Maybe a)
+ Graphics.UI.Threepenny.Editors.Types: editorReadShow :: (Read a, Show a) => Editor (Maybe a) TextEntry (Maybe a)
- Graphics.UI.Threepenny.Editors.Types: editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)
+ Graphics.UI.Threepenny.Editors.Types: editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- Graphics.UI.Threepenny.Editors.Types: editorString :: EditorFactory String TextEntry String
+ Graphics.UI.Threepenny.Editors.Types: editorString :: Editor String TextEntry String
- Graphics.UI.Threepenny.Editors.Types: editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, EditorFactory a el a)] -> (a -> tag) -> EditorFactory a Layout a
+ Graphics.UI.Threepenny.Editors.Types: editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, Editor a el a)] -> (a -> tag) -> Editor a Layout a
- Graphics.UI.Threepenny.Editors.Types: editorUnit :: EditorFactory b Element b
+ Graphics.UI.Threepenny.Editors.Types: editorUnit :: Editor b Element b
- Graphics.UI.Threepenny.Editors.Types: field :: Renderable m => String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out Layout a
+ Graphics.UI.Threepenny.Editors.Types: field :: Renderable m => String -> (out -> inn) -> Editor inn m a -> Editor out Layout a
- Graphics.UI.Threepenny.Editors.Types: fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out m' a
+ Graphics.UI.Threepenny.Editors.Types: fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> Editor inn m a -> Editor out m' a
- Graphics.UI.Threepenny.Editors.Types: withLayout :: (layout -> layout') -> EditorFactory a layout b -> EditorFactory a layout' b
+ Graphics.UI.Threepenny.Editors.Types: withLayout :: (layout -> layout') -> Editor a layout b -> Editor a layout' b

Files

+ examples/Parser.hs view
@@ -0,0 +1,86 @@+{-# OPTIONS_GHC -fno-warn-name-shadowing #-}+{-# LANGUAGE RecursiveDo #-}++module Main(main) where++import qualified Graphics.UI.Threepenny         as UI+import           Graphics.UI.Threepenny.Core+import           Graphics.UI.Threepenny.Editors++import           Control.Monad+import           Data.Maybe+import           Language.Haskell.Exts+++{-----------------------------------------------------------------------------+    Main+------------------------------------------------------------------------------}+main :: IO ()+main = startGUI defaultConfig setup++example :: String+example = unlines+    ["module Main(main) where"+    ,""+    ,"main :: IO ()"+    ,"main = putStrLn \"Hello World!\""+    ]+++parser :: ParseMode -> String -> String+parser mode x = case parseFileContentsWithMode mode x of+    ParseOk x       -> show $ Control.Monad.void x+    x@ParseFailed{} -> show x+++pMode :: UI (Element, Behavior ParseMode)+pMode = do+    filename <- UI.input+    language <- UI.select+        #+ [UI.option # set text (show x) | x <- knownLanguages]+        # set UI.selection (Just 0)+    ignore <- UI.input # set (attr "type") "checkbox"++    layout <- grid+        [[string "Filename", element filename]+        ,[string "Language", element language]+        ,[string "Ignore pragmas", element ignore]]++    filename <- stepper "" $ UI.valueChange filename+    language <- fmap (fmap ((!!) knownLanguages . fromMaybe 0)) $ stepper Nothing $ UI.selectionChange language+    ignore <- stepper False $ UI.checkedChange ignore++    let val = (\f l i -> defaultParseMode{parseFilename=f, baseLanguage=l, ignoreLanguagePragmas=i}) <$>+            filename <*> language <*> ignore+    return (layout, val)++pModeEditor :: Editor ParseMode Layout ParseMode+pModeEditor =+  (\f l i  -> defaultParseMode{parseFilename=f, baseLanguage=l, ignoreLanguagePragmas=i})+    <$> field "Filename" parseFilename editor+    -*- field "Language" baseLanguage (editorJust $ editorSelection (pure knownLanguages) (pure (string . show)))+    -*- field "Ignore pragmas" ignoreLanguagePragmas editor++pMode' :: UI (UI Element, Behavior ParseMode)+pMode' = mdo+  parseModeE <- create pModeEditor parseModeB+  parseModeB <- stepper defaultParseMode (edited parseModeE)+  return (render parseModeE, parseModeB)++setup :: Window -> UI ()+setup window = void $ do+    _ <- return window # set title "HSE parser"+    mode <- pMode+    mode2 <- pMode'++    source <- UI.textarea+        # set UI.style [("width","600px"),("height","250px")]+        # set value example+    sourceVal <- stepper example $ UI.valueChange source++    output <- UI.textarea+        # set UI.style [("width","600px"),("height","250px")]+        # set (attr "readonly") "readonly"+        # sink value (parser <$> snd mode <*> sourceVal)++    getBody window #+ [row [column [element source, element output], element $ fst mode, fst mode2]]
examples/Person.hs view
@@ -14,12 +14,14 @@ import           Data.Biapplicative import           Data.Default import           Data.Maybe-import qualified Generics.SOP                         as SOP-import           GHC.Generics+import qualified Generics.SOP                              as SOP+import           GHC.Generics                              (Generic) import           Graphics.UI.Threepenny.Core import           Graphics.UI.Threepenny.Editors import           Graphics.UI.Threepenny.Editors.Types+import           Graphics.UI.Threepenny.Editors.Validation import           Graphics.UI.Threepenny.Elements+import           Prelude                                   hiding (span)  main :: IO () main = startGUI defaultConfig setup@@ -37,6 +39,13 @@ type Person = PersonF Value type PersonEditor = PersonF Edit +instance Validable Person where+  validate Person{..}+    | null firstName = Invalid "First name cannot be null"+    | null lastName  = Invalid "Last name cannot be null"+    | Just x <- age, x <= 0 = Invalid "Age must be a natural number"+    | otherwise = Ok+ data LegalStatus   = Single   | Married@@ -63,7 +72,7 @@  -- | A manually defined editor for 'Education'. --   It is also possible to derive this 'Editor' via Generics.SOP, as done below.-editorEducation :: EditorFactory Education Layout Education+editorEducation :: Editor Education Layout Education editorEducation = do     let selector x = case x of             Other _ -> "Other"@@ -71,7 +80,7 @@     editorSum beside       [ ("Basic", const Basic <$> withSomeWidget editorUnit)       , ("Intermediate", const Intermediate <$> withSomeWidget editorUnit)-      , ("Other", dimapEF (fromMaybe "" . getOther) Other someEditor)+      , ("Other", dimapE (fromMaybe "" . getOther) Other someEditor)       ]       selector @@ -94,7 +103,7 @@ instance Default Person where def = Person Basic "First" "Last" (Just 18) def def  -- | An editor for 'Person' values that combines the 'Horizontal' and 'Vertical' layout builders-editorPersonHV :: EditorFactory Person Vertical Person+editorPersonHV :: Editor Person Vertical Person editorPersonHV = do   (firstName, lastName) <- withLayout Vertical $ construct $ do       firstName <- fieldLayout Horizontal "First:"     firstName editor@@ -111,7 +120,7 @@   return Person{..}  -- | An editor for 'Person' values that uses the 'Columns' layout builder-editorPersonColumns :: EditorFactory Person Columns Person+editorPersonColumns :: Editor Person Columns Person editorPersonColumns = do       firstName <- fieldLayout Next "First:"     firstName editor       lastName  <- fieldLayout Next "Last:"      lastName editor@@ -124,7 +133,7 @@  -- | A editor for 'Person' values with a fully fledged Widget type. --   The UI and layout are defined in the 'Renderable' instance for the widget.-personEditor :: EditorFactory Person PersonEditor Person+personEditor :: Editor Person PersonEditor Person personEditor =     bipure Person Person       <<*>> edit education editor@@ -151,24 +160,35 @@ setup :: Window -> UI () setup w = void $ mdo   _ <- return w # set title "Threepenny editors example"-  person1HV <- createEditor editorPersonHV person1B-  person1C <- createEditor editorPersonColumns person1B-  person2 <- createEditor editorGeneric person1B-  person3 <- createEditor personEditor person1B-  person1B <- stepper def (head <$> unions+  person1HV <- create editorPersonHV person1B+  person1C <- create editorPersonColumns person1B+  person2  <- create editorGeneric person1B+  person3e <- create personEditor person1B+  -- When using a biapplicative editor, we can set the attributes of the field editors after creation.+  _ <- element (firstName (_widgetControl person3e)) # set style [("background-color", "Blue")]+  person1B <- accumB def (updateIfValid . head <$> unions                             [ edited person1HV                             , edited person1C                             , edited person2-                            , edited person3+                            , edited person3e                             ]) +  -- We can attach validation to any editor+  validation <-+      stepper Ok (validate . head <$>+                  unions [ edited person1HV+                          , edited person1C+                          , edited person2+                          , edited person3e])+   getBody w #+ [grid-    [ [return $ _editorElement person1HV]+    [ [span # sink text (show <$> validation) # set style [("color", "red")]]+    , [render person1HV]     , [hr]-    , [return $ _editorElement person1C]+    , [render person1C]     , [hr]-    , [return $ _editorElement person2]+    , [render person2]     , [hr]-    , [return $ _editorElement person3]+    , [render person3e]     , [hr]     ]]
src/Graphics/UI/Threepenny/Editors.hs view
@@ -17,15 +17,18 @@ {-# OPTIONS_GHC -Wno-duplicate-exports  #-}  module Graphics.UI.Threepenny.Editors-  ( -- * Editors-    Editor(..)+  ( -- * Widgets+    GenericWidget(..)   , edited   , contents-  , editorElement-    -- * Editor factories-  , EditorFactory(Horizontally, horizontally, Vertically, vertically)+  , widgetControl+  , widgetTidings+    -- * Editors+  , Editor(Horizontally, horizontally, Vertically, vertically)   , someEditor-  , createEditor+  , create+  , lmapE+  , dimapE   , Editable(..)   , EditorWidgetFor(..)   , Field@@ -89,16 +92,16 @@   type family EditorWidget a   type EditorWidget a = Layout   -- | The editor factory-  editor :: EditorFactory a (EditorWidget a) a-  default editor :: (Generic a, HasDatatypeInfo a, (All (All Editable `And` All Default) (Code a)), EditorWidget a ~ Layout) => EditorFactory a (EditorWidget a) a+  editor :: Editor a (EditorWidget a) a+  default editor :: (Generic a, HasDatatypeInfo a, (All (All Editable `And` All Default) (Code a)), EditorWidget a ~ Layout) => Editor a (EditorWidget a) a   editor = editorGeneric  -- | Conceal the widget type of some 'Editor'-withSomeWidget :: Renderable w => EditorFactory a w b -> EditorFactory a Layout b+withSomeWidget :: Renderable w => Editor a w b -> Editor a Layout b withSomeWidget = first getLayout  -- | A version of 'editor' with a concealed widget type.-someEditor :: Editable a => EditorFactory a Layout a+someEditor :: Editable a => Editor a Layout a someEditor = withSomeWidget editor  -- | A container for 'EditorWidget'.@@ -148,7 +151,7 @@  instance (Editable a, Editable b) => Editable (a,b) where   type EditorWidget (a,b) = EditorWidget a |*| EditorWidget b-  editor = bipure (:|*|) (,) <<*>> lmapEF fst editor <<*>> lmapEF snd editor+  editor = bipure (:|*|) (,) <<*>> lmapE fst editor <<*>> lmapE snd editor  instance Editable a => Editable (Identity a) where   type EditorWidget (Identity a) = EditorWidget a@@ -161,38 +164,38 @@ editorGenericSimple   :: forall a xs.      (Generic a, HasDatatypeInfo a, All Editable xs, Code a ~ '[xs])-  => EditorFactory a Layout a-editorGenericSimple = dimapEF from to $ editorGenericSimple' (datatypeInfo(Proxy @ a))+  => Editor a Layout a+editorGenericSimple = dimapE from to $ editorGenericSimple' (datatypeInfo(Proxy @ a))  editorGenericSimple'   :: forall xs.      (All Editable xs)-  => DatatypeInfo '[xs] -> EditorFactory (SOP I '[xs]) Layout (SOP I '[xs])+  => DatatypeInfo '[xs] -> Editor (SOP I '[xs]) Layout (SOP I '[xs]) editorGenericSimple' (ADT _ _ (c :* Nil)) = constructorEditorFor c editorGenericSimple' (Newtype _ _ c)      = constructorEditorFor c  constructorEditorFor   :: (All Editable xs)   => ConstructorInfo xs-  -> EditorFactory (SOP I '[xs]) Layout (SOP I '[xs])-constructorEditorFor (Record _ fields) = dimapEF (unZ . unSOP) (SOP . Z) $ constructorEditorFor' fields-constructorEditorFor (Constructor _) = dimapEF (unZ . unSOP) (SOP . Z) someEditor-constructorEditorFor Infix{} = dimapEF (unZ . unSOP) (SOP . Z) someEditor+  -> Editor (SOP I '[xs]) Layout (SOP I '[xs])+constructorEditorFor (Record _ fields) = dimapE (unZ . unSOP) (SOP . Z) $ constructorEditorFor' fields+constructorEditorFor (Constructor _) = dimapE (unZ . unSOP) (SOP . Z) someEditor+constructorEditorFor Infix{} = dimapE (unZ . unSOP) (SOP . Z) someEditor  -- | A generic editor for SOP types. editorGeneric   :: forall a .      (Generic a, HasDatatypeInfo a, (All (All Editable `And` All Default) (Code a)))-  => EditorFactory a Layout a-editorGeneric = dimapEF from to $ editorGeneric' (datatypeInfo(Proxy @ a))+  => Editor a Layout a+editorGeneric = dimapE from to $ editorGeneric' (datatypeInfo(Proxy @ a))  editorGeneric'   :: forall xx.      (All (All Editable `And` All Default) xx)-  => DatatypeInfo xx -> EditorFactory (SOP I xx) Layout (SOP I xx)+  => DatatypeInfo xx -> Editor (SOP I xx) Layout (SOP I xx) editorGeneric' (ADT _ _ (c :* Nil)) = constructorEditorFor c editorGeneric' (ADT _ _ cc) = editorSum above editors constructor where-  editors :: [(Tag, EditorFactory (SOP I xx) Layout (SOP I xx))]+  editors :: [(Tag, Editor (SOP I xx) Layout (SOP I xx))]   editors = first Tag <$> constructorEditorsFor cc   constructors = hmap (K . constructorName) cc   constructor a = Tag $ hcollapse $ hliftA2 const constructors (unSOP a)@@ -203,7 +206,7 @@  constructorEditorsFor   :: forall xx . (All (All Editable `And` All Default) xx)-  => NP ConstructorInfo xx -> [(String, EditorFactory (SOP I xx) Layout (SOP I xx))]+  => NP ConstructorInfo xx -> [(String, Editor (SOP I xx) Layout (SOP I xx))] constructorEditorsFor cc =   hcollapse $ hcliftA3 p (\c i p -> (constructorName c,) `mapKK` constructorEditorForUnion c i p) cc     (injections  :: NP (Injection  (NP I) xx) xx)@@ -216,24 +219,24 @@   => ConstructorInfo xs   -> Injection (NP I) xx xs   -> Projection (Compose Maybe (NP I)) xx xs-  -> K (EditorFactory (SOP I xx) Layout (SOP I xx)) xs-constructorEditorForUnion (Constructor _) inj prj = K $ composeEditorFactory inj prj editor-constructorEditorForUnion Infix{} inj prj = K $ composeEditorFactory inj prj editor-constructorEditorForUnion (Record _ fields) inj prj = K $ composeEditorFactory inj prj $ constructorEditorFor' fields+  -> K (Editor (SOP I xx) Layout (SOP I xx)) xs+constructorEditorForUnion (Constructor _) inj prj = K $ composeEditor inj prj editor+constructorEditorForUnion Infix{} inj prj = K $ composeEditor inj prj editor+constructorEditorForUnion (Record _ fields) inj prj = K $ composeEditor inj prj $ constructorEditorFor' fields -composeEditorFactory+composeEditor   :: forall xss xs.     (SListI xss, All Default xs) =>      Injection (NP I) xss xs   -> Projection (Compose Maybe (NP I)) xss xs-  -> EditorFactory (NP I xs) Layout (NP I xs)-  -> EditorFactory (SOP I xss) Layout (SOP I xss)-composeEditorFactory (Fn inj) (Fn prj) = dimapEF f (SOP . unK . inj)+  -> Editor (NP I xs) Layout (NP I xs)+  -> Editor (SOP I xss) Layout (SOP I xss)+composeEditor (Fn inj) (Fn prj) = dimapE f (SOP . unK . inj)   where     f :: SOP I xss -> NP I xs     f = fromMaybe def . getCompose . prj . K . hexpand (Compose Nothing) . hmap (Compose . Just) . unSOP -constructorEditorFor' :: (SListI xs, All Editable xs) => NP FieldInfo xs -> EditorFactory (NP I xs) Layout (NP I xs)+constructorEditorFor' :: (SListI xs, All Editable xs) => NP FieldInfo xs -> Editor (NP I xs) Layout (NP I xs) constructorEditorFor' fields = vertically $ hsequence $ hliftA Vertically $ fieldsEditor (hliftA (K . fieldName) fields)  -- | Tuple editor without fields@@ -241,15 +244,15 @@   type EditorWidget (NP I xs) = Layout   editor = horizontally $ hsequence $ hliftA Horizontally tupleEditor -tupleEditor :: forall xs . All Editable xs => NP (EditorFactory (NP I xs) Layout) xs+tupleEditor :: forall xs . All Editable xs => NP (Editor (NP I xs) Layout) xs tupleEditor = go id sList where-  go :: forall ys. All Editable ys => (forall f . NP f xs -> NP f ys) -> SList ys -> NP (EditorFactory (NP I xs) Layout) ys+  go :: forall ys. All Editable ys => (forall f . NP f xs -> NP f ys) -> SList ys -> NP (Editor (NP I xs) Layout) ys   go _ SNil  = Nil-  go f SCons = lmapEF (unI . hd . f) someEditor :* go (tl . f) sList+  go f SCons = lmapE (unI . hd . f) someEditor :* go (tl . f) sList -fieldsEditor :: forall xs . All Editable xs => NP (K String) xs -> NP (EditorFactory (NP I xs) Layout) xs+fieldsEditor :: forall xs . All Editable xs => NP (K String) xs -> NP (Editor (NP I xs) Layout) xs fieldsEditor = go id sList where-  go :: forall ys. All Editable ys => (forall f . NP f xs -> NP f ys) -> SList ys -> NP (K String) ys -> NP (EditorFactory (NP I xs) Layout) ys+  go :: forall ys. All Editable ys => (forall f . NP f xs -> NP f ys) -> SList ys -> NP (K String) ys -> NP (Editor (NP I xs) Layout) ys   go _ SNil Nil = Nil   go f SCons (K fn :* xs) = field (toFieldLabel fn) (unI . hd . f) someEditor :* go (tl . f) sList xs 
src/Graphics/UI/Threepenny/Editors/Types.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE DataKinds       #-} {-# LANGUAGE DeriveFunctor   #-} {-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections   #-} {-# LANGUAGE ViewPatterns    #-} {-# OPTIONS_GHC -Wno-name-shadowing     #-}@@ -8,21 +9,21 @@  module Graphics.UI.Threepenny.Editors.Types   (-  -- * Editors-    Editor(..)+  -- * GenericWidgets+    GenericWidget(..)   , edited   , contents-  , editorElement-  , EditorFactory(.., Horizontally, horizontally, Vertically, vertically)-  , dimapEF-  , lmapEF-  , applyEF-  , createEditor-  , renderEditor+  , widgetControl+  , widgetTidings+  , liftElement+  , Editor(.., Horizontally, horizontally, Vertically, vertically)+  , dimapE+  , lmapE+  , applyE   , editorFactoryElement   , editorFactoryInput   , editorFactoryOutput-    -- ** Editor composition+    -- ** GenericWidget composition   , (|*|), (|*), (*|)   , (-*-), (-*), (*-)   , field@@ -30,7 +31,7 @@   , edit   , pattern Horizontally   , pattern Vertically-    -- ** Editor constructors+    -- ** GenericWidget constructors   , editorUnit   , editorIdentity   , editorString@@ -40,7 +41,7 @@   , editorSelection   , editorSum   , editorJust-    -- ** Editor layout+    -- ** GenericWidget layout   , withLayout   , construct   ) where@@ -60,103 +61,104 @@ import           Text.Read  -- | A widget for editing values of type @a@.-data Editor editorElement a = Editor-  { _editorTidings :: Tidings a-  , _editorElement :: editorElement+data GenericWidget control a = GenericWidget+  { _widgetTidings :: Tidings a+  , _widgetControl :: control   }   deriving Functor -instance Bifunctor Editor where-  bimap f g (Editor t e) = Editor (g <$> t) (f e)+makeLenses ''GenericWidget --- | A lens over the 'editorElement' field-editorElement :: Lens (Editor el a) (Editor el' a) el el'-editorElement f (Editor t el) = Editor t <$> f el+instance Bifunctor GenericWidget where+  bimap f g (GenericWidget t e) = GenericWidget (g <$> t) (f e) -edited :: Editor el a -> Event a-edited = rumors . _editorTidings+edited :: GenericWidget el a -> Event a+edited = rumors . _widgetTidings -contents :: Editor el a -> Behavior a-contents = facts . _editorTidings+contents :: GenericWidget el a -> Behavior a+contents = facts . _widgetTidings -instance Widget el => Widget (Editor el a) where-  getElement = getElement . _editorElement+instance Widget el => Widget (GenericWidget el a) where+  getElement = getElement . _widgetControl -renderEditor :: Renderable w => Editor w a -> UI (Editor Element a)-renderEditor = mapMOf editorElement render+instance Renderable el => Renderable (GenericWidget el a) where+  render = render . _widgetControl++renderEditor :: Renderable w => GenericWidget w a -> UI (GenericWidget Element a)+renderEditor = mapMOf widgetControl render   where     mapMOf l cmd = unwrapMonad . l (WrapMonad . cmd) --- | Create an editor to display the argument.---   User edits are fed back via the 'edited' 'Event'.-createEditor :: Renderable w => EditorFactory a w b -> Behavior a -> UI (Editor Element b)-createEditor e b = runEF e b >>= renderEditor---- | A function from 'Behavior' @a@ to 'Editor' @b@+-- | A function from 'Behavior' @a@ to 'GenericWidget' @b@ --   All the three type arguments are functorial, but @a@ is contravariant.---   'EditorFactory' is a 'Biapplicative' functor on @el@ and @b@, and+--   'Editor' is a 'Biapplicative' functor on @el@ and @b@, and --   a 'Profunctor' on @a@ and @b@.-newtype EditorFactory a el b = EF {runEF :: Behavior a -> UI (Editor el b)}+newtype Editor a el b = Editor {+  -- | Create an editor to display the argument.+  --   User edits are fed back via the 'edited' 'Event'.+  create :: Behavior a -> UI (GenericWidget el b)+  } -_EditorFactory :: Iso (EditorFactory a el b) (EditorFactory a' el' b') (Behavior a -> UI (Editor el b)) (Behavior a' -> UI (Editor el' b'))-_EditorFactory = iso runEF EF+_Editor :: Iso (Editor a el b) (Editor a' el' b') (Behavior a -> UI (GenericWidget el b)) (Behavior a' -> UI (GenericWidget el' b'))+_Editor = iso create Editor  -- | A 'Setter' over the element of the editor being built-editorFactoryElement :: Setter (EditorFactory a el b) (EditorFactory a el' b) el el'-editorFactoryElement = _EditorFactory.mapped.mapped.editorElement+editorFactoryElement :: Setter (Editor a el b) (Editor a el' b) el el'+editorFactoryElement = _Editor.mapped.mapped.widgetControl  -- | A 'Setter' over the input thing-editorFactoryInput :: Setter (EditorFactory a el b) (EditorFactory a' el b) a' a-editorFactoryInput = _EditorFactory.argument.mapped+editorFactoryInput :: Setter (Editor a el b) (Editor a' el b) a' a+editorFactoryInput = _Editor.argument.mapped  -- | A 'Setter' over the output thing-editorFactoryOutput :: Setter (EditorFactory a el b) (EditorFactory a el b') b b'-editorFactoryOutput = _EditorFactory.mapped.mapped.mapped+editorFactoryOutput :: Setter (Editor a el b) (Editor a el b') b b'+editorFactoryOutput = _Editor.mapped.mapped.mapped -liftElement :: UI el -> EditorFactory a el ()-liftElement el = EF $ \_ -> Editor (pure ()) <$> el+-- | Lift an HTML element into a vacuous editor.+liftElement :: UI el -> Editor a el ()+liftElement el = Editor $ \_ -> GenericWidget (pure ()) <$> el -bimapEF :: (el -> el') -> (b -> b') -> EditorFactory a el b -> EditorFactory a el' b'-bimapEF g h = EF . fmap (fmap (bimap g h)) . runEF+bimapEditor :: (el -> el') -> (b -> b') -> Editor a el b -> Editor a el' b'+bimapEditor g h = Editor . fmap (fmap (bimap g h)) . create -dimapEF :: (a' -> a) -> (b -> b') -> EditorFactory a el b -> EditorFactory a' el b'-dimapEF g h (EF f) = EF $ \b -> getCompose $ h <$> Compose (f (g <$> b))+dimapE :: (a' -> a) -> (b -> b') -> Editor a el b -> Editor a' el b'+dimapE g h (Editor f) = Editor $ \b -> getCompose $ h <$> Compose (f (g <$> b))  -- | Applies a function over the input-lmapEF :: (a' -> a) -> EditorFactory a el b -> EditorFactory a' el b-lmapEF f = dimapEF f id+lmapE :: (a' -> a) -> Editor a el b -> Editor a' el b+lmapE f = dimapE f id  -- | Focus the editor on the field retrieved by the getter. --   Use when composing editors via the Biapplicative interface ----- > personEditor :: EditorFactory Person PersonEditor Person+-- > personEditor :: Editor Person PersonEditor Person -- > personEditor = -- >     bipure Person Person -- >       <<*>> edit education editor -- >       <<*>> edit firstName editor -- >       <<*>> edit lastName  editor-edit :: (a' -> a) -> EditorFactory a el b -> EditorFactory a' el b-edit = lmapEF+edit :: (a' -> a) -> Editor a el b -> Editor a' el b+edit = lmapE -applyEF :: (el1 -> el2 -> el) -> EditorFactory in_ el1 (a -> b) -> EditorFactory in_ el2 a -> EditorFactory in_ el b-applyEF combineElements a b = EF $ \s -> do-    a <- runEF a s-    b <- runEF b s-    return $ Editor (_editorTidings a <*> _editorTidings b) (_editorElement a `combineElements` _editorElement b)+applyE :: (el1 -> el2 -> el) -> Editor in_ el1 (a -> b) -> Editor in_ el2 a -> Editor in_ el b+applyE combineElements a b = Editor $ \s -> do+    a <- create a s+    b <- create b s+    return $ GenericWidget (_widgetTidings a <*> _widgetTidings b) (_widgetControl a `combineElements` _widgetControl b) -instance Functor (EditorFactory a el) where-  fmap = dimapEF id+instance Functor (Editor a el) where+  fmap = dimapE id -instance Bifunctor (EditorFactory a) where-  bimap = bimapEF+instance Bifunctor (Editor a) where+  bimap = bimapEditor -instance Biapplicative (EditorFactory a) where-  bipure w o = EF $ \_ -> return $ Editor (pure o) w-  (<<*>>) = applyEF ($)+instance Biapplicative (Editor a) where+  bipure w o = Editor $ \_ -> return $ GenericWidget (pure o) w+  (<<*>>) = applyE ($) -instance Monoid el => Applicative (EditorFactory a el) where+instance Monoid el => Applicative (Editor a el) where   pure = bipure mempty-  (<*>) = applyEF mappend+  (<*>) = applyE mappend  -- | Applicative modifier for vertical composition of editor factories. --   This can be used in conjunction with ApplicativeDo as:@@ -168,7 +170,7 @@ -- >       return Person{..} -- -- DEPRECATED: Use the 'Vertical' layout builder instead-pattern Vertically :: EditorFactory a Layout b -> EditorFactory a Vertical b+pattern Vertically :: Editor a Layout b -> Editor a Vertical b pattern Vertically {vertically} <- (withLayout getVertical -> vertically) where Vertically a = withLayout Vertical a  -- | Applicative modifier for horizontal composition of editor factories.@@ -181,109 +183,109 @@ -- >       return Person{..} -- -- DEPRECATED: Use the 'Horizontal' layout builder instead-pattern Horizontally :: EditorFactory a Layout b -> EditorFactory a Horizontal b+pattern Horizontally :: Editor a Layout b -> Editor a Horizontal b pattern Horizontally {horizontally} <- (withLayout getHorizontal -> horizontally) where Horizontally a = withLayout Horizontal a  infixl 4 |*|, -*- infixl 5 |*, *|, -*, *-  -- | Apply a layout builder.-withLayout :: (layout -> layout') -> EditorFactory a layout b -> EditorFactory a layout' b+withLayout :: (layout -> layout') -> Editor a layout b -> Editor a layout' b withLayout = over editorFactoryElement  -- | Construct a concrete 'Layout'. Useful when combining heterogeneours layout builders.-construct :: Renderable m => EditorFactory a m b -> EditorFactory a Layout b+construct :: Renderable m => Editor a m b -> Editor a Layout b construct = withLayout getLayout  -- | Left-right editor composition-(|*|) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a+(|*|) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a a |*| b = withLayout getHorizontal $ withLayout Horizontal a <*> withLayout Horizontal b --- | Left-right composition of an editorElement with a editor-(*|) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a+-- | Left-right composition of an element with a editor+(*|) :: UI Element -> Editor s Layout a -> Editor s Layout a e *| a = withLayout getHorizontal $ liftElement(return $ horizontal e) *> withLayout Horizontal a --- | Left-right composition of an editorElement with a editor-(|*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a+-- | Left-right composition of an element with a editor+(|*) :: Editor s Layout a -> UI Element -> Editor s Layout a a |* e = withLayout getHorizontal $ withLayout Horizontal a <* liftElement(return $ horizontal e)  -- | Left-right editor composition-(-*-) :: EditorFactory s Layout (b -> a) -> EditorFactory s Layout b -> EditorFactory s Layout a+(-*-) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a a -*- b = withLayout getVertical $ withLayout Vertical a <*> withLayout Vertical b --- | Left-right composition of an editorElement with a editor-(*-) :: UI Element -> EditorFactory s Layout a -> EditorFactory s Layout a+-- | Left-right composition of an element with a editor+(*-) :: UI Element -> Editor s Layout a -> Editor s Layout a e *- a = withLayout getVertical $ liftElement(return $ vertical e) *> withLayout Vertical a --- | Left-right composition of an editorElement with a editor-(-*) :: EditorFactory s Layout a -> UI Element -> EditorFactory s Layout a+-- | Left-right composition of an element with a editor+(-*) :: Editor s Layout a -> UI Element -> Editor s Layout a a -* e = withLayout getVertical $ withLayout Vertical a <* liftElement(return $ vertical e)  -- | A helper that arranges a label with the field name --   and the editor horizontally. This version takes a Layout builder as well.-fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out m' a-fieldLayout l name f e = withLayout l (string name *| first getLayout (dimapEF f id e))+fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> Editor inn m a -> Editor out m' a+fieldLayout l name f e = withLayout l (string name *| first getLayout (dimapE f id e))  -- | A helper that arranges a label with the field name --   and the editor horizontally.-field :: Renderable m => String -> (out -> inn) -> EditorFactory inn m a -> EditorFactory out Layout a-field name f e = string name *| first getLayout (dimapEF f id e)+field :: Renderable m => String -> (out -> inn) -> Editor inn m a -> Editor out Layout a+field name f e = string name *| first getLayout (dimapE f id e) -editorUnit :: EditorFactory b Element b-editorUnit = EF $ \b -> do+editorUnit :: Editor b Element b+editorUnit = Editor $ \b -> do     t <- new-    return $ Editor (tidings b never) t+    return $ GenericWidget (tidings b never) t -editorCheckBox :: EditorFactory Bool Element Bool-editorCheckBox = EF $ \b -> do+editorCheckBox :: Editor Bool Element Bool+editorCheckBox = Editor $ \b -> do     t <- sink checked b $ input # set type_ "checkbox"-    return $ Editor (tidings b $ checkedChange t) t+    return $ GenericWidget (tidings b $ checkedChange t) t -editorString :: EditorFactory String TextEntry String-editorString = EF $ \b -> do+editorString :: Editor String TextEntry String+editorString = Editor $ \b -> do     w <- askWindow     t <- entry b     liftIOLater $ do       initialValue <- currentValue b       _ <- runUI w $ set value initialValue (element t)       return ()-    return $ Editor (userText t) t+    return $ GenericWidget (userText t) t -editorReadShow :: (Read a, Show a) => EditorFactory (Maybe a) TextEntry (Maybe a)-editorReadShow = EF $ \b -> do-    e <- runEF editorString (maybe "" show <$> b)+editorReadShow :: (Read a, Show a) => Editor (Maybe a) TextEntry (Maybe a)+editorReadShow = Editor $ \b -> do+    e <- create editorString (maybe "" show <$> b)     let readIt "" = Nothing         readIt x  = readMaybe x     let t = tidings b (readIt <$> edited e)-    return $ Editor t (_editorElement e)+    return $ GenericWidget t (_widgetControl e)  -- An editor that presents a choice of values. editorEnumBounded   :: (Bounded a, Enum a, Ord a, Show a)-  => Behavior(a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)+  => Behavior(a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a) editorEnumBounded = editorSelection (pure $ enumFrom minBound)  -- | An editor that presents a dynamic choice of values. editorSelection   :: Ord a-  => Behavior [a] -> Behavior(a -> UI Element) -> EditorFactory (Maybe a) (ListBox a) (Maybe a)-editorSelection options display = EF $ \b -> do+  => Behavior [a] -> Behavior(a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)+editorSelection options display = Editor $ \b -> do   l <- listBox options b display-  return $ Editor (tidings b (rumors $ userSelection l)) l+  return $ GenericWidget (tidings b (rumors $ userSelection l)) l  -- | Ignores 'Nothing' values and only updates for 'Just' values-editorJust :: EditorFactory (Maybe b) el (Maybe b) -> EditorFactory b el b-editorJust (EF editor) = EF $ \b -> do+editorJust :: Editor (Maybe b) el (Maybe b) -> Editor b el b+editorJust (Editor editor) = Editor $ \b -> do   e <- editor (Just <$> b)   let ev = filterJust (edited e)-  return $ Editor (tidings b ev) (_editorElement e)+  return $ GenericWidget (tidings b ev) (_widgetControl e)  -- | An editor for union types, built from editors for its constructors. editorSum   :: (Ord tag, Show tag, Renderable el)-  => (Layout -> Layout -> Layout) -> [(tag, EditorFactory a el a)] -> (a -> tag) -> EditorFactory a Layout a-editorSum combineLayout options selector = EF $ \ba -> do-  options <- mapM (\(tag, EF mk) -> (tag,) <$> (mk ba >>= renderEditor)) options+  => (Layout -> Layout -> Layout) -> [(tag, Editor a el a)] -> (a -> tag) -> Editor a Layout a+editorSum combineLayout options selector = Editor $ \ba -> do+  options <- mapM (\(tag, Editor mk) -> (tag,) <$> (mk ba >>= renderEditor)) options   let tag = selector <$> ba   tag' <- calmB tag   let build a = lookup a options@@ -291,7 +293,7 @@   l <- listBox (pure $ fmap fst options) (Just <$> tag) (pure (string . show))   -- a placeholder for the constructor editor   nestedEditor <--    new # sink children ((\x -> [maybe (error "editorSum") _editorElement (build x)]) <$> tag')+    new # sink children ((\x -> [maybe (error "editorSum") _widgetControl (build x)]) <$> tag')   --   let composed = combineLayout (Single (return $ getElement l)) (Single $ return nestedEditor)   -- the result event fires when any of the nested editors or the tag selector fire.@@ -300,7 +302,7 @@       taggedOptions = sequenceA [(tag, ) <$> contents e | (tag, e) <- options]       editedTag = filterJust $ flip lookup <$> taggedOptions <@> eTag       editedE = head <$> unions (editedTag : editedEvents)-  return $ Editor (tidings ba editedE) composed+  return $ GenericWidget (tidings ba editedE) composed -editorIdentity :: EditorFactory a el a -> EditorFactory (Identity a) el (Identity a)-editorIdentity = dimapEF runIdentity Identity+editorIdentity :: Editor a el a -> Editor (Identity a) el (Identity a)+editorIdentity = dimapE runIdentity Identity
+ src/Graphics/UI/Threepenny/Editors/Validation.hs view
@@ -0,0 +1,24 @@+module Graphics.UI.Threepenny.Editors.Validation+  ( ValidationResult(..)+  , Validable(..)+  , isValid+  , updateIfValid+  ) where++data ValidationResult = Ok | Invalid String+instance Show ValidationResult where+  show Ok            = ""+  show (Invalid msg) = msg++class Validable a where+  validate :: a -> ValidationResult++isValid :: Validable a => a -> Bool+isValid x+  | Ok <- validate x = True+  | otherwise = False++updateIfValid :: Validable a => a -> a -> a+updateIfValid new old+  | isValid new = new+  | otherwise   = old
threepenny-editors.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           threepenny-editors-version:        0.5.1+version:        0.5.2 synopsis:       Composable algebraic editors description:    This package provides a type class 'Editable' and combinators to                 easily put together form-like editors for algebraic datatypes.@@ -50,10 +50,32 @@       Graphics.UI.Threepenny.Editors.Layout       Graphics.UI.Threepenny.Editors.Utils       Graphics.UI.Threepenny.Editors.Types+      Graphics.UI.Threepenny.Editors.Validation   other-modules:       Paths_threepenny_editors   default-language: Haskell2010 +executable parser+  main-is: Parser.hs+  hs-source-dirs:+      examples+  ghc-options: -Wall -Wno-name-shadowing+  if flag(buildExamples)+    build-depends:+        base+      , bifunctors+      , data-default+      , generics-sop+      , profunctors+      , threepenny-gui+      , threepenny-editors+      , haskell-src-exts+  else+    buildable: False+  other-modules:+      Person+  default-language: Haskell2010+ executable person   main-is: Person.hs   hs-source-dirs:@@ -70,4 +92,6 @@       , threepenny-editors   else     buildable: False+  other-modules:+      Parser   default-language: Haskell2010