itemfield-1.2.3.0: compat/brick_015plus/TextUI/ItemField/BrickHelper.hs
module TextUI.ItemField.BrickHelper
(getEventWidgetLocation)
where
import Brick.Main (lookupViewport, lookupExtent, clickedExtent)
import Brick.Types (EventM, Location(..), locationRowL, locationColumnL,
Extent(..), Viewport(..))
import Brick.Widgets.Core (Named(..))
import Data.Monoid ((<>))
import Lens.Micro ((^.))
import Control.Concurrent
-- Brick 0.16 introduces the BChan to abstract over the underlying
-- Chan implementation.
type BChan = Chan
newBChan :: Int -> IO BChan
newBChan = const . newChan
writeBChan = writeChan
readBChan = readChan
-- | When processing a global EvMouseDown VtyEvent, the coordinates of
-- the mouse event on the screen must be mapped to a specific location
-- in a Widget. The `lookupExtent` function will return the "extent"
-- of the Widget (i.e. where it was drawn and how big it is) but this
-- only indicates that the widget was clocked and does not identify
-- the actual location within the widget where the click occurred.
--
-- The `getEventWidgetLocation` function translates the mouse event
-- coordinates to a specific location within the widget in the
-- widget's local reference frame, taking into account any scrolling
-- that has occurred within a viewport that wraps that widget.
--
-- drawUI st = reportExtent (getName st) $
-- viewport (getName st) Vertical $
-- Widget Fixed Fixed $ ...
--
-- handleEvent event st =
-- case event of
-- EvMouseDown col row button _mods ->
-- do wcoords <- getEventWidgetLocation fieldw col row
-- case wcoords of
-- Nothing -> return fieldw
-- Just l -> ...
--
getEventWidgetLocation :: (Named a n, Ord n)
=> a -> Int -> Int -> EventM n (Maybe Location)
getEventWidgetLocation widget screenCol screenRow =
do mExtent <- Brick.Main.lookupExtent (getName widget)
case mExtent of
Nothing -> return Nothing
Just e@(Extent _ upperLeft _) ->
if Brick.Main.clickedExtent (screenCol, screenRow) e
then let widgetRow = screenRow - upperLeft^.locationRowL
widgetCol = screenCol - upperLeft^.locationColumnL
widgetLoc = Location (widgetCol, widgetRow)
in do mView <- Brick.Main.lookupViewport (getName widget)
case mView of
Nothing -> return $ Just widgetLoc
Just (VP left top _) ->
return $ Just $ widgetLoc <> Location (left, top)
else return Nothing