mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 23:49:45 -05:00
✨ Improved auto/flex size assignment
This commit is contained in:
parent
8671e9cf8a
commit
2177b7ae13
4 changed files with 86 additions and 42 deletions
|
@ -61,6 +61,18 @@
|
|||
(let [[pad-top pad-right pad-bottom pad-left] (ctl/paddings parent)]
|
||||
(gpo/pad-points shape-bounds pad-top pad-right pad-bottom pad-left)))
|
||||
|
||||
(defn child-min-width
|
||||
[child bounds]
|
||||
(if (ctl/fill-width? child)
|
||||
(ctl/child-min-width child)
|
||||
(gpo/width-points bounds)))
|
||||
|
||||
(defn child-min-height
|
||||
[child bounds]
|
||||
(if (ctl/fill-height? child)
|
||||
(ctl/child-min-height child)
|
||||
(gpo/height-points bounds)))
|
||||
|
||||
(defn calculate-initial-track-size
|
||||
[total-value {:keys [type value] :as track}]
|
||||
|
||||
|
@ -82,8 +94,8 @@
|
|||
|
||||
(let [[prop prop-span size-fn]
|
||||
(if (= type :column)
|
||||
[:column :column-span gpo/width-points]
|
||||
[:row :row-span gpo/height-points])]
|
||||
[:column :column-span child-min-width]
|
||||
[:row :row-span child-min-height])]
|
||||
|
||||
(reduce (fn [tracks [child-bounds child-shape]]
|
||||
(let [cell (get shape-cells (:id child-shape))
|
||||
|
@ -91,7 +103,7 @@
|
|||
track (get tracks idx)]
|
||||
(cond-> tracks
|
||||
(and (= (get cell prop-span) 1) (= :auto (:type track)))
|
||||
(update-in [idx :size] max (size-fn child-bounds)))))
|
||||
(update-in [idx :size] max (size-fn child-shape child-bounds)))))
|
||||
track-list
|
||||
children)))
|
||||
|
||||
|
@ -135,17 +147,28 @@
|
|||
(= :auto type)
|
||||
(assoc :size (min (+ size add-size) max-size)))))))
|
||||
|
||||
(defn has-flex-track?
|
||||
[type track-list cell]
|
||||
(let [[prop prop-span]
|
||||
(if (= type :column)
|
||||
[:column :column-span]
|
||||
[:row :row-span])
|
||||
from-idx (dec (get cell prop))
|
||||
to-idx (+ (dec (get cell prop)) (get cell prop-span))
|
||||
tracks (subvec track-list from-idx to-idx)]
|
||||
(some? (->> tracks (d/seek #(= :flex (:type %)))))))
|
||||
|
||||
(defn size-to-allocate
|
||||
[type parent [child-bounds _] cell]
|
||||
[type parent [child-bounds child] cell]
|
||||
(let [[row-gap column-gap] (ctl/gaps parent)
|
||||
[sfn gap prop-span]
|
||||
(if (= type :column)
|
||||
[gpo/width-points column-gap :column-span ]
|
||||
[gpo/height-points row-gap :row-span ])
|
||||
[child-min-width column-gap :column-span]
|
||||
[child-min-height row-gap :row-span])
|
||||
span (get cell prop-span)]
|
||||
(- (sfn child-bounds) (* gap (dec span)))))
|
||||
(- (sfn child child-bounds) (* gap (dec span)))))
|
||||
|
||||
(defn allocate-size
|
||||
(defn allocate-auto-tracks
|
||||
[allocations indexed-tracks to-allocate]
|
||||
(if (empty? indexed-tracks)
|
||||
allocations
|
||||
|
@ -158,11 +181,13 @@
|
|||
(/ to-allocate (count indexed-tracks))
|
||||
(:size track))
|
||||
(:size track))]
|
||||
(recur (cond-> allocations auto-track?
|
||||
(assoc idx allocated))
|
||||
(rest indexed-tracks) (- to-allocate allocated)))))
|
||||
(recur (cond-> allocations
|
||||
auto-track?
|
||||
(assoc idx allocated))
|
||||
(rest indexed-tracks)
|
||||
(- to-allocate allocated)))))
|
||||
|
||||
(defn allocate-flex
|
||||
(defn allocate-flex-tracks
|
||||
[allocations indexed-tracks to-allocate fr-value]
|
||||
(if (empty? indexed-tracks)
|
||||
allocations
|
||||
|
@ -196,29 +221,40 @@
|
|||
[:row :row-span])
|
||||
|
||||
;; First calculate allocation without applying so we can modify them on the following tracks
|
||||
allocate-auto-tracks
|
||||
allocated
|
||||
(->> shape-cells
|
||||
(vals)
|
||||
(filter #(> (get % prop-span) 1))
|
||||
(remove #(has-flex-track? type track-list %))
|
||||
(sort-by prop-span -)
|
||||
(reduce
|
||||
(fn [alloc cell]
|
||||
(fn [allocated cell]
|
||||
(let [shape-id (first (:shapes cell))
|
||||
|
||||
from-idx (dec (get cell prop))
|
||||
to-idx (+ (dec (get cell prop)) (get cell prop-span))
|
||||
|
||||
indexed-tracks (subvec (d/enumerate track-list) from-idx to-idx)
|
||||
has-flex? (->> indexed-tracks (d/seek #(= :flex (:type (second %)))) some?)
|
||||
to-allocate (size-to-allocate type parent (get children-map shape-id) cell)]
|
||||
(cond-> alloc
|
||||
;; skip cells with flex tracks
|
||||
(and (not has-flex?) (some? to-allocate))
|
||||
(allocate-size indexed-tracks to-allocate))))
|
||||
to-allocate (size-to-allocate type parent (get children-map shape-id) cell)
|
||||
|
||||
;; Remove the size and the tracks that are not allocated
|
||||
[to-allocate indexed-tracks]
|
||||
(->> indexed-tracks
|
||||
(reduce (fn find-auto-allocations
|
||||
[[to-allocate result] [_ track :as idx-track]]
|
||||
(if (= :auto (:type track))
|
||||
;; If auto, we don't change allocate and add the track
|
||||
[to-allocate (conj result idx-track)]
|
||||
;; If fixed, we remove from allocate and don't add the track
|
||||
[(- to-allocate (:size track)) result]))
|
||||
[to-allocate []]))]
|
||||
(allocate-auto-tracks allocated indexed-tracks (max to-allocate 0))))
|
||||
{}))
|
||||
|
||||
;; Apply the allocations to the tracks
|
||||
track-list
|
||||
(into []
|
||||
(map-indexed #(update %2 :size max (get allocate-auto-tracks %1)))
|
||||
(map-indexed #(update %2 :size max (get allocated %1)))
|
||||
track-list)]
|
||||
track-list))
|
||||
|
||||
|
@ -235,6 +271,7 @@
|
|||
(->> shape-cells
|
||||
(vals)
|
||||
(filter #(> (get % prop-span) 1))
|
||||
(filter #(has-flex-track? type track-list %))
|
||||
(sort-by prop-span -)
|
||||
(reduce
|
||||
(fn [alloc cell]
|
||||
|
@ -242,20 +279,25 @@
|
|||
from-idx (dec (get cell prop))
|
||||
to-idx (+ (dec (get cell prop)) (get cell prop-span))
|
||||
indexed-tracks (subvec (d/enumerate track-list) from-idx to-idx)
|
||||
has-flex? (->> indexed-tracks (d/seek #(= :auto (:type (second %)))) some?)
|
||||
total-frs (->> indexed-tracks (reduce (fn [tot [_ {:keys [type value]}]]
|
||||
(cond-> tot
|
||||
(= type :flex)
|
||||
(+ value)))
|
||||
0))
|
||||
|
||||
|
||||
to-allocate (size-to-allocate type parent (get children-map shape-id) cell)
|
||||
fr-value (when (some? to-allocate) (/ to-allocate total-frs))]
|
||||
(cond-> alloc
|
||||
;; skip cells with no flex tracks
|
||||
(and has-flex? (some? to-allocate))
|
||||
(allocate-flex indexed-tracks to-allocate fr-value))))
|
||||
|
||||
;; Remove the size and the tracks that are not allocated
|
||||
[to-allocate total-frs indexed-tracks]
|
||||
(->> indexed-tracks
|
||||
(reduce (fn find-lex-allocations
|
||||
[[to-allocate total-fr result] [_ track :as idx-track]]
|
||||
(if (= :flex (:type track))
|
||||
;; If flex, we don't change allocate and add the track
|
||||
[to-allocate (+ total-fr (:value track)) (conj result idx-track)]
|
||||
|
||||
;; If fixed or auto, we remove from allocate and don't add the track
|
||||
[(- to-allocate (:size track)) total-fr result]))
|
||||
[to-allocate 0 []]))
|
||||
|
||||
to-allocate (max to-allocate 0)
|
||||
fr-value (/ to-allocate total-frs)]
|
||||
(allocate-flex-tracks alloc indexed-tracks to-allocate fr-value)))
|
||||
{}))
|
||||
|
||||
;; Apply the allocations to the tracks
|
||||
|
@ -305,7 +347,6 @@
|
|||
column-tracks (set-auto-base-size column-tracks children shape-cells :column)
|
||||
row-tracks (set-auto-base-size row-tracks children shape-cells :row)
|
||||
|
||||
|
||||
;; Adjust multi-spaned cells with no flex columns
|
||||
column-tracks (set-auto-multi-span parent column-tracks children-map shape-cells :column)
|
||||
row-tracks (set-auto-multi-span parent row-tracks children-map shape-cells :row)
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
(as-> p1 $
|
||||
(reduce (fn [p track] (gpt/add p (vv (:size track)))) $ span-row-tracks)
|
||||
(gpt/add $ (vv (* row-gap (dec (count span-row-tracks))))))]
|
||||
|
||||
[p1 p2 p3 p4]))
|
||||
|
||||
(defn calc-fill-width-data
|
||||
|
@ -152,6 +153,7 @@
|
|||
(-> position-delta
|
||||
(gpt/add (gpt/to-vec from-h to-h))
|
||||
(gpt/add (gpt/to-vec from-v to-v)))]
|
||||
|
||||
(-> (ctm/empty)
|
||||
(ctm/add-modifiers fill-modifiers)
|
||||
(ctm/move position-delta))))
|
||||
|
|
|
@ -320,28 +320,28 @@
|
|||
[child]
|
||||
(if (and (fill-width? child)
|
||||
(some? (:layout-item-min-w child)))
|
||||
(max 0 (:layout-item-min-w child))
|
||||
0))
|
||||
(max 0.01 (:layout-item-min-w child))
|
||||
0.01))
|
||||
|
||||
(defn child-max-width
|
||||
[child]
|
||||
(if (and (fill-width? child)
|
||||
(some? (:layout-item-max-w child)))
|
||||
(max 0 (:layout-item-max-w child))
|
||||
(max 0.01 (:layout-item-max-w child))
|
||||
##Inf))
|
||||
|
||||
(defn child-min-height
|
||||
[child]
|
||||
(if (and (fill-height? child)
|
||||
(some? (:layout-item-min-h child)))
|
||||
(max 0 (:layout-item-min-h child))
|
||||
0))
|
||||
(max 0.01 (:layout-item-min-h child))
|
||||
0.01))
|
||||
|
||||
(defn child-max-height
|
||||
[child]
|
||||
(if (and (fill-height? child)
|
||||
(some? (:layout-item-max-h child)))
|
||||
(max 0 (:layout-item-max-h child))
|
||||
(max 0.01 (:layout-item-max-h child))
|
||||
##Inf))
|
||||
|
||||
(defn child-margins
|
||||
|
|
|
@ -357,8 +357,9 @@
|
|||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dc/detach-comment-thread ids)
|
||||
(dch/commit-changes changes)
|
||||
(ptk/data-event :layout/update all-parents)
|
||||
(dwu/commit-undo-transaction undo-id))))
|
||||
(dwu/commit-undo-transaction undo-id)
|
||||
(ptk/data-event :layout/update all-parents))))
|
||||
|
||||
|
||||
(defn create-and-add-shape
|
||||
[type frame-x frame-y data]
|
||||
|
|
Loading…
Add table
Reference in a new issue