package tiny_appkits
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Application engines from scratch: a spreadsheet, rich text, paint, draw, CAD, editors and more
Install
dune-project
Dependency
Authors
Maintainers
Sources
0.3.6.tar.gz
md5=7c636383d146d30ac6f2fa234a6253c8
sha512=c79f3823c5f8f57e5038eb640d487c61168b84aa07c61999d6622ef9fd0c890e2b03b4c6a7cdbbe9352a49e25dda00ac7bb14693cee8e3d7beeed251351a2af0
doc/src/tiny_appkits.browser_layout/Flex_layout.ml.html
Source file Flex_layout.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135(* Claude Code * * Copyright (C) 2026 Yoann Padioleau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License * (LGPL) as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. *) (* See Flex_layout.mli *) type item = { base : float; grow : float; shrink : float; min_size : float; max_size : float; auto_before : bool; auto_after : bool; } let clamp (it : item) (size : float) : float = Float.max it.min_size (Float.min it.max_size size) (*****************************************************************************) (* Lines *) (*****************************************************************************) let lines ~(wrap : bool) ~(room : float) ~(gap : float) (items : item array) : (int * int) list = let n = Array.length items in if n = 0 then [] else if not wrap then [ (0, n - 1) ] else (* each line as many as fit, at least one *) let rec go start acc = if start >= n then List.rev acc else let rec extend j used = if j + 1 < n && used +. gap +. clamp items.(j + 1) items.(j + 1).base <= room then extend (j + 1) (used +. gap +. clamp items.(j + 1) items.(j + 1).base) else j in let j = extend start (clamp items.(start) items.(start).base) in go (j + 1) ((start, j) :: acc) in go 0 [] (*****************************************************************************) (* Resolving flexible lengths (section 9.7) *) (*****************************************************************************) let resolve ~(room : float) ~(gap : float) (items : item array) : float array = let n = Array.length items in let gaps = gap *. float_of_int (max 0 (n - 1)) in let growing = room -. gaps -. Array.fold_left (fun s it -> s +. clamp it it.base) 0. items >= 0. in (* an item that cannot flex this way is frozen at its base from the * start *) let frozen = Array.map (fun it -> if growing then it.grow = 0. else it.shrink = 0.) items in let sizes = Array.map (fun it -> clamp it it.base) items in let rec loop () = if Array.exists not frozen then ( let free = ref (room -. gaps) and grow = ref 0. and scaled = ref 0. in Array.iteri (fun i it -> if frozen.(i) then free := !free -. sizes.(i) else ( free := !free -. it.base; grow := !grow +. it.grow; scaled := !scaled +. (it.shrink *. it.base))) items; (* grow factors summing to less than 1 take only that part *) let free = if growing && !grow < 1. then !free *. !grow else !free in let target = Array.mapi (fun i it -> if frozen.(i) then sizes.(i) else if growing then if !grow > 0. then it.base +. (free *. it.grow /. !grow) else it.base else if !scaled > 0. then it.base +. (free *. it.shrink *. it.base /. !scaled) else it.base) items in (* clamped by min and max: the violations decide who is frozen *) let total = ref 0. in let clamped = Array.mapi (fun i it -> if frozen.(i) then sizes.(i) else clamp it target.(i)) items in Array.iteri (fun i _ -> if not frozen.(i) then total := !total +. (clamped.(i) -. target.(i))) items; if Float.abs !total < 1e-9 then Array.iteri (fun i _ -> if not frozen.(i) then (sizes.(i) <- clamped.(i); frozen.(i) <- true)) items else ( Array.iteri (fun i _ -> let v = clamped.(i) -. target.(i) in if (not frozen.(i)) && ((!total > 0. && v > 0.) || (!total < 0. && v < 0.)) then ( sizes.(i) <- clamped.(i); frozen.(i) <- true)) items; loop ())) in loop (); sizes (*****************************************************************************) (* Placing *) (*****************************************************************************) let place ~(justify : Computed.align) ~(room : float) ~(gap : float) (items : item array) (sizes : float array) : float array = let n = Array.length items in let used = Array.fold_left ( +. ) 0. sizes +. (gap *. float_of_int (max 0 (n - 1))) in let left = Float.max 0. (room -. used) in let autos = Array.fold_left (fun k it -> k + (if it.auto_before then 1 else 0) + if it.auto_after then 1 else 0) 0 items in (* the room left before the first, and between two *) let first, between = if autos > 0 then (0., 0.) else match justify with | End -> (left, 0.) | Center -> (left /. 2., 0.) | Space_between -> (0., if n > 1 then left /. float_of_int (n - 1) else 0.) | Space_around -> (left /. float_of_int (2 * n), left /. float_of_int n) | Space_evenly -> (left /. float_of_int (n + 1), left /. float_of_int (n + 1)) | Start | Stretch | Align_baseline -> (0., 0.) in let per_auto = if autos > 0 then left /. float_of_int autos else 0. in let pos = ref first in Array.mapi (fun i it -> if it.auto_before then pos := !pos +. per_auto; let at = !pos in pos := !pos +. sizes.(i) +. gap +. between +. if it.auto_after then per_auto else 0.; at) items let cross ~(align : Computed.align) ~(line : float) ~(size : float) : float * float = match align with | End -> (line -. size, size) | Center -> ((line -. size) /. 2., size) | Stretch -> (0., Float.max size line) | Start | Align_baseline | Space_between | Space_around | Space_evenly -> (0., size)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>