@@ -55,8 +55,7 @@ scrollable
55
55
-> (m (Event t () , a ))
56
56
-> m (Scrollable t , a )
57
57
scrollable (ScrollableConfig scrollBy scrollTo startingPos onAppend) mkImg = do
58
- ((update, a), imgs) <- captureImages mkImg
59
- let sz = foldl' max 0 . fmap V. imageHeight <$> imgs
58
+ dh <- displayHeight
60
59
kup <- key V. KUp
61
60
kdown <- key V. KDown
62
61
m <- mouseScroll
@@ -69,25 +68,28 @@ scrollable (ScrollableConfig scrollBy scrollTo startingPos onAppend) mkImg = do
69
68
ScrollDirection_Down -> 1
70
69
, scrollBy
71
70
]
72
- dh <- displayHeight
73
- lineIndex <- foldDynMaybe ($) startingPos $ leftmost
74
- [ (\ ((totalLines, h), d) sp -> Just $ scrollByLines sp totalLines h d) <$> attach ((,) <$> sz <*> current dh) requestedScroll
75
- , (\ ((totalLines, h), newScrollPosition) _ -> Just $ case newScrollPosition of
76
- ScrollPos_Line n -> scrollToLine totalLines h n
77
- ScrollPos_Top -> ScrollPos_Top
78
- ScrollPos_Bottom -> ScrollPos_Bottom
79
- ) <$> attach ((,) <$> sz <*> current dh) scrollTo
80
- , (\ cfg sp -> case cfg of
81
- Just ScrollToBottom_Always -> case sp of
82
- ScrollPos_Bottom -> Nothing
83
- _ -> Just ScrollPos_Bottom
84
- _ -> Nothing ) <$> tag onAppend update
85
- ]
86
- let imgsToTell height scrollPos totalLines images = case scrollPos of
87
- ScrollPos_Bottom -> cropFromTop ((1 ) * max 0 (totalLines - height)) <$> images
88
- ScrollPos_Top -> images -- take height images
89
- ScrollPos_Line n -> cropFromTop ((1 ) * max 0 n) <$> images
90
- tellImages $ imgsToTell <$> current dh <*> current lineIndex <*> sz <*> imgs
71
+ rec
72
+ ((update, a), imgs) <- captureImages $ localInput (translateMouseEvents translation) $ mkImg
73
+ let sz = foldl' max 0 . fmap V. imageHeight <$> imgs
74
+ lineIndex <- foldDynMaybe ($) startingPos $ leftmost
75
+ [ (\ ((totalLines, h), d) sp -> Just $ scrollByLines sp totalLines h d) <$> attach ((,) <$> sz <*> current dh) requestedScroll
76
+ , (\ ((totalLines, h), newScrollPosition) _ -> Just $ case newScrollPosition of
77
+ ScrollPos_Line n -> scrollToLine totalLines h n
78
+ ScrollPos_Top -> ScrollPos_Top
79
+ ScrollPos_Bottom -> ScrollPos_Bottom
80
+ ) <$> attach ((,) <$> sz <*> current dh) scrollTo
81
+ , (\ cfg sp -> case cfg of
82
+ Just ScrollToBottom_Always -> case sp of
83
+ ScrollPos_Bottom -> Nothing
84
+ _ -> Just ScrollPos_Bottom
85
+ _ -> Nothing ) <$> tag onAppend update
86
+ ]
87
+ let translation = calculateTranslation
88
+ <$> current dh
89
+ <*> current lineIndex
90
+ <*> sz
91
+ let cropImages dy images = cropFromTop dy <$> images
92
+ tellImages $ cropImages <$> translation <*> imgs
91
93
return $ (,a) $ Scrollable
92
94
{ _scrollable_scrollPosition = current lineIndex
93
95
, _scrollable_totalLines = sz
@@ -97,6 +99,16 @@ scrollable (ScrollableConfig scrollBy scrollTo startingPos onAppend) mkImg = do
97
99
cropFromTop :: Int -> V. Image -> V. Image
98
100
cropFromTop rows i =
99
101
V. cropTop (max 0 $ V. imageHeight i - rows) i
102
+ calculateTranslation height scrollPos totalLines = case scrollPos of
103
+ ScrollPos_Bottom -> max 0 (totalLines - height)
104
+ ScrollPos_Top -> 0
105
+ ScrollPos_Line n -> max 0 n
106
+ translateMouseEvents translation vtyEvent =
107
+ let e = attach translation vtyEvent
108
+ in ffor e $ \ case
109
+ (dy, V. EvMouseDown x y btn mods) -> V. EvMouseDown x (y + dy) btn mods
110
+ (dy, V. EvMouseUp x y btn) -> V. EvMouseUp x (y + dy) btn
111
+ (_, otherEvent) -> otherEvent
100
112
101
113
-- | Modify the scroll position by the given number of lines
102
114
scrollByLines :: ScrollPos -> Int -> Int -> Int -> ScrollPos
0 commit comments