@@ -11,7 +11,10 @@ Description: Basic set of widgets and building blocks for reflex-vty application
1111{-# LANGUAGE OverloadedStrings #-}
1212{-# LANGUAGE RankNTypes #-}
1313{-# LANGUAGE RecursiveDo #-}
14+{-# LANGUAGE ScopedTypeVariables #-}
15+{-# LANGUAGE StandaloneDeriving #-}
1416{-# LANGUAGE TypeFamilies #-}
17+{-# LANGUAGE UndecidableInstances #-}
1518module Reflex.Vty.Widget
1619 ( VtyWidgetCtx(..)
1720 , VtyWidget(..)
@@ -32,6 +35,7 @@ module Reflex.Vty.Widget
3235 , MouseDown(..)
3336 , MouseUp(..)
3437 , mouseDown
38+ , mouseUp
3539 , pane
3640 , modifyImages
3741 , tellImages
@@ -55,6 +59,7 @@ import Control.Monad.Fix (MonadFix)
5559import Control.Monad.Trans (lift)
5660import Control.Monad.Trans.Reader (ReaderT, runReaderT, asks, ask)
5761import Control.Monad.Trans.Writer (WriterT, runWriterT, censor, tell)
62+import Control.Monad.Writer.Adjustable ()
5863import Data.Default (Default(..))
5964import Data.Text (Text)
6065import qualified Data.Text as T
@@ -62,6 +67,9 @@ import qualified Data.Text.Zipper as TZ
6267import Graphics.Vty (Image)
6368import qualified Graphics.Vty as V
6469import Reflex
70+import Reflex.Class.Switchable
71+import Reflex.NotReady.Class
72+import Reflex.NotReady.Class.Orphans ()
6573
6674import Reflex.Vty.Host
6775
@@ -96,11 +104,32 @@ instance (Reflex t) => Monoid (VtyWidgetOut t) where
96104 mempty = VtyWidgetOut mempty mempty
97105 mappend wo wo' = wo <> wo'
98106
107+instance Reflex t => Switchable t (VtyWidgetOut t) where
108+ switching e0 e = do
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
114+ }
115+
99116-- | A widget that can read its context and produce image output
100117newtype VtyWidget t m a = VtyWidget
101118 { unVtyWidget :: WriterT (VtyWidgetOut t) (ReaderT (VtyWidgetCtx t) m) a
102119 }
103− deriving (Functor, Applicative, Monad, MonadSample t, MonadHold t, MonadFix)
120+ deriving (Functor, Applicative, Monad, MonadSample t, MonadHold t, MonadFix, NotReady t)
121+
122+instance (PostBuild t m, Reflex t) => PostBuild t (VtyWidget t m) where
123+ getPostBuild = VtyWidget $ lift getPostBuild
124+
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'
104133
105134-- | Runs a 'VtyWidget' with a given context
106135runVtyWidget
@@ -128,7 +157,9 @@ mainWidgetWithHandle vty child =
128157 , _vtyWidgetCtx_input = inp'
129158 , _vtyWidgetCtx_focus = constDyn True
130159 }
131− ((), wo) <- runVtyWidget ctx child
160+ ((), wo) <- runVtyWidget ctx $ do
161+ tellImages . ffor (current size) $ \(w, h) -> [V.charFill V.defAttr ' ' w h]
162+ child
132163 return $ VtyResult
133164 { _vtyResult_picture = fmap (V.picForLayers . reverse) (_vtyWidgetOut_images wo)
134165 , _vtyResult_shutdown = _vtyWidgetOut_shutdown wo
@@ -316,6 +347,16 @@ mouseDown btn = do
316347 else Nothing
317348 _ -> Nothing
318349
350+-- | Mouse up events for a particular mouse button
351+mouseUp
352+ :: (Reflex t, Monad m)
353+ => VtyWidget t m (Event t MouseUp)
354+mouseUp = do
355+ i <- input
356+ return $ fforMaybe i $ \case
357+ V.EvMouseUp x y btn' -> Just $ MouseUp btn' (x, y)
358+ _ -> Nothing
359+
319360-- | Information about a mouse down event
320361data MouseDown = MouseDown
321362 { _mouseDown_button :: V.Button