Skip to content

Commit 088b006

Browse files
authored
Merge pull request #91 from reflex-frp/aa/scrollable-mouse-input
Translate mouse inputs in scrollable elements
2 parents 217d4db + d300d49 commit 088b006

File tree

4 files changed

+39
-23
lines changed

4 files changed

+39
-23
lines changed

ChangeLog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Revision history for reflex-vty
22

3+
## 0.6.1.0
4+
5+
* Fix mouse input translation in scrollable elements
6+
37
## 0.6.0.0
48

59
* *Breaking Change*: `Reflex.Vty.Widget.Scroll.scrollable`'s type has changed. The child widget no longer has to return images (see `captureImages` below), but can return a value. Specifically, the child widget type has gone from `m (Behavior t Image, Event t ())` to `m (Event t (), a)`.

reflex-vty.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: reflex-vty
2-
version: 0.6.0.0
2+
version: 0.6.1.0
33
synopsis: Reflex FRP host and widgets for VTY applications
44
description:
55
Build terminal applications using functional reactive programming (FRP) with Reflex FRP (<https://reflex-frp.org>).

src-bin/example.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ darkTheme :: V.Attr
5656
darkTheme = V.Attr {
5757
V.attrStyle = V.SetTo V.standout
5858
, V.attrForeColor = V.SetTo V.black
59-
, V.attrBackColor = V.Default
59+
, V.attrBackColor = V.SetTo V.green
6060
, V.attrURL = V.Default
6161
}
6262

src/Reflex/Vty/Widget/Scroll.hs

+33-21
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ scrollable
5555
-> (m (Event t (), a))
5656
-> m (Scrollable t, a)
5757
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
6059
kup <- key V.KUp
6160
kdown <- key V.KDown
6261
m <- mouseScroll
@@ -69,25 +68,28 @@ scrollable (ScrollableConfig scrollBy scrollTo startingPos onAppend) mkImg = do
6968
ScrollDirection_Down -> 1
7069
, scrollBy
7170
]
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
9193
return $ (,a) $ Scrollable
9294
{ _scrollable_scrollPosition = current lineIndex
9395
, _scrollable_totalLines = sz
@@ -97,6 +99,16 @@ scrollable (ScrollableConfig scrollBy scrollTo startingPos onAppend) mkImg = do
9799
cropFromTop :: Int -> V.Image -> V.Image
98100
cropFromTop rows i =
99101
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
100112

101113
-- | Modify the scroll position by the given number of lines
102114
scrollByLines :: ScrollPos -> Int -> Int -> Int -> ScrollPos

0 commit comments

Comments
 (0)