mirror of
https://github.com/penpot/penpot.git
synced 2025-02-03 04:49:03 -05:00
🎉 Now all component roots are frames
This commit is contained in:
parent
47b791e938
commit
2790111405
5 changed files with 166 additions and 92 deletions
|
@ -172,7 +172,13 @@
|
|||
(cond-> new-shape
|
||||
:always
|
||||
(-> (gsh/move delta)
|
||||
(dissoc :touched :main-instance?))
|
||||
(dissoc :touched))
|
||||
|
||||
main-instance?
|
||||
(assoc :main-instance? true)
|
||||
|
||||
(not main-instance?)
|
||||
(dissoc :main-instance?)
|
||||
|
||||
(and (not main-instance?) (nil? (:shape-ref original-shape)))
|
||||
(assoc :shape-ref (:id original-shape))
|
||||
|
|
|
@ -346,7 +346,7 @@
|
|||
(map (partial get-component-root file-data) components)
|
||||
start-pos
|
||||
grid-gap)]
|
||||
(loop [file-data file-data
|
||||
(loop [file-data file-data
|
||||
components-seq (seq components)
|
||||
position-seq position-seq]
|
||||
(let [component (first components-seq)
|
||||
|
@ -355,10 +355,26 @@
|
|||
file-data
|
||||
(recur (add-main-instance file-data component position)
|
||||
(rest components-seq)
|
||||
(rest position-seq)))))))]
|
||||
(rest position-seq)))))))
|
||||
|
||||
root-to-board
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
(and (ctk/instance-root? shape)
|
||||
(not= (:type shape) :frame))
|
||||
(assoc :type :frame
|
||||
:fills []
|
||||
:hide-in-viewer true
|
||||
:rx 0
|
||||
:ry 0)))
|
||||
|
||||
roots-to-board
|
||||
(fn [page]
|
||||
(update page :objects update-vals root-to-board))]
|
||||
|
||||
(-> file-data
|
||||
(add-instance-grid (sort-by :name components))
|
||||
(update :pages-index update-vals roots-to-board)
|
||||
(assoc-in [:options :components-v2] true))))))
|
||||
|
||||
(defn- absorb-components
|
||||
|
|
|
@ -315,11 +315,13 @@
|
|||
objects (wsh/lookup-page-objects state page-id)
|
||||
shapes (dwg/shapes-for-grouping objects selected)]
|
||||
(when-not (empty? shapes)
|
||||
(let [[group _ changes]
|
||||
(dwlh/generate-add-component it shapes objects page-id file-id components-v2 dwg/prepare-create-group)]
|
||||
(let [[root _ changes]
|
||||
(dwlh/generate-add-component it shapes objects page-id file-id components-v2
|
||||
dwg/prepare-create-group
|
||||
dwsh/prepare-create-artboard-from-selection)]
|
||||
(when-not (empty? (:redo-changes changes))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(dws/select-shapes (d/ordered-set (:id group)))))))))))
|
||||
(dws/select-shapes (d/ordered-set (:id root)))))))))))
|
||||
|
||||
(defn add-component
|
||||
"Add a new component to current file library, from the currently selected shapes.
|
||||
|
|
|
@ -62,37 +62,48 @@
|
|||
;; ---- Components and instances creation ----
|
||||
|
||||
(defn generate-add-component
|
||||
"If there is exactly one id, and it's a group or a frame, and not already a component,
|
||||
use it as root. Otherwise, create a group that contains all ids. Then, make a
|
||||
"If there is exactly one id, and it's a frame (or a group in v1), and not already a component,
|
||||
use it as root. Otherwise, create a frame (v2) or group (v1) that contains all ids. Then, make a
|
||||
component with it, and link all shapes to their corresponding one in the component."
|
||||
[it shapes objects page-id file-id components-v2 prepare-create-group]
|
||||
(let [[group changes]
|
||||
[it shapes objects page-id file-id components-v2 prepare-create-group prepare-create-board]
|
||||
(let [changes (pcb/empty-changes it page-id)
|
||||
|
||||
[root changes]
|
||||
(if (and (= (count shapes) 1)
|
||||
(or (= (:type (first shapes)) :group)
|
||||
(or (and (= (:type (first shapes)) :group) (not components-v2))
|
||||
(= (:type (first shapes)) :frame))
|
||||
(not (ctk/instance-root? (first shapes))))
|
||||
[(first shapes) (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects))]
|
||||
(let [group-name (if (= 1 (count shapes))
|
||||
(let [root-name (if (= 1 (count shapes))
|
||||
(:name (first shapes))
|
||||
"Component 1")]
|
||||
(prepare-create-group it ; This function needs to be passed as argument
|
||||
objects ; to avoid a circular dependence
|
||||
page-id
|
||||
shapes
|
||||
group-name
|
||||
(not (ctk/instance-root? (first shapes))))))
|
||||
(if-not components-v2
|
||||
(prepare-create-group it ; These functions needs to be passed as argument
|
||||
objects ; to avoid a circular dependence
|
||||
page-id
|
||||
shapes
|
||||
root-name
|
||||
(not (ctk/instance-root? (first shapes))))
|
||||
(prepare-create-board changes
|
||||
(uuid/next)
|
||||
(:parent-id (first shapes))
|
||||
objects
|
||||
(map :id shapes)
|
||||
nil
|
||||
root-name
|
||||
true))))
|
||||
|
||||
name (:name group)
|
||||
name (:name root)
|
||||
[path name] (cph/parse-path-name name)
|
||||
|
||||
[root-shape new-shapes updated-shapes]
|
||||
(if-not components-v2
|
||||
(ctn/make-component-shape group objects file-id components-v2)
|
||||
(ctn/make-component-shape root objects file-id components-v2)
|
||||
(let [new-id (uuid/next)]
|
||||
[(assoc group :id new-id)
|
||||
[(assoc root :id new-id)
|
||||
nil
|
||||
[(assoc group
|
||||
[(assoc root
|
||||
:component-id new-id
|
||||
:component-file file-id
|
||||
:component-root? true
|
||||
|
@ -104,9 +115,9 @@
|
|||
name
|
||||
new-shapes
|
||||
updated-shapes
|
||||
(:id group)
|
||||
(:id root)
|
||||
page-id))]
|
||||
[group (:id root-shape) changes]))
|
||||
[root (:id root-shape) changes]))
|
||||
|
||||
(defn duplicate-component
|
||||
"Clone the root shape of the component and all children. Generate new
|
||||
|
|
|
@ -74,6 +74,31 @@
|
|||
:parent-id parent-id
|
||||
:index index))))
|
||||
|
||||
(defn prepare-add-shape
|
||||
[changes attrs objects selected]
|
||||
(let [id (or (:id attrs) (uuid/next))
|
||||
name (:name attrs)
|
||||
|
||||
shape (make-new-shape
|
||||
(assoc attrs :id id :name name)
|
||||
objects
|
||||
selected)
|
||||
|
||||
index (:index (meta attrs))
|
||||
|
||||
changes (-> changes
|
||||
(pcb/with-objects objects)
|
||||
(cond-> (some? index)
|
||||
(pcb/add-object shape {:index index}))
|
||||
(cond-> (nil? index)
|
||||
(pcb/add-object shape))
|
||||
(cond-> (some? (:parent-id attrs))
|
||||
(pcb/change-parent (:parent-id attrs) [shape]))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id shape))
|
||||
(pcb/update-shapes [(:parent-id shape)] ctl/assign-cells)))]
|
||||
|
||||
[shape changes]))
|
||||
|
||||
(defn add-shape
|
||||
([attrs]
|
||||
(add-shape attrs {}))
|
||||
|
@ -87,27 +112,11 @@
|
|||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
|
||||
id (or (:id attrs) (uuid/next))
|
||||
name (:name attrs)
|
||||
changes (pcb/empty-changes it page-id)
|
||||
|
||||
shape (make-new-shape
|
||||
(assoc attrs :id id :name name)
|
||||
objects
|
||||
selected)
|
||||
[shape changes]
|
||||
(prepare-add-shape changes attrs objects selected)
|
||||
|
||||
index (:index (meta attrs))
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
(cond-> (some? index)
|
||||
(pcb/add-object shape {:index index}))
|
||||
(cond-> (nil? index)
|
||||
(pcb/add-object shape))
|
||||
(cond-> (some? (:parent-id attrs))
|
||||
(pcb/change-parent (:parent-id attrs) [shape]))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id shape))
|
||||
(pcb/update-shapes [(:parent-id shape)] ctl/assign-cells))
|
||||
)
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(rx/concat
|
||||
|
@ -116,36 +125,38 @@
|
|||
(when-not no-update-layout?
|
||||
(ptk/data-event :layout/update [(:parent-id shape)]))
|
||||
(when-not no-select?
|
||||
(dws/select-shapes (d/ordered-set id)))
|
||||
(dws/select-shapes (d/ordered-set (:id shape))))
|
||||
(dwu/commit-undo-transaction undo-id))
|
||||
(when (= :text (:type attrs))
|
||||
(->> (rx/of (dwe/start-edition-mode id))
|
||||
(->> (rx/of (dwe/start-edition-mode (:id shape)))
|
||||
(rx/observe-on :async)))))))))
|
||||
|
||||
(defn prepare-move-shapes-into-frame
|
||||
[changes frame-id shapes objects]
|
||||
(let [ordered-indexes (cph/order-by-indexed-shapes objects shapes)
|
||||
parent-id (get-in objects [frame-id :parent-id])
|
||||
ordered-indexes (->> ordered-indexes (remove #(= % parent-id)))
|
||||
to-move-shapes (map (d/getf objects) ordered-indexes)]
|
||||
(when (d/not-empty? to-move-shapes)
|
||||
(-> changes
|
||||
(cond-> (not (ctl/any-layout? objects frame-id))
|
||||
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
||||
(pcb/update-shapes ordered-indexes #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
||||
(pcb/change-parent frame-id to-move-shapes 0)
|
||||
(cond-> (ctl/grid-layout? objects frame-id)
|
||||
(pcb/update-shapes [frame-id] ctl/assign-cells))))))
|
||||
|
||||
(defn move-shapes-into-frame [frame-id shapes]
|
||||
(ptk/reify ::move-shapes-into-frame
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
|
||||
ordered-indexes (cph/order-by-indexed-shapes objects shapes)
|
||||
parent-id (get-in objects [frame-id :parent-id])
|
||||
|
||||
ordered-indexes (->> ordered-indexes (remove #(= % parent-id)))
|
||||
to-move-shapes (map (d/getf objects) ordered-indexes)
|
||||
|
||||
changes
|
||||
(when (d/not-empty? to-move-shapes)
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
(cond-> (not (ctl/any-layout? objects frame-id))
|
||||
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
||||
(pcb/update-shapes ordered-indexes #(cond-> % (cph/frame-shape? %) (assoc :hide-in-viewer true)))
|
||||
(pcb/change-parent frame-id to-move-shapes 0)
|
||||
(cond-> (ctl/grid-layout? objects frame-id)
|
||||
(pcb/update-shapes [frame-id] ctl/assign-cells))))]
|
||||
|
||||
changes (pcb/empty-changes it page-id)
|
||||
changes (prepare-move-shapes-into-frame changes
|
||||
frame-id
|
||||
shapes
|
||||
objects)]
|
||||
(if (some? changes)
|
||||
(rx/of (dch/commit-changes changes))
|
||||
(rx/empty))))))
|
||||
|
@ -362,6 +373,35 @@
|
|||
;; Artboard
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn prepare-create-artboard-from-selection
|
||||
[changes id parent-id objects selected index frame-name without-fill?]
|
||||
(let [selected-objs (map #(get objects %) selected)
|
||||
new-index (or index
|
||||
(cph/get-index-replacement selected objects))]
|
||||
(when (d/not-empty? selected)
|
||||
(let [srect (gsh/selection-rect selected-objs)
|
||||
frame-id (get-in objects [(first selected) :frame-id])
|
||||
parent-id (or parent-id (get-in objects [(first selected) :parent-id]))
|
||||
shape (-> (cts/make-minimal-shape :frame)
|
||||
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
|
||||
(cond-> id
|
||||
(assoc :id id))
|
||||
(cond-> frame-name
|
||||
(assoc :name frame-name))
|
||||
(assoc :frame-id frame-id :parent-id parent-id)
|
||||
(with-meta {:index new-index})
|
||||
(cond-> (or (not= frame-id uuid/zero) without-fill?)
|
||||
(assoc :fills [] :hide-in-viewer true))
|
||||
(cts/setup-rect-selrect))
|
||||
|
||||
[shape changes]
|
||||
(prepare-add-shape changes shape objects selected)
|
||||
|
||||
changes
|
||||
(prepare-move-shapes-into-frame changes (:id shape) selected objects)]
|
||||
|
||||
[shape changes]))))
|
||||
|
||||
(defn create-artboard-from-selection
|
||||
([]
|
||||
(create-artboard-from-selection nil))
|
||||
|
@ -372,34 +412,33 @@
|
|||
([id parent-id index]
|
||||
(ptk/reify ::create-artboard-from-selection
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (cph/clean-loops objects selected)
|
||||
selected-objs (map #(get objects %) selected)
|
||||
new-index (or index
|
||||
(cph/get-index-replacement selected objects))]
|
||||
(when (d/not-empty? selected)
|
||||
(let [srect (gsh/selection-rect selected-objs)
|
||||
frame-id (get-in objects [(first selected) :frame-id])
|
||||
parent-id (or parent-id (get-in objects [(first selected) :parent-id]))
|
||||
shape (-> (cts/make-minimal-shape :frame)
|
||||
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
|
||||
(cond-> id
|
||||
(assoc :id id))
|
||||
(assoc :frame-id frame-id :parent-id parent-id)
|
||||
(with-meta {:index new-index})
|
||||
(cond-> (not= frame-id uuid/zero)
|
||||
(assoc :fills [] :hide-in-viewer true))
|
||||
(cts/setup-rect-selrect))
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(add-shape shape {:no-update-layout? true})
|
||||
(move-shapes-into-frame (:id shape) selected)
|
||||
(ptk/data-event :layout/update [(:id shape)])
|
||||
(dwu/commit-undo-transaction undo-id)))))))))
|
||||
(watch [it state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
selected (cph/clean-loops objects selected)
|
||||
|
||||
changes (pcb/empty-changes it page-id)
|
||||
|
||||
[frame-shape changes]
|
||||
(prepare-create-artboard-from-selection changes
|
||||
id
|
||||
parent-id
|
||||
objects
|
||||
selected
|
||||
index
|
||||
nil
|
||||
false)
|
||||
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(when changes
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(dch/commit-changes changes)
|
||||
(dws/select-shapes (d/ordered-set (:id frame-shape)))
|
||||
(ptk/data-event :layout/update [(:id frame-shape)])
|
||||
(dwu/commit-undo-transaction undo-id))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Shape Flags
|
||||
|
|
Loading…
Add table
Reference in a new issue