"SQR AlexJGriffith 2026 LGPL3+ A simple tool for placing rectangles relativly, and iterating over collections of collections. Place a rectangle at the top left of the screen: (let [(w h) (values 64 64) (x y) (place 0 0 w h :tl :tl)] (love.graphics.rectangle :line x y w h)) Drawing a 3 x 4 grid: (let [item-count 12 padding 10 grid-width 3 ox 0 oy 0 w 64 h 64 iter (grid-iter item-count padding grid-width ox oy w h :c :c)] (each [index x y iter] (love.graphics.rectangle :line x y w h))) " (local love (require :love)) (fn xy->position [x y w h position] (let [[ow oh] (. {:tl [0 0] :t [0.5 0] :tr [1 0] :r [1 0.5] :br [1 1] :b [0.5 1] :bl [0 1] :l [0 0.5] :c [0.5 0.5] :bottom-third [0.5 0.666]} position)] (values (+ x (* ow w)) (+ y (* oh h))))) (fn wh->alignment [w h alignment] (let [[ow oh] (. {:tl [0 0] :t [-0.5 0] :tr [-1 0] :r [-1 -0.5] :br [-1 -1] :b [-0.5 -1] :bl [0 -1] :l [0 -0.5] :c [-0.5 -0.5]} alignment)] (values (* ow w) (* oh h)))) (fn place [x y w h position alignment px? py? pw? ph?] (let [pw (or pw? (love.graphics.getWidth)) ph (or ph? (love.graphics.getHeight)) px (or px? 0) py (or py? 0) (x1 y1) (xy->position px py pw ph position) (x2 y2) (wh->alignment w h alignment)] (values (+ x x1 x2) (+ y y1 y2)))) (fn left-iter [count padding x y iw ih position alignment px? py? pw? ph?] (let [w (+ (* count iw) (* padding (math.max 0 (- count 1)))) h ih (x y) (place x y w h position alignment px? py? pw? ph?)] (var index 0) (values (fn [] (set index (+ index 1)) (when (<= index count) (values index (+ x (* (+ padding iw) (- index 1))) y))) w h))) (fn left-iter* [items padding x y position alignment px? py? pw? ph?] (let [count (# items) w (+ (accumulate [col 0 _ {: w} (ipairs items)] (+ col w)) (* padding (- count 1))) h (accumulate [max 0 _ {: h} (ipairs items)] (math.max max h)) (x y) (place x y w h position alignment px? py? pw? ph?)] (var index 0) (var ox x) (values (fn [] (set index (+ index 1)) (when (<= index count) (local pox ox) (set ox (+ pox padding (. items index :w))) (values index (. items index) pox y))) w h))) (fn down-iter [count padding x y iw ih position alignment px? py? pw? ph?] (let [w iw h (+ (* count ih) (* padding (math.max 0 (- count 1)))) (x y) (place x y w h position alignment px? py? pw? ph?)] (var index 0) (values (fn [] (set index (+ index 1)) (when (<= index count) (values index x (+ y (* (+ padding ih) (- index 1)))))) w h))) (fn down-iter* [items padding x y position alignment px? py? pw? ph?] (let [count (# items) w (accumulate [max 0 _ {: w} (ipairs items)] (math.max max w)) h (+ (accumulate [col 0 _ {: h} (ipairs items)] (+ col h)) (* padding (- count 1))) (x y) (place x y w h position alignment px? py? pw? ph?)] (var index 0) (var oy y) (values (fn [] (set index (+ index 1)) (when (<= index count) (local poy oy) (set oy (+ poy padding (. items index :h))) (values index (. items index) x poy))) w h))) (fn grid-iter [count padding grid-width x y iw ih position alignment px? py? pw? ph?] (let [w (+ (* grid-width iw) (* padding (- grid-width 1))) grid-height (math.ceil (/ count grid-width)) h (+ (* grid-height ih) (* padding (- grid-height 1))) (x y) (place x y w h position alignment px? py? pw? ph?)] (var index 0) (values (fn [] (set index (+ index 1)) (when (<= index count) (local i (% (- index 1) grid-width)) (local j (math.floor (/ (- index 1) grid-width))) (values index (+ x (* (+ padding iw) i)) (+ y (* (+ padding ih) j))))) w h))) (fn within [mx my x y w h] (and (> mx x) (<= mx (+ x w)) (> my y) (<= my (+ y h)))) {: place : within : left-iter : left-iter* : down-iter : down-iter* : grid-iter}