0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-15 17:21:17 -05:00

🔧 Move :reg-objects operation to frontend

This commit is contained in:
Andrés Moya 2022-02-23 17:53:27 +01:00
parent 2bb8c535bd
commit 8ed857b4b9
4 changed files with 120 additions and 26 deletions

View file

@ -160,6 +160,7 @@
(dm/export gtr/transform-rect)
(dm/export gtr/calculate-adjust-matrix)
(dm/export gtr/update-group-selrect)
(dm/export gtr/update-mask-selrect)
(dm/export gtr/resize-modifiers)
(dm/export gtr/rotation-modifiers)
(dm/export gtr/merge-modifiers)

View file

@ -318,7 +318,8 @@
(update :width + (:width deltas))
(update :height + (:height deltas)))))))
(defn update-group-selrect [group children]
(defn update-group-selrect
[group children]
(let [shape-center (gco/center-shape group)
;; Points for every shape inside the group
points (->> children (mapcat :points))
@ -346,6 +347,18 @@
(assoc :flip-y false)
(apply-transform (gmt/matrix) true))))
(defn update-mask-selrect
[masked-group children]
(let [mask (first children)]
(-> masked-group
(assoc :selrect (-> mask :selrect))
(assoc :points (-> mask :points))
(assoc :x (-> mask :selrect :x))
(assoc :y (-> mask :selrect :y))
(assoc :width (-> mask :selrect :width))
(assoc :height (-> mask :selrect :height))
(assoc :flip-x (-> mask :flip-x))
(assoc :flip-y (-> mask :flip-y)))))
;; --- Modifiers
@ -600,3 +613,4 @@
(->> shapes
(map (comp gpr/points->selrect :points transform-shape))
(gpr/join-selrects)))

View file

