Remove widgetUpdateSizeReq. Update sizeReq when necessary on init/merge/handleEvent/handleMessage

This commit is contained in:
Francisco Vallarino 2021-01-03 22:01:26 -03:00
parent d11452bf8c
commit 45f7490ead
27 changed files with 178 additions and 128 deletions

View File

@ -294,7 +294,7 @@ buildUI wenv model = trace "Creating UI" widgetTree where
label "Label 1234" `style` [bgColor darkGray]
] `style` [bgColor blue]
] `style` [bgColor green],
--label (model ^. textField1) `style` [bgColor lightBlue, textLeft],
label (model ^. textField1) `style` [bgColor lightBlue, textLeft],
textField textField1 `style` [bgColor lightBlue, textLeft],
hgrid [
label_ "This is a really long label used to check what I did works fine" [textMultiLine, textEllipsis],
@ -319,4 +319,4 @@ buildUI wenv model = trace "Creating UI" widgetTree where
textDropdown_ dropdown1 items id [onChange DropdownVal, onChangeIdx DropdownIdx],
button_ "Click\nme!" (PrintMessage "Button clicked") [textMultiLine]
] `key` "main vstack" `style` [borderT 20 red, borderL 10 blue, borderR 10 green, borderB 10 gray, iradius 50] --, padding 20
items = fmap (\i -> "This is a long label: " <> showt i) [1..3::Int]
items = fmap (\i -> "This is a long label: " <> showt i) [1..30::Int]

View File

@ -26,6 +26,7 @@ nodeDesc level node = infoDesc (_wnInfo node) where
spaces ++ "type: " ++ unWidgetType (_wniWidgetType info) ++ "\n" ++
spaces ++ "path: " ++ show (_wniPath info) ++ "\n" ++
spaces ++ "vp: " ++ rectDesc (_wniViewport info) ++ "\n" ++
spaces ++ "ra: " ++ rectDesc (_wniRenderArea info) ++ "\n" ++
spaces ++ "req: " ++ show (_wniSizeReqW info, _wniSizeReqH info) ++ "\n"
rectDesc r = show (_rX r, _rY r, _rW r, _rH r)
@ -41,6 +42,7 @@ nodeInstDesc level node = infoDesc (_winInfo node) where
spaces ++ "type: " ++ unWidgetType (_wniWidgetType info) ++ "\n" ++
spaces ++ "path: " ++ show (_wniPath info) ++ "\n" ++
spaces ++ "vp: " ++ rectDesc (_wniViewport info) ++ "\n" ++
spaces ++ "ra: " ++ rectDesc (_wniRenderArea info) ++ "\n" ++
spaces ++ "req: " ++ show (_wniSizeReqW info, _wniSizeReqH info) ++ "\n"
rectDesc r = show (_rX r, _rY r, _rW r, _rH r)

View File

@ -217,11 +217,6 @@ data Widget s e =
-> i
-> WidgetNode s e
-> Maybe (WidgetResult s e),
-- | Updates the sizeReq field for the widget
widgetUpdateSizeReq
:: WidgetEnv s e
-> WidgetNode s e
-> WidgetNode s e,
-- | Resizes the children of this widget
--
-- Vieport assigned to the widget

View File

@ -64,7 +64,8 @@ resizeRoot
resizeRoot wenv windowSize widgetRoot = newRoot where
Size w h = windowSize
assigned = Rect 0 0 w h
newRoot = resizeWidget wenv assigned assigned widgetRoot
widget = widgetRoot ^. L.widget
newRoot = widgetResize widget wenv assigned assigned widgetRoot
resizeWindow
:: (MonomerM s m)

View File

@ -161,7 +161,7 @@ makeBox config = widget where
_ -> Nothing
getSizeReq :: ContainerGetSizeReqHandler s e
getSizeReq wenv node children = (newReqW, newReqH) where
getSizeReq wenv currState node children = (newReqW, newReqH) where
child = Seq.index children 0
newReqW = child ^. L.info . L.sizeReqW
newReqH = child ^. L.info . L.sizeReqH

View File

@ -214,7 +214,9 @@ makeButton config state = widget where
events = _btnOnClick config
result = resultReqsEvts node requests events
getSizeReq wenv node = (sizeW, sizeH) where
getSizeReq wenv currState node = (sizeW, sizeH) where
newState = fromMaybe state (useState currState)
caption = _btnCaption newState
style = activeStyle wenv node
targetW = fmap sizeReqMax (style ^. L.sizeReqW)
Size w h = getTextSize_ wenv style mode trimSpaces targetW caption

