Adds integration with new UI

This commit is contained in:
alonso.torres 2022-10-20 17:10:36 +02:00
parent 11f347941e
commit af098bb64d
13 changed files with 431 additions and 336 deletions

View file

@ -13,8 +13,8 @@
[app.common.geom.shapes.common :as gco] [app.common.geom.shapes.common :as gco]
[app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.corners :as gsc] [app.common.geom.shapes.corners :as gsc]
[app.common.geom.shapes.flex-layout :as gcl]
[app.common.geom.shapes.intersect :as gin] [app.common.geom.shapes.intersect :as gin]
[app.common.geom.shapes.layout :as gcl]
[app.common.geom.shapes.modifiers :as gsm] [app.common.geom.shapes.modifiers :as gsm]
[app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.path :as gsp]
[app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.rect :as gpr]

View file

@ -4,7 +4,7 @@
;; ;;
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.common.geom.shapes.layout (ns app.common.geom.shapes.flex-layout
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
@ -16,52 +16,95 @@
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm])) [app.common.types.modifiers :as ctm]))
;; :layout ;; true if active, false if not ;; :layout ;; :flex, :grid in the future
;; :layout-dir ;; :right, :left, :top, :bottom ;; :layout-flex-dir ;; :row, :reverse-row, :column, :reverse-column
;; :layout-gap ;; number could be negative ;; :layout-gap-type ;; :simple, :multiple
;; :layout-type ;; :packed, :space-between, :space-around ;; :layout-gap ;; {:row-gap number , :column-gap number}
;; :layout-align-items ;; :start :end :center :strech
;; :layout-justify-content ;; :start :center :end :space-between :space-around
;; :layout-align-content ;; :start :center :end :space-between :space-around :strech (by default)
;; :layout-wrap-type ;; :wrap, :no-wrap ;; :layout-wrap-type ;; :wrap, :no-wrap
;; :layout-padding-type ;; :simple, :multiple ;; :layout-padding-type ;; :simple, :multiple
;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative ;; :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 ;; ITEMS
;; :layout-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
;; :layout-margin-type ;; :simple :multiple
;; :layout-h-behavior ;; :fill :fix :auto
;; :layout-v-behavior ;; :fill :fix :auto
;; :layout-max-h ;; num
;; :layout-min-h ;; num
;; :layout-max-w ;; num
;; :layout-min-w
(defn col? (defn col?
[{:keys [layout-dir]}] [{:keys [layout-flex-dir]}]
(or (= :right layout-dir) (= :left layout-dir))) (or (= :column layout-flex-dir) (= :reverse-column layout-flex-dir)))
(defn row? (defn row?
[{:keys [layout-dir]}] [{:keys [layout-flex-dir]}]
(or (= :top layout-dir) (= :bottom layout-dir))) (or (= :row layout-flex-dir) (= :reverse-row layout-flex-dir)))
(defn h-start? (defn h-start?
[{:keys [layout-h-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-h-orientation :left)) (or (and (col? shape)
(= layout-align-items :start))
(and (row? shape)
(= layout-justify-content :start))))
(defn h-center? (defn h-center?
[{:keys [layout-h-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-h-orientation :center)) (or (and (col? shape)
(= layout-align-items :center))
(and (row? shape)
(= layout-justify-content :center))))
(defn h-end? (defn h-end?
[{:keys [layout-h-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-h-orientation :right)) (or (and (col? shape)
(= layout-align-items :end))
(and (row? shape)
(= layout-justify-content :end))))
(defn v-start? (defn v-start?
[{:keys [layout-v-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-v-orientation :top)) (or (and (row? shape)
(= layout-align-items :start))
(and (col? shape)
(= layout-justify-content :start))))
(defn v-center? (defn v-center?
[{:keys [layout-v-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-v-orientation :center)) (or (and (row? shape)
(= layout-align-items :center))
(and (col? shape)
(= layout-justify-content :center))))
(defn v-end? (defn v-end?
[{:keys [layout-v-orientation]}] [{:keys [layout-align-items layout-justify-content] :as shape}]
(= layout-v-orientation :bottom)) (or (and (row? shape)
(= layout-align-items :end))
(and (col? shape)
(= layout-justify-content :end))))
(defn gaps
[{:keys [layout-gap layout-gap-type]}]
(let [layout-gap-row (or (-> layout-gap :row-gap) 0)
layout-gap-col (if (= layout-gap-type :simple)
layout-gap-row
(or (-> layout-gap :column-gap) 0))]
[layout-gap-row layout-gap-col]))
(defn calc-layout-lines (defn calc-layout-lines
[{:keys [layout-gap layout-wrap-type] :as parent} children layout-bounds] "Calculates the lines basic data and accumulated values. The positions will be calculated in a different operation"
[{:keys [layout-wrap-type] :as parent} children layout-bounds]
(let [wrap? (= layout-wrap-type :wrap) (let [wrap? (= layout-wrap-type :wrap)
col? (col? parent)
row? (row? parent)
[layout-gap-row layout-gap-col] (gaps parent)
layout-width (gpo/width-points layout-bounds) layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds) layout-height (gpo/height-points layout-bounds)
@ -71,39 +114,36 @@
child-width (gpo/width-points child-bounds) child-width (gpo/width-points child-bounds)
child-height (gpo/height-points child-bounds) child-height (gpo/height-points child-bounds)
col? (col? parent)
row? (row? parent)
cur-child-fill? 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))) (or (and row? (= :fill (:layout-h-behavior child)))
(and col? (= :fill (:layout-v-behavior child)))) (and col? (= :fill (:layout-v-behavior child))))
cur-line-fill?
(or (and col? (= :fill (:layout-h-behavior child)))
(and row? (= :fill (:layout-v-behavior child))))
;; TODO LAYOUT: ADD MINWIDTH/HEIGHT ;; TODO LAYOUT: ADD MINWIDTH/HEIGHT
next-width (if (or (and col? cur-child-fill?) next-width (if (or (and row? cur-child-fill?)
(and row? cur-line-fill?)) (and col? cur-line-fill?))
0 0
child-width) child-width)
next-height (if (or (and row? cur-child-fill?) next-height (if (or (and col? cur-child-fill?)
(and col? cur-line-fill?)) (and row? cur-line-fill?))
0 0
child-height) child-height)
next-total-width (+ line-width next-width (* layout-gap (dec num-children))) next-total-width (+ line-width next-width (* layout-gap-row (dec num-children)))
next-total-height (+ line-height next-height (* layout-gap (dec num-children)))] next-total-height (+ line-height next-height (* layout-gap-col (dec num-children)))]
(if (and (some? line-data) (if (and (some? line-data)
(or (not wrap?) (or (not wrap?)
(and col? (<= next-total-width layout-width)) (and row? (<= next-total-width layout-width))
(and row? (<= next-total-height layout-height)))) (and col? (<= next-total-height layout-height))))
;; When :fill we add min width (0 by default) ;; When :fill we add min width (0 by default)
[{:line-width (if col? (+ line-width next-width) (max line-width next-width)) [{:line-width (if row? (+ line-width next-width) (max line-width next-width))
:line-height (if row? (+ line-height next-height) (max line-height next-height)) :line-height (if col? (+ line-height next-height) (max line-height next-height))
:num-children (inc num-children) :num-children (inc num-children)
:child-fill? (or cur-child-fill? child-fill?) :child-fill? (or cur-child-fill? child-fill?)
:line-fill? (or cur-line-fill? line-fill?) :line-fill? (or cur-line-fill? line-fill?)
@ -123,14 +163,16 @@
(cond-> layout-lines (some? line-data) (conj line-data)))) (cond-> layout-lines (some? line-data) (conj line-data))))
(defn calc-layout-lines-position (defn calc-layout-lines-position
[{:keys [layout-gap] :as parent} layout-bounds layout-lines] [{:keys [layout-justify-content] :as parent} layout-bounds layout-lines]
(let [layout-width (gpo/width-points layout-bounds) (let [layout-width (gpo/width-points layout-bounds)
layout-height (gpo/height-points layout-bounds) layout-height (gpo/height-points layout-bounds)
[layout-gap-row layout-gap-col] (gaps parent)
row? (row? parent) row? (row? parent)
col? (col? parent) col? (col? parent)
space-between? (= :space-between (:layout-type parent)) space-between? (= layout-justify-content :space-between)
space-around? (= :space-around (:layout-type parent)) space-around? (= layout-justify-content :space-around)
h-center? (h-center? parent) h-center? (h-center? parent)
h-end? (h-end? parent) h-end? (h-end? parent)
v-center? (v-center? parent) v-center? (v-center? parent)
@ -148,61 +190,62 @@
[total-width total-height] [total-width total-height]
(cond-> (gpo/origin layout-bounds) (cond-> (gpo/origin layout-bounds)
(and row? h-center?) (and col? h-center?)
(gpt/add (xv (/ (- layout-width total-width) 2))) (gpt/add (xv (/ (- layout-width total-width) 2)))
(and row? h-end?) (and col? h-end?)
(gpt/add (xv (- layout-width total-width))) (gpt/add (xv (- layout-width total-width)))
(and col? v-center?) (and row? v-center?)
(gpt/add (yv (/ (- layout-height total-height) 2))) (gpt/add (yv (/ (- layout-height total-height) 2)))
(and col? v-end?) (and row? v-end?)
(gpt/add (yv (- layout-height total-height))))) (gpt/add (yv (- layout-height total-height)))))
(get-start-line (get-start-line
[{:keys [line-width line-height num-children child-fill?]} base-p] [{:keys [line-width line-height num-children child-fill?]} base-p]
(let [children-gap (* layout-gap (dec num-children)) (let [children-gap-width (* layout-gap-row (dec num-children))
children-gap-height (* layout-gap-col (dec num-children))
line-width (if (and col? child-fill?) line-width (if (and row? child-fill?)
(- layout-width (* layout-gap (dec num-children))) (- layout-width (* layout-gap-row (dec num-children)))
line-width) line-width)
line-height (if (and row? child-fill?) line-height (if (and col? child-fill?)
(- layout-height (* layout-gap (dec num-children))) (- layout-height (* layout-gap-col (dec num-children)))
line-height) line-height)
start-p start-p
(cond-> base-p (cond-> base-p
;; X AXIS ;; X AXIS
(and col? h-center? (not space-around?) (not space-between?)) (and row? h-center? (not space-around?) (not space-between?))
(-> (gpt/add (xv (/ layout-width 2))) (-> (gpt/add (xv (/ layout-width 2)))
(gpt/subtract (xv (/ (+ line-width children-gap) 2)))) (gpt/subtract (xv (/ (+ line-width children-gap-width) 2))))
(and col? h-end? (not space-around?) (not space-between?)) (and row? h-end? (not space-around?) (not space-between?))
(-> (gpt/add (xv layout-width)) (-> (gpt/add (xv layout-width))
(gpt/subtract (xv (+ line-width children-gap)))) (gpt/subtract (xv (+ line-width children-gap-width))))
(and row? h-center?) (and col? h-center?)
(gpt/add (xv (/ line-width 2))) (gpt/add (xv (/ line-width 2)))
(and row? h-end?) (and col? h-end?)
(gpt/add (xv line-width)) (gpt/add (xv line-width))
;; Y AXIS ;; Y AXIS
(and row? v-center? (not space-around?) (not space-between?)) (and col? v-center? (not space-around?) (not space-between?))
(-> (gpt/add (yv (/ layout-height 2))) (-> (gpt/add (yv (/ layout-height 2)))
(gpt/subtract (yv (/ (+ line-height children-gap) 2)))) (gpt/subtract (yv (/ (+ line-height children-gap-height) 2))))
(and row? v-end? (not space-around?) (not space-between?)) (and col? v-end? (not space-around?) (not space-between?))
(-> (gpt/add (yv layout-height)) (-> (gpt/add (yv layout-height))
(gpt/subtract (yv (+ line-height children-gap)))) (gpt/subtract (yv (+ line-height children-gap-height))))
(and col? v-center?) (and row? v-center?)
(gpt/add (yv (/ line-height 2))) (gpt/add (yv (/ line-height 2)))
(and col? v-end?) (and row? v-end?)
(gpt/add (yv line-height)))] (gpt/add (yv line-height)))]
start-p)) start-p))
@ -211,11 +254,11 @@
[{:keys [line-width line-height]} base-p] [{:keys [line-width line-height]} base-p]
(cond-> base-p (cond-> base-p
row?
(gpt/add (xv (+ line-width layout-gap)))
col? col?
(gpt/add (yv (+ line-height layout-gap))))) (gpt/add (xv (+ line-width layout-gap-row)))
row?
(gpt/add (yv (+ line-height layout-gap-col)))))
(add-lines [[total-width total-height] {:keys [line-width line-height]}] (add-lines [[total-width total-height] {:keys [line-width line-height]}]
[(+ total-width line-width) [(+ total-width line-width)
@ -230,24 +273,25 @@
(let [[total-width total-height] (->> layout-lines (reduce add-lines [0 0])) (let [[total-width total-height] (->> layout-lines (reduce add-lines [0 0]))
total-width (+ total-width (* layout-gap (dec (count layout-lines)))) total-width (+ total-width (* layout-gap-row (dec (count layout-lines))))
total-height (+ total-height (* layout-gap (dec (count layout-lines)))) total-height (+ total-height (* layout-gap-col (dec (count layout-lines))))
vertical-fill-space (- layout-height total-height) vertical-fill-space (- layout-height total-height)
horizontal-fill-space (- layout-width total-width) horizontal-fill-space (- layout-width total-width)
num-line-fill (count (->> layout-lines (filter :line-fill?))) num-line-fill (count (->> layout-lines (filter :line-fill?)))
layout-lines layout-lines
(->> layout-lines (->> layout-lines
(mapv #(cond-> % (mapv #(cond-> %
(and col? (:line-fill? %)) (and row? (:line-fill? %))
(update :line-height + (/ vertical-fill-space num-line-fill)) (update :line-height + (/ vertical-fill-space num-line-fill))
(and row? (:line-fill? %)) (and col? (:line-fill? %))
(update :line-width + (/ horizontal-fill-space num-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 col? (> num-line-fill 0)) layout-width total-width)
total-width (if (and row? (> num-line-fill 0)) layout-width total-width) total-height (if (and row? (> num-line-fill 0)) layout-height total-height)
base-p (get-base-line total-width total-height) base-p (get-base-line total-width total-height)
@ -257,40 +301,54 @@
(defn calc-layout-line-data (defn calc-layout-line-data
"Calculates the baseline for a flex layout" "Calculates the baseline for a flex layout"
[{:keys [layout-type layout-gap] :as shape} [{:keys [layout-justify-content] :as shape}
layout-bounds layout-bounds
{:keys [num-children line-width line-height child-fill?] :as line-data}] {:keys [num-children line-width line-height] :as line-data}]
(let [width (gpo/width-points layout-bounds) (let [width (gpo/width-points layout-bounds)
height (gpo/height-points layout-bounds) height (gpo/height-points layout-bounds)
layout-gap row? (row? shape)
(cond col? (col? shape)
(or (= :packed layout-type) child-fill?) space-between? (= layout-justify-content :space-between)
layout-gap space-around? (= layout-justify-content :space-around)
(= :space-around layout-type) [layout-gap-row layout-gap-col] (gaps shape)
0
(and (col? shape) (= :space-between layout-type)) layout-gap-row
(/ (- width line-width) (dec num-children)) (cond (and row? space-around?)
0
(and (row? shape) (= :space-between layout-type)) (and row? space-between?)
(/ (- height line-height) (dec num-children))) (/ (- width line-width) (dec num-children))
:else
layout-gap-row)
layout-gap-col
(cond (and col? space-around?)
0
(and col? space-between?)
(/ (- height line-height) (dec num-children))
:else
layout-gap-col)
margin-x margin-x
(if (and (col? shape) (= :space-around layout-type)) (if (and row? space-around?)
(/ (- width line-width) (inc num-children)) (/ (- width line-width) (inc num-children))
0) 0)
margin-y margin-y
(if (and (row? shape) (= :space-around layout-type)) (if (and col? space-around?)
(/ (- height line-height) (inc num-children)) (/ (- height line-height) (inc num-children))
0)] 0)]
(assoc line-data (assoc line-data
:layout-bounds layout-bounds :layout-bounds layout-bounds
:layout-gap layout-gap :layout-gap-row layout-gap-row
:layout-gap-col layout-gap-col
:margin-x margin-x :margin-x margin-x
:margin-y margin-y))) :margin-y margin-y)))
@ -298,7 +356,7 @@
"Calculates the position for the current shape given the layout-data context" "Calculates the position for the current shape given the layout-data context"
[parent [parent
child-width child-height child-width child-height
{:keys [start-p layout-gap margin-x margin-y] :as layout-data}] {:keys [start-p layout-gap-row layout-gap-col margin-x margin-y] :as layout-data}]
(let [row? (row? parent) (let [row? (row? parent)
col? (col? parent) col? (col? parent)
@ -314,16 +372,16 @@
corner-p corner-p
(cond-> start-p (cond-> start-p
(and row? h-center?) (and col? h-center?)
(gpt/add (xv (- (/ child-width 2)))) (gpt/add (xv (- (/ child-width 2))))
(and row? h-end?) (and col? h-end?)
(gpt/add (xv (- child-width))) (gpt/add (xv (- child-width)))
(and col? v-center?) (and row? v-center?)
(gpt/add (yv (- (/ child-height 2)))) (gpt/add (yv (- (/ child-height 2))))
(and col? v-end?) (and row? v-end?)
(gpt/add (yv (- child-height))) (gpt/add (yv (- child-height)))
(some? margin-x) (some? margin-x)
@ -334,11 +392,11 @@
next-p next-p
(cond-> start-p (cond-> start-p
col?
(gpt/add (xv (+ child-width layout-gap)))
row? row?
(gpt/add (yv (+ child-height layout-gap))) (gpt/add (xv (+ child-width layout-gap-row)))
col?
(gpt/add (yv (+ child-height layout-gap-col)))
(some? margin-x) (some? margin-x)
(gpt/add (xv margin-x)) (gpt/add (xv margin-x))
@ -353,46 +411,48 @@
(defn calc-fill-width-data (defn calc-fill-width-data
"Calculates the size and modifiers for the width of an auto-fill child" "Calculates the size and modifiers for the width of an auto-fill child"
[{:keys [layout-gap transform transform-inverse] :as parent} [{:keys [transform transform-inverse] :as parent}
{:keys [layout-h-behavior] :as child} {:keys [layout-h-behavior] :as child}
child-origin child-width child-origin child-width
{:keys [num-children line-width line-fill? child-fill? layout-bounds] :as layout-data}] {:keys [num-children line-width line-fill? child-fill? layout-bounds] :as layout-data}]
(cond (let [[layout-gap-row _] (gaps parent)]
(and (col? parent) (= :fill layout-h-behavior) child-fill?) (cond
(let [layout-width (gpo/width-points layout-bounds) (and (row? parent) (= :fill layout-h-behavior) child-fill?)
fill-space (- layout-width line-width (* layout-gap (dec num-children))) (let [layout-width (gpo/width-points layout-bounds)
fill-width (/ fill-space (:num-child-fill layout-data)) fill-space (- layout-width line-width (* layout-gap-row (dec num-children)))
fill-scale (/ fill-width child-width)] fill-width (/ fill-space (:num-child-fill layout-data))
fill-scale (/ fill-width child-width)]
{:width fill-width {:width fill-width
:modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}) :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)})
(and (row? parent) (= :fill layout-h-behavior) line-fill?) (and (col? parent) (= :fill layout-h-behavior) line-fill?)
(let [fill-scale (/ line-width child-width)] (let [fill-scale (/ line-width child-width)]
{:width line-width {:width line-width
:modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}))) :modifiers (ctm/resize (gpt/point fill-scale 1) child-origin transform transform-inverse)}))))
(defn calc-fill-height-data (defn calc-fill-height-data
"Calculates the size and modifiers for the height of an auto-fill child" "Calculates the size and modifiers for the height of an auto-fill child"
[{:keys [layout-gap transform transform-inverse] :as parent} [{:keys [transform transform-inverse] :as parent}
{:keys [layout-v-behavior] :as child} {:keys [layout-v-behavior] :as child}
child-origin child-height child-origin child-height
{:keys [num-children line-height layout-bounds line-fill? child-fill?] :as layout-data}] {:keys [num-children line-height layout-bounds line-fill? child-fill?] :as layout-data}]
(cond (let [[_ layout-gap-col] (gaps parent)]
(and (row? parent) (= :fill layout-v-behavior) child-fill?) (cond
(let [layout-height (gpo/height-points layout-bounds) (and (col? parent) (= :fill layout-v-behavior) child-fill?)
fill-space (- layout-height line-height (* layout-gap (dec num-children))) (let [layout-height (gpo/height-points layout-bounds)
fill-height (/ fill-space (:num-child-fill layout-data)) fill-space (- layout-height line-height (* layout-gap-col (dec num-children)))
fill-scale (/ fill-height child-height)] fill-height (/ fill-space (:num-child-fill layout-data))
{:height fill-height fill-scale (/ fill-height child-height)]
:modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}) {:height fill-height
:modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)})
(and (col? parent) (= :fill layout-v-behavior) line-fill?) (and (row? parent) (= :fill layout-v-behavior) line-fill?)
(let [fill-scale (/ line-height child-height)] (let [fill-scale (/ line-height child-height)]
{:height line-height {:height line-height
:modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}))) :modifiers (ctm/resize (gpt/point 1 fill-scale) child-origin transform transform-inverse)}))))
(defn normalize-child-modifiers (defn normalize-child-modifiers
"Apply the modifiers and then normalized them against the parent coordinates" "Apply the modifiers and then normalized them against the parent coordinates"
@ -412,7 +472,7 @@
(defn calc-layout-data (defn calc-layout-data
"Digest the layout data to pass it to the constrains" "Digest the layout data to pass it to the constrains"
[{:keys [layout-dir layout-padding layout-padding-type] :as parent} children] [{:keys [layout-flex-dir layout-padding layout-padding-type] :as parent} children]
(let [;; Add padding to the bounds (let [;; Add padding to the bounds
{pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding {pad-top :p1 pad-right :p2 pad-bottom :p3 pad-left :p4} layout-padding
@ -427,7 +487,7 @@
layout-bounds (gpo/pad-points points pad-top pad-right pad-bottom pad-left) layout-bounds (gpo/pad-points points pad-top pad-right pad-bottom pad-left)
;; Reverse ;; Reverse
reverse? (or (= :left layout-dir) (= :bottom layout-dir)) reverse? (or (= :reverse-row layout-flex-dir) (= :reverse-column layout-flex-dir))
children (cond->> children reverse? reverse) children (cond->> children reverse? reverse)
;; Creates the layout lines information ;; Creates the layout lines information
@ -476,7 +536,9 @@
h-end? (and row? (h-end? frame)) h-end? (and row? (h-end? frame))
v-center? (and col? (v-center? frame)) v-center? (and col? (v-center? frame))
v-end? (and row? (v-end? frame)) v-end? (and row? (v-end? frame))
layout-gap (:layout-gap frame 0) layout-gap-row (or (-> frame :layout-gap :row-gap) 0)
;;layout-gap-col (or (-> frame :layout-gap :column-gap) 0)
layout-gap layout-gap-row ;; TODO LAYOUT: FIXME
reverse? (:reverse? layout-data) reverse? (:reverse? layout-data)
children (vec (cond->> (d/enumerate children) children (vec (cond->> (d/enumerate children)
@ -499,31 +561,31 @@
box-width (-> child :selrect :width) box-width (-> child :selrect :width)
box-height (-> child :selrect :height) box-height (-> child :selrect :height)
x (if row? (:x parent-rect) prev-x) x (if col? (:x parent-rect) prev-x)
y (if col? (:y parent-rect) prev-y) y (if row? (:y parent-rect) prev-y)
width (cond width (cond
(and col? last?) (and row? last?)
(- (+ (:x parent-rect) (:width parent-rect)) x) (- (+ (:x parent-rect) (:width parent-rect)) x)
row? col?
(:width parent-rect) (:width parent-rect)
:else :else
(+ box-width (- box-x prev-x) (/ layout-gap 2))) (+ box-width (- box-x prev-x) (/ layout-gap 2)))
height (cond height (cond
(and row? last?) (and col? last?)
(- (+ (:y parent-rect) (:height parent-rect)) y) (- (+ (:y parent-rect) (:height parent-rect)) y)
col? row?
(:height parent-rect) (:height parent-rect)
:else :else
(+ box-height (- box-y prev-y) (/ layout-gap 2))) (+ box-height (- box-y prev-y) (/ layout-gap 2)))
[line-area-1 line-area-2] [line-area-1 line-area-2]
(if col? (if row?
(let [half-point-width (+ (- box-x x) (/ box-width 2))] (let [half-point-width (+ (- box-x x) (/ box-width 2))]
[(-> (gsr/make-rect x y half-point-width height) [(-> (gsr/make-rect x y half-point-width height)
(assoc :index (if reverse? (inc index) index))) (assoc :index (if reverse? (inc index) index)))
@ -555,16 +617,16 @@
last? (nil? next) last? (nil? next)
line-width line-width
(if col? (if row?
(:width frame) (:width frame)
(+ line-width margin-x (+ line-width margin-x
(if col? (* layout-gap (dec num-children)) 0))) (if row? (* layout-gap (dec num-children)) 0)))
line-height line-height
(if row? (if col?
(:height frame) (:height frame)
(+ line-height margin-y (+ line-height margin-y
(if row? (if col?
(* layout-gap (dec num-children)) (* layout-gap (dec num-children))
0))) 0)))
@ -582,24 +644,24 @@
v-end? line-height v-end? line-height
:else 0)) :else 0))
x (if col? (:x frame) prev-x) x (if row? (:x frame) prev-x)
y (if row? (:y frame) prev-y) y (if col? (:y frame) prev-y)
width (cond width (cond
(and row? last?) (and col? last?)
(- (+ (:x frame) (:width frame)) x) (- (+ (:x frame) (:width frame)) x)
col? row?
(:width frame) (:width frame)
:else :else
(+ line-width (- box-x prev-x) (/ layout-gap 2))) (+ line-width (- box-x prev-x) (/ layout-gap 2)))
height (cond height (cond
(and col? last?) (and row? last?)
(- (+ (:y frame) (:height frame)) y) (- (+ (:y frame) (:height frame)) y)
row? col?
(:height frame) (:height frame)
:else :else

View file

@ -8,9 +8,10 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.layout :as gcl] [app.common.geom.shapes.flex-layout :as gcl]
[app.common.geom.shapes.pixel-precision :as gpp] [app.common.geom.shapes.pixel-precision :as gpp]
[app.common.geom.shapes.transforms :as gtr] [app.common.geom.shapes.transforms :as gtr]
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm] [app.common.types.modifiers :as ctm]
[app.common.uuid :as uuid])) [app.common.uuid :as uuid]))
@ -101,7 +102,7 @@
modif-tree))))) modif-tree)))))
(defn get-first-layout (defn get-tree-root
[id objects] [id objects]
(loop [current id (loop [current id
@ -127,24 +128,40 @@
(recur (:id parent) result))))) (recur (:id parent) result)))))
(defn resolve-tree-sequence (defn resolve-tree-sequence
;; TODO LAYOUT: Esta ahora puesto al zero pero tiene que mirar todas las raices
"Given the ids that have changed search for layout roots to recalculate" "Given the ids that have changed search for layout roots to recalculate"
[_ids objects] [modif-tree objects]
(->> (tree-seq
#(d/not-empty? (get-in objects [% :shapes]))
#(get-in objects [% :shapes])
uuid/zero)
(map #(get objects %)))) (let [redfn
(fn [result id]
(if (= id uuid/zero)
result
(let [root (get-tree-root id objects)
(defn resolve-layout-ids ;; Remove the children from the current root
"Given a list of ids, resolve the parent layouts that will need to update. This will go upwards result
in the tree while a layout is found" (into #{} (remove #(cph/is-child? objects root %)) result)
[ids objects]
(into (d/ordered-set) contains-parent?
(map #(get-first-layout % objects)) (some #(cph/is-child? objects % root) result)]
ids))
(cond-> result
(not contains-parent?)
(conj root)))))
generate-tree
(fn [id]
(->> (tree-seq
#(d/not-empty? (get-in objects [% :shapes]))
#(get-in objects [% :shapes])
id)
(map #(get objects %))))
roots (->> modif-tree keys (reduce redfn #{}))]
(concat
(when (contains? modif-tree uuid/zero) [(get objects uuid/zero)])
(mapcat generate-tree roots))))
(defn inside-layout? (defn inside-layout?
[objects shape] [objects shape]
@ -170,34 +187,31 @@
;; modif-tree)))) ;; modif-tree))))
(defn set-objects-modifiers (defn set-objects-modifiers
[ids objects get-modifier ignore-constraints snap-pixel?] [modif-tree objects ignore-constraints snap-pixel?]
(let [set-modifiers (let [shapes-tree (resolve-tree-sequence modif-tree objects)
(fn [modif-tree id]
(let [root? (= uuid/zero id)
shape (get objects id)
modifiers (cond-> (get-modifier shape)
(and (not root?) snap-pixel?)
(gpp/set-pixel-precision shape))]
(-> modif-tree
(assoc id {:modifiers modifiers}))))
modif-tree (reduce set-modifiers {} ids)
shapes-tree (resolve-tree-sequence ids objects)
modif-tree modif-tree
(->> shapes-tree (->> shapes-tree
(reduce (reduce
(fn [modif-tree shape] (fn [modif-tree shape]
(let [root? (= uuid/zero (:id shape)) (let [root? (= uuid/zero (:id shape))
modifiers (get-in modif-tree [(:id shape) :modifiers]) modifiers (get-in modif-tree [(:id shape) :modifiers])
has-modifiers? (some? modifiers) modifiers (cond-> modifiers
(and (not root?) (ctm/has-geometry? modifiers) snap-pixel?)
(gpp/set-pixel-precision shape))
modif-tree (-> modif-tree (assoc-in [(:id shape) :modifiers] modifiers))
has-modifiers? (ctm/child-modifiers? modifiers)
is-layout? (layout? shape) is-layout? (layout? shape)
is-parent? (or (group? shape) (and (frame? shape) (not (layout? shape)))) is-parent? (or (group? shape) (and (frame? shape) (not (layout? shape))))
;; If the current child is inside the layout we ignore the constraints ;; If the current child is inside the layout we ignore the constraints
is-inside-layout? (inside-layout? objects shape)] is-inside-layout? (inside-layout? objects shape)]
(cond-> modif-tree (cond-> modif-tree
(and has-modifiers? is-parent? (not root?)) (and has-modifiers? is-parent? (not root?))
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?) (set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)
@ -207,6 +221,6 @@
modif-tree))] modif-tree))]
;; #?(:cljs ;;#?(:cljs
;; (.log js/console ">result" (modif->js modif-tree objects))) ;; (.log js/console ">result" (modif->js modif-tree objects)))
modif-tree)) modif-tree))

View file

@ -31,8 +31,10 @@
ratio-width (/ target-width curr-width) ratio-width (/ target-width curr-width)
ratio-height (/ target-height curr-height) ratio-height (/ target-height curr-height)
scalev (gpt/point ratio-width ratio-height)] scalev (gpt/point ratio-width ratio-height)]
(-> modifiers (cond-> modifiers
(ctm/set-resize scalev origin transform transform-inverse)))) (or (not (mth/almost-zero? (- ratio-width 1)))
(not (mth/almost-zero? (- ratio-height 1))))
(ctm/set-resize scalev origin transform transform-inverse))))
(defn position-pixel-precision (defn position-pixel-precision
[modifiers shape] [modifiers shape]
@ -41,8 +43,10 @@
corner (gpt/point bounds) corner (gpt/point bounds)
target-corner (gpt/round corner) target-corner (gpt/round corner)
deltav (gpt/to-vec corner target-corner)] deltav (gpt/to-vec corner target-corner)]
(-> modifiers (cond-> modifiers
(ctm/set-move deltav)))) (or (not (mth/almost-zero? (:x deltav)))
(not (mth/almost-zero? (:y deltav))))
(ctm/set-move deltav))))
(defn set-pixel-precision (defn set-pixel-precision
"Adjust modifiers so they adjust to the pixel grid" "Adjust modifiers so they adjust to the pixel grid"

View file

@ -24,7 +24,8 @@
;; - structure-parent: Structure non recursive ;; - structure-parent: Structure non recursive
;; * add-children ;; * add-children
;; * remove-children ;; * remove-children
;; - structure-child: Structre recursive ;; * reflow
;; - structure-child: Structure recursive
;; * scale-content ;; * scale-content
;; ;;
@ -47,44 +48,48 @@
([modifiers vector origin] ([modifiers vector origin]
(-> modifiers (-> modifiers
(update :geometry conjv {:type :resize (update :geometry conjv {:type :resize
:vector vector :vector vector
:origin origin}))) :origin origin})))
([modifiers vector origin transform transform-inverse] ([modifiers vector origin transform transform-inverse]
(-> modifiers (-> modifiers
(update :geometry conjv {:type :resize (update :geometry conjv {:type :resize
:vector vector :vector vector
:origin origin :origin origin
:transform transform :transform transform
:transform-inverse transform-inverse})))) :transform-inverse transform-inverse}))))
(defn set-rotation (defn set-rotation
[modifiers center angle] [modifiers center angle]
(-> modifiers (-> modifiers
(update :geometry conjv {:type :rotation (update :geometry conjv {:type :rotation
:center center :center center
:rotation angle}))) :rotation angle})))
(defn set-remove-children (defn set-remove-children
[modifiers shapes] [modifiers shapes]
(-> modifiers (-> modifiers
(update :structure-parent conjv {:type :remove-children (update :structure-parent conjv {:type :remove-children
:value shapes})) :value shapes}))
) )
(defn set-add-children (defn set-add-children
[modifiers shapes index] [modifiers shapes index]
(-> modifiers (-> modifiers
(update :structure-parent conjv {:type :add-children (update :structure-parent conjv {:type :add-children
:value shapes :value shapes
:index index}))) :index index})))
(defn set-reflow
[modifiers]
(-> modifiers
(update :structure-parent conjv {:type :reflow})))
(defn set-scale-content (defn set-scale-content
[modifiers value] [modifiers value]
(-> modifiers (-> modifiers
(update :structure-child conjv {:type :scale-content :value value}))) (update :structure-child conjv {:type :scale-content :value value})))
(defn add-modifiers (defn add-modifiers
[modifiers new-modifiers] [modifiers new-modifiers]
@ -124,7 +129,7 @@
(-> (empty-modifiers) (-> (empty-modifiers)
(set-rotation shape-center angle) (set-rotation shape-center angle)
(set-move (gpt/transform (gpt/point 1 1) rotation))))) (set-move (gpt/transform (gpt/point 0 0) rotation)))))
(defn remove-children (defn remove-children
[shapes] [shapes]
@ -136,11 +141,21 @@
(-> (empty-modifiers) (-> (empty-modifiers)
(set-add-children shapes index))) (set-add-children shapes index)))
(defn reflow
[]
(-> (empty-modifiers)
(set-reflow)))
(defn scale-content (defn scale-content
[value] [value]
(-> (empty-modifiers) (-> (empty-modifiers)
(set-scale-content value))) (set-scale-content value)))
(defn child-modifiers?
[{:keys [geometry structure-child]}]
(or (d/not-empty? geometry)
(d/not-empty? structure-child)))
(defn select-child-modifiers (defn select-child-modifiers
[modifiers] [modifiers]
(select-keys modifiers [:geometry :structure-child])) (select-keys modifiers [:geometry :structure-child]))
@ -337,3 +352,7 @@
(as-> shape $ (as-> shape $
(reduce apply-modifier $ (:structure-parent modifiers)) (reduce apply-modifier $ (:structure-parent modifiers))
(reduce apply-modifier $ (:structure-child modifiers))))) (reduce apply-modifier $ (:structure-child modifiers)))))
(defn has-geometry?
[{:keys [geometry]}]
(d/not-empty? geometry))

View file

@ -10,6 +10,7 @@
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.math :as mth :refer [close?]] [app.common.math :as mth :refer [close?]]
[app.common.types.modifiers :as ctm]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[clojure.test :as t])) [clojure.test :as t]))
@ -59,7 +60,7 @@
(t/testing "Transform shape with translation modifiers" (t/testing "Transform shape with translation modifiers"
(t/are [type] (t/are [type]
(let [modifiers {:displacement (gmt/translate-matrix (gpt/point 10 -10))}] (let [modifiers (ctm/move (gpt/point 10 -10))]
(let [shape-before (create-test-shape type {:modifiers modifiers}) (let [shape-before (create-test-shape type {:modifiers modifiers})
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(t/is (not= shape-before shape-after)) (t/is (not= shape-before shape-after))
@ -91,9 +92,7 @@
(t/testing "Transform shape with resize modifiers" (t/testing "Transform shape with resize modifiers"
(t/are [type] (t/are [type]
(let [modifiers {:resize-origin (gpt/point 0 0) (let [modifiers (ctm/resize (gpt/point 2 2) (gpt/point 0 0))
:resize-vector (gpt/point 2 2)
:resize-transform (gmt/matrix)}
shape-before (create-test-shape type {:modifiers modifiers}) shape-before (create-test-shape type {:modifiers modifiers})
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(t/is (not= shape-before shape-after)) (t/is (not= shape-before shape-after))
@ -113,9 +112,7 @@
(t/testing "Transform with empty resize" (t/testing "Transform with empty resize"
(t/are [type] (t/are [type]
(let [modifiers {:resize-origin (gpt/point 0 0) (let [modifiers (ctm/resize (gpt/point 1 1) (gpt/point 0 0))
:resize-vector (gpt/point 1 1)
:resize-transform (gmt/matrix)}
shape-before (create-test-shape type {:modifiers modifiers}) shape-before (create-test-shape type {:modifiers modifiers})
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(t/are [prop] (t/are [prop]
@ -126,9 +123,7 @@
(t/testing "Transform with resize=0" (t/testing "Transform with resize=0"
(t/are [type] (t/are [type]
(let [modifiers {:resize-origin (gpt/point 0 0) (let [modifiers (ctm/resize (gpt/point 0 0) (gpt/point 0 0))
:resize-vector (gpt/point 0 0)
:resize-transform (gmt/matrix)}
shape-before (create-test-shape type {:modifiers modifiers}) shape-before (create-test-shape type {:modifiers modifiers})
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(t/is (> (get-in shape-before [:selrect :width]) (t/is (> (get-in shape-before [:selrect :width])
@ -142,13 +137,13 @@
(t/testing "Transform shape with rotation modifiers" (t/testing "Transform shape with rotation modifiers"
(t/are [type] (t/are [type]
(let [modifiers {:rotation 30} (let [shape-before (create-test-shape type)
shape-before (create-test-shape type {:modifiers modifiers}) modifiers (ctm/rotation shape-before (gsh/center-shape shape-before) 30 )
shape-before (assoc shape-before :modifiers modifiers)
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(t/is (not= shape-before shape-after)) (t/is (not= (:selrect shape-before) (:selrect shape-after)))
;; Selrect won't change with a rotation, but points will
(t/is (close? (get-in shape-before [:selrect :x]) (t/is (close? (get-in shape-before [:selrect :x])
(get-in shape-after [:selrect :x]))) (get-in shape-after [:selrect :x])))
@ -166,9 +161,9 @@
(t/testing "Transform shape with rotation = 0 should leave equal selrect" (t/testing "Transform shape with rotation = 0 should leave equal selrect"
(t/are [type] (t/are [type]
(let [modifiers {:rotation 0} (let [shape-before (create-test-shape type)
shape-before (create-test-shape type {:modifiers modifiers}) modifiers (ctm/rotation shape-before (gsh/center-shape shape-before) 0)
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape (assoc shape-before :modifiers modifiers))]
(t/are [prop] (t/are [prop]
(t/is (close? (get-in shape-before [:selrect prop]) (t/is (close? (get-in shape-before [:selrect prop])
(get-in shape-after [:selrect prop]))) (get-in shape-after [:selrect prop])))
@ -177,12 +172,13 @@
(t/testing "Transform shape with invalid selrect fails gracefully" (t/testing "Transform shape with invalid selrect fails gracefully"
(t/are [type selrect] (t/are [type selrect]
(let [modifiers {:displacement (gmt/matrix)} (let [modifiers (ctm/move 0 0)
shape-before (-> (create-test-shape type {:modifiers modifiers}) shape-before (-> (create-test-shape type {:modifiers modifiers})
(assoc :selrect selrect)) (assoc :selrect selrect))
shape-after (gsh/transform-shape shape-before)] shape-after (gsh/transform-shape shape-before)]
(= (:selrect shape-before)
(:selrect shape-after))) (t/is (not= (:selrect shape-before)
(:selrect shape-after))))
:rect {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf} :rect {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf}
:path {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf} :path {:x 0.0 :y 0.0 :x1 0.0 :y1 0.0 :x2 ##Inf :y2 ##Inf :width ##Inf :height ##Inf}

View file

@ -8,6 +8,7 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
[app.main.data.workspace.changes :as dwc] [app.main.data.workspace.changes :as dwc]
[app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.transforms :as dwt]
@ -25,8 +26,7 @@
:layout-wrap-type :layout-wrap-type
:layout-padding-type :layout-padding-type
:layout-padding :layout-padding
]) :layout-gap-type])
(def initial-flex-layout (def initial-flex-layout
{:layout :flex {:layout :flex
@ -51,8 +51,9 @@
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
ids (->> ids (filter #(get-in objects [% :layout])))] ids (->> ids (filter #(get-in objects [% :layout])))]
(if (d/not-empty? ids) (if (d/not-empty? ids)
(rx/of (dwt/set-modifiers ids) (let [modif-tree (dwt/create-modif-tree ids (ctm/reflow))]
(dwt/apply-modifiers)) (rx/of (dwt/set-modifiers modif-tree)
(dwt/apply-modifiers)))
(rx/empty)))))) (rx/empty))))))
;; TODO LAYOUT: Remove constraints from children ;; TODO LAYOUT: Remove constraints from children

View file

@ -11,7 +11,7 @@
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl] [app.common.geom.shapes.flex-layout :as gsl]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.pages.changes-builder :as pcb] [app.common.pages.changes-builder :as pcb]
[app.common.pages.common :as cpc] [app.common.pages.common :as cpc]
@ -117,46 +117,69 @@
(declare get-ignore-tree) (declare get-ignore-tree)
(defn create-modif-tree
[ids modifiers]
(us/verify (s/coll-of uuid?) ids)
(into {} (map #(vector % {:modifiers modifiers})) ids))
(defn build-modif-tree
[ids objects get-modifier]
(us/verify (s/coll-of uuid?) ids)
(into {} (map #(vector % {:modifiers (get-modifier (get objects %))})) ids))
(defn build-change-frame-modifiers
[modif-tree objects selected target-frame position]
(let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
layout? (get-in objects [target-frame :layout])
child-set (set (get-in objects [target-frame :shapes]))
drop-index (when layout? (gsl/get-drop-index target-frame objects position))
update-frame-modifiers
(fn [modif-tree [original-frame shapes]]
(let [shapes (->> shapes (d/removev #(= target-frame %)))
shapes (cond->> shapes
(and layout? (= original-frame target-frame))
;; When movining inside a layout frame remove the shapes that are not immediate children
(filterv #(contains? child-set %)))]
(cond-> modif-tree
(not= original-frame target-frame)
(-> (update-in [original-frame :modifiers] ctm/set-remove-children shapes)
(update-in [target-frame :modifiers] ctm/set-add-children shapes drop-index))
(and layout? (= original-frame target-frame))
(update-in [target-frame :modifiers] ctm/set-add-children shapes drop-index))))]
(reduce update-frame-modifiers modif-tree origin-frame-ids)))
(defn modif->js
[modif-tree objects]
(clj->js (into {}
(map (fn [[k v]]
[(get-in objects [k :name]) v]))
modif-tree)))
(defn set-modifiers (defn set-modifiers
([ids] ([modif-tree]
(set-modifiers ids nil false)) (set-modifiers modif-tree false))
([ids modifiers] ([modif-tree ignore-constraints]
(set-modifiers ids modifiers false)) (set-modifiers modif-tree ignore-constraints false))
([ids modifiers ignore-constraints] ([modif-tree ignore-constraints ignore-snap-pixel]
(set-modifiers ids modifiers ignore-constraints false))
([ids modifiers ignore-constraints ignore-snap-pixel]
(us/verify (s/coll-of uuid?) ids)
(ptk/reify ::set-modifiers (ptk/reify ::set-modifiers
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [objects (wsh/lookup-page-objects state) (let [objects
ids (into #{} (remove #(get-in objects [% :blocked] false)) ids) (wsh/lookup-page-objects state)
snap-pixel? (and (not ignore-snap-pixel) snap-pixel?
(contains? (:workspace-layout state) :snap-pixel-grid)) (and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
workspace-modifiers (:workspace-modifiers state)
modif-tree modif-tree
(gsh/set-objects-modifiers (gsh/set-objects-modifiers modif-tree objects ignore-constraints snap-pixel?)]
;; TODO LAYOUT: I don't like this
(concat (keys workspace-modifiers) ids)
objects
(fn [shape]
(let [
modifiers (if (contains? ids (:id shape)) modifiers (ctm/empty-modifiers))
structure-modifiers (ctm/select-structure (assoc state :workspace-modifiers modif-tree))))))
(get-in state [:workspace-modifiers (:id shape) :modifiers]))]
(cond-> modifiers
(some? structure-modifiers)
(ctm/add-modifiers structure-modifiers))))
ignore-constraints snap-pixel?)]
(update state :workspace-modifiers merge modif-tree))))))
;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints). ;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints).
(defn- set-rotation-modifiers (defn- set-rotation-modifiers
@ -171,8 +194,6 @@
ids ids
(->> shapes (->> shapes
(remove #(get % :blocked false)) (remove #(get % :blocked false))
#_(mapcat #(cph/get-children objects (:id %)))
#_(concat shapes)
(filter #((cpc/editable-attrs (:type %)) :rotation)) (filter #((cpc/editable-attrs (:type %)) :rotation))
(map :id)) (map :id))
@ -181,9 +202,10 @@
(ctm/rotation shape center angle)) (ctm/rotation shape center angle))
modif-tree modif-tree
(gsh/set-objects-modifiers ids objects get-modifier false false)] (-> (build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false false))]
(update state :workspace-modifiers merge modif-tree)))))) (assoc state :workspace-modifiers modif-tree))))))
(defn- update-grow-type (defn- update-grow-type
[shape old-shape] [shape old-shape]
@ -408,9 +430,11 @@
(ctm/set-resize scalev resize-origin shape-transform shape-transform-inverse) (ctm/set-resize scalev resize-origin shape-transform shape-transform-inverse)
(cond-> scale-text (cond-> scale-text
(ctm/set-scale-content (:x scalev))))] (ctm/set-scale-content (:x scalev))))
(rx/of (set-modifiers ids modifiers)))) modif-tree (create-modif-tree ids modifiers)]
(rx/of (set-modifiers modif-tree))))
;; Unifies the instantaneous proportion lock modifier ;; Unifies the instantaneous proportion lock modifier
;; activated by Shift key and the shapes own proportion ;; activated by Shift key and the shapes own proportion
@ -463,7 +487,8 @@
(fn [shape] (ctm/change-dimensions shape attr value)) (fn [shape] (ctm/change-dimensions shape attr value))
modif-tree modif-tree
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] (-> (build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false snap-pixel?))]
(assoc state :workspace-modifiers modif-tree))) (assoc state :workspace-modifiers modif-tree)))
@ -487,7 +512,8 @@
(fn [shape] (ctm/change-orientation-modifiers shape orientation)) (fn [shape] (ctm/change-orientation-modifiers shape orientation))
modif-tree modif-tree
(gsh/set-objects-modifiers ids objects get-modifier false snap-pixel?)] (-> (build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false snap-pixel?))]
(assoc state :workspace-modifiers modif-tree))) (assoc state :workspace-modifiers modif-tree)))
@ -621,37 +647,6 @@
(rx/take 1) (rx/take 1)
(rx/map #(start-move from-position)))))) (rx/map #(start-move from-position))))))
(defn set-change-frame-modifiers
[selected target-frame position]
(ptk/reify ::set-change-frame-modifiers
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
layout? (get-in objects [target-frame :layout])
drop-index
(when layout? (gsl/get-drop-index target-frame objects position))
modif-tree
(into {}
(mapcat
(fn [original-frame]
(let [shapes (->> (get origin-frame-ids original-frame)
(d/removev #(= target-frame %)))]
(cond
(not= original-frame target-frame)
[[original-frame {:modifiers (ctm/remove-children shapes)}]
[target-frame {:modifiers (ctm/add-children shapes drop-index)}]]
layout?
[[target-frame {:modifiers (ctm/add-children shapes drop-index)}]]))))
(keys origin-frame-ids))]
(assoc state :workspace-modifiers modif-tree)))))
(defn- start-move (defn- start-move
([from-position] (start-move from-position nil)) ([from-position] (start-move from-position nil))
@ -699,22 +694,21 @@
(rx/of (finish-transform)) (rx/of (finish-transform))
(rx/concat (rx/concat
(rx/merge (rx/merge
(->> position
(rx/map (fn [delta]
(let [position (gpt/add from-position delta)
target-frame (ctst/top-nested-frame objects position)]
(set-change-frame-modifiers selected target-frame position))))
(rx/take-until stopper))
(->> position (->> position
;; We ask for the snap position but we continue even if the result is not available ;; We ask for the snap position but we continue even if the result is not available
(rx/with-latest vector snap-delta) (rx/with-latest vector snap-delta)
;; We try to use the previous snap so we don't have to wait for the result of the new ;; We try to use the previous snap so we don't have to wait for the result of the new
(rx/map snap/correct-snap-point) (rx/map snap/correct-snap-point)
(rx/map ctm/move)
(rx/map (partial set-modifiers ids)) (rx/map
(fn [move-vector]
(let [position (gpt/add from-position move-vector)
target-frame (ctst/top-nested-frame objects position)]
(-> (create-modif-tree ids (ctm/move move-vector))
(build-change-frame-modifiers objects selected target-frame position)
(set-modifiers)))))
(rx/take-until stopper))) (rx/take-until stopper)))
(rx/of (dwu/start-undo-transaction) (rx/of (dwu/start-undo-transaction)
@ -762,8 +756,8 @@
(rx/merge (rx/merge
(->> move-events (->> move-events
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0)) (rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
(rx/map #(ctm/move %)) (rx/map #(create-modif-tree selected (ctm/move %)))
(rx/map (partial set-modifiers selected)) (rx/map (partial set-modifiers))
(rx/take-until stopper)) (rx/take-until stopper))
(rx/of (move-selected direction shift?))) (rx/of (move-selected direction shift?)))
@ -793,11 +787,12 @@
cpos (gpt/point (:x bbox) (:y bbox)) cpos (gpt/point (:x bbox) (:y bbox))
pos (gpt/point (or (:x position) (:x bbox)) pos (gpt/point (or (:x position) (:x bbox))
(or (:y position) (:y bbox))) (or (:y position) (:y bbox)))
delta (gpt/subtract pos cpos)] delta (gpt/subtract pos cpos)
(rx/of modif-tree (create-modif-tree [id] (ctm/move delta))]
(set-modifiers [id] (ctm/move delta))
(apply-modifiers [id])))))) (rx/of (set-modifiers modif-tree)
(apply-modifiers))))))
(defn- calculate-frame-for-move (defn- calculate-frame-for-move
[ids] [ids]
@ -816,7 +811,11 @@
moving-shapes moving-shapes
(cond->> shapes (cond->> shapes
(not layout?) (not layout?)
(remove #(= (:frame-id %) frame-id))) (remove #(= (:frame-id %) frame-id))
layout?
(remove #(and (= (:frame-id %) frame-id)
(not= (:parent-id %) frame-id))))
drop-index (when layout? (gsl/get-drop-index frame-id objects position)) drop-index (when layout? (gsl/get-drop-index frame-id objects position))
@ -850,13 +849,15 @@
selected (wsh/lookup-selected state {:omit-blocked? true}) selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected) shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes) selrect (gsh/selection-rect shapes)
origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))] origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))
(rx/of (set-modifiers selected modif-tree (create-modif-tree
(-> (ctm/empty-modifiers) selected
(ctm/set-resize (gpt/point -1.0 1.0) origin) (-> (ctm/empty-modifiers)
(ctm/move (gpt/point (:width selrect) 0))) (ctm/set-resize (gpt/point -1.0 1.0) origin)
true) (ctm/move (gpt/point (:width selrect) 0))))]
(rx/of (set-modifiers modif-tree true)
(apply-modifiers)))))) (apply-modifiers))))))
(defn flip-vertical-selected [] (defn flip-vertical-selected []
@ -867,11 +868,13 @@
selected (wsh/lookup-selected state {:omit-blocked? true}) selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected) shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes) selrect (gsh/selection-rect shapes)
origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))] origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))
(rx/of (set-modifiers selected modif-tree (create-modif-tree
(-> (ctm/empty-modifiers) selected
(ctm/set-resize (gpt/point 1.0 -1.0) origin) (-> (ctm/empty-modifiers)
(ctm/move (gpt/point 0 (:height selrect)))) (ctm/set-resize (gpt/point 1.0 -1.0) origin)
true) (ctm/move (gpt/point 0 (:height selrect)))))]
(rx/of (set-modifiers modif-tree true)
(apply-modifiers)))))) (apply-modifiers))))))

View file

@ -358,7 +358,8 @@
"Snaps a position given an old snap to a different position. We use this to provide a temporal "Snaps a position given an old snap to a different position. We use this to provide a temporal
snap while the new is being processed." snap while the new is being processed."
[[position [snap-pos snap-delta]]] [[position [snap-pos snap-delta]]]
(if (some? snap-delta) (if (nil? snap-delta)
position
(let [dx (if (not= 0 (:x snap-delta)) (let [dx (if (not= 0 (:x snap-delta))
(- (+ (:x snap-pos) (:x snap-delta)) (:x position)) (- (+ (:x snap-pos) (:x snap-delta)) (:x position))
0) 0)
@ -372,6 +373,4 @@
dy (if (> (mth/abs dy) snap-accuracy) 0 dy)] dy (if (> (mth/abs dy) snap-accuracy) 0 dy)]
(-> position (-> position
(update :x + dx) (update :x + dx)
(update :y + dy))) (update :y + dy)))))
position))

View file

@ -68,24 +68,21 @@
[:g.frame-children [:g.frame-children
(for [shape shapes] (for [shape shapes]
[:g.ws-shape-wrapper [:g.ws-shape-wrapper {:key (:id shape)}
(cond (cond
(not (cph/frame-shape? shape)) (not (cph/frame-shape? shape))
[:& shape-wrapper [:& shape-wrapper
{:shape shape {:shape shape}]
:key (:id shape)}]
(cph/root-frame? shape) (cph/root-frame? shape)
[:& root-frame-wrapper [:& root-frame-wrapper
{:shape shape {:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape)) :objects (get frame-objects (:id shape))
:thumbnail? (not (contains? active-frames (:id shape)))}] :thumbnail? (not (contains? active-frames (:id shape)))}]
:else :else
[:& nested-frame-wrapper [:& nested-frame-wrapper
{:shape shape {:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape))}])])]]])) :objects (get frame-objects (:id shape))}])])]]]))
(mf/defc shape-wrapper (mf/defc shape-wrapper

View file

@ -84,38 +84,38 @@
[:div.layout-behavior.horizontal [:div.layout-behavior.horizontal
[:button.behavior-btn.tooltip.tooltip-bottom [:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fix width" {:alt "Fix width"
:class (dom/classnames :activated (= layout-h-behavior :fix)) :class (dom/classnames :active (= layout-h-behavior :fix))
:on-click #(on-change-behavior :h :fix)} :on-click #(on-change-behavior :h :fix)}
i/auto-fix-layout] i/auto-fix-layout]
(when fill? (when fill?
[:button.behavior-btn.tooltip.tooltip-bottom [:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Width 100%" {:alt "Width 100%"
:class (dom/classnames :activated (= layout-h-behavior :fill)) :class (dom/classnames :active (= layout-h-behavior :fill))
:on-click #(on-change-behavior :h :fill)} :on-click #(on-change-behavior :h :fill)}
i/auto-fill]) i/auto-fill])
(when auto? (when auto?
[:button.behavior-btn.tooltip.tooltip-bottom [:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fit content" {:alt "Fit content"
:class (dom/classnames :activated (= layout-v-behavior :auto)) :class (dom/classnames :active (= layout-v-behavior :auto))
:on-click #(on-change-behavior :h :auto)} :on-click #(on-change-behavior :h :auto)}
i/auto-hug])] i/auto-hug])]
[:div.layout-behavior [:div.layout-behavior
[:button.behavior-btn.tooltip.tooltip-bottom [:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fix height" {:alt "Fix height"
:class (dom/classnames :activated (= layout-v-behavior :fix)) :class (dom/classnames :active (= layout-v-behavior :fix))
:on-click #(on-change-behavior :v :fix)} :on-click #(on-change-behavior :v :fix)}
i/auto-fix-layout] i/auto-fix-layout]
(when fill? (when fill?
[:button.behavior-btn.tooltip.tooltip-bottom [:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Height 100%" {:alt "Height 100%"
:class (dom/classnames :activated (= layout-v-behavior :fill)) :class (dom/classnames :active (= layout-v-behavior :fill))
:on-click #(on-change-behavior :v :fill)} :on-click #(on-change-behavior :v :fill)}
i/auto-fill]) i/auto-fill])
(when auto? (when auto?
[:button.behavior-btn.tooltip.tooltip-bottom-left [:button.behavior-btn.tooltip.tooltip-bottom-left
{:alt "Fit content" {:alt "Fit content"
:class (dom/classnames :activated (= layout-v-behavior :auto)) :class (dom/classnames :active (= layout-v-behavior :auto))
:on-click #(on-change-behavior :v :auto)} :on-click #(on-change-behavior :v :auto)}
i/auto-hug])]])) i/auto-hug])]]))

View file

@ -47,7 +47,7 @@
[:* [:*
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values}] [:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values}]
(when (or (:layout shape) is-layout-child?) (when is-layout-child?
[:& layout-item-menu [:& layout-item-menu
{:ids ids {:ids ids
:type type :type type

View file

@ -9,7 +9,7 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl] [app.common.geom.shapes.flex-layout :as gsl]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))