Safe Haskell | None |
---|---|
Language | Haskell2010 |
- data GenericWidget control a = GenericWidget {
- widgetTidings :: Tidings a
- widgetControl :: control
- edited :: GenericWidget el a -> Event a
- contents :: GenericWidget el a -> Behavior a
- data Editor a el b
- someEditor :: Editable a => Editor a Layout a
- create :: Editor a el b -> Behavior a -> UI (GenericWidget el b)
- edit :: (a' -> a) -> Editor a el b -> Editor a' el b
- lmapE :: (a' -> a) -> Editor a el b -> Editor a' el b
- dimapE :: (a' -> a) -> (b -> b') -> Editor a el b -> Editor a' el b'
- class Renderable (EditorWidget a) => Editable a where
- type EditorWidget a
- data EditorWidgetFor a where
- EditorWidgetFor :: Editable a => EditorWidget a -> EditorWidgetFor a
- type family Field (usage :: Usage) a where ...
- data Usage
- (|*|) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- (|*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- (*|) :: UI Element -> Editor s Layout a -> Editor s Layout a
- (-*-) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a
- (-*) :: Editor s Layout a -> UI Element -> Editor s Layout a
- (*-) :: UI Element -> Editor s Layout a -> Editor s Layout a
- field :: Renderable m => String -> (out -> inn) -> Editor inn m a -> Editor out Layout a
- fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> Editor inn m a -> Editor out m' a
- pattern Horizontally :: forall a b. Editor a Layout b -> Editor a Horizontal b
- pattern Vertically :: forall a b. Editor a Layout b -> Editor a Vertical b
- withLayout :: (layout -> layout') -> Editor a layout b -> Editor a layout' b
- withSomeWidget :: Renderable w => Editor a w b -> Editor a Layout b
- construct :: Renderable m => Editor a m b -> Editor a Layout b
- editorUnit :: Editor b Element b
- editorIdentity :: Editor a el a -> Editor (Identity a) el (Identity a)
- editorReadShow :: (Read a, Show a) => Editor (Maybe a) TextEntry (Maybe a)
- editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a)
- editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, Editor a el a)] -> (a -> tag) -> Editor a Layout a
- editorJust :: Editor (Maybe b) el (Maybe b) -> Editor b el b
- editorGeneric :: forall a. (Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a)) => Editor a Layout a
- editorGenericSimple :: forall a xs. (Generic a, HasDatatypeInfo a, All Editable xs, Code a ~ '[xs]) => Editor a Layout a
- editorGenericSimpleBi :: forall xs typ. (Generic (typ Value), Generic (typ Edit), All Editable xs, Code (typ Value) ~ '[xs], Code (typ Edit) ~ '[EditorWidgetsFor xs]) => Editor (typ Value) (typ Edit) (typ Value)
- data Layout
- above :: Layout -> Layout -> Layout
- beside :: Layout -> Layout -> Layout
- newtype Vertical = Vertical {}
- newtype Horizontal = Horizontal {}
- data Columns
- data a |*| b = a :|*| b
- data a -*- b = a :-*- b
- class Renderable w where
- renderGeneric :: forall a xs. (Generic a, HasDatatypeInfo a, All Renderable xs, Code a ~ '[xs]) => a -> UI Element
- getLayoutGeneric :: forall a xs. (Generic a, HasDatatypeInfo a, All Renderable xs, Code a ~ '[xs]) => a -> [[Layout]]
- class Validable a where
- data ValidationResult
- ok :: ValidationResult
- fromWarnings :: [String] -> ValidationResult
- getWarnings :: ValidationResult -> [String]
- isValid :: Validable a => a -> Bool
- updateIfValid :: Validable a => a -> a -> a
Widgets
data GenericWidget control a Source #
A widget for editing values of type a
.
GenericWidget | |
|
Bifunctor GenericWidget Source # | |
Functor (GenericWidget control) Source # | |
Widget el => Widget (GenericWidget el a) Source # | |
Renderable el => Renderable (GenericWidget el a) Source # | |
edited :: GenericWidget el a -> Event a Source #
contents :: GenericWidget el a -> Behavior a Source #
Editors
A widget el
for editing b
values while displaying a
values.
For obvious reasons, a
and b
are usually the same type, except while composing editors.
All the three type arguments are functorial, but a
is contravariant.
Editor
is a Biapplicative
functor on el
and b
, and a Profunctor
on a
and b
.
Editors compose using the Applicative interface when el
is monoidal
or more generally with the Biapplicative interface. In both cases the
Profunctor lmap
is used to select the value to display.
For an example of the Applicative interface, let's assemble the editor for a tuple of values:
editorTuple = (,) <$> lmap fst editable <*> lmap snd editable
someEditor :: Editable a => Editor a Layout a Source #
A version of editor
with a concealed widget type.
edit :: (a' -> a) -> Editor a el b -> Editor a' el b Source #
Use when composing Biapplicative editors to focus on a field.
personEditor :: Editor Person PersonEditor Person personEditor = bipure Person Person <<*>> edit education editor <<*>> edit firstName editor <<*>> edit lastName editor
class Renderable (EditorWidget a) => Editable a where Source #
The class of Editable
datatypes.
.
Define your own instance by using the Applicative
composition operators or
derive it via SOP
.
type EditorWidget a Source #
editor :: Editor a (EditorWidget a) a Source #
The editor factory
editor :: (Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a), EditorWidget a ~ Layout) => Editor a (EditorWidget a) a Source #
The editor factory
Editable Bool Source # | |
Editable Double Source # | |
Editable Int Source # | |
Editable () Source # | |
(~) * a Char => Editable [a] Source # | |
Editable (Maybe Double) Source # | |
Editable (Maybe Int) Source # | |
Editable a => Editable (Identity a) Source # | |
(Editable a, Editable b) => Editable (a, b) Source # | |
All * Editable xs => Editable (NP * I xs) Source # | Tuple editor without fields |
data EditorWidgetFor a where Source #
A container for EditorWidget
.
EditorWidgetFor :: Editable a => EditorWidget a -> EditorWidgetFor a |
type family Field (usage :: Usage) a where ... Source #
Type level fields. Use this helper to define EditorWidget types. Example:
data PersonF (usage :: Usage) = Person { education :: Field usage Education , firstName, lastName :: Field usage String , age :: Field usage (Maybe Int)
type Person = PersonF Value type PersonEditor = PersonF Edit
Field Value a = a | |
Field Edit a = EditorWidget a |
Editor composition
(|*|) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a infixl 4 Source #
Left-right editor composition
(|*) :: Editor s Layout a -> UI Element -> Editor s Layout a infixl 5 Source #
Left-right composition of an element with a editor
(*|) :: UI Element -> Editor s Layout a -> Editor s Layout a infixl 5 Source #
Left-right composition of an element with a editor
(-*-) :: Editor s Layout (b -> a) -> Editor s Layout b -> Editor s Layout a infixl 4 Source #
Left-right editor composition
(-*) :: Editor s Layout a -> UI Element -> Editor s Layout a infixl 5 Source #
Left-right composition of an element with a editor
(*-) :: UI Element -> Editor s Layout a -> Editor s Layout a infixl 5 Source #
Left-right composition of an element with a editor
field :: Renderable m => String -> (out -> inn) -> Editor inn m a -> Editor out Layout a Source #
A helper that arranges a label with the field name and the editor horizontally.
fieldLayout :: (Renderable m, Renderable m') => (Layout -> m') -> String -> (out -> inn) -> Editor inn m a -> Editor out m' a Source #
A helper that arranges a label with the field name and the editor horizontally. This version takes a Layout builder as well.
pattern Horizontally :: forall a b. Editor a Layout b -> Editor a Horizontal b Source #
Applicative modifier for horizontal composition of editor factories. This can be used in conjunction with ApplicativeDo as:
editorPerson = horizontally $ do firstName <- Horizontally $ field "First:" firstName editor lastName <- Horizontally $ field "Last:" lastName editor age <- Horizontally $ field "Age:" age editor return Person{..}
DEPRECATED: Use the Horizontal
layout builder instead
pattern Vertically :: forall a b. Editor a Layout b -> Editor a Vertical b Source #
Applicative modifier for vertical composition of editor factories. This can be used in conjunction with ApplicativeDo as:
editorPerson = vertically $ do firstName <- Vertically $ field "First:" firstName editor lastName <- Vertically $ field "Last:" lastName editor age <- Vertically $ field "Age:" age editor return Person{..}
DEPRECATED: Use the Vertical
layout builder instead
Editor layout
withLayout :: (layout -> layout') -> Editor a layout b -> Editor a layout' b Source #
Apply a layout builder.
withSomeWidget :: Renderable w => Editor a w b -> Editor a Layout b Source #
Conceal the widget type of some Editor
construct :: Renderable m => Editor a m b -> Editor a Layout b Source #
Construct a concrete Layout
. Useful when combining heterogeneours layout builders.
Editor constructors
editorUnit :: Editor b Element b Source #
editorEnumBounded :: (Bounded a, Enum a, Ord a, Show a) => Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a) Source #
editorSelection :: Ord a => Behavior [a] -> Behavior (a -> UI Element) -> Editor (Maybe a) (ListBox a) (Maybe a) Source #
An editor that presents a dynamic choice of values.
editorSum :: (Ord tag, Show tag, Renderable el) => (Layout -> Layout -> Layout) -> [(tag, Editor a el a)] -> (a -> tag) -> Editor a Layout a Source #
An editor for union types, built from editors for its constructors.
Generic editors
editorGeneric :: forall a. (Generic a, HasDatatypeInfo a, All (All Editable `And` All Default) (Code a)) => Editor a Layout a Source #
A generic editor for SOP types.
editorGenericSimple :: forall a xs. (Generic a, HasDatatypeInfo a, All Editable xs, Code a ~ '[xs]) => Editor a Layout a Source #
A generic editor for record types.
editorGenericSimpleBi :: forall xs typ. (Generic (typ Value), Generic (typ Edit), All Editable xs, Code (typ Value) ~ '[xs], Code (typ Edit) ~ '[EditorWidgetsFor xs]) => Editor (typ Value) (typ Edit) (typ Value) Source #
A generic implementation of editor
for dual purpose datatypes with a single constructor.
e.g. for the datatype
data Person usage = Person { firstName, lastName :: Field usage String }
instance Editable (Person Value) where type EditorWidget (Person Value) = Person Edit editor = editorGenericSimpleBi
will be equivalent to
instance Editable (Person Value) where type EditorWidget (Person Value) = Person Edit editor = bipure DataItem DataItem <<*>> edit firstName editor <<*>> edit lastName editor
Layouts
Monoidal layouts
A layout monoid that places everything in a single column
newtype Horizontal Source #
A layout monoid that places everything in a single row
A layout monoid that lays elements in columns
Type level layouts
Type level Horizontal layouts
a :|*| b |
Bifunctor (|*|) Source # | |
Biapplicative (|*|) Source # | |
Bifoldable (|*|) Source # | |
(Renderable a, Renderable b) => Renderable ((|*|) a b) Source # | |
Type level Vertical layouts
a :-*- b |
Bifunctor (-*-) Source # | |
Biapplicative (-*-) Source # | |
Bifoldable (-*-) Source # | |
(Renderable a, Renderable b) => Renderable ((-*-) a b) Source # | |
Custom layout definition
class Renderable w where Source #
Renderable String Source # | |
Renderable TextEntry Source # | |
Renderable Element Source # | |
Renderable Columns Source # | |
Renderable Horizontal Source # | |
Renderable Vertical Source # | |
Renderable Layout Source # | |
Renderable (ListBox a) Source # | |
Renderable a => Renderable (UI a) Source # | |
(Renderable a, Renderable b) => Renderable ((-*-) a b) Source # | |
(Renderable a, Renderable b) => Renderable ((|*|) a b) Source # | |
Renderable el => Renderable (GenericWidget el a) Source # | |
renderGeneric :: forall a xs. (Generic a, HasDatatypeInfo a, All Renderable xs, Code a ~ '[xs]) => a -> UI Element Source #
A generic implementation of render
for data types with a single constructor
which renders the (labelled) fields in a vertical layout.
For custom layouts use getLayoutGeneric
.
e.g. given the declarations
data PersonEditor = PersonEditor { firstName, lastName :: EditorWidget String } deriveGeneric ''PersonEditor
using renderGeneric
to instantiate Renderable
instance Renderable PersonEditor where getLayout = renderGeneric
will be equivalent to writing the below by hand
instance Renderable PersonEditor where getLayout PersonEditor{..} = grid [ [string "First name:", element firstName] , [string "Last name:", element lastName ] ]
getLayoutGeneric :: forall a xs. (Generic a, HasDatatypeInfo a, All Renderable xs, Code a ~ '[xs]) => a -> [[Layout]] Source #
A helper to implement getLayout
for data types with a single constructor.
Given a value, getLayoutGeneric
returns a grid of Layout
s with one row per field.
Rows can carry one element, for unnamed fields; two elements, for named fields; or three elements, for operators.
Validation
class Validable a where Source #
The class of values that support validation.
validate :: a -> ValidationResult Source #
ok :: ValidationResult Source #
All is good
fromWarnings :: [String] -> ValidationResult Source #
Create a validation result from a list of warnings.
fromWarnings [] = ok
getWarnings :: ValidationResult -> [String] Source #
updateIfValid :: Validable a => a -> a -> a Source #