2
2
Module: Reflex.Vty.Widget
3
3
Description: Basic set of widgets and building blocks for reflex-vty applications
4
4
-}
5
+ {-# Language ScopedTypeVariables #-}
5
6
{-# Language UndecidableInstances #-}
7
+ {-# Language PolyKinds #-}
8
+ {-# Language RankNTypes #-}
6
9
7
10
module Reflex.Vty.Widget where
8
11
9
12
import Control.Applicative (liftA2 )
10
- import Control.Monad.Catch (MonadCatch , MonadThrow , MonadMask )
13
+ import Control.Monad.Catch (MonadCatch , MonadMask , MonadThrow )
11
14
import Control.Monad.Fix (MonadFix )
12
15
import Control.Monad.IO.Class (MonadIO )
13
16
import Control.Monad.Morph (MFunctor (.. ))
14
17
import Control.Monad.NodeId
15
- import Control.Monad.Reader (ReaderT , ask , local , runReaderT )
18
+ import Control.Monad.Reader (ReaderT ( .. ) , ask , local , runReaderT )
16
19
import Control.Monad.Ref
17
20
import Control.Monad.Trans (MonadTrans , lift )
21
+ import Control.Monad.Trans.State.Strict
18
22
import Data.Set (Set )
19
23
import qualified Data.Set as Set
20
24
import Graphics.Vty (Image )
@@ -129,7 +133,10 @@ deriving instance NotReady t m => NotReady t (Input t m)
129
133
deriving instance PerformEvent t m => PerformEvent t (Input t m )
130
134
deriving instance PostBuild t m => PostBuild t (Input t m )
131
135
deriving instance TriggerEvent t m => TriggerEvent t (Input t m )
132
- instance HasImageWriter t m => HasImageWriter t (Input t m )
136
+ instance HasImageWriter t m => HasImageWriter t (Input t m ) where
137
+ captureImages x = do
138
+ a <- input
139
+ lift $ captureImages $ runInput a x
133
140
instance HasDisplayRegion t m => HasDisplayRegion t (Input t m )
134
141
instance HasFocusReader t m => HasFocusReader t (Input t m )
135
142
@@ -354,7 +361,10 @@ deriving instance NotReady t m => NotReady t (DisplayRegion t m)
354
361
deriving instance PerformEvent t m => PerformEvent t (DisplayRegion t m )
355
362
deriving instance PostBuild t m => PostBuild t (DisplayRegion t m )
356
363
deriving instance TriggerEvent t m => TriggerEvent t (DisplayRegion t m )
357
- instance HasImageWriter t m => HasImageWriter t (DisplayRegion t m )
364
+ instance HasImageWriter t m => HasImageWriter t (DisplayRegion t m ) where
365
+ captureImages x = do
366
+ reg <- askRegion
367
+ lift $ captureImages $ runDisplayRegion reg x
358
368
instance HasFocusReader t m => HasFocusReader t (DisplayRegion t m )
359
369
360
370
instance (Adjustable t m , MonadFix m , MonadHold t m ) => Adjustable t (DisplayRegion t m ) where
@@ -422,7 +432,10 @@ deriving instance NotReady t m => NotReady t (FocusReader t m)
422
432
deriving instance PerformEvent t m => PerformEvent t (FocusReader t m )
423
433
deriving instance PostBuild t m => PostBuild t (FocusReader t m )
424
434
deriving instance TriggerEvent t m => TriggerEvent t (FocusReader t m )
425
- instance HasImageWriter t m => HasImageWriter t (FocusReader t m )
435
+ instance HasImageWriter t m => HasImageWriter t (FocusReader t m ) where
436
+ captureImages x = do
437
+ a <- focus
438
+ lift $ captureImages $ runFocusReader a x
426
439
427
440
instance (Adjustable t m , MonadFix m , MonadHold t m ) => Adjustable t (FocusReader t m ) where
428
441
runWithReplace (FocusReader a) e = FocusReader $ runWithReplace a $ fmap unFocusReader e
@@ -449,7 +462,7 @@ runFocusReader b = flip runReaderT b . unFocusReader
449
462
-- * "Image" output
450
463
451
464
-- | A class for widgets that can produce images to draw to the display
452
- class (Reflex t , Monad m ) => HasImageWriter t m | m -> t where
465
+ class (Reflex t , Monad m ) => HasImageWriter ( t :: * ) m | m -> t where
453
466
-- | Send images upstream for rendering
454
467
tellImages :: Behavior t [Image ] -> m ()
455
468
default tellImages :: (f m' ~ m , Monad m' , MonadTrans f , HasImageWriter t m' ) => Behavior t [Image ] -> m ()
@@ -458,6 +471,8 @@ class (Reflex t, Monad m) => HasImageWriter t m | m -> t where
458
471
mapImages :: (Behavior t [Image ] -> Behavior t [Image ]) -> m a -> m a
459
472
default mapImages :: (f m' ~ m , Monad m' , MFunctor f , HasImageWriter t m' ) => (Behavior t [Image ] -> Behavior t [Image ]) -> m a -> m a
460
473
mapImages f = hoist (mapImages f)
474
+ -- | Capture images, preventing them from being drawn
475
+ captureImages :: m a -> m (a , Behavior t [Image ])
461
476
462
477
-- | A widget that can produce images to draw onto the display
463
478
newtype ImageWriter t m a = ImageWriter
@@ -493,18 +508,44 @@ instance (Adjustable t m, MonadFix m, MonadHold t m) => Adjustable t (ImageWrite
493
508
traverseDMapWithKeyWithAdjust f m e = ImageWriter $ traverseDMapWithKeyWithAdjust (\ k v -> unImageWriter $ f k v) m e
494
509
traverseDMapWithKeyWithAdjustWithMove f m e = ImageWriter $ traverseDMapWithKeyWithAdjustWithMove (\ k v -> unImageWriter $ f k v) m e
495
510
496
- instance HasImageWriter t m => HasImageWriter t (ReaderT x m )
497
- instance HasImageWriter t m => HasImageWriter t (BehaviorWriterT t x m )
498
- instance HasImageWriter t m => HasImageWriter t (DynamicWriterT t x m )
499
- instance HasImageWriter t m => HasImageWriter t (EventWriterT t x m )
500
- instance HasImageWriter t m => HasImageWriter t (NodeIdT m )
511
+ instance HasImageWriter t m => HasImageWriter t (ReaderT x m ) where
512
+ captureImages x = do
513
+ a <- ask
514
+ lift $ captureImages $ runReaderT x a
515
+ instance HasImageWriter t m => HasImageWriter t (BehaviorWriterT t x m ) where
516
+ captureImages (BehaviorWriterT x) = BehaviorWriterT $ do
517
+ s <- get
518
+ ((result, s'), images) <- lift $ captureImages $ runStateT x s
519
+ put s'
520
+ return (result, images)
521
+ instance HasImageWriter t m => HasImageWriter t (DynamicWriterT t x m ) where
522
+ captureImages (DynamicWriterT x) = DynamicWriterT $ do
523
+ s <- get
524
+ ((result, s'), images) <- lift $ captureImages $ runStateT x s
525
+ put s'
526
+ return (result, images)
527
+
528
+ instance HasImageWriter t m => HasImageWriter t (EventWriterT t x m ) where
529
+ captureImages (EventWriterT x) = EventWriterT $ do
530
+ s <- get
531
+ ((result, s'), images) <- lift $ captureImages $ runStateT x s
532
+ put s'
533
+ return (result, images)
534
+
535
+ instance HasImageWriter t m => HasImageWriter t (NodeIdT m ) where
536
+ captureImages x = NodeIdT $ do
537
+ ref <- ask
538
+ lift $ captureImages $ flip runReaderT ref . unNodeIdT $ x
501
539
502
540
instance (Monad m , Reflex t ) => HasImageWriter t (ImageWriter t m ) where
503
541
tellImages = ImageWriter . tellBehavior
504
542
mapImages f (ImageWriter x) = ImageWriter $ do
505
543
(a, images) <- lift $ runBehaviorWriterT x
506
544
tellBehavior $ f images
507
545
pure a
546
+ captureImages (ImageWriter x) = ImageWriter $ do
547
+ lift $ runBehaviorWriterT x
548
+
508
549
509
550
instance HasDisplayRegion t m => HasDisplayRegion t (ImageWriter t m )
510
551
instance HasFocusReader t m => HasFocusReader t (ImageWriter t m )
@@ -563,7 +604,10 @@ deriving instance NotReady t m => NotReady t (ThemeReader t m)
563
604
deriving instance PerformEvent t m => PerformEvent t (ThemeReader t m )
564
605
deriving instance PostBuild t m => PostBuild t (ThemeReader t m )
565
606
deriving instance TriggerEvent t m => TriggerEvent t (ThemeReader t m )
566
- instance HasImageWriter t m => HasImageWriter t (ThemeReader t m )
607
+ instance HasImageWriter t m => HasImageWriter t (ThemeReader t m ) where
608
+ captureImages x = ThemeReader $ do
609
+ a <- ask
610
+ lift $ captureImages $ flip runReaderT a $ unThemeReader x
567
611
568
612
instance (Adjustable t m , MonadFix m , MonadHold t m ) => Adjustable t (ThemeReader t m ) where
569
613
runWithReplace (ThemeReader a) e = ThemeReader $ runWithReplace a $ fmap unThemeReader e
0 commit comments