itemfield-1.2.4.0: compat/brick_016/TextUI/ItemField/BrickHelper.hs
module TextUI.ItemField.BrickHelper
( getEventWidgetLocation
, BChan, newBChan, writeBChan, readBChan
, defaultConfig
)
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 Brick.BChan (BChan, newBChan, writeBChan, readBChan)
import Data.Default
import Graphics.Vty
-- Vty 5.15 introduces defaultConfig instead of using Data.Default.def
defaultConfig :: Graphics.Vty.Config
defaultConfig = def
-- | 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 clicked 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
-- brick now uses bounded channels (Brick.BChan.BChan for event communications instead of Control.Concurrent.Chan unbounded channels
-- Brick.List now has listModify for modifying the selected element
-- hBox and vBox use more efficient DList data struct