Standardize widget initialization

This commit is contained in:
Francisco Vallarino 2020-07-13 19:38:51 -03:00
parent 3a6231b31c
commit 43b53aef96
7 changed files with 140 additions and 94 deletions

View File

@ -59,7 +59,7 @@ handleKeysCompEvent app evt = case evt of
buildKeysComp app = trace "Created keys composite UI" $
hgrid [
button "Rotate" RotateChildren,
button RotateChildren "Rotate",
vgrid $ fmap (editableItem app) [0..(length (_items app) - 1)]
]

View File

@ -67,14 +67,14 @@ buildComposite app = trace "Created composite UI" $
scroll $ label "This is a composite label again!",
vgrid [
hgrid [
button "Message parent" MessageParent
button MessageParent "Message parent"
],
hgrid [
sandbox CallSandbox,
button "Run task" StartTask
button StartTask "Run task"
],
hgrid [
button "Run Producer" StartProducer,
button StartProducer "Run Producer",
label ("Produced: " <> showt (_csProduced app))
]
] `style` color gray

View File

@ -1,6 +1,6 @@
{-# LANGUAGE RecordWildCards #-}
module Monomer.Widget.Widgets.Button (button) where
module Monomer.Widget.Widgets.Button (ButtonConfig(..), button, button_) where
import Control.Monad
import Data.Text (Text)
@ -15,27 +15,38 @@ import Monomer.Widget.BaseWidget
import Monomer.Widget.Types
import Monomer.Widget.Util
button :: Text -> e -> WidgetInstance s e
button label onClick = defaultWidgetInstance "button" (makeButton label onClick)
data ButtonConfig s e = ButtonConfig {
_btnLabel :: Text,
_btnOnChange :: [e],
_btnOnChangeReq :: [WidgetRequest s]
}
makeButton :: Text -> e -> Widget s e
makeButton label onClick = createWidget {
button :: e -> Text -> WidgetInstance s e
button onClick label = button_ config where
config = ButtonConfig label [onClick] []
button_ :: ButtonConfig s e -> WidgetInstance s e
button_ config = defaultWidgetInstance "button" (makeButton config)
makeButton :: ButtonConfig s e -> Widget s e
makeButton config = createWidget {
_widgetHandleEvent = handleEvent,
_widgetPreferredSize = preferredSize,
_widgetRender = render
}
where
handleEvent wctx ctx evt widgetInstance = case evt of
Click (Point x y) _ -> Just $ resultEvents events widgetInstance where
events = [onClick]
Click (Point x y) _ -> Just $ resultReqsEvents requests events widgetInstance where
requests = _btnOnChangeReq config
events = _btnOnChange config
_ -> Nothing
preferredSize renderer wctx widgetInstance = singleNode sizeReq where
Style{..} = _instanceStyle widgetInstance
size = calcTextBounds renderer _styleText label
size = calcTextBounds renderer _styleText (_btnLabel config)
sizeReq = SizeReq size FlexibleSize FlexibleSize
render renderer wctx ctx WidgetInstance{..} =
do
drawStyledBackground renderer _instanceRenderArea _instanceStyle
drawStyledText_ renderer _instanceRenderArea _instanceStyle label
drawStyledText_ renderer _instanceRenderArea _instanceStyle (_btnLabel config)

View File

@ -3,7 +3,7 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module Monomer.Widget.Widgets.Dropdown (dropdown) where
module Monomer.Widget.Widgets.Dropdown (DropdownConfig(..), dropdown) where
import Control.Applicative ((<|>))
import Control.Lens (ALens', (&), (^#), (#~))
@ -37,6 +37,8 @@ import Monomer.Widget.Widgets.ListView
data DropdownConfig s e a = DropdownConfig {
_ddValue :: WidgetValue s a,
_ddItems :: Seq a,
_ddItemToText :: a -> Text,
_ddOnChange :: [a -> e],
_ddOnChangeReq :: [WidgetRequest s]
}
@ -48,12 +50,12 @@ newtype DropdownState = DropdownState {
newtype DropdownMessage = OnChangeMessage Int deriving Typeable
dropdown :: (Traversable t, Eq a) => ALens' s a -> t a -> (a -> Text) -> WidgetInstance s e
dropdown field items itemToText = dropdown_ config items itemToText where
config = DropdownConfig (WidgetLens field) [] []
dropdown_ :: (Traversable t, Eq a) => DropdownConfig s e a -> t a -> (a -> Text) -> WidgetInstance s e
dropdown_ config items itemToText = makeInstance (makeDropdown config newState newItems itemToText) where
dropdown field items itemToText = dropdown_ config where
config = DropdownConfig (WidgetLens field) newItems itemToText [] []
newItems = foldl' (|>) Empty items
dropdown_ :: (Eq a) => DropdownConfig s e a -> WidgetInstance s e
dropdown_ config = makeInstance (makeDropdown config newState) where
newState = DropdownState False
makeInstance :: Widget s e -> WidgetInstance s e
@ -61,8 +63,8 @@ makeInstance widget = (defaultWidgetInstance "dropdown" widget) {
_instanceFocusable = True
}
makeDropdown :: (Eq a) => DropdownConfig s e a -> DropdownState -> Seq a -> (a -> Text) -> Widget s e
makeDropdown config state items itemToText = createContainer {
makeDropdown :: (Eq a) => DropdownConfig s e a -> DropdownState -> Widget s e
makeDropdown config state = createContainer {
_widgetInit = containerInit init,
_widgetGetState = makeState state,
_widgetMerge = containerMergeTrees merge,
@ -79,8 +81,8 @@ makeDropdown config state items itemToText = createContainer {
createDropdown wctx ctx newState widgetInstance = newInstance where
selected = currentValue wctx
newInstance = widgetInstance {
_instanceWidget = makeDropdown config newState items itemToText,
_instanceChildren = Seq.singleton $ makeListView ctx items selected itemToText
_instanceWidget = makeDropdown config newState,
_instanceChildren = Seq.singleton $ makeListView config ctx selected
}
init wctx ctx widgetInstance = resultWidget $ createDropdown wctx ctx state widgetInstance
@ -109,10 +111,10 @@ makeDropdown config state items itemToText = createContainer {
handleOpenDropdown wctx ctx widgetInstance = resultReqs requests newInstance where
selected = currentValue wctx
selectedIdx = fromMaybe 0 (Seq.elemIndexL selected items)
selectedIdx = fromMaybe 0 (Seq.elemIndexL selected (_ddItems config))
newState = DropdownState True
newInstance = widgetInstance {
_instanceWidget = makeDropdown config newState items itemToText
_instanceWidget = makeDropdown config newState
}
lvPath = currentPath (childContext ctx)
requests = [SetOverlay (currentPath ctx), SetFocus lvPath]
@ -120,12 +122,12 @@ makeDropdown config state items itemToText = createContainer {
handleCloseDropdown wctx ctx widgetInstance = resultReqs requests newInstance where
newState = DropdownState False
newInstance = widgetInstance {
_instanceWidget = makeDropdown config newState items itemToText
_instanceWidget = makeDropdown config newState
}
requests = [ResetOverlay, SetFocus (currentPath ctx)]
handleMessage wctx ctx message widgetInstance = cast message
>>= \(OnChangeMessage idx) -> Seq.lookup idx items
>>= \(OnChangeMessage idx) -> Seq.lookup idx (_ddItems config)
>>= \value -> Just $ handleOnChange wctx ctx idx value widgetInstance
handleOnChange wctx ctx idx item widgetInstance = WidgetResult (reqs <> newReqs) (events <> newEvents) newInstance where
@ -161,13 +163,15 @@ makeDropdown config state items itemToText = createContainer {
renderOverlay renderer wctx ctx overlayInstance = renderAction where
renderAction = _widgetRender (_instanceWidget overlayInstance) renderer wctx (childContext ctx) overlayInstance
dropdownLabel wctx = itemToText $ currentValue wctx
dropdownLabel wctx = _ddItemToText config $ currentValue wctx
makeListView :: (Eq a) => PathContext -> Seq a -> a -> (a -> Text) -> WidgetInstance s e
makeListView ctx items selected itemToText = listView_ lvConfig items itemToText where
makeListView :: (Eq a) => DropdownConfig s e a -> PathContext -> a -> WidgetInstance s e
makeListView DropdownConfig{..} ctx selected = listView_ lvConfig where
path = _pathCurrent ctx
lvConfig = ListViewConfig {
_lvValue = WidgetValue selected,
_lvItems = _ddItems,
_lvItemToText = _ddItemToText,
_lvOnChange = [],
_lvOnChangeReq = [SendMessage path . OnChangeMessage]
}

View File

@ -1,6 +1,7 @@
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
module Monomer.Widget.Widgets.ListView (ListViewConfig(..), listView, listView_) where
@ -40,6 +41,8 @@ import Monomer.Widget.Widgets.Stack
data ListViewConfig s e a = ListViewConfig {
_lvValue :: WidgetValue s a,
_lvItems :: Seq a,
_lvItemToText :: a -> Text,
_lvOnChange :: [Int -> a -> e],
_lvOnChangeReq :: [Int -> WidgetRequest s]
}
@ -51,12 +54,12 @@ newtype ListViewState = ListViewState {
newtype ListViewMessage = OnClickMessage Int deriving Typeable
listView :: (Traversable t, Eq a) => ALens' s a -> t a -> (a -> Text) -> WidgetInstance s e
listView field items itemToText = listView_ config items itemToText where
config = ListViewConfig (WidgetLens field) [] []
listView_ :: (Traversable t, Eq a) => ListViewConfig s e a -> t a -> (a -> Text) -> WidgetInstance s e
listView_ config items itemToText = makeInstance (makeListView config newState newItems itemToText) where
listView field items itemToText = listView_ config where
config = ListViewConfig (WidgetLens field) newItems itemToText [] []
newItems = foldl' (|>) Empty items
listView_ :: (Eq a) => ListViewConfig s e a -> WidgetInstance s e
listView_ config = makeInstance (makeListView config newState) where
newState = ListViewState 0
makeInstance :: Widget s e -> WidgetInstance s e
@ -64,8 +67,8 @@ makeInstance widget = (defaultWidgetInstance "listView" widget) {
_instanceFocusable = True
}
makeListView :: (Eq a) => ListViewConfig s e a -> ListViewState -> Seq a -> (a -> Text) -> Widget s e
makeListView config state items itemToText = createContainer {
makeListView :: (Eq a) => ListViewConfig s e a -> ListViewState -> Widget s e
makeListView config state = createContainer {
_widgetInit = init,
_widgetGetState = makeState state,
_widgetMerge = containerMergeTrees merge,
@ -79,9 +82,9 @@ makeListView config state items itemToText = createContainer {
createListView wctx ctx newState widgetInstance = newInstance where
selected = currentValue wctx
itemsList = makeItemsList ctx items selected (_highlighted newState) itemToText
itemsList = makeItemsList config ctx selected (_highlighted newState)
newInstance = widgetInstance {
_instanceWidget = makeListView config newState items itemToText,
_instanceWidget = makeListView config newState,
_instanceChildren = Seq.singleton (scroll itemsList)
}
@ -99,7 +102,7 @@ makeListView config state items itemToText = createContainer {
handleHighlightNext wctx ctx widgetInstance = highlightItem wctx ctx widgetInstance nextIdx where
tempIdx = _highlighted state
nextIdx = if tempIdx < length items - 1 then tempIdx + 1 else tempIdx
nextIdx = if tempIdx < length (_lvItems config) - 1 then tempIdx + 1 else tempIdx
handleHighlightPrev wctx ctx widgetInstance = highlightItem wctx ctx widgetInstance nextIdx where
tempIdx = _highlighted state
@ -110,7 +113,7 @@ makeListView config state items itemToText = createContainer {
highlightItem wctx ctx widgetInstance nextIdx = Just $ widgetResult { _resultRequests = requests } where
newState = ListViewState nextIdx
newWidget = makeListView config newState items itemToText
newWidget = makeListView config newState
-- ListView's merge uses the old widget's state. Since we want the newly created state, the old widget is replaced here
oldInstance = widgetInstance {
_instanceWidget = newWidget
@ -123,14 +126,14 @@ makeListView config state items itemToText = createContainer {
selectItem wctx ctx widgetInstance idx = resultReqs requests newInstance where
selected = currentValue wctx
value = fromMaybe selected (Seq.lookup idx items)
value = fromMaybe selected (Seq.lookup idx (_lvItems config))
valueSetReq = widgetValueSet (_lvValue config) value
scrollToReq = itemScrollTo ctx widgetInstance idx
changeReqs = fmap ($ idx) (_lvOnChangeReq config)
requests = valueSetReq ++ scrollToReq ++ changeReqs
newState = ListViewState idx
newInstance = widgetInstance {
_instanceWidget = makeListView config newState items itemToText
_instanceWidget = makeListView config newState
}
itemScrollTo ctx widgetInstance idx = maybeToList (fmap makeScrollReq renderArea) where
@ -149,15 +152,15 @@ makeListView config state items itemToText = createContainer {
resize wctx viewport renderArea widgetInstance childrenPairs = (widgetInstance, assignedArea) where
assignedArea = Seq.singleton (viewport, renderArea)
makeItemsList :: (Eq a) => PathContext -> Seq a -> a -> Int -> (a -> Text) -> WidgetInstance s e
makeItemsList ctx items selected highlightedIdx itemToText = makeItemsList where
makeItemsList :: (Eq a) => ListViewConfig s e a -> PathContext -> a -> Int -> WidgetInstance s e
makeItemsList ListViewConfig{..} ctx selected highlightedIdx = makeItemsList where
path = _pathCurrent ctx
isSelected item = item == selected
selectedColor item = if isSelected item then Just gray else Nothing
highlightedColor idx = if idx == highlightedIdx then Just darkGray else Nothing
pairs = Seq.zip (Seq.fromList [0..length items]) items
pairs = Seq.zip (Seq.fromList [0..length _lvItems]) _lvItems
makeItemsList = vstack $ fmap (uncurry makeItem) pairs
makeItem idx item = container (config idx item) $ label (itemToText item)
makeItem idx item = container (config idx item) $ label (_lvItemToText item)
config idx item = def {
_ctOnClickReq = [SendMessage path (OnClickMessage idx)],
_ctBgColor = highlightedColor idx <|> selectedColor item,

View File

@ -26,16 +26,25 @@ import Monomer.Widget.Util
data ActiveBar = HBar | VBar deriving (Eq)
newtype ScrollMessage = ScrollTo Rect deriving Typeable
data ScrollConfig = ScrollConfig {
_scActiveBarColor :: Maybe Color,
_scIdleBarColor :: Maybe Color,
_scActiveThumbColor :: Color,
_scIdleThumbColor :: Color,
_scBarThickness :: Double,
_scWheelRate :: Double
}
data ScrollState = ScrollState {
_scDragging :: Maybe ActiveBar,
_scDeltaX :: !Double,
_scDeltaY :: !Double,
_scChildSize :: Size,
_scReqSize :: Tree SizeReq
_sstDragging :: Maybe ActiveBar,
_sstDeltaX :: !Double,
_sstDeltaY :: !Double,
_sstChildSize :: Size,
_sstReqSize :: Tree SizeReq
} deriving (Typeable)
newtype ScrollMessage = ScrollTo Rect deriving Typeable
data ScrollContext = ScrollContext {
hScrollRatio :: Double,
vScrollRatio :: Double,
@ -51,14 +60,28 @@ data ScrollContext = ScrollContext {
vThumbRect :: Rect
}
defaultState = ScrollState Nothing 0 0 def (singleNode def)
defaultScrollConfig = ScrollConfig {
_scActiveBarColor = Just $ darkGray { _alpha = 0.4 },
_scIdleBarColor = Nothing,
_scActiveThumbColor = gray,
_scIdleThumbColor = darkGray,
_scBarThickness = 10,
_scWheelRate = 10
}
barThickness = 10
stepSize = 50
wheelRate = 10
defaultState = ScrollState {
_sstDragging = Nothing,
_sstDeltaX = 0,
_sstDeltaY = 0,
_sstChildSize = def,
_sstReqSize = singleNode def
}
scroll :: WidgetInstance s e -> WidgetInstance s e
scroll managedWidget = makeInstance (makeScroll defaultState) managedWidget
scroll managedWidget = scroll_ defaultScrollConfig managedWidget
scroll_ :: ScrollConfig -> WidgetInstance s e -> WidgetInstance s e
scroll_ config managedWidget = makeInstance (makeScroll config defaultState) managedWidget
makeInstance :: Widget s e -> WidgetInstance s e -> WidgetInstance s e
makeInstance widget managedWidget = (defaultWidgetInstance "scroll" widget) {
@ -66,8 +89,8 @@ makeInstance widget managedWidget = (defaultWidgetInstance "scroll" widget) {
_instanceFocusable = False
}
makeScroll :: ScrollState -> Widget s e
makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
makeScroll :: ScrollConfig -> ScrollState -> Widget s e
makeScroll config state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
_widgetGetState = makeState state,
_widgetMerge = containerMergeTrees merge,
_widgetHandleEvent = containerHandleEvent handleEvent,
@ -82,22 +105,22 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
merge wctx ctx oldState widgetInstance = resultWidget newInstance where
newState = fromMaybe state (useState oldState)
newInstance = widgetInstance {
_instanceWidget = makeScroll newState
_instanceWidget = makeScroll config newState
}
handleEvent wctx ctx evt widgetInstance = case evt of
ButtonAction point btn status -> result where
isLeftPressed = status == PressedBtn && btn == LeftBtn
isButtonReleased = status == ReleasedBtn
isDragging = isJust $ _scDragging state
newState = if | isLeftPressed && hMouseInThumb && not isDragging -> state { _scDragging = Just HBar }
| isLeftPressed && vMouseInThumb && not isDragging -> state { _scDragging = Just VBar }
isDragging = isJust $ _sstDragging state
newState = if | isLeftPressed && hMouseInThumb && not isDragging -> state { _sstDragging = Just HBar }
| isLeftPressed && vMouseInThumb && not isDragging -> state { _sstDragging = Just VBar }
| isButtonReleased && hMouseInScroll && not isDragging -> updateScrollThumb state HBar point viewport sctx
| isButtonReleased && vMouseInScroll && not isDragging -> updateScrollThumb state VBar point viewport sctx
| isButtonReleased -> state { _scDragging = Nothing }
| isButtonReleased -> state { _sstDragging = Nothing }
| otherwise -> state
newInstance = widgetInstance {
_instanceWidget = makeScroll newState
_instanceWidget = makeScroll config newState
}
handledResult = Just $ resultReqs [IgnoreChildrenEvents] newInstance
result = if | isLeftPressed && (hMouseInThumb || vMouseInThumb) -> handledResult
@ -105,7 +128,7 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
| isButtonReleased && isDragging -> handledResult
| otherwise -> Nothing
Click point btn -> result where
isDragging = isJust $ _scDragging state
isDragging = isJust $ _sstDragging state
handledResult = Just $ resultReqs [IgnoreChildrenEvents] widgetInstance
result = if | hMouseInScroll || vMouseInScroll || isDragging -> handledResult
| otherwise -> Nothing
@ -117,17 +140,18 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
needsUpdate = (wx /= 0 && childWidth > vw) || (wy /= 0 && childHeight > vh)
result = if | needsUpdate -> Just $ resultReqs [IgnoreChildrenEvents] (rebuildWidget wctx newState widgetInstance prevReqs)
| otherwise -> Nothing
wheelRate = _scWheelRate config
stepX = wx * if wheelDirection == WheelNormal then -wheelRate else wheelRate
stepY = wy * if wheelDirection == WheelNormal then wheelRate else -wheelRate
newState = state {
_scDeltaX = scrollAxis stepX dx childWidth vw,
_scDeltaY = scrollAxis stepY dy childHeight vh
_sstDeltaX = scrollAxis stepX dx childWidth vw,
_sstDeltaY = scrollAxis stepY dy childHeight vh
}
_ -> Nothing
where
viewport = _instanceViewport widgetInstance
Rect vx vy vw vh = _instanceViewport widgetInstance
sctx@ScrollContext{..} = scrollStatus wctx state viewport
sctx@ScrollContext{..} = scrollStatus config wctx state viewport
scrollAxis reqDelta currScroll childPos viewportLimit
| reqDelta >= 0 = if currScroll + reqDelta < 0
@ -158,8 +182,8 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
| abs diffT <= abs diffB -> diffT + dy
| otherwise -> diffB + dy
newState = state {
_scDeltaX = scrollAxis stepX 0 childWidth vw,
_scDeltaY = scrollAxis stepY 0 childHeight vh
_sstDeltaX = scrollAxis stepX 0 childWidth vw,
_sstDeltaY = scrollAxis stepY 0 childHeight vh
}
newInstance = rebuildWidget wctx newState widgetInstance prevReqs
@ -173,10 +197,10 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
vDelta = (ry - py + vMid) / vScrollRatio
newDeltaX = if activeBar == HBar then scrollAxis hDelta 0 childWidth rw else dx
newDeltaY = if activeBar == VBar then scrollAxis vDelta 0 childHeight rh else dy
newState = state { _scDeltaX = newDeltaX, _scDeltaY = newDeltaY }
newState = state { _sstDeltaX = newDeltaX, _sstDeltaY = newDeltaY }
rebuildWidget wctx newState widgetInstance reqs = newInstance where
newWidget = makeScroll newState
newWidget = makeScroll config newState
tempInstance = widgetInstance { _instanceWidget = newWidget }
newInstance = scrollResize (Just newWidget) wctx (_instanceViewport tempInstance) (_instanceRenderArea tempInstance) tempInstance reqs
@ -194,7 +218,7 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
areaH = max h childHeight2
childRenderArea = Rect (l + dx) (t + dy) areaW areaH
newWidget = fromMaybe (makeScroll $ state { _scChildSize = Size areaW areaH, _scReqSize = reqs }) updatedWidget
newWidget = fromMaybe (makeScroll config $ state { _sstChildSize = Size areaW areaH, _sstReqSize = reqs }) updatedWidget
newChildWidget = _widgetResize (_instanceWidget child) wctx viewport childRenderArea child childReq
newInstance = widgetInstance {
@ -210,29 +234,31 @@ makeScroll state@(ScrollState dragging dx dy cs prevReqs) = createContainer {
containerRender defaultContainerRender renderer wctx ctx widgetInstance
resetScissor renderer
when (hScrollRequired && hMouseInScroll) $
drawRect renderer hScrollRect (Just barColor) Nothing
when (vScrollRequired && vMouseInScroll) $
drawRect renderer vScrollRect (Just barColor) Nothing
when hScrollRequired $
drawRect renderer hThumbRect (Just handleColorH) Nothing
drawRect renderer hScrollRect barColorH Nothing
when vScrollRequired $
drawRect renderer vThumbRect (Just handleColorV) Nothing
drawRect renderer vScrollRect barColorV Nothing
when hScrollRequired $
drawRect renderer hThumbRect (Just thumbColorH) Nothing
when vScrollRequired $
drawRect renderer vThumbRect (Just thumbColorV) Nothing
where
viewport = _instanceViewport widgetInstance
ScrollContext{..} = scrollStatus wctx state viewport
barColor = darkGray { _alpha = 0.4 }
draggingH = _scDragging state == Just HBar
draggingV = _scDragging state == Just VBar
handleColorH = if hMouseInThumb || draggingH then gray else darkGray
handleColorV = if vMouseInThumb || draggingV then gray else darkGray
ScrollContext{..} = scrollStatus config wctx state viewport
draggingH = _sstDragging state == Just HBar
draggingV = _sstDragging state == Just VBar
barColorH = if hMouseInScroll then _scActiveBarColor config else _scIdleBarColor config
barColorV = if vMouseInScroll then _scActiveBarColor config else _scIdleBarColor config
thumbColorH = if hMouseInThumb || draggingH then _scActiveThumbColor config else _scIdleThumbColor config
thumbColorV = if vMouseInThumb || draggingV then _scActiveThumbColor config else _scIdleThumbColor config
scrollStatus :: WidgetContext s e -> ScrollState -> Rect -> ScrollContext
scrollStatus wctx scrollState viewport = ScrollContext{..} where
scrollStatus :: ScrollConfig -> WidgetContext s e -> ScrollState -> Rect -> ScrollContext
scrollStatus config wctx scrollState viewport = ScrollContext{..} where
ScrollState _ dx dy (Size childWidth childHeight) _ = scrollState
barThickness = _scBarThickness config
mousePos = statusMousePos (_wcInputStatus wctx)
vpLeft = _rx viewport
vpTop = _ry viewport

View File

@ -30,7 +30,7 @@
- Reorganize drawing operations
- Stop, think and design
- How should all of this be organized?
- How should modules be layed out?
- How should modules be laid out?
- What are good interfaces for the different parts of the system?
- Does it make sense that handleEvent is the only pure function in a widget?
- Based on the previous design, refactor modules
@ -42,7 +42,7 @@
- Check if resize children still makes sense (maybe the widget itself can resize on the corresponding event?)
- Handle SetFocus request
- Check if WidgetState is really needed
- Maybe Data.Dynamic can be used, but currently abadoned
- Maybe Data.Dynamic can be used, but currently abandoned
- Rethink Tree.Path import
- Clean up Seq imports
- Where can we use Seq? Does it make sense to use it everywhere? What about Traversable?
@ -108,12 +108,13 @@
- Create nullable version which takes care of fmapping traversable with Just
- Check why vstack fails when using [spacer, listView]
- Remove status from Click event. Add ButtonPressed and ButtonReleased events
- Change order of parameters. We should always pass _old_ before _new_
- Pending
- Change order of parameters. We should always pass _old_ before _new_
- Unify criteria for instantiation
- Component name without underscore receives parameters positionally
- Component name with underscore receives Config instance
- Add renderer parameter to resize. It will be needed for auto adjustable Label and to handle ellipsis in text
- Should Resize be restored?
- Try to unify path handling on widgetFind and widgetNextFocusable
- This is also needed for _widgetPreferredSize and _widgetResize
@ -126,6 +127,7 @@
- Add support for dashed borders
- Create self rendered version of dropdown and list
- Show listview in appropriate location (if dropdown is at bottom, the listView should be up)
- Add config for Label to choose from: Overflow | Cut (better name?) | Ellipsis
- Create Checkbox
- Create Radio
- Create Slider