ui: refactor, generalise listScrollPushingSelection
This commit is contained in:
		
							parent
							
								
									731a416b8c
								
							
						
					
					
						commit
						9f6595f122
					
				| @ -13,11 +13,10 @@ where | |||||||
| 
 | 
 | ||||||
| import Brick | import Brick | ||||||
| import Brick.Widgets.List | import Brick.Widgets.List | ||||||
|   (handleListEvent, list, listElementsL, listMoveDown, listMoveTo, listNameL, listSelectedElement, listSelectedL, renderList, listElements, listSelected, listMoveUp) |  | ||||||
| import Brick.Widgets.Edit | import Brick.Widgets.Edit | ||||||
| import Control.Monad | import Control.Monad | ||||||
| import Control.Monad.IO.Class (liftIO) | import Control.Monad.IO.Class (liftIO) | ||||||
| import Data.List | import Data.List hiding (reverse) | ||||||
| import Data.Maybe | import Data.Maybe | ||||||
| import qualified Data.Text as T | import qualified Data.Text as T | ||||||
| import Data.Time.Calendar (Day) | import Data.Time.Calendar (Day) | ||||||
| @ -339,36 +338,12 @@ asHandle ui0@UIState{ | |||||||
|           vScrollBy (viewportScroll $ _asList^.listNameL) 1 >> continue ui |           vScrollBy (viewportScroll $ _asList^.listNameL) 1 >> continue ui | ||||||
|           where mnextelement = listSelectedElement $ listMoveDown _asList |           where mnextelement = listSelectedElement $ listMoveDown _asList | ||||||
| 
 | 
 | ||||||
|         -- mouse scroll wheel scrolls the viewport up or down to its maximum extent. |         -- mouse scroll wheel scrolls the viewport up or down to its maximum extent, | ||||||
|         -- The selection will be moved when necessary to keep it visible and allow the scroll. |         -- pushing the selection when necessary. | ||||||
|         MouseDown name BScrollDown _mods _loc -> do |         MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do | ||||||
|           mvp <- lookupViewport name |           let scrollamt = if btn==BScrollUp then -1 else 1 | ||||||
|           let mselidx = listSelected _asList |           list' <- listScrollPushingSelection name _asList (asListSize _asList) scrollamt | ||||||
|           case (mvp, mselidx) of |           continue ui{aScreen=scr{_asList=list'}} | ||||||
|             (Just VP{_vpTop}, Just selidx) -> do |  | ||||||
|               let |  | ||||||
|                 listheight = asListSize _asList |  | ||||||
|                 pushsel | selidx <= _vpTop && selidx < (listheight-1) = listMoveDown |  | ||||||
|                         | otherwise = id |  | ||||||
|                 ui' = ui{aScreen=scr{_asList=pushsel _asList}} |  | ||||||
|               viewportScroll name `vScrollBy` 1 |  | ||||||
|               continue ui' |  | ||||||
| 
 |  | ||||||
|             _ -> continue ui |  | ||||||
| 
 |  | ||||||
|         MouseDown name BScrollUp _mods _loc -> do |  | ||||||
|           mvp <- lookupViewport name |  | ||||||
|           let mselidx = listSelected _asList |  | ||||||
|           case (mvp, mselidx) of |  | ||||||
|             (Just VP{_vpTop, _vpSize=(_,vpheight)}, Just selidx) -> do |  | ||||||
|               let |  | ||||||
|                 pushsel | selidx >= _vpTop + vpheight - 1 && selidx > 0 = listMoveUp |  | ||||||
|                         | otherwise = id |  | ||||||
|                 ui'   = ui{aScreen=scr{_asList=pushsel _asList}} |  | ||||||
|               viewportScroll name `vScrollBy` (-1) |  | ||||||
|               continue ui' |  | ||||||
| 
 |  | ||||||
|             _ -> continue ui |  | ||||||
| 
 | 
 | ||||||
|         -- if page down or end leads to a blank padding item, stop at last non-blank |         -- if page down or end leads to a blank padding item, stop at last non-blank | ||||||
|         VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do |         VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do | ||||||
|  | |||||||
| @ -22,8 +22,7 @@ import Data.Time.Calendar | |||||||
| import qualified Data.Vector as V | import qualified Data.Vector as V | ||||||
| import Graphics.Vty (Event(..),Key(..),Modifier(..), Button (BLeft, BScrollDown, BScrollUp)) | import Graphics.Vty (Event(..),Key(..),Modifier(..), Button (BLeft, BScrollDown, BScrollUp)) | ||||||
| import Brick | import Brick | ||||||
| import Brick.Widgets.List | import Brick.Widgets.List hiding (reverse) | ||||||
|   (handleListEvent, list, listElementsL, listMoveDown, listMoveTo, listNameL, listSelectedElement, listSelectedL, renderList, listElements, listSelected, listMoveUp) |  | ||||||
| import Brick.Widgets.Edit | import Brick.Widgets.Edit | ||||||
| import Lens.Micro.Platform | import Lens.Micro.Platform | ||||||
| import Safe | import Safe | ||||||
| @ -379,31 +378,11 @@ rsHandle ui@UIState{ | |||||||
|           where mnextelement = listSelectedElement $ listMoveDown rsList |           where mnextelement = listSelectedElement $ listMoveDown rsList | ||||||
| 
 | 
 | ||||||
|         -- mouse scroll wheel scrolls the viewport up or down to its maximum extent, |         -- mouse scroll wheel scrolls the viewport up or down to its maximum extent, | ||||||
|         -- The selection will be moved when necessary to keep it visible and allow the scroll. |         -- pushing the selection when necessary. | ||||||
|         MouseDown name BScrollDown _mods _loc -> do |         MouseDown name btn _mods _loc | btn `elem` [BScrollUp, BScrollDown] -> do | ||||||
|           mvp <- lookupViewport name |           let scrollamt = if btn==BScrollUp then -1 else 1 | ||||||
|           let mselidx = listSelected rsList |           list' <- listScrollPushingSelection name rsList (rsListSize rsList) scrollamt | ||||||
|           case (mvp, mselidx) of |           continue ui{aScreen=s{rsList=list'}} | ||||||
|             (Just VP{_vpTop}, Just selidx) -> do |  | ||||||
|               let |  | ||||||
|                 pushsel | selidx <= _vpTop && selidx < (listheight-1) = listMoveDown |  | ||||||
|                         | otherwise = id |  | ||||||
|                   where listheight = rsListSize rsList |  | ||||||
|               viewportScroll name `vScrollBy` 1 |  | ||||||
|               continue ui{aScreen=s{rsList=pushsel rsList}} |  | ||||||
|             _ -> continue ui |  | ||||||
| 
 |  | ||||||
|         MouseDown name BScrollUp _mods _loc -> do |  | ||||||
|           mvp <- lookupViewport name |  | ||||||
|           let mselidx = listSelected rsList |  | ||||||
|           case (mvp, mselidx) of |  | ||||||
|             (Just VP{_vpTop, _vpSize=(_,vpheight)}, Just selidx) -> do |  | ||||||
|               let |  | ||||||
|                 pushsel | selidx >= _vpTop + vpheight - 1 && selidx > 0 = listMoveUp |  | ||||||
|                         | otherwise = id |  | ||||||
|               viewportScroll name `vScrollBy` (-1) |  | ||||||
|               continue ui{aScreen=s{rsList=pushsel rsList}} |  | ||||||
|             _ -> continue ui |  | ||||||
| 
 | 
 | ||||||
|         -- if page down or end leads to a blank padding item, stop at last non-blank |         -- if page down or end leads to a blank padding item, stop at last non-blank | ||||||
|         VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do |         VtyEvent e@(EvKey k           []) | k `elem` [KPageDown, KEnd] -> do | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ | |||||||
| 
 | 
 | ||||||
| {-# LANGUAGE CPP               #-} | {-# LANGUAGE CPP               #-} | ||||||
| {-# LANGUAGE OverloadedStrings #-} | {-# LANGUAGE OverloadedStrings #-} | ||||||
|  | {-# LANGUAGE NamedFieldPuns #-} | ||||||
| 
 | 
 | ||||||
| module Hledger.UI.UIUtils ( | module Hledger.UI.UIUtils ( | ||||||
|    borderDepthStr |    borderDepthStr | ||||||
| @ -25,7 +26,8 @@ module Hledger.UI.UIUtils ( | |||||||
|   ,suspend |   ,suspend | ||||||
|   ,redraw |   ,redraw | ||||||
|   ,reportSpecSetFutureAndForecast |   ,reportSpecSetFutureAndForecast | ||||||
| ) |   ,listScrollPushingSelection | ||||||
|  |   ) | ||||||
| where | where | ||||||
| 
 | 
 | ||||||
| import Brick | import Brick | ||||||
| @ -33,7 +35,7 @@ import Brick.Widgets.Border | |||||||
| import Brick.Widgets.Border.Style | import Brick.Widgets.Border.Style | ||||||
| import Brick.Widgets.Dialog | import Brick.Widgets.Dialog | ||||||
| import Brick.Widgets.Edit | import Brick.Widgets.Edit | ||||||
| import Brick.Widgets.List (List, listSelectedL, listNameL, listItemHeightL) | import Brick.Widgets.List (List, listSelectedL, listNameL, listItemHeightL, listSelected, listMoveDown, listMoveUp, GenericList, Splittable) | ||||||
| import Control.Monad.IO.Class | import Control.Monad.IO.Class | ||||||
| import Data.Bifunctor (second) | import Data.Bifunctor (second) | ||||||
| import Data.List | import Data.List | ||||||
| @ -360,3 +362,22 @@ reportSpecSetFutureAndForecast d forecast rspec = | |||||||
|          Not (Date $ DateSpan (Just $ addDays 1 d) Nothing) |          Not (Date $ DateSpan (Just $ addDays 1 d) Nothing) | ||||||
|         ,Not generatedTransactionTag |         ,Not generatedTransactionTag | ||||||
|       ] |       ] | ||||||
|  | 
 | ||||||
|  | -- Vertically scroll the named list with the given number of non-empty items | ||||||
|  | -- by the given positive or negative number of items (usually 1 or -1). | ||||||
|  | -- The selection will be moved when necessary to keep it visible and allow the scroll. | ||||||
|  | listScrollPushingSelection :: (Ord n, Foldable t, Splittable t) =>  | ||||||
|  |   n -> GenericList n t e -> Int -> Int -> EventM n (GenericList n t e) | ||||||
|  | listScrollPushingSelection name list listheight scrollamt = do | ||||||
|  |   mvp <- lookupViewport name | ||||||
|  |   let mselidx = listSelected list | ||||||
|  |   case (mvp, mselidx) of | ||||||
|  |     (Just VP{_vpTop, _vpSize=(_,vpheight)}, Just selidx) -> do | ||||||
|  |       viewportScroll name `vScrollBy` scrollamt | ||||||
|  |       return $ pushsel list | ||||||
|  |       where | ||||||
|  |         pushsel  | ||||||
|  |           | scrollamt > 0, selidx <= _vpTop                && selidx < (listheight-1) = listMoveDown | ||||||
|  |           | scrollamt < 0, selidx >= _vpTop + vpheight - 1 && selidx > 0              = listMoveUp | ||||||
|  |           | otherwise = id | ||||||
|  |     _ -> return list | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user