mirror of
https://github.com/penpot/penpot.git
synced 2025-05-25 04:56:11 +02:00
✨ Add to plugins clone and remove
This commit is contained in:
parent
e30c21a71f
commit
9243ba937d
4 changed files with 112 additions and 71 deletions
|
@ -723,23 +723,21 @@
|
||||||
|
|
||||||
(gpt/subtract new-pos pt-obj)))))
|
(gpt/subtract new-pos pt-obj)))))
|
||||||
|
|
||||||
(defn duplicate-selected
|
(defn duplicate-shapes
|
||||||
([move-delta?]
|
[ids & {:keys [move-delta? alt-duplication? change-selection? return-ref]
|
||||||
(duplicate-selected move-delta? false))
|
:or {move-delta? false alt-duplication? false change-selection? true return-ref nil}}]
|
||||||
([move-delta? alt-duplication?]
|
(ptk/reify ::duplicate-shapes
|
||||||
(ptk/reify ::duplicate-selected
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(when (or (not move-delta?) (nil? (get-in state [:workspace-local :transform])))
|
|
||||||
(let [page (wsh/lookup-page state)
|
(let [page (wsh/lookup-page state)
|
||||||
objects (:objects page)
|
objects (:objects page)
|
||||||
selected (->> (wsh/lookup-selected state)
|
ids (into #{}
|
||||||
(map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
(filter #(ctk/allow-duplicate? objects %))
|
(filter #(ctk/allow-duplicate? objects %))
|
||||||
(map :id)
|
(map :id))
|
||||||
set)]
|
ids)]
|
||||||
(when (seq selected)
|
(when (seq ids)
|
||||||
(let [obj (get objects (first selected))
|
(let [obj (get objects (first ids))
|
||||||
delta (if move-delta?
|
delta (if move-delta?
|
||||||
(calc-duplicate-delta obj state objects)
|
(calc-duplicate-delta obj state objects)
|
||||||
(gpt/point 0 0))
|
(gpt/point 0 0))
|
||||||
|
@ -748,37 +746,53 @@
|
||||||
libraries (wsh/get-libraries state)
|
libraries (wsh/get-libraries state)
|
||||||
library-data (wsh/get-file state file-id)
|
library-data (wsh/get-file state file-id)
|
||||||
|
|
||||||
changes (->> (prepare-duplicate-changes objects page selected delta it libraries library-data file-id)
|
changes (->> (prepare-duplicate-changes objects page ids delta it libraries library-data file-id)
|
||||||
(duplicate-changes-update-indices objects selected))
|
(duplicate-changes-update-indices objects ids))
|
||||||
|
|
||||||
tags (or (:tags changes) #{})
|
tags (or (:tags changes) #{})
|
||||||
|
|
||||||
changes (cond-> changes alt-duplication? (assoc :tags (conj tags :alt-duplication)))
|
changes (cond-> changes alt-duplication? (assoc :tags (conj tags :alt-duplication)))
|
||||||
|
|
||||||
id-original (first selected)
|
id-original (first ids)
|
||||||
|
|
||||||
new-selected (->> changes
|
new-ids (->> changes
|
||||||
:redo-changes
|
:redo-changes
|
||||||
(filter #(= (:type %) :add-obj))
|
(filter #(= (:type %) :add-obj))
|
||||||
(filter #(selected (:old-id %)))
|
(filter #(ids (:old-id %)))
|
||||||
(map #(get-in % [:obj :id]))
|
(map #(get-in % [:obj :id]))
|
||||||
(into (d/ordered-set)))
|
(into (d/ordered-set)))
|
||||||
|
|
||||||
id-duplicated (first new-selected)
|
id-duplicated (first new-ids)
|
||||||
|
|
||||||
frames (into #{}
|
frames (into #{}
|
||||||
(map #(get-in objects [% :frame-id]))
|
(map #(get-in objects [% :frame-id]))
|
||||||
selected)
|
ids)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
;; Warning: This order is important for the focus mode.
|
;; Warning: This order is important for the focus mode.
|
||||||
(rx/of
|
(->> (rx/of
|
||||||
(dwu/start-undo-transaction undo-id)
|
(dwu/start-undo-transaction undo-id)
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(select-shapes new-selected)
|
(when change-selection?
|
||||||
|
(select-shapes new-ids))
|
||||||
(ptk/data-event :layout/update {:ids frames})
|
(ptk/data-event :layout/update {:ids frames})
|
||||||
(memorize-duplicated id-original id-duplicated)
|
(memorize-duplicated id-original id-duplicated)
|
||||||
(dwu/commit-undo-transaction undo-id))))))))))
|
(dwu/commit-undo-transaction undo-id))
|
||||||
|
(rx/tap #(when (some? return-ref)
|
||||||
|
(reset! return-ref id-duplicated))))))))))
|
||||||
|
|
||||||
|
(defn duplicate-selected
|
||||||
|
([move-delta?]
|
||||||
|
(duplicate-selected move-delta? false))
|
||||||
|
([move-delta? alt-duplication?]
|
||||||
|
(ptk/reify ::duplicate-selected
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(when (or (not move-delta?) (nil? (get-in state [:workspace-local :transform])))
|
||||||
|
(let [selected (wsh/lookup-selected state)]
|
||||||
|
(rx/of (duplicate-shapes selected
|
||||||
|
:move-delta? move-delta?
|
||||||
|
:alt-duplication? alt-duplication?))))))))
|
||||||
|
|
||||||
(defn change-hover-state
|
(defn change-hover-state
|
||||||
[id value]
|
[id value]
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.changes :as dwc]
|
[app.main.data.workspace.changes :as dwc]
|
||||||
|
[app.main.data.workspace.selection :as dws]
|
||||||
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.utils :as utils :refer [get-data get-data-fn]]
|
[app.plugins.utils :as utils :refer [get-data get-data-fn]]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
@ -61,8 +63,18 @@
|
||||||
(st/emit! (udw/update-dimensions [id] :width width)
|
(st/emit! (udw/update-dimensions [id] :width width)
|
||||||
(udw/update-dimensions [id] :height height))))
|
(udw/update-dimensions [id] :height height))))
|
||||||
|
|
||||||
(clone [_] (.log js/console (clj->js _data)))
|
(clone [self]
|
||||||
(delete [_] (.log js/console (clj->js _data)))
|
(let [id (get-data self :id)
|
||||||
|
page-id (:current-page-id @st/state)
|
||||||
|
ret-v (atom nil)]
|
||||||
|
(st/emit! (dws/duplicate-shapes #{id} :change-selection? false :return-ref ret-v))
|
||||||
|
(let [new-id (deref ret-v)
|
||||||
|
shape (dm/get-in @st/state [:workspace-data :pages-index page-id :objects new-id])]
|
||||||
|
(data->shape-proxy shape))))
|
||||||
|
|
||||||
|
(remove [self]
|
||||||
|
(let [id (get-data self :id)]
|
||||||
|
(st/emit! (dwsh/delete-shapes #{id}))))
|
||||||
|
|
||||||
(appendChild [self child]
|
(appendChild [self child]
|
||||||
(let [parent-id (get-data self :id)
|
(let [parent-id (get-data self :id)
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.spec :as us]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]
|
||||||
|
[promesa.core :as p]))
|
||||||
(def uuid-regex
|
|
||||||
#"\w{8}-\w{4}-\w{4}-\w{4}-\w{12}")
|
|
||||||
|
|
||||||
(defn get-data
|
(defn get-data
|
||||||
([self attr]
|
([self attr]
|
||||||
|
@ -42,7 +41,7 @@
|
||||||
(let [v (cond (map? v)
|
(let [v (cond (map? v)
|
||||||
(from-js v)
|
(from-js v)
|
||||||
|
|
||||||
(and (string? v) (re-matches uuid-regex v))
|
(and (string? v) (re-matches us/uuid-rx v))
|
||||||
(uuid/uuid v)
|
(uuid/uuid v)
|
||||||
|
|
||||||
:else v)]
|
:else v)]
|
||||||
|
@ -50,7 +49,6 @@
|
||||||
{}
|
{}
|
||||||
ret)))
|
ret)))
|
||||||
|
|
||||||
|
|
||||||
(defn to-js
|
(defn to-js
|
||||||
"Converts to javascript an camelize the keys"
|
"Converts to javascript an camelize the keys"
|
||||||
[obj]
|
[obj]
|
||||||
|
@ -65,5 +63,19 @@
|
||||||
obj)]
|
obj)]
|
||||||
(clj->js result)))
|
(clj->js result)))
|
||||||
|
|
||||||
|
(defn result-p
|
||||||
|
"Creates a pair of atom+promise. The promise will be resolved when the atom gets a value.
|
||||||
|
We use this to return the promise to the library clients and resolve its value when a value is passed
|
||||||
|
to the atom"
|
||||||
|
[]
|
||||||
|
(let [ret-v (atom nil)
|
||||||
|
ret-p
|
||||||
|
(p/create
|
||||||
|
(fn [resolve _]
|
||||||
|
(add-watch
|
||||||
|
ret-v
|
||||||
|
::watcher
|
||||||
|
(fn [_ _ _ value]
|
||||||
|
(remove-watch ret-v ::watcher)
|
||||||
|
(resolve value)))))]
|
||||||
|
[ret-v ret-p]))
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
|
[app.common.spec :as us]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace.viewport :as dwv]
|
[app.main.data.workspace.viewport :as dwv]
|
||||||
[app.main.data.workspace.zoom :as dwz]
|
[app.main.data.workspace.zoom :as dwz]
|
||||||
|
@ -46,8 +47,9 @@
|
||||||
:set
|
:set
|
||||||
(fn [_ value]
|
(fn [_ value]
|
||||||
(let [new-x (obj/get value "x")
|
(let [new-x (obj/get value "x")
|
||||||
new-y (obj/get value "y")
|
new-y (obj/get value "y")]
|
||||||
vb (dm/get-in @st/state [:workspace-local :vbox])
|
(when (and (us/safe-number? new-x) (us/safe-number? new-y))
|
||||||
|
(let [vb (dm/get-in @st/state [:workspace-local :vbox])
|
||||||
old-x (+ (:x vb) (/ (:width vb) 2))
|
old-x (+ (:x vb) (/ (:width vb) 2))
|
||||||
old-y (+ (:y vb) (/ (:height vb) 2))
|
old-y (+ (:y vb) (/ (:height vb) 2))
|
||||||
delta-x (- new-x old-x)
|
delta-x (- new-x old-x)
|
||||||
|
@ -55,7 +57,7 @@
|
||||||
to-position
|
to-position
|
||||||
{:x #(+ % delta-x)
|
{:x #(+ % delta-x)
|
||||||
:y #(+ % delta-y)}]
|
:y #(+ % delta-y)}]
|
||||||
(st/emit! (dwv/update-viewport-position to-position))))}
|
(st/emit! (dwv/update-viewport-position to-position))))))}
|
||||||
|
|
||||||
{:name "zoom"
|
{:name "zoom"
|
||||||
:get
|
:get
|
||||||
|
@ -63,8 +65,9 @@
|
||||||
(dm/get-in @st/state [:workspace-local :zoom]))
|
(dm/get-in @st/state [:workspace-local :zoom]))
|
||||||
:set
|
:set
|
||||||
(fn [_ value]
|
(fn [_ value]
|
||||||
|
(when (us/safe-number? value)
|
||||||
(let [z (dm/get-in @st/state [:workspace-local :zoom])]
|
(let [z (dm/get-in @st/state [:workspace-local :zoom])]
|
||||||
(st/emit! (dwz/set-zoom (/ value z)))))}
|
(st/emit! (dwz/set-zoom (/ value z))))))}
|
||||||
|
|
||||||
{:name "bounds"
|
{:name "bounds"
|
||||||
:get
|
:get
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue