    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE GADTs #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    -- | NOTE: This API is experimental and will probably change. Please try
    -- it out! Feedback is very much appreciated, and your patience in the
    -- face of breaking API changes is also appreciated! It's also worth
    -- bearing in mind that this API is designed to support a narrow range
    -- of use cases. If you find that you need more customization than this
    -- offers, then you will need to consider building your own layout and
    -- event handling for input fields.
    --
    -- For a fuller introduction to this API, see the "Input Forms" section
    -- of the Brick User Guide. Also see the demonstration programs for
    -- examples of forms in action.
    --
    -- This module provides an input form API. This API allows you to
    -- construct an input interface based on a data type of your choice.
    -- Each input in the form corresponds to a field in your data type. This
    -- API then automatically dispatches keyboard and mouse input events to
    -- each form input field, manages rendering of the form, notifies the
    -- user when a form field's value is invalid, and stores valid inputs in
    -- your data type when possible.
    --
    -- A form has both a visual representation and a corresponding data
    -- structure representing the latest valid values for that form
    -- (referred to as the "state" of the form). A 'FormField' is a single
    -- input component in the form and a 'FormFieldState' defines the
    -- linkage between that visual input and the corresponding portion
    -- of the state represented by that visual; there may be multiple
    -- 'FormField's combined for a single 'FormFieldState' (e.g. a radio
    -- button sequence).
    --
    -- Also note that, by default, forms and their field inputs are
    -- concatenated together in a 'vBox'. This can be customized on a
    -- per-field basis and for the entire form by using the functions
    -- 'setFieldConcat' and 'setFormConcat', respectively.
    --
    -- Bear in mind that for most uses, the 'FormField' and 'FormFieldState'
    -- types will not be used directly. Instead, the constructors for
    -- various field types (such as 'editTextField') will be used instead.
    module Brick.Forms
      ( -- * Data types
        Form
      , FormFieldState(..)
      , FormField(..)

      -- * Creating and using forms
      , newForm
      , formFocus
      , formState
      , handleFormEvent
      , renderForm
      , renderFormFieldState
      , (@@=)
      , allFieldsValid
      , invalidFields
      , setFieldValid
      , setFormConcat
      , setFieldConcat
      , setFormFocus

      -- * Simple form field constructors
      , editTextField
      , editShowableField
      , editPasswordField
      , radioField
      , checkboxField
      , listField

      -- * Advanced form field constructors
      , editField
      , radioCustomField
      , checkboxCustomField

      -- * Attributes
      , formAttr
      , invalidFormInputAttr
      , focusedFormInputAttr
      )
    where

    import Graphics.Vty hiding (showCursor)
    #if !(MIN_VERSION_base(4,11,0))
    import Data.Monoid
    #endif
    import Data.Maybe (isJust, isNothing)
    import Data.List (elemIndex)
    import Data.Vector (Vector)

    import Brick
    import Brick.Focus
    import Brick.Widgets.Edit
    import Brick.Widgets.List
    import qualified Data.Text.Zipper as Z

    import qualified Data.Text as T
    import Text.Read (readMaybe)

    import Lens.Micro

    -- | A form field. This represents an interactive input field in the
    -- form. Its user input is validated and thus converted into a type of
    -- your choosing.
    --
    -- Type variables are as follows:
    --
    --  * @a@ - the type of the field in your form state that this field
    --    manipulates
    --  * @b@ - the form field's internal state type
    --  * @e@ - your application's event type
    --  * @n@ - your application's resource name type
    data FormField a b e n =
        FormField { FormField a b e n -> n
    formFieldName :: n
                  -- ^ The name identifying this form field.
                  , FormField a b e n -> b -> Maybe a
    formFieldValidate :: b -> Maybe a
                  -- ^ A validation function converting this field's state
                  -- into a value of your choosing. @Nothing@ indicates a
                  -- validation failure. For example, this might validate
                  -- an 'Editor' state value by parsing its text contents s
                  -- aan integer and return 'Maybe' 'Int'. This is for pure
                  -- avalue validation; if additional validation is required
                  -- a(e.g. via 'IO'), use this field's state value in an
                  -- aexternal validation routine and use 'setFieldValid' to
                  -- afeed the result back into the form.
                  , FormField a b e n -> Bool
    formFieldExternallyValid :: Bool
                  -- ^ Whether the field is valid according to an external
                  -- validation source. Defaults to always being 'True' and
                  -- can be set with 'setFieldValid'. The value of this
                  -- field also affects the behavior of 'allFieldsValid' and
                  -- 'getInvalidFields'.
                  , FormField a b e n -> Bool -> b -> Widget n
    formFieldRender :: Bool -> b -> Widget n
                  -- ^ A function to render this form field. Parameters are
                  -- whether the field is currently focused, followed by the
                  -- field state.
                  , FormField a b e n -> BrickEvent n e -> b -> EventM n b
    formFieldHandleEvent :: BrickEvent n e -> b -> EventM n b
                  -- ^ An event handler for this field. This receives the
                  -- event and the field state and returns a new field
                  -- state.
                  }

    -- | A form field state accompanied by the fields that manipulate that
    -- state. The idea is that some record field in your form state has
    -- one or more form fields that manipulate that value. This data type
    -- maps that state field (using a lens into your state) to the form
    -- input fields responsible for managing that state field, along with
    -- a current value for that state field and an optional function to
    -- control how the form inputs are rendered.
    --
    -- Most form fields will just have one input, such as text editors, but
    -- others, such as radio button collections, will have many, which is
    -- why this type supports more than one input corresponding to a state
    -- field.
    --
    -- Type variables are as follows:
    --
    --  * @s@ - the data type containing the value manipulated by these form
    --    fields.
    --  * @e@ - your application's event type
    --  * @n@ - your application's resource name type
    data FormFieldState s e n where
        FormFieldState :: { ()
    formFieldState :: b
                          -- ^ The current state value associated with
                          -- the field collection. Note that this type is
                          -- existential. All form fields in the collection
                          -- must validate to this type.
                          , ()
    formFieldLens :: Lens' s a
                          -- ^ A lens to extract and store a
                          -- successfully-validated form input back into
                          -- your form state.
                          , ()
    formFields :: [FormField a b e n]
                          -- ^ The form fields, in order, that the user will
                          -- interact with to manipulate this state value.
                          , FormFieldState s e n -> Widget n -> Widget n
    formFieldRenderHelper :: Widget n -> Widget n
                          -- ^ A helper function to augment the rendered
                          -- representation of this collection of form
                          -- fields. It receives the default representation
                          -- and can augment it, for example, by adding a
                          -- label on the left.
                          , FormFieldState s e n -> [Widget n] -> Widget n
    formFieldConcat :: [Widget n] -> Widget n
                          -- ^ Concatenation function for this field's input
                          -- renderings.
                          } -> FormFieldState s e n

    -- | A form: a sequence of input fields that manipulate the fields of an
    -- underlying state that you choose.
    --
    -- Type variables are as follows:
    --
    --  * @s@ - the data type of your choosing containing the values
    --    manipulated by the fields in this form.
    --  * @e@ - your application's event type
    --  * @n@ - your application's resource name type
    data Form s e n =
        Form { Form s e n -> [FormFieldState s e n]
    formFieldStates  :: [FormFieldState s e n]
             , Form s e n -> FocusRing n
    formFocus :: FocusRing n
             -- ^ The focus ring for the form, indicating which form field
             -- has input focus.
             , Form s e n -> s
    formState :: s
             -- ^ The current state of the form. Forms guarantee that only
             -- valid inputs ever get stored in the state, and that after
             -- each input event on a form field, if that field contains a
             -- valid state value then the value is immediately saved to its
             -- corresponding field in this state value using the form
             -- field's lens over @s@.
             , Form s e n -> [Widget n] -> Widget n
    formConcatAll :: [Widget n] -> Widget n
             -- ^ Concatenation function for this form's field renderings.
             }

    -- | Compose a new rendering augmentation function with the one in the
    -- form field collection. For example, we might put a label on the left
    -- side of a form field:
    --
    -- > (str "Please check: " <+>) @@= checkboxField alive AliveField "Alive?"
    --
    -- This can also be used to add multiple augmentations and associates
    -- right:
    --
    -- > (withDefAttr someAttribute) @@=
    -- > (str "Please check: " <+>) @@=
    -- >   checkboxField alive AliveField "Alive?"
    infixr 5 @@=
    (@@=) :: (Widget n -> Widget n) -> (s -> FormFieldState s e n) -> s -> FormFieldState s e n
    @@= :: (Widget n -> Widget n)
    -> (s -> FormFieldState s e n) -> s -> FormFieldState s e n
    (@@=) h :: Widget n -> Widget n
    h mkFs :: s -> FormFieldState s e n
    mkFs s :: s
    s =
        let v :: FormFieldState s e n
    v = s -> FormFieldState s e n
    mkFs s
    s
        in FormFieldState s e n
    v { formFieldRenderHelper :: Widget n -> Widget n
    formFieldRenderHelper = Widget n -> Widget n
    h (Widget n -> Widget n)
    -> (Widget n -> Widget n) -> Widget n -> Widget n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (FormFieldState s e n -> Widget n -> Widget n
    forall s e n. FormFieldState s e n -> Widget n -> Widget n
    formFieldRenderHelper FormFieldState s e n
    v) }

    -- | Set the focused field of a form.
    setFormFocus :: (Eq n) => n -> Form s e n -> Form s e n
    setFormFocus :: n -> Form s e n -> Form s e n
    setFormFocus n :: n
    n f :: Form s e n
    f = Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent n
    n (FocusRing n -> FocusRing n) -> FocusRing n -> FocusRing n
    forall a b. (a -> b) -> a -> b
    $ Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f }

    -- | Set a form field's concatenation function.
    setFieldConcat :: ([Widget n] -> Widget n) -> FormFieldState s e n -> FormFieldState s e n
    setFieldConcat :: ([Widget n] -> Widget n)
    -> FormFieldState s e n -> FormFieldState s e n
    setFieldConcat f :: [Widget n] -> Widget n
    f s :: FormFieldState s e n
    s = FormFieldState s e n
    s { formFieldConcat :: [Widget n] -> Widget n
    formFieldConcat = [Widget n] -> Widget n
    f }

    -- | Set a form's concatenation function.
    setFormConcat :: ([Widget n] -> Widget n) -> Form s e n -> Form s e n
    setFormConcat :: ([Widget n] -> Widget n) -> Form s e n -> Form s e n
    setFormConcat func :: [Widget n] -> Widget n
    func f :: Form s e n
    f = Form s e n
    f { formConcatAll :: [Widget n] -> Widget n
    formConcatAll = [Widget n] -> Widget n
    func }

    -- | Create a new form with the specified input fields and an initial
    -- form state. The fields are initialized from the state using their
    -- state lenses and the first form input is focused initially.
    newForm :: [s -> FormFieldState s e n]
            -- ^ The form field constructors. This is intended to be
            -- populated using the various field constructors in this
            -- module.
            -> s
            -- ^ The initial form state used to populate the fields.
            -> Form s e n
    newForm :: [s -> FormFieldState s e n] -> s -> Form s e n
    newForm mkEs :: [s -> FormFieldState s e n]
    mkEs s :: s
    s =
        let es :: [FormFieldState s e n]
    es = [s -> FormFieldState s e n]
    mkEs [s -> FormFieldState s e n] -> [s] -> [FormFieldState s e n]
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> s -> [s]
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure s
    s
        in Form :: forall s e n.
    [FormFieldState s e n]
    -> FocusRing n -> s -> ([Widget n] -> Widget n) -> Form s e n
    Form { formFieldStates :: [FormFieldState s e n]
    formFieldStates = [FormFieldState s e n]
    es
                , formFocus :: FocusRing n
    formFocus       = [n] -> FocusRing n
    forall n. [n] -> FocusRing n
    focusRing ([n] -> FocusRing n) -> [n] -> FocusRing n
    forall a b. (a -> b) -> a -> b
    $ [[n]] -> [n]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[n]] -> [n]) -> [[n]] -> [n]
    forall a b. (a -> b) -> a -> b
    $ FormFieldState s e n -> [n]
    forall s e n. FormFieldState s e n -> [n]
    formFieldNames (FormFieldState s e n -> [n]) -> [FormFieldState s e n] -> [[n]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [FormFieldState s e n]
    es
                , formState :: s
    formState       = s
    s
                , formConcatAll :: [Widget n] -> Widget n
    formConcatAll   = [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    vBox
                }

    formFieldNames :: FormFieldState s e n -> [n]
    formFieldNames :: FormFieldState s e n -> [n]
    formFieldNames (FormFieldState _ _ fields :: [FormField a b e n]
    fields _ _) = FormField a b e n -> n
    forall a b e n. FormField a b e n -> n
    formFieldName (FormField a b e n -> n) -> [FormField a b e n] -> [n]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [FormField a b e n]
    fields

    -- | A form field for manipulating a boolean value. This represents
    -- 'True' as @[X] label@ and 'False' as @[ ] label@.
    --
    -- This field responds to `Space` keypresses to toggle the checkbox and
    -- to mouse clicks.
    checkboxField :: (Ord n, Show n)
                  => Lens' s Bool
                  -- ^ The state lens for this value.
                  -> n
                  -- ^ The resource name for the input field.
                  -> T.Text
                  -- ^ The label for the check box, to appear at its right.
                  -> s
                  -- ^ The initial form state.
                  -> FormFieldState s e n
    checkboxField :: Lens' s Bool -> n -> Text -> s -> FormFieldState s e n
    checkboxField = Char
    -> Char
    -> Char
    -> Lens' s Bool
    -> n
    -> Text
    -> s
    -> FormFieldState s e n
    forall n s e.
    (Ord n, Show n) =>
    Char
    -> Char
    -> Char
    -> Lens' s Bool
    -> n
    -> Text
    -> s
    -> FormFieldState s e n
    checkboxCustomField '[' 'X' ']'

    -- | A form field for manipulating a boolean value. This represents
    -- 'True' as @[X] label@ and 'False' as @[ ] label@. This function
    -- permits the customization of the @[X]@ notation characters.
    --
    -- This field responds to `Space` keypresses to toggle the checkbox and
    -- to mouse clicks.
    checkboxCustomField :: (Ord n, Show n)
                        => Char
                        -- ^ Left bracket character.
                        -> Char
                        -- ^ Checkmark character.
                        -> Char
                        -- ^ Right bracket character.
                        -> Lens' s Bool
                        -- ^ The state lens for this value.
                        -> n
                        -- ^ The resource name for the input field.
                        -> T.Text
                        -- ^ The label for the check box, to appear at its right.
                        -> s
                        -- ^ The initial form state.
                        -> FormFieldState s e n
    checkboxCustomField :: Char
    -> Char
    -> Char
    -> Lens' s Bool
    -> n
    -> Text
    -> s
    -> FormFieldState s e n
    checkboxCustomField lb :: Char
    lb check :: Char
    check rb :: Char
    rb stLens :: Lens' s Bool
    stLens name :: n
    name label :: Text
    label initialState :: s
    initialState =
        let initVal :: Bool
    initVal = s
    initialState s -> Getting Bool s Bool -> Bool
    forall s a. s -> Getting a s a -> a
    ^. Getting Bool s Bool
    Lens' s Bool
    stLens

            handleEvent :: BrickEvent n e -> Bool -> EventM n Bool
    handleEvent (MouseDown n :: n
    n _ _ _) s :: Bool
    s | n
    n n -> n -> Bool
    forall a. Eq a => a -> a -> Bool
    == n
    name = Bool -> EventM n Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> EventM n Bool) -> Bool -> EventM n Bool
    forall a b. (a -> b) -> a -> b
    $ Bool -> Bool
    not Bool
    s
            handleEvent (VtyEvent (EvKey (KChar ' ') [])) s :: Bool
    s = Bool -> EventM n Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool -> EventM n Bool) -> Bool -> EventM n Bool
    forall a b. (a -> b) -> a -> b
    $ Bool -> Bool
    not Bool
    s
            handleEvent _ s :: Bool
    s = Bool -> EventM n Bool
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    s

        in $WFormFieldState :: forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState { formFieldState :: Bool
    formFieldState = Bool
    initVal
                          , formFields :: [FormField Bool Bool e n]
    formFields = [ n
    -> (Bool -> Maybe Bool)
    -> Bool
    -> (Bool -> Bool -> Widget n)
    -> (BrickEvent n e -> Bool -> EventM n Bool)
    -> FormField Bool Bool e n
    forall a b e n.
    n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    FormField n
    name Bool -> Maybe Bool
    forall a. a -> Maybe a
    Just Bool
    True
                                                     (Char -> Char -> Char -> Text -> n -> Bool -> Bool -> Widget n
    forall n.
    Char -> Char -> Char -> Text -> n -> Bool -> Bool -> Widget n
    renderCheckbox Char
    lb Char
    check Char
    rb Text
    label n
    name)
                                                     BrickEvent n e -> Bool -> EventM n Bool
    handleEvent
                                         ]
                          , formFieldLens :: Lens' s Bool
    formFieldLens = Lens' s Bool
    stLens
                          , formFieldRenderHelper :: Widget n -> Widget n
    formFieldRenderHelper = Widget n -> Widget n
    forall a. a -> a
    id
                          , formFieldConcat :: [Widget n] -> Widget n
    formFieldConcat = [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    vBox
                          }

    renderCheckbox :: Char -> Char -> Char -> T.Text -> n -> Bool -> Bool -> Widget n
    renderCheckbox :: Char -> Char -> Char -> Text -> n -> Bool -> Bool -> Widget n
    renderCheckbox lb :: Char
    lb check :: Char
    check rb :: Char
    rb label :: Text
    label n :: n
    n foc :: Bool
    foc val :: Bool
    val =
        let addAttr :: Widget n -> Widget n
    addAttr = if Bool
    foc then AttrName -> Widget n -> Widget n
    forall n. AttrName -> Widget n -> Widget n
    withDefAttr AttrName
    focusedFormInputAttr else Widget n -> Widget n
    forall a. a -> a
    id
            csr :: Widget n -> Widget n
    csr = if Bool
    foc then n -> Location -> Widget n -> Widget n
    forall n. n -> Location -> Widget n -> Widget n
    showCursor n
    n ((Int, Int) -> Location
    Location (1,0)) else Widget n -> Widget n
    forall a. a -> a
    id
        in n -> Widget n -> Widget n
    forall n. n -> Widget n -> Widget n
    clickable n
    n (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $
           Widget n -> Widget n
    addAttr (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $ Widget n -> Widget n
    csr (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $
           (Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> Text -> Widget n
    forall a b. (a -> b) -> a -> b
    $ Char -> Text
    T.singleton Char
    lb Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (if Bool
    val then Char -> Text
    T.singleton Char
    check else " ") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                  Char -> Text
    T.singleton Char
    rb Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " ") Widget n -> Widget n -> Widget n
    forall n. Widget n -> Widget n -> Widget n
    <+> Text -> Widget n
    forall n. Text -> Widget n
    txt Text
    label

    -- | A form field for selecting a single choice from a set of possible
    -- choices in a scrollable list. This uses a 'List' internally.
    --
    -- This field responds to the same input events that a 'List' does.
    listField :: forall s e n a . (Ord n, Show n, Eq a)
              => (s -> Vector a)
              -- ^ Possible choices.
              -> Lens' s (Maybe a)
              -- ^ The state lens for the initially/finally selected
              -- element.
              -> (Bool -> a -> Widget n)
              -- ^ List item rendering function.
              -> Int
              -- ^ List item height in rows.
              -> n
              -- ^ The resource name for the input field.
              -> s
              -- ^ The initial form state.
              -> FormFieldState s e n
    listField :: (s -> Vector a)
    -> Lens' s (Maybe a)
    -> (Bool -> a -> Widget n)
    -> Int
    -> n
    -> s
    -> FormFieldState s e n
    listField options :: s -> Vector a
    options stLens :: Lens' s (Maybe a)
    stLens renderItem :: Bool -> a -> Widget n
    renderItem itemHeight :: Int
    itemHeight name :: n
    name initialState :: s
    initialState =
        let optionsVector :: Vector a
    optionsVector = s -> Vector a
    options s
    initialState
            initVal :: List n a
    initVal = s
    initialState s -> Getting (List n a) s (List n a) -> List n a
    forall s a. s -> Getting a s a -> a
    ^. Getting (List n a) s (List n a)
    Lens' s (List n a)
    customStLens

            customStLens :: Lens' s (List n a)
            customStLens :: (List n a -> f (List n a)) -> s -> f s
    customStLens = (s -> List n a) -> (s -> List n a -> s) -> Lens' s (List n a)
    forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
    lens s -> List n a
    getList s -> List n a -> s
    setList
                where
                   getList :: s -> List n a
    getList s :: s
    s = let l :: List n a
    l = n -> Vector a -> Int -> List n a
    forall (t :: * -> *) n e.
    Foldable t =>
    n -> t e -> Int -> GenericList n t e
    list n
    name Vector a
    optionsVector Int
    itemHeight
                               in case s
    s s -> Getting (Maybe a) s (Maybe a) -> Maybe a
    forall s a. s -> Getting a s a -> a
    ^. Getting (Maybe a) s (Maybe a)
    Lens' s (Maybe a)
    stLens of
                                   Nothing -> List n a
    l
                                   Just e :: a
    e -> a -> List n a -> List n a
    forall e (t :: * -> *) n.
    (Eq e, Foldable t, Splittable t) =>
    e -> GenericList n t e -> GenericList n t e
    listMoveToElement a
    e List n a
    l
                   setList :: s -> List n a -> s
    setList s :: s
    s l :: List n a
    l = s
    s s -> (s -> s) -> s
    forall a b. a -> (a -> b) -> b
    & (Maybe a -> Identity (Maybe a)) -> s -> Identity s
    Lens' s (Maybe a)
    stLens ((Maybe a -> Identity (Maybe a)) -> s -> Identity s)
    -> Maybe a -> s -> s
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ ((Int, a) -> a
    forall a b. (a, b) -> b
    snd ((Int, a) -> a) -> Maybe (Int, a) -> Maybe a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> List n a -> Maybe (Int, a)
    forall (t :: * -> *) n e.
    (Splittable t, Foldable t) =>
    GenericList n t e -> Maybe (Int, e)
    listSelectedElement List n a
    l)

            handleEvent :: BrickEvent n e -> GenericList n t e -> EventM n (GenericList n t e)
    handleEvent (VtyEvent e :: Event
    e) s :: GenericList n t e
    s = Event -> GenericList n t e -> EventM n (GenericList n t e)
    forall (t :: * -> *) n e.
    (Foldable t, Splittable t, Ord n) =>
    Event -> GenericList n t e -> EventM n (GenericList n t e)
    handleListEvent Event
    e GenericList n t e
    s
            handleEvent _ s :: GenericList n t e
    s = GenericList n t e -> EventM n (GenericList n t e)
    forall (m :: * -> *) a. Monad m => a -> m a
    return GenericList n t e
    s

        in $WFormFieldState :: forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState { formFieldState :: List n a
    formFieldState = List n a
    initVal
                          , formFields :: [FormField (List n a) (List n a) e n]
    formFields = [ n
    -> (List n a -> Maybe (List n a))
    -> Bool
    -> (Bool -> List n a -> Widget n)
    -> (BrickEvent n e -> List n a -> EventM n (List n a))
    -> FormField (List n a) (List n a) e n
    forall a b e n.
    n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    FormField n
    name List n a -> Maybe (List n a)
    forall a. a -> Maybe a
    Just Bool
    True
                                                     ((Bool -> a -> Widget n) -> Bool -> List n a -> Widget n
    forall (t :: * -> *) n e.
    (Traversable t, Splittable t, Ord n, Show n) =>
    (Bool -> e -> Widget n) -> Bool -> GenericList n t e -> Widget n
    renderList Bool -> a -> Widget n
    renderItem)
                                                     BrickEvent n e -> List n a -> EventM n (List n a)
    forall (t :: * -> *) n n e e.
    (Foldable t, Splittable t, Ord n) =>
    BrickEvent n e -> GenericList n t e -> EventM n (GenericList n t e)
    handleEvent
                                         ]
                          , formFieldLens :: Lens' s (List n a)
    formFieldLens = Lens' s (List n a)
    customStLens
                          , formFieldRenderHelper :: Widget n -> Widget n
    formFieldRenderHelper = Widget n -> Widget n
    forall a. a -> a
    id
                          , formFieldConcat :: [Widget n] -> Widget n
    formFieldConcat = [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    vBox
                          }
    -- | A form field for selecting a single choice from a set of possible
    -- choices. Each choice has an associated value and text label.
    --
    -- This field responds to `Space` keypresses to select a radio button
    -- option and to mouse clicks.
    radioField :: (Ord n, Show n, Eq a)
               => Lens' s a
               -- ^ The state lens for this value.
               -> [(a, n, T.Text)]
               -- ^ The available choices, in order. Each choice has a value
               -- of type @a@, a resource name, and a text label.
               -> s
               -- ^ The initial form state.
               -> FormFieldState s e n
    radioField :: Lens' s a -> [(a, n, Text)] -> s -> FormFieldState s e n
    radioField = Char
    -> Char
    -> Char
    -> Lens' s a
    -> [(a, n, Text)]
    -> s
    -> FormFieldState s e n
    forall n a s e.
    (Ord n, Show n, Eq a) =>
    Char
    -> Char
    -> Char
    -> Lens' s a
    -> [(a, n, Text)]
    -> s
    -> FormFieldState s e n
    radioCustomField '[' '*' ']'

    -- | A form field for selecting a single choice from a set of possible
    -- choices. Each choice has an associated value and text label. This
    -- function permits the customization of the @[*]@ notation characters.
    --
    -- This field responds to `Space` keypresses to select a radio button
    -- option and to mouse clicks.
    radioCustomField :: (Ord n, Show n, Eq a)
                     => Char
                     -- ^ Left bracket character.
                     -> Char
                     -- ^ Checkmark character.
                     -> Char
                     -- ^ Right bracket character.
                     -> Lens' s a
                     -- ^ The state lens for this value.
                     -> [(a, n, T.Text)]
                     -- ^ The available choices, in order. Each choice has a value
                     -- of type @a@, a resource name, and a text label.
                     -> s
                     -- ^ The initial form state.
                     -> FormFieldState s e n
    radioCustomField :: Char
    -> Char
    -> Char
    -> Lens' s a
    -> [(a, n, Text)]
    -> s
    -> FormFieldState s e n
    radioCustomField lb :: Char
    lb check :: Char
    check rb :: Char
    rb stLens :: Lens' s a
    stLens options :: [(a, n, Text)]
    options initialState :: s
    initialState =
        let initVal :: a
    initVal = s
    initialState s -> Getting a s a -> a
    forall s a. s -> Getting a s a -> a
    ^. Getting a s a
    Lens' s a
    stLens

            lookupOptionValue :: n -> Maybe a
    lookupOptionValue n :: n
    n =
                let results :: [(a, n, Text)]
    results = ((a, n, Text) -> Bool) -> [(a, n, Text)] -> [(a, n, Text)]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\(_, n' :: n
    n', _) -> n
    n' n -> n -> Bool
    forall a. Eq a => a -> a -> Bool
    == n
    n) [(a, n, Text)]
    options
                in case [(a, n, Text)]
    results of
                    [(val :: a
    val, _, _)] -> a -> Maybe a
    forall a. a -> Maybe a
    Just a
    val
                    _ -> Maybe a
    forall a. Maybe a
    Nothing

            handleEvent :: a -> BrickEvent n e -> a -> EventM n a
    handleEvent _ (MouseDown n :: n
    n _ _ _) s :: a
    s =
                case n -> Maybe a
    lookupOptionValue n
    n of
                    Nothing -> a -> EventM n a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    s
                    Just v :: a
    v -> a -> EventM n a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    v
            handleEvent new :: a
    new (VtyEvent (EvKey (KChar ' ') [])) _ = a -> EventM n a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    new
            handleEvent _ _ s :: a
    s = a -> EventM n a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    s

            optionFields :: [FormField a a e n]
    optionFields = (a, n, Text) -> FormField a a e n
    mkOptionField ((a, n, Text) -> FormField a a e n)
    -> [(a, n, Text)] -> [FormField a a e n]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [(a, n, Text)]
    options
            mkOptionField :: (a, n, Text) -> FormField a a e n
    mkOptionField (val :: a
    val, name :: n
    name, label :: Text
    label) =
                n
    -> (a -> Maybe a)
    -> Bool
    -> (Bool -> a -> Widget n)
    -> (BrickEvent n e -> a -> EventM n a)
    -> FormField a a e n
    forall a b e n.
    n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    FormField n
    name
                          a -> Maybe a
    forall a. a -> Maybe a
    Just
                          Bool
    True
                          (Char -> Char -> Char -> a -> n -> Text -> Bool -> a -> Widget n
    forall a n.
    Eq a =>
    Char -> Char -> Char -> a -> n -> Text -> Bool -> a -> Widget n
    renderRadio Char
    lb Char
    check Char
    rb a
    val n
    name Text
    label)
                          (a -> BrickEvent n e -> a -> EventM n a
    handleEvent a
    val)

        in $WFormFieldState :: forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState { formFieldState :: a
    formFieldState = a
    initVal
                          , formFields :: [FormField a a e n]
    formFields = [FormField a a e n]
    optionFields
                          , formFieldLens :: Lens' s a
    formFieldLens = Lens' s a
    stLens
                          , formFieldRenderHelper :: Widget n -> Widget n
    formFieldRenderHelper = Widget n -> Widget n
    forall a. a -> a
    id
                          , formFieldConcat :: [Widget n] -> Widget n
    formFieldConcat = [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    vBox
                          }

    renderRadio :: (Eq a) => Char -> Char -> Char -> a -> n -> T.Text -> Bool -> a -> Widget n
    renderRadio :: Char -> Char -> Char -> a -> n -> Text -> Bool -> a -> Widget n
    renderRadio lb :: Char
    lb check :: Char
    check rb :: Char
    rb val :: a
    val name :: n
    name label :: Text
    label foc :: Bool
    foc cur :: a
    cur =
        let addAttr :: Widget n -> Widget n
    addAttr = if Bool
    foc
                      then AttrName -> Widget n -> Widget n
    forall n. AttrName -> Widget n -> Widget n
    withDefAttr AttrName
    focusedFormInputAttr
                      else Widget n -> Widget n
    forall a. a -> a
    id
            isSet :: Bool
    isSet = a
    val a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    cur
            csr :: Widget n -> Widget n
    csr = if Bool
    foc then n -> Location -> Widget n -> Widget n
    forall n. n -> Location -> Widget n -> Widget n
    showCursor n
    name ((Int, Int) -> Location
    Location (1,0)) else Widget n -> Widget n
    forall a. a -> a
    id
        in n -> Widget n -> Widget n
    forall n. n -> Widget n -> Widget n
    clickable n
    name (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $
           Widget n -> Widget n
    addAttr (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $ Widget n -> Widget n
    csr (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $
           [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    hBox [ Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> Text -> Widget n
    forall a b. (a -> b) -> a -> b
    $ Char -> Text
    T.singleton Char
    lb
                , Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> Text -> Widget n
    forall a b. (a -> b) -> a -> b
    $ if Bool
    isSet then Char -> Text
    T.singleton Char
    check else " "
                , Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> Text -> Widget n
    forall a b. (a -> b) -> a -> b
    $ Char -> Text
    T.singleton Char
    rb Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label
                ]

    -- | A form field for using an editor to edit the text representation of
    -- a value. The other editing fields in this module are special cases of
    -- this function.
    --
    -- This field responds to all events handled by 'editor', including
    -- mouse events.
    editField :: (Ord n, Show n)
              => Lens' s a
              -- ^ The state lens for this value.
              -> n
              -- ^ The resource name for the input field.
              -> Maybe Int
              -- ^ The optional line limit for the editor (see 'editor').
              -> (a -> T.Text)
              -- ^ The initialization function that turns your value into
              -- the editor's initial contents. The resulting text may
              -- contain newlines.
              -> ([T.Text] -> Maybe a)
              -- ^ The validation function that converts the editors
              -- contents into a valid value of type @a@.
              -> ([T.Text] -> Widget n)
              -- ^ The rendering function for the editor's contents (see
              -- 'renderEditor').
              -> (Widget n -> Widget n)
              -- ^ A rendering augmentation function to adjust the
              -- representation of the rendered editor.
              -> s
              -- ^ The initial form state.
              -> FormFieldState s e n
    editField :: Lens' s a
    -> n
    -> Maybe Int
    -> (a -> Text)
    -> ([Text] -> Maybe a)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    editField stLens :: Lens' s a
    stLens n :: n
    n limit :: Maybe Int
    limit ini :: a -> Text
    ini val :: [Text] -> Maybe a
    val renderText :: [Text] -> Widget n
    renderText wrapEditor :: Widget n -> Widget n
    wrapEditor initialState :: s
    initialState =
        let initVal :: Editor Text n
    initVal = (TextZipper Text -> TextZipper Text)
    -> Editor Text n -> Editor Text n
    forall t n.
    (TextZipper t -> TextZipper t) -> Editor t n -> Editor t n
    applyEdit TextZipper Text -> TextZipper Text
    gotoEnd (Editor Text n -> Editor Text n) -> Editor Text n -> Editor Text n
    forall a b. (a -> b) -> a -> b
    $
                      n -> Maybe Int -> Text -> Editor Text n
    forall a n.
    GenericTextZipper a =>
    n -> Maybe Int -> a -> Editor a n
    editor n
    n Maybe Int
    limit Text
    initialText
            gotoEnd :: TextZipper Text -> TextZipper Text
    gotoEnd = let ls :: [Text]
    ls = Text -> [Text]
    T.lines Text
    initialText
                          pos :: (Int, Int)
    pos = ([Text] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Text]
    ls Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1, Text -> Int
    T.length ([Text] -> Text
    forall a. [a] -> a
    last [Text]
    ls))
                      in if [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    ls
                         then TextZipper Text -> TextZipper Text
    forall a. a -> a
    id
                         else (Int, Int) -> TextZipper Text -> TextZipper Text
    forall a. Monoid a => (Int, Int) -> TextZipper a -> TextZipper a
    Z.moveCursor (Int, Int)
    pos
            initialText :: Text
    initialText = a -> Text
    ini (a -> Text) -> a -> Text
    forall a b. (a -> b) -> a -> b
    $ s
    initialState s -> Getting a s a -> a
    forall s a. s -> Getting a s a -> a
    ^. Getting a s a
    Lens' s a
    stLens
            handleEvent :: BrickEvent n e -> Editor t n -> EventM n (Editor t n)
    handleEvent (VtyEvent e :: Event
    e) ed :: Editor t n
    ed = Event -> Editor t n -> EventM n (Editor t n)
    forall t n.
    (DecodeUtf8 t, Eq t, Monoid t) =>
    Event -> Editor t n -> EventM n (Editor t n)
    handleEditorEvent Event
    e Editor t n
    ed
            handleEvent _ ed :: Editor t n
    ed = Editor t n -> EventM n (Editor t n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Editor t n
    ed

        in $WFormFieldState :: forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState { formFieldState :: Editor Text n
    formFieldState = Editor Text n
    initVal
                          , formFields :: [FormField a (Editor Text n) e n]
    formFields = [ n
    -> (Editor Text n -> Maybe a)
    -> Bool
    -> (Bool -> Editor Text n -> Widget n)
    -> (BrickEvent n e -> Editor Text n -> EventM n (Editor Text n))
    -> FormField a (Editor Text n) e n
    forall a b e n.
    n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    FormField n
    n
                                                     ([Text] -> Maybe a
    val ([Text] -> Maybe a)
    -> (Editor Text n -> [Text]) -> Editor Text n -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Editor Text n -> [Text]
    forall t n. Monoid t => Editor t n -> [t]
    getEditContents)
                                                     Bool
    True
                                                     (\b :: Bool
    b e :: Editor Text n
    e -> Widget n -> Widget n
    wrapEditor (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $ ([Text] -> Widget n) -> Bool -> Editor Text n -> Widget n
    forall n t.
    (Ord n, Show n, Monoid t, TextWidth t, GenericTextZipper t) =>
    ([t] -> Widget n) -> Bool -> Editor t n -> Widget n
    renderEditor [Text] -> Widget n
    renderText Bool
    b Editor Text n
    e)
                                                     BrickEvent n e -> Editor Text n -> EventM n (Editor Text n)
    forall t n e n.
    (DecodeUtf8 t, Eq t, Monoid t) =>
    BrickEvent n e -> Editor t n -> EventM n (Editor t n)
    handleEvent
                                         ]
                          , formFieldLens :: Lens' s a
    formFieldLens = Lens' s a
    stLens
                          , formFieldRenderHelper :: Widget n -> Widget n
    formFieldRenderHelper = Widget n -> Widget n
    forall a. a -> a
    id
                          , formFieldConcat :: [Widget n] -> Widget n
    formFieldConcat = [Widget n] -> Widget n
    forall n. [Widget n] -> Widget n
    vBox
                          }

    -- | A form field using a single-line editor to edit the 'Show'
    -- representation of a state field value of type @a@. This automatically
    -- uses its 'Read' instance to validate the input. This field is mostly
    -- useful in cases where the user-facing representation of a value
    -- matches the 'Show' representation exactly, such as with 'Int'.
    --
    -- This field responds to all events handled by 'editor', including
    -- mouse events.
    editShowableField :: (Ord n, Show n, Read a, Show a)
                      => Lens' s a
                      -- ^ The state lens for this value.
                      -> n
                      -- ^ The resource name for the input field.
                      -> s
                      -- ^ The initial form state.
                      -> FormFieldState s e n
    editShowableField :: Lens' s a -> n -> s -> FormFieldState s e n
    editShowableField stLens :: Lens' s a
    stLens n :: n
    n =
        let ini :: a -> Text
    ini = String -> Text
    T.pack (String -> Text) -> (a -> String) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> String
    forall a. Show a => a -> String
    show
            val :: [Text] -> Maybe a
    val = String -> Maybe a
    forall a. Read a => String -> Maybe a
    readMaybe (String -> Maybe a) -> ([Text] -> String) -> [Text] -> Maybe a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> String
    T.unpack (Text -> String) -> ([Text] -> Text) -> [Text] -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Text] -> Text
    T.intercalate "\n"
            limit :: Maybe Int
    limit = Int -> Maybe Int
    forall a. a -> Maybe a
    Just 1
            renderText :: [Text] -> Widget n
    renderText = Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> ([Text] -> Text) -> [Text] -> Widget n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> Text
    T.unlines
        in Lens' s a
    -> n
    -> Maybe Int
    -> (a -> Text)
    -> ([Text] -> Maybe a)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    forall n s a e.
    (Ord n, Show n) =>
    Lens' s a
    -> n
    -> Maybe Int
    -> (a -> Text)
    -> ([Text] -> Maybe a)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    editField Lens' s a
    stLens n
    n Maybe Int
    limit a -> Text
    ini [Text] -> Maybe a
    val [Text] -> Widget n
    forall n. [Text] -> Widget n
    renderText Widget n -> Widget n
    forall a. a -> a
    id

    -- | A form field using an editor to edit a text value. Since the value
    -- is free-form text, it is always valid.
    --
    -- This field responds to all events handled by 'editor', including
    -- mouse events.
    editTextField :: (Ord n, Show n)
                  => Lens' s T.Text
                  -- ^ The state lens for this value.
                  -> n
                  -- ^ The resource name for the input field.
                  -> Maybe Int
                  -- ^ The optional line limit for the editor (see 'editor').
                  -> s
                  -- ^ The initial form state.
                  -> FormFieldState s e n
    editTextField :: Lens' s Text -> n -> Maybe Int -> s -> FormFieldState s e n
    editTextField stLens :: Lens' s Text
    stLens n :: n
    n limit :: Maybe Int
    limit =
        let ini :: a -> a
    ini = a -> a
    forall a. a -> a
    id
            val :: [Text] -> Maybe Text
    val = Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> ([Text] -> Text) -> [Text] -> Maybe Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Text] -> Text
    T.intercalate "\n"
            renderText :: [Text] -> Widget n
    renderText = Text -> Widget n
    forall n. Text -> Widget n
    txt (Text -> Widget n) -> ([Text] -> Text) -> [Text] -> Widget n
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> [Text] -> Text
    T.intercalate "\n"
        in Lens' s Text
    -> n
    -> Maybe Int
    -> (Text -> Text)
    -> ([Text] -> Maybe Text)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    forall n s a e.
    (Ord n, Show n) =>
    Lens' s a
    -> n
    -> Maybe Int
    -> (a -> Text)
    -> ([Text] -> Maybe a)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    editField Lens' s Text
    stLens n
    n Maybe Int
    limit Text -> Text
    forall a. a -> a
    ini [Text] -> Maybe Text
    val [Text] -> Widget n
    forall n. [Text] -> Widget n
    renderText Widget n -> Widget n
    forall a. a -> a
    id

    -- | A form field using a single-line editor to edit a free-form text
    -- value represented as a password. The value is always considered valid
    -- and is always represented with one asterisk per password character.
    --
    -- This field responds to all events handled by 'editor', including
    -- mouse events.
    editPasswordField :: (Ord n, Show n)
                      => Lens' s T.Text
                      -- ^ The state lens for this value.
                      -> n
                      -- ^ The resource name for the input field.
                      -> s
                      -- ^ The initial form state.
                      -> FormFieldState s e n
    editPasswordField :: Lens' s Text -> n -> s -> FormFieldState s e n
    editPasswordField stLens :: Lens' s Text
    stLens n :: n
    n =
        let ini :: a -> a
    ini = a -> a
    forall a. a -> a
    id
            val :: [Text] -> Maybe Text
    val = Text -> Maybe Text
    forall a. a -> Maybe a
    Just (Text -> Maybe Text) -> ([Text] -> Text) -> [Text] -> Maybe Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> Text
    T.concat
            limit :: Maybe Int
    limit = Int -> Maybe Int
    forall a. a -> Maybe a
    Just 1
            renderText :: [Text] -> Widget a
    renderText = [Text] -> Widget a
    forall n. [Text] -> Widget n
    toPassword
        in Lens' s Text
    -> n
    -> Maybe Int
    -> (Text -> Text)
    -> ([Text] -> Maybe Text)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    forall n s a e.
    (Ord n, Show n) =>
    Lens' s a
    -> n
    -> Maybe Int
    -> (a -> Text)
    -> ([Text] -> Maybe a)
    -> ([Text] -> Widget n)
    -> (Widget n -> Widget n)
    -> s
    -> FormFieldState s e n
    editField Lens' s Text
    stLens n
    n Maybe Int
    limit Text -> Text
    forall a. a -> a
    ini [Text] -> Maybe Text
    val [Text] -> Widget n
    forall n. [Text] -> Widget n
    renderText Widget n -> Widget n
    forall a. a -> a
    id

    toPassword :: [T.Text] -> Widget a
    toPassword :: [Text] -> Widget a
    toPassword s :: [Text]
    s = Text -> Widget a
    forall n. Text -> Widget n
    txt (Text -> Widget a) -> Text -> Widget a
    forall a b. (a -> b) -> a -> b
    $ Int -> Text -> Text
    T.replicate (Text -> Int
    T.length (Text -> Int) -> Text -> Int
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    T.concat [Text]
    s) "*"

    -- | The namespace for the other form attributes.
    formAttr :: AttrName
    formAttr :: AttrName
    formAttr = "brickForm"

    -- | The attribute for form input fields with invalid values.
    invalidFormInputAttr :: AttrName
    invalidFormInputAttr :: AttrName
    invalidFormInputAttr = AttrName
    formAttr AttrName -> AttrName -> AttrName
    forall a. Semigroup a => a -> a -> a
    <> "invalidInput"

    -- | The attribute for form input fields that have the focus.
    focusedFormInputAttr :: AttrName
    focusedFormInputAttr :: AttrName
    focusedFormInputAttr = AttrName
    formAttr AttrName -> AttrName -> AttrName
    forall a. Semigroup a => a -> a -> a
    <> "focusedInput"

    -- | Returns whether all form fields in the form currently have valid
    -- values according to the fields' validation functions. This is useful
    -- when we need to decide whether the form state is up to date with
    -- respect to the form input fields.
    allFieldsValid :: Form s e n -> Bool
    allFieldsValid :: Form s e n -> Bool
    allFieldsValid = [n] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([n] -> Bool) -> (Form s e n -> [n]) -> Form s e n -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Form s e n -> [n]
    forall s e n. Form s e n -> [n]
    invalidFields

    -- | Returns the resource names associated with all form input fields
    -- that currently have invalid inputs. This is useful when we need to
    -- force the user to repair invalid inputs before moving on from a form
    -- editing session.
    invalidFields :: Form s e n -> [n]
    invalidFields :: Form s e n -> [n]
    invalidFields f :: Form s e n
    f = [[n]] -> [n]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[n]] -> [n]) -> [[n]] -> [n]
    forall a b. (a -> b) -> a -> b
    $ FormFieldState s e n -> [n]
    forall s e n. FormFieldState s e n -> [n]
    getInvalidFields (FormFieldState s e n -> [n]) -> [FormFieldState s e n] -> [[n]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Form s e n -> [FormFieldState s e n]
    forall s e n. Form s e n -> [FormFieldState s e n]
    formFieldStates Form s e n
    f

    -- | Manually indicate that a field has invalid contents. This can be
    -- useful in situations where validation beyond the form element's
    -- validator needs to be performed and the result of that validation
    -- needs to be fed back into the form state.
    setFieldValid :: (Eq n)
                  => Bool
                  -- ^ Whether the field is considered valid.
                  -> n
                  -- ^ The name of the form field to set as (in)valid.
                  -> Form s e n
                  -- ^ The form to modify.
                  -> Form s e n
    setFieldValid :: Bool -> n -> Form s e n -> Form s e n
    setFieldValid v :: Bool
    v n :: n
    n form :: Form s e n
    form =
        let go1 :: [FormFieldState s e n] -> [FormFieldState s e n]
    go1 [] = []
            go1 (s :: FormFieldState s e n
    s:ss :: [FormFieldState s e n]
    ss) =
                let s' :: FormFieldState s e n
    s' = case FormFieldState s e n
    s of
                           FormFieldState st :: b
    st l :: Lens' s a
    l fs :: [FormField a b e n]
    fs rh :: Widget n -> Widget n
    rh concatAll :: [Widget n] -> Widget n
    concatAll ->
                               let go2 :: [FormField a b e n] -> [FormField a b e n]
    go2 [] = []
                                   go2 (f :: FormField a b e n
    f@(FormField fn :: n
    fn val :: b -> Maybe a
    val _ r :: Bool -> b -> Widget n
    r h :: BrickEvent n e -> b -> EventM n b
    h):ff :: [FormField a b e n]
    ff)
                                       | n
    n n -> n -> Bool
    forall a. Eq a => a -> a -> Bool
    == n
    fn = n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    forall a b e n.
    n
    -> (b -> Maybe a)
    -> Bool
    -> (Bool -> b -> Widget n)
    -> (BrickEvent n e -> b -> EventM n b)
    -> FormField a b e n
    FormField n
    fn b -> Maybe a
    val Bool
    v Bool -> b -> Widget n
    r BrickEvent n e -> b -> EventM n b
    h FormField a b e n -> [FormField a b e n] -> [FormField a b e n]
    forall a. a -> [a] -> [a]
    : [FormField a b e n]
    ff
                                       | Bool
    otherwise = FormField a b e n
    f FormField a b e n -> [FormField a b e n] -> [FormField a b e n]
    forall a. a -> [a] -> [a]
    : [FormField a b e n] -> [FormField a b e n]
    go2 [FormField a b e n]
    ff
                               in b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState b
    st Lens' s a
    l ([FormField a b e n] -> [FormField a b e n]
    go2 [FormField a b e n]
    fs) Widget n -> Widget n
    rh [Widget n] -> Widget n
    concatAll
                in FormFieldState s e n
    s' FormFieldState s e n
    -> [FormFieldState s e n] -> [FormFieldState s e n]
    forall a. a -> [a] -> [a]
    : [FormFieldState s e n] -> [FormFieldState s e n]
    go1 [FormFieldState s e n]
    ss

        in Form s e n
    form { formFieldStates :: [FormFieldState s e n]
    formFieldStates = [FormFieldState s e n] -> [FormFieldState s e n]
    go1 (Form s e n -> [FormFieldState s e n]
    forall s e n. Form s e n -> [FormFieldState s e n]
    formFieldStates Form s e n
    form) }

    getInvalidFields :: FormFieldState s e n -> [n]
    getInvalidFields :: FormFieldState s e n -> [n]
    getInvalidFields (FormFieldState st :: b
    st _ fs :: [FormField a b e n]
    fs _ _) =
        let gather :: FormField a b e n -> [n]
    gather (FormField n :: n
    n validate :: b -> Maybe a
    validate extValid :: Bool
    extValid _ _) =
                if (Bool -> Bool
    not Bool
    extValid Bool -> Bool -> Bool
    || (Maybe a -> Bool
    forall a. Maybe a -> Bool
    isNothing (Maybe a -> Bool) -> Maybe a -> Bool
    forall a b. (a -> b) -> a -> b
    $ b -> Maybe a
    validate b
    st)) then [n
    n] else []
        in [[n]] -> [n]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[n]] -> [n]) -> [[n]] -> [n]
    forall a b. (a -> b) -> a -> b
    $ FormField a b e n -> [n]
    gather (FormField a b e n -> [n]) -> [FormField a b e n] -> [[n]]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [FormField a b e n]
    fs

    -- | Render a form.
    --
    -- For each form field, each input for the field is rendered using
    -- the implementation provided by its 'FormField'. The inputs are
    -- then concatenated with the field's concatenation function (see
    -- 'setFieldConcat') and are then augmented using the form field's
    -- rendering augmentation function (see '@@='). Fields with invalid
    -- inputs (either due to built-in validator failure or due to external
    -- validation failure via 'setFieldValid') will be displayed using the
    -- 'invalidFormInputAttr' attribute.
    --
    -- Finally, all of the resulting field renderings are concatenated with
    -- the form's concatenation function (see 'setFormConcat').
    renderForm :: (Eq n) => Form s e n -> Widget n
    renderForm :: Form s e n -> Widget n
    renderForm (Form es :: [FormFieldState s e n]
    es fr :: FocusRing n
    fr _ concatAll :: [Widget n] -> Widget n
    concatAll) =
        [Widget n] -> Widget n
    concatAll ([Widget n] -> Widget n) -> [Widget n] -> Widget n
    forall a b. (a -> b) -> a -> b
    $ FocusRing n -> FormFieldState s e n -> Widget n
    forall n s e.
    Eq n =>
    FocusRing n -> FormFieldState s e n -> Widget n
    renderFormFieldState FocusRing n
    fr (FormFieldState s e n -> Widget n)
    -> [FormFieldState s e n] -> [Widget n]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [FormFieldState s e n]
    es

    -- | Render a single form field collection. This is called internally by
    -- 'renderForm' but is exposed in cases where a form field state needs
    -- to be rendered outside of a 'Form', so 'renderForm' is probably what
    -- you want.
    renderFormFieldState :: (Eq n)
                         => FocusRing n
                         -> FormFieldState s e n
                         -> Widget n
    renderFormFieldState :: FocusRing n -> FormFieldState s e n -> Widget n
    renderFormFieldState fr :: FocusRing n
    fr (FormFieldState st :: b
    st _ fields :: [FormField a b e n]
    fields helper :: Widget n -> Widget n
    helper concatFields :: [Widget n] -> Widget n
    concatFields) =
        let renderFields :: [FormField a b e n] -> [Widget n]
    renderFields [] = []
            renderFields ((FormField n :: n
    n validate :: b -> Maybe a
    validate extValid :: Bool
    extValid renderField :: Bool -> b -> Widget n
    renderField _):fs :: [FormField a b e n]
    fs) =
                let maybeInvalid :: Widget n -> Widget n
    maybeInvalid = if (Maybe a -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe a -> Bool) -> Maybe a -> Bool
    forall a b. (a -> b) -> a -> b
    $ b -> Maybe a
    validate b
    st) Bool -> Bool -> Bool
    && Bool
    extValid
                                   then Widget n -> Widget n
    forall a. a -> a
    id
                                   else AttrName -> Widget n -> Widget n
    forall n. AttrName -> Widget n -> Widget n
    forceAttr AttrName
    invalidFormInputAttr
                    foc :: Bool
    foc = n -> Maybe n
    forall a. a -> Maybe a
    Just n
    n Maybe n -> Maybe n -> Bool
    forall a. Eq a => a -> a -> Bool
    == FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent FocusRing n
    fr
                in Widget n -> Widget n
    maybeInvalid (Bool -> b -> Widget n
    renderField Bool
    foc b
    st) Widget n -> [Widget n] -> [Widget n]
    forall a. a -> [a] -> [a]
    : [FormField a b e n] -> [Widget n]
    renderFields [FormField a b e n]
    fs
        in Widget n -> Widget n
    helper (Widget n -> Widget n) -> Widget n -> Widget n
    forall a b. (a -> b) -> a -> b
    $ [Widget n] -> Widget n
    concatFields ([Widget n] -> Widget n) -> [Widget n] -> Widget n
    forall a b. (a -> b) -> a -> b
    $ [FormField a b e n] -> [Widget n]
    renderFields [FormField a b e n]
    fields

    -- | Dispatch an event to the appropriate form field and return a new
    -- form. This handles the following events in this order:
    --
    -- * On @Tab@ keypresses, this changes the focus to the next field in
    --   the form.
    -- * On @Shift-Tab@ keypresses, this changes the focus to the previous
    --   field in the form.
    -- * On mouse button presses (regardless of button or modifier), the
    --   focus is changed to the clicked form field and the event is
    --   forwarded to the event handler for the clicked form field.
    -- * On @Left@ or @Up@, if the currently-focused field is part of a
    --   collection (e.g. radio buttons), the previous entry in the
    --   collection is focused.
    -- * On @Right@ or @Down@, if the currently-focused field is part of a
    --   collection (e.g. radio buttons), the next entry in the collection
    --   is focused.
    -- * All other events are forwarded to the currently focused form field.
    --
    -- In all cases where an event is forwarded to a form field, validation
    -- of the field's input state is performed immediately after the
    -- event has been handled. If the form field's input state succeeds
    -- validation using the field's validator function, its value is
    -- immediately stored in the form state using the form field's state
    -- lens. The external validation flag is ignored during this step to
    -- ensure that external validators have a chance to get the intermediate
    -- validated value.
    handleFormEvent :: (Eq n) => BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormEvent :: BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormEvent (VtyEvent (EvKey (KChar '\t') [])) f :: Form s e n
    f =
        Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = FocusRing n -> FocusRing n
    forall n. FocusRing n -> FocusRing n
    focusNext (FocusRing n -> FocusRing n) -> FocusRing n -> FocusRing n
    forall a b. (a -> b) -> a -> b
    $ Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f }
    handleFormEvent (VtyEvent (EvKey KBackTab [])) f :: Form s e n
    f =
        Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = FocusRing n -> FocusRing n
    forall n. FocusRing n -> FocusRing n
    focusPrev (FocusRing n -> FocusRing n) -> FocusRing n -> FocusRing n
    forall a b. (a -> b) -> a -> b
    $ Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f }
    handleFormEvent e :: BrickEvent n e
    e@(MouseDown n :: n
    n _ _ _) f :: Form s e n
    f =
        n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormFieldEvent n
    n BrickEvent n e
    e (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent n
    n (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e@(MouseUp n :: n
    n _ _) f :: Form s e n
    f =
        n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormFieldEvent n
    n BrickEvent n e
    e (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent n
    n (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e@(VtyEvent (EvKey KUp [])) f :: Form s e n
    f =
        case FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) of
            Nothing -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            Just n :: n
    n  ->
                case Form s e n -> n -> Maybe [n]
    forall n s e. Eq n => Form s e n -> n -> Maybe [n]
    getFocusGrouping Form s e n
    f n
    n of
                    Nothing -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent BrickEvent n e
    e Form s e n
    f
                    Just grp :: [n]
    grp -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent ([n] -> n -> n
    forall a. Eq a => [a] -> a -> a
    entryBefore [n]
    grp n
    n) (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e@(VtyEvent (EvKey KDown [])) f :: Form s e n
    f =
        case FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) of
            Nothing -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            Just n :: n
    n  ->
                case Form s e n -> n -> Maybe [n]
    forall n s e. Eq n => Form s e n -> n -> Maybe [n]
    getFocusGrouping Form s e n
    f n
    n of
                    Nothing -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent BrickEvent n e
    e Form s e n
    f
                    Just grp :: [n]
    grp -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent ([n] -> n -> n
    forall a. Eq a => [a] -> a -> a
    entryAfter [n]
    grp n
    n) (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e@(VtyEvent (EvKey KLeft [])) f :: Form s e n
    f =
        case FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) of
            Nothing -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            Just n :: n
    n  ->
                case Form s e n -> n -> Maybe [n]
    forall n s e. Eq n => Form s e n -> n -> Maybe [n]
    getFocusGrouping Form s e n
    f n
    n of
                    Nothing -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent BrickEvent n e
    e Form s e n
    f
                    Just grp :: [n]
    grp -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent ([n] -> n -> n
    forall a. Eq a => [a] -> a -> a
    entryBefore [n]
    grp n
    n) (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e@(VtyEvent (EvKey KRight [])) f :: Form s e n
    f =
        case FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) of
            Nothing -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            Just n :: n
    n  ->
                case Form s e n -> n -> Maybe [n]
    forall n s e. Eq n => Form s e n -> n -> Maybe [n]
    getFocusGrouping Form s e n
    f n
    n of
                    Nothing -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent BrickEvent n e
    e Form s e n
    f
                    Just grp :: [n]
    grp -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFocus :: FocusRing n
    formFocus = n -> FocusRing n -> FocusRing n
    forall n. Eq n => n -> FocusRing n -> FocusRing n
    focusSetCurrent ([n] -> n -> n
    forall a. Eq a => [a] -> a -> a
    entryAfter [n]
    grp n
    n) (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) }
    handleFormEvent e :: BrickEvent n e
    e f :: Form s e n
    f = BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent BrickEvent n e
    e Form s e n
    f

    getFocusGrouping :: (Eq n) => Form s e n -> n -> Maybe [n]
    getFocusGrouping :: Form s e n -> n -> Maybe [n]
    getFocusGrouping f :: Form s e n
    f n :: n
    n = [FormFieldState s e n] -> Maybe [n]
    findGroup (Form s e n -> [FormFieldState s e n]
    forall s e n. Form s e n -> [FormFieldState s e n]
    formFieldStates Form s e n
    f)
        where
            findGroup :: [FormFieldState s e n] -> Maybe [n]
    findGroup [] = Maybe [n]
    forall a. Maybe a
    Nothing
            findGroup (e :: FormFieldState s e n
    e:es :: [FormFieldState s e n]
    es) =
                let ns :: [n]
    ns = FormFieldState s e n -> [n]
    forall s e n. FormFieldState s e n -> [n]
    formFieldNames FormFieldState s e n
    e
                in if n
    n n -> [n] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [n]
    ns Bool -> Bool -> Bool
    && [n] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [n]
    ns Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 1
                   then [n] -> Maybe [n]
    forall a. a -> Maybe a
    Just [n]
    ns
                   else [FormFieldState s e n] -> Maybe [n]
    findGroup [FormFieldState s e n]
    es

    entryAfter :: (Eq a) => [a] -> a -> a
    entryAfter :: [a] -> a -> a
    entryAfter as :: [a]
    as a :: a
    a =
        let Just i :: Int
    i = a -> [a] -> Maybe Int
    forall a. Eq a => a -> [a] -> Maybe Int
    elemIndex a
    a [a]
    as
            i' :: Int
    i' = if Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    as Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1 then 0 else Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + 1
        in [a]
    as [a] -> Int -> a
    forall a. [a] -> Int -> a
    !! Int
    i'

    entryBefore :: (Eq a) => [a] -> a -> a
    entryBefore :: [a] -> a -> a
    entryBefore as :: [a]
    as a :: a
    a =
        let Just i :: Int
    i = a -> [a] -> Maybe Int
    forall a. Eq a => a -> [a] -> Maybe Int
    elemIndex a
    a [a]
    as
            i' :: Int
    i' = if Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 then [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    as Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1 else Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1
        in [a]
    as [a] -> Int -> a
    forall a. [a] -> Int -> a
    !! Int
    i'

    forwardToCurrent :: (Eq n) => BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent :: BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forwardToCurrent e :: BrickEvent n e
    e f :: Form s e n
    f =
        case FocusRing n -> Maybe n
    forall n. FocusRing n -> Maybe n
    focusGetCurrent (Form s e n -> FocusRing n
    forall s e n. Form s e n -> FocusRing n
    formFocus Form s e n
    f) of
            Nothing -> Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            Just n :: n
    n  -> n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    forall n e s.
    Eq n =>
    n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormFieldEvent n
    n BrickEvent n e
    e Form s e n
    f

    handleFormFieldEvent :: (Eq n) => n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormFieldEvent :: n -> BrickEvent n e -> Form s e n -> EventM n (Form s e n)
    handleFormFieldEvent n :: n
    n ev :: BrickEvent n e
    ev f :: Form s e n
    f = [FormFieldState s e n]
    -> [FormFieldState s e n] -> EventM n (Form s e n)
    findFieldState [] (Form s e n -> [FormFieldState s e n]
    forall s e n. Form s e n -> [FormFieldState s e n]
    formFieldStates Form s e n
    f)
        where
            findFieldState :: [FormFieldState s e n]
    -> [FormFieldState s e n] -> EventM n (Form s e n)
    findFieldState _ [] = Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return Form s e n
    f
            findFieldState prev :: [FormFieldState s e n]
    prev (e :: FormFieldState s e n
    e:es :: [FormFieldState s e n]
    es) =
                case FormFieldState s e n
    e of
                    FormFieldState st :: b
    st stLens :: Lens' s a
    stLens fields :: [FormField a b e n]
    fields helper :: Widget n -> Widget n
    helper concatAll :: [Widget n] -> Widget n
    concatAll -> do
                        let findField :: [FormField a b e n] -> EventM n (Maybe (b, Maybe a))
    findField [] = Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a))
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe (b, Maybe a)
    forall a. Maybe a
    Nothing
                            findField (field :: FormField a b e n
    field:rest :: [FormField a b e n]
    rest) =
                                case FormField a b e n
    field of
                                    FormField n' :: n
    n' validate :: b -> Maybe a
    validate _ _ handleFunc :: BrickEvent n e -> b -> EventM n b
    handleFunc | n
    n n -> n -> Bool
    forall a. Eq a => a -> a -> Bool
    == n
    n' -> do
                                        b
    nextSt <- BrickEvent n e -> b -> EventM n b
    handleFunc BrickEvent n e
    ev b
    st
                                        -- If the new state validates, go ahead and update
                                        -- the form state with it.
                                        case b -> Maybe a
    validate b
    nextSt of
                                            Nothing -> Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a)))
    -> Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a))
    forall a b. (a -> b) -> a -> b
    $ (b, Maybe a) -> Maybe (b, Maybe a)
    forall a. a -> Maybe a
    Just (b
    nextSt, Maybe a
    forall a. Maybe a
    Nothing)
                                            Just newSt :: a
    newSt -> Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a))
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a)))
    -> Maybe (b, Maybe a) -> EventM n (Maybe (b, Maybe a))
    forall a b. (a -> b) -> a -> b
    $ (b, Maybe a) -> Maybe (b, Maybe a)
    forall a. a -> Maybe a
    Just (b
    nextSt, a -> Maybe a
    forall a. a -> Maybe a
    Just a
    newSt)
                                    _ -> [FormField a b e n] -> EventM n (Maybe (b, Maybe a))
    findField [FormField a b e n]
    rest

                        Maybe (b, Maybe a)
    result <- [FormField a b e n] -> EventM n (Maybe (b, Maybe a))
    findField [FormField a b e n]
    fields
                        case Maybe (b, Maybe a)
    result of
                            Nothing -> [FormFieldState s e n]
    -> [FormFieldState s e n] -> EventM n (Form s e n)
    findFieldState ([FormFieldState s e n]
    prev [FormFieldState s e n]
    -> [FormFieldState s e n] -> [FormFieldState s e n]
    forall a. Semigroup a => a -> a -> a
    <> [FormFieldState s e n
    e]) [FormFieldState s e n]
    es
                            Just (newSt :: b
    newSt, maybeSt :: Maybe a
    maybeSt) ->
                                let newFieldState :: FormFieldState s e n
    newFieldState = b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    forall b s a e n.
    b
    -> Lens' s a
    -> [FormField a b e n]
    -> (Widget n -> Widget n)
    -> ([Widget n] -> Widget n)
    -> FormFieldState s e n
    FormFieldState b
    newSt Lens' s a
    stLens [FormField a b e n]
    fields Widget n -> Widget n
    helper [Widget n] -> Widget n
    concatAll
                                in Form s e n -> EventM n (Form s e n)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Form s e n -> EventM n (Form s e n))
    -> Form s e n -> EventM n (Form s e n)
    forall a b. (a -> b) -> a -> b
    $ Form s e n
    f { formFieldStates :: [FormFieldState s e n]
    formFieldStates = [FormFieldState s e n]
    prev [FormFieldState s e n]
    -> [FormFieldState s e n] -> [FormFieldState s e n]
    forall a. Semigroup a => a -> a -> a
    <> [FormFieldState s e n
    newFieldState] [FormFieldState s e n]
    -> [FormFieldState s e n] -> [FormFieldState s e n]
    forall a. Semigroup a => a -> a -> a
    <> [FormFieldState s e n]
    es
                                              , formState :: s
    formState = case Maybe a
    maybeSt of
                                                  Nothing -> Form s e n -> s
    forall s e n. Form s e n -> s
    formState Form s e n
    f
                                                  Just s :: a
    s  -> Form s e n -> s
    forall s e n. Form s e n -> s
    formState Form s e n
    f s -> (s -> s) -> s
    forall a b. a -> (a -> b) -> b
    & (a -> Identity a) -> s -> Identity s
    Lens' s a
    stLens ((a -> Identity a) -> s -> Identity s) -> a -> s -> s
    forall s t a b. ASetter s t a b -> b -> s -> t
    .~ a
    s
                                              }