[client] Improve cursor behaviour when elements are deleted
This commit is contained in:
parent
9fa804f87f
commit
a2c2c4487b
1 changed files with 24 additions and 1 deletions
|
|
@ -33,6 +33,7 @@ module Forest.Client.UiState
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Brick
|
import Brick
|
||||||
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
@ -113,7 +114,29 @@ validate :: UiState n -> UiState n
|
||||||
validate = validateEditor . validateFocused . validateUnfolded
|
validate = validateEditor . validateFocused . validateUnfolded
|
||||||
|
|
||||||
replaceRootNode :: Node -> UiState n -> UiState n
|
replaceRootNode :: Node -> UiState n -> UiState n
|
||||||
replaceRootNode node s = validate s {uiRootNode = node}
|
replaceRootNode node s = validate s { uiRootNode = node
|
||||||
|
, uiFocused = findNextValidNode (uiRootNode s) node (uiFocused s)
|
||||||
|
}
|
||||||
|
|
||||||
|
-- | Find a node that is close to the previously focused node, taking into
|
||||||
|
-- account its previous position in the tree.
|
||||||
|
findNextValidNode :: Node -> Node -> Path -> Path
|
||||||
|
findNextValidNode _ _ (Path []) = Path []
|
||||||
|
findNextValidNode from to (Path (x:xs)) = fromMaybe (Path []) $ do
|
||||||
|
fromNode <- applyId x from
|
||||||
|
case applyId x to of
|
||||||
|
Just toNode -> pure $ Path [x] <> findNextValidNode fromNode toNode (Path xs)
|
||||||
|
Nothing -> do
|
||||||
|
fromIdx <- elemIndex x $ OMap.keys $ nodeChildren from
|
||||||
|
let toKeys = OMap.keys $ nodeChildren to
|
||||||
|
x' <- getValueClosestToIndex fromIdx toKeys
|
||||||
|
pure $ Path [x']
|
||||||
|
where
|
||||||
|
-- Slightly unsafe code, but it should be fine
|
||||||
|
getValueClosestToIndex idx list
|
||||||
|
| length list > idx = Just $ list !! idx
|
||||||
|
| null list = Nothing
|
||||||
|
| otherwise = Just $ last list
|
||||||
|
|
||||||
moveFocus :: (Node -> Path -> Path) -> UiState n -> UiState n
|
moveFocus :: (Node -> Path -> Path) -> UiState n -> UiState n
|
||||||
moveFocus f s =
|
moveFocus f s =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue