Allow drag selecting outside of the selection section

Does not yet work outside of any selection section.
Need to think about what widths are acceptable to allow for selection.
This commit is contained in:
2025-08-26 12:42:48 +01:00
parent 004c4d1950
commit f7fd747a7c
5 changed files with 180 additions and 174 deletions
+1 -1
View File
@@ -26,7 +26,7 @@ data CardinalCover
| NSW
| NS
data XInfinity a = NegInf | NonInf a | PosInf
data XInfinity a = NegInf | NonInf {_nonInf :: a} | PosInf
deriving (Eq, Ord, Show)
makeLenses ''XInfinity
+1 -5
View File
@@ -17,11 +17,7 @@ data MouseContext
| MouseInGame
| MouseMenuClick {_mcoMenuClick :: Int}
| MouseMenuCursor
| OverInvDrag {_mcoDragSection :: Int
, _mcoMaybeSelect :: Maybe (Int,Int)
-- , _mcoAboveSelect :: Maybe (Int,Int)
-- , _mcoBelowSelect :: Maybe (Int,Int)
}
| OverInvDrag {_mcoDragSection :: Int , _mcoMaybeSelect :: Maybe (Int,Int) }
| OverInvDragSelect { _mcoSecSelStart :: Maybe (Int,Int), _mcoSelEnd :: Maybe Int }
| OverInvSelect { _mcoInvSelect :: (Int,Int)}
| OverCombFiltInv { _mcoInvFilt :: (Int,Int)}
+15 -12
View File
@@ -10,6 +10,7 @@ module Dodge.SelectionSections (
inverseSelNumPos,
) where
import Dodge.Data.CardinalPoint
import qualified Data.IntSet as IS
import Control.Applicative
import qualified Control.Foldl as L
@@ -198,16 +199,18 @@ selSecYint i j sss = do
where
secpos = sum . fmap _ssShownLength . fst $ IM.split i sss
inverseSelSecYint :: Int -> IM.IntMap (SelectionSection a) -> Maybe (Int, Int)
inverseSelSecYint yint sss = do
((i, ss), othersss) <- IM.minViewWithKey sss
let l = _ssShownLength ss
if l <= yint
then inverseSelSecYint (yint - l) othersss
else do
let ls = L.postscan (L.premap _siHeight L.sum) (_ssItems ss)
(j,_) <- L.fold (L.find (\(_,x) -> x - _ssOffset ss > yint)) $ IM.toList ls
return (i, j)
inverseSelSecYint :: Int -> IM.IntMap (SelectionSection a) -> XInfinity (Int, Int)
inverseSelSecYint yint sss
| yint < 0 = NegInf
| otherwise = fromMaybe PosInf $ do
((i, ss), othersss) <- IM.minViewWithKey sss
let l = _ssShownLength ss
if l <= yint
then return $ inverseSelSecYint (yint - l) othersss
else do
let ls = L.postscan (L.premap _siHeight L.sum) (_ssItems ss)
(j,_) <- L.fold (L.find (\(_,x) -> x - _ssOffset ss > yint)) $ IM.toList ls
return $ NonInf (i, j)
inverseSelSecYintXPosCheck ::
Configuration ->
@@ -216,8 +219,8 @@ inverseSelSecYintXPosCheck ::
Int ->
IM.IntMap (SelectionSection a) ->
Maybe (Int,Int)
inverseSelSecYintXPosCheck cfig ldp x yint sss = do
(i,j) <- inverseSelSecYint yint sss
inverseSelSecYintXPosCheck cfig ldp x yint sss = do
(i,j) <- inverseSelSecYint yint sss ^? nonInf
let V2 x0 _ = screenPosAbs cfig (ldp ^. ldpPos)
sindent <- sss ^? ix i . ssIndent
itindent <- sss ^? ix i . ssItems . ix j . siOffX
+13 -5
View File
@@ -5,6 +5,7 @@ module Dodge.Update.Input.InGame (
updateMouseInGame,
) where
import Dodge.Data.CardinalPoint
import Dodge.Inventory.CheckSlots
import Dodge.Base.Collide
import Geometry.Vector
@@ -103,12 +104,17 @@ updateMouseHeldInGame cfig w = case w ^. input . mouseContext of
OverInvDragSelect (Just sstart) _ -> fromMaybe w $ do
sss <- w ^? hud . hudElement . diSections
let msel = inverseSelNumPos cfig invDP sss (w ^. input . mousePos)
guard $ Just (fst sstart) == fmap fst msel
return $ w & input . mouseContext . mcoSelEnd .~ fmap snd msel
return $ case msel of
Nothing -> w & input . mouseContext . mcoSelEnd .~ Nothing
Just (i,j) | i == fst sstart -> w & input . mouseContext . mcoSelEnd ?~ j
| i < fst sstart -> w & input . mouseContext . mcoSelEnd ?~ 0
| otherwise -> w & input . mouseContext . mcoSelEnd .~ fmap fst
(IM.lookupMax =<< sss ^? ix (fst sstart) . ssItems)
OverInvDragSelect Nothing _ -> fromMaybe w $ do
sss <- w ^? hud . hudElement . diSections
ysel <- inverseSelSecYint
(posSelSecYint cfig invDP (w ^. input . mousePos . _y)) sss
^? nonInf
guard (isGroupSelectableSection $ fst ysel)
return $ w & input . mouseContext .~ OverInvDragSelect (Just ysel) Nothing
OverInvDrag k mmouseover -> doDrag cfig 30 k mmouseover w
@@ -204,7 +210,7 @@ updateMouseClickInGame cfig w = case w ^. input . mouseContext of
MouseInGame -> fromMaybe (w & input . mouseContext .~ OverInvDragSelect Nothing Nothing) $ do
sss <- w ^? hud . hudElement . diSections
ysel <- inverseSelSecYint
(posSelSecYint cfig invDP (w ^. input . mousePos . _y)) sss
(posSelSecYint cfig invDP (w ^. input . mousePos . _y)) sss ^? nonInf
guard (isGroupSelectableSection $ fst ysel)
return $ w & input . mouseContext .~ OverInvDragSelect (Just ysel) Nothing
OverInvSelect (-1, _)
@@ -314,8 +320,10 @@ shiftInvItems ::
shiftInvItems cfig n k x xs ss w = setSelWhileDragging . fromMaybe w $ do
let xk = fst x
let yint = posSelSecYint cfig invDP (w ^. input . mousePos . _y)
bn = inverseSelSecYint (yint + 1) =<< w ^? hud . hudElement . diSections
ab = inverseSelSecYint (yint - 1) =<< w ^? hud . hudElement . diSections
bn = (\v -> inverseSelSecYint (yint + 1) v ^? nonInf)
=<< w ^? hud . hudElement . diSections
ab = (\v -> inverseSelSecYint (yint - 1) v ^? nonInf)
=<< w ^? hud . hudElement . diSections
guard $ xk == k || xk + 1 == k || xk -1 == k
(maxi, _) <- IS.maxView xs
(mini, _) <- IS.minView xs