packages feed

vty-ui 1.0.1 → 1.1

raw patch · 37 files changed

+532/−454 lines, 37 filesdep ~containersdep ~directorydep ~filepathPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: containers, directory, filepath, time

API changes (from Hackage documentation)

+ Graphics.Vty.Widgets.EventLoop: shutdownUi :: IO ()
+ Graphics.Vty.Widgets.List: getListItem :: Widget (List a b) -> Int -> IO (Maybe (ListItem a b))
+ Graphics.Vty.Widgets.List: insertIntoList :: Show b => Widget (List a b) -> a -> Widget b -> Int -> IO ()
+ Graphics.Vty.Widgets.List: setSelected :: Widget (List a b) -> Int -> IO ()
+ Graphics.Vty.Widgets.Util: inject :: Int -> a -> [a] -> [a]
+ Graphics.Vty.Widgets.Util: remove :: Int -> [a] -> [a]
+ Graphics.Vty.Widgets.Util: repl :: Int -> a -> [a] -> [a]
- Graphics.Vty.Widgets.Borders: bordered :: (MonadIO m, Show a) => Widget a -> m (Widget (Bordered a))
+ Graphics.Vty.Widgets.Borders: bordered :: Show a => Widget a -> IO (Widget (Bordered a))
- Graphics.Vty.Widgets.Borders: hBorder :: MonadIO m => m (Widget HBorder)
+ Graphics.Vty.Widgets.Borders: hBorder :: IO (Widget HBorder)
- Graphics.Vty.Widgets.Borders: setBorderAttribute :: (HasBorderAttr a, MonadIO m) => a -> Attr -> m ()
+ Graphics.Vty.Widgets.Borders: setBorderAttribute :: HasBorderAttr a => a -> Attr -> IO ()
- Graphics.Vty.Widgets.Borders: setBorderedLabel :: MonadIO m => Widget (Bordered a) -> String -> m ()
+ Graphics.Vty.Widgets.Borders: setBorderedLabel :: Widget (Bordered a) -> String -> IO ()
- Graphics.Vty.Widgets.Borders: setHBorderLabel :: MonadIO m => Widget HBorder -> String -> m ()
+ Graphics.Vty.Widgets.Borders: setHBorderLabel :: Widget HBorder -> String -> IO ()
- Graphics.Vty.Widgets.Borders: vBorder :: MonadIO m => m (Widget VBorder)
+ Graphics.Vty.Widgets.Borders: vBorder :: IO (Widget VBorder)
- Graphics.Vty.Widgets.Borders: withBorderAttribute :: (MonadIO m, HasBorderAttr a) => Attr -> a -> m a
+ Graphics.Vty.Widgets.Borders: withBorderAttribute :: HasBorderAttr a => Attr -> a -> IO a
- Graphics.Vty.Widgets.Borders: withBorderedLabel :: MonadIO m => String -> Widget (Bordered a) -> m (Widget (Bordered a))
+ Graphics.Vty.Widgets.Borders: withBorderedLabel :: String -> Widget (Bordered a) -> IO (Widget (Bordered a))
- Graphics.Vty.Widgets.Borders: withHBorderLabel :: MonadIO m => String -> Widget HBorder -> m (Widget HBorder)
+ Graphics.Vty.Widgets.Borders: withHBorderLabel :: String -> Widget HBorder -> IO (Widget HBorder)
- Graphics.Vty.Widgets.Box: (<++>) :: (MonadIO m, Show a, Show b) => m (Widget a) -> m (Widget b) -> m (Widget (Box a b))
+ Graphics.Vty.Widgets.Box: (<++>) :: (Show a, Show b) => IO (Widget a) -> IO (Widget b) -> IO (Widget (Box a b))
- Graphics.Vty.Widgets.Box: (<-->) :: (MonadIO m, Show a, Show b) => m (Widget a) -> m (Widget b) -> m (Widget (Box a b))
+ Graphics.Vty.Widgets.Box: (<-->) :: (Show a, Show b) => IO (Widget a) -> IO (Widget b) -> IO (Widget (Box a b))
- Graphics.Vty.Widgets.Box: getBoxChildSizePolicy :: MonadIO m => Widget (Box a b) -> m ChildSizePolicy
+ Graphics.Vty.Widgets.Box: getBoxChildSizePolicy :: Widget (Box a b) -> IO ChildSizePolicy
- Graphics.Vty.Widgets.Box: getFirstChild :: MonadIO m => Widget (Box a b) -> m (Widget a)
+ Graphics.Vty.Widgets.Box: getFirstChild :: Widget (Box a b) -> IO (Widget a)
- Graphics.Vty.Widgets.Box: getSecondChild :: MonadIO m => Widget (Box a b) -> m (Widget b)
+ Graphics.Vty.Widgets.Box: getSecondChild :: Widget (Box a b) -> IO (Widget b)
- Graphics.Vty.Widgets.Box: hBox :: (MonadIO m, Show a, Show b) => Widget a -> Widget b -> m (Widget (Box a b))
+ Graphics.Vty.Widgets.Box: hBox :: (Show a, Show b) => Widget a -> Widget b -> IO (Widget (Box a b))
- Graphics.Vty.Widgets.Box: setBoxChildSizePolicy :: MonadIO m => Widget (Box a b) -> ChildSizePolicy -> m ()
+ Graphics.Vty.Widgets.Box: setBoxChildSizePolicy :: Widget (Box a b) -> ChildSizePolicy -> IO ()
- Graphics.Vty.Widgets.Box: setBoxSpacing :: MonadIO m => Widget (Box a b) -> Int -> m ()
+ Graphics.Vty.Widgets.Box: setBoxSpacing :: Widget (Box a b) -> Int -> IO ()
- Graphics.Vty.Widgets.Box: vBox :: (MonadIO m, Show a, Show b) => Widget a -> Widget b -> m (Widget (Box a b))
+ Graphics.Vty.Widgets.Box: vBox :: (Show a, Show b) => Widget a -> Widget b -> IO (Widget (Box a b))
- Graphics.Vty.Widgets.Box: withBoxSpacing :: MonadIO m => Int -> Widget (Box a b) -> m (Widget (Box a b))
+ Graphics.Vty.Widgets.Box: withBoxSpacing :: Int -> Widget (Box a b) -> IO (Widget (Box a b))
- Graphics.Vty.Widgets.Button: newButton :: MonadIO m => String -> m Button
+ Graphics.Vty.Widgets.Button: newButton :: String -> IO Button
- Graphics.Vty.Widgets.Button: onButtonPressed :: MonadIO m => Button -> (Button -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Button: onButtonPressed :: Button -> (Button -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Button: pressButton :: MonadIO m => Button -> m ()
+ Graphics.Vty.Widgets.Button: pressButton :: Button -> IO ()
- Graphics.Vty.Widgets.Button: setButtonText :: MonadIO m => Button -> String -> m ()
+ Graphics.Vty.Widgets.Button: setButtonText :: Button -> String -> IO ()
- Graphics.Vty.Widgets.Centering: centered :: (MonadIO m, Show a) => Widget a -> m (Widget (VCentered (HCentered a)))
+ Graphics.Vty.Widgets.Centering: centered :: Show a => Widget a -> IO (Widget (VCentered (HCentered a)))
- Graphics.Vty.Widgets.Centering: hCentered :: (MonadIO m, Show a) => Widget a -> m (Widget (HCentered a))
+ Graphics.Vty.Widgets.Centering: hCentered :: Show a => Widget a -> IO (Widget (HCentered a))
- Graphics.Vty.Widgets.Centering: vCentered :: (MonadIO m, Show a) => Widget a -> m (Widget (VCentered a))
+ Graphics.Vty.Widgets.Centering: vCentered :: Show a => Widget a -> IO (Widget (VCentered a))
- Graphics.Vty.Widgets.CheckBox: addToRadioGroup :: MonadIO m => RadioGroup -> Widget (CheckBox Bool) -> m ()
+ Graphics.Vty.Widgets.CheckBox: addToRadioGroup :: RadioGroup -> Widget (CheckBox Bool) -> IO ()
- Graphics.Vty.Widgets.CheckBox: cycleCheckbox :: (Eq a, MonadIO m) => Widget (CheckBox a) -> m ()
+ Graphics.Vty.Widgets.CheckBox: cycleCheckbox :: Eq a => Widget (CheckBox a) -> IO ()
- Graphics.Vty.Widgets.CheckBox: getCheckboxLabel :: MonadIO m => Widget (CheckBox a) -> m String
+ Graphics.Vty.Widgets.CheckBox: getCheckboxLabel :: Widget (CheckBox a) -> IO String
- Graphics.Vty.Widgets.CheckBox: getCheckboxState :: MonadIO m => Widget (CheckBox a) -> m a
+ Graphics.Vty.Widgets.CheckBox: getCheckboxState :: Widget (CheckBox a) -> IO a
- Graphics.Vty.Widgets.CheckBox: getCurrentRadio :: MonadIO m => RadioGroup -> m (Maybe (Widget (CheckBox Bool)))
+ Graphics.Vty.Widgets.CheckBox: getCurrentRadio :: RadioGroup -> IO (Maybe (Widget (CheckBox Bool)))
- Graphics.Vty.Widgets.CheckBox: newCheckbox :: MonadIO m => String -> m (Widget (CheckBox Bool))
+ Graphics.Vty.Widgets.CheckBox: newCheckbox :: String -> IO (Widget (CheckBox Bool))
- Graphics.Vty.Widgets.CheckBox: newMultiStateCheckbox :: (Eq a, MonadIO m) => String -> [(a, Char)] -> m (Widget (CheckBox a))
+ Graphics.Vty.Widgets.CheckBox: newMultiStateCheckbox :: Eq a => String -> [(a, Char)] -> IO (Widget (CheckBox a))
- Graphics.Vty.Widgets.CheckBox: newRadioGroup :: MonadIO m => m RadioGroup
+ Graphics.Vty.Widgets.CheckBox: newRadioGroup :: IO RadioGroup
- Graphics.Vty.Widgets.CheckBox: onCheckboxChange :: MonadIO m => Widget (CheckBox a) -> (a -> IO ()) -> m ()
+ Graphics.Vty.Widgets.CheckBox: onCheckboxChange :: Widget (CheckBox a) -> (a -> IO ()) -> IO ()
- Graphics.Vty.Widgets.CheckBox: onRadioChange :: MonadIO m => RadioGroup -> (Widget (CheckBox Bool) -> IO ()) -> m ()
+ Graphics.Vty.Widgets.CheckBox: onRadioChange :: RadioGroup -> (Widget (CheckBox Bool) -> IO ()) -> IO ()
- Graphics.Vty.Widgets.CheckBox: setBracketChars :: MonadIO m => Widget (CheckBox a) -> Char -> Char -> m ()
+ Graphics.Vty.Widgets.CheckBox: setBracketChars :: Widget (CheckBox a) -> Char -> Char -> IO ()
- Graphics.Vty.Widgets.CheckBox: setCheckboxChecked :: MonadIO m => Widget (CheckBox Bool) -> m ()
+ Graphics.Vty.Widgets.CheckBox: setCheckboxChecked :: Widget (CheckBox Bool) -> IO ()
- Graphics.Vty.Widgets.CheckBox: setCheckboxState :: (Eq a, MonadIO m) => Widget (CheckBox a) -> a -> m ()
+ Graphics.Vty.Widgets.CheckBox: setCheckboxState :: Eq a => Widget (CheckBox a) -> a -> IO ()
- Graphics.Vty.Widgets.CheckBox: setCheckboxUnchecked :: MonadIO m => Widget (CheckBox Bool) -> m ()
+ Graphics.Vty.Widgets.CheckBox: setCheckboxUnchecked :: Widget (CheckBox Bool) -> IO ()
- Graphics.Vty.Widgets.CheckBox: setStateChar :: (Eq a, MonadIO m) => Widget (CheckBox a) -> a -> Char -> m ()
+ Graphics.Vty.Widgets.CheckBox: setStateChar :: Eq a => Widget (CheckBox a) -> a -> Char -> IO ()
- Graphics.Vty.Widgets.CheckBox: toggleCheckbox :: MonadIO m => Widget (CheckBox Bool) -> m ()
+ Graphics.Vty.Widgets.CheckBox: toggleCheckbox :: Widget (CheckBox Bool) -> IO ()
- Graphics.Vty.Widgets.Core: (<~) :: MonadIO m => (a -> b) -> IORef a -> m b
+ Graphics.Vty.Widgets.Core: (<~) :: (a -> b) -> IORef a -> IO b
- Graphics.Vty.Widgets.Core: (<~~) :: MonadIO m => (a -> b) -> Widget a -> m b
+ Graphics.Vty.Widgets.Core: (<~~) :: (a -> b) -> Widget a -> IO b
- Graphics.Vty.Widgets.Core: addToFocusGroup :: (MonadIO m, Show a) => Widget FocusGroup -> Widget a -> m (Widget FocusEntry)
+ Graphics.Vty.Widgets.Core: addToFocusGroup :: Show a => Widget FocusGroup -> Widget a -> IO (Widget FocusEntry)
- Graphics.Vty.Widgets.Core: focus :: MonadIO m => Widget a -> m ()
+ Graphics.Vty.Widgets.Core: focus :: Widget a -> IO ()
- Graphics.Vty.Widgets.Core: focusNext :: MonadIO m => Widget FocusGroup -> m ()
+ Graphics.Vty.Widgets.Core: focusNext :: Widget FocusGroup -> IO ()
- Graphics.Vty.Widgets.Core: focusPrevious :: MonadIO m => Widget FocusGroup -> m ()
+ Graphics.Vty.Widgets.Core: focusPrevious :: Widget FocusGroup -> IO ()
- Graphics.Vty.Widgets.Core: getCurrentPosition :: (MonadIO m, Functor m) => Widget a -> m DisplayRegion
+ Graphics.Vty.Widgets.Core: getCurrentPosition :: Widget a -> IO DisplayRegion
- Graphics.Vty.Widgets.Core: getCurrentSize :: MonadIO m => Widget a -> m DisplayRegion
+ Graphics.Vty.Widgets.Core: getCurrentSize :: Widget a -> IO DisplayRegion
- Graphics.Vty.Widgets.Core: getCursorPosition :: MonadIO m => Widget a -> m (Maybe DisplayRegion)
+ Graphics.Vty.Widgets.Core: getCursorPosition :: Widget a -> IO (Maybe DisplayRegion)
- Graphics.Vty.Widgets.Core: getState :: MonadIO m => Widget a -> m a
+ Graphics.Vty.Widgets.Core: getState :: Widget a -> IO a
- Graphics.Vty.Widgets.Core: growHorizontal :: MonadIO m => Widget a -> m Bool
+ Graphics.Vty.Widgets.Core: growHorizontal :: Widget a -> IO Bool
- Graphics.Vty.Widgets.Core: growVertical :: MonadIO m => Widget a -> m Bool
+ Graphics.Vty.Widgets.Core: growVertical :: Widget a -> IO Bool
- Graphics.Vty.Widgets.Core: handleKeyEvent :: MonadIO m => Widget a -> Key -> [Modifier] -> m Bool
+ Graphics.Vty.Widgets.Core: handleKeyEvent :: Widget a -> Key -> [Modifier] -> IO Bool
- Graphics.Vty.Widgets.Core: mergeFocusGroups :: MonadIO m => Widget FocusGroup -> Widget FocusGroup -> m (Widget FocusGroup)
+ Graphics.Vty.Widgets.Core: mergeFocusGroups :: Widget FocusGroup -> Widget FocusGroup -> IO (Widget FocusGroup)
- Graphics.Vty.Widgets.Core: newFocusGroup :: MonadIO m => m (Widget FocusGroup)
+ Graphics.Vty.Widgets.Core: newFocusGroup :: IO (Widget FocusGroup)
- Graphics.Vty.Widgets.Core: newWidget :: MonadIO m => (WidgetImpl a -> WidgetImpl a) -> m (Widget a)
+ Graphics.Vty.Widgets.Core: newWidget :: (WidgetImpl a -> WidgetImpl a) -> IO (Widget a)
- Graphics.Vty.Widgets.Core: onGainFocus :: MonadIO m => Widget a -> (Widget a -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Core: onGainFocus :: Widget a -> (Widget a -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Core: onKeyPressed :: MonadIO m => Widget a -> (Widget a -> Key -> [Modifier] -> IO Bool) -> m ()
+ Graphics.Vty.Widgets.Core: onKeyPressed :: Widget a -> (Widget a -> Key -> [Modifier] -> IO Bool) -> IO ()
- Graphics.Vty.Widgets.Core: onLoseFocus :: MonadIO m => Widget a -> (Widget a -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Core: onLoseFocus :: Widget a -> (Widget a -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Core: relayFocusEvents :: MonadIO m => Widget a -> Widget b -> m ()
+ Graphics.Vty.Widgets.Core: relayFocusEvents :: Widget a -> Widget b -> IO ()
- Graphics.Vty.Widgets.Core: relayKeyEvents :: MonadIO m => Widget a -> Widget b -> m ()
+ Graphics.Vty.Widgets.Core: relayKeyEvents :: Widget a -> Widget b -> IO ()
- Graphics.Vty.Widgets.Core: render :: (MonadIO m, Show a) => Widget a -> DisplayRegion -> RenderContext -> m Image
+ Graphics.Vty.Widgets.Core: render :: Show a => Widget a -> DisplayRegion -> RenderContext -> IO Image
- Graphics.Vty.Widgets.Core: renderAndPosition :: (MonadIO m, Show a) => Widget a -> DisplayRegion -> DisplayRegion -> RenderContext -> m Image
+ Graphics.Vty.Widgets.Core: renderAndPosition :: Show a => Widget a -> DisplayRegion -> DisplayRegion -> RenderContext -> IO Image
- Graphics.Vty.Widgets.Core: resetFocusGroup :: MonadIO m => Widget FocusGroup -> m ()
+ Graphics.Vty.Widgets.Core: resetFocusGroup :: Widget FocusGroup -> IO ()
- Graphics.Vty.Widgets.Core: setCurrentPosition :: MonadIO m => Widget a -> DisplayRegion -> m ()
+ Graphics.Vty.Widgets.Core: setCurrentPosition :: Widget a -> DisplayRegion -> IO ()
- Graphics.Vty.Widgets.Core: setFocusAttribute :: (HasFocusAttr w, MonadIO m) => w -> Attr -> m ()
+ Graphics.Vty.Widgets.Core: setFocusAttribute :: HasFocusAttr w => w -> Attr -> IO ()
- Graphics.Vty.Widgets.Core: setFocusGroupNextKey :: MonadIO m => Widget FocusGroup -> Key -> [Modifier] -> m ()
+ Graphics.Vty.Widgets.Core: setFocusGroupNextKey :: Widget FocusGroup -> Key -> [Modifier] -> IO ()
- Graphics.Vty.Widgets.Core: setFocusGroupPrevKey :: MonadIO m => Widget FocusGroup -> Key -> [Modifier] -> m ()
+ Graphics.Vty.Widgets.Core: setFocusGroupPrevKey :: Widget FocusGroup -> Key -> [Modifier] -> IO ()
- Graphics.Vty.Widgets.Core: setNormalAttribute :: (HasNormalAttr w, MonadIO m) => w -> Attr -> m ()
+ Graphics.Vty.Widgets.Core: setNormalAttribute :: HasNormalAttr w => w -> Attr -> IO ()
- Graphics.Vty.Widgets.Core: showWidget :: (Functor m, MonadIO m, Show a) => Widget a -> m String
+ Graphics.Vty.Widgets.Core: showWidget :: Show a => Widget a -> IO String
- Graphics.Vty.Widgets.Core: unfocus :: MonadIO m => Widget a -> m ()
+ Graphics.Vty.Widgets.Core: unfocus :: Widget a -> IO ()
- Graphics.Vty.Widgets.Core: updateWidget :: MonadIO m => Widget a -> (WidgetImpl a -> WidgetImpl a) -> m ()
+ Graphics.Vty.Widgets.Core: updateWidget :: Widget a -> (WidgetImpl a -> WidgetImpl a) -> IO ()
- Graphics.Vty.Widgets.Core: updateWidgetState :: MonadIO m => Widget a -> (a -> a) -> m ()
+ Graphics.Vty.Widgets.Core: updateWidgetState :: Widget a -> (a -> a) -> IO ()
- Graphics.Vty.Widgets.Core: withFocusAttribute :: (HasFocusAttr w, MonadIO m) => Attr -> w -> m w
+ Graphics.Vty.Widgets.Core: withFocusAttribute :: HasFocusAttr w => Attr -> w -> IO w
- Graphics.Vty.Widgets.Core: withNormalAttribute :: (HasNormalAttr w, MonadIO m) => Attr -> w -> m w
+ Graphics.Vty.Widgets.Core: withNormalAttribute :: HasNormalAttr w => Attr -> w -> IO w
- Graphics.Vty.Widgets.Dialog: acceptDialog :: MonadIO m => Dialog -> m ()
+ Graphics.Vty.Widgets.Dialog: acceptDialog :: Dialog -> IO ()
- Graphics.Vty.Widgets.Dialog: cancelDialog :: MonadIO m => Dialog -> m ()
+ Graphics.Vty.Widgets.Dialog: cancelDialog :: Dialog -> IO ()
- Graphics.Vty.Widgets.Dialog: newDialog :: (MonadIO m, Show a) => Widget a -> String -> m (Dialog, Widget FocusGroup)
+ Graphics.Vty.Widgets.Dialog: newDialog :: Show a => Widget a -> String -> IO (Dialog, Widget FocusGroup)
- Graphics.Vty.Widgets.Dialog: onDialogAccept :: MonadIO m => Dialog -> (Dialog -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Dialog: onDialogAccept :: Dialog -> (Dialog -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Dialog: onDialogCancel :: MonadIO m => Dialog -> (Dialog -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Dialog: onDialogCancel :: Dialog -> (Dialog -> IO ()) -> IO ()
- Graphics.Vty.Widgets.DirBrowser: getDirBrowserPath :: MonadIO m => DirBrowser -> m FilePath
+ Graphics.Vty.Widgets.DirBrowser: getDirBrowserPath :: DirBrowser -> IO FilePath
- Graphics.Vty.Widgets.DirBrowser: newDirBrowser :: MonadIO m => BrowserSkin -> m (DirBrowser, Widget FocusGroup)
+ Graphics.Vty.Widgets.DirBrowser: newDirBrowser :: BrowserSkin -> IO (DirBrowser, Widget FocusGroup)
- Graphics.Vty.Widgets.DirBrowser: onBrowseAccept :: MonadIO m => DirBrowser -> (FilePath -> IO ()) -> m ()
+ Graphics.Vty.Widgets.DirBrowser: onBrowseAccept :: DirBrowser -> (FilePath -> IO ()) -> IO ()
- Graphics.Vty.Widgets.DirBrowser: onBrowseCancel :: MonadIO m => DirBrowser -> (FilePath -> IO ()) -> m ()
+ Graphics.Vty.Widgets.DirBrowser: onBrowseCancel :: DirBrowser -> (FilePath -> IO ()) -> IO ()
- Graphics.Vty.Widgets.DirBrowser: onBrowserPathChange :: MonadIO m => DirBrowser -> (FilePath -> IO ()) -> m ()
+ Graphics.Vty.Widgets.DirBrowser: onBrowserPathChange :: DirBrowser -> (FilePath -> IO ()) -> IO ()
- Graphics.Vty.Widgets.DirBrowser: refreshBrowser :: MonadIO m => DirBrowser -> m ()
+ Graphics.Vty.Widgets.DirBrowser: refreshBrowser :: DirBrowser -> IO ()
- Graphics.Vty.Widgets.DirBrowser: reportBrowserError :: MonadIO m => DirBrowser -> String -> m ()
+ Graphics.Vty.Widgets.DirBrowser: reportBrowserError :: DirBrowser -> String -> IO ()
- Graphics.Vty.Widgets.DirBrowser: setDirBrowserPath :: MonadIO m => DirBrowser -> FilePath -> m ()
+ Graphics.Vty.Widgets.DirBrowser: setDirBrowserPath :: DirBrowser -> FilePath -> IO ()
- Graphics.Vty.Widgets.Edit: editWidget :: MonadIO m => m (Widget Edit)
+ Graphics.Vty.Widgets.Edit: editWidget :: IO (Widget Edit)
- Graphics.Vty.Widgets.Edit: getEditCursorPosition :: MonadIO m => Widget Edit -> m Int
+ Graphics.Vty.Widgets.Edit: getEditCursorPosition :: Widget Edit -> IO Int
- Graphics.Vty.Widgets.Edit: getEditText :: MonadIO m => Widget Edit -> m String
+ Graphics.Vty.Widgets.Edit: getEditText :: Widget Edit -> IO String
- Graphics.Vty.Widgets.Edit: onActivate :: MonadIO m => Widget Edit -> (Widget Edit -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Edit: onActivate :: Widget Edit -> (Widget Edit -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Edit: onChange :: MonadIO m => Widget Edit -> (String -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Edit: onChange :: Widget Edit -> (String -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Edit: onCursorMove :: MonadIO m => Widget Edit -> (Int -> IO ()) -> m ()
+ Graphics.Vty.Widgets.Edit: onCursorMove :: Widget Edit -> (Int -> IO ()) -> IO ()
- Graphics.Vty.Widgets.Edit: setEditCursorPosition :: MonadIO m => Widget Edit -> Int -> m ()
+ Graphics.Vty.Widgets.Edit: setEditCursorPosition :: Widget Edit -> Int -> IO ()
- Graphics.Vty.Widgets.Edit: setEditMaxLength :: MonadIO m => Widget Edit -> Int -> m ()
+ Graphics.Vty.Widgets.Edit: setEditMaxLength :: Widget Edit -> Int -> IO ()
- Graphics.Vty.Widgets.Edit: setEditText :: MonadIO m => Widget Edit -> String -> m ()
+ Graphics.Vty.Widgets.Edit: setEditText :: Widget Edit -> String -> IO ()
- Graphics.Vty.Widgets.EventLoop: addToCollection :: (MonadIO m, Show a) => Collection -> Widget a -> Widget FocusGroup -> m (m ())
+ Graphics.Vty.Widgets.EventLoop: addToCollection :: Show a => Collection -> Widget a -> Widget FocusGroup -> IO (IO ())
- Graphics.Vty.Widgets.EventLoop: newCollection :: MonadIO m => m Collection
+ Graphics.Vty.Widgets.EventLoop: newCollection :: IO Collection
- Graphics.Vty.Widgets.EventLoop: runUi :: MonadIO m => Collection -> RenderContext -> m ()
+ Graphics.Vty.Widgets.EventLoop: runUi :: Collection -> RenderContext -> IO ()
- Graphics.Vty.Widgets.EventLoop: schedule :: MonadIO m => IO () -> m ()
+ Graphics.Vty.Widgets.EventLoop: schedule :: IO () -> IO ()
- Graphics.Vty.Widgets.EventLoop: setCurrentEntry :: MonadIO m => Collection -> Int -> m ()
+ Graphics.Vty.Widgets.EventLoop: setCurrentEntry :: Collection -> Int -> IO ()
- Graphics.Vty.Widgets.Events: addHandler :: MonadIO m => (w -> m (Handlers a)) -> w -> Handler a -> m ()
+ Graphics.Vty.Widgets.Events: addHandler :: (w -> IO (Handlers a)) -> w -> Handler a -> IO ()
- Graphics.Vty.Widgets.Events: fireEvent :: MonadIO m => w -> (w -> m (Handlers a)) -> a -> m ()
+ Graphics.Vty.Widgets.Events: fireEvent :: w -> (w -> IO (Handlers a)) -> a -> IO ()
- Graphics.Vty.Widgets.Events: newHandlers :: MonadIO m => m (Handlers a)
+ Graphics.Vty.Widgets.Events: newHandlers :: IO (Handlers a)
- Graphics.Vty.Widgets.Fills: hFill :: MonadIO m => Char -> Int -> m (Widget HFill)
+ Graphics.Vty.Widgets.Fills: hFill :: Char -> Int -> IO (Widget HFill)
- Graphics.Vty.Widgets.Fills: vFill :: MonadIO m => Char -> m (Widget VFill)
+ Graphics.Vty.Widgets.Fills: vFill :: Char -> IO (Widget VFill)
- Graphics.Vty.Widgets.Fixed: addToHFixed :: MonadIO m => Widget (HFixed a) -> Int -> m ()
+ Graphics.Vty.Widgets.Fixed: addToHFixed :: Widget (HFixed a) -> Int -> IO ()
- Graphics.Vty.Widgets.Fixed: addToVFixed :: MonadIO m => Widget (VFixed a) -> Int -> m ()
+ Graphics.Vty.Widgets.Fixed: addToVFixed :: Widget (VFixed a) -> Int -> IO ()
- Graphics.Vty.Widgets.Fixed: boxFixed :: (MonadIO m, Show a) => Int -> Int -> Widget a -> m (Widget (VFixed (HFixed a)))
+ Graphics.Vty.Widgets.Fixed: boxFixed :: Show a => Int -> Int -> Widget a -> IO (Widget (VFixed (HFixed a)))
- Graphics.Vty.Widgets.Fixed: getHFixedSize :: MonadIO m => Widget (HFixed a) -> m Int
+ Graphics.Vty.Widgets.Fixed: getHFixedSize :: Widget (HFixed a) -> IO Int
- Graphics.Vty.Widgets.Fixed: getVFixedSize :: MonadIO m => Widget (VFixed a) -> m Int
+ Graphics.Vty.Widgets.Fixed: getVFixedSize :: Widget (VFixed a) -> IO Int
- Graphics.Vty.Widgets.Fixed: hFixed :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (HFixed a))
+ Graphics.Vty.Widgets.Fixed: hFixed :: Show a => Int -> Widget a -> IO (Widget (HFixed a))
- Graphics.Vty.Widgets.Fixed: setHFixed :: MonadIO m => Widget (HFixed a) -> Int -> m ()
+ Graphics.Vty.Widgets.Fixed: setHFixed :: Widget (HFixed a) -> Int -> IO ()
- Graphics.Vty.Widgets.Fixed: setVFixed :: MonadIO m => Widget (VFixed a) -> Int -> m ()
+ Graphics.Vty.Widgets.Fixed: setVFixed :: Widget (VFixed a) -> Int -> IO ()
- Graphics.Vty.Widgets.Fixed: vFixed :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (VFixed a))
+ Graphics.Vty.Widgets.Fixed: vFixed :: Show a => Int -> Widget a -> IO (Widget (VFixed a))
- Graphics.Vty.Widgets.Limits: addToHLimit :: MonadIO m => Widget (HLimit a) -> Int -> m ()
+ Graphics.Vty.Widgets.Limits: addToHLimit :: Widget (HLimit a) -> Int -> IO ()
- Graphics.Vty.Widgets.Limits: addToVLimit :: MonadIO m => Widget (VLimit a) -> Int -> m ()
+ Graphics.Vty.Widgets.Limits: addToVLimit :: Widget (VLimit a) -> Int -> IO ()
- Graphics.Vty.Widgets.Limits: boxLimit :: (MonadIO m, Show a) => Int -> Int -> Widget a -> m (Widget (VLimit (HLimit a)))
+ Graphics.Vty.Widgets.Limits: boxLimit :: Show a => Int -> Int -> Widget a -> IO (Widget (VLimit (HLimit a)))
- Graphics.Vty.Widgets.Limits: getHLimit :: MonadIO m => Widget (HLimit a) -> m Int
+ Graphics.Vty.Widgets.Limits: getHLimit :: Widget (HLimit a) -> IO Int
- Graphics.Vty.Widgets.Limits: getVLimit :: MonadIO m => Widget (VLimit a) -> m Int
+ Graphics.Vty.Widgets.Limits: getVLimit :: Widget (VLimit a) -> IO Int
- Graphics.Vty.Widgets.Limits: hLimit :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (HLimit a))
+ Graphics.Vty.Widgets.Limits: hLimit :: Show a => Int -> Widget a -> IO (Widget (HLimit a))
- Graphics.Vty.Widgets.Limits: setHLimit :: MonadIO m => Widget (HLimit a) -> Int -> m ()
+ Graphics.Vty.Widgets.Limits: setHLimit :: Widget (HLimit a) -> Int -> IO ()
- Graphics.Vty.Widgets.Limits: setVLimit :: MonadIO m => Widget (VLimit a) -> Int -> m ()
+ Graphics.Vty.Widgets.Limits: setVLimit :: Widget (VLimit a) -> Int -> IO ()
- Graphics.Vty.Widgets.Limits: vLimit :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (VLimit a))
+ Graphics.Vty.Widgets.Limits: vLimit :: Show a => Int -> Widget a -> IO (Widget (VLimit a))
- Graphics.Vty.Widgets.List: activateCurrentItem :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: activateCurrentItem :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.List: addToList :: (MonadIO m, Show b) => Widget (List a b) -> a -> m (ListItem a b)
+ Graphics.Vty.Widgets.List: addToList :: Show b => Widget (List a b) -> a -> Widget b -> IO ()
- Graphics.Vty.Widgets.List: clearList :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: clearList :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.List: getListSize :: MonadIO m => Widget (List a b) -> m Int
+ Graphics.Vty.Widgets.List: getListSize :: Widget (List a b) -> IO Int
- Graphics.Vty.Widgets.List: getSelected :: MonadIO m => Widget (List a b) -> m (Maybe (Int, ListItem a b))
+ Graphics.Vty.Widgets.List: getSelected :: Widget (List a b) -> IO (Maybe (Int, ListItem a b))
- Graphics.Vty.Widgets.List: newList :: (MonadIO m, Show b) => Attr -> (a -> IO (Widget b)) -> m (Widget (List a b))
+ Graphics.Vty.Widgets.List: newList :: Show b => Attr -> IO (Widget (List a b))
- Graphics.Vty.Widgets.List: newStringList :: MonadIO m => Attr -> [String] -> m (Widget (List String FormattedText))
+ Graphics.Vty.Widgets.List: newStringList :: Attr -> [String] -> IO (Widget (List String FormattedText))
- Graphics.Vty.Widgets.List: onItemActivated :: MonadIO m => Widget (List a b) -> (ActivateItemEvent a b -> IO ()) -> m ()
+ Graphics.Vty.Widgets.List: onItemActivated :: Widget (List a b) -> (ActivateItemEvent a b -> IO ()) -> IO ()
- Graphics.Vty.Widgets.List: onItemAdded :: MonadIO m => Widget (List a b) -> (NewItemEvent a b -> IO ()) -> m ()
+ Graphics.Vty.Widgets.List: onItemAdded :: Widget (List a b) -> (NewItemEvent a b -> IO ()) -> IO ()
- Graphics.Vty.Widgets.List: onItemRemoved :: MonadIO m => Widget (List a b) -> (RemoveItemEvent a b -> IO ()) -> m ()
+ Graphics.Vty.Widgets.List: onItemRemoved :: Widget (List a b) -> (RemoveItemEvent a b -> IO ()) -> IO ()
- Graphics.Vty.Widgets.List: onSelectionChange :: MonadIO m => Widget (List a b) -> (SelectionEvent a b -> IO ()) -> m ()
+ Graphics.Vty.Widgets.List: onSelectionChange :: Widget (List a b) -> (SelectionEvent a b -> IO ()) -> IO ()
- Graphics.Vty.Widgets.List: pageDown :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: pageDown :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.List: pageUp :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: pageUp :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.List: removeFromList :: MonadIO m => Widget (List a b) -> Int -> m (ListItem a b)
+ Graphics.Vty.Widgets.List: removeFromList :: Widget (List a b) -> Int -> IO (ListItem a b)
- Graphics.Vty.Widgets.List: scrollBy :: MonadIO m => Widget (List a b) -> Int -> m ()
+ Graphics.Vty.Widgets.List: scrollBy :: Widget (List a b) -> Int -> IO ()
- Graphics.Vty.Widgets.List: scrollDown :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: scrollDown :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.List: scrollUp :: MonadIO m => Widget (List a b) -> m ()
+ Graphics.Vty.Widgets.List: scrollUp :: Widget (List a b) -> IO ()
- Graphics.Vty.Widgets.Padding: padded :: (MonadIO m, Show a) => Widget a -> Padding -> m (Widget Padded)
+ Graphics.Vty.Widgets.Padding: padded :: Show a => Widget a -> Padding -> IO (Widget Padded)
- Graphics.Vty.Widgets.Padding: withPadding :: (MonadIO m, Show a) => Padding -> Widget a -> m (Widget Padded)
+ Graphics.Vty.Widgets.Padding: withPadding :: Show a => Padding -> Widget a -> IO (Widget Padded)
- Graphics.Vty.Widgets.ProgressBar: addProgress :: MonadIO m => ProgressBar -> Int -> m ()
+ Graphics.Vty.Widgets.ProgressBar: addProgress :: ProgressBar -> Int -> IO ()
- Graphics.Vty.Widgets.ProgressBar: getProgress :: MonadIO m => ProgressBar -> m Int
+ Graphics.Vty.Widgets.ProgressBar: getProgress :: ProgressBar -> IO Int
- Graphics.Vty.Widgets.ProgressBar: newProgressBar :: MonadIO m => Color -> Color -> m ProgressBar
+ Graphics.Vty.Widgets.ProgressBar: newProgressBar :: Color -> Color -> IO ProgressBar
- Graphics.Vty.Widgets.ProgressBar: onProgressChange :: MonadIO m => ProgressBar -> (Int -> IO ()) -> m ()
+ Graphics.Vty.Widgets.ProgressBar: onProgressChange :: ProgressBar -> (Int -> IO ()) -> IO ()
- Graphics.Vty.Widgets.ProgressBar: setProgress :: MonadIO m => ProgressBar -> Int -> m ()
+ Graphics.Vty.Widgets.ProgressBar: setProgress :: ProgressBar -> Int -> IO ()
- Graphics.Vty.Widgets.Table: addHeadingRow :: MonadIO m => Widget Table -> Attr -> [String] -> m [Widget FormattedText]
+ Graphics.Vty.Widgets.Table: addHeadingRow :: Widget Table -> Attr -> [String] -> IO [Widget FormattedText]
- Graphics.Vty.Widgets.Table: addHeadingRow_ :: MonadIO m => Widget Table -> Attr -> [String] -> m ()
+ Graphics.Vty.Widgets.Table: addHeadingRow_ :: Widget Table -> Attr -> [String] -> IO ()
- Graphics.Vty.Widgets.Table: addRow :: (MonadIO m, RowLike a) => Widget Table -> a -> m ()
+ Graphics.Vty.Widgets.Table: addRow :: RowLike a => Widget Table -> a -> IO ()
- Graphics.Vty.Widgets.Table: newTable :: MonadIO m => [ColumnSpec] -> BorderStyle -> m (Widget Table)
+ Graphics.Vty.Widgets.Table: newTable :: [ColumnSpec] -> BorderStyle -> IO (Widget Table)
- Graphics.Vty.Widgets.Table: setDefaultCellAlignment :: MonadIO m => Widget Table -> Alignment -> m ()
+ Graphics.Vty.Widgets.Table: setDefaultCellAlignment :: Widget Table -> Alignment -> IO ()
- Graphics.Vty.Widgets.Table: setDefaultCellPadding :: MonadIO m => Widget Table -> Padding -> m ()
+ Graphics.Vty.Widgets.Table: setDefaultCellPadding :: Widget Table -> Padding -> IO ()
- Graphics.Vty.Widgets.Text: plainText :: MonadIO m => String -> m (Widget FormattedText)
+ Graphics.Vty.Widgets.Text: plainText :: String -> IO (Widget FormattedText)
- Graphics.Vty.Widgets.Text: setText :: MonadIO m => Widget FormattedText -> String -> m ()
+ Graphics.Vty.Widgets.Text: setText :: Widget FormattedText -> String -> IO ()
- Graphics.Vty.Widgets.Text: textWidget :: MonadIO m => Formatter -> String -> m (Widget FormattedText)
+ Graphics.Vty.Widgets.Text: textWidget :: Formatter -> String -> IO (Widget FormattedText)

Files

doc/ch1/api_notes.tex view
@@ -15,14 +15,6 @@ \fw{Widget a} whenever you need to refer to a widget; this makes it possible to mutate widget state when events occur in your application. -All widget constructors must ultimately be run in the \fw{IO} monad,-so all API functions must be run in an instance of \fw{MonadIO}.  In-this manual we will use \fw{IO} to simplify type signatures, but keep-in mind that the actual type is likely to be \fw{(MonadIO m) => m}.-Although \fw{MonadIO} is by far the more common constraint, be sure to-check the API documentation to be sure; some functions, such as event-handlers, are \fw{IO} actions.- Regarding return values, even if a function is of type \fw{...\ -> IO   a}, we say it is ``in the \fw{IO} monad'' and \textit{returns} \fw{a}.  We won't bother saying that a function \textit{returns \fw{IO
doc/ch2/collections.tex view
@@ -50,13 +50,12 @@  changeToW <- addToCollection c ui fg \end{haskellcode} -As a convenience, \fw{addToCollection} returns a \fw{MonadIO} action-which, when run, will switch to the specified interface.  In the-example above, \fw{changeToW} is an action which will switch to the-interface with \fw{ui} as its top-level widget and \fw{fg} as its-focus group.  You can use this action in event handlers that change-your interface state.  If you prefer, you can use the-\fw{setCurrentEntry} function instead, which allows you to set the-\fw{Collection}'s interface by number.  Use of \fw{setCurrentEntry} is-not recommended, however, since a bad index can cause an exception to-be thrown.+As a convenience, \fw{addToCollection} returns a \fw{IO} action which,+when run, will switch to the specified interface.  In the example+above, \fw{changeToW} is an action which will switch to the interface+with \fw{ui} as its top-level widget and \fw{fg} as its focus group.+You can use this action in event handlers that change your interface+state.  If you prefer, you can use the \fw{setCurrentEntry} function+instead, which allows you to set the \fw{Collection}'s interface by+number.  Use of \fw{setCurrentEntry} is not recommended, however,+since a bad index can cause an exception to be thrown.
doc/ch2/event_loop.tex view
@@ -22,6 +22,24 @@ \item The current ``override'' attribute \end{itemize} +The event loop will run until one of two conditions occurs:++\begin{itemize}+\item An exception of any kind is thrown; if an exception is thrown,+  the event loop will shut down Vty cleanly and re-throw the+  exception.+\item An event handler or thread calls \fw{shutdownUi}; the+  \fw{shutdownUi} function sends a signal to stop the event loop, at+  which point control will be returned to your program.  The shutdown+  signal goes into a queue with all of the other signals processed by+  the event loop, such as key input events and scheduled actions (see+  Section \ref{sec:concurrency}), but it will preempt them.  Note that+  there is no \textit{guarantee} that there won't be some other signal+  placed into the queue before you run \fw{shutdownUi}, such as when+  another thread is running in parallel with an event handler which+  calls \fw{shutdownUi}.+\end{itemize}+ \subsection{Skinning} \label{sec:skinning} @@ -164,26 +182,3 @@ Some built-in widgets will almost always be used in this way; for an example, take a look at the \fw{ProgressBar} widget in the \fw{ProgressBar} module (see Section \ref{sec:progress_bars}).--\subsection{Managing Your Own State}--If your applications have their own state management needs, then that-state management can be done in parallel with the \vtyui\ event loop-with proper use of \fw{schedule}.--A typical design for applications using \vtyui\ is:--\begin{itemize}-\item The application defines its own state type, call it-  \fw{AppState}.-\item The \fw{AppState} type has fields for the various widgets that-  need to be mutated over the course of the application's execution;-  for example, lists, progress bars, radio buttons, check boxes, edit-  widgets, etc.-\item Various event handlers are set up on these and other widgets.-\item The application spawns one or more threads to manage events from-  external sources, and when these events occur, actions are scheduled-  with \fw{schedule} to update the interface state accordingly.-\item The main event loop is executed and control is passed to the-  library.-\end{itemize}
doc/ch3/deferring_to_children.tex view
@@ -22,7 +22,7 @@   Section \ref{sec:containers_and_input}.}  \begin{haskellcode}- newWrapper :: (MonadIO m) => Widget a -> m (Widget (Wrapper a))+ newWrapper :: Widget a -> IO (Widget (Wrapper a))  newWrapper child = do    wRef <- newWidget $ \w ->      w { state = Wrapper child
doc/ch3/implementing_composite_widgets.tex view
@@ -65,7 +65,7 @@ % Let this block span a page boundary since it's so big that it's % likely, and we don't want to bump it down unless it looks good. :) \begin{haskellcode*}{samepage=false}- newPhoneInput :: (MonadIO m) => m (PhoneInput, Widget FocusGroup)+ newPhoneInput :: IO (PhoneInput, Widget FocusGroup)  newPhoneInput = do    ahs <- newHandlers    e1 <- editWidget@@ -108,8 +108,8 @@ Then we provide a function to register phone number handlers:  \begin{haskellcode}- onPhoneInputActivate :: (MonadIO m) => PhoneInput-                      -> (PhoneNumber -> IO ()) -> m ()+ onPhoneInputActivate :: PhoneInput+                      -> (PhoneNumber -> IO ()) -> IO ()  onPhoneInputActivate input handler =    addHandler (return . activateHandlers) input handler \end{haskellcode}
doc/ch3/implementing_event_handlers.tex view
@@ -41,7 +41,7 @@ constructor to construct a \fw{Handlers} list:  \begin{haskellcode}- newTempMonitor :: (MonadIO m) => m (Widget TempMonitor)+ newTempMonitor :: IO (Widget TempMonitor)  newTempMonitor = do    handlers <- newHandlers    wRef <- newWidget $ \w ->@@ -61,9 +61,9 @@ monitor case, we might write something like this:  \begin{haskellcode}- onTemperatureChange :: (MonadIO m) => Widget TempMonitor+ onTemperatureChange :: Widget TempMonitor                      -> (TemperatureEvent -> IO ())-                     -> m ()+                     -> IO ()  onTemperatureChange wRef handler =    addHandler (tempChangeHandlers <~~) wRef handler \end{haskellcode}@@ -94,7 +94,7 @@ invoke the handlers as follows:  \begin{haskellcode}- setTemperature :: (MonadIO m) => Widget TempMonitor -> Int -> m ()+ setTemperature :: Widget TempMonitor -> Int -> IO ()  setTemperature wRef newTemp = do    -- Set the internal widget state.    -- ...
doc/ch3/new_widget_type.tex view
@@ -24,7 +24,7 @@ Here's what the function will look like in full:  \begin{haskellcode}- newCounter :: (MonadIO m) => Int -> m (Widget Counter)+ newCounter :: Int -> IO (Widget Counter)  newCounter initialValue = do    wRef <- newWidget $ \w ->      w { state = Counter initialValue@@ -141,11 +141,11 @@ its state:  \begin{haskellcode}- setCounterValue :: (MonadIO m) => Widget Counter -> Int -> m ()+ setCounterValue :: Widget Counter -> Int -> IO ()  setCounterValue wRef val =     updateWidgetState wRef $ const $ Counter val - getCounterValue :: (MonadIO m) => Widget Counter -> m Int+ getCounterValue :: Widget Counter -> IO Int  getCounterValue wRef = do     Counter val <- getState wRef     return val
doc/ch4/Fixed.tex view
@@ -51,7 +51,7 @@ guarantee that the specified space is consumed.  \begin{haskellcode}- lst <- newList (green `on` black) plainText+ lst <- newList (green `on` black)  ui <- vFixed 5 lst \end{haskellcode} 
doc/ch4/List.tex view
@@ -36,40 +36,42 @@ Lists are created with the \fw{newList} function:  \begin{haskellcode}- lst <- newList attr plainText+ lst <- newList attr \end{haskellcode} -\fw{newList} takes two parameters: the attribute of the+\fw{newList} takes one parameter: the attribute of the currently-selected item to be used when the list is \textit{not}-focused, and the \textit{constructor function} to be used to create-widgets when new items are added to the list.  The \fw{List} uses its-own focus attribute (Section \ref{sec:attributes}) as the attribute of-the currently-selected item when it has the focus.+focused.  The \fw{List} uses its own focus attribute (Section+\ref{sec:attributes}) as the attribute of the currently-selected item+when it has the focus.  The widget type of the list (\fw{b} above)+won't be chosen by the type system until you actually add something to+the list.  Items may be added to a \fw{List} with the \fw{addToList} function,-which takes an internal value (e.g., \fw{String}) and uses it to-construct a widget with the appropriate type (e.g., \fw{Widget-  FormattedText}):+which takes an internal value (e.g., \fw{String}) and a widget of the+appropriate type:  \begin{haskellcode}- addToList lst "foobar"+ let s = "foobar"+ addToList lst s =<< plainText s \end{haskellcode} -The constructor function passed to \fw{newList} is essentially a-specification of how list items should be represented.  For a \fw{List-  a b}, it must take a value of type \fw{a} and return a \fw{Widget-  b}.  There are two restrictions on the constructor's return value:+In addition, items may be inserted into a \fw{List} at any position with+the \fw{insertIntoList} function. +There are two restrictions on the widget type that can be used with+\fw{List}s:+ \begin{itemize} \item The \fw{Widget b} type \textit{must not grow vertically}.  This   is because all \fw{List} item widgets must take up a fixed amount of   vertical space so the \fw{List} can manage scrolling.  If the widget   grows vertically, \fw{addToList} will throw a \fw{ListError}   exception.-\item All widgets returned \textit{must have the same height}.  This-  is because the list uses the item height to calculate how many items-  can be displayed, given the space available to the rendered-  \fw{List}.  If the constructor creates a widget whose rendered size+\item All widgets added to the \fw{List} \textit{must have the same+  height}.  This is because the list uses the item height to calculate+  how many items can be displayed, given the space available to the+  rendered \fw{List}.  If you specify a widget whose rendered size   doesn't match that of the rest of the wigets of the list, layout   problems are likely to ensue. \end{itemize}@@ -91,6 +93,12 @@ \fw{clearList} function.  \fw{clearList} does \textit{not} invoke any event handlers for the removed items. +In addition to \fw{addToList}, the \fw{List} API provides the+\fw{setSelected} function.  This function takes a \fw{List} widget and+an index and scrolls the list so that the item at the specified+position is selected.  If the position is out of bounds, the \fw{List}+is scrolled as much as possible.+ \subsection{\fw{List} Inspection}  The \fw{List} module provides some functions to get information about@@ -103,6 +111,10 @@   \fw{Nothing} if the \fw{List} is empty or returns \fw{Just (pos,     (val, widget))} corresponding to the list index, internal item   value, and widget of the currently-selected list item.+\item \fw{getListItem} -- takes a \fw{Widget (List a b)} and an index+  and returns \fw{Nothing} if the \fw{List} has no item at the+  specified index item or returns \fw{Just (pos, (val, widget))}+  corresponding to the list index. \end{itemize}  \subsection{Scrolling a \fw{List}}
doc/macros.tex view
@@ -1,6 +1,6 @@ % Custom macros. -\newcommand{\vtyuiversion}{1.0}+\newcommand{\vtyuiversion}{1.1}  \newcommand{\fw}[1]{\texttt{#1}} \newcommand{\vtyui}{\fw{vty-ui}}
src/ComplexDemo.hs view
@@ -66,7 +66,7 @@   edit1Header <- textWidget wrap "" >>= withNormalAttribute headerAttr   edit2Header <- textWidget wrap "" >>= withNormalAttribute headerAttr -  lst <- newList (fgColor bright_green) plainText+  lst <- newList (fgColor bright_green)    selector <- vLimit 3 lst   listHeader <- plainText ""@@ -126,13 +126,16 @@            KEsc -> exitSuccess            _ -> return False -  mapM_ (addToList lst) [ "Cookies"-                        , "Cupcakes"-                        , "Twinkies"-                        , "M&Ms"-                        , "Fritos"-                        , "Cheetos"-                        ]+  let strs = [ "Cookies"+             , "Cupcakes"+             , "Twinkies"+             , "M&Ms"+             , "Fritos"+             , "Cheetos"+             ]++  forM_ strs $ \s ->+      (addToList lst s =<< plainText s)    addToFocusGroup fgr r1   addToFocusGroup fgr r2
src/DialogDemo.hs view
@@ -1,8 +1,6 @@ {-# OPTIONS_GHC -fno-warn-unused-do-bind #-}-{-# LANGUAGE MultiParamTypeClasses #-} module Main where -import System.Exit import Graphics.Vty hiding (Button) import Graphics.Vty.Widgets.All @@ -29,10 +27,12 @@   e `onActivate` (const $ acceptDialog d)    -- Exit either way.-  d `onDialogAccept` const exitSuccess-  d `onDialogCancel` const exitSuccess+  d `onDialogAccept` const shutdownUi+  d `onDialogCancel` const shutdownUi    coll <- newCollection   _ <- addToCollection coll c =<< (mergeFocusGroups fg dFg)    runUi coll $ defaultContext { focusAttr = black `on` yellow }++  (putStrLn . ("You entered: " ++)) =<< getEditText e
src/Graphics/Vty/Widgets/All.hs view
src/Graphics/Vty/Widgets/Borders.hs view
@@ -20,7 +20,6 @@     ) where -import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Box@@ -31,7 +30,7 @@ -- |The class of types with a border attribute, which differs from the -- |normal and focused attributes. class HasBorderAttr a where-    setBorderAttribute :: (MonadIO m) => a -> Attr -> m ()+    setBorderAttribute :: a -> Attr -> IO ()  data HBorder = HBorder Attr String                deriving (Show)@@ -40,26 +39,26 @@     setBorderAttribute t a =         updateWidgetState t $ \(HBorder a' s) -> HBorder (mergeAttr a a') s -withBorderAttribute :: (MonadIO m, HasBorderAttr a) => Attr -> a -> m a+withBorderAttribute :: (HasBorderAttr a) => Attr -> a -> IO a withBorderAttribute att w = setBorderAttribute w att >> return w -withHBorderLabel :: (MonadIO m) => String -> Widget HBorder -> m (Widget HBorder)+withHBorderLabel :: String -> Widget HBorder -> IO (Widget HBorder) withHBorderLabel label w = setHBorderLabel w label >> return w -setHBorderLabel :: (MonadIO m) => Widget HBorder -> String -> m ()+setHBorderLabel :: Widget HBorder -> String -> IO () setHBorderLabel w label =     updateWidgetState w $ \(HBorder a _) -> HBorder a label -withBorderedLabel :: (MonadIO m) => String -> Widget (Bordered a) -> m (Widget (Bordered a))+withBorderedLabel :: String -> Widget (Bordered a) -> IO (Widget (Bordered a)) withBorderedLabel label w = setBorderedLabel w label >> return w -setBorderedLabel :: (MonadIO m) => Widget (Bordered a) -> String -> m ()+setBorderedLabel :: Widget (Bordered a) -> String -> IO () setBorderedLabel w label =     updateWidgetState w $ \(Bordered a ch _) -> Bordered a ch label  -- |Create a single-row horizontal border using the specified -- attribute and character.-hBorder :: (MonadIO m) => m (Widget HBorder)+hBorder :: IO (Widget HBorder) hBorder = do   wRef <- newWidget $ \w ->       w { state = HBorder def_attr ""@@ -102,7 +101,7 @@  -- |Create a single-column vertical border using the specified -- attribute and character.-vBorder :: (MonadIO m) => m (Widget VBorder)+vBorder :: IO (Widget VBorder) vBorder = do   wRef <- newWidget $ \w ->       w { state = VBorder def_attr@@ -132,7 +131,7 @@         updateWidgetState t $ \(Bordered a' ch s) -> Bordered (mergeAttr a a') ch s  -- |Wrap a widget in a bordering box.-bordered :: (MonadIO m, Show a) => Widget a -> m (Widget (Bordered a))+bordered :: (Show a) => Widget a -> IO (Widget (Bordered a)) bordered child = do   wRef <- newWidget $ \w ->       w { state = Bordered def_attr child ""
src/Graphics/Vty/Widgets/Box.hs view
@@ -32,7 +32,6 @@ import Data.Typeable import Control.Exception import Control.Monad-import Control.Monad.Trans import Graphics.Vty.Widgets.Core import Graphics.Vty import Graphics.Vty.Widgets.Util@@ -101,24 +100,24 @@ -- |Create a horizontal box widget containing two widgets side by -- side.  Space consumed by the box will depend on its contents, -- available space, and the box child size policy.-hBox :: (MonadIO m, Show a, Show b) => Widget a -> Widget b -> m (Widget (Box a b))+hBox :: (Show a, Show b) => Widget a -> Widget b -> IO (Widget (Box a b)) hBox = box Horizontal 0  -- |Create a vertical box widget containing two widgets, one above the -- other.  Space consumed by the box will depend on its contents, -- available space, and the box child size policy.-vBox :: (MonadIO m, Show a, Show b) => Widget a -> Widget b -> m (Widget (Box a b))+vBox :: (Show a, Show b) => Widget a -> Widget b -> IO (Widget (Box a b)) vBox = box Vertical 0  -- |Create a vertical box widget using monadic widget constructors.-(<-->) :: (MonadIO m, Show a, Show b) => m (Widget a) -> m (Widget b) -> m (Widget (Box a b))+(<-->) :: (Show a, Show b) => IO (Widget a) -> IO (Widget b) -> IO (Widget (Box a b)) (<-->) act1 act2 = do   ch1 <- act1   ch2 <- act2   vBox ch1 ch2  -- |Create a horizontal box widget using monadic widget constructors.-(<++>) :: (MonadIO m, Show a, Show b) => m (Widget a) -> m (Widget b) -> m (Widget (Box a b))+(<++>) :: (Show a, Show b) => IO (Widget a) -> IO (Widget b) -> IO (Widget (Box a b)) (<++>) act1 act2 = do   ch1 <- act1   ch2 <- act2@@ -132,8 +131,8 @@ defaultChildSizePolicy :: ChildSizePolicy defaultChildSizePolicy = PerChild BoxAuto BoxAuto -box :: (MonadIO m, Show a, Show b) =>-       Orientation -> Int -> Widget a -> Widget b -> m (Widget (Box a b))+box :: (Show a, Show b) =>+       Orientation -> Int -> Widget a -> Widget b -> IO (Widget (Box a b)) box o spacing wa wb = do   wRef <- newWidget $ \w ->       w { state = Box { boxChildSizePolicy = defaultChildSizePolicy@@ -194,6 +193,14 @@                       b <- getState this                       renderBox s ctx b +        , getCursorPosition_ =+            \this -> do+              b <- getState this+              ch1_pos <- getCursorPosition $ boxFirst b+              case ch1_pos of+                Just v -> return $ Just v+                Nothing -> getCursorPosition $ boxSecond b+         , setCurrentPosition_ =             \this pos -> do               b <- getState this@@ -211,30 +218,30 @@    return wRef -getFirstChild :: (MonadIO m) => Widget (Box a b) -> m (Widget a)+getFirstChild :: Widget (Box a b) -> IO (Widget a) getFirstChild = (boxFirst <~~) -getSecondChild :: (MonadIO m) => Widget (Box a b) -> m (Widget b)+getSecondChild :: Widget (Box a b) -> IO (Widget b) getSecondChild = (boxSecond <~~)  -- |Set the spacing in between a box's child widgets in rows or -- columns, depending on the box type.-setBoxSpacing :: (MonadIO m) => Widget (Box a b) -> Int -> m ()+setBoxSpacing :: Widget (Box a b) -> Int -> IO () setBoxSpacing wRef spacing =     updateWidgetState wRef $ \b -> b { boxSpacing = spacing } -withBoxSpacing :: (MonadIO m) => Int -> Widget (Box a b) -> m (Widget (Box a b))+withBoxSpacing :: Int -> Widget (Box a b) -> IO (Widget (Box a b)) withBoxSpacing spacing wRef = do   setBoxSpacing wRef spacing   return wRef -getBoxChildSizePolicy :: (MonadIO m) => Widget (Box a b) -> m ChildSizePolicy+getBoxChildSizePolicy :: Widget (Box a b) -> IO ChildSizePolicy getBoxChildSizePolicy = (boxChildSizePolicy <~~)  -- |Set the box child size policy.  Throws 'BadPercentage' if the size -- |policy uses an invalid percentage value, which must be between 0 -- |and 100 inclusive.-setBoxChildSizePolicy :: (MonadIO m) => Widget (Box a b) -> ChildSizePolicy -> m ()+setBoxChildSizePolicy :: Widget (Box a b) -> ChildSizePolicy -> IO () setBoxChildSizePolicy b spol = do   case spol of     Percentage v -> when (v < 0 || v > 100) $ throw BadPercentage
src/Graphics/Vty/Widgets/Button.hs view
@@ -11,7 +11,6 @@     ) where -import Control.Monad.Trans import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Text import Graphics.Vty.Widgets.Padding@@ -27,15 +26,15 @@                      }  -- |Register a handler for the button press event.-onButtonPressed :: (MonadIO m) => Button -> (Button -> IO ()) -> m ()+onButtonPressed :: Button -> (Button -> IO ()) -> IO () onButtonPressed = addHandler (return . buttonPressedHandlers)  -- |Programmatically press a button to trigger its event handlers.-pressButton :: (MonadIO m) => Button -> m ()+pressButton :: Button -> IO () pressButton b = fireEvent b (return . buttonPressedHandlers) b  -- |Set the text label on a button.-setButtonText :: (MonadIO m) => Button -> String -> m ()+setButtonText :: Button -> String -> IO () setButtonText b s = setText (buttonText b) s  instance HasNormalAttr Button where@@ -45,7 +44,7 @@     setFocusAttribute b a = setFocusAttribute (buttonWidget b) a  -- |Create a button.  Get its underlying widget with 'buttonWidget'.-newButton :: (MonadIO m) => String -> m Button+newButton :: String -> IO Button newButton msg = do   t <- plainText msg 
src/Graphics/Vty/Widgets/Centering.hs view
@@ -12,7 +12,6 @@ where  import GHC.Word ( Word )-import Control.Monad.Trans import Graphics.Vty.Widgets.Core import Graphics.Vty import Graphics.Vty.Widgets.Util@@ -23,7 +22,7 @@     show (HCentered _) = "HCentered { ... }"  -- |Wrap another widget to center it horizontally.-hCentered :: (MonadIO m, Show a) => Widget a -> m (Widget (HCentered a))+hCentered :: (Show a) => Widget a -> IO (Widget (HCentered a)) hCentered ch = do   wRef <- newWidget $ \w ->       w { state = HCentered ch@@ -64,7 +63,7 @@     show (VCentered _) = "VCentered { ... }"  -- |Wrap another widget to center it vertically.-vCentered :: (MonadIO m, Show a) => Widget a -> m (Widget (VCentered a))+vCentered :: (Show a) => Widget a -> IO (Widget (VCentered a)) vCentered ch = do   wRef <- newWidget $ \w ->       w { state = VCentered ch@@ -99,7 +98,7 @@   return wRef  -- |Wrap another widget to center it both vertically and horizontally.-centered :: (MonadIO m, Show a) => Widget a -> m (Widget (VCentered (HCentered a)))+centered :: (Show a) => Widget a -> IO (Widget (VCentered (HCentered a))) centered wRef = vCentered =<< hCentered wRef  centered_halves :: (DisplayRegion -> Word) -> DisplayRegion -> Word -> (Word, Word)
src/Graphics/Vty/Widgets/CheckBox.hs view
@@ -41,7 +41,6 @@ import Data.List ( findIndex ) import Data.Maybe import Control.Monad-import Control.Monad.Trans import Control.Exception import Data.Typeable import Graphics.Vty@@ -58,26 +57,26 @@ -- |Create a new radio button group.  This is used to guarantee -- exclusivity among the check boxes in the group so that they behave -- like radio buttons.-newRadioGroup :: (MonadIO m) => m RadioGroup+newRadioGroup :: IO RadioGroup newRadioGroup = do   hs <- newHandlers-  liftIO $ newIORef $ RadioGroupData Nothing hs+  newIORef $ RadioGroupData Nothing hs  -- |Register a handler to be notified when the currently-selected -- check box in a radio group changes.-onRadioChange :: (MonadIO m) => RadioGroup -> (Widget (CheckBox Bool) -> IO ())-              -> m ()+onRadioChange :: RadioGroup -> (Widget (CheckBox Bool) -> IO ())+              -> IO () onRadioChange rg act = do-  rd <- liftIO $ readIORef rg+  rd <- readIORef rg   addHandler (return . changeHandlers) rd act  -- |Get the currently-selected checkbox in a radio group, if any.-getCurrentRadio :: (MonadIO m) => RadioGroup -> m (Maybe (Widget (CheckBox Bool)))+getCurrentRadio :: RadioGroup -> IO (Maybe (Widget (CheckBox Bool))) getCurrentRadio = (currentlySelected <~)  -- |Add a check box to a radio group.  The check box's apperance will -- be changed so that it resembles a radio button.-addToRadioGroup :: (MonadIO m) => RadioGroup -> Widget (CheckBox Bool) -> m ()+addToRadioGroup :: RadioGroup -> Widget (CheckBox Bool) -> IO () addToRadioGroup rg wRef = do   setStateChar wRef True '*'   setBracketChars wRef '(' ')'@@ -93,7 +92,7 @@         -- Uncheck the old currently-selected checkbox in the radio         -- group, if any, before updating the radiogroup state. -        rgData <- liftIO $ readIORef rg+        rgData <- readIORef rg          -- If the radio group has a currently-selected checkbox,         -- uncheck it (but only if it's a different widget: it could@@ -142,17 +141,17 @@                      ]  -- |Create a new checkbox with the specified text label.-newCheckbox :: (MonadIO m) => String -> m (Widget (CheckBox Bool))+newCheckbox :: String -> IO (Widget (CheckBox Bool)) newCheckbox label = newMultiStateCheckbox label [(False, ' '), (True, 'x')]  -- |Create a new multi-state checkbox.-newMultiStateCheckbox :: (Eq a, MonadIO m) =>+newMultiStateCheckbox :: (Eq a) =>                          String -- ^The checkbox label.                       -> [(a, Char)] -- ^The list of valid states that                                      -- the checkbox can be in, along                                      -- with the visual representation                                      -- ('Char') for each state.-                      -> m (Widget (CheckBox a))+                      -> IO (Widget (CheckBox a)) newMultiStateCheckbox _ [] = throw EmptyCheckboxStates newMultiStateCheckbox label states = do   cchs <- newHandlers@@ -202,7 +201,7 @@  -- |Set the visual representation for a state in a checkbox.  May -- throw 'BadStateArgument'.-setStateChar :: (Eq a, MonadIO m) => Widget (CheckBox a) -> a -> Char -> m ()+setStateChar :: (Eq a) => Widget (CheckBox a) -> a -> Char -> IO () setStateChar wRef v ch = do   states <- checkboxStates <~~ wRef @@ -216,14 +215,14 @@  -- |Set the checkbox's bracketing characters for the left and right -- brackets around the state character.-setBracketChars :: (MonadIO m) => Widget (CheckBox a) -> Char -> Char -> m ()+setBracketChars :: Widget (CheckBox a) -> Char -> Char -> IO () setBracketChars wRef chL chR =     updateWidgetState wRef $ \s -> s { leftBracketChar = chL                                      , rightBracketChar = chR                                      }  -- |Get a checkbox's text label.-getCheckboxLabel :: (MonadIO m) => Widget (CheckBox a) -> m String+getCheckboxLabel :: Widget (CheckBox a) -> IO String getCheckboxLabel = (checkboxLabel <~~)  radioKeyEvent :: (Eq a) => Widget (CheckBox a) -> Key -> [Modifier] -> IO Bool@@ -232,29 +231,29 @@ radioKeyEvent _ _ _ = return False  -- |Set the state of a checkbox.  May throw 'BadCheckboxState'.-setCheckboxState :: (Eq a, MonadIO m) => Widget (CheckBox a) -> a -> m ()+setCheckboxState :: (Eq a) => Widget (CheckBox a) -> a -> IO () setCheckboxState = setChecked_  -- |Set a binary checkbox to unchecked.-setCheckboxUnchecked :: (MonadIO m) => Widget (CheckBox Bool) -> m ()+setCheckboxUnchecked :: Widget (CheckBox Bool) -> IO () setCheckboxUnchecked wRef = setCheckboxState wRef False  -- |Set a binary checkbox to checked.-setCheckboxChecked :: (MonadIO m) => Widget (CheckBox Bool) -> m ()+setCheckboxChecked :: Widget (CheckBox Bool) -> IO () setCheckboxChecked wRef = setCheckboxState wRef True  -- |Toggle a binary checkbox.-toggleCheckbox :: (MonadIO m) => Widget (CheckBox Bool) -> m ()+toggleCheckbox :: Widget (CheckBox Bool) -> IO () toggleCheckbox wRef = do   v <- currentState <~~ wRef   setCheckboxState wRef (not v)  -- |Get a checkbox's current state value.-getCheckboxState :: (MonadIO m) => Widget (CheckBox a) -> m a+getCheckboxState :: Widget (CheckBox a) -> IO a getCheckboxState = (currentState <~~)  -- |Cycle a checkbox's state to the next value in its state list.-cycleCheckbox :: (Eq a, MonadIO m) => Widget (CheckBox a) -> m ()+cycleCheckbox :: (Eq a) => Widget (CheckBox a) -> IO () cycleCheckbox wRef = do   v <- currentState <~~ wRef   states <- checkboxStates <~~ wRef@@ -262,7 +261,7 @@       nextI = (curI + 1) `mod` length states   setChecked_ wRef $ fst $ states !! nextI -setChecked_ :: (Eq a, MonadIO m) => Widget (CheckBox a) -> a -> m ()+setChecked_ :: (Eq a) => Widget (CheckBox a) -> a -> IO () setChecked_ wRef v = do   f <- checkboxFrozen <~~ wRef @@ -278,18 +277,18 @@            updateWidgetState wRef $ \s -> s { currentState = v }            notifyChangeHandlers wRef -notifyChangeHandlers :: (MonadIO m) => Widget (CheckBox a) -> m ()+notifyChangeHandlers :: Widget (CheckBox a) -> IO () notifyChangeHandlers wRef = do   v <- currentState <~~ wRef   fireEvent wRef (checkboxChangeHandlers <~~) v  -- |Register a handler for a checkbox state change.  The handler will -- be passed the new state value.-onCheckboxChange :: (MonadIO m) => Widget (CheckBox a) -> (a -> IO ()) -> m ()+onCheckboxChange :: Widget (CheckBox a) -> (a -> IO ()) -> IO () onCheckboxChange = addHandler (checkboxChangeHandlers <~~) -thaw :: (MonadIO m) => Widget (CheckBox a) -> m ()+thaw :: Widget (CheckBox a) -> IO () thaw wRef = updateWidgetState wRef $ \s -> s { checkboxFrozen = False } -freeze :: (MonadIO m) => Widget (CheckBox a) -> m ()+freeze :: Widget (CheckBox a) -> IO () freeze wRef = updateWidgetState wRef $ \s -> s { checkboxFrozen = True }
src/Graphics/Vty/Widgets/Core.hs view
@@ -74,7 +74,6 @@ import Data.IORef import Control.Applicative import Control.Monad-import Control.Monad.Trans import Control.Exception import Graphics.Vty import Graphics.Vty.Widgets.Util@@ -82,10 +81,10 @@ import Graphics.Vty.Widgets.Events  class HasNormalAttr w where-    setNormalAttribute :: (MonadIO m) => w -> Attr -> m ()+    setNormalAttribute :: w -> Attr -> IO ()  class HasFocusAttr w where-    setFocusAttribute :: (MonadIO m) => w -> Attr -> m ()+    setFocusAttribute :: w -> Attr -> IO ()  instance HasNormalAttr (Widget a) where     setNormalAttribute wRef a =@@ -95,12 +94,12 @@     setFocusAttribute wRef a =         updateWidget wRef $ \w -> w { focusAttribute = mergeAttr a (focusAttribute w) } -withNormalAttribute :: (HasNormalAttr w, MonadIO m) => Attr -> w -> m w+withNormalAttribute :: (HasNormalAttr w) => Attr -> w -> IO w withNormalAttribute att w = do   setNormalAttribute w att   return w -withFocusAttribute :: (HasFocusAttr w, MonadIO m) => Attr -> w -> m w+withFocusAttribute :: (HasFocusAttr w) => Attr -> w -> IO w withFocusAttribute att w = do   setFocusAttribute w att   return w@@ -141,8 +140,8 @@  type Widget a = IORef (WidgetImpl a) -showWidget :: (Functor m, MonadIO m, Show a) => Widget a -> m String-showWidget wRef = show <$> (liftIO $ readIORef wRef)+showWidget :: (Show a) => Widget a -> IO String+showWidget wRef = show <$> readIORef wRef  instance (Show a) => Show (WidgetImpl a) where     show w = concat [ "WidgetImpl { "@@ -156,70 +155,70 @@                     , " }"                     ] -growHorizontal :: (MonadIO m) => Widget a -> m Bool+growHorizontal :: Widget a -> IO Bool growHorizontal w = do   act <- growHorizontal_ <~ w   st <- state <~ w-  liftIO $ act st+  act st -growVertical :: (MonadIO m) => Widget a -> m Bool+growVertical :: Widget a -> IO Bool growVertical w = do   act <- growVertical_ <~ w   st <- state <~ w-  liftIO $ act st+  act st -render :: (MonadIO m, Show a) => Widget a -> DisplayRegion -> RenderContext -> m Image-render wRef sz ctx =-    liftIO $ do-      impl <- readIORef wRef+render :: (Show a) => Widget a -> DisplayRegion -> RenderContext -> IO Image+render wRef sz ctx = do+  impl <- readIORef wRef -      -- Merge the override attributes with the context.  If the-      -- overrides haven't been set (still def_attr), they will have-      -- no effect on the context attributes.-      norm <- normalAttribute <~ wRef-      foc <- focusAttribute <~ wRef-      let newCtx = ctx { normalAttr = mergeAttr norm $ normalAttr ctx-                       , focusAttr = mergeAttr foc $ focusAttr ctx-                       }+  -- Merge the override attributes with the context.  If the overrides+  -- haven't been set (still def_attr), they will have no effect on+  -- the context attributes.+  norm <- normalAttribute <~ wRef+  foc <- focusAttribute <~ wRef+  let newCtx = ctx { normalAttr = mergeAttr norm $ normalAttr ctx+                   , focusAttr = mergeAttr foc $ focusAttr ctx+                   } -      img <- render_ impl wRef sz newCtx-      let imgsz =  DisplayRegion (image_width img) (image_height img)-      when (image_width img > region_width sz ||-            image_height img > region_height sz) $ throw $ ImageTooBig (show impl) sz imgsz-      setCurrentSize wRef $ DisplayRegion (image_width img) (image_height img)-      return img+  img <- render_ impl wRef sz newCtx+  let imgsz =  DisplayRegion (image_width img) (image_height img) -renderAndPosition :: (MonadIO m, Show a) => Widget a -> DisplayRegion -> DisplayRegion-                  -> RenderContext -> m Image+  when (image_width img > region_width sz ||+        image_height img > region_height sz) $ throw $ ImageTooBig (show impl) sz imgsz++  setCurrentSize wRef $ DisplayRegion (image_width img) (image_height img)+  return img++renderAndPosition :: (Show a) => Widget a -> DisplayRegion -> DisplayRegion+                  -> RenderContext -> IO Image renderAndPosition wRef pos sz ctx = do   img <- render wRef sz ctx   -- Position post-processing depends on the sizes being correct!   setCurrentPosition wRef pos   return img -setCurrentSize :: (MonadIO m) => Widget a -> DisplayRegion -> m ()+setCurrentSize :: Widget a -> DisplayRegion -> IO () setCurrentSize wRef newSize =-    liftIO $ modifyIORef wRef $ \w -> w { currentSize = newSize }+    modifyIORef wRef $ \w -> w { currentSize = newSize } -getCurrentSize :: (MonadIO m) => Widget a -> m DisplayRegion-getCurrentSize wRef = (return . currentSize) =<< (liftIO $ readIORef wRef)+getCurrentSize :: Widget a -> IO DisplayRegion+getCurrentSize wRef = (return . currentSize) =<< (readIORef wRef) -getCurrentPosition :: (MonadIO m, Functor m) => Widget a -> m DisplayRegion-getCurrentPosition wRef = currentPosition <$> (liftIO $ readIORef wRef)+getCurrentPosition :: Widget a -> IO DisplayRegion+getCurrentPosition wRef = currentPosition <$> (readIORef wRef) -setCurrentPosition :: (MonadIO m) => Widget a -> DisplayRegion -> m ()+setCurrentPosition :: Widget a -> DisplayRegion -> IO () setCurrentPosition wRef pos = do   updateWidget wRef $ \w -> w { currentPosition = pos }-  liftIO $ do-    w <- readIORef wRef-    (setCurrentPosition_ w) wRef pos+  w <- readIORef wRef+  (setCurrentPosition_ w) wRef pos -newWidget :: (MonadIO m) => (WidgetImpl a -> WidgetImpl a) -> m (Widget a)+newWidget :: (WidgetImpl a -> WidgetImpl a) -> IO (Widget a) newWidget f = do   gfhs <- newHandlers   lfhs <- newHandlers -  wRef <- liftIO $ newIORef $+  wRef <- newIORef $           WidgetImpl { state = undefined                      , render_ = undefined                      , growVertical_ = const $ return False@@ -245,20 +244,20 @@   pos <- getCurrentPosition w   return $ Just $ pos `plusWidth` (region_width sz - 1) -handleKeyEvent :: (MonadIO m) => Widget a -> Key -> [Modifier] -> m Bool+handleKeyEvent :: Widget a -> Key -> [Modifier] -> IO Bool handleKeyEvent wRef keyEvent mods = do   act <- keyEventHandler <~ wRef-  liftIO $ act wRef keyEvent mods+  act wRef keyEvent mods -relayKeyEvents :: (MonadIO m) => Widget a -> Widget b -> m ()+relayKeyEvents :: Widget a -> Widget b -> IO () relayKeyEvents a b = a `onKeyPressed` \_ k mods -> handleKeyEvent b k mods -relayFocusEvents :: (MonadIO m) => Widget a -> Widget b -> m ()+relayFocusEvents :: Widget a -> Widget b -> IO () relayFocusEvents a b = do   a `onGainFocus` \_ -> focus b   a `onLoseFocus` \_ -> unfocus b -onKeyPressed :: (MonadIO m) => Widget a -> (Widget a -> Key -> [Modifier] -> IO Bool) -> m ()+onKeyPressed :: Widget a -> (Widget a -> Key -> [Modifier] -> IO Bool) -> IO () onKeyPressed wRef handler = do   -- Create a new handler that calls this one but defers to the old   -- one if the new one doesn't handle the event.@@ -273,39 +272,38 @@    updateWidget wRef $ \w -> w { keyEventHandler = combinedHandler } -focus :: (MonadIO m) => Widget a -> m ()+focus :: Widget a -> IO () focus wRef = do   updateWidget wRef $ \w -> w { focused = True }   fireEvent wRef (gainFocusHandlers <~) wRef -unfocus :: (MonadIO m) => Widget a -> m ()+unfocus :: Widget a -> IO () unfocus wRef = do   updateWidget wRef $ \w -> w { focused = False }   fireEvent wRef (loseFocusHandlers <~) wRef -onGainFocus :: (MonadIO m) => Widget a -> (Widget a -> IO ()) -> m ()+onGainFocus :: Widget a -> (Widget a -> IO ()) -> IO () onGainFocus = addHandler (gainFocusHandlers <~) -onLoseFocus :: (MonadIO m) => Widget a -> (Widget a -> IO ()) -> m ()+onLoseFocus :: Widget a -> (Widget a -> IO ()) -> IO () onLoseFocus = addHandler (loseFocusHandlers <~) -(<~) :: (MonadIO m) => (a -> b) -> IORef a -> m b-(<~) f wRef = (return . f) =<< (liftIO $ readIORef wRef)+(<~) :: (a -> b) -> IORef a -> IO b+(<~) f wRef = (return . f) =<< (readIORef wRef) -(<~~) :: (MonadIO m) => (a -> b) -> Widget a -> m b-(<~~) f wRef = (return . f . state) =<< (liftIO $ readIORef wRef)+(<~~) :: (a -> b) -> Widget a -> IO b+(<~~) f wRef = (return . f . state) =<< (readIORef wRef) -updateWidget :: (MonadIO m) => Widget a -> (WidgetImpl a -> WidgetImpl a) -> m ()-updateWidget wRef f = (liftIO $ modifyIORef wRef f)+updateWidget :: Widget a -> (WidgetImpl a -> WidgetImpl a) -> IO ()+updateWidget wRef f = modifyIORef wRef f -getState :: (MonadIO m) => Widget a -> m a+getState :: Widget a -> IO a getState wRef = state <~ wRef -updateWidgetState :: (MonadIO m) => Widget a -> (a -> a) -> m ()-updateWidgetState wRef f =-    liftIO $ do-      w <- readIORef wRef-      writeIORef wRef $ w { state = f (state w) }+updateWidgetState :: Widget a -> (a -> a) -> IO ()+updateWidgetState wRef f = do+  w <- readIORef wRef+  writeIORef wRef $ w { state = f (state w) }  data FocusGroupError = FocusGroupEmpty                      | FocusGroupBadIndex Int@@ -321,7 +319,7 @@                              , prevKey :: (Key, [Modifier])                              } -newFocusEntry :: (MonadIO m, Show a) => Widget a -> m (Widget FocusEntry)+newFocusEntry :: (Show a) => Widget a -> IO (Widget FocusEntry) newFocusEntry chRef = do   wRef <- newWidget $ \w ->       w { state = FocusEntry chRef@@ -343,7 +341,7 @@    return wRef -newFocusGroup :: (MonadIO m) => m (Widget FocusGroup)+newFocusGroup :: IO (Widget FocusGroup) newFocusGroup = do   wRef <- newWidget $ \w ->       w { state = FocusGroup { entries = []@@ -377,15 +375,15 @@         }   return wRef -setFocusGroupNextKey :: (MonadIO m) => Widget FocusGroup -> Key -> [Modifier] -> m ()+setFocusGroupNextKey :: Widget FocusGroup -> Key -> [Modifier] -> IO () setFocusGroupNextKey fg k mods =     updateWidgetState fg $ \s -> s { nextKey = (k, mods) } -setFocusGroupPrevKey :: (MonadIO m) => Widget FocusGroup -> Key -> [Modifier] -> m ()+setFocusGroupPrevKey :: Widget FocusGroup -> Key -> [Modifier] -> IO () setFocusGroupPrevKey fg k mods =     updateWidgetState fg $ \s -> s { prevKey = (k, mods) } -mergeFocusGroups :: (MonadIO m) => Widget FocusGroup -> Widget FocusGroup -> m (Widget FocusGroup)+mergeFocusGroups :: Widget FocusGroup -> Widget FocusGroup -> IO (Widget FocusGroup) mergeFocusGroups a b = do   c <- newFocusGroup @@ -416,7 +414,7 @@    return c -resetFocusGroup :: (MonadIO m) => Widget FocusGroup -> m ()+resetFocusGroup :: Widget FocusGroup -> IO () resetFocusGroup fg = do   cur <- currentEntryNum <~~ fg   es <- entries <~~ fg@@ -425,19 +423,19 @@   when (cur >= 0) $        focus =<< currentEntry fg -getCursorPosition :: (MonadIO m) => Widget a -> m (Maybe DisplayRegion)+getCursorPosition :: Widget a -> IO (Maybe DisplayRegion) getCursorPosition wRef = do   ci <- getCursorPosition_ <~ wRef-  liftIO (ci wRef)+  ci wRef -currentEntry :: (MonadIO m) => Widget FocusGroup -> m (Widget FocusEntry)+currentEntry :: Widget FocusGroup -> IO (Widget FocusEntry) currentEntry wRef = do   es <- entries <~~ wRef   i <- currentEntryNum <~~ wRef   when (i == -1) $ throw FocusGroupEmpty   return (es !! i) -addToFocusGroup :: (MonadIO m, Show a) => Widget FocusGroup -> Widget a -> m (Widget FocusEntry)+addToFocusGroup :: (Show a) => Widget FocusGroup -> Widget a -> IO (Widget FocusEntry) addToFocusGroup cRef wRef = do   eRef <- newFocusEntry wRef @@ -456,7 +454,7 @@    return eRef -focusNext :: (MonadIO m) => Widget FocusGroup -> m ()+focusNext :: Widget FocusGroup -> IO () focusNext wRef = do   st <- getState wRef   let cur = currentEntryNum st@@ -466,7 +464,7 @@                       (entries st) !! 0   focus nextEntry -focusPrevious :: (MonadIO m) => Widget FocusGroup -> m ()+focusPrevious :: Widget FocusGroup -> IO () focusPrevious wRef = do   st <- getState wRef   let cur = currentEntryNum st@@ -481,7 +479,7 @@ -- focus on the newly-focused widget, because this is intended to be -- callable from a focus event handler for the widget that got -- focused.-setCurrentFocus :: (MonadIO m) => Widget FocusGroup -> Int -> m ()+setCurrentFocus :: Widget FocusGroup -> Int -> IO () setCurrentFocus cRef i = do   st <- state <~ cRef 
src/Graphics/Vty/Widgets/Dialog.hs view
@@ -13,7 +13,6 @@     ) where -import Control.Monad.Trans import Graphics.Vty.Widgets.Centering import Graphics.Vty.Widgets.Button import Graphics.Vty.Widgets.Padding@@ -34,7 +33,7 @@ -- |Create a new dialog with the specified embedded interface and -- title.  Returns the dialog itself and the 'FocusGroup' to which its -- buttons were added, for use in your application.-newDialog :: (MonadIO m, Show a) => Widget a -> String -> m (Dialog, Widget FocusGroup)+newDialog :: (Show a) => Widget a -> String -> IO (Dialog, Widget FocusGroup) newDialog body title = do   okB <- newButton "OK"   cancelB <- newButton "Cancel"@@ -67,17 +66,17 @@   return (dlg, fg)  -- |Register an event handler for the dialog's acceptance event.-onDialogAccept :: (MonadIO m) => Dialog -> (Dialog -> IO ()) -> m ()+onDialogAccept :: Dialog -> (Dialog -> IO ()) -> IO () onDialogAccept = addHandler (return . dialogAcceptHandlers)  -- |Register an event handler for the dialog's cancellation event.-onDialogCancel :: (MonadIO m) => Dialog -> (Dialog -> IO ()) -> m ()+onDialogCancel :: Dialog -> (Dialog -> IO ()) -> IO () onDialogCancel = addHandler (return . dialogCancelHandlers)  -- |Programmatically accept the dialog.-acceptDialog :: (MonadIO m) => Dialog -> m ()+acceptDialog :: Dialog -> IO () acceptDialog dlg = fireEvent dlg (return . dialogAcceptHandlers) dlg  -- |Programmatically cancel the dialog.-cancelDialog :: (MonadIO m) => Dialog -> m ()+cancelDialog :: Dialog -> IO () cancelDialog dlg = fireEvent dlg (return . dialogCancelHandlers) dlg
src/Graphics/Vty/Widgets/DirBrowser.hs view
@@ -19,7 +19,6 @@ import Data.IORef import qualified Data.Map as Map import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.List@@ -106,9 +105,9 @@  -- |Create a directory browser widget with the specified skin. -- Returns the browser itself along with its focus group.-newDirBrowser :: (MonadIO m) => BrowserSkin -> m (DirBrowser, Widget FocusGroup)+newDirBrowser :: BrowserSkin -> IO (DirBrowser, Widget FocusGroup) newDirBrowser bSkin = do-  path <- liftIO $ getCurrentDirectory+  path <- getCurrentDirectory   pathWidget <- plainText ""   errorText <- plainText "" >>= withNormalAttribute (browserErrorAttr bSkin)   header <- ((plainText " Path: ") <++> (return pathWidget) <++> (hFill ' ' 1))@@ -118,11 +117,11 @@   footer <- ((plainText " ") <++> (return fileInfo) <++> (hFill ' ' 1) <++> (return errorText))             >>= withNormalAttribute (browserHeaderAttr bSkin) -  l <- newList (browserUnfocusedSelAttr bSkin) (\s -> plainText " " <++> plainText s)+  l <- newList (browserUnfocusedSelAttr bSkin)   ui <- vBox header =<< vBox l footer -  r <- liftIO $ newIORef ""-  r2 <- liftIO $ newIORef Map.empty+  r <- newIORef ""+  r2 <- newIORef Map.empty    hs <- newHandlers   chs <- newHandlers@@ -154,28 +153,28 @@ -- |Report an error in the browser's error-reporting area.  Useful for -- reporting application-specific errors with the user's file -- selection.-reportBrowserError :: (MonadIO m) => DirBrowser -> String -> m ()+reportBrowserError :: DirBrowser -> String -> IO () reportBrowserError b msg = setText (dirBrowserErrorWidget b) $ "Error: " ++ msg -clearError :: (MonadIO m) => DirBrowser -> m ()+clearError :: DirBrowser -> IO () clearError b = setText (dirBrowserErrorWidget b) ""  -- |Register handlers to be invoked when the user makes a selection.-onBrowseAccept :: (MonadIO m) => DirBrowser -> (FilePath -> IO ()) -> m ()+onBrowseAccept :: DirBrowser -> (FilePath -> IO ()) -> IO () onBrowseAccept = addHandler (return . dirBrowserChooseHandlers)  -- |Register handlers to be invoked when the user cancels browsing.-onBrowseCancel :: (MonadIO m) => DirBrowser -> (FilePath -> IO ()) -> m ()+onBrowseCancel :: DirBrowser -> (FilePath -> IO ()) -> IO () onBrowseCancel = addHandler (return . dirBrowserCancelHandlers)  -- |Register handlers to be invoked when the browser's path changes.-onBrowserPathChange :: (MonadIO m) => DirBrowser -> (FilePath -> IO ()) -> m ()+onBrowserPathChange :: DirBrowser -> (FilePath -> IO ()) -> IO () onBrowserPathChange = addHandler (return . dirBrowserPathChangeHandlers) -cancelBrowse :: (MonadIO m) => DirBrowser -> m ()+cancelBrowse :: DirBrowser -> IO () cancelBrowse b = fireEvent b (return . dirBrowserCancelHandlers) =<< getDirBrowserPath b -chooseCurrentEntry :: (MonadIO m) => DirBrowser -> m ()+chooseCurrentEntry :: DirBrowser -> IO () chooseCurrentEntry b = do   p <- getDirBrowserPath b   mCur <- getSelected (dirBrowserList b)@@ -189,13 +188,13 @@     SelectionOff -> setText (dirBrowserFileInfo b) "-"     SelectionOn _ path _ -> setText (dirBrowserFileInfo b) =<< getFileInfo b path -getFileInfo :: (MonadIO m) => DirBrowser -> FilePath -> m String+getFileInfo :: DirBrowser -> FilePath -> IO String getFileInfo b path = do   cur <- getDirBrowserPath b   let newPath = cur </> path-  st <- liftIO $ getSymbolicLinkStatus newPath+  st <- getSymbolicLinkStatus newPath   (_, mkAnn) <- fileAnnotation (dirBrowserSkin b) st cur path-  ann <- liftIO mkAnn+  ann <- mkAnn   return $ path ++ ": " ++ ann  builtInAnnotations :: FilePath -> BrowserSkin -> [(FilePath -> FileStatus -> Bool, FilePath -> FileStatus -> IO String, Attr)]@@ -209,8 +208,8 @@           linkDest <- if not $ isSymbolicLink stat                       then return ""                       else do-                        linkPath <- liftIO $ readSymbolicLink p-                        liftIO $ canonicalizePath $ cur </> linkPath+                        linkPath <- readSymbolicLink p+                        canonicalizePath $ cur </> linkPath           return $ "symbolic link to " ++ linkDest)       , browserLinkAttr sk)     , (\_ s -> isDirectory s, \_ _ -> return "directory", browserDirAttr sk)@@ -220,7 +219,7 @@     , (\_ s -> isSocket s, \_ _ -> return "socket", browserSockAttr sk)     ] -fileAnnotation :: (MonadIO m) => BrowserSkin -> FileStatus -> FilePath -> FilePath -> m (Attr, IO String)+fileAnnotation :: BrowserSkin -> FileStatus -> FilePath -> FilePath -> IO (Attr, IO String) fileAnnotation sk st cur shortPath = do   let fullPath = cur </> shortPath @@ -246,21 +245,20 @@  -- |Refresh the browser by reloading and displaying the contents of -- the browser's current path.-refreshBrowser :: (MonadIO m) => DirBrowser -> m ()+refreshBrowser :: DirBrowser -> IO () refreshBrowser b = setDirBrowserPath b =<< getDirBrowserPath b  -- |Set the browser's current path.-setDirBrowserPath :: (MonadIO m) => DirBrowser -> FilePath -> m ()+setDirBrowserPath :: DirBrowser -> FilePath -> IO () setDirBrowserPath b path = do-  cPath <- liftIO $ canonicalizePath path+  cPath <- canonicalizePath path    -- If for some reason we can't load the directory, report an error   -- and don't change the browser state.-  (res, entries) <--      liftIO $ (do-                 entries <- getDirectoryContents cPath-                 return (True, entries))-                `catch` \e -> do+  (res, entries) <- (do+                      entries <- getDirectoryContents cPath+                      return (True, entries))+                     `catch` \e -> do                              reportBrowserError b (ioeGetErrorString e)                              return (False, []) @@ -274,9 +272,9 @@       Just (i, _) -> storeSelection b cur i      clearList (dirBrowserList b)-    liftIO $ modifyIORef (dirBrowserPath b) $ const cPath+    modifyIORef (dirBrowserPath b) $ const cPath -    liftIO $ load b cPath entries+    load b cPath entries      sel <- getSelection b path     case sel of@@ -286,18 +284,17 @@     fireEvent b (return . dirBrowserPathChangeHandlers) cPath  -- |Get the browser's current path.-getDirBrowserPath :: (MonadIO m) => DirBrowser -> m FilePath-getDirBrowserPath = liftIO . readIORef . dirBrowserPath+getDirBrowserPath :: DirBrowser -> IO FilePath+getDirBrowserPath = readIORef . dirBrowserPath -storeSelection :: (MonadIO m) => DirBrowser -> FilePath -> Int -> m ()+storeSelection :: DirBrowser -> FilePath -> Int -> IO () storeSelection b path i =-    liftIO $ modifyIORef (dirBrowserSelectionMap b) $ \m -> Map.insert path i m+    modifyIORef (dirBrowserSelectionMap b) $ \m -> Map.insert path i m -getSelection :: (MonadIO m) => DirBrowser -> FilePath -> m (Maybe Int)-getSelection b path =-    liftIO $ do-      st <- readIORef (dirBrowserSelectionMap b)-      return $ Map.lookup path st+getSelection :: DirBrowser -> FilePath -> IO (Maybe Int)+getSelection b path = do+  st <- readIORef (dirBrowserSelectionMap b)+  return $ Map.lookup path st  load :: DirBrowser -> FilePath -> [FilePath] -> IO () load b cur entries =@@ -305,11 +302,12 @@       let fullPath = cur </> entry       f <- getSymbolicLinkStatus fullPath       (attr, _) <- fileAnnotation (dirBrowserSkin b) f cur entry-      (_, w) <- addToList (dirBrowserList b) entry+      w <- plainText " " <++> plainText entry+      addToList (dirBrowserList b) entry w       ch <- getSecondChild w       setNormalAttribute ch attr -descend :: (MonadIO m) => DirBrowser -> Bool -> m ()+descend :: DirBrowser -> Bool -> IO () descend b shouldSelect = do   base <- getDirBrowserPath b   mCur <- getSelected (dirBrowserList b)@@ -317,10 +315,10 @@     Nothing -> return ()     Just (_, (p, _)) -> do               let newPath = base </> p-              e <- liftIO $ doesDirectoryExist newPath+              e <- doesDirectoryExist newPath               case e of                 True -> do-                       cPath <- liftIO $ canonicalizePath newPath+                       cPath <- canonicalizePath newPath                        cur <- getDirBrowserPath b                        when (cur /= cPath) $ do                           case takeDirectory cur == cPath of@@ -329,9 +327,9 @@                  False -> when shouldSelect $ chooseCurrentEntry b -ascend :: (MonadIO m) => DirBrowser -> m ()+ascend :: DirBrowser -> IO () ascend b = do-  cur <- liftIO $ getDirBrowserPath b+  cur <- getDirBrowserPath b   let newPath = takeDirectory cur   when (newPath /= cur) $        setDirBrowserPath b newPath
src/Graphics/Vty/Widgets/Edit.hs view
@@ -15,7 +15,6 @@ where  import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Events@@ -41,7 +40,7 @@                     ]  -- |Create a new editing widget.-editWidget :: (MonadIO m) => m (Widget Edit)+editWidget :: IO (Widget Edit) editWidget = do   ahs <- newHandlers   chs <- newHandlers@@ -95,7 +94,7 @@   return wRef  -- |Set the maximum length of the edit widget's content.-setEditMaxLength :: (MonadIO m) => Widget Edit -> Int -> m ()+setEditMaxLength :: Widget Edit -> Int -> IO () setEditMaxLength wRef v = do   cur <- maxTextLength <~~ wRef   case cur of@@ -110,10 +109,10 @@ -- |Register handlers to be invoked when the edit widget has been -- ''activated'' (when the user presses Enter while the widget is -- focused).-onActivate :: (MonadIO m) => Widget Edit -> (Widget Edit -> IO ()) -> m ()+onActivate :: Widget Edit -> (Widget Edit -> IO ()) -> IO () onActivate = addHandler (activateHandlers <~~) -notifyActivateHandlers :: (MonadIO m) => Widget Edit -> m ()+notifyActivateHandlers :: Widget Edit -> IO () notifyActivateHandlers wRef = fireEvent wRef (activateHandlers <~~) wRef  notifyChangeHandlers :: Widget Edit -> IO ()@@ -121,28 +120,28 @@   s <- getEditText wRef   fireEvent wRef (changeHandlers <~~) s -notifyCursorMoveHandlers :: (MonadIO m) => Widget Edit -> m ()+notifyCursorMoveHandlers :: Widget Edit -> IO () notifyCursorMoveHandlers wRef = do   pos <- getEditCursorPosition wRef   fireEvent wRef (cursorMoveHandlers <~~) pos  -- |Register handlers to be invoked when the edit widget's contents -- change.  Handlers will be passed the new contents.-onChange :: (MonadIO m) => Widget Edit -> (String -> IO ()) -> m ()+onChange :: Widget Edit -> (String -> IO ()) -> IO () onChange = addHandler (changeHandlers <~~)  -- |Register handlers to be invoked when the edit widget's cursor -- position changes.  Handlers will be passed the new cursor position, -- relative to the beginning of the string (position 0).-onCursorMove :: (MonadIO m) => Widget Edit -> (Int -> IO ()) -> m ()+onCursorMove :: Widget Edit -> (Int -> IO ()) -> IO () onCursorMove = addHandler (cursorMoveHandlers <~~)  -- |Get the current contents of the edit widget.-getEditText :: (MonadIO m) => Widget Edit -> m String+getEditText :: Widget Edit -> IO String getEditText = (currentText <~~)  -- |Set the contents of the edit widget.-setEditText :: (MonadIO m) => Widget Edit -> String -> m ()+setEditText :: Widget Edit -> String -> IO () setEditText wRef str = do   oldS <- currentText <~~ wRef   maxLen <- maxTextLength <~~ wRef@@ -150,14 +149,13 @@     Nothing -> return str     Just l -> return $ take l str   updateWidgetState wRef $ \st -> st { currentText = s }-  when (oldS /= s) $-       liftIO $ do-         gotoBeginning wRef-         notifyChangeHandlers wRef+  when (oldS /= s) $ do+    gotoBeginning wRef+    notifyChangeHandlers wRef  -- |Set the current edit widget cursor position.  Invalid cursor -- positions will be ignored.-setEditCursorPosition :: (MonadIO m) => Widget Edit -> Int -> m ()+setEditCursorPosition :: Widget Edit -> Int -> IO () setEditCursorPosition wRef pos = do   oldPos <- getEditCursorPosition wRef   str <- getEditText wRef@@ -173,10 +171,10 @@          updateWidgetState wRef $ \s ->              s { cursorPosition = newPos                }-         liftIO $ notifyCursorMoveHandlers wRef+         notifyCursorMoveHandlers wRef  -- |Get the edit widget's current cursor position.-getEditCursorPosition :: (MonadIO m) => Widget Edit -> m Int+getEditCursorPosition :: Widget Edit -> IO Int getEditCursorPosition = (cursorPosition <~~)  setDisplayWidth :: Widget Edit -> Int -> IO ()@@ -305,10 +303,3 @@          let newContent = remove (cursorPosition st) (currentText st)          updateWidgetState wRef $ \s -> s { currentText = newContent }          notifyChangeHandlers wRef--remove :: Int -> [a] -> [a]-remove pos as = (take pos as) ++ (drop (pos + 1) as)--inject :: Int -> a -> [a] -> [a]-inject pos a as = let (h, t) = splitAt pos as-                  in h ++ (a:t)
src/Graphics/Vty/Widgets/EventLoop.hs view
@@ -7,6 +7,7 @@     , CollectionError(..)     , runUi     , schedule+    , shutdownUi     , newCollection     , addToCollection     , setCurrentEntry@@ -18,13 +19,13 @@ import Control.Concurrent import Control.Exception import Control.Monad-import Control.Monad.Trans import System.IO.Unsafe ( unsafePerformIO ) import Graphics.Vty import Graphics.Vty.Widgets.Core  data CombinedEvent = VTYEvent Event                    | UserEvent UserEvent+                   | ShutdownUi  data UserEvent = ScheduledAction (IO ()) @@ -37,17 +38,16 @@ -- provides the default attributes and 'Skin' to use for the -- application.  Throws 'BadCollectionIndex' if the specified -- 'Collection' is empty.-runUi :: (MonadIO m) => Collection -> RenderContext -> m ()-runUi collection ctx =-    liftIO $ do-      vty <- mkVty+runUi :: Collection -> RenderContext -> IO ()+runUi collection ctx = do+  vty <- mkVty -      -- Create VTY event listener thread-      _ <- forkIO $ vtyEventListener vty eventChan+  -- Create VTY event listener thread+  _ <- forkIO $ vtyEventListener vty eventChan -      runUi' vty eventChan collection ctx `finally` do-               reserve_display $ terminal vty-               shutdown vty+  runUi' vty eventChan collection ctx `finally` do+                         reserve_display $ terminal vty+                         shutdown vty  vtyEventListener :: Vty -> Chan CombinedEvent -> IO () vtyEventListener vty chan =@@ -58,9 +58,14 @@ -- |Schedule a widget-mutating 'IO' action to be run by the main event -- loop.  Use of this function is required to guarantee consistency -- between interface presentation and internal state.-schedule :: (MonadIO m) => IO () -> m ()-schedule act = liftIO $ writeChan eventChan $ UserEvent $ ScheduledAction act+schedule :: IO () -> IO ()+schedule act = writeChan eventChan $ UserEvent $ ScheduledAction act +-- |Schedule a vty-ui event loop shutdown.  This event will preempt+-- others so that it will be processed next.+shutdownUi :: IO ()+shutdownUi = unGetChan eventChan ShutdownUi+ runUi' :: Vty -> Chan CombinedEvent -> Collection -> RenderContext -> IO () runUi' vty chan collection ctx = do   sz <- display_bounds $ terminal vty@@ -80,12 +85,13 @@    evt <- readChan chan -  case evt of-    VTYEvent (EvKey k mods) -> handleKeyEvent fg k mods >> return ()-    UserEvent (ScheduledAction act) -> liftIO act-    _ -> return ()+  cont <- case evt of+            VTYEvent (EvKey k mods) -> handleKeyEvent fg k mods >> return True+            VTYEvent _ -> return True+            UserEvent (ScheduledAction act) -> act >> return True+            ShutdownUi -> return False -  runUi' vty chan collection ctx+  when cont $ runUi' vty chan collection ctx  data CollectionError = BadCollectionIndex Int                        deriving (Show, Typeable)@@ -109,20 +115,20 @@                                           , " }"                                           ] -entryRenderAndPosition :: (MonadIO m) => Entry -> DisplayRegion -> DisplayRegion -> RenderContext -> m Image+entryRenderAndPosition :: Entry -> DisplayRegion -> DisplayRegion -> RenderContext -> IO Image entryRenderAndPosition (Entry w _) = renderAndPosition w  entryFocusGroup :: Entry -> Widget FocusGroup entryFocusGroup (Entry _ fg) = fg  -- |Create a new collection.-newCollection :: (MonadIO m) => m Collection+newCollection :: IO Collection newCollection =-    liftIO $ newIORef $ CollectionData { entries = []-                                       , currentEntryNum = -1-                                       }+    newIORef $ CollectionData { entries = []+                              , currentEntryNum = -1+                              } -getCurrentEntry :: (MonadIO m) => Collection -> m Entry+getCurrentEntry :: Collection -> IO Entry getCurrentEntry cRef = do   cur <- currentEntryNum <~ cRef   es <- entries <~ cRef@@ -135,10 +141,10 @@ -- |Add a widget and its focus group to a collection.  Returns an -- action which, when invoked, will switch to the interface specified -- in the call.-addToCollection :: (MonadIO m, Show a) => Collection -> Widget a -> Widget FocusGroup -> m (m ())+addToCollection :: (Show a) => Collection -> Widget a -> Widget FocusGroup -> IO (IO ()) addToCollection cRef wRef fg = do   i <- (length . entries) <~ cRef-  liftIO $ modifyIORef cRef $ \st ->+  modifyIORef cRef $ \st ->       st { entries = (entries st) ++ [Entry wRef fg]          , currentEntryNum = if currentEntryNum st == -1                              then 0@@ -147,11 +153,11 @@   resetFocusGroup fg   return $ setCurrentEntry cRef i -setCurrentEntry :: (MonadIO m) => Collection -> Int -> m ()+setCurrentEntry :: Collection -> Int -> IO () setCurrentEntry cRef i = do-  st <- liftIO $ readIORef cRef+  st <- readIORef cRef   if i < length (entries st) && i >= 0 then-      (liftIO $ modifyIORef cRef $ \s -> s { currentEntryNum = i }) else+      (modifyIORef cRef $ \s -> s { currentEntryNum = i }) else       throw $ BadCollectionIndex i    e <- getCurrentEntry cRef
src/Graphics/Vty/Widgets/Events.hs view
@@ -10,7 +10,6 @@     ) where -import Control.Monad.Trans import Control.Monad import Data.IORef @@ -23,23 +22,23 @@ -- |Given an event handler collection projection combinator, a target, -- and a handler, add the handler to the target's event handler -- collection.-addHandler :: (MonadIO m) => (w -> m (Handlers a)) -> w -> Handler a -> m ()+addHandler :: (w -> IO (Handlers a)) -> w -> Handler a -> IO () addHandler getRef w handler = do   (Handlers r) <- getRef w-  liftIO $ modifyIORef r $ \s -> s ++ [handler]+  modifyIORef r $ \s -> s ++ [handler]  -- |Fire an event by extracting an event handler collection from a -- target and invoking all of its handlers with the specified -- parameter value.-fireEvent :: (MonadIO m) => w -> (w -> m (Handlers a)) -> a -> m ()+fireEvent :: w -> (w -> IO (Handlers a)) -> a -> IO () fireEvent w getRef ev = do   (Handlers r) <- getRef w-  handlers <- liftIO $ readIORef r+  handlers <- readIORef r   forM_ handlers $ \handler ->-      liftIO $ handler ev+      handler ev  -- |Create a new event handler collection.-newHandlers :: (MonadIO m) => m (Handlers a)+newHandlers :: IO (Handlers a) newHandlers = do-  r <- liftIO $ newIORef []+  r <- newIORef []   return $ Handlers r
src/Graphics/Vty/Widgets/Fills.hs view
@@ -9,7 +9,6 @@     ) where -import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Util@@ -19,7 +18,7 @@  -- |A vertical fill widget.  Fills all available space with the -- specified character and attribute.-vFill :: (MonadIO m) => Char -> m (Widget VFill)+vFill :: Char -> IO (Widget VFill) vFill c = do   wRef <- newWidget $ \w ->       w { state = VFill c@@ -39,7 +38,7 @@  -- |A horizontal fill widget.  Fills the available horizontal space, -- one row high, using the specified character and attribute.-hFill :: (MonadIO m) => Char -> Int -> m (Widget HFill)+hFill :: Char -> Int -> IO (Widget HFill) hFill c h = do   wRef <- newWidget $ \w ->       w { state = HFill c h
src/Graphics/Vty/Widgets/Fixed.hs view
@@ -19,7 +19,6 @@ where  import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Util@@ -30,7 +29,7 @@     show (HFixed i _) = "HFixed { width = " ++ show i ++ ", ... }"  -- |Impose a fixed horizontal size, in columns, on a 'Widget'.-hFixed :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (HFixed a))+hFixed :: (Show a) => Int -> Widget a -> IO (Widget (HFixed a)) hFixed fixedWidth child = do   wRef <- newWidget $ \w ->       w { state = HFixed fixedWidth child@@ -61,7 +60,7 @@     show (VFixed i _) = "VFixed { height = " ++ show i ++ ", ... }"  -- |Impose a fixed vertical size, in columns, on a 'Widget'.-vFixed :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (VFixed a))+vFixed :: (Show a) => Int -> Widget a -> IO (Widget (VFixed a)) vFixed maxHeight child = do   wRef <- newWidget $ \w ->       w { state = VFixed maxHeight child@@ -89,47 +88,47 @@   return wRef  -- |Set the vertical fixed size of a child widget.-setVFixed :: (MonadIO m) => Widget (VFixed a) -> Int -> m ()+setVFixed :: Widget (VFixed a) -> Int -> IO () setVFixed wRef lim =     when (lim >= 1) $          updateWidgetState wRef $ \(VFixed _ ch) -> VFixed lim ch  -- |Set the horizontal fixed size of a child widget.-setHFixed :: (MonadIO m) => Widget (HFixed a) -> Int -> m ()+setHFixed :: Widget (HFixed a) -> Int -> IO () setHFixed wRef lim =     when (lim >= 1) $          updateWidgetState wRef $ \(HFixed _  ch) -> HFixed lim ch  -- |Add to the vertical fixed size of a child widget.-addToVFixed :: (MonadIO m) => Widget (VFixed a) -> Int -> m ()+addToVFixed :: Widget (VFixed a) -> Int -> IO () addToVFixed wRef delta = do   lim <- getVFixedSize wRef   setVFixed wRef $ lim + delta  -- |Add to the horizontal fixed size of a child widget.-addToHFixed :: (MonadIO m) => Widget (HFixed a) -> Int -> m ()+addToHFixed :: Widget (HFixed a) -> Int -> IO () addToHFixed wRef delta = do   lim <- getHFixedSize wRef   setHFixed wRef $ lim + delta  -- |Get the vertical fixed size of a child widget.-getVFixedSize :: (MonadIO m) => Widget (VFixed a) -> m Int+getVFixedSize :: Widget (VFixed a) -> IO Int getVFixedSize wRef = do   (VFixed lim _) <- state <~ wRef   return lim  -- |Get the horizontal fixed size of a child widget.-getHFixedSize :: (MonadIO m) => Widget (HFixed a) -> m Int+getHFixedSize :: Widget (HFixed a) -> IO Int getHFixedSize wRef = do   (HFixed lim _) <- state <~ wRef   return lim  -- |Impose a maximum horizontal and vertical size on a widget.-boxFixed :: (MonadIO m, Show a) =>+boxFixed :: (Show a) =>             Int -- ^Maximum width in columns          -> Int -- ^Maximum height in rows          -> Widget a-         -> m (Widget (VFixed (HFixed a)))+         -> IO (Widget (VFixed (HFixed a))) boxFixed maxWidth maxHeight w = do   ch <- hFixed maxWidth w   vFixed maxHeight ch
src/Graphics/Vty/Widgets/Limits.hs view
@@ -21,7 +21,6 @@ where  import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Util@@ -32,7 +31,7 @@     show (HLimit i _) = "HLimit { width = " ++ show i ++ ", ... }"  -- |Impose a maximum horizontal size, in columns, on a 'Widget'.-hLimit :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (HLimit a))+hLimit :: (Show a) => Int -> Widget a -> IO (Widget (HLimit a)) hLimit maxWidth child = do   wRef <- newWidget $ \w ->       w { state = HLimit maxWidth child@@ -58,7 +57,7 @@     show (VLimit i _) = "VLimit { height = " ++ show i ++ ", ... }"  -- |Impose a maximum vertical size, in columns, on a 'Widget'.-vLimit :: (MonadIO m, Show a) => Int -> Widget a -> m (Widget (VLimit a))+vLimit :: (Show a) => Int -> Widget a -> IO (Widget (VLimit a)) vLimit maxHeight child = do   wRef <- newWidget $ \w ->       w { state = VLimit maxHeight child@@ -80,48 +79,48 @@   return wRef  -- |Set the vertical limit of a child widget's size.-setVLimit :: (MonadIO m) => Widget (VLimit a) -> Int -> m ()+setVLimit :: Widget (VLimit a) -> Int -> IO () setVLimit wRef lim =     when (lim >= 1) $          updateWidgetState wRef $ \(VLimit _ ch) -> VLimit lim ch  -- |Set the horizontal limit of a child widget's size.-setHLimit :: (MonadIO m) => Widget (HLimit a) -> Int -> m ()+setHLimit :: Widget (HLimit a) -> Int -> IO () setHLimit wRef lim =     when (lim >= 1) $          updateWidgetState wRef $ \(HLimit _  ch) -> HLimit lim ch  -- |Add to the vertical limit of a child widget's size.-addToVLimit :: (MonadIO m) => Widget (VLimit a) -> Int -> m ()+addToVLimit :: Widget (VLimit a) -> Int -> IO () addToVLimit wRef delta = do   lim <- getVLimit wRef   setVLimit wRef $ lim + delta  -- |Add to the horizontal limit of a child widget's size.-addToHLimit :: (MonadIO m) => Widget (HLimit a) -> Int -> m ()+addToHLimit :: Widget (HLimit a) -> Int -> IO () addToHLimit wRef delta = do   lim <- getHLimit wRef   setHLimit wRef $ lim + delta  -- |Get the vertical limit of a child widget's size.-getVLimit :: (MonadIO m) => Widget (VLimit a) -> m Int+getVLimit :: Widget (VLimit a) -> IO Int getVLimit wRef = do   (VLimit lim _) <- state <~ wRef   return lim  -- |Get the horizontal limit of a child widget's size.-getHLimit :: (MonadIO m) => Widget (HLimit a) -> m Int+getHLimit :: Widget (HLimit a) -> IO Int getHLimit wRef = do   (HLimit lim _) <- state <~ wRef   return lim  -- |Impose a horizontal and vertical upper bound on the size of a -- widget.-boxLimit :: (MonadIO m, Show a) =>+boxLimit :: (Show a) =>             Int -- ^Maximum width in columns          -> Int -- ^Maximum height in rows          -> Widget a-         -> m (Widget (VLimit (HLimit a)))+         -> IO (Widget (VLimit (HLimit a))) boxLimit maxWidth maxHeight w = do   ch <- hLimit maxWidth w   vLimit maxHeight ch
src/Graphics/Vty/Widgets/List.hs view
@@ -17,6 +17,7 @@     , newStringList     , newList     , addToList+    , insertIntoList     , removeFromList     -- ** List manipulation     , scrollBy@@ -30,16 +31,17 @@     , onItemActivated     , activateCurrentItem     , clearList+    , setSelected     -- ** List inspection     , getListSize     , getSelected+    , getListItem     ) where  import Data.Typeable import Control.Exception hiding (Handler) import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Text@@ -100,7 +102,6 @@                      , itemRemoveHandlers :: Handlers (RemoveItemEvent a b)                      , itemActivateHandlers :: Handlers (ActivateItemEvent a b)                      , itemHeight :: Int-                     , itemConstructor :: a -> IO (Widget b)                      -- ^Function to construct new items                      } @@ -115,11 +116,9 @@                       , " }"                       ] -newListData :: (MonadIO m) =>-               Attr -- ^The attribute of the selected item-            -> (a -> IO (Widget b)) -- ^Constructor for new item widgets-            -> m (List a b)-newListData selAttr f = do+newListData :: Attr -- ^The attribute of the selected item+            -> IO (List a b)+newListData selAttr = do   schs <- newHandlers   iahs <- newHandlers   irhs <- newHandlers@@ -135,18 +134,18 @@                 , itemRemoveHandlers = irhs                 , itemActivateHandlers = iacths                 , itemHeight = 0-                , itemConstructor = f                 }  -- |Get the length of the list in elements.-getListSize :: (MonadIO m) => Widget (List a b) -> m Int+getListSize :: Widget (List a b) -> IO Int getListSize = ((length . listItems) <~~)  -- |Remove an element from the list at the specified position.  May -- throw 'BadItemIndex'.-removeFromList :: (MonadIO m) => Widget (List a b) -> Int -> m (ListItem a b)+removeFromList :: Widget (List a b) -> Int -> IO (ListItem a b) removeFromList list pos = do   st <- getState list+  foc <- focused <~ list    let numItems = length $ listItems st       oldScr = scrollTopIndex st@@ -185,6 +184,17 @@                                    , scrollTopIndex = newScrollTop                                    } +  when foc $ do+    -- Unfocus the item we are about to remove if it's currently+    -- selected+    when (pos == sel) $ do+               unfocus w+               -- Focus the newly-selected item, if any+               cur <- getSelected list+               case cur of+                 Nothing -> return ()+                 Just (_, (_, w')) -> focus w'+   -- Notify the removal handler.   notifyItemRemoveHandler list pos label w @@ -201,12 +211,14 @@ -- |Add an item to the list.  Its widget will be constructed from the -- specified internal value using the widget constructor passed to -- 'newList'.-addToList :: (MonadIO m, Show b) => Widget (List a b) -> a -> m (ListItem a b)-addToList list key = do+addToList :: (Show b) => Widget (List a b) -> a -> Widget b -> IO ()+addToList list key w = do   numItems <- (length . listItems) <~~ list+  insertIntoList list key w numItems -  makeWidget <- itemConstructor <~~ list-  w <- liftIO $ makeWidget key+insertIntoList :: (Show b) => Widget (List a b) -> a -> Widget b -> Int -> IO ()+insertIntoList list key w pos = do+  numItems <- (length . listItems) <~~ list    v <- growVertical w   when (v) $ throw BadListWidgetSizePolicy@@ -221,53 +233,69 @@            -- same size.  If you violate this, you'll have interesting            -- results!            img <- render w (DisplayRegion 100 100) defaultContext-           return $ fromEnum $ image_height img+           return $ max 1 $ fromEnum $ image_height img          _ -> itemHeight <~~ list +  -- Calculate the new selected index.+  oldSel <- selectedIndex <~~ list+  oldScr <- scrollTopIndex <~~ list+  swSize <- scrollWindowSize <~~ list++  let newSelIndex = if numItems == 0+                    then 0+                    else if pos <= oldSel+                         then oldSel + 1+                         else oldSel+      newScrollTop = if pos <= oldSel+                     then if (oldSel - oldScr + 1) == swSize+                          then oldScr + 1+                          else oldScr+                     else oldScr+   updateWidgetState list $ \s -> s { itemHeight = h-                                   , listItems = listItems s ++ [(key, w)]-                                   , selectedIndex = if numItems == 0-                                                     then 0-                                                     else selectedIndex s+                                   , listItems = inject pos (key, w) (listItems s)+                                   , selectedIndex = newSelIndex+                                   , scrollTopIndex = newScrollTop                                    }    notifyItemAddHandler list (numItems + 1) key w    when (numItems == 0) $-       notifySelectionHandler list+       do+         foc <- focused <~ list+         when foc $ focus w -  return (key, w)+  when (oldSel /= newSelIndex) $ notifySelectionHandler list  -- |Register event handlers to be invoked when the list's selected -- item changes.-onSelectionChange :: (MonadIO m) =>-                     Widget (List a b)+onSelectionChange :: Widget (List a b)                   -> (SelectionEvent a b -> IO ())-                  -> m ()+                  -> IO () onSelectionChange = addHandler (selectionChangeHandlers <~~)  -- |Register event handlers to be invoked when a new item is added to -- the list.-onItemAdded :: (MonadIO m) => Widget (List a b)-            -> (NewItemEvent a b -> IO ()) -> m ()+onItemAdded :: Widget (List a b)+            -> (NewItemEvent a b -> IO ()) -> IO () onItemAdded = addHandler (itemAddHandlers <~~)  -- |Register event handlers to be invoked when an item is removed from -- the list.-onItemRemoved :: (MonadIO m) => Widget (List a b)-              -> (RemoveItemEvent a b -> IO ()) -> m ()+onItemRemoved :: Widget (List a b)+              -> (RemoveItemEvent a b -> IO ()) -> IO () onItemRemoved = addHandler (itemRemoveHandlers <~~)  -- |Register event handlers to be invoked when an item is activated, -- which happens when the user presses Enter on a selected element -- while the list has the focus.-onItemActivated :: (MonadIO m) => Widget (List a b)-            -> (ActivateItemEvent a b -> IO ()) -> m ()+onItemActivated :: Widget (List a b)+            -> (ActivateItemEvent a b -> IO ()) -> IO () onItemActivated = addHandler (itemActivateHandlers <~~)  -- |Clear the list, removing all elements.  Does not invoke any -- handlers.-clearList :: (MonadIO m) => Widget (List a b) -> m ()+clearList :: Widget (List a b) -> IO () clearList w = do   updateWidgetState w $ \l ->       l { selectedIndex = (-1)@@ -276,15 +304,12 @@         }  -- |Create a new list using the specified attribute for the--- currently-selected element when the list does NOT have focus.  Use--- the specified constructor function to create widgets for new items--- in the list.-newList :: (MonadIO m, Show b) =>+-- currently-selected element when the list does NOT have focus.+newList :: (Show b) =>            Attr -- ^The attribute of the selected item-        -> (a -> IO (Widget b)) -- ^Constructor for new item widgets-        -> m (Widget (List a b))-newList selAttr f = do-  list <- newListData selAttr f+        -> IO (Widget (List a b))+newList selAttr = do+  list <- newListData selAttr   wRef <- newWidget $ \w ->       w { state = list         , keyEventHandler = listKeyEvent@@ -294,12 +319,10 @@          , getCursorPosition_ =             \this -> do-              st <- getState this-              pos <- getCurrentPosition this-              sz <- getCurrentSize this-              let newCol = max 0 (region_width pos + region_width sz - 1)-                  newRow = region_height pos + toEnum (max 0 $ selectedIndex st - scrollTopIndex st)-              return $ Just (pos `withWidth` newCol `withHeight` newRow)+              sel <- getSelected this+              case sel of+                Nothing -> return Nothing+                Just (_, (_, e)) -> getCursorPosition e          , render_ =             \this sz ctx -> do@@ -324,6 +347,21 @@               forM_ (zip [0..] items) $ \(i, ((_, iw), _)) ->                   setCurrentPosition iw (pos `plusHeight` (toEnum $ i * ih))         }++  wRef `onGainFocus` \_ ->+      do+        val <- getSelected wRef+        case val of+          Nothing -> return ()+          Just (_, (_, w)) -> focus w++  wRef `onLoseFocus` \_ ->+      do+        val <- getSelected wRef+        case val of+          Nothing -> return ()+          Just (_, (_, w)) -> unfocus w+   return wRef  listKeyEvent :: Widget (List a b) -> Key -> [Modifier] -> IO Bool@@ -332,7 +370,11 @@ listKeyEvent w KPageUp _ = pageUp w >> return True listKeyEvent w KPageDown _ = pageDown w >> return True listKeyEvent w KEnter _ = activateCurrentItem w >> return True-listKeyEvent _ _ _ = return False+listKeyEvent w k mods = do+  val <- getSelected w+  case val of+    Nothing -> return False+    Just (_, (_, e)) -> handleKeyEvent e k mods  renderListWidget :: (Show b) => Bool -> List a b -> DisplayRegion -> RenderContext -> IO Image renderListWidget foc list s ctx = do@@ -371,18 +413,18 @@ -- |A convenience function to create a new list using 'String's as the -- internal values and 'FormattedText' widgets to represent those -- strings.-newStringList :: (MonadIO m) =>-                 Attr -- ^The attribute of the selected item+newStringList :: Attr -- ^The attribute of the selected item               -> [String] -- ^The list items-              -> m (Widget (List String FormattedText))+              -> IO (Widget (List String FormattedText)) newStringList selAttr labels = do-  list <- newList selAttr plainText-  mapM_ (addToList list) labels+  list <- newList selAttr+  forM_ labels $ \l ->+      (addToList list l =<< plainText l)   return list  -- |Programmatically activate the currently-selected item in the list, -- if any.-activateCurrentItem :: (MonadIO m) => Widget (List a b) -> m ()+activateCurrentItem :: Widget (List a b) -> IO () activateCurrentItem wRef = do   mSel <- getSelected wRef   case mSel of@@ -393,14 +435,30 @@ -- note that !! here will always succeed because selectedIndex will -- never be out of bounds and the list will always be non-empty. -- |Get the currently-selected list item.-getSelected :: (MonadIO m) => Widget (List a b) -> m (Maybe (Int, ListItem a b))+getSelected :: Widget (List a b) -> IO (Maybe (Int, ListItem a b)) getSelected wRef = do   list <- state <~ wRef   case selectedIndex list of     (-1) -> return Nothing     i -> return $ Just (i, (listItems list) !! i) -resize :: (MonadIO m) => Widget (List a b) -> Int -> m ()+-- |Get the list item at the specified position.+getListItem :: Widget (List a b) -> Int -> IO (Maybe (ListItem a b))+getListItem wRef pos = do+  list <- state <~ wRef+  case pos >= 0 && pos < (length $ listItems list) of+    False ->  return Nothing+    True -> return $ Just ((listItems list) !! pos)++-- |Set the currently-selected list index.+setSelected :: Widget (List a b) -> Int -> IO ()+setSelected wRef newPos = do+  list <- state <~ wRef+  case selectedIndex list of+    (-1) -> return ()+    curPos -> scrollBy wRef (newPos - curPos)++resize :: Widget (List a b) -> Int -> IO () resize wRef newSize = do   when (newSize == 0) $ throw ResizeError @@ -434,9 +492,24 @@ -- Scrolling by a positive amount scrolls downward and scrolling by a -- negative amount scrolls upward.  This automatically takes care of -- managing internal list state and invoking event handlers.-scrollBy :: (MonadIO m) => Widget (List a b) -> Int -> m ()+scrollBy :: Widget (List a b) -> Int -> IO () scrollBy wRef amount = do+  foc <- focused <~ wRef++  -- Unfocus the currently-selected item.+  old <- getSelected wRef+  case old of+    Nothing -> return ()+    Just (_, (_, w)) -> when foc $ unfocus w+   updateWidgetState wRef $ scrollBy' amount++  -- Focus the newly-selected item.+  new <- getSelected wRef+  case new of+    Nothing -> return ()+    Just (_, (_, w)) -> when foc $ focus w+   notifySelectionHandler wRef  scrollBy' :: Int -> List a b -> List a b@@ -468,7 +541,7 @@      else list { scrollTopIndex = adjustedTop                , selectedIndex = newSelected } -notifySelectionHandler :: (MonadIO m) => Widget (List a b) -> m ()+notifySelectionHandler :: Widget (List a b) -> IO () notifySelectionHandler wRef = do   sel <- getSelected wRef   case sel of@@ -477,35 +550,35 @@     Just (pos, (a, b)) ->         fireEvent wRef (selectionChangeHandlers <~~) $ SelectionOn pos a b -notifyItemRemoveHandler :: (MonadIO m) => Widget (List a b) -> Int -> a -> Widget b -> m ()+notifyItemRemoveHandler :: Widget (List a b) -> Int -> a -> Widget b -> IO () notifyItemRemoveHandler wRef pos k w =     fireEvent wRef (itemRemoveHandlers <~~) $ RemoveItemEvent pos k w -notifyItemAddHandler :: (MonadIO m) => Widget (List a b) -> Int -> a -> Widget b -> m ()+notifyItemAddHandler :: Widget (List a b) -> Int -> a -> Widget b -> IO () notifyItemAddHandler wRef pos k w =     fireEvent wRef (itemAddHandlers <~~) $ NewItemEvent pos k w  -- |Scroll a list down by one position.-scrollDown :: (MonadIO m) => Widget (List a b) -> m ()+scrollDown :: Widget (List a b) -> IO () scrollDown wRef = scrollBy wRef 1  -- |Scroll a list up by one position.-scrollUp :: (MonadIO m) => Widget (List a b) -> m ()+scrollUp :: Widget (List a b) -> IO () scrollUp wRef = scrollBy wRef (-1)  -- |Scroll a list down by one page from the current cursor position.-pageDown :: (MonadIO m) => Widget (List a b) -> m ()+pageDown :: Widget (List a b) -> IO () pageDown wRef = do   amt <- scrollWindowSize <~~ wRef   scrollBy wRef amt  -- |Scroll a list up by one page from the current cursor position.-pageUp :: (MonadIO m) => Widget (List a b) -> m ()+pageUp :: Widget (List a b) -> IO () pageUp wRef = do   amt <- scrollWindowSize <~~ wRef   scrollBy wRef (-1 * amt) -getVisibleItems :: (MonadIO m) => Widget (List a b) -> m [(ListItem a b, Bool)]+getVisibleItems :: Widget (List a b) -> IO [(ListItem a b, Bool)] getVisibleItems wRef = do   list <- state <~ wRef   return $ getVisibleItems_ list
src/Graphics/Vty/Widgets/Padding.hs view
@@ -21,7 +21,6 @@  import Data.Word import Data.Monoid-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Util@@ -100,11 +99,11 @@ padLeftRight v = Padding 0 v 0 v  -- |Monadic combinator to construct a 'Padded' wrapper.-withPadding :: (MonadIO m, Show a) => Padding -> Widget a -> m (Widget Padded)+withPadding :: (Show a) => Padding -> Widget a -> IO (Widget Padded) withPadding = flip padded  -- |Create a 'Padded' wrapper to add padding.-padded :: (MonadIO m, Show a) => Widget a -> Padding -> m (Widget Padded)+padded :: (Show a) => Widget a -> Padding -> IO (Widget Padded) padded ch padding = do   wRef <- newWidget $ \w ->       w { state = Padded ch padding
src/Graphics/Vty/Widgets/ProgressBar.hs view
@@ -30,7 +30,7 @@  -- |Create a new progress bar with the specified completed and -- uncompleted colors, respectively.-newProgressBar :: (MonadIO m) => Color -> Color -> m ProgressBar+newProgressBar :: Color -> Color -> IO ProgressBar newProgressBar completeColor incompleteColor = do   let completeAttr = completeColor `on` completeColor       incompleteAttr = incompleteColor `on` incompleteColor@@ -45,12 +45,12 @@  -- |Register a handler to be invoked when the progress bar's progress -- value changes.  The handler will be passed the new progress value.-onProgressChange :: (MonadIO m) => ProgressBar -> (Int -> IO ()) -> m ()+onProgressChange :: ProgressBar -> (Int -> IO ()) -> IO () onProgressChange = addHandler (return . onChangeHandlers)  -- |Set the progress bar's progress value.  Values outside the allowed -- range will be ignored.-setProgress :: (MonadIO m) => ProgressBar -> Int -> m ()+setProgress :: ProgressBar -> Int -> IO () setProgress p amt =     when (amt >= 0 && amt <= 100) $ do       liftIO $ writeIORef (progressBarAmount p) amt@@ -58,11 +58,11 @@       fireEvent p (return . onChangeHandlers) amt  -- |Get the progress bar's current progress value.-getProgress :: (MonadIO m) => ProgressBar -> m Int+getProgress :: ProgressBar -> IO Int getProgress = liftIO . readIORef . progressBarAmount  -- |Add a delta value to the progress bar's current value.-addProgress :: (MonadIO m) => ProgressBar -> Int -> m ()+addProgress :: ProgressBar -> Int -> IO () addProgress p amt = do   cur <- getProgress p   let newAmt = cur + amt
src/Graphics/Vty/Widgets/Table.hs view
@@ -33,7 +33,6 @@ import Control.Applicative hiding ((<|>)) import Control.Exception import Control.Monad-import Control.Monad.Trans import Graphics.Vty import Graphics.Vty.Widgets.Core import Graphics.Vty.Widgets.Text@@ -199,11 +198,11 @@ emptyCell = EmptyCell  -- |Set the default table-wide cell alignment.-setDefaultCellAlignment :: (MonadIO m) => Widget Table -> Alignment -> m ()+setDefaultCellAlignment :: Widget Table -> Alignment -> IO () setDefaultCellAlignment t a = updateWidgetState t $ \s -> s { defaultCellAlignment = a }  -- |Set the default table-wide cell padding.-setDefaultCellPadding :: (MonadIO m) => Widget Table -> Padding -> m ()+setDefaultCellPadding :: Widget Table -> Padding -> IO () setDefaultCellPadding t p = updateWidgetState t $ \s -> s { defaultCellPadding = p }  -- |Create a column.@@ -212,10 +211,10 @@  -- |Create a table widget using a list of column specifications and a -- border style.-newTable :: (MonadIO m) =>+newTable ::              [ColumnSpec]          -> BorderStyle-         -> m (Widget Table)+         -> IO (Widget Table) newTable specs borderSty = do   t <- newWidget $ \w ->       w { state = Table { rows = []@@ -298,7 +297,7 @@         }   return t -getCellAlignment :: (MonadIO m) => Widget Table -> Int -> TableCell -> m Alignment+getCellAlignment :: Widget Table -> Int -> TableCell -> IO Alignment getCellAlignment _ _ (TableCell _ (Just p) _) = return p getCellAlignment t columnNumber _ = do   -- If the column for this cell has properties, use those; otherwise@@ -310,7 +309,7 @@     Nothing -> defaultCellAlignment <~~ t     Just p -> return p -getCellPadding :: (MonadIO m) => Widget Table -> Int -> TableCell -> m Padding+getCellPadding :: Widget Table -> Int -> TableCell -> IO Padding getCellPadding _ _ (TableCell _ _ (Just p)) = return p getCellPadding t columnNumber _ = do   -- If the column for this cell has properties, use those; otherwise@@ -439,7 +438,7 @@    doPositioning 0 $ zip szs cells -autoWidth :: (MonadIO m) => Widget Table -> DisplayRegion -> m Word+autoWidth :: Widget Table -> DisplayRegion -> IO Word autoWidth t sz = do   specs <- columnSpecs <~~ t   bs <- borderStyle <~~ t@@ -456,16 +455,16 @@   return $ toEnum ((max 0 ((fromEnum $ region_width sz) - totalFixed - edgeWidth - colWidth))                    `div` numAuto) -addHeadingRow :: (MonadIO m) => Widget Table -> Attr -> [String] -> m [Widget FormattedText]+addHeadingRow :: Widget Table -> Attr -> [String] -> IO [Widget FormattedText] addHeadingRow tbl attr labels = do   ws <- mapM (\s -> plainText s >>= withNormalAttribute attr) labels   addRow tbl ws   return ws -addHeadingRow_ :: (MonadIO m) => Widget Table -> Attr -> [String] -> m ()+addHeadingRow_ :: Widget Table -> Attr -> [String] -> IO () addHeadingRow_ tbl attr labels = addHeadingRow tbl attr labels >> return () -applyCellAlignment :: (MonadIO m) => Alignment -> TableCell -> m TableCell+applyCellAlignment :: Alignment -> TableCell -> IO TableCell applyCellAlignment _ EmptyCell = return EmptyCell applyCellAlignment al (TableCell w a p) = do   case al of@@ -488,7 +487,7 @@                   return $ TableCell w' a p         True -> return $ TableCell w a p -applyCellPadding :: (MonadIO m) => Padding -> TableCell -> m TableCell+applyCellPadding :: Padding -> TableCell -> IO TableCell applyCellPadding _ EmptyCell = return EmptyCell applyCellPadding padding (TableCell w a p) = do   w' <- padded w padding@@ -498,7 +497,7 @@ -- row.  Throws 'BadTableWidgetSizePolicy' if any widgets in the row -- grow vertically; throws 'ColumnCountMismatch' if the row's number -- of columns does not match the table's column count.-addRow :: (MonadIO m, RowLike a) => Widget Table -> a -> m ()+addRow :: (RowLike a) => Widget Table -> a -> IO () addRow t row = do   let (TableRow cells_) = mkRow row 
src/Graphics/Vty/Widgets/Text.hs view
@@ -21,7 +21,6 @@     ) where -import Control.Monad.Trans import Data.Maybe import Data.Word import Graphics.Vty@@ -70,7 +69,7 @@  -- |Construct a Widget directly from a String.  This is recommended if -- you don't need to use a 'Formatter'.-plainText :: (MonadIO m) => String -> m (Widget FormattedText)+plainText :: String -> IO (Widget FormattedText) plainText s = textWidget nullFormatter s  -- |A formatter for wrapping text into the available space.  This@@ -103,12 +102,13 @@ -- |Construct a text widget formatted with the specified formatters. -- the formatters will be applied in the order given here, so be aware -- of how the formatters will modify the text (and affect each other).-textWidget :: (MonadIO m) => Formatter -> String -> m (Widget FormattedText)+textWidget :: Formatter -> String -> IO (Widget FormattedText) textWidget format s = do   wRef <- newWidget $ \w ->       w { state = FormattedText { text = prepareText s                                 , formatter = format                                 }+        , getCursorPosition_ = const $ return Nothing         , render_ =             \this size ctx -> do               ft <- getState this@@ -118,7 +118,7 @@   return wRef  -- |Set the text value of a 'FormattedText' widget.-setText :: (MonadIO m) => Widget FormattedText -> String -> m ()+setText :: Widget FormattedText -> String -> IO () setText wRef s = do   updateWidgetState wRef $ \st ->       st { text = (prepareText s) }
src/Graphics/Vty/Widgets/Util.hs view
@@ -9,6 +9,9 @@     , withHeight     , plusWidth     , plusHeight+    , remove+    , inject+    , repl     ) where @@ -37,11 +40,12 @@ -- Left-most attribute's fields take precedence. -- |Merge two attributes.  Leftmost attribute takes precedence where -- it specifies any of the foreground color, background color, or--- style.+-- style.  Note that the style precedence is total: all bits of the+-- style mask will take precedence if any are set. mergeAttr :: Attr -> Attr -> Attr mergeAttr a b =     let b1 = case attr_style a of-               SetTo v -> b `with_style` v+               SetTo v -> b { attr_style = SetTo v }                _ -> b         b2 = case attr_fore_color a of                SetTo v -> b1 `with_fore_color` v@@ -76,3 +80,13 @@     if (fromEnum h' + fromEnum h < 0)     then error $ "plusHeight: would overflow on " ++ (show h') ++ " + " ++ (show h)     else DisplayRegion w (h + h')++remove :: Int -> [a] -> [a]+remove pos as = (take pos as) ++ (drop (pos + 1) as)++inject :: Int -> a -> [a] -> [a]+inject pos a as = let (h, t) = splitAt pos as+                  in h ++ (a:t)++repl :: Int -> a -> [a] -> [a]+repl pos a as = inject pos a (remove pos as)
src/ListDemo.hs view
@@ -106,7 +106,8 @@   -- context.   (theEdit st) `onChange` (updateFooterText st (theEdit st))   (theEdit st) `onActivate` \e -> do-         addToList (theList st) =<< getEditText e+         s <- getEditText e+         addToList (theList st) s =<< plainText s          setEditText e ""    let doBodyUpdate (SelectionOn i _ _) = updateBody st i@@ -152,6 +153,7 @@            _ -> return False    setEditText (theEdit st) "edit me"+  focus (theEdit st)    -- We need to call these handlers manually because while they will   -- be called automatically as items are added to the list in the
src/PhoneInputDemo.hs view
@@ -3,7 +3,6 @@ -- This demo is discussed in the vty-ui user's manual.  import Control.Monad-import Control.Monad.Trans  import Graphics.Vty import Graphics.Vty.Widgets.All@@ -26,7 +25,7 @@               , activateHandlers :: Handlers PhoneNumber               } -newPhoneInput :: (MonadIO m) => m (PhoneInput, Widget FocusGroup)+newPhoneInput :: IO (PhoneInput, Widget FocusGroup) newPhoneInput = do    ahs <- newHandlers    e1 <- editWidget@@ -64,8 +63,8 @@    mapM_ (addToFocusGroup fg) [e1, e2, e3]    return (w, fg) -onPhoneInputActivate :: (MonadIO m) => PhoneInput-                     -> (PhoneNumber -> IO ()) -> m ()+onPhoneInputActivate :: PhoneInput+                     -> (PhoneNumber -> IO ()) -> IO () onPhoneInputActivate input handler =     addHandler (return . activateHandlers) input handler 
test/src/Tests/FormattedText.hs view
vty-ui.cabal view
@@ -1,5 +1,5 @@ Name:                vty-ui-Version:             1.0.1+Version:             1.1 Synopsis:            An interactive terminal user interface library                      for Vty Description:         An extensible library of user interface widgets@@ -75,10 +75,10 @@   Build-Depends:     base >= 4 && < 5,     vty >= 4.6 && < 4.7,-    containers >= 0.2 && < 0.4,+    containers >= 0.2 && < 0.5,     pcre-light >= 0.3 && < 0.4,-    directory >= 1.0 && < 1.1,-    filepath >= 1.1 && < 1.2,+    directory >= 1.0 && < 1.2,+    filepath >= 1.1 && < 1.3,     unix >= 2.4 && < 2.5,     mtl >= 2.0 && < 2.1 @@ -155,7 +155,7 @@     base >= 4 && < 5,     mtl >= 2.0 && < 2.1,     bytestring >= 0.9 && < 1.0,-    time >= 1.1 && < 1.2,+    time >= 1.1 && < 1.3,     old-locale >= 1.0 && < 1.1,     pcre-light >= 0.3 && < 0.4,     vty >= 4.6 && < 4.7