Remove visible/enabled fields from WidgetContext

This commit is contained in:
Francisco Vallarino 2020-07-22 01:37:36 -03:00
parent b085419954
commit f0335a464f
10 changed files with 49 additions and 56 deletions

View File

@ -137,8 +137,6 @@ mainLoop window c renderer widgetPlatform !prevTicks !tsAccum !frames widgetRoot
currentFocus <- use focused
let ctx = WidgetContext {
_wcVisible = _instanceVisible newWidgetRoot,
_wcEnabled = _instanceEnabled newWidgetRoot,
_wcFocusedPath = currentFocus,
_wcTargetPath = rootPath,
_wcCurrentPath = rootPath

View File

@ -55,8 +55,6 @@ createEventContext wenv latestPressed activeOverlay currentFocus currentTarget s
pathFromPoint point = _widgetFind (_instanceWidget widgetRoot) wenv findStartPath point widgetRoot
pointEvent point = makePathCtx <$> (pathFromPoint point <|> activeOverlay <|> latestPressed)
makePathCtx targetPath = WidgetContext {
_wcVisible = _instanceVisible widgetRoot,
_wcEnabled = _instanceEnabled widgetRoot,
_wcFocusedPath = currentFocus,
_wcTargetPath = targetPath,
_wcCurrentPath = rootPath
@ -90,8 +88,6 @@ handleWidgetInit :: (MonomerM s m) => Renderer m -> WidgetEnv s e -> WidgetInsta
handleWidgetInit renderer wenv widgetRoot = do
let widget = _instanceWidget widgetRoot
let ctx = WidgetContext {
_wcVisible = _instanceVisible widgetRoot,
_wcEnabled = _instanceEnabled widgetRoot,
_wcFocusedPath = rootPath,
_wcTargetPath = rootPath,
_wcCurrentPath = rootPath
@ -201,8 +197,6 @@ handleSendMessages renderer reqs previousStep = foldM reducer previousStep reqs
let (wenv, events, widgetRoot) = previousStep
let ctx = WidgetContext {
_wcVisible = _instanceVisible widgetRoot,
_wcEnabled = _instanceEnabled widgetRoot,
_wcFocusedPath = currentFocus,
_wcTargetPath = path,
_wcCurrentPath = rootPath

View File

@ -29,8 +29,6 @@ initMonomerContext model winSize useHiDPI devicePixelRate = MonomerContext {
findNextFocusable :: WidgetEnv s e -> Path -> WidgetInstance s e -> Path
findNextFocusable wenv currentFocus widgetRoot = fromMaybe rootFocus candidateFocus where
ctxFocus = WidgetContext {
_wcVisible = _instanceVisible widgetRoot,
_wcEnabled = _instanceEnabled widgetRoot,
_wcFocusedPath = currentFocus,
_wcTargetPath = currentFocus,
_wcCurrentPath = rootPath

View File

@ -68,8 +68,6 @@ processWidgetTaskEvent renderer wenv widgetRoot path event = do
currentFocus <- use focused
let ctx = WidgetContext {
_wcVisible = _instanceVisible widgetRoot,
_wcEnabled = _instanceEnabled widgetRoot,
_wcFocusedPath = currentFocus,
_wcTargetPath = path,
_wcCurrentPath = rootPath

View File

@ -70,7 +70,15 @@ containerInit initHandler wenv ctx widgetInstance = WidgetResult (reqs <> newReq
WidgetResult reqs events tempInstance = initHandler wenv ctx widgetInstance
children = _instanceChildren tempInstance
indexes = Seq.fromList [0..length children]
zipper idx child = _widgetInit (_instanceWidget child) wenv (updateCtx (addToCurrent ctx idx) child) child
parentVisible = _instanceVisible widgetInstance
parentEnabled = _instanceEnabled widgetInstance
zipper idx child = _widgetInit wchild wenv cctx newChild where
cctx = addToCurrent ctx idx
wchild = _instanceWidget child
newChild = child {
_instanceVisible = _instanceVisible child && parentVisible,
_instanceEnabled = _instanceEnabled child && parentEnabled
}
results = Seq.zipWith zipper indexes children
newReqs = fold $ fmap _resultRequests results
newEvents = fold $ fmap _resultEvents results
@ -93,8 +101,15 @@ containerMergeTrees mergeHandler wenv ctx oldInstance newInstance = result where
WidgetResult uReqs uEvents updatedInstance = mergeHandler wenv ctx oldState newInstance
oldChildren = _instanceChildren oldInstance
newChildren = _instanceChildren updatedInstance
parentVisible = _instanceVisible updatedInstance
parentEnabled = _instanceEnabled updatedInstance
indexes = Seq.fromList [0..length newChildren]
newPairs = Seq.zipWith (\idx child -> (updateCtx (addToCurrent ctx idx) child, child)) indexes newChildren
zipper idx child = (addToCurrent ctx idx, child) where
newChild = child {
_instanceVisible = _instanceVisible child && parentVisible,
_instanceEnabled = _instanceEnabled child && parentEnabled
}
newPairs = Seq.zipWith zipper indexes newChildren
mergedResults = mergeChildren wenv oldChildren newPairs
mergedChildren = fmap _resultWidget mergedResults
concatSeq seqs = foldl' (><) Seq.empty seqs
@ -124,7 +139,7 @@ mergeChildren wenv oldFull@(oldChild :<| oldChildren) ((ctx, newChild) :<| newCh
containerNextFocusable :: WidgetEnv s e -> WidgetContext -> WidgetInstance s e -> Maybe Path
containerNextFocusable wenv ctx widgetInstance = nextFocus where
children = _instanceChildren widgetInstance
stepper idx child = (updateCtx (addToCurrent ctx idx) child, child)
stepper idx child = (addToCurrent ctx idx, child)
filterChildren (ctx, child) = isTargetBeforeCurrent ctx && not (isTargetReached ctx)
indexes = Seq.fromList [0..length children]
pairs = Seq.zipWith stepper indexes children
@ -138,18 +153,18 @@ containerNextFocusable wenv ctx widgetInstance = nextFocus where
-- | Find instance matching point
containerFind :: WidgetEnv s e -> Path -> Point -> WidgetInstance s e -> Maybe Path
containerFind wenv path point widgetInstance = fmap (combinePath wenv newPath point children) childIdx where
containerFind wenv startPath point widgetInstance = fmap (combinePath wenv newStartPath point children) childIdx where
children = _instanceChildren widgetInstance
pointInWidget wi = pointInRect point (_instanceViewport wi)
newPath = Seq.drop 1 path
childIdx = case path of
newStartPath = Seq.drop 1 startPath
childIdx = case startPath of
Empty -> Seq.findIndexL pointInWidget children
p :<| ps -> if Seq.length children > p then Just p else Nothing
combinePath :: WidgetEnv s e -> Path -> Point -> Seq (WidgetInstance s e) -> Int -> Path
combinePath wenv path point children childIdx = childIdx <| childPath where
combinePath wenv startPath point children childIdx = childIdx <| childPath where
child = Seq.index children childIdx
childPath = fromMaybe Seq.empty $ _widgetFind (_instanceWidget child) wenv path point child
childPath = fromMaybe Seq.empty $ _widgetFind (_instanceWidget child) wenv startPath point child
-- | Event Handling
defaultHandleEvent :: ContainerEventHandler s e
@ -167,7 +182,7 @@ containerHandleEvent pHandler wenv ctx event widgetInstance
childIdx = fromJust $ nextTargetStep ctx
children = _instanceChildren widgetInstance
child = Seq.index children childIdx
nextCtx = updateCtx (fromJust $ moveToTarget ctx) child
nextCtx = fromJust $ moveToTarget ctx
pResponse = pHandler wenv ctx event widgetInstance
childrenIgnored = isJust pResponse && ignoreChildren (fromJust pResponse)
cResponse = if childrenIgnored || not (_instanceEnabled child)
@ -202,7 +217,7 @@ containerHandleMessage mHandler wenv ctx arg widgetInstance
childIdx = fromJust $ nextTargetStep ctx
children = _instanceChildren widgetInstance
child = Seq.index children childIdx
nextCtx = updateCtx (fromJust $ moveToTarget ctx) child
nextCtx = fromJust $ moveToTarget ctx
messageResult = updateChild <$> _widgetHandleMessage (_instanceWidget child) wenv nextCtx arg child
updateChild cr = cr {
_resultWidget = replaceChild widgetInstance (_resultWidget cr) childIdx
@ -254,12 +269,11 @@ containerRender rHandler renderer wenv ctx widgetInstance = do
let children = _instanceChildren widgetInstance
let indexes = Seq.fromList [0..length children]
let pairs = Seq.zip indexes children
let childCtx ctx idx child = updateCtx (addToCurrent ctx idx) child
rHandler renderer wenv ctx widgetInstance
forM_ pairs $ \(idx, child) -> when (_instanceVisible child) $
_widgetRender (_instanceWidget child) renderer wenv (childCtx ctx idx child) child
_widgetRender (_instanceWidget child) renderer wenv (addToCurrent ctx idx) child
-- | Event Handling Helpers
ignoreChildren :: WidgetResult s e -> Bool
@ -272,12 +286,6 @@ replaceChild :: WidgetInstance s e -> WidgetInstance s e -> Int -> WidgetInstanc
replaceChild parent child idx = parent { _instanceChildren = newChildren } where
newChildren = Seq.update idx child (_instanceChildren parent)
updateCtx :: WidgetContext -> WidgetInstance s e -> WidgetContext
updateCtx ctx widgetInstance = ctx {
_wcVisible = _wcVisible ctx && _instanceVisible widgetInstance,
_wcEnabled = _wcEnabled ctx && _instanceEnabled widgetInstance
}
visibleChildrenReq :: Seq (WidgetInstance s e) -> Seq (Tree SizeReq) -> (Seq (WidgetInstance s e), Seq SizeReq)
visibleChildrenReq children reqs = Seq.unzipWith extract filtered where
pairs = Seq.zip children reqs

View File

@ -100,7 +100,8 @@ compositeInit :: (Eq s, Typeable s, Typeable e) => Composite s e ep -> Composite
compositeInit comp state wenv ctx widgetComposite = result where
CompositeState{..} = state
widget = _instanceWidget _compositeRoot
(cwenv, cctx) = convertContexts comp state wenv (childContext ctx)
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = childContext ctx
WidgetResult reqs evts root = _widgetInit widget cwenv cctx _compositeRoot
newEvts = maybe evts (evts |>) _compositeInitEvent
newState = state {
@ -121,8 +122,7 @@ compositeMerge comp state wenv ctx oldComposite newComposite = result where
}
newWidget = _instanceWidget newRoot
cwenv = convertWidgetEnv wenv oldGlobalKeys oldModel
cctx = convertWidgetCtx (childContext ctx) newRoot
-- (cwenv, cctx) = convertContexts comp state wenv (childContext ctx)
cctx = childContext ctx
widgetResult = if instanceMatches newRoot oldRoot
then _widgetMerge newWidget cwenv cctx oldRoot newRoot
else _widgetInit newWidget cwenv cctx newRoot
@ -132,7 +132,8 @@ compositeNextFocusable :: Composite s e ep -> CompositeState s e -> WidgetEnv sp
compositeNextFocusable comp state wenv ctx widgetComposite = nextFocus where
CompositeState{..} = state
widget = _instanceWidget _compositeRoot
(cwenv, cctx) = convertContexts comp state wenv (childContext ctx)
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = childContext ctx
isEnabled = _instanceEnabled _compositeRoot
nextFocus
| isEnabled = _widgetNextFocusable widget cwenv cctx _compositeRoot
@ -153,7 +154,8 @@ compositeHandleEvent :: (Eq s, Typeable s, Typeable e) => Composite s e ep -> Co
compositeHandleEvent comp state wenv ctx evt widgetComposite = fmap processEvent result where
CompositeState{..} = state
widget = _instanceWidget _compositeRoot
(cwenv, cctx) = convertContexts comp state wenv (childContext ctx)
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = childContext ctx
rootEnabled = _instanceEnabled _compositeRoot
processEvent = processWidgetResult comp state wenv ctx widgetComposite
result
@ -181,7 +183,7 @@ updateComposite comp state wenv ctx newModel oldRoot widgetComposite = if modelC
modelChanged = _compositeModel /= newModel
builtRoot = _uiBuilder comp newModel
cwenv = convertWidgetEnv wenv _compositeGlobalKeys newModel
cctx = convertWidgetCtx (childContext ctx) builtRoot
cctx = childContext ctx
mergedResult = _widgetMerge (_instanceWidget builtRoot) cwenv cctx oldRoot builtRoot
mergedState = state {
_compositeModel = newModel,
@ -258,12 +260,14 @@ compositeHandleMessage comp state@CompositeState{..} wenv ctx arg widgetComposit
| otherwise = fmap processEvent result where
processEvent = processWidgetResult comp state wenv ctx widgetComposite
nextCtx = fromJust $ moveToTarget ctx
(cwenv, cctx) = convertContexts comp state wenv nextCtx
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = childContext ctx
result = _widgetHandleMessage (_instanceWidget _compositeRoot) cwenv cctx arg _compositeRoot
-- Preferred size
compositePreferredSize :: CompositeState s e -> WidgetEnv sp ep -> WidgetInstance sp ep -> Tree SizeReq
compositePreferredSize CompositeState{..} wenv _ = _widgetPreferredSize widget cwenv _compositeRoot where
compositePreferredSize state wenv _ = _widgetPreferredSize widget cwenv _compositeRoot where
CompositeState{..} = state
widget = _instanceWidget _compositeRoot
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
@ -289,11 +293,12 @@ compositeRender :: (Monad m) => Composite s e ep -> CompositeState s e -> Render
compositeRender comp state renderer wenv ctx _ = _widgetRender widget renderer cwenv cctx _compositeRoot where
CompositeState{..} = state
widget = _instanceWidget _compositeRoot
(cwenv, cctx) = convertContexts comp state wenv (childContext ctx)
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = childContext ctx
collectGlobalKeys :: Map WidgetKey (Path, WidgetInstance s e) -> WidgetContext -> WidgetInstance s e -> Map WidgetKey (Path, WidgetInstance s e)
collectGlobalKeys keys ctx widgetInstance = foldl' collectFn updatedMap pairs where
createChildCtx idx child = convertWidgetCtx (addToCurrent ctx idx) child
createChildCtx idx child = addToCurrent ctx idx
children = _instanceChildren widgetInstance
idxs = Seq.fromList [0..length children]
pairs = Seq.zipWith (\idx child -> (createChildCtx idx child, child)) idxs children
@ -302,12 +307,6 @@ collectGlobalKeys keys ctx widgetInstance = foldl' collectFn updatedMap pairs wh
Just key -> M.insert key (_wcCurrentPath ctx, widgetInstance) keys
_ -> keys
convertContexts :: Composite s e ep -> CompositeState s e -> WidgetEnv sp ep -> WidgetContext -> (WidgetEnv s e, WidgetContext)
convertContexts comp state wenv ctx = (cwenv, cctx) where
CompositeState{..} = state
cwenv = convertWidgetEnv wenv _compositeGlobalKeys _compositeModel
cctx = convertWidgetCtx ctx _compositeRoot
convertWidgetEnv :: WidgetEnv sp ep -> GlobalKeys s e -> s -> WidgetEnv s e
convertWidgetEnv wenv globalKeys model = WidgetEnv {
_wePlatform = _wePlatform wenv,
@ -317,9 +316,3 @@ convertWidgetEnv wenv globalKeys model = WidgetEnv {
_weInputStatus = _weInputStatus wenv,
_weTimestamp = _weTimestamp wenv
}
convertWidgetCtx :: WidgetContext -> WidgetInstance s e -> WidgetContext
convertWidgetCtx ctx widgetRoot = ctx {
_wcVisible = _wcVisible ctx && _instanceVisible widgetRoot,
_wcEnabled = _wcEnabled ctx && _instanceEnabled widgetRoot
}

View File

@ -154,6 +154,8 @@ data WidgetInstance s e =
_instanceType :: WidgetType,
-- | Key/Identifier of the widget
_instanceKey :: Maybe WidgetKey,
-- | The path of the instance in the widget tree
_instancePath :: Path,
-- | The actual widget
_instanceWidget :: Widget s e,
-- | The children widget, if any

View File

@ -23,6 +23,7 @@ defaultWidgetInstance :: WidgetType -> Widget s e -> WidgetInstance s e
defaultWidgetInstance widgetType widget = WidgetInstance {
_instanceType = widgetType,
_instanceKey = Nothing,
_instancePath = Seq.empty,
_instanceWidget = widget,
_instanceChildren = Seq.empty,
_instanceEnabled = True,

View File

@ -12,8 +12,6 @@ import qualified Data.Sequence as Seq
import Monomer.Common.Tree (Path, PathStep)
data WidgetContext = WidgetContext {
_wcVisible :: Bool,
_wcEnabled :: Bool,
_wcFocusedPath :: Path,
_wcTargetPath :: Path,
_wcCurrentPath :: Path

View File

@ -123,11 +123,14 @@
- This is also needed for _widgetPreferredSize and _widgetResize
- Generalize the "startFrom" concept of _widgetFind (and also validate it's actually well/fully implemented)
- Should Resize be restored? -> Restored
- Pending
- Make sure enabled/visible attributes are being used
- This needs modifying WidgetContext (former PathContext) to include visible and enabled attributes
- Pending
- Move widgetPath into WidgetInstance (do it in init/merge)
- Move currentPath into WidgetInstance
- Move focusedPath and targetPath to WidgetEnv
- Visible and enabled would get updated on init/merge
- Format code!
- Add testing
- Delayed until this point to try to settle down interfaces