This module is an implementation of picker by scrolling and basic view type is elm-ui.
and animation can be done a bit tricky but easily thanks to elm-style-animation.
Due to some non-standard way to hiding scrollbar, elm-css is also required.
Picker direction
this type is for general use, and also used in the picker shading part from the beginning and the end.
Option record for each item in the list which we need to decide to choose this record depends on the type of value and element (Element)
Msg chain generally covers the following steps
1. Detect any scroll which has delayed 'Cmd' to check whether
scrolling is stopped or not.
2. If scroll stopped, trigger snapping to nearst item.
3. Find and decide which item will be target to snap.
4. Do animation related to snapping
5. Inform the snapping is done so outside world is able to know the
which item(Option) is selected.Unfortunately we need own Msg here which means you might need to
map over those message into your own Msg type
There are examples in this module regarding message mapping
you could possibly search keyword 'messageMap' where I need to map the
Msg' into msg'
Error used for Task x a
XXX: this module doesn't really analyse the error status very well, but those data types are only used to explain the code what happened now and explain the reason to stop the task.
Helper function to initialise the minimal model. You can call
setOptions after this.
initMinimalState "myPicker"
|> setOptions
String.fromInt
[ ( 1, Element.text "1" )
, ( 2, Element.text "2" )
...
save options from the list of pair of ( data, Element ) option Ids are stored separately and details stored in a Dict there is no way to know how to make data value to string you should suggest the function (vt -> String)
get a list of Option record data from the whole model by searching option ID in a ditionary in the same order of optionID list
Every scroll is being watched to check whether it is stopped at the moment and this function will change the timing to wait until checking.
Limitation: minimum value is 75 (ms). Animation will fail or work unexpectedly under 75 ms.
Check the Msg, and return if there is any new selected option
updateWith function needs your own app model to ask messageMapWith and
pickerDirection from the model. So if you want to use multiple picker,
you can keep the same information in the same place.
As other update function supposed to do, updateWith also does the job
described in the Msg
Passing our 'Animation.Messenger.State msg' through subscriptions from elm-style-animation. because it involves with animation otherwise animation will not work at all!
Generating Element with theme setting and state value each function only try to some state value in the whole record so if you can apply this funciton with additional state you might want to use. BaseTheme DOES NOT use all the color in the Palette. the Colors used in the theme are 'accent', 'surface', 'background' 'on.background', 'on.surface'.
...This means the color listed above are should be in your own palette at least, even though if you are using your own color accessor(function).
All setting values are set to Theme.Default, which can be applied to
scrollPicker function. please see exampleView.
An example settings value type in use here
More settings for 'view' and 'defaultShadeAttrsWith' mainly
because that picker has Direction
make option id string value for 'Option.idString'
minimal testing function if the picker is snapping to some item at the moment
reset some states for runtime to stop snapping which includes current target, scroll position to snap to, clock when scroll happened etc.
Note: this function only try to stop snapping but asynchronous messasing will produce more animation after calling this function, so keep in mind that animation for snapping is not guaranteed to be done even if call this function in `model' part.
You can test any value -- even under 75 ms -- however which is not recommended
Takes the direction of picker and gives the shade length
and helper function for shade attributes for elm-ui
Generate setting values for a picker which has Direction
geometry data type which can be seen in 'Browser.Dom.Viewport'
Browser.Dom.Viewport, Browser.Dom.Element share basic record accessor like .x .y .width .height getCenterPosOf function try to get center poistion of the some field
ex) to get center 'y' position of viewport, you can try
getCenterPosOf .y .height .viewport aRecordwhen all the items are distributed uniformly, it might be easier to get the option to focus(for snapping). partitionOptions will provide one candidate to snap and previous options prior to current one and next options as well. Calulating relative position in Viewport probably be only way to test whether the target is correct one or not, however you might need to check around current candidate.
To get relative position of element in the viewport.
you need to apply position accessor and length accessor which are normally
.x and .width for Horizontal scroll picker and .y and .height for
Vertical scroll picker.
Note: the element is got from getElement, viewport is got from getViewport
A Task helper function to get relative distance of the item from frame which is measured from the center position of each other. This value has sign -- negtative value shows that the item is left or above the centre of view frame
Task helper to get viewport of the item id.
Task helper to retreive the position. posAccessor
An utility which converts an floating value to an integer value which contains upto milli of base unit (pixel in this case)
An utility which converts an integer value(which contains up to thousandth value of original) to an float value.
- add keyboard input support
Provide Minimal model (or state) to work with. most of funciton in this module works well with your own record type generally, as I used more generic type constraint in function definition
Note: elm-style-animation module doesn't supply low-level functions to get intermediate states of animation so I need more research but now I'm using renderPairs function to get the states of current values in 'String' format which will be traslated into number. Even though one state value is used, I need to use Animation.style function to generate the state which can contain a lot more information