@@ -11,7 +11,10 @@ Description: Basic set of widgets and building blocks for reflex-vty application
11{-# LANGUAGE OverloadedStrings #-}
11{-# LANGUAGE OverloadedStrings #-}
12{-# LANGUAGE RankNTypes #-}
12{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE RecursiveDo #-}
13{-# LANGUAGE RecursiveDo #-}
14+{-# LANGUAGE ScopedTypeVariables #-}
15+{-# LANGUAGE StandaloneDeriving #-}
14{-# LANGUAGE TypeFamilies #-}
16{-# LANGUAGE TypeFamilies #-}
17+{-# LANGUAGE UndecidableInstances #-}
15module Reflex.Vty.Widget
18module Reflex.Vty.Widget
16 ( VtyWidgetCtx(..)
19 ( VtyWidgetCtx(..)
17 , VtyWidget(..)
20 , VtyWidget(..)
@@ -32,6 +35,7 @@ module Reflex.Vty.Widget
32 , MouseDown(..)
35 , MouseDown(..)
33 , MouseUp(..)
36 , MouseUp(..)
34 , mouseDown
37 , mouseDown
36 , modifyImages
40 , modifyImages
37 , tellImages
41 , tellImages
@@ -55,6 +59,7 @@ import Control.Monad.Fix (MonadFix)
55import Control.Monad.Trans (lift)
59import Control.Monad.Trans (lift)
56import Control.Monad.Trans.Reader (ReaderT, runReaderT, asks, ask)
60import Control.Monad.Trans.Reader (ReaderT, runReaderT, asks, ask)
57import Control.Monad.Trans.Writer (WriterT, runWriterT, censor, tell)
61import Control.Monad.Trans.Writer (WriterT, runWriterT, censor, tell)
62+import Control.Monad.Writer.Adjustable ()
58import Data.Default (Default(..))
63import Data.Default (Default(..))
59import Data.Text (Text)
64import Data.Text (Text)
60import qualified Data.Text as T
65import qualified Data.Text as T
@@ -62,6 +67,9 @@ import qualified Data.Text.Zipper as TZ
62import Graphics.Vty (Image)
67import Graphics.Vty (Image)
63import qualified Graphics.Vty as V
68import qualified Graphics.Vty as V
64import Reflex
69import Reflex
70+import Reflex.Class.Switchable
71+import Reflex.NotReady.Class
72+import Reflex.NotReady.Class.Orphans ()
66import Reflex.Vty.Host
74import Reflex.Vty.Host
@@ -96,11 +104,32 @@ instance (Reflex t) => Monoid (VtyWidgetOut t) where
96 mempty = VtyWidgetOut mempty mempty
104 mempty = VtyWidgetOut mempty mempty
97 mappend wo wo' = wo <> wo'
105 mappend wo wo' = wo <> wo'
107+instance Reflex t => Switchable t (VtyWidgetOut t) where
109+ shutdown <- switching (_vtyWidgetOut_shutdown e0) $ fmap _vtyWidgetOut_shutdown e
110+ images <- switching (_vtyWidgetOut_images e0) $ fmap _vtyWidgetOut_images e
111+ return $ VtyWidgetOut
112+ { _vtyWidgetOut_images = images
113+ , _vtyWidgetOut_shutdown = shutdown
99-- | A widget that can read its context and produce image output
116-- | A widget that can read its context and produce image output
100newtype VtyWidget t m a = VtyWidget
117newtype VtyWidget t m a = VtyWidget
101 { unVtyWidget :: WriterT (VtyWidgetOut t) (ReaderT (VtyWidgetCtx t) m) a
118 { unVtyWidget :: WriterT (VtyWidgetOut t) (ReaderT (VtyWidgetCtx t) m) a
103− deriving (Functor, Applicative, Monad, MonadSample t, MonadHold t, MonadFix)
120+ deriving (Functor, Applicative, Monad, MonadSample t, MonadHold t, MonadFix, NotReady t)
122+instance (PostBuild t m, Reflex t) => PostBuild t (VtyWidget t m) where
123+ getPostBuild = VtyWidget $ lift getPostBuild
125+instance (Adjustable t m, MonadHold t m, Reflex t) => Adjustable t (VtyWidget t m) where
126+ runWithReplace a0 a' = VtyWidget $ runWithReplace (unVtyWidget a0) $ fmap unVtyWidget a'
127+ traverseIntMapWithKeyWithAdjust f dm0 dm' = VtyWidget $
128+ traverseIntMapWithKeyWithAdjust (\k v -> unVtyWidget (f k v)) dm0 dm'
129+ traverseDMapWithKeyWithAdjust f dm0 dm' = VtyWidget $ do
130+ traverseDMapWithKeyWithAdjust (\k v -> unVtyWidget (f k v)) dm0 dm'
131+ traverseDMapWithKeyWithAdjustWithMove f dm0 dm' = VtyWidget $ do
132+ traverseDMapWithKeyWithAdjustWithMove (\k v -> unVtyWidget (f k v)) dm0 dm'
105-- | Runs a 'VtyWidget' with a given context
134-- | Runs a 'VtyWidget' with a given context
106runVtyWidget
135runVtyWidget
@@ -128,7 +157,9 @@ mainWidgetWithHandle vty child =
128 , _vtyWidgetCtx_input = inp'
157 , _vtyWidgetCtx_input = inp'
129 , _vtyWidgetCtx_focus = constDyn True
158 , _vtyWidgetCtx_focus = constDyn True
131− ((), wo) <- runVtyWidget ctx child
160+ ((), wo) <- runVtyWidget ctx $ do
161+ tellImages . ffor (current size) $ \(w, h) -> [V.charFill V.defAttr ' ' w h]
132 return $ VtyResult
163 return $ VtyResult
133 { _vtyResult_picture = fmap (V.picForLayers . reverse) (_vtyWidgetOut_images wo)
164 { _vtyResult_picture = fmap (V.picForLayers . reverse) (_vtyWidgetOut_images wo)
134 , _vtyResult_shutdown = _vtyWidgetOut_shutdown wo
165 , _vtyResult_shutdown = _vtyWidgetOut_shutdown wo
@@ -316,6 +347,16 @@ mouseDown btn = do
316 else Nothing
347 else Nothing
317 _ -> Nothing
348 _ -> Nothing
350+-- | Mouse up events for a particular mouse button
352+ :: (Reflex t, Monad m)
353+ => VtyWidget t m (Event t MouseUp)
356+ return $ fforMaybe i $ \case
357+ V.EvMouseUp x y btn' -> Just $ MouseUp btn' (x, y)
319-- | Information about a mouse down event
360-- | Information about a mouse down event
320data MouseDown = MouseDown
361data MouseDown = MouseDown
321 { _mouseDown_button :: V.Button
362 { _mouseDown_button :: V.Button