mouse events use local widget coordinates
This commit is contained in:
parent
75edc11a1e
commit
5f29ce7610
@ -145,7 +145,7 @@ clickHandler btn pos@(x,y) = do
|
||||
case hits of
|
||||
[] -> liftIO $ putStrLn $ unwords [show btn ++ ":press on (",show x,",",show y,")"]
|
||||
_ -> do
|
||||
changes <- mapM (\uid -> do
|
||||
changes <- mapM (\(uid, pos') -> do
|
||||
let w = toGUIAny hMap uid
|
||||
short = w ^. baseProperties.shorthand
|
||||
bound <- w ^. baseProperties.boundary
|
||||
@ -153,8 +153,8 @@ clickHandler btn pos@(x,y) = do
|
||||
liftIO $ putStrLn $ "hitting(" ++ show btn ++ ") " ++ short ++ ": " ++ show bound ++ " "
|
||||
++ show prio ++ " at [" ++ show x ++ "," ++ show y ++ "]"
|
||||
case w ^. eventHandlers.(at MouseEvent) of
|
||||
Just ma -> do w' <- fromJust (ma ^? onMousePress) btn pos w -- TODO unsafe fromJust
|
||||
w'' <- fromJust (ma ^? onMouseRelease) btn pos True w' -- TODO unsafe fromJust
|
||||
Just ma -> do w' <- fromJust (ma ^? onMousePress) btn pos' w -- TODO unsafe fromJust
|
||||
w'' <- fromJust (ma ^? onMouseRelease) btn pos' True w' -- TODO unsafe fromJust
|
||||
return $ Just (uid, w'')
|
||||
Nothing -> return Nothing
|
||||
) hits
|
||||
|
@ -44,6 +44,10 @@ f >: (x, y) = (f x, f y)
|
||||
(*:) = merge (*)
|
||||
{-# INLINABLE (*:) #-}
|
||||
|
||||
infixl 7 *:
|
||||
infixl 6 +:, -:
|
||||
infixl 5 >:
|
||||
|
||||
-- |Id to reference a specific widget, must be unique.
|
||||
newtype UIId = UIId Int deriving (Eq, Ord, Bounded, Ix, Hashable, Show, Read)
|
||||
|
||||
@ -275,13 +279,25 @@ buttonMouseActions a = MouseHandler press' release'
|
||||
emptyGraphics :: (Monad m) => GUIGraphics m
|
||||
emptyGraphics = Graphics (return 3)
|
||||
|
||||
isInsideRect :: (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> Pixel -> Bool
|
||||
isInsideRect (x,y,w,h) (x',y') = (x' - x <= w) && (x' - x >= 0) && (y' - y <= h) && (y' - y >= 0)
|
||||
-- |Extracts width and height from a '_boundary' property of a 'GUIBaseProperties'.
|
||||
extractExtent :: (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> (ScreenUnit, ScreenUnit)
|
||||
extractExtent (_,_,w,h) = (w,h)
|
||||
{-# INLINABLE extractExtent #-}
|
||||
|
||||
-- |Calculates whether a point's value exceed the given width and height.
|
||||
isInsideExtent :: (ScreenUnit, ScreenUnit) -> Pixel -> Bool
|
||||
isInsideExtent (w,h) (x',y') = (x' <= w) && (x' >= 0) && (y' <= h) && (y' >= 0)
|
||||
|
||||
-- |Calculates whether a point is within a given rectangle.
|
||||
isInsideRect :: (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> Pixel -> Bool
|
||||
isInsideRect (x,y,w,h) px = isInsideExtent (w, h) $ px -: (x, y)
|
||||
|
||||
|
||||
-- |@GUIBaseProperties@ with a rectangular base that fills the bounds.
|
||||
rectangularBase :: (Monad m) => (ScreenUnit, ScreenUnit, ScreenUnit, ScreenUnit) -> [UIId] -> Int -> String -> GUIBaseProperties m
|
||||
rectangularBase bnd chld prio short =
|
||||
BaseProperties (return bnd) (return chld)
|
||||
(\w p -> liftM (`isInsideRect` p) (w ^. baseProperties.boundary)) -- isInside
|
||||
(\w p -> liftM (flip isInsideExtent p . extractExtent) (w ^. baseProperties.boundary)) -- isInside
|
||||
(return prio) short
|
||||
|
||||
debugShowWidget' :: (Monad m) => GUIWidget m -> m String
|
||||
|
@ -21,7 +21,7 @@ toGUIAnys m = mapMaybe (`Map.lookup` m)
|
||||
|
||||
|
||||
-- |The function 'getInsideId' returns child widgets that overlap with a
|
||||
-- specific screen position.
|
||||
-- specific screen position and the pixel's local coordinates.
|
||||
--
|
||||
-- A screen position may be inside the bounding box of a widget but not
|
||||
-- considered part of the component. The function returns all hit widgets that
|
||||
@ -30,17 +30,18 @@ toGUIAnys m = mapMaybe (`Map.lookup` m)
|
||||
getInsideId :: Map.HashMap UIId (GUIWidget Pioneers) -- ^map containing ui widgets
|
||||
-> Pixel -- ^screen position
|
||||
-> UIId -- ^the parent widget
|
||||
-> Pioneers [UIId]
|
||||
-> Pioneers [(UIId, Pixel)]
|
||||
getInsideId hMap px uid = do
|
||||
let wg = toGUIAny hMap uid
|
||||
bnd@(bX, bY, _, _) <- wg ^. baseProperties.boundary
|
||||
inside <- liftM (isInsideRect bnd px &&) $ (wg ^. baseProperties.isInside) wg px
|
||||
let px' = px -: (bX, bY)
|
||||
inside <- liftM (isInsideRect bnd px &&) $ (wg ^. baseProperties.isInside) wg px'
|
||||
if inside -- test inside parent's bounding box
|
||||
then do
|
||||
childrenIds <- wg ^. baseProperties.children
|
||||
hitChildren <- liftM concat $ mapM (getInsideId hMap (px -: (bX, bY))) childrenIds
|
||||
hitChildren <- liftM concat $ mapM (getInsideId hMap px') childrenIds
|
||||
case hitChildren of
|
||||
[] -> return [uid]
|
||||
[] -> return [(uid, px')]
|
||||
_ -> return hitChildren
|
||||
else return []
|
||||
--TODO: Priority queue?
|
||||
|
Loading…
Reference in New Issue
Block a user