0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-15 00:12:33 -05:00

Review changes

This commit is contained in:
alonso.torres 2022-11-10 14:55:13 +01:00
parent 6e35b5c6b6
commit 4c5e8f42ce
7 changed files with 245 additions and 209 deletions

View file

@ -105,9 +105,8 @@
(child-layout-bound-points parent child)
points))]
(as-> children $
(mapcat child-bounds $)
(gco/transform-points $ (gco/center-shape parent) (:transform-inverse parent))
(gre/squared-points $)
(gpo/pad-points $ (- pad-top) (- pad-right) (- pad-bottom) (- pad-left))
(gre/points->rect $))))
(-> (mapcat child-bounds children)
(gco/transform-points (gco/center-shape parent) (:transform-inverse parent))
(gre/squared-points)
(gpo/pad-points (- pad-top) (- pad-right) (- pad-bottom) (- pad-left))
(gre/points->rect))))

View file

@ -8,16 +8,71 @@
(:require
[app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.common :as gco]
[app.common.geom.shapes.flex-layout.lines :as fli]
[app.common.geom.shapes.rect :as gsr]
[app.common.pages.helpers :as cph]
[app.common.types.shape.layout :as ctl]))
(defn layout-drop-areas
"Retrieve the layout drop areas to move shapes inside layouts"
[{:keys [margin-x margin-y] :as frame} layout-data children]
(defn drop-child-areas
[{:keys [transform-inverse] :as frame} parent-rect child index reverse? prev-x prev-y last?]
(let [col? (ctl/col? frame)
row? (ctl/row? frame)
[layout-gap-row layout-gap-col] (ctl/gaps frame)
start-p (-> child :points first)
center (gco/center-shape frame)
start-p (gmt/transform-point-center start-p center transform-inverse)
box-x (:x start-p)
box-y (:y start-p)
box-width (-> child :selrect :width)
box-height (-> child :selrect :height)
x (if col? (:x parent-rect) prev-x)
y (if row? (:y parent-rect) prev-y)
width
(cond
(and row? last?)
(- (+ (:x parent-rect) (:width parent-rect)) x)
col?
(:width parent-rect)
:else
(+ box-width (- box-x prev-x) (/ layout-gap-row 2)))
height
(cond
(and col? last?)
(- (+ (:y parent-rect) (:height parent-rect)) y)
row?
(:height parent-rect)
:else
(+ box-height (- box-y prev-y) (/ layout-gap-col 2)))]
(if row?
(let [half-point-width (+ (- box-x x) (/ box-width 2))]
[(gsr/make-rect x y width height)
(-> (gsr/make-rect x y half-point-width height)
(assoc :index (if reverse? (inc index) index)))
(-> (gsr/make-rect (+ x half-point-width) y (- width half-point-width) height)
(assoc :index (if reverse? index (inc index))))])
(let [half-point-height (+ (- box-y y) (/ box-height 2))]
[(gsr/make-rect x y width height)
(-> (gsr/make-rect x y width half-point-height)
(assoc :index (if reverse? (inc index) index)))
(-> (gsr/make-rect x (+ y half-point-height) width (- height half-point-height))
(assoc :index (if reverse? index (inc index))))]))))
(defn drop-line-area
[{:keys [transform-inverse margin-x margin-y] :as frame}
{:keys [start-p layout-gap-row layout-gap-col num-children line-width line-height] :as line-data}
prev-x prev-y last?]
(let [col? (ctl/col? frame)
row? (ctl/row? frame)
@ -25,138 +80,108 @@
h-end? (and row? (ctl/h-end? frame))
v-center? (and col? (ctl/v-center? frame))
v-end? (and row? (ctl/v-end? frame))
reverse? (:reverse? layout-data)
[layout-gap-row layout-gap-col] (ctl/gaps frame)
center (gco/center-shape frame)
start-p (gmt/transform-point-center start-p center transform-inverse)
children (vec (cond->> (d/enumerate children)
reverse? reverse))
line-width
(if row?
(:width frame)
(+ line-width margin-x
(if row? (* layout-gap-row (dec num-children)) 0)))
redfn-child
(fn [[result parent-rect prev-x prev-y] [[index child] next]]
(let [prev-x (or prev-x (:x parent-rect))
prev-y (or prev-y (:y parent-rect))
line-height
(if col?
(:height frame)
(+ line-height margin-y
(if col?
(* layout-gap-col (dec num-children))
0)))
last? (nil? next)
box-x
(- (:x start-p)
(cond
h-center? (/ line-width 2)
h-end? line-width
:else 0))
start-p (gpt/point (:selrect child))
start-p (-> start-p
(gmt/transform-point-center (gco/center-shape child) (:transform frame))
(gmt/transform-point-center (gco/center-shape frame) (:transform-inverse frame)))
box-y
(- (:y start-p)
(cond
v-center? (/ line-height 2)
v-end? line-height
:else 0))
box-x (:x start-p)
box-y (:y start-p)
box-width (-> child :selrect :width)
box-height (-> child :selrect :height)
x (if row? (:x frame) prev-x)
y (if col? (:y frame) prev-y)
x (if col? (:x parent-rect) prev-x)
y (if row? (:y parent-rect) prev-y)
width (cond
(and col? last?)
(- (+ (:x frame) (:width frame)) x)
width (cond
(and row? last?)
(- (+ (:x parent-rect) (:width parent-rect)) x)
row?
(:width frame)
col?
(:width parent-rect)
:else
(+ line-width (- box-x prev-x) (/ layout-gap-row 2)))
:else
(+ box-width (- box-x prev-x) (/ layout-gap-row 2)))
height (cond
(and row? last?)
(- (+ (:y frame) (:height frame)) y)
height (cond
(and col? last?)
(- (+ (:y parent-rect) (:height parent-rect)) y)
col?
(:height frame)
row?
(:height parent-rect)
:else
(+ line-height (- box-y prev-y) (/ layout-gap-col 2)))]
(gsr/make-rect x y width height)))
:else
(+ box-height (- box-y prev-y) (/ layout-gap-col 2)))
(defn layout-drop-areas
"Retrieve the layout drop areas to move shapes inside layouts"
[frame layout-data children]
[line-area-1 line-area-2]
(if row?
(let [half-point-width (+ (- box-x x) (/ box-width 2))]
[(-> (gsr/make-rect x y half-point-width height)
(assoc :index (if reverse? (inc index) index)))
(-> (gsr/make-rect (+ x half-point-width) y (- width half-point-width) height)
(assoc :index (if reverse? index (inc index))))])
(let [half-point-height (+ (- box-y y) (/ box-height 2))]
[(-> (gsr/make-rect x y width half-point-height)
(assoc :index (if reverse? (inc index) index)))
(-> (gsr/make-rect x (+ y half-point-height) width (- height half-point-height))
(assoc :index (if reverse? index (inc index))))]))
(let [reverse? (:reverse? layout-data)
children (vec (cond->> (d/enumerate children) reverse? reverse))
lines (:layout-lines layout-data)]
result (conj result line-area-1 line-area-2)]
(loop [areas []
from-idx 0
prev-line-x (:x frame)
prev-line-y (:y frame)
[result parent-rect (+ x width) (+ y height)]))
current-line (first lines)
lines (rest lines)]
redfn-lines
(fn [[result from-idx prev-x prev-y] [{:keys [start-p layout-gap-row layout-gap-col num-children line-width line-height]} next]]
(let [start-p (gmt/transform-point-center start-p (gco/center-shape frame) (:transform-inverse frame))
(if (nil? current-line)
areas
prev-x (or prev-x (:x frame))
prev-y (or prev-y (:y frame))
last? (nil? next)
(let [line-area (drop-line-area frame current-line prev-line-x prev-line-y (nil? (first lines)))
children (subvec children from-idx (+ from-idx (:num-children current-line)))
line-width
(if row?
(:width frame)
(+ line-width margin-x
(if row? (* layout-gap-row (dec num-children)) 0)))
next-areas
(loop [areas areas
prev-child-x (:x line-area)
prev-child-y (:y line-area)
[index child] (first children)
children (rest children)]
line-height
(if col?
(:height frame)
(+ line-height margin-y
(if col?
(* layout-gap-col (dec num-children))
0)))
(if (nil? child)
areas
box-x
(- (:x start-p)
(cond
h-center? (/ line-width 2)
h-end? line-width
:else 0))
(let [[child-area child-area-start child-area-end]
(drop-child-areas frame line-area child index reverse? prev-child-x prev-child-y (nil? (first children)))]
(recur (conj areas child-area-start child-area-end)
(+ (:x child-area) (:width child-area))
(+ (:y child-area) (:height child-area))
(first children)
(rest children)))))]
box-y
(- (:y start-p)
(cond
v-center? (/ line-height 2)
v-end? line-height
:else 0))
x (if row? (:x frame) prev-x)
y (if col? (:y frame) prev-y)
width (cond
(and col? last?)
(- (+ (:x frame) (:width frame)) x)
row?
(:width frame)
:else
(+ line-width (- box-x prev-x) (/ layout-gap-row 2)))
height (cond
(and row? last?)
(- (+ (:y frame) (:height frame)) y)
col?
(:height frame)
:else
(+ line-height (- box-y prev-y) (/ layout-gap-col 2)))
line-area (gsr/make-rect x y width height)
children (subvec children from-idx (+ from-idx num-children))
result (first (reduce redfn-child [result line-area] (d/with-next children)))]
[result (+ from-idx num-children) (+ x width) (+ y height)]))]
(first (reduce redfn-lines [[] 0] (d/with-next (:layout-lines layout-data))))))
(recur next-areas
(+ from-idx (:num-children current-line))
(+ (:x line-area) (:width line-area))
(+ (:y line-area) (:height line-area))
(first lines)
(rest lines)))))))
(defn get-drop-index
[frame-id objects position]

View file

@ -37,71 +37,79 @@
(or row? (not (ctl/auto-height? shape))))
[layout-gap-row layout-gap-col] (ctl/gaps shape)
layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds)
calculate-line-data
(fn [[{:keys [line-min-width line-min-height
layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds)]
(loop [line-data nil
result []
child (first children)
children (rest children)]
(if (nil? child)
(cond-> result (some? line-data) (conj line-data))
(let [{:keys [line-min-width line-min-height
line-max-width line-max-height
num-children
children-data] :as line-data} result] child]
children-data]} line-data
(let [child-bounds (gst/parent-coords-points child shape)
child-width (gpo/width-points child-bounds)
child-height (gpo/height-points child-bounds)
child-min-width (ctl/child-min-width child)
child-min-height (ctl/child-min-height child)
child-max-width (ctl/child-max-width child)
child-max-height (ctl/child-max-height child)
child-bounds (gst/parent-coords-points child shape)
child-width (gpo/width-points child-bounds)
child-height (gpo/height-points child-bounds)
child-min-width (ctl/child-min-width child)
child-min-height (ctl/child-min-height child)
child-max-width (ctl/child-max-width child)
child-max-height (ctl/child-max-height child)
[child-margin-top child-margin-right child-margin-bottom child-margin-left]
(ctl/child-margins child)
[child-margin-top child-margin-right child-margin-bottom child-margin-left]
(ctl/child-margins child)
child-margin-width (+ child-margin-left child-margin-right)
child-margin-height (+ child-margin-top child-margin-bottom)
child-margin-width (+ child-margin-left child-margin-right)
child-margin-height (+ child-margin-top child-margin-bottom)
fill-width? (ctl/fill-width? child)
fill-height? (ctl/fill-height? child)
fill-width? (ctl/fill-width? child)
fill-height? (ctl/fill-height? child)
;; We need this info later to calculate the child resizes when fill
child-data {:id (:id child)
:child-min-width (if fill-width? child-min-width child-width)
:child-min-height (if fill-height? child-min-height child-height)
:child-max-width (if fill-width? child-max-width child-width)
:child-max-height (if fill-height? child-max-height child-height)}
;; We need this info later to calculate the child resizes when fill
child-data {:id (:id child)
:child-min-width (if fill-width? child-min-width child-width)
:child-min-height (if fill-height? child-min-height child-height)
:child-max-width (if fill-width? child-max-width child-width)
:child-max-height (if fill-height? child-max-height child-height)}
next-min-width (+ child-margin-width (if fill-width? child-min-width child-width))
next-min-height (+ child-margin-height (if fill-height? child-min-height child-height))
next-max-width (+ child-margin-width (if fill-width? child-max-width child-width))
next-max-height (+ child-margin-height (if fill-height? child-max-height child-height))
next-min-width (+ child-margin-width (if fill-width? child-min-width child-width))
next-min-height (+ child-margin-height (if fill-height? child-min-height child-height))
next-max-width (+ child-margin-width (if fill-width? child-max-width child-width))
next-max-height (+ child-margin-height (if fill-height? child-max-height child-height))
next-line-min-width (+ line-min-width next-min-width (* layout-gap-row num-children))
next-line-min-height (+ line-min-height next-min-height (* layout-gap-col num-children))]
(if (and (some? line-data)
(or (not wrap?)
(and row? (<= next-line-min-width layout-width))
(and col? (<= next-line-min-height layout-height))))
next-line-min-width (+ line-min-width next-min-width (* layout-gap-row num-children))
next-line-min-height (+ line-min-height next-min-height (* layout-gap-col num-children))]
[{:line-min-width (if row? (+ line-min-width next-min-width) (max line-min-width next-min-width))
:line-max-width (if row? (+ line-max-width next-max-width) (max line-max-width next-max-width))
:line-min-height (if col? (+ line-min-height next-min-height) (max line-min-height next-min-height))
:line-max-height (if col? (+ line-max-height next-max-height) (max line-max-height next-max-height))
:num-children (inc num-children)
:children-data (conjv children-data child-data)}
result]
(if (and (some? line-data)
(or (not wrap?)
(and row? (<= next-line-min-width layout-width))
(and col? (<= next-line-min-height layout-height))))
[{:line-min-width next-min-width
:line-min-height next-min-height
:line-max-width next-max-width
:line-max-height next-max-height
:num-children 1
:children-data [child-data]}
(cond-> result (some? line-data) (conj line-data))])))
[line-data layout-lines] (reduce calculate-line-data [nil []] children)]
(cond-> layout-lines (some? line-data) (conj line-data))))
(recur {:line-min-width (if row? (+ line-min-width next-min-width) (max line-min-width next-min-width))
:line-max-width (if row? (+ line-max-width next-max-width) (max line-max-width next-max-width))
:line-min-height (if col? (+ line-min-height next-min-height) (max line-min-height next-min-height))
:line-max-height (if col? (+ line-max-height next-max-height) (max line-max-height next-max-height))
:num-children (inc num-children)
:children-data (conjv children-data child-data)}
result
(first children)
(rest children))
(recur {:line-min-width next-min-width
:line-min-height next-min-height
:line-max-width next-max-width
:line-max-height next-max-height
:num-children 1
:children-data [child-data]}
(cond-> result (some? line-data) (conj line-data))
(first children)
(rest children))))))))
(defn add-space-to-items
;; Distributes the remainder space between the lines
@ -162,8 +170,7 @@
(let [start-p (flp/get-start-line parent layout-bounds layout-line base-p total-width total-height num-lines)
next-p (flp/get-next-line parent layout-bounds layout-line base-p total-width total-height num-lines)]
[(conj result
(assoc layout-line :start-p start-p))
[(conj result (assoc layout-line :start-p start-p))
next-p]))]
(let [[total-min-width total-min-height total-max-width total-max-height]
@ -303,10 +310,10 @@
layout-lines
(->> (init-layout-lines shape children layout-bounds)
(add-lines-positions shape layout-bounds)
(mapv (partial add-line-spacing shape layout-bounds))
(mapv (partial add-children-resizes shape)))]
(into []
(comp (map (partial add-line-spacing shape layout-bounds))
(map (partial add-children-resizes shape)))))]
{:layout-lines layout-lines
:layout-bounds layout-bounds
:reverse? reverse?}))