@ -7,7 +7,11 @@
(ns app.common.pages.changes-builder
(:require
[app.common.data :as d]
[app.common.pages.helpers :as cph]))
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.bool :as gshb]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]))
;; Auxiliary functions to help create a set of changes (undo + redo)
@ -29,7 +33,10 @@
::objects (:objects page)))
(defn with-objects [changes objects]
(vary-meta changes assoc ::objects objects))
(let [file-data (-> (cp/make-file-data (uuid/next) uuid/zero)
(assoc-in [:pages-index uuid/zero :objects] objects))]
(vary-meta changes assoc ::file-data file-data
::applied-changes 0)))
(defn amend-last-change
"Modify the last redo-changes added with an update function."
@ -52,7 +59,21 @@
(defn- assert-objects
[changes]
(assert (contains? (meta changes) ::objects) "Call (with-objects) before using this function"))
(assert (contains? (meta changes) ::file-data) "Call (with-objects) before using this function"))
(defn- apply-changes-local
[changes]
(if-let [file-data (::file-data (meta changes))]
(let [index (::applied-changes (meta changes))
redo-changes (:redo-changes changes)
new-changes (if (< index (count redo-changes))
(->> (subvec (:redo-changes changes) index)
(map #(assoc % :page-id uuid/zero)))
[])
new-file-data (cp/process-changes file-data new-changes)]
(vary-meta changes assoc ::file-data new-file-data
::applied-changes (count redo-changes)))
changes))
;; Page changes
@ -60,31 +81,36 @@
[changes id name]
(-> changes
(update :redo-changes conj {:type :add-page :id id :name name})
(update :undo-changes conj {:type :del-page :id id})))
(update :undo-changes conj {:type :del-page :id id})
(apply-changes-local)))
(defn add-page
[changes id page]
(-> changes
(update :redo-changes conj {:type :add-page :id id :page page})
(update :undo-changes conj {:type :del-page :id id})))
(update :undo-changes conj {:type :del-page :id id})
(apply-changes-local)))
(defn mod-page
[changes page new-name]
(-> changes
(update :redo-changes conj {:type :mod-page :id (:id page) :name new-name})
(update :undo-changes conj {:type :mod-page :id (:id page) :name (:name page)})))
(update :undo-changes conj {:type :mod-page :id (:id page) :name (:name page)})
(apply-changes-local)))
(defn del-page
[changes page]
(-> changes
(update :redo-changes conj {:type :del-page :id (:id page)})
(update :undo-changes conj {:type :add-page :id (:id page) :page page})))
(update :undo-changes conj {:type :add-page :id (:id page) :page page})
(apply-changes-local)))
(defn move-page
[changes page-id index prev-index]
(-> changes
(update :redo-changes conj {:type :mov-page :id page-id :index index})
(update :undo-changes conj {:type :mov-page :id page-id :index prev-index})))
(update :undo-changes conj {:type :mov-page :id page-id :index prev-index})
(apply-changes-local)))
(defn set-page-option
[changes option-key option-val]
@ -101,7 +127,8 @@
(update :undo-changes conj {:type :set-option
:page-id page-id
:option option-key
:value old-val}))))
:value old-val})
(apply-changes-local))))
;; Shape tree changes
@ -132,7 +159,8 @@
(-> changes
(update :redo-changes conj add-change)
(update :undo-changes d/preconj del-change)))))
(update :undo-changes d/preconj del-change)
(apply-changes-local)))))
(defn change-parent
([changes parent-id shapes]
@ -141,7 +169,8 @@
([changes parent-id shapes index]
(assert-page-id changes)
(assert-objects changes)
(let [objects (::objects (meta changes))
(let [objects (-> changes meta ::file-data (get-in [:pages-index uuid/zero :objects]))
set-parent-change
(cond-> {:type :mov-objects
:parent-id parent-id
@ -163,7 +192,8 @@
(-> changes
(update :redo-changes conj set-parent-change)
(update :undo-changes #(reduce mk-undo-change % shapes))))))
(update :undo-changes #(reduce mk-undo-change % shapes))
(apply-changes-local)))))
(defn update-shapes
"Calculate the changes and undos to be done when a function is applied to a
@ -174,15 +204,15 @@
([changes ids update-fn {:keys [attrs ignore-geometry?] :or {attrs nil ignore-geometry? false}}]
(assert-page-id changes)
(assert-objects changes)
(let [objects (::objects (meta changes))
(let [objects (-> changes meta ::file-data (get-in [:pages-index uuid/zero :objects]))
generate-operation
(fn [changes attr old new ignore-geometry?]
(fn [operations attr old new ignore-geometry?]
(let [old-val (get old attr)
new-val (get new attr)]
(if (= old-val new-val)
changes
(-> changes
operations
(-> operations
(update :rops conj {:type :set :attr attr :val new-val :ignore-geometry ignore-geometry?})
(update :uops conj {:type :set :attr attr :val old-val :ignore-touched true})))))
@ -213,14 +243,15 @@
(seq uops)
(update :undo-changes d/preconj (assoc change :operations uops)))))]
(reduce update-shape changes ids))))
(-> (reduce update-shape changes ids)
(apply-changes-local)))))
(defn remove-objects
[changes ids]
(assert-page-id changes)
(assert-objects changes)
(let [page-id (::page-id (meta changes))
objects (::objects (meta changes))
objects (-> changes meta ::file-data (get-in [:pages-index uuid/zero :objects]))
add-redo-change
(fn [change-set id]
@ -260,14 +291,63 @@
(update :redo-changes #(reduce add-redo-change % ids))
(update :undo-changes #(as-> % $
(reduce add-undo-change-parent $ ids)
(reduce add-undo-change-shape $ ids))))))
(reduce add-undo-change-shape $ ids)))
(apply-changes-local))))
(defn resize-parents
[changes ids]
(assert-page-id changes)
(assert-objects changes)
(let [page-id (::page-id (meta changes))
shapes (vec ids)]
(-> changes
(update :redo-changes conj {:type :reg-objects :page-id page-id :shapes shapes})
(update :undo-changes conj {:type :reg-objects :page-id page-id :shapes shapes}))))
objects (-> changes meta ::file-data (get-in [:pages-index uuid/zero :objects]))
xform (comp
(mapcat #(cons % (cph/get-parent-ids objects %)))
(map (d/getf objects))
(filter #(contains? #{:group :bool} (:type %)))
(distinct))
all-parents (sequence xform ids)
generate-operation
(fn [operations attr old new]
(let [old-val (get old attr)
new-val (get new attr)]
(if (= old-val new-val)
operations
(-> operations
(update :rops conj {:type :set :attr attr :val new-val :ignore-touched true})
(update :uops conj {:type :set :attr attr :val old-val :ignore-touched true})))))
resize-parent
(fn [changes parent]
(let [children (->> parent :shapes (map (d/getf objects)))
resized-parent (cond
(empty? children)
changes
(= (:type parent) :bool)
(gshb/update-bool-selrect parent children objects)
(= (:type parent) :group)
(if (:masked-group? parent)
(gsh/update-mask-selrect parent children)
(gsh/update-group-selrect parent children)))
{rops :rops uops :uops}
(reduce #(generate-operation %1 %2 parent resized-parent)
{:rops [] :uops []}
(keys parent))
change {:type :mod-obj
:page-id page-id
:id (:id parent)}]
(if (seq rops)
(-> changes
(update :redo-changes conj (assoc change :operations rops))
(update :undo-changes conj (assoc change :operations uops)))
changes)))]
(-> (reduce resize-parent changes all-parents)
(apply-changes-local))))

View file

@ -1526,9 +1526,8 @@
(pcb/amend-changes (partial process-rchange media-idx))
(pcb/amend-changes (partial change-add-obj-index paste-objects selected index)))
;; Adds a reg-objects operation so the groups are updated. We add all the new objects
;; Adds a resize-parents operation so the groups are updated. We add all the new objects
new-objects-ids (->> changes :redo-changes (filter #(= (:type %) :add-obj)) (mapv :id))
changes (pcb/resize-parents changes new-objects-ids)
selected (->> changes