Skip to content

Commit

Permalink
Scrolling - Store actual buffer lines displayed in a window.
Browse files Browse the repository at this point in the history
In order for scrolling to work we have to differentiate between the height
of the window in display lines and the number of actual buffer lines
displayed in a window. This patch stores that information in a window.
  • Loading branch information
jwall@google.com committed Sep 18, 2010
1 parent fc8c75f commit 2a1ed20
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 21 deletions.
9 changes: 5 additions & 4 deletions src/Yi/Buffer/HighLevel.hs
Expand Up @@ -388,7 +388,7 @@ pointScreenRelPosition p rs re
| p < rs = Above
| p > re = Below
pointScreenRelPosition _ _ _ = Within -- just to disable the non-exhaustive pattern match warning

-- | Move the visible region to include the point
snapScreenB :: BufferM Bool
snapScreenB = do
Expand All @@ -397,12 +397,13 @@ snapScreenB = do
if movePoint w then return False else do
inWin <- pointInWindowB =<< pointB
if inWin then return False else do
h <- askWindow height
h <- askWindow actualLines
--h <- askWindow height
r <- winRegionB
p <- pointB
let gap = case pointScreenRelPosition p (regionStart r) (regionEnd r) of
Above -> 0
Below -> h - 2
Below -> h - 1
Within -> 0 -- Impossible but handle it anyway
i <- indexOfSolAbove gap
f <- fromMark <$> askMarks
Expand Down Expand Up @@ -435,7 +436,7 @@ middleB = do
pointInWindowB :: Point -> BufferM Bool
pointInWindowB p = nearRegion p <$> winRegionB
-- do w <- winRegionB; trace ("pointInWindowB " ++ show w ++ " p = " ++ show p)

-----------------------------
-- Region-related operations

Expand Down
6 changes: 5 additions & 1 deletion src/Yi/Editor.hs
Expand Up @@ -444,9 +444,13 @@ alternateBufferE n = do
then fail "no alternate buffer"
else switchToBufferE $ lst!!n

-- | Create a new zero size window on a given buffer
newZeroSizeWindow ::Bool -> BufferRef -> WindowRef -> Window
newZeroSizeWindow mini bk ref = Window mini bk [] 0 emptyRegion ref 0

-- | Create a new window onto the given buffer.
newWindowE :: Bool -> BufferRef -> EditorM Window
newWindowE mini bk = Window mini bk [] 0 emptyRegion <$> newRef
newWindowE mini bk = newZeroSizeWindow mini bk <$> newRef

-- | Attach the specified buffer to the current window
switchToBufferE :: BufferRef -> EditorM ()
Expand Down
33 changes: 21 additions & 12 deletions src/Yi/UI/Vty.hs
Expand Up @@ -178,7 +178,8 @@ layout ui e = do
-- Discard this field, otherwise we keep retaining reference to
-- old Window objects (leak)
apply win = win {
winRegion = getRegionImpl win (configUI $ config ui) e cols (height win)
winRegion = getRegionImpl win (configUI $ config ui) e cols (height win)
,actualLines = windowLinesDisp win (configUI $ config ui) e cols (height win)
}

return $ windowsA ^= ws'' $ e
Expand Down Expand Up @@ -252,20 +253,25 @@ scanrT (+*+) k t = fst $ runState (mapM f t) k
put s'
return s

windowLinesDisp :: Window -> UIConfig -> Editor -> Int -> Int -> Int
windowLinesDisp win cfg e w h = dispCount
where (_,_,dispCount) = drawWindow cfg e (error "focus must not be used") win w h

getRegionImpl :: Window -> UIConfig -> Editor -> Int -> Int -> Region
getRegionImpl win cfg e w h = snd $
drawWindow cfg e (error "focus must not be used") win w h
getRegionImpl win cfg e w h = region
where (_,region,_) = drawWindow cfg e (error "focus must not be used") win w h

-- | Return a rendered wiew of the window.
renderWindow :: UIConfig -> Editor -> Int -> (Window, Bool) -> Rendered
renderWindow cfg e width (win,hasFocus) =
let (rendered,_) = drawWindow cfg e hasFocus win width (height win)
let (rendered,_,_) = drawWindow cfg e hasFocus win width (height win)
in rendered