View file

@ -114,24 +114,21 @@
"Cross axis line. It's position is fixed along the different lines"
[parent layout-bounds {:keys [line-width line-height num-children]} base-p total-width total-height num-lines]
(let [layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds)
(let [layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds)
[layout-gap-row layout-gap-col] (ctl/gaps parent)
row? (ctl/row? parent)
col? (ctl/col? parent)
space-between? (ctl/space-between? parent)
space-around? (ctl/space-around? parent)
h-center? (ctl/h-center? parent)
h-end? (ctl/h-end? parent)
v-center? (ctl/v-center? parent)
v-end? (ctl/v-end? parent)
content-stretch? (ctl/content-stretch? parent)
hv #(gpo/start-hv layout-bounds %)
vv #(gpo/start-vv layout-bounds %)
children-gap-width (* layout-gap-row (dec num-children))
row? (ctl/row? parent)
col? (ctl/col? parent)
space-between? (ctl/space-between? parent)
space-around? (ctl/space-around? parent)
h-center? (ctl/h-center? parent)
h-end? (ctl/h-end? parent)
v-center? (ctl/v-center? parent)
v-end? (ctl/v-end? parent)
content-stretch? (ctl/content-stretch? parent)
hv (partial gpo/start-hv layout-bounds)
vv (partial gpo/start-vv layout-bounds)
children-gap-width (* layout-gap-row (dec num-children))
children-gap-height (* layout-gap-col (dec num-children))
line-height

View file

@ -14,6 +14,7 @@
[app.common.geom.shapes.pixel-precision :as gpp]
[app.common.geom.shapes.transforms :as gtr]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]))
@ -30,7 +31,9 @@
"Given the ids that have changed search for layout roots to recalculate"
[ids objects]
(assert (or (nil? ids) (set? ids)) (dm/str "tree sequence from not set: " ids))
(us/assert!
:expr (or (nil? ids) (set? ids))
:hint (dm/str "tree sequence from not set: " ids))
(letfn [(get-tree-root ;; Finds the tree root for the current id
[id]
@ -76,8 +79,8 @@
(generate-tree ;; Generate a tree sequence from a given root id
[id]
(->> (tree-seq
#(d/not-empty? (get-in objects [% :shapes]))
#(get-in objects [% :shapes])
#(d/not-empty? (dm/get-in objects [% :shapes]))
#(dm/get-in objects [% :shapes])
id)
(map #(get objects %))))]
@ -90,7 +93,7 @@
"Propagates the modifiers from a parent too its children applying constraints if necesary"
[modif-tree objects parent transformed-parent ignore-constraints snap-pixel?]
(let [children (map (d/getf objects) (:shapes parent))
modifiers (get-in modif-tree [(:id parent) :modifiers])
modifiers (dm/get-in modif-tree [(:id parent) :modifiers])
parent (gtr/transform-shape parent (ctm/select-parent-modifiers modifiers))
set-child
@ -106,7 +109,7 @@
(defn- process-layout-children
[modif-tree objects parent transformed-parent]
(letfn [(process-child [modif-tree child]
(let [modifiers (get-in modif-tree [(:id parent) :modifiers])
(let [modifiers (dm/get-in modif-tree [(:id parent) :modifiers])
child-modifiers (-> modifiers
(ctm/select-child-geometry-modifiers)
(gcl/normalize-child-modifiers parent child transformed-parent))]
@ -120,7 +123,7 @@
[modif-tree objects parent]
(letfn [(apply-modifiers [modif-tree child]
(let [modifiers (get-in modif-tree [(:id child) :modifiers])]
(let [modifiers (dm/get-in modif-tree [(:id child) :modifiers])]
(cond-> child
(some? modifiers)
(gtr/transform-shape modifiers)
@ -165,7 +168,7 @@
[modif-tree objects parent]
(letfn [(apply-modifiers
[child]
(let [modifiers (get-in modif-tree [(:id child) :modifiers])]
(let [modifiers (dm/get-in modif-tree [(:id child) :modifiers])]
(cond-> child
(some? modifiers)
(gtr/transform-shape modifiers)
@ -187,7 +190,7 @@
(-> modifiers
(ctm/resize-parent (gpt/point 1 scale-height) origin (:transform parent) (:transform-inverse parent)))))]
(let [modifiers (get-in modif-tree [(:id parent) :modifiers])
(let [modifiers (dm/get-in modif-tree [(:id parent) :modifiers])
children (->> parent
:shapes
(map (comp apply-modifiers (d/getf objects))))
@ -210,7 +213,7 @@
[objects snap-pixel? ignore-constraints [modif-tree recalculate] parent]
(let [parent-id (:id parent)
root? (= uuid/zero parent-id)
modifiers (get-in modif-tree [parent-id :modifiers])
modifiers (dm/get-in modif-tree [parent-id :modifiers])
modifiers (cond-> modifiers
(and (not root?) (ctm/has-geometry? modifiers) snap-pixel?)
@ -248,7 +251,7 @@
[objects modif-tree parent]
(let [is-layout? (ctl/layout? parent)
is-auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent))
modifiers (get-in modif-tree [(:id parent) :modifiers])
modifiers (dm/get-in modif-tree [(:id parent) :modifiers])
transformed-parent (gtr/transform-shape parent modifiers)]
(cond-> modif-tree
is-layout?

View file

@ -12,10 +12,14 @@
(defn make-rect
([p1 p2]
(let [x1 (min (:x p1) (:x p2))
y1 (min (:y p1) (:y p2))
x2 (max (:x p1) (:x p2))
y2 (max (:y p1) (:y p2))]
(let [xp1 (:x p1)
yp1 (:y p1)
xp2 (:x p2)
yp2 (:y p2)
x1 (min xp1 xp2)
y1 (min yp1 yp2)
x2 (max xp1 xp2)
y2 (max yp1 yp2)]
(make-rect x1 y1 (- x2 x1) (- y2 y1))))
([x y width height]

View file

@ -14,6 +14,7 @@
[app.common.geom.shapes.path :as gpa]
[app.common.geom.shapes.rect :as gpr]
[app.common.math :as mth]
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
[app.common.uuid :as uuid]))
@ -452,7 +453,7 @@
(map (d/getf objects))
(apply-children-modifiers objects modif-tree))]
(cond-> parent
(= :group (:type parent))
(cph/group-shape? parent)
(update-group-selrect children))))
(defn get-children-bounds