Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file partial_render_list_intf.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197open!Coreopen!ImportopenUtilmoduleInterval=structtype'at=|Empty|Rangeof'a*'a[@@derivingcompare,sexp]endmoduleMeasurements=structtypet={list_rect:floatJs_misc.Rect.t;view_rect:floatJs_misc.Rect.t}[@@derivingcompare,sexp]endmoduletypeKey=sigtypet[@@derivingsexp,compare]includeComparable.Swithtypet:=tend(** [Row_id.t] is used to uniquely identify rows, while [Sort_key.t] is used to sort them.
If the order of your rows frequently changes, you can use [Row_id.t] to uniquely
identify a row even as its [Sort_key.t] value changes.
This is useful for preserving the measured heights in [Height_cache] as row values
change, causing rows to get reordered.
In simple cases, [Row_id] and [Sort_key] can be the same (use [Make_simple] for this).
*)moduletypeRow_id=KeymoduletypeSort_key=sigincludeKeytyperow_idvalrow_id:t->row_idend(** [Partial_render_list] provides common functionality for partially rendering large (e.g
10_000 rows) lists or tables. It allows apps to measure and cache the height of each
row and incrementally compute which rows to show while scrolling. It puts spacers
above and below the viewport so that the list element remains the same height with
only as many rendered rows as necessary to fill the viewport. This approach allows
high data change rates because it doesn't change the dom for rows that are not in
view.
Because of the height cache your rows don't all have to be the same height. It is fine
if some rows have more data or the editing UI is taller than a display row.
See lib/incr_dom/examples/ts_gui for a demonstration of how to use of this module.
*)moduletypeS=sigmoduleRow_id:KeymoduleSort_key:Key(** Height_cache keeps track of the rendered height of items so that scrolling
to a given position can decide which elements to render accurately. This allows
rows to have different heights and change height at runtime.
It only caches heights for rows that are currently in the list with a given key, so
items will be dropped on changing a filter or sort, but this is only noticeable if
the height guess is wrong and the user is paying very close attention to consistency
of scroll positions.
The [height_guess] parameter is the default height in pixels returned for any item
that is not in the cache. Rows that are measured to be exactly [height_guess] tall
will not even be added to the cache. If most of your rows are a certain size you
should determine the exact height returned to [measure_heights] in the typical case
and use that as your guess.
*)moduleHeight_cache:sigtypet[@@derivingcompare,sexp_of]valempty:height_guess:float->t(** [height t key] will return the actual height of [key] if available, otherwise it
returns [height_guess] *)valheight:t->Row_id.t->floatend(** Meant to be stored in the derived model *)type'vtvalcreate:rows:'vSort_key.Map.tIncr.t->height_cache:Height_cache.tIncr.t->measurements:Measurements.toptionIncr.t->'vtIncr.tvalmeasurements:_t->Measurements.toptionvalfind_by_position:_t->position:float->Sort_key.toption(** [find_by_relative_position t key ~offset] returns the key at a distance of
approximately [offset] away from [key], preferring closer elements to farther ones.
If the offset extends past the end of the list, the end key is returned instead. *)valfind_by_relative_position:_t->Sort_key.t->offset:float->Sort_key.toptionvalfocus_offset_to_position:_t->Sort_key.t->offset:float->float(** Meant for rendering, apps should normally use Incr.Map.mapi' on this *)valrows_to_render:'vt->'vSort_key.Map.t(** (top, bottom) spacer pixel heights to put the rendered rows in the right place *)valspacer_heights:_tIncr.t->(float*float)Incr.t(** Scroll the view to the row with the given key, scrolling the minimum amount possible
while still being [(top|bottom)_margin] pixels away from the top and bottom of the
screen. If this can't be satisfied, the margin will be reduced to the point where it
can. If a margin of 0 can't show the whole element, it will prefer showing the top.
[?in] determines the element which should be scrolled. Default is `Window *)valscroll_into_scroll_region:?in_:Scroll_region.t->_t->top_margin:float->bottom_margin:float->key:Sort_key.t->Scroll_result.tvalscroll_to_position:?in_:Scroll_region.t->_t->position:float->key:Sort_key.t->Scroll_result.tvalscroll_to_position_and_into_region:?in_:Scroll_region.t->_t->position:float->top_margin:float->bottom_margin:float->key:Sort_key.t->Scroll_result.t(** [is_in_region] and [get_position] return [None] if the given key does not exist or
the view rect and list rect measurements are not yet available. *)valis_in_region:_t->top_margin:float->bottom_margin:float->key:Sort_key.t->booloptionvalget_position:_t->key:Sort_key.t->floatoptionvalget_top_and_bottom:_t->key:Sort_key.t->(float*float)option(** [measure_heights_simple] updates a height cache by measuring the rendered elements,
relying on the app to provide a function for finding and measuring the element for a
given key.
This function can be used for table with collapsed borders and box sizing set to
border-box.
*)valmeasure_heights_simple:_t->measure:(Sort_key.t->floatoption)->Height_cache.t(** [measure_heights] is like [measure_heights_simple], but allows the app to use the
previous and next rows in addition to the current row to measure the current row's
height (e.g. using the bottom position of the previous row and/or the top position
of the next row).
To avoid retaking the same measures three times for each row (once as the "previous"
row, once as the "current" row, and once as the "next" row), [measure_row] allows
the app to specify what measurements to take for a given row, and it is called
exactly once per row.
This function should be used for tables with non-collapsed borders.
*)valmeasure_heights:_t->measure_row:(Sort_key.t->'moption)->get_row_height:(prev:'moption->curr:'moption->next:'moption->floatoption)->Height_cache.tendmoduletypePartial_render_list=sigmoduletypeS=SmoduletypeRow_id=Row_idmoduletypeSort_key=Sort_keymoduleInterval=IntervalmoduleMeasurements=MeasurementsmoduleMake(Row_id:Row_id)(Sort_key:Sort_keywithtyperow_id:=Row_id.t):SwithmoduleRow_id=Row_idandmoduleSort_key=Sort_keymoduleMake_simple(Row_id:Row_id):SwithmoduleRow_id=Row_idandmoduleSort_key=Row_idend