View File

@ -146,7 +146,7 @@ makeCheckbox widgetData config = widget where
reqs = setValueReq ++ _ckcOnChangeReq config
clickReqs = setFocusReq : reqs
getSizeReq wenv node = req where
getSizeReq wenv currState node = req where
theme = activeTheme wenv node
width = fromMaybe (theme ^. L.checkboxWidth) (_ckcWidth config)
req = (FixedSize width, FixedSize width)

View File

@ -242,7 +242,6 @@ createComposite comp state = widget where
widgetFindByPoint = compositeFindByPoint comp state,
widgetHandleEvent = compositeHandleEvent comp state,
widgetHandleMessage = compositeHandleMessage comp state,
widgetUpdateSizeReq = compositeUpdateSizeReq comp state,
widgetResize = compositeResize comp state,
widgetRender = compositeRender comp state
}
@ -446,28 +445,20 @@ compositeHandleMessage comp state@CompositeState{..} wenv target arg widgetComp
result = widgetHandleMessage cmpWidget cwenv target arg _cpsRoot
-- Preferred size
compositeUpdateSizeReq
updateSizeReq
:: (CompositeModel s, CompositeEvent e, ParentModel sp)
=> Composite s e sp ep
-> CompositeState s e sp
=> CompositeState s e sp
-> WidgetEnv sp ep
-> WidgetNode sp ep
-> WidgetNode sp ep
compositeUpdateSizeReq comp state wenv widgetComp = newComp where
updateSizeReq state wenv widgetComp = newComp where
CompositeState{..} = state
style = activeStyle wenv widgetComp
widget = _cpsRoot ^. L.widget
model = getModel comp wenv
cwenv = convertWidgetEnv wenv _cpsGlobalKeys model
newRoot = widgetUpdateSizeReq widget cwenv _cpsRoot
currReqW = newRoot ^. L.info . L.sizeReqW
currReqH = newRoot ^. L.info . L.sizeReqH
currReqW = _cpsRoot ^. L.info . L.sizeReqW
currReqH = _cpsRoot ^. L.info . L.sizeReqH
(newReqW, newReqH) = sizeReqAddStyle style (currReqW, currReqH)
newState = state {
_cpsRoot = newRoot
}
newComp = widgetComp
& L.widget .~ createComposite comp newState
& L.info . L.sizeReqW .~ newReqW
& L.info . L.sizeReqH .~ newReqH
@ -575,7 +566,7 @@ updateComposite comp state wenv newModel widgetRoot widgetComp = result where
}
result
| mergeRequired = mergeChild comp state wenv newModel widgetRoot widgetComp
| otherwise = resultWidget $ widgetComp
| otherwise = resultWidget $ updateSizeReq newState wenv widgetComp
& L.widget .~ createComposite comp newState
mergeChild

View File

