packages feed

reflex-vty 0.2.0.1 → 0.3.0.0

raw patch · 3 files changed

+52/−8 lines, 3 filesdep ~vty

Dependency ranges changed: vty

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Revision history for reflex-vty +## 0.3.0.0++* Re-design `textInput`, `TextInput` and `TextInputConfig`.+  * Allows users to implement more complex behavior.+  * `_textInputConfig_modify` is now applied to the text-value of `textInput`+    after user input events such as mouse clicks and keyboard input.+    This may change the observable behavior.+ ## 0.2.0.1  * Loosen version bounds on ref-tf and vty
reflex-vty.cabal view
@@ -1,5 +1,5 @@ name: reflex-vty-version: 0.2.0.1+version: 0.3.0.0 synopsis: Reflex FRP host and widgets for VTY applications description:   Build terminal applications using functional reactive programming (FRP) with Reflex FRP (<https://reflex-frp.org>).@@ -56,7 +56,7 @@     ref-tf >= 0.4.0 && < 0.6,     reflex >= 0.8 && < 0.9,     time >= 1.8.0 && < 1.10,-    vty >= 5.28 && < 5.37+    vty >= 5.28 && < 5.34   hs-source-dirs: src   default-language: Haskell2010   ghc-options: -Wall
src/Reflex/Vty/Widget/Input/Text.hs view
@@ -10,6 +10,7 @@ import Control.Monad (join) import Control.Monad.Fix (MonadFix) import Data.Default (Default(..))+import Data.Function ((&)) import Data.Text (Text) import Data.Text.Zipper import qualified Graphics.Vty as V@@ -23,7 +24,29 @@ -- 'TextZipper', see 'Data.Text.Zipper'. data TextInputConfig t = TextInputConfig   { _textInputConfig_initialValue :: TextZipper+  -- ^ Initial value. This is a 'TextZipper' because it is more flexible+  -- than plain 'Text'. For example, this allows to set the Cursor position,+  -- by choosing appropriate values for '_textZipper_before' and '_textZipper_after'.   , _textInputConfig_modify :: Event t (TextZipper -> TextZipper)+  -- ^ Event to update the value of the 'textInput'.+  --+  -- Event is applied after other Input sources have been applied to the 'TextZipper',+  -- thus you may modify the final value that is displayed to the user.+  --+  -- You may set the value of the displayed text in 'textInput' by ignoring the input parameter.+  --+  -- Additionally, you can modify the updated value before displaying it to the user.+  -- For example, the following 'TextInputConfig' inserts an additional 'a'+  -- when the letter 'b' is entered into 'textInput':+  --+  -- @+  --   i <- input+  --   textInput def+  --     { _textInputConfig_modify = fforMaybe i $ \case+  --         V.EvKey (V.KChar 'b') _ -> Just (insert "a")+  --         _ -> Nothing+  --     }+  -- @   , _textInputConfig_tabWidth :: Int   , _textInputConfig_display :: Dynamic t (Char -> Char)   -- ^ Transform the characters in a text input before displaying them. This is useful, e.g., for@@ -38,6 +61,11 @@ -- display lines may not be visible due to scrolling. data TextInput t = TextInput   { _textInput_value :: Dynamic t Text+  -- ^ The current value of the textInput as Text.+  , _textInput_userInput :: Event t TextZipper+  -- ^ UI Event updates with the current 'TextZipper'.+  -- This does not include Events added by '_textInputConfig_setValue', but+  -- it does include '_textInputConfig_modify' Events.   , _textInput_lines :: Dynamic t Int   } @@ -53,12 +81,19 @@   dw <- displayWidth   bt <- theme   attr0 <- sample bt-  rec v <- foldDyn ($) (_textInputConfig_initialValue cfg) $ mergeWith (.)-        [ uncurry (updateTextZipper (_textInputConfig_tabWidth cfg)) <$> attach (current dh) i-        , _textInputConfig_modify cfg-        , let displayInfo = (,) <$> current rows <*> scrollTop-          in ffor (attach displayInfo click) $ \((dl, st), MouseDown _ (mx, my) _) ->-            goToDisplayLinePosition mx (st + my) dl+  rec+      -- we split up the events from vty and the one users provide to avoid cyclical+      -- update dependencies. This way, users may subscribe only to UI updates.+      let valueChangedByCaller = _textInputConfig_modify cfg+      let valueChangedByUI = mergeWith (.)+            [ uncurry (updateTextZipper (_textInputConfig_tabWidth cfg)) <$> attach (current dh) i+            , let displayInfo = (,) <$> current rows <*> scrollTop+              in ffor (attach displayInfo click) $ \((dl, st), MouseDown _ (mx, my) _) ->+                goToDisplayLinePosition mx (st + my) dl+            ]+      v <- foldDyn ($) (_textInputConfig_initialValue cfg) $ mergeWith (.)+        [ valueChangedByCaller+        , valueChangedByUI         ]       click <- mouseDown V.BLeft @@ -85,6 +120,7 @@       tellImages $ (\imgs st -> (:[]) . V.vertCat $ drop st imgs) <$> current img <*> scrollTop   return $ TextInput     { _textInput_value = value <$> v+    , _textInput_userInput = attachWith (&) (current v) valueChangedByUI     , _textInput_lines = length . _displayLines_spans <$> rows     }