-- | Draw a window
-- TODO: horizontal scrolling.
drawWindow :: UIConfig -> Editor -> Bool -> Window -> Int -> Int -> (Rendered, Region)
drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkRegion fromMarkPoint toMarkPoint')
-- TODO(jwall): Store display line counts so scrolling has all the necesary info
drawWindow :: UIConfig -> Editor -> Bool -> Window -> Int -> Int -> (Rendered, Region, Int)
drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkRegion fromMarkPoint toMarkPoint', dispLnCount)
where
b = findBufferWith (bufkey win) e
sty = configStyle cfg
Expand Down Expand Up @@ -298,7 +304,7 @@ drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkR
tabWidth = tabSize . fst $ runBuffer win b indentSettingsB
prompt = if isMini win then miniIdentString b else ""

(rendered,toMarkPoint',cur) = drawText h' w
(rendered,toMarkPoint',cur,dispLnCount) = drawText h' w
fromMarkPoint
point
tabWidth
Expand All @@ -315,20 +321,23 @@ drawWindow cfg e focused win w h = (Rendered { picture = pict,cursor = cur}, mkR
-- | Renders text in a rectangle.
-- This also returns
-- * the index of the last character fitting in the rectangle
-- * the position of the Point in (x,y) coordinates, if in the window.
-- * the position of the Point in (x,y) coordinates, if in the window,
-- * the number of display lines for this drawing.
drawText :: Int -- ^ The height of the part of the window we are in
-> Int -- ^ The width of the part of the window we are in
-> Point -- ^ The position of the first character to draw
-> Point -- ^ The position of the cursor
-> Int -- ^ The number of spaces to represent a tab character with.
-> [(Char,(Vty.Attr,Point))] -- ^ The data to draw.
-> ([Image], Point, Maybe (Int,Int))
-> ([Image], Point, Maybe (Int,Int), Int)
drawText h w topPoint point tabWidth bufData
| h == 0 || w == 0 = ([], topPoint, Nothing)
| otherwise = (rendered_lines, bottomPoint, pntpos)
| h == 0 || w == 0 = ([], topPoint, Nothing, 0)
| otherwise = (rendered_lines, bottomPoint, pntpos, h - (length wrapped - h))
where

lns0 = take h $ concatMap (wrapLine w) $ map (concatMap expandGraphic) $ take h $ lines' $ bufData
-- the actual lines to display, can get line count from here.
wrapped = concatMap (wrapLine w) $ map (concatMap expandGraphic) $ take h $ lines' $ bufData
lns0 = take h wrapped

bottomPoint = case lns0 of
[] -> topPoint
Expand Down
9 changes: 5 additions & 4 deletions src/Yi/Window.hs
Expand Up @@ -21,18 +21,19 @@ data Window = Window {
isMini :: !Bool -- ^ regular or mini window?
,bufkey :: !BufferRef -- ^ the buffer this window opens to
,bufAccessList :: ![BufferRef] -- ^ list of last accessed buffers (former bufKeys). Last accessed one is first element
,height :: Int -- ^ height of the window (in number of lines displayed)
,height :: Int -- ^ height of the window (in number of screen lines displayed)
,winRegion :: Region -- ^ view area.
-- note that the top point is also available as a buffer mark.
,wkey :: !WindowRef -- ^ identifier for the window (for UI sync)
,actualLines :: Int-- ^ The actual number of lines displayed. Taking into account line wrapping
}
deriving (Typeable)

instance Binary Window where
put (Window mini bk bl _h _rgn key) = put mini >> put bk >> put bl >> put key
put (Window mini bk bl _h _rgn key lns) = put mini >> put bk >> put bl >> put key >> put lns
get = Window <$> get <*> get <*> get
<*> return 0 <*> return emptyRegion
<*> get
<*> get <*> get


-- | Get the identification of a window.
Expand All @@ -58,5 +59,5 @@ dummyWindowKey = (-1)

-- | Return a "fake" window onto a buffer.
dummyWindow :: BufferRef -> Window
dummyWindow b = Window False b [] 0 emptyRegion dummyWindowKey
dummyWindow b = Window False b [] 0 emptyRegion dummyWindowKey 0

0 comments on commit 2a1ed20

Please sign in to comment.