@ -18,7 +18,6 @@ module Monomer.Widgets.Container (
mergeWrapper,
handleEventWrapper,
handleMessageWrapper,
getSizeReqWrapper,
findByPointWrapper,
findNextFocusWrapper,
resizeWrapper,
@ -118,6 +117,7 @@ type ContainerMessageHandler s e
type ContainerGetSizeReqHandler s e
= WidgetEnv s e
-> Maybe WidgetState
-> WidgetNode s e
-> Seq (WidgetNode s e)
-> (SizeReq, SizeReq)
@ -196,7 +196,6 @@ createContainer container = Widget {
widgetFindByPoint = findByPointWrapper container,
widgetHandleEvent = handleEventWrapper container,
widgetHandleMessage = handleMessageWrapper container,
widgetUpdateSizeReq = getSizeReqWrapper container,
widgetResize = resizeWrapper container,
widgetRender = renderWrapper container
}
@ -227,7 +226,8 @@ initWrapper container wenv node = result where
newReqs = foldMap _wrRequests results
newEvents = foldMap _wrEvents results
newChildren = fmap _wrNode results
newNode = tempNode & L.children .~ newChildren
newNode = updateSizeReq container wenv $ tempNode
& L.children .~ newChildren
result = WidgetResult newNode (reqs <> newReqs) (events <> newEvents)
-- | Merging
@ -260,10 +260,14 @@ mergeWrapper container wenv oldNode newNode = result where
pResult = mergeParent mergeHandler wenv oldState oldNode styledNode
cResult = mergeChildren wenv oldNode newNode pResult
vResult = mergeChildrenCheckVisible oldNode cResult
tempResult
tmpRes
| mergeRequired || oldFlags /= newFlags = vResult
| otherwise = pResult & L.node . L.children .~ oldNode ^. L.children
result = mergePostHandler wenv tempResult oldState oldNode (vResult ^. L.node)
postRes = mergePostHandler wenv tmpRes oldState oldNode (tmpRes ^. L.node)
result
| isResizeResult (Just postRes) = postRes
& L.node .~ updateSizeReq container wenv (postRes ^. L.node)
| otherwise = postRes
mergeParent
:: ContainerMergeHandler s e
@ -471,7 +475,7 @@ handleEventWrapper
-> SystemEvent
-> WidgetNode s e
-> Maybe (WidgetResult s e)
handleEventWrapper container wenv target event node
handleEventWrapper container wenv target evt node
| not (node ^. L.info . L.visible) = Nothing
| targetReached || not targetValid = pResultStyled
| styleOnMerge = cResultStyled
@ -490,14 +494,16 @@ handleEventWrapper container wenv target event node
children = node ^. L.children
child = Seq.index children childIdx
childWidget = child ^. L.widget
pResponse = pHandler wenv target event node
pResponse = pHandler wenv target evt node
childrenIgnored = isJust pResponse && ignoreChildren (fromJust pResponse)
cResponse
| childrenIgnored || not (child ^. L.info . L.enabled) = Nothing
| otherwise = widgetHandleEvent childWidget wenv target event child
pResultStyled = handleStyleChange wenv target event style pResponse def node
| otherwise = widgetHandleEvent childWidget wenv target evt child
pResultStyled = handleStyleChange wenv target style def node evt
$ handleSizeReqChange container wenv node (Just evt) pResponse
cResult = mergeParentChildEvts node pResponse cResponse childIdx
cResultStyled = handleStyleChange wenv target event style cResult def node
cResultStyled = handleStyleChange wenv target style def node evt
$ handleSizeReqChange container wenv node (Just evt) cResult
mergeParentChildEvts
:: WidgetNode s e
@ -537,9 +543,8 @@ handleMessageWrapper
-> WidgetNode s e
-> Maybe (WidgetResult s e)
handleMessageWrapper container wenv target arg node
| targetReached = mHandler wenv target arg node
| not targetValid = Nothing
| otherwise = messageResult
| not targetReached && not targetValid = Nothing
| otherwise = handleSizeReqChange container wenv node Nothing result
where
mHandler = containerHandleMessage container
targetReached = isTargetReached target node
@ -552,31 +557,46 @@ handleMessageWrapper container wenv target arg node
updateChild cr = cr {
_wrNode = replaceChild node (_wrNode cr) childIdx
}
result
| targetReached = mHandler wenv target arg node
| otherwise = messageResult
-- | Preferred size
defaultGetSizeReq :: ContainerGetSizeReqHandler s e
defaultGetSizeReq wenv node children = def
getSizeReqWrapper
updateSizeReq
:: Container s e
-> WidgetEnv s e
-> WidgetNode s e
-> WidgetNode s e
getSizeReqWrapper container wenv node = newNode where
resizeRequired = containerResizeRequired container
updateSizeReq container wenv node = newNode where
psHandler = containerGetSizeReq container
currState = widgetGetState (node ^. L.widget) wenv
style = activeStyle wenv node
children = node ^. L.children
updateChild child = widgetUpdateSizeReq (child ^. L.widget) wenv child
newChildren = fmap updateChild children
reqs = psHandler wenv node newChildren
reqs = psHandler wenv currState node children
(newReqW, newReqH) = sizeReqAddStyle style reqs
newNode
| resizeRequired = node
& L.children .~ newChildren
& L.info . L.sizeReqW .~ newReqW
& L.info . L.sizeReqH .~ newReqH
| otherwise = node
newNode = node
& L.info . L.sizeReqW .~ newReqW
& L.info . L.sizeReqH .~ newReqH
handleSizeReqChange
:: Container s e
-> WidgetEnv s e
-> WidgetNode s e
-> Maybe SystemEvent
-> Maybe (WidgetResult s e)
-> Maybe (WidgetResult s e)
handleSizeReqChange container wenv node evt mResult = result where
baseResult = fromMaybe (resultWidget node) mResult
newNode = baseResult ^. L.node
resizeReq = isResizeResult mResult
styleChanged = isJust evt && styleStateChanged wenv newNode (fromJust evt)
result
| styleChanged || resizeReq = Just $ baseResult
& L.node .~ updateSizeReq container wenv newNode
| otherwise = mResult
-- | Resize
defaultResize :: ContainerResizeHandler s e

View File

@ -345,16 +345,15 @@ makeDropdown widgetData items makeMain makeRow config state = widget where
++ fmap (\fn -> fn idx item) (_ddcOnChangeIdx config)
result = WidgetResult newNode (reqs <> newReqs) (events <> newEvents)
getSizeReq wenv node children = (newReqW, newReqH) where
getSizeReq :: ContainerGetSizeReqHandler s e
getSizeReq wenv currState node children = (newReqW, newReqH) where
-- Main section reqs
mainC = Seq.index children 0
mainReq = widgetUpdateSizeReq (mainC ^. L.widget) wenv mainC
mainReqW = mainReq ^. L.info . L.sizeReqW
mainReqH = mainReq ^. L.info . L.sizeReqH
mainReqW = mainC ^. L.info . L.sizeReqW
mainReqH = mainC ^. L.info . L.sizeReqH
-- List items reqs
listC = Seq.index children 1
listReq = widgetUpdateSizeReq (listC ^. L.widget) wenv listC
listReqW = listReq ^. L.info . L.sizeReqW
listReqW = listC ^. L.info . L.sizeReqW
-- Items other than main could be wider
-- Height only matters for the selected item, since the rest is in a scroll
newReqW = sizeReqMergeMax mainReqW listReqW

View File

@ -34,7 +34,7 @@ makeFixedGrid isHorizontal = widget where
isVertical = not isHorizontal
getSizeReq wenv node children = (newSizeReqW, newSizeReqH) where
getSizeReq wenv currState node children = (newSizeReqW, newSizeReqH) where
vchildren = Seq.filter (_wniVisible . _wnInfo) children
newSizeReqW = getDimSizeReq isHorizontal (_wniSizeReqW . _wnInfo) vchildren
newSizeReqH = getDimSizeReq isVertical (_wniSizeReqH . _wnInfo) vchildren

View File

@ -60,7 +60,7 @@ makeImage iconType config = widget where
singleRender = render
}
getSizeReq wenv node = sizeReq where
getSizeReq wenv currState node = sizeReq where
(w, h) = (16, 16)
factor = 1
sizeReq = (FlexSize w factor, FlexSize h factor)

