♻️ Refactor to transforms actions

This commit is contained in:
alonso.torres 2020-04-24 09:33:24 +02:00
parent 8886db7453
commit e6855fd9b3
5 changed files with 91 additions and 196 deletions

View file

@ -1730,8 +1730,8 @@
(def start-move-selected transforms/start-move-selected) (def start-move-selected transforms/start-move-selected)
(def move-selected transforms/move-selected) (def move-selected transforms/move-selected)
(def apply-displacement-in-bulk transforms/apply-displacement-in-bulk) (def set-modifiers transforms/set-modifiers)
(def materialize-displacement-in-bulk transforms/materialize-displacement-in-bulk) (def apply-modifiers transforms/apply-modifiers)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shortcuts ;; Shortcuts

View file

@ -14,20 +14,14 @@
[uxbox.util.geom.matrix :as gmt] [uxbox.util.geom.matrix :as gmt]
[uxbox.main.data.helpers :as helpers] [uxbox.main.data.helpers :as helpers]
[uxbox.main.data.workspace.common :refer [IBatchedChange IUpdateGroup] :as common])) [uxbox.main.data.workspace.common :refer [IBatchedChange IUpdateGroup] :as common]))
;; -- Specs
(s/def ::set-of-uuid
(s/every uuid? :kind set?))
;; -- Declarations ;; -- Declarations
(declare assoc-resize-modifier-in-bulk) (declare set-modifiers)
(declare apply-displacement-in-bulk) (declare set-rotation)
(declare apply-rotation) (declare apply-modifiers)
(declare materialize-resize-modifier-in-bulk) ;; -- Helpers
(declare materialize-displacement-in-bulk)
(declare materialize-rotation)
(defn- apply-zoom (defn- apply-zoom
[point] [point]
@ -71,7 +65,7 @@
;; -- RESIZE ;; -- RESIZE
(defn start-resize (defn start-resize
[vid ids shape objects] [handler ids shape objects]
(letfn [(resize [shape initial [point lock?]] (letfn [(resize [shape initial [point lock?]]
(let [frame (get objects (:frame-id shape)) (let [frame (get objects (:frame-id shape))
{:keys [width height rotation]} shape {:keys [width height rotation]} shape
@ -80,7 +74,7 @@
shapev (-> (gpt/point width height)) shapev (-> (gpt/point width height))
;; Vector modifiers depending on the handler ;; Vector modifiers depending on the handler
handler-modif (let [[x y] (handler-modifiers vid)] (gpt/point x y)) handler-modif (let [[x y] (handler-modifiers handler)] (gpt/point x y))
;; Difference between the origin point in the coordinate system of the rotation ;; Difference between the origin point in the coordinate system of the rotation
deltav (-> (gpt/subtract point initial) deltav (-> (gpt/subtract point initial)
@ -94,13 +88,13 @@
shape-transform-inverse (:transform-inverse shape (gmt/matrix)) shape-transform-inverse (:transform-inverse shape (gmt/matrix))
;; Resize origin point given the selected handler ;; Resize origin point given the selected handler
origin (-> (handler-resize-origin shape vid) origin (-> (handler-resize-origin shape handler)
(geom/transform-shape-point shape shape-transform))] (geom/transform-shape-point shape shape-transform))]
(rx/of (assoc-resize-modifier-in-bulk ids {:resize-modifier-vector scalev (rx/of (set-modifiers ids {:resize-vector scalev
:resize-modifier-origin origin :resize-origin origin
:resize-modifier-transform shape-transform :resize-transform shape-transform
:resize-modifier-transform-inverse shape-transform-inverse})))) :resize-transform-inverse shape-transform-inverse}))))
;; Unifies the instantaneous proportion lock modifier ;; Unifies the instantaneous proportion lock modifier
;; activated by Ctrl key and the shapes own proportion ;; activated by Ctrl key and the shapes own proportion
@ -130,64 +124,7 @@
(rx/map normalize-proportion-lock) (rx/map normalize-proportion-lock)
(rx/mapcat (partial resize shape initial)) (rx/mapcat (partial resize shape initial))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (materialize-resize-modifier-in-bulk ids)))))))) (rx/of (apply-modifiers ids))))))))
(defn assoc-resize-modifier-in-bulk
[ids modifiers]
(us/verify ::set-of-uuid ids)
;; (us/verify gmt/matrix? resize-matrix)
;; (us/verify gmt/matrix? displacement-matrix)
(ptk/reify ::assoc-resize-modifier-in-bulk
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data page-id :objects])
rfn #(-> %1
(update-in [:workspace-data page-id :objects %2] (fn [item] (merge item modifiers))))
not-frame-id? (fn [shape-id] (not (= :frame (:type (get objects shape-id)))))
;; TODO: REMOVE FRAMES FROM IDS TO PROPAGATE
ids-with-children (concat ids (mapcat #(helpers/get-children % objects) (filter not-frame-id? ids)))]
(reduce rfn state ids-with-children)))))
(defn materialize-resize-modifier-in-bulk
[ids]
(ptk/reify ::materialize-resize-modifier-in-bulk
IUpdateGroup
(get-ids [_] ids)
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data page-id :objects])
;; Updates the resize data for a single shape
materialize-shape
(fn [state id]
(update-in state [:workspace-data page-id :objects id] geom/transform-shape))
;; Applies materialize-shape over shape children
materialize-children
(fn [state id]
(reduce materialize-shape state (helpers/get-children id objects)))
;; For each shape makes permanent the displacemnt
update-shapes
(fn [state id]
(let [shape (-> (get objects id) geom/transform-shape)]
(-> state
(materialize-shape id)
(materialize-children id))))]
(reduce update-shapes state ids)))
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)]
(rx/of (common/diff-and-commit-changes page-id)
(common/rehash-shape-frame-relationship ids))))))
;; -- ROTATE ;; -- ROTATE
@ -219,12 +156,9 @@
(rx/with-latest vector ms/mouse-position-ctrl) (rx/with-latest vector ms/mouse-position-ctrl)
(rx/map (fn [[pos ctrl?]] (rx/map (fn [[pos ctrl?]]
(let [delta-angle (calculate-angle pos ctrl?)] (let [delta-angle (calculate-angle pos ctrl?)]
(apply-rotation delta-angle shapes)))) (set-rotation delta-angle shapes))))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (materialize-rotation shapes)) (rx/of (apply-modifiers (map :id shapes))))))))
)))))
;; -- MOVE ;; -- MOVE
@ -235,13 +169,16 @@
(let [selected (get-in state [:workspace-local :selected]) (let [selected (get-in state [:workspace-local :selected])
stoper (rx/filter ms/mouse-up? stream) stoper (rx/filter ms/mouse-up? stream)
zero-point? #(= % (gpt/point 0 0)) zero-point? #(= % (gpt/point 0 0))
initial (apply-zoom @ms/mouse-position)
position @ms/mouse-position] position @ms/mouse-position]
(rx/concat (rx/concat
(->> (ms/mouse-position-deltas position) (->> ms/mouse-position
(rx/map apply-zoom)
(rx/filter (complement zero-point?)) (rx/filter (complement zero-point?))
(rx/map #(apply-displacement-in-bulk selected %)) (rx/map #(gpt/subtract % initial))
(rx/map #(set-modifiers selected {:displacement (gmt/translate-matrix %)}))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (materialize-displacement-in-bulk selected))))))) (rx/of (apply-modifiers selected)))))))
(defn- get-displacement-with-grid (defn- get-displacement-with-grid
"Retrieve the correct displacement delta point for the "Retrieve the correct displacement delta point for the
@ -283,81 +220,40 @@
displacement (if align? displacement (if align?
(get-displacement-with-grid shape direction options) (get-displacement-with-grid shape direction options)
(get-displacement shape direction))] (get-displacement shape direction))]
(rx/of (apply-displacement-in-bulk selected displacement) (rx/of (set-modifiers selected displacement)
(materialize-displacement-in-bulk selected)))))) (apply-modifiers selected))))))
;; -- Apply modifiers ;; -- Apply modifiers
(defn apply-displacement-in-bulk
"Apply the same displacement delta to all shapes identified by the set (defn set-modifiers
if ids." ([ids modifiers] (set-modifiers ids modifiers true))
[ids delta] ([ids modifiers recurse-frames?]
(us/verify ::set-of-uuid ids) (us/verify (s/coll-of uuid?) ids)
(us/verify gpt/point? delta) (ptk/reify ::set-modifiers
(ptk/reify ::apply-displacement-in-bulk
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [page-id (:current-page-id state) (let [page-id (:current-page-id state)
objects (get-in state [:workspace-data page-id :objects]) objects (get-in state [:workspace-data page-id :objects])
rfn (fn [state id] not-frame-id? (fn [shape-id]
(let [path [:workspace-data page-id :objects id] (let [shape (get objects shape-id)]
shape (get-in state path) (or recurse-frames? (not (= :frame (:type shape))))))
prev (:displacement-modifier shape (gmt/matrix))
curr (gmt/translate prev delta)]
(update-in state path #(assoc % :displacement-modifier curr))))
ids-with-children (concat ids (mapcat #(helpers/get-children % objects) ids))]
(reduce rfn state ids-with-children)))))
;; ID's + Children but remove frame children if the flag is set to false
ids-with-children (concat ids (mapcat #(helpers/get-children % objects) (filter not-frame-id? ids)))
(defn materialize-displacement-in-bulk ;; For each shape updates the modifiers given as arguments
[ids] update-shape (fn [state shape-id]
(ptk/reify ::materialize-displacement-in-bulk
IBatchedChange
IUpdateGroup
(get-ids [_] ids)
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (get-in state [:workspace-data page-id :objects])
;; Updates the displacement data for a single shape
materialize-shape
(fn [state id mtx]
(update-in (update-in
state state
[:workspace-data page-id :objects id] [:workspace-data page-id :objects shape-id :modifiers]
#(-> % #(merge % modifiers)))]
(dissoc :displacement-modifier) (reduce update-shape state ids-with-children))))))
(geom/transform mtx))))
;; Applies materialize-shape over shape children ;; Set-rotation is custom because applies different modifiers to each shape adjusting their position
materialize-children (defn set-rotation
(fn [state id mtx]
(reduce #(materialize-shape %1 %2 mtx) state (helpers/get-children id objects)))
;; For each shape makes permanent the resize
update-shapes
(fn [state id]
(let [shape (get objects id)
mtx (:displacement-modifier shape (gmt/matrix))]
(-> state
(materialize-shape id mtx)
(materialize-children id mtx))))]
(as-> state $
(reduce update-shapes $ ids))))
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)]
(rx/of (common/diff-and-commit-changes page-id)
(common/rehash-shape-frame-relationship ids))))))
(defn apply-rotation
[delta-rotation shapes] [delta-rotation shapes]
(ptk/reify ::apply-rotation (ptk/reify ::set-rotation
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [page-id (:current-page-id state)] (let [page-id (:current-page-id state)]
@ -369,11 +265,11 @@
(rotate-shape [state angle shape center] (rotate-shape [state angle shape center]
(let [objects (get-in state [:workspace-data page-id :objects]) (let [objects (get-in state [:workspace-data page-id :objects])
path [:workspace-data page-id :objects (:id shape)] path [:workspace-data page-id :objects (:id shape) :modifiers]
ds (calculate-displacement shape angle center)] ds (calculate-displacement shape angle center)]
(-> state (-> state
(assoc-in (conj path :rotation-modifier) angle) (assoc-in (conj path :rotation) angle)
(assoc-in (conj path :displacement-modifier) ds)))) (assoc-in (conj path :displacement) ds))))
(rotate-around-center [state angle center shapes] (rotate-around-center [state angle center shapes]
@ -386,25 +282,30 @@
shapes (concat shapes (mapcat get-children shapes))] shapes (concat shapes (mapcat get-children shapes))]
(rotate-around-center state delta-rotation center shapes))))))) (rotate-around-center state delta-rotation center shapes)))))))
(defn materialize-rotation (defn apply-modifiers
[shapes] [ids]
(ptk/reify ::materialize-rotation (us/verify (s/coll-of uuid?) ids)
IBatchedChange (ptk/reify ::apply-modifiers
IUpdateGroup IUpdateGroup
(get-ids [_] (map :id shapes)) (get-ids [_] ids)
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(letfn
[(materialize-shape [state shape]
(let [page-id (:current-page-id state) (let [page-id (:current-page-id state)
objects (get-in state [:workspace-data page-id :objects]) objects (get-in state [:workspace-data page-id :objects])
path [:workspace-data page-id :objects (:id shape)]]
(as-> state $
(update-in $ path geom/transform-shape)
(reduce materialize-shape $ (map #(get objects %) (:shapes shape))))))]
(reduce materialize-shape state shapes))))) ;; ID's + Children
ids-with-children (concat ids (mapcat #(helpers/get-children % objects) ids))
;; For each shape applies the modifiers by transforming the objects
update-shape
(fn [state shape-id]
(update-in state [:workspace-data page-id :objects shape-id] geom/transform-shape))]
(reduce update-shape state ids-with-children)))
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)]
(rx/of (common/diff-and-commit-changes page-id)
(common/rehash-shape-frame-relationship ids))))))

View file

@ -679,12 +679,13 @@
(defn- transform-apply-modifiers (defn- transform-apply-modifiers
[shape] [shape]
(let [ds-modifier (:displacement-modifier shape (gmt/matrix)) (let [modifiers (:modifiers shape)
resize (:resize-modifier-vector shape (gpt/point 1 1)) ds-modifier (:displacement modifiers (gmt/matrix))
origin (:resize-modifier-origin shape (gpt/point 0 0)) resize (:resize-vector modifiers (gpt/point 1 1))
resize-transform (:resize-modifier-transform shape (gmt/matrix)) origin (:resize-origin modifiers (gpt/point 0 0))
resize-transform-inverse (:resize-modifier-transform-inverse shape (gmt/matrix)) resize-transform (:resize-transform modifiers (gmt/matrix))
rt-modif (:rotation-modifier shape 0) resize-transform-inverse (:resize-transform-inverse modifiers (gmt/matrix))
rt-modif (:rotation modifiers 0)
shape (-> shape shape (-> shape
(transform ds-modifier)) (transform ds-modifier))
@ -734,15 +735,6 @@
(translate-to-frame frame) (translate-to-frame frame)
(shape->rect-shape))) (shape->rect-shape)))
(defn dissoc-modifiers [shape]
(-> shape
(dissoc :rotation-modifier)
(dissoc :displacement-modifier)
(dissoc :resize-modifier)
(dissoc :resize-modifier-vector)
(dissoc :resize-modifier-origin)
(dissoc :resize-modifier-rotation)))
(defn transform-rect-shape (defn transform-rect-shape
[shape] [shape]
(let [;; Apply modifiers to the rect as a path so we have the end shape expected (let [;; Apply modifiers to the rect as a path so we have the end shape expected
@ -813,8 +805,8 @@
(transform-rect-shape shape))] (transform-rect-shape shape))]
(-> new-shape (-> new-shape
(translate-to-frame frame) (translate-to-frame frame)
(update :rotation #(mod (+ % (:rotation-modifier shape)) 360)) (update :rotation #(mod (+ % (get-in shape [:modifiers :rotation] 0)) 360))
(dissoc-modifiers))))) (dissoc :modifiers)))))
(defn transform-matrix (defn transform-matrix

View file

@ -123,9 +123,9 @@
scalev (gpt/divide (gpt/add shapev deltav) shapev)] scalev (gpt/divide (gpt/add shapev deltav) shapev)]
(-> shape (-> shape
(assoc :resize-modifier-vector scalev) (assoc-in [:modifiers :resize-vector] scalev)
(assoc :resize-modifier-origin (gpt/point x y)) (assoc-in [:modifiers :resize-origin] (gpt/point x y))
(assoc :resize-modifier-rotation 0)))) (assoc-in [:modifiers :resize-rotation] 0))))
(update-drawing [state initial point lock?] (update-drawing [state initial point lock?]
(update-in state [:workspace-local :drawing] resize-shape initial point lock?))] (update-in state [:workspace-local :drawing] resize-shape initial point lock?))]

View file

@ -64,8 +64,10 @@
delta (if (= attr :x) delta (if (= attr :x)
(gpt/point (math/neg (- pval cval)) 0) (gpt/point (math/neg (- pval cval)) 0)
(gpt/point 0 (math/neg (- pval cval))))] (gpt/point 0 (math/neg (- pval cval))))]
(st/emit! (udw/apply-displacement-in-bulk #{(:id shape)} delta)
(udw/materialize-displacement-in-bulk #{(:id shape)})))) ;; TODO: Change so not apply the modifiers until blur
(st/emit! (udw/set-modifiers #{(:id shape)} {:displacement delta})
(udw/apply-modifiers #{(:id shape)}))))
on-width-change #(on-size-change % :width) on-width-change #(on-size-change % :width)
on-height-change #(on-size-change % :height) on-height-change #(on-size-change % :height)