Flex layout small fixes

This commit is contained in:
alonso.torres 2022-11-04 14:56:51 +01:00
parent c86d88834e
commit 861eb283e8
9 changed files with 132 additions and 102 deletions

View file

@ -26,7 +26,6 @@
;; [(get-in objects [k :name]) v])) ;; [(get-in objects [k :name]) v]))
;; modif-tree)))) ;; modif-tree))))
(defn set-children-modifiers (defn set-children-modifiers
[modif-tree objects parent ignore-constraints snap-pixel?] [modif-tree objects parent ignore-constraints snap-pixel?]
(let [children (map (d/getf objects) (:shapes parent)) (let [children (map (d/getf objects) (:shapes parent))
@ -52,10 +51,9 @@
(= :frame (:type shape))) (= :frame (:type shape)))
(defn set-layout-modifiers (defn set-layout-modifiers
;; TODO LAYOUT: SNAP PIXEL! [modif-tree objects parent process-child?]
[modif-tree objects parent _snap-pixel?]
(letfn [(process-child [transformed-parent _snap-pixel? modif-tree child] (letfn [(process-child [transformed-parent modif-tree child]
(let [modifiers (get-in modif-tree [(:id parent) :modifiers]) (let [modifiers (get-in modif-tree [(:id parent) :modifiers])
child-modifiers (-> modifiers child-modifiers (-> modifiers
(ctm/select-child-geometry-modifiers) (ctm/select-child-geometry-modifiers)
@ -88,7 +86,9 @@
transformed-parent (gtr/transform-shape parent modifiers) transformed-parent (gtr/transform-shape parent modifiers)
children (map (d/getf objects) (:shapes transformed-parent)) children (map (d/getf objects) (:shapes transformed-parent))
modif-tree (reduce (partial process-child transformed-parent _snap-pixel?) modif-tree children) modif-tree (if process-child?
(reduce (partial process-child transformed-parent) modif-tree children)
modif-tree)
children (->> children (map (partial apply-modifiers modif-tree))) children (->> children (map (partial apply-modifiers modif-tree)))
layout-data (gcl/calc-layout-data transformed-parent children) layout-data (gcl/calc-layout-data transformed-parent children)
@ -169,16 +169,13 @@
result result
;; Frame found, but not layout we return the last layout found (or the id) ;; Frame found, but not layout we return the last layout found (or the id)
(and (and (= :frame (:type parent)) (and (= :frame (:type parent))
(not (ctl/auto-width? parent)) (not (ctl/layout? parent)))
(not (ctl/auto-height? parent)))
(not (:layout parent)))
result result
;; Layout found. We continue upward but we mark this layout ;; Layout found. We continue upward but we mark this layout
(and (= :frame (:type parent)) (ctl/layout? parent)
(:layout parent)) (recur (:id parent) (:id parent))
(:id parent)
;; If group or boolean or other type of group we continue with the last result ;; If group or boolean or other type of group we continue with the last result
:else :else
@ -238,42 +235,50 @@
(recur (:parent-id current)))))) (recur (:parent-id current))))))
(defn- calculate-modifiers (defn- calculate-modifiers
([objects snap-pixel? ignore-constraints [modif-tree recalculate] shape] [objects snap-pixel? ignore-constraints [modif-tree recalculate] shape]
(calculate-modifiers objects snap-pixel? ignore-constraints false [modif-tree recalculate] shape)) (let [shape-id (:id shape)
root? (= uuid/zero shape-id)
modifiers (get-in modif-tree [shape-id :modifiers])
([objects snap-pixel? ignore-constraints ignore-auto? [modif-tree recalculate] shape] modifiers (cond-> modifiers
(let [shape-id (:id shape) (and (not root?) (ctm/has-geometry? modifiers) snap-pixel?)
root? (= uuid/zero shape-id) (gpp/set-pixel-precision shape))
modifiers (get-in modif-tree [shape-id :modifiers])
modifiers (cond-> modifiers modif-tree (-> modif-tree (assoc-in [shape-id :modifiers] modifiers))
(and (not root?) (ctm/has-geometry? modifiers) snap-pixel?)
(gpp/set-pixel-precision shape))
modif-tree (-> modif-tree (assoc-in [shape-id :modifiers] modifiers)) has-modifiers? (ctm/child-modifiers? modifiers)
is-layout? (ctl/layout? shape)
is-auto? (or (ctl/auto-height? shape) (ctl/auto-width? shape))
is-parent? (or (group? shape) (and (frame? shape) (not (ctl/layout? shape))))
has-modifiers? (ctm/child-modifiers? modifiers) ;; If the current child is inside the layout we ignore the constraints
is-layout? (ctl/layout? shape) is-inside-layout? (inside-layout? objects shape)]
is-auto? (or (ctl/auto-height? shape) (ctl/auto-width? shape))
is-parent? (or (group? shape) (and (frame? shape) (not (ctl/layout? shape))))
;; If the current child is inside the layout we ignore the constraints [(cond-> modif-tree
is-inside-layout? (inside-layout? objects shape)] (and has-modifiers? is-parent? (not root?))
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)
[(cond-> modif-tree is-layout?
(and has-modifiers? is-parent? (not root?)) (set-layout-modifiers objects shape true)
(set-children-modifiers objects shape (or ignore-constraints is-inside-layout?) snap-pixel?)
is-layout? is-auto?
(set-layout-modifiers objects shape snap-pixel?) (set-auto-modifiers objects shape))
(and (not ignore-auto?) is-auto?) (cond-> recalculate
(set-auto-modifiers objects shape)) ;; Auto-width/height can change the positions in the parent so we need to recalculate
is-auto?
(conj (:id shape)))]))
(cond-> recalculate (defn- calculate-reflow-layout
;; Auto-width/height can change the positions in the parent so we need to recalculate [objects snap-pixel? modif-tree shape]
(and (not ignore-auto?) is-auto?) (let [is-layout? (ctl/layout? shape)
(conj (:id shape)))]))) is-auto? (or (ctl/auto-height? shape) (ctl/auto-width? shape))]
(cond-> modif-tree
is-layout?
(set-layout-modifiers objects shape false)
is-auto?
(set-auto-modifiers objects shape))))
(defn set-objects-modifiers (defn set-objects-modifiers
[modif-tree objects ignore-constraints snap-pixel?] [modif-tree objects ignore-constraints snap-pixel?]
@ -284,8 +289,19 @@
(reduce (partial calculate-modifiers objects snap-pixel? ignore-constraints) [modif-tree #{}] shapes-tree) (reduce (partial calculate-modifiers objects snap-pixel? ignore-constraints) [modif-tree #{}] shapes-tree)
shapes-tree (resolve-tree-sequence recalculate objects) shapes-tree (resolve-tree-sequence recalculate objects)
[modif-tree _]
(reduce (partial calculate-modifiers objects snap-pixel? ignore-constraints true) [modif-tree #{}] shapes-tree)] ;; We need to go again and recalculate the layout positions+hug
;; TODO LAYOUT: How to remove this recalculus?
modif-tree
(->> shapes-tree
reverse
(filter ctl/layout?)
(reduce (partial calculate-reflow-layout objects snap-pixel?) modif-tree ))
modif-tree
(->> shapes-tree
(filter ctl/layout?)
(reduce (partial calculate-reflow-layout objects snap-pixel?) modif-tree ))]
;;#?(:cljs ;;#?(:cljs
;; (.log js/console ">result" (modif->js modif-tree objects))) ;; (.log js/console ">result" (modif->js modif-tree objects)))

View file

@ -31,10 +31,8 @@
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)]
(cond-> modifiers (-> modifiers
(or (not (mth/almost-zero? (- ratio-width 1))) (ctm/set-resize scalev origin transform transform-inverse))))
(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]
@ -43,10 +41,8 @@
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)]
(cond-> modifiers (-> modifiers
(or (not (mth/almost-zero? (:x deltav))) (ctm/set-move 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

@ -10,6 +10,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.common :as gco] [app.common.geom.shapes.common :as gco]
[app.common.math :as mth]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.spec :as us] [app.common.spec :as us]
[app.common.text :as txt])) [app.common.text :as txt]))
@ -41,73 +42,89 @@
(defn empty-modifiers [] (defn empty-modifiers []
{}) {})
(defn move-vec? [vector]
(or (not (mth/almost-zero? (:x vector)))
(not (mth/almost-zero? (:y vector)))))
(defn resize-vec? [vector]
(or (not (mth/almost-zero? (- (:x vector) 1)))
(not (mth/almost-zero? (- (:y vector) 1)))))
(defn set-move-parent (defn set-move-parent
([modifiers x y] ([modifiers x y]
(set-move-parent modifiers (gpt/point x y))) (set-move-parent modifiers (gpt/point x y)))
([modifiers vector] ([modifiers vector]
(-> modifiers (cond-> modifiers
(update :geometry-parent conjv {:type :move :vector vector})))) (move-vec? vector)
(update :geometry-parent conjv {:type :move :vector vector}))))
(defn set-resize-parent (defn set-resize-parent
([modifiers vector origin] ([modifiers vector origin]
(-> modifiers (cond-> modifiers
(update :geometry-parent conjv {:type :resize (resize-vec? vector)
(update :geometry-parent conjv {:type :resize
:vector vector :vector vector
:origin origin}))) :origin origin})))
([modifiers vector origin transform transform-inverse] ([modifiers vector origin transform transform-inverse]
(-> modifiers (cond-> modifiers
(update :geometry-parent conjv {:type :resize (resize-vec? vector)
:vector vector (update :geometry-parent conjv {:type :resize
:origin origin :vector vector
:transform transform :origin origin
:transform-inverse transform-inverse})))) :transform transform
:transform-inverse transform-inverse}))))
(defn set-move (defn set-move
([modifiers x y] ([modifiers x y]
(set-move modifiers (gpt/point x y))) (set-move modifiers (gpt/point x y)))
([modifiers vector] ([modifiers vector]
(-> modifiers (cond-> modifiers
(update :geometry-child conjv {:type :move :vector vector})))) (move-vec? vector)
(update :geometry-child conjv {:type :move :vector vector}))))
(defn set-resize (defn set-resize
([modifiers vector origin] ([modifiers vector origin]
(-> modifiers (cond-> modifiers
(update :geometry-child conjv {:type :resize (resize-vec? vector)
:vector vector (update :geometry-child conjv {:type :resize
:origin origin}))) :vector vector
:origin origin})))
([modifiers vector origin transform transform-inverse] ([modifiers vector origin transform transform-inverse]
(-> modifiers (cond-> modifiers
(update :geometry-child conjv {:type :resize (resize-vec? vector)
:vector vector (update :geometry-child conjv {:type :resize
:origin origin :vector vector
:transform transform :origin origin
:transform-inverse transform-inverse})))) :transform transform
:transform-inverse transform-inverse}))))
(defn set-rotation (defn set-rotation
[modifiers center angle] [modifiers center angle]
(-> modifiers (cond-> modifiers
(update :structure-child conjv {:type :rotation (not (mth/close? angle 0))
:rotation angle}) (-> (update :structure-child conjv {:type :rotation
(update :geometry-child conjv {:type :rotation :rotation angle})
:center center (update :geometry-child conjv {:type :rotation
:rotation angle}))) :center center
:rotation angle}))))
(defn set-remove-children (defn set-remove-children
[modifiers shapes] [modifiers shapes]
(-> modifiers (cond-> modifiers
(update :structure-parent conjv {:type :remove-children (d/not-empty? shapes)
:value shapes})) (update :structure-parent conjv {:type :remove-children
) :value shapes})))
(defn set-add-children (defn set-add-children
[modifiers shapes index] [modifiers shapes index]
(-> modifiers (cond-> modifiers
(update :structure-parent conjv {:type :add-children (d/not-empty? shapes)
:value shapes (update :structure-parent conjv {:type :add-children
:index index}))) :value shapes
:index index})))
(defn set-reflow (defn set-reflow
[modifiers] [modifiers]

View file

@ -46,15 +46,14 @@
(s/def ::p4 ::us/safe-number) (s/def ::p4 ::us/safe-number)
(s/def ::layout-padding (s/def ::layout-padding
(s/keys :req-un [::p1] (s/keys :opt-un [::p1 ::p2 ::p3 ::p4]))
:opt-un [::p2 ::p3 ::p4]))
(s/def ::row-gap ::us/safe-number) (s/def ::row-gap ::us/safe-number)
(s/def ::column-gap ::us/safe-number) (s/def ::column-gap ::us/safe-number)
(s/def ::layout-type #{:flex :grid}) (s/def ::layout-type #{:flex :grid})
(s/def ::layout-gap (s/def ::layout-gap
(s/keys :req-un [::row-gap ::column-gap])) (s/keys :opt-un [::row-gap ::column-gap]))
(s/def ::layout-container-props (s/def ::layout-container-props
(s/keys :opt-un [::layout (s/keys :opt-un [::layout
@ -74,8 +73,7 @@
(s/def ::m3 ::us/safe-number) (s/def ::m3 ::us/safe-number)
(s/def ::m4 ::us/safe-number) (s/def ::m4 ::us/safe-number)
(s/def ::layout-item-margin (s/keys :req-un [::m1] (s/def ::layout-item-margin (s/keys :opt-un [::m1 ::m2 ::m3 ::m4]))
:opt-un [::m2 ::m3 ::m4]))
(s/def ::layout-item-margin-type #{:simple :multiple}) (s/def ::layout-item-margin-type #{:simple :multiple})
(s/def ::layout-item-h-sizing #{:fill :fix :auto}) (s/def ::layout-item-h-sizing #{:fill :fix :auto})

View file

@ -10,7 +10,6 @@
[app.common.data :as d] [app.common.data :as d]
[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.flex-layout :as gsl]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.pages.common :as cpc] [app.common.pages.common :as cpc]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]

View file

@ -460,9 +460,7 @@
(rx/switch-map (rx/switch-map
(fn [pos] (fn [pos]
(->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos) (->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos)
(rx/map #(vector pos %))))))) (rx/map #(vector pos %)))))))]
drop-frame (atom nil)]
(if (empty? shapes) (if (empty? shapes)
(rx/of (finish-transform)) (rx/of (finish-transform))
(let [move-stream (let [move-stream
@ -496,7 +494,7 @@
(->> move-stream (->> move-stream
(rx/last) (rx/last)
(rx/mapcat (rx/mapcat
(fn [[move-vector target-frame drop-index]] (fn [[_ target-frame drop-index]]
(rx/of (dwu/start-undo-transaction) (rx/of (dwu/start-undo-transaction)
(move-shapes-to-frame ids target-frame drop-index) (move-shapes-to-frame ids target-frame drop-index)
(dwm/apply-modifiers {:undo-transation? false}) (dwm/apply-modifiers {:undo-transation? false})
@ -606,7 +604,7 @@
(pcb/with-objects objects) (pcb/with-objects objects)
(pcb/change-parent frame-id moving-shapes drop-index))] (pcb/change-parent frame-id moving-shapes drop-index))]
(when (and (some? frame-id) (not (empty? changes))) (when (and (some? frame-id) (d/not-empty? changes))
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwc/expand-collapse frame-id))))))) (dwc/expand-collapse frame-id)))))))
@ -637,7 +635,7 @@
selected selected
(-> (ctm/empty-modifiers) (-> (ctm/empty-modifiers)
(ctm/set-resize (gpt/point -1.0 1.0) origin) (ctm/set-resize (gpt/point -1.0 1.0) origin)
(ctm/move (gpt/point (:width selrect) 0))))] (ctm/set-move (gpt/point (:width selrect) 0))))]
(rx/of (dwm/set-modifiers modif-tree true) (rx/of (dwm/set-modifiers modif-tree true)
(dwm/apply-modifiers)))))) (dwm/apply-modifiers))))))
@ -656,7 +654,7 @@
selected selected
(-> (ctm/empty-modifiers) (-> (ctm/empty-modifiers)
(ctm/set-resize (gpt/point 1.0 -1.0) origin) (ctm/set-resize (gpt/point 1.0 -1.0) origin)
(ctm/move (gpt/point 0 (:height selrect)))))] (ctm/set-move (gpt/point 0 (:height selrect)))))]
(rx/of (dwm/set-modifiers modif-tree true) (rx/of (dwm/set-modifiers modif-tree true)
(dwm/apply-modifiers)))))) (dwm/apply-modifiers))))))