View File

@ -159,8 +159,9 @@ makeImage imgPath config state = widget where
& L.widget .~ makeImage imgPath config newState
result = Just $ resultReqs newNode [ResizeWidgets]
getSizeReq wenv node = sizeReq where
Size w h = maybe def snd (isImageData state)
getSizeReq wenv currState node = sizeReq where
newState = fromMaybe state (useState currState)
Size w h = maybe def snd (isImageData newState)
factor = 1
sizeReq = (FlexSize w factor, FlexSize h factor)

View File

@ -490,7 +490,9 @@ makeInputField config state = widget where
| isValid || not textAdd = resultReqsEvts newNode reqs events
| otherwise = resultReqsEvts node reqs events
getSizeReq wenv node = sizeReq where
getSizeReq wenv currState node = sizeReq where
newState = fromMaybe state (useState currState)
currText = _ifsCurrText newState
style = activeStyle wenv node
Size w h = getTextSize wenv style currText
targetW = max w 100

View File

@ -117,6 +117,7 @@ makeLabel config state = widget where
merge wenv oldState oldNode newNode = result where
prevState = fromMaybe state (useState oldState)
captionChanged = _lstCaption prevState /= caption
-- This is used in resize to have glyphs recalculated
newRect
| captionChanged = def
| otherwise = _lstTextRect prevState
@ -129,7 +130,9 @@ makeLabel config state = widget where
& L.widget .~ makeLabel config newState
result = resultReqs resNode reqs
getSizeReq wenv node = (sizeW, sizeH) where
getSizeReq wenv currState node = (sizeW, sizeH) where
newState = fromMaybe state (useState currState)
caption = _lstCaption newState
style = activeStyle wenv node
targetW = fmap sizeReqMax (style ^. L.sizeReqW)
Size w h = getTextSize_ wenv style mode trimSpaces targetW caption

View File

@ -366,7 +366,7 @@ makeListView widgetData items makeRow config state = widget where
>>= lookup 0 -- vstack
>>= lookup idx -- item
getSizeReq wenv node children = (newSizeReqW, newSizeReqH) where
getSizeReq wenv currState node children = (newSizeReqW, newSizeReqH) where
child = Seq.index children 0
newSizeReqW = _wniSizeReqW . _wnInfo $ child
newSizeReqH = _wniSizeReqH . _wnInfo $ child

View File

@ -156,7 +156,7 @@ makeRadio field option config = widget where
reqs = setValueReq ++ _rdcOnChangeReq config
clickReqs = setFocusReq : reqs
getSizeReq wenv node = req where
getSizeReq wenv currState node = req where
theme = activeTheme wenv node
width = fromMaybe (theme ^. L.radioWidth) (_rdcWidth config)
req = (FixedSize width, FixedSize width)

View File

@ -347,7 +347,7 @@ makeScroll config state = widget where
newNode = scrollResize (Just newWidget) newState wenv vp ra tempNode
getSizeReq :: ContainerGetSizeReqHandler s e
getSizeReq wenv node children = sizeReq where
getSizeReq wenv currState node children = sizeReq where
style = scrollActiveStyle wenv node
child = Seq.index children 0
tw = sizeReqMax $ child ^. L.info . L.sizeReqW

View File

@ -14,8 +14,12 @@ module Monomer.Widgets.Single (
import Control.Lens ((&), (^.), (^?), (.~), _Just)
import Data.Default
import Data.Maybe
import Data.Sequence (Seq(..))
import Data.Typeable (Typeable)
import qualified Data.Sequence as Seq
import Monomer.Core
import Monomer.Core.Combinators
import Monomer.Event
@ -84,6 +88,7 @@ type SingleMessageHandler s e
type SingleGetSizeReqHandler s e
= WidgetEnv s e
-> Maybe WidgetState
-> WidgetNode s e
-> (SizeReq, SizeReq)
@ -149,8 +154,7 @@ createSingle single = Widget {
widgetFindNextFocus = singleFindNextFocus single,
widgetFindByPoint = singleFindByPoint single,
widgetHandleEvent = handleEventWrapper single,
widgetHandleMessage = singleHandleMessage single,
widgetUpdateSizeReq = updateSizeReqWrapper single,
widgetHandleMessage = handleMessageWrapper single,
widgetResize = resizeHandlerWrapper single,
widgetRender = renderWrapper single
}
@ -173,7 +177,9 @@ initWrapper single wenv node = newResult where
initHandler = singleInit single
getBaseStyle = singleGetBaseStyle single
styledNode = initNodeStyle getBaseStyle wenv node
newResult = initHandler wenv styledNode
tmpResult = initHandler wenv styledNode
newResult = tmpResult
& L.node .~ updateSizeReq single wenv (tmpResult ^. L.node)
defaultMerge :: SingleMergeHandler s e
defaultMerge wenv oldState oldNode newNode = resultWidget newNode
@ -195,7 +201,11 @@ mergeWrapper single wenv oldNode newNode = newResult where
& L.info . L.sizeReqW .~ oldInfo ^. L.sizeReqW
& L.info . L.sizeReqH .~ oldInfo ^. L.sizeReqH
styledNode = initNodeStyle getBaseStyle wenv tempNode
newResult = mergeHandler wenv oldState oldNode styledNode
tmpResult = mergeHandler wenv oldState oldNode styledNode
newResult
| isResizeResult (Just tmpResult) = tmpResult
& L.node .~ updateSizeReq single wenv (tmpResult ^. L.node)
| otherwise = tmpResult
defaultDispose :: SingleDisposeHandler s e
defaultDispose wenv node = resultWidget node
@ -230,36 +240,69 @@ handleEventWrapper
-> Maybe (WidgetResult s e)
handleEventWrapper single wenv target evt node
| not (node ^. L.info . L.visible) = Nothing
| otherwise = handleStyleChange wenv target evt style resFocus styleCfg node
| otherwise = handleStyleChange wenv target style styleCfg newNode evt result
where
style = singleGetActiveStyle single wenv node
styleCfg = singleStyleChangeCfg single
focusOnPressed = singleFocusOnPressedBtn single
handler = singleHandleEvent single
result = handler wenv target evt node
resFocus
| singleFocusOnPressedBtn single = handleFocusRequest wenv evt node result
| otherwise = result
sizeResult = handleSizeReqChange single wenv node (Just evt)
$ handler wenv target evt node
newNode = maybe node (^. L.node) sizeResult
result
| focusOnPressed = handleFocusRequest wenv evt newNode sizeResult
| otherwise = sizeResult
defaultHandleMessage :: SingleMessageHandler s e
defaultHandleMessage wenv target message node = Nothing
handleMessageWrapper :: forall s e i . Typeable i
=> Single s e
-> WidgetEnv s e
-> Path
-> i
-> WidgetNode s e
-> Maybe (WidgetResult s e)
handleMessageWrapper single wenv target msg node = result where
handler = singleHandleMessage single
result = handleSizeReqChange single wenv node Nothing
$ handler wenv target msg node
defaultGetSizeReq :: SingleGetSizeReqHandler s e
defaultGetSizeReq wenv node = def
updateSizeReqWrapper
updateSizeReq
:: Single s e
-> WidgetEnv s e
-> WidgetNode s e
-> WidgetNode s e
updateSizeReqWrapper single wenv node = newNode where
updateSizeReq single wenv node = newNode where
handler = singleGetSizeReq single
style = singleGetActiveStyle single wenv node
reqs = handler wenv node
currState = widgetGetState (node ^. L.widget) wenv
reqs = handler wenv currState node
(newReqW, newReqH) = sizeReqAddStyle style reqs
newNode = node
& L.info . L.sizeReqW .~ newReqW
& L.info . L.sizeReqH .~ newReqH
handleSizeReqChange
:: Single s e
-> WidgetEnv s e
-> WidgetNode s e
-> Maybe SystemEvent
-> Maybe (WidgetResult s e)
-> Maybe (WidgetResult s e)
handleSizeReqChange single wenv node evt mResult = result where
baseResult = fromMaybe (resultWidget node) mResult
newNode = baseResult ^. L.node
resizeReq = isResizeResult mResult
styleChanged = isJust evt && styleStateChanged wenv newNode (fromJust evt)
result
| styleChanged || resizeReq = Just $ baseResult
& L.node .~ updateSizeReq single wenv newNode
| otherwise = mResult
defaultResize :: SingleResizeHandler s e
defaultResize wenv viewport renderArea node = node

View File

@ -61,7 +61,7 @@ makeSpacer config = widget where
singleGetSizeReq = getSizeReq
}
getSizeReq wenv node = sizeReq where
getSizeReq wenv currState node = sizeReq where
width = fromMaybe 5 (_spcWidth config)
height = fromMaybe 5 (_spcHeight config)
factor = fromMaybe 0.5 (_spcFactor config)

View File

@ -78,7 +78,7 @@ makeStack isHorizontal config = widget where
isVertical = not isHorizontal
ignoreEmptyArea = fromMaybe False (_stcIgnoreEmptyArea config)
getSizeReq wenv node children = (newSizeReqW, newSizeReqH) where
getSizeReq wenv currState node children = (newSizeReqW, newSizeReqH) where
vchildren = Seq.filter (_wniVisible . _wnInfo) children
newSizeReqW = getDimSizeReq isHorizontal (_wniSizeReqW . _wnInfo) vchildren
newSizeReqH = getDimSizeReq isVertical (_wniSizeReqH . _wnInfo) vchildren

View File

