mirror of
https://github.com/penpot/penpot.git
synced 2025-03-12 15:51:37 -05:00
✨ Refactor frames
This commit is contained in:
parent
8d9ed4f8af
commit
bc890a0b33
7 changed files with 716 additions and 52 deletions
|
@ -177,6 +177,8 @@
|
|||
(dm/export gtr/move-position-data)
|
||||
(dm/export gtr/apply-transform)
|
||||
(dm/export gtr/apply-objects-modifiers)
|
||||
(dm/export gtr/parent-coords-rect)
|
||||
(dm/export gtr/parent-coords-points)
|
||||
|
||||
;; Constratins
|
||||
(dm/export gct/calc-child-modifiers)
|
||||
|
@ -210,3 +212,4 @@
|
|||
|
||||
;; Modifiers
|
||||
(dm/export gsm/set-objects-modifiers)
|
||||
|
||||
|
|
|
@ -261,18 +261,8 @@
|
|||
"Before aplying constraints we need to remove the deformation caused by the resizing of the parent"
|
||||
[constraints-h constraints-v modifiers child parent transformed-child transformed-parent]
|
||||
|
||||
(let [child-bb-before
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gre/points->rect))
|
||||
|
||||
child-bb-after
|
||||
(-> transformed-child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse transformed-parent))
|
||||
(gre/points->rect))
|
||||
|
||||
(let [child-bb-before (gst/parent-coords-rect child parent)
|
||||
child-bb-after (gst/parent-coords-rect transformed-child transformed-parent)
|
||||
scale-x (/ (:width child-bb-before) (:width child-bb-after))
|
||||
scale-y (/ (:height child-bb-before) (:height child-bb-after))]
|
||||
|
||||
|
@ -332,3 +322,5 @@
|
|||
transformed-parent)]
|
||||
|
||||
(update modifiers :v2 d/concat-vec modifiers-h modifiers-v)))))
|
||||
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
(cond-> layout-lines (some? line-data) (conj line-data))))
|
||||
|
||||
(defn calc-layout-lines-position
|
||||
[{:keys [layout-gap layout-type] :as shape} {:keys [x y width height]} layout-lines]
|
||||
[{:keys [layout-gap layout-type] :as shape} {:keys [x y width height] :as layout-bounds} layout-lines]
|
||||
|
||||
(letfn [(get-base-line
|
||||
[total-width total-height]
|
||||
|
@ -414,8 +414,9 @@
|
|||
|
||||
(defn calc-layout-modifiers
|
||||
"Calculates the modifiers for the layout"
|
||||
[parent transform child layout-data]
|
||||
(let [child-bounds (-> child :points gre/points->selrect)
|
||||
[parent child layout-data]
|
||||
(let [transform (:transform parent)
|
||||
child-bounds (-> child :points gre/points->selrect)
|
||||
|
||||
fill-width (calc-fill-width-data child-bounds parent child layout-data)
|
||||
fill-height (calc-fill-height-data child-bounds parent child layout-data)
|
||||
|
|
606
common/src/app/common/geom/shapes/layout_new.cljc
Normal file
606
common/src/app/common/geom/shapes/layout_new.cljc
Normal file
|
@ -0,0 +1,606 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) UXBOX Labs SL
|
||||
|
||||
(ns app.common.geom.shapes.layout-new
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.rect :as gre]
|
||||
[app.common.geom.shapes.transforms :as gst]
|
||||
))
|
||||
|
||||
;; :layout ;; true if active, false if not
|
||||
;; :layout-dir ;; :right, :left, :top, :bottom
|
||||
;; :layout-gap ;; number could be negative
|
||||
;; :layout-type ;; :packed, :space-between, :space-around
|
||||
;; :layout-wrap-type ;; :wrap, :no-wrap
|
||||
;; :layout-padding-type ;; :simple, :multiple
|
||||
;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
|
||||
;; :layout-h-orientation ;; :top, :center, :bottom
|
||||
;; :layout-v-orientation ;; :left, :center, :right
|
||||
|
||||
(defn col?
|
||||
[{:keys [layout-dir]}]
|
||||
(or (= :right layout-dir) (= :left layout-dir)))
|
||||
|
||||
(defn row?
|
||||
[{:keys [layout-dir]}]
|
||||
(or (= :top layout-dir) (= :bottom layout-dir)))
|
||||
|
||||
(defn h-start?
|
||||
[{:keys [layout-h-orientation]}]
|
||||
(= layout-h-orientation :left))
|
||||
|
||||
(defn h-center?
|
||||
[{:keys [layout-h-orientation]}]
|
||||
(= layout-h-orientation :center))
|
||||
|
||||
(defn h-end?
|
||||
[{:keys [layout-h-orientation]}]
|
||||
(= layout-h-orientation :right))
|
||||
|
||||
(defn v-start?
|
||||
[{:keys [layout-v-orientation]}]
|
||||
(= layout-v-orientation :top))
|
||||
|
||||
(defn v-center?
|
||||
[{:keys [layout-v-orientation]}]
|
||||
(= layout-v-orientation :center))
|
||||
|
||||
(defn v-end?
|
||||
[{:keys [layout-v-orientation]}]
|
||||
(= layout-v-orientation :bottom))
|
||||
|
||||
(defn add-padding [transformed-rect {:keys [layout-padding-type layout-padding]}]
|
||||
(let [{:keys [p1 p2 p3 p4]} layout-padding
|
||||
[p1 p2 p3 p4]
|
||||
(if (= layout-padding-type :multiple)
|
||||
[p1 p2 p3 p4]
|
||||
[p1 p1 p1 p1])]
|
||||
|
||||
(-> transformed-rect
|
||||
(update :y + p1)
|
||||
(update :width - p2 p3)
|
||||
(update :x + p3)
|
||||
(update :height - p1 p4))))
|
||||
|
||||
;; FUNCTIONS TO WORK WITH POINTS SQUARES
|
||||
|
||||
(defn origin
|
||||
[points]
|
||||
(nth points 0))
|
||||
|
||||
(defn start-hv
|
||||
"Horizontal vector from the origin with a magnitude `val`"
|
||||
[[p0 p1 p2 p3] val]
|
||||
(-> (gpt/to-vec p0 p1)
|
||||
(gpt/unit)
|
||||
(gpt/scale val)))
|
||||
|
||||
(defn end-hv
|
||||
"Horizontal vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
[[p0 p1 p2 p3] val]
|
||||
(-> (gpt/to-vec p1 p0)
|
||||
(gpt/unit)
|
||||
(gpt/scale val)))
|
||||
|
||||
(defn start-vv
|
||||
"Vertical vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
[[p0 p1 p2 p3] val]
|
||||
(-> (gpt/to-vec p0 p3)
|
||||
(gpt/unit)
|
||||
(gpt/scale val)))
|
||||
|
||||
(defn end-vv
|
||||
"Vertical vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
[[p0 p1 p2 p3] val]
|
||||
(-> (gpt/to-vec p3 p0)
|
||||
(gpt/unit)
|
||||
(gpt/scale val)))
|
||||
|
||||
;;(defn start-hp
|
||||
;; [[p0 _ _ _ :as points] val]
|
||||
;; (gpt/add p0 (start-hv points val)))
|
||||
;;
|
||||
;;(defn end-hp
|
||||
;; "Horizontal Vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
;; [[_ p1 _ _ :as points] val]
|
||||
;; (gpt/add p1 (end-hv points val)))
|
||||
;;
|
||||
;;(defn start-vp
|
||||
;; "Vertical Vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
;; [[p0 _ _ _ :as points] val]
|
||||
;; (gpt/add p0 (start-vv points val)))
|
||||
;;
|
||||
;;(defn end-vp
|
||||
;; "Vertical Vector from the oposite to the origin in the x axis with a magnitude `val`"
|
||||
;; [[_ _ p3 _ :as points] val]
|
||||
;; (gpt/add p3 (end-vv points val)))
|
||||
|
||||
(defn width-points
|
||||
[[p0 p1 p2 p3]]
|
||||
(gpt/length (gpt/to-vec p0 p1)))
|
||||
|
||||
(defn height-points
|
||||
[[p0 p1 p2 p3]]
|
||||
(gpt/length (gpt/to-vec p0 p3)))
|
||||
|
||||
(defn pad-points
|
||||
[[p0 p1 p2 p3 :as points] pad-top pad-right pad-bottom pad-left]
|
||||
(let [top-v (start-vv points pad-top)
|
||||
right-v (end-hv points pad-right)
|
||||
bottom-v (end-vv points pad-bottom)
|
||||
left-v (start-hv points pad-left)]
|
||||
|
||||
[(-> p0 (gpt/add left-v) (gpt/add top-v))
|
||||
(-> p1 (gpt/add right-v) (gpt/add top-v))
|
||||
(-> p2 (gpt/add right-v) (gpt/add bottom-v))
|
||||
(-> p3 (gpt/add left-v) (gpt/add bottom-v))]))
|
||||
|
||||
;;;;
|
||||
|
||||
|
||||
(defn calc-layout-lines
|
||||
[{:keys [layout-gap layout-wrap-type] :as parent} children layout-bounds]
|
||||
|
||||
(let [wrap? (= layout-wrap-type :wrap)
|
||||
layout-width (width-points layout-bounds)
|
||||
layout-height (height-points layout-bounds)
|
||||
|
||||
reduce-fn
|
||||
(fn [[{:keys [line-width line-height num-children line-fill? child-fill? num-child-fill] :as line-data} result] child]
|
||||
(let [child-bounds (gst/parent-coords-points child parent)
|
||||
child-width (width-points child-bounds)
|
||||
child-height (height-points child-bounds)
|
||||
|
||||
col? (col? parent)
|
||||
row? (row? parent)
|
||||
|
||||
cur-child-fill?
|
||||
(or (and col? (= :fill (:layout-h-behavior child)))
|
||||
(and row? (= :fill (:layout-v-behavior child))))
|
||||
|
||||
cur-line-fill?
|
||||
(or (and row? (= :fill (:layout-h-behavior child)))
|
||||
(and col? (= :fill (:layout-v-behavior child))))
|
||||
|
||||
;; TODO LAYOUT: ADD MINWIDTH/HEIGHT
|
||||
next-width (if (or (and col? cur-child-fill?)
|
||||
(and row? cur-line-fill?))
|
||||
0
|
||||
child-width)
|
||||
|
||||
next-height (if (or (and row? cur-child-fill?)
|
||||
(and col? cur-line-fill?))
|
||||
0
|
||||
child-height)
|
||||
|
||||
next-total-width (+ line-width next-width (* layout-gap num-children))
|
||||
next-total-height (+ line-height next-height (* layout-gap num-children))]
|
||||
|
||||
(if (and (some? line-data)
|
||||
(or (not wrap?)
|
||||
(and col? (<= next-total-width layout-width))
|
||||
(and row? (<= next-total-height layout-height))))
|
||||
|
||||
;; When :fill we add min width (0 by default)
|
||||
[{:line-width (if col? (+ line-width next-width) (max line-width next-width))
|
||||
:line-height (if row? (+ line-height next-height) (max line-height next-height))
|
||||
:num-children (inc num-children)
|
||||
:child-fill? (or cur-child-fill? child-fill?)
|
||||
:line-fill? (or cur-line-fill? line-fill?)
|
||||
:num-child-fill (cond-> num-child-fill cur-child-fill? inc)}
|
||||
result]
|
||||
|
||||
[{:line-width next-width
|
||||
:line-height next-height
|
||||
:num-children 1
|
||||
:child-fill? cur-child-fill?
|
||||
:line-fill? cur-line-fill?
|
||||
:num-child-fill (if cur-child-fill? 1 0)}
|
||||
(cond-> result (some? line-data) (conj line-data))])))
|
||||
|
||||
[line-data layout-lines] (reduce reduce-fn [nil []] children)]
|
||||
|
||||
(cond-> layout-lines (some? line-data) (conj line-data))))
|
||||
|
||||
(defn calc-layout-lines-position
|
||||
[{:keys [layout-gap layout-type] :as parent} layout-bounds layout-lines]
|
||||
|
||||
(let [layout-width (width-points layout-bounds)
|
||||
layout-height (height-points layout-bounds)
|
||||
row? (row? parent)
|
||||
col? (col? parent)
|
||||
h-center? (h-center? parent)
|
||||
h-end? (h-end? parent)
|
||||
v-center? (v-center? parent)
|
||||
v-end? (v-end? parent)
|
||||
space-between? (= :space-between layout-type)
|
||||
space-around? (= :space-around layout-type)]
|
||||
|
||||
(letfn [(get-base-line
|
||||
[total-width total-height]
|
||||
|
||||
(cond-> (origin layout-bounds)
|
||||
(and row? h-center?)
|
||||
(gpt/add (start-hv layout-bounds (/ (- layout-width total-width) 2)))
|
||||
|
||||
(and row? h-end?)
|
||||
(gpt/add (start-hv layout-bounds (- layout-width total-width)))
|
||||
|
||||
(and col? v-center?)
|
||||
(gpt/add (start-vv layout-bounds (/ (- layout-height total-height) 2)))
|
||||
|
||||
(and col? v-end?)
|
||||
(gpt/add (start-vv layout-bounds (- layout-height total-height)))
|
||||
))
|
||||
|
||||
(get-start-line
|
||||
[{:keys [line-width line-height num-children child-fill?]} base-p]
|
||||
|
||||
(let [children-gap (* layout-gap (dec num-children))
|
||||
|
||||
;;line-width (if (and col? child-fill?)
|
||||
;; (- layout-width (* layout-gap num-children))
|
||||
;; line-width)
|
||||
;;
|
||||
;;line-height (if (and row? child-fill?)
|
||||
;; (- layout-height (* layout-gap num-children))
|
||||
;; line-height)
|
||||
|
||||
|
||||
start-p
|
||||
(cond-> base-p
|
||||
;; X AXIS
|
||||
(and col? h-center? (not space-between?) (not space-around?))
|
||||
(-> (gpt/add (start-hv layout-bounds (/ layout-width 2)))
|
||||
(gpt/subtract (start-hv layout-bounds (/ (+ line-width children-gap) 2))))
|
||||
|
||||
(and col? h-end? (not space-between?) (not space-around?))
|
||||
(-> (gpt/add (start-hv layout-bounds layout-width))
|
||||
(gpt/subtract (start-hv layout-bounds (+ line-width children-gap))))
|
||||
|
||||
(and row? h-center? (not space-between?) (not space-around?))
|
||||
(gpt/add (start-hv layout-bounds (/ line-width 2)))
|
||||
|
||||
(and row? h-end? (not space-between?) (not space-around?))
|
||||
(gpt/add (start-hv layout-bounds line-width))
|
||||
|
||||
;; Y AXIS
|
||||
(and row? v-center? (not space-between?) (not space-around?))
|
||||
(-> (gpt/add (start-vv layout-bounds (/ layout-height 2)))
|
||||
(gpt/subtract (start-vv layout-bounds (/ (+ line-height children-gap) 2))))
|
||||
|
||||
(and row? v-end? (not space-between?) (not space-around?))
|
||||
(-> (gpt/add (start-vv layout-bounds layout-height))
|
||||
(gpt/subtract (start-vv layout-bounds (+ line-height children-gap))))
|
||||
|
||||
(and col? v-center? (not space-between?) (not space-around?))
|
||||
(gpt/add (start-vv layout-bounds (/ line-height 2)))
|
||||
|
||||
(and col? v-end? (not space-between?) (not space-around?))
|
||||
(gpt/add (start-vv layout-bounds line-height))
|
||||
|
||||
)
|
||||
|
||||
|
||||
;;start-x
|
||||
;;(cond
|
||||
;; ;;(and (col? shape) child-fill?)
|
||||
;; ;; TODO LAYOUT: Start has to take into account max-width
|
||||
;; ;;x
|
||||
;;
|
||||
;; (or (and col? space-between?) (and col? space-around?))
|
||||
;; x
|
||||
;;
|
||||
;; (and col? h-center?)
|
||||
;; (- (+ x (/ width 2)) (/ (+ line-width children-gap) 2))
|
||||
;;
|
||||
;; (and col? h-end?)
|
||||
;; (- (+ x width) (+ line-width children-gap))
|
||||
;;
|
||||
;; (and row? h-center?)
|
||||
;; (+ base-x (/ line-width 2))
|
||||
;;
|
||||
;; (and row? h-end?)
|
||||
;; (+ base-x line-width)
|
||||
;;
|
||||
;; row?
|
||||
;; base-x
|
||||
;;
|
||||
;; :else
|
||||
;; x)
|
||||
|
||||
;;start-y
|
||||
;;(cond
|
||||
;; ;; (and (row? shape) child-fill?)
|
||||
;; ;; TODO LAYOUT: Start has to take into account max-width
|
||||
;; ;; y
|
||||
;;
|
||||
;; (or (and (row? shape) (= :space-between layout-type))
|
||||
;; (and (row? shape) (= :space-around layout-type)))
|
||||
;; y
|
||||
;;
|
||||
;; (and (row? shape) (v-center? shape))
|
||||
;; (- (+ y (/ height 2)) (/ (+ line-height children-gap) 2))
|
||||
;;
|
||||
;; (and (row? shape) (v-end? shape))
|
||||
;; (- (+ y height) (+ line-height children-gap))
|
||||
;;
|
||||
;; (and (col? shape) (v-center? shape))
|
||||
;; (+ base-y (/ line-height 2))
|
||||
;;
|
||||
;; (and (col? shape) (v-end? shape))
|
||||
;; (+ base-y line-height)
|
||||
;;
|
||||
;; (col? shape)
|
||||
;; base-y
|
||||
;;
|
||||
;; :else
|
||||
;; y)
|
||||
]
|
||||
|
||||
start-p))
|
||||
|
||||
(get-next-line
|
||||
[{:keys [line-width line-height]} base-p]
|
||||
|
||||
(cond-> base-p
|
||||
col?
|
||||
(gpt/add (start-hv layout-bounds (+ line-width layout-gap)))
|
||||
|
||||
row?
|
||||
(gpt/add (start-vv layout-bounds (+ line-height layout-gap)))
|
||||
)
|
||||
|
||||
#_(let [next-x (if col? base-x (+ base-x line-width layout-gap))
|
||||
next-y (if row? base-y (+ base-y line-height layout-gap))]
|
||||
[next-x next-y]))
|
||||
|
||||
(add-lines [[total-width total-height] {:keys [line-width line-height]}]
|
||||
[(+ total-width line-width)
|
||||
(+ total-height line-height)])
|
||||
|
||||
(add-starts [[result base-p] layout-line]
|
||||
(let [start-p (get-start-line layout-line base-p)
|
||||
next-p (get-next-line layout-line base-p)]
|
||||
[(conj result
|
||||
(assoc layout-line :start-p start-p))
|
||||
next-p]))]
|
||||
|
||||
(let [[total-width total-height] (->> layout-lines (reduce add-lines [0 0]))
|
||||
|
||||
total-width (+ total-width (* layout-gap (dec (count layout-lines))))
|
||||
total-height (+ total-height (* layout-gap (dec (count layout-lines))))
|
||||
|
||||
vertical-fill-space (- layout-height total-height)
|
||||
horizontal-fill-space (- layout-width total-width)
|
||||
num-line-fill (count (->> layout-lines (filter :line-fill?)))
|
||||
|
||||
layout-lines
|
||||
(->> layout-lines
|
||||
(mapv #(cond-> %
|
||||
(and col? (:line-fill? %))
|
||||
(update :line-height + (/ vertical-fill-space num-line-fill))
|
||||
|
||||
(and row? (:line-fill? %))
|
||||
(update :line-width + (/ horizontal-fill-space num-line-fill)))))
|
||||
|
||||
total-height (if (and col? (> num-line-fill 0)) layout-height total-height)
|
||||
total-width (if (and row? (> num-line-fill 0)) layout-width total-width)
|
||||
|
||||
base-p (get-base-line total-width total-height)
|
||||
|
||||
[layout-lines _ _ _ _]
|
||||
(reduce add-starts [[] base-p] layout-lines)]
|
||||
layout-lines))))
|
||||
|
||||
(defn calc-layout-line-data
|
||||
[{:keys [layout-type layout-gap] :as shape}
|
||||
{:keys [width height] :as layout-bounds}
|
||||
{:keys [num-children line-width line-height] :as line-data}]
|
||||
|
||||
(let [layout-gap
|
||||
(cond
|
||||
(= :packed layout-type)
|
||||
layout-gap
|
||||
|
||||
(= :space-around layout-type)
|
||||
0
|
||||
|
||||
(and (col? shape) (= :space-between layout-type))
|
||||
(/ (- width line-width) (dec num-children))
|
||||
|
||||
(and (row? shape) (= :space-between layout-type))
|
||||
(/ (- height line-height) (dec num-children)))
|
||||
|
||||
margin-x
|
||||
(if (and (col? shape) (= :space-around layout-type))
|
||||
(/ (- width line-width) (inc num-children) )
|
||||
0)
|
||||
|
||||
margin-y
|
||||
(if (and (row? shape) (= :space-around layout-type))
|
||||
(/ (- height line-height) (inc num-children))
|
||||
0)]
|
||||
|
||||
(assoc line-data
|
||||
:layout-bounds layout-bounds
|
||||
:layout-gap layout-gap
|
||||
:margin-x margin-x
|
||||
:margin-y margin-y)))
|
||||
|
||||
(defn next-p
|
||||
"Calculates the position for the current shape given the layout-data context"
|
||||
[parent
|
||||
child-bounds
|
||||
{:keys [start-p layout-gap margin-x margin-y] :as layout-data}]
|
||||
|
||||
(let [width (width-points child-bounds)
|
||||
height (height-points child-bounds)
|
||||
|
||||
row? (row? parent)
|
||||
col? (col? parent)
|
||||
h-center? (h-center? parent)
|
||||
h-end? (h-end? parent)
|
||||
v-center? (v-center? parent)
|
||||
v-end? (v-end? parent)
|
||||
points (:points parent)
|
||||
|
||||
corner-p
|
||||
(cond-> start-p
|
||||
(and row? h-center?)
|
||||
(gpt/add (start-hv points (- (/ width 2))))
|
||||
|
||||
(and row? h-end?)
|
||||
(gpt/add (start-hv points (- width)))
|
||||
|
||||
(and col? v-center?)
|
||||
(gpt/add (start-vv points (- (/ height 2))))
|
||||
|
||||
(and col? v-end?)
|
||||
(gpt/add (start-vv points (- height)))
|
||||
|
||||
(some? margin-x)
|
||||
(gpt/add (start-hv points margin-x))
|
||||
|
||||
(some? margin-y)
|
||||
(gpt/add (start-vv points margin-y)))
|
||||
|
||||
next-p
|
||||
(cond-> start-p
|
||||
col?
|
||||
(gpt/add (start-hv points (+ width layout-gap)))
|
||||
|
||||
row?
|
||||
(gpt/add (start-vv points (+ height layout-gap)))
|
||||
|
||||
(some? margin-x)
|
||||
(gpt/add (start-hv points margin-x))
|
||||
|
||||
(some? margin-y)
|
||||
(gpt/add (start-vv points margin-y)))
|
||||
|
||||
layout-data
|
||||
(assoc layout-data :start-p next-p)]
|
||||
|
||||
[corner-p layout-data]))
|
||||
|
||||
(defn calc-fill-width-data
|
||||
[child-bounds
|
||||
{:keys [layout-gap] :as parent}
|
||||
{:keys [layout-h-behavior] :as child}
|
||||
{:keys [num-children line-width layout-bounds line-fill? child-fill?] :as layout-data}]
|
||||
|
||||
(cond
|
||||
(and (col? parent) (= :fill layout-h-behavior) child-fill?)
|
||||
(let [fill-space (- (:width layout-bounds) line-width (* layout-gap num-children))
|
||||
fill-width (/ fill-space (:num-child-fill layout-data))
|
||||
fill-scale (/ fill-width (:width child-bounds))]
|
||||
{:bounds {:width fill-width}
|
||||
:modifiers [{:type :resize
|
||||
:origin (gpt/point child-bounds)
|
||||
:vector (gpt/point fill-scale 1)}]})
|
||||
|
||||
(and (row? parent) (= :fill layout-h-behavior) line-fill?)
|
||||
(let [fill-scale (/ line-width (:width child-bounds))]
|
||||
{:bounds {:width line-width}
|
||||
:modifiers [{:type :resize
|
||||
:origin (gpt/point child-bounds)
|
||||
:vector (gpt/point fill-scale 1)}]})
|
||||
))
|
||||
|
||||
(defn calc-fill-height-data
|
||||
[child-bounds
|
||||
{:keys [layout-gap] :as parent}
|
||||
{:keys [layout-v-behavior] :as child}
|
||||
{:keys [num-children line-height layout-bounds line-fill? child-fill?] :as layout-data}]
|
||||
|
||||
(cond
|
||||
(and (row? parent) (= :fill layout-v-behavior) child-fill?)
|
||||
(let [fill-space (- (:height layout-bounds) line-height (* layout-gap num-children))
|
||||
fill-height (/ fill-space (:num-child-fill layout-data))
|
||||
fill-scale (/ fill-height (:height child-bounds))]
|
||||
{:bounds {:height fill-height}
|
||||
:modifiers [{:type :resize
|
||||
:origin (gpt/point child-bounds)
|
||||
:vector (gpt/point 1 fill-scale)}]})
|
||||
|
||||
(and (col? parent) (= :fill layout-v-behavior) line-fill?)
|
||||
(let [fill-scale (/ line-height (:height child-bounds))]
|
||||
{:bounds {:height line-height}
|
||||
:modifiers [{:type :resize
|
||||
:origin (gpt/point child-bounds)
|
||||
:vector (gpt/point 1 fill-scale)}]})
|
||||
))
|
||||
|
||||
(defn normalize-child-modifiers
|
||||
"Apply the modifiers and then normalized them against the parent coordinates"
|
||||
[parent child modifiers transformed-parent]
|
||||
|
||||
(let [transformed-child (gst/transform-shape child modifiers)
|
||||
child-bb-before (gst/parent-coords-rect child parent)
|
||||
child-bb-after (gst/parent-coords-rect transformed-child transformed-parent)
|
||||
scale-x (/ (:width child-bb-before) (:width child-bb-after))
|
||||
scale-y (/ (:height child-bb-before) (:height child-bb-after))]
|
||||
(-> modifiers
|
||||
(update :v2 #(conj %
|
||||
{:type :resize
|
||||
:transform (:transform transformed-parent)
|
||||
:transform-inverse (:transform-inverse transformed-parent)
|
||||
:origin (-> transformed-parent :points (nth 0))
|
||||
:vector (gpt/point scale-x scale-y)})))))
|
||||
|
||||
(defn calc-layout-data
|
||||
"Digest the layout data to pass it to the constrains"
|
||||
[{:keys [layout-dir points layout-padding layout-padding-type] :as parent} children]
|
||||
|
||||
(let [;; Add padding to the bounds
|
||||
{pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding
|
||||
[pad-top pad-right pad-bottom pad-left]
|
||||
(if (= layout-padding-type :multiple)
|
||||
[pad-top pad-right pad-bottom pad-left]
|
||||
[pad-top pad-top pad-top pad-top])
|
||||
layout-bounds (-> points (pad-points pad-top pad-right pad-bottom pad-left))
|
||||
|
||||
;; Reverse
|
||||
reverse? (or (= :left layout-dir) (= :bottom layout-dir))
|
||||
children (cond->> children reverse? reverse)
|
||||
|
||||
;; Creates the layout lines information
|
||||
layout-lines
|
||||
(->> (calc-layout-lines parent children layout-bounds)
|
||||
(calc-layout-lines-position parent layout-bounds)
|
||||
(map (partial calc-layout-line-data parent layout-bounds)))]
|
||||
|
||||
{:layout-lines layout-lines
|
||||
:reverse? reverse?}))
|
||||
|
||||
(defn calc-layout-modifiers
|
||||
"Calculates the modifiers for the layout"
|
||||
[parent child layout-line]
|
||||
(let [child-bounds (gst/parent-coords-points child parent)
|
||||
|
||||
;;fill-width (calc-fill-width-data child-bounds parent child layout-line)
|
||||
;;fill-height (calc-fill-height-data child-bounds parent child layout-line)
|
||||
|
||||
;;child-bounds (cond-> child-bounds
|
||||
;; fill-width (merge (:bounds fill-width))
|
||||
;; fill-height (merge (:bounds fill-height)))
|
||||
|
||||
|
||||
[corner-p layout-line] (next-p parent child-bounds layout-line)
|
||||
|
||||
move-vec (gpt/to-vec (origin child-bounds) corner-p)
|
||||
|
||||
modifiers
|
||||
(-> []
|
||||
#_(cond-> fill-width (d/concat-vec (:modifiers fill-width)))
|
||||
#_(cond-> fill-height (d/concat-vec (:modifiers fill-height)))
|
||||
(conj {:type :move :vector move-vec}))]
|
||||
|
||||
[modifiers layout-line]))
|
||||
|
|
@ -11,7 +11,8 @@
|
|||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.common :as gco]
|
||||
[app.common.geom.shapes.constraints :as gct]
|
||||
[app.common.geom.shapes.layout :as gcl]
|
||||
[app.common.geom.shapes.layout :as gclo]
|
||||
[app.common.geom.shapes.layout-new :as gcln]
|
||||
[app.common.geom.shapes.rect :as gpr]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
[app.common.math :as mth]
|
||||
|
@ -108,40 +109,21 @@
|
|||
|
||||
|
||||
(defn set-children-modifiers
|
||||
[modif-tree objects shape ignore-constraints snap-pixel?]
|
||||
[modif-tree objects parent ignore-constraints snap-pixel?]
|
||||
;; TODO LAYOUT: SNAP PIXEL!
|
||||
(letfn [(set-child [transformed-parent _snap-pixel? modif-tree child]
|
||||
(let [modifiers (get-in modif-tree [(:id shape) :modifiers])
|
||||
|
||||
child-modifiers (gct/calc-child-modifiers shape child modifiers ignore-constraints transformed-parent)
|
||||
|
||||
;;_ (.log js/console (:name child) (clj->js child-modifiers))
|
||||
|
||||
(let [modifiers (get-in modif-tree [(:id parent) :modifiers])
|
||||
child-modifiers (gct/calc-child-modifiers parent child modifiers ignore-constraints transformed-parent)
|
||||
;;child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))
|
||||
|
||||
result
|
||||
]
|
||||
(cond-> modif-tree
|
||||
(not (ctm/empty-modifiers? child-modifiers))
|
||||
(update-in [(:id child) :modifiers :v2] #(d/concat-vec % (:v2 child-modifiers)))
|
||||
#_(update-in [(:id child) :modifiers] #(merge-mod2 child-modifiers %))
|
||||
#_(update-in [(:id child) :modifiers] #(merge child-modifiers %)))
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec (:v2 child-modifiers)))))]
|
||||
|
||||
;;_ (.log js/console ">>>" (:name child))
|
||||
;;_ (.log js/console " >" (clj->js child-modifiers))
|
||||
;;_ (.log js/console " >" (clj->js (get-in modif-tree [(:id child) :modifiers])))
|
||||
;;_ (.log js/console " >" (clj->js (get-in result [(:id child) :modifiers])))
|
||||
]
|
||||
result
|
||||
))
|
||||
]
|
||||
(let [children (map (d/getf objects) (:shapes shape))
|
||||
modifiers (get-in modif-tree [(:id shape) :modifiers])
|
||||
;; transformed-rect (gtr/transform-selrect (:selrect shape) modifiers)
|
||||
;; transformed-rect (-> shape (merge {:modifiers modifiers}) gtr/transform-shape :selrect)
|
||||
transformed-parent (-> shape (merge {:modifiers modifiers}) gtr/transform-shape)
|
||||
|
||||
resize-modif? (or (:resize-vector modifiers) (:resize-vector-2 modifiers))]
|
||||
(reduce (partial set-child transformed-parent (and snap-pixel? resize-modif?)) modif-tree children))))
|
||||
(let [children (map (d/getf objects) (:shapes parent))
|
||||
modifiers (get-in modif-tree [(:id parent) :modifiers])
|
||||
transformed-parent (gtr/transform-shape parent modifiers)]
|
||||
(reduce (partial set-child transformed-parent snap-pixel?) modif-tree children))))
|
||||
|
||||
(defn group? [shape]
|
||||
(or (= :group (:type shape))
|
||||
|
@ -158,6 +140,68 @@
|
|||
;; TODO LAYOUT: SNAP PIXEL!
|
||||
[modif-tree objects parent _snap-pixel?]
|
||||
|
||||
(letfn [(normalize-child [transformed-parent _snap-pixel? modif-tree child]
|
||||
(let [modifiers (get-in modif-tree [(:id parent) :modifiers])
|
||||
child-modifiers (gcln/normalize-child-modifiers parent child modifiers transformed-parent)]
|
||||
(cond-> modif-tree
|
||||
(not (ctm/empty-modifiers? child-modifiers))
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec (:v2 child-modifiers)))))
|
||||
|
||||
(apply-modifiers [modif-tree child]
|
||||
(let [modifiers (get-in modif-tree [(:id child) :modifiers])]
|
||||
(cond-> child
|
||||
(some? modifiers)
|
||||
(gtr/transform-shape modifiers)
|
||||
|
||||
(and (nil? modifiers) (group? child))
|
||||
(gtr/apply-group-modifiers objects modif-tree))))
|
||||
|
||||
(set-layout-modifiers [parent [layout-line modif-tree] child]
|
||||
(let [[modifiers layout-line]
|
||||
(gcln/calc-layout-modifiers parent child layout-line)
|
||||
|
||||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(d/not-empty? modifiers)
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers))]
|
||||
|
||||
[layout-line modif-tree]))]
|
||||
|
||||
(let [children (map (d/getf objects) (:shapes parent))
|
||||
modifiers (get-in modif-tree [(:id parent) :modifiers])
|
||||
transformed-parent (gtr/transform-shape parent modifiers)
|
||||
|
||||
modif-tree (reduce (partial normalize-child transformed-parent _snap-pixel?) modif-tree children)
|
||||
|
||||
children (->> children (map (partial apply-modifiers modif-tree)))
|
||||
|
||||
layout-data (gcln/calc-layout-data transformed-parent children)
|
||||
|
||||
children (into [] (cond-> children (:reverse? layout-data) reverse))
|
||||
|
||||
max-idx (dec (count children))
|
||||
layout-lines (:layout-lines layout-data)]
|
||||
|
||||
(loop [modif-tree modif-tree
|
||||
layout-line (first layout-lines)
|
||||
pending (rest layout-lines)
|
||||
from-idx 0]
|
||||
|
||||
|
||||
(if (and (some? layout-line) (<= from-idx max-idx))
|
||||
(let [to-idx (+ from-idx (:num-children layout-line))
|
||||
children (subvec children from-idx to-idx)
|
||||
|
||||
[_ modif-tree]
|
||||
(reduce (partial set-layout-modifiers transformed-parent) [layout-line modif-tree] children)]
|
||||
(recur modif-tree (first pending) (rest pending) to-idx))
|
||||
|
||||
modif-tree)))))
|
||||
|
||||
#_(defn set-layout-modifiers'
|
||||
;; TODO LAYOUT: SNAP PIXEL!
|
||||
[modif-tree objects parent _snap-pixel?]
|
||||
|
||||
(letfn [(transform-child [child]
|
||||
(let [modifiers (get modif-tree (:id child))
|
||||
|
||||
|
@ -182,8 +226,7 @@
|
|||
modif-tree
|
||||
(cond-> modif-tree
|
||||
(d/not-empty? modifiers)
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers)
|
||||
#_(merge-modifiers [(:id child)] modifiers))]
|
||||
(update-in [(:id child) :modifiers :v2] d/concat-vec modifiers))]
|
||||
|
||||
[layout-data modif-tree]))]
|
||||
|
||||
|
@ -218,7 +261,6 @@
|
|||
|
||||
[_ modif-tree]
|
||||
(reduce (partial set-layout-modifiers shape transform) [layout-line modif-tree] children)]
|
||||
|
||||
(recur modif-tree (first pending) (rest pending) to-idx))
|
||||
|
||||
modif-tree)))))
|
||||
|
@ -316,11 +358,12 @@
|
|||
is-inside-layout? (inside-layout? objects shape)]
|
||||
|
||||
(cond-> modif-tree
|
||||
(and has-modifiers? is-parent?)
|
||||
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)
|
||||
|
||||
is-layout?
|
||||
(set-layout-modifiers objects shape snap-pixel?)
|
||||
|
||||
(and has-modifiers? is-parent?)
|
||||
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?))))
|
||||
)))
|
||||
|
||||
modif-tree))]
|
||||
|
||||
|
|
|
@ -558,3 +558,19 @@
|
|||
(apply-group-modifiers shape objects modif-tree)
|
||||
shape)))))]
|
||||
(update-group-selrect group children)))
|
||||
|
||||
(defn parent-coords-rect
|
||||
[child parent]
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gpr/points->rect)))
|
||||
|
||||
(defn parent-coords-points
|
||||
[child parent]
|
||||
(-> child
|
||||
:points
|
||||
(gco/transform-points (:transform-inverse parent))
|
||||
(gpr/points->rect)
|
||||
(gpr/rect->points)
|
||||
(gco/transform-points (:transform parent))))
|
||||
|
|
|
@ -24,7 +24,10 @@
|
|||
[app.main.ui.workspace.shapes.frame.node-store :as fns]
|
||||
[app.main.ui.workspace.shapes.frame.thumbnail-render :as ftr]
|
||||
[beicon.core :as rx]
|
||||
[rumext.v2 :as mf]))
|
||||
[rumext.v2 :as mf]
|
||||
|
||||
[app.common.geom.shapes.layout :as gsl]
|
||||
[app.common.geom.point :as gpt]))
|
||||
|
||||
(defn frame-shape-factory
|
||||
[shape-wrapper]
|
||||
|
|
Loading…
Add table
Reference in a new issue