View file

@ -6,6 +6,8 @@
(ns app.main.ui.workspace.shapes.path.editor (ns app.main.ui.workspace.shapes.path.editor
(:require (:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.path :as gsp]
[app.common.path.commands :as upc] [app.common.path.commands :as upc]
@ -308,7 +310,7 @@
:start-path? start-p? :start-path? start-p?
:zoom zoom}]]) :zoom zoom}]])
(for [position points] (for [[index position] (d/enumerate points)]
(let [show-handler? (let [show-handler?
(fn [[index prefix]] (fn [[index prefix]]
(let [handler-position (upc/handler->point content index prefix)] (let [handler-position (upc/handler->point content index prefix)]
@ -322,7 +324,7 @@
pos-handlers (->> pos-handlers (filter show-handler?)) pos-handlers (->> pos-handlers (filter show-handler?))
curve? (boolean (seq pos-handlers))] curve? (boolean (seq pos-handlers))]
[:g.path-node [:g.path-node {:key (dm/str index "-" (:x position) "-" (:y position))}
[:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")} [:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")}
(for [[index prefix] pos-handlers] (for [[index prefix] pos-handlers]
(let [handler-position (upc/handler->point content index prefix) (let [handler-position (upc/handler->point content index prefix)

View file

@ -21,6 +21,7 @@
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]] [app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
[app.main.ui.workspace.viewport.utils :as vwu] [app.main.ui.workspace.viewport.utils :as vwu]
[app.util.dom :as dom] [app.util.dom :as dom]
[debug :refer [debug?]]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
(mf/defc pixel-grid (mf/defc pixel-grid
@ -34,8 +35,8 @@
:pattern-units "userSpaceOnUse"} :pattern-units "userSpaceOnUse"}
[:path {:d "M 1 0 L 0 0 0 1" [:path {:d "M 1 0 L 0 0 0 1"
:style {:fill "none" :style {:fill "none"
:stroke "var(--color-info)" :stroke (if (debug? :pixel-grid) "red" "var(--color-info)")
:stroke-opacity "0.2" :stroke-opacity (if (debug? :pixel-grid) 1 "0.2")
:stroke-width (str (/ 1 zoom))}}]]] :stroke-width (str (/ 1 zoom))}}]]]
[:rect {:x (:x vbox) [:rect {:x (:x vbox)
:y (:y vbox) :y (:y vbox)

View file

@ -70,6 +70,9 @@
;; Enable a widget to show the auto-layout drop-zones ;; Enable a widget to show the auto-layout drop-zones
:layout-drop-zones :layout-drop-zones
;; Makes the pixel grid red so its more visibile
:pixel-grid
}) })
;; These events are excluded when we activate the :events flag ;; These events are excluded when we activate the :events flag