@ -9,7 +9,9 @@ module Monomer.Widgets.Util.Style (
activeStyle_,
focusedStyle,
initNodeStyle,
handleStyleChange
handleStyleChange,
styleStateChanged,
isResizeResult
) where
import Control.Applicative ((<|>))
@ -17,6 +19,7 @@ import Control.Lens ((&), (^.), (^?), (.~), (<>~), _Just)
import Data.Bits (xor)
import Data.Default
import Data.Maybe
import Data.Sequence (Seq(..))
import qualified Data.Sequence as Seq
@ -88,13 +91,13 @@ initNodeStyle getBaseStyle wenv node = newNode where
handleStyleChange
:: WidgetEnv s e
-> Path
-> SystemEvent
-> StyleState
-> Maybe (WidgetResult s e)
-> StyleChangeCfg
-> WidgetNode s e
-> SystemEvent
-> Maybe (WidgetResult s e)
handleStyleChange wenv target evt style result cfg node = newResult where
-> Maybe (WidgetResult s e)
handleStyleChange wenv target style cfg node evt result = newResult where
baseResult = fromMaybe (resultWidget node) result
baseNode = baseResult ^. L.node
sizeReqs = handleSizeChange wenv target evt cfg baseNode node
@ -137,24 +140,10 @@ styleStateChanged wenv node evt = hoverChanged || focusChanged where
-- Focus
focusChanged = isOnFocus evt || isOnBlur evt
styleStateSizeChanged :: StyleState -> StyleState -> Bool
styleStateSizeChanged st1 st2 = borderChg || paddChg || textChg where
fontLens = L.text . _Just . L.font
fontSizeLens = L.text . _Just . L.fontSize
bs1 = borderSizes <$> st1 ^. L.border
bs2 = borderSizes <$> st2 ^. L.border
fontChg = st1 ^? fontLens /= st2 ^? fontLens
fontSizeChg = st1 ^? fontSizeLens /= st2 ^? fontSizeLens
borderChg = bs1 /= bs2
paddChg = st1 ^. L.padding /= st2 ^. L.padding
textChg = fontChg || fontSizeChg
borderSizes :: Border -> (Double, Double, Double, Double)
borderSizes border = (sl, sr, st, sb) where
sl = fromMaybe 0 (border ^? L.left . _Just . L.width)
sr = fromMaybe 0 (border ^? L.right . _Just . L.width)
st = fromMaybe 0 (border ^? L.top . _Just . L.width)
sb = fromMaybe 0 (border ^? L.bottom . _Just . L.width)
isResizeResult :: Maybe (WidgetResult s e) -> Bool
isResizeResult result = isJust resizeReq where
requests = maybe Empty (^. L.requests) result
resizeReq = Seq.findIndexL isResizeWidgets requests
handleCursorChange
:: WidgetEnv s e

View File

@ -21,7 +21,6 @@ module Monomer.Widgets.Util.Widget (
isTopLevel,
handleFocusRequest,
handleFocusChange,
resizeWidget,
buildLocalMap,
findWidgetByKey,
getInstanceTree
@ -170,16 +169,6 @@ handleFocusChange evtFn reqFn config node = result where
| not (null evts && null reqs) = Just $ resultReqsEvts node reqs evts
| otherwise = Nothing
resizeWidget
:: WidgetEnv s e
-> Rect
-> Rect
-> WidgetNode s e
-> WidgetNode s e
resizeWidget wenv viewport renderArea widgetRoot = newRoot where
reqNode = widgetUpdateSizeReq (_wnWidget widgetRoot) wenv widgetRoot
newRoot = widgetResize (reqNode ^. L.widget) wenv viewport renderArea reqNode
findWidgetByKey
:: WidgetKey
-> LocalKeys s e

View File

@ -99,7 +99,7 @@ makeZStack config = widget where
| onlyTopActive = Seq.take 1 vchildren
| otherwise = vchildren
getSizeReq wenv node children = (newSizeReqW, newSizeReqH) where
getSizeReq wenv currState node children = (newSizeReqW, newSizeReqH) where
vchildren = Seq.filter (_wniVisible . _wnInfo) children
newSizeReqW = getDimSizeReq (_wniSizeReqW . _wnInfo) vchildren
newSizeReqH = getDimSizeReq (_wniSizeReqH . _wnInfo) vchildren

View File

@ -379,6 +379,17 @@
- Add user documentation
Maybe postponed after release?
- Remove getSizeReq from Widget interface. Keep it in Single/Container
- Other Widgets should take care of updating those fields during init/merge/handleEvent/handleMessage
- Remove Widget.resizeWidget
- Remove Widget.widgetUpdateSizeReq
- Update Style.handleSizeChange
- Remove old code from Single, Container and Composite
- Make sure Single, Container and Composite update size when needed
- Copy merge logic from Label to Button
- Add containerGetActiveStyle
- Review handleSizeReqChange
- Rethink containerStyleOnMerge (it should really be containerStyleOnMerge and yes we need it)
- Listview is not properly changing styles
- Label needs to rebuild its glyphs if style/renderArea changes
- Listview needs to update sizeReq of modified items
@ -386,8 +397,6 @@ Maybe postponed after release?
- Further improvements
- Stack resizing should exclude invisible items (outside of viewprot)
- Refactor Stack code, so sizeReq/resizing functions can be used from ListView directly
- Remove getSizeReq from Widget interface. Keep it in Single/Container
- Other Widgets should take care of updating those fields during init/merge/handleEvent/handleMessage
- Add serialization logic for Widget Tree
- Store state in Widget Tree
- Rethink merge. Maybe we can provide WidgetInstanceNode instead of WidgetNode?

View File

@ -144,13 +144,13 @@ nodeMerge wenv oldNode node = newNode where
nodeUpdateSizeReq :: WidgetEnv s e -> WidgetNode s e -> (SizeReq, SizeReq)
nodeUpdateSizeReq wenv node = (sizeReqW, sizeReqH) where
WidgetResult node2 _ _ = widgetInit (node ^. L.widget) wenv node
reqNode = widgetUpdateSizeReq (node2 ^. L.widget) wenv node2
sizeReqW = reqNode ^. L.info ^. L.sizeReqW
sizeReqH = reqNode ^. L.info ^. L.sizeReqH
sizeReqW = node2 ^. L.info . L.sizeReqW
sizeReqH = node2 ^. L.info . L.sizeReqH
nodeResize :: WidgetEnv s e -> Rect -> WidgetNode s e -> WidgetNode s e
nodeResize wenv viewport node = newNode where
newNode = resizeWidget wenv viewport viewport node
widget = node ^. L.widget
newNode = widgetResize widget wenv viewport viewport node
nodeHandleEventCtx
:: (Eq s)

View File

@ -6,7 +6,7 @@ module Monomer.Widgets.Util.StyleSpec (spec) where
import Control.Lens ((&), (^.), (^?), (^?!), (.~), (?~), _Just, ix, non)
import Data.Default
import Data.Sequence (Seq)
import Data.Sequence (Seq(..))
import Data.Text (Text)
import Test.Hspec
@ -58,10 +58,11 @@ testActiveStyle = describe "activeStyle" $ do
testHandleSizeChange :: Spec
testHandleSizeChange = describe "handleSizeChange" $ do
it "should request Resize widgets if sizeReq changed" $ do
resHover ^? _Just . L.requests `shouldSatisfy` (==3) . maybeLength
resHover ^? _Just . L.requests . ix 0 `shouldSatisfy` isMRenderOnce
resHover ^? _Just . L.requests . ix 1 `shouldSatisfy` isMSetCursorIcon
resHover ^? _Just . L.requests . ix 2 `shouldSatisfy` isMRenderOnce
resHover ^? _Just . L.requests `shouldSatisfy` (==4) . maybeLength
resHover ^? _Just . L.requests . ix 0 `shouldSatisfy` isMResizeWidgets
resHover ^? _Just . L.requests . ix 1 `shouldSatisfy` isMRenderOnce
resHover ^? _Just . L.requests . ix 2 `shouldSatisfy` isMSetCursorIcon
resHover ^? _Just . L.requests . ix 3 `shouldSatisfy` isMRenderOnce
it "should not request Resize widgets if sizeReq has not changed" $
resFocus ^? _Just . L.requests `shouldSatisfy` (==0) . maybeLength
@ -76,13 +77,16 @@ testHandleSizeChange = describe "handleSizeChange" $ do
baseNode = createNode True
& L.info . L.style .~ style
node = nodeInit wenv baseNode
modNode = node & L.info . L.sizeReqW .~ FixedSize 100
res1 = Just $ WidgetResult modNode Empty Empty
res2 = Just $ WidgetResult node Empty Empty
point = Point 200 200
path = Seq.fromList [0]
wenvHover = mockWenv () & L.inputStatus . L.mousePos .~ point
wenvFocus = mockWenv () & L.focusedPath .~ path
evtEnter = Enter point
resHover = handleStyleChange wenvHover path evtEnter hoverStyle Nothing def node
resFocus = handleStyleChange wenvFocus path Focus focusStyle Nothing def node
evEnter = Enter point
resHover = handleStyleChange wenvHover path hoverStyle def node evEnter res1
resFocus = handleStyleChange wenvFocus path focusStyle def node Focus res2
isMResizeWidgets :: Maybe (WidgetRequest s) -> Bool
isMResizeWidgets (Just ResizeWidgets) = True