mirror of
https://github.com/penpot/penpot.git
synced 2025-05-23 19:56:13 +02:00
✨ Add support for plugin data into penpot objects
This commit is contained in:
parent
4d4a3a512d
commit
5233654da2
22 changed files with 764 additions and 138 deletions
|
@ -133,6 +133,18 @@
|
||||||
[:id ::sm/uuid]
|
[:id ::sm/uuid]
|
||||||
[:name :string]]]
|
[:name :string]]]
|
||||||
|
|
||||||
|
[:mod-plugin-data
|
||||||
|
[:map {:title "ModPagePluginData"}
|
||||||
|
[:type [:= :mod-plugin-data]]
|
||||||
|
[:object-type [::sm/one-of #{:file :page :shape :color :typography :component}]]
|
||||||
|
;; It's optional because files don't need the id for type :file
|
||||||
|
[:object-id {:optional true} [:maybe ::sm/uuid]]
|
||||||
|
;; Only needed in type shape
|
||||||
|
[:page-id {:optional true} [:maybe ::sm/uuid]]
|
||||||
|
[:namespace :keyword]
|
||||||
|
[:key :string]
|
||||||
|
[:value [:maybe :string]]]]
|
||||||
|
|
||||||
[:del-page
|
[:del-page
|
||||||
[:map {:title "DelPageChange"}
|
[:map {:title "DelPageChange"}
|
||||||
[:type [:= :del-page]]
|
[:type [:= :del-page]]
|
||||||
|
@ -586,6 +598,36 @@
|
||||||
[data {:keys [id name]}]
|
[data {:keys [id name]}]
|
||||||
(d/update-in-when data [:pages-index id] assoc :name name))
|
(d/update-in-when data [:pages-index id] assoc :name name))
|
||||||
|
|
||||||
|
(defmethod process-change :mod-plugin-data
|
||||||
|
[data {:keys [object-type object-id page-id namespace key value]}]
|
||||||
|
|
||||||
|
(when (and (= object-type :shape) (nil? page-id))
|
||||||
|
(ex/raise :type :internal :hint "update for shapes needs a page-id"))
|
||||||
|
|
||||||
|
(letfn [(update-fn
|
||||||
|
[data]
|
||||||
|
(if (some? value)
|
||||||
|
(assoc-in data [:plugin-data namespace key] value)
|
||||||
|
(update-in data [:plugin-data namespace] (fnil dissoc {}) key)))]
|
||||||
|
(case object-type
|
||||||
|
:file
|
||||||
|
(update-fn data)
|
||||||
|
|
||||||
|
:page
|
||||||
|
(d/update-in-when data [:pages-index object-id :options] update-fn)
|
||||||
|
|
||||||
|
:shape
|
||||||
|
(d/update-in-when data [:pages-index page-id :objects object-id] update-fn)
|
||||||
|
|
||||||
|
:color
|
||||||
|
(d/update-in-when data [:colors object-id] update-fn)
|
||||||
|
|
||||||
|
:typography
|
||||||
|
(d/update-in-when data [:typographies object-id] update-fn)
|
||||||
|
|
||||||
|
:component
|
||||||
|
(d/update-in-when data [:components object-id] update-fn))))
|
||||||
|
|
||||||
(defmethod process-change :del-page
|
(defmethod process-change :del-page
|
||||||
[data {:keys [id]}]
|
[data {:keys [id]}]
|
||||||
(ctpl/delete-page data id))
|
(ctpl/delete-page data id))
|
||||||
|
|
|
@ -201,6 +201,37 @@
|
||||||
(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)))
|
(apply-changes-local)))
|
||||||
|
|
||||||
|
(defn mod-plugin-data
|
||||||
|
([changes namespace key value]
|
||||||
|
(mod-plugin-data changes :file nil nil namespace key value))
|
||||||
|
([changes type id namespace key value]
|
||||||
|
(mod-plugin-data changes type id nil namespace key value))
|
||||||
|
([changes type id page-id namespace key value]
|
||||||
|
(let [data (::file-data (meta changes))
|
||||||
|
old-val
|
||||||
|
(case type
|
||||||
|
:file
|
||||||
|
(get-in data [:plugin-data namespace key])
|
||||||
|
|
||||||
|
:page
|
||||||
|
(get-in data [:pages-index id :options :plugin-data namespace key])
|
||||||
|
|
||||||
|
:shape
|
||||||
|
(get-in data [:pages-index page-id :objects id :plugin-data namespace key])
|
||||||
|
|
||||||
|
:color
|
||||||
|
(get-in data [:colors id :plugin-data namespace key])
|
||||||
|
|
||||||
|
:typography
|
||||||
|
(get-in data [:typographies id :plugin-data namespace key])
|
||||||
|
|
||||||
|
:component
|
||||||
|
(get-in data [:components id :plugin-data namespace key]))]
|
||||||
|
(-> changes
|
||||||
|
(update :redo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value value})
|
||||||
|
(update :undo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value old-val})
|
||||||
|
(apply-changes-local)))))
|
||||||
|
|
||||||
(defn del-page
|
(defn del-page
|
||||||
[changes page]
|
[changes page]
|
||||||
(-> changes
|
(-> changes
|
||||||
|
|
|
@ -658,6 +658,9 @@
|
||||||
::oapi/format "uri"
|
::oapi/format "uri"
|
||||||
::oapi/decode (comp u/uri str/trim)}})
|
::oapi/decode (comp u/uri str/trim)}})
|
||||||
|
|
||||||
|
(def! ::plugin-data
|
||||||
|
[:map-of {:gen/max 5} :string :string])
|
||||||
|
|
||||||
;; ---- PREDICATES
|
;; ---- PREDICATES
|
||||||
|
|
||||||
(def valid-safe-number?
|
(def valid-safe-number?
|
||||||
|
|
|
@ -84,7 +84,9 @@
|
||||||
[:ref-id {:optional true} ::sm/uuid]
|
[:ref-id {:optional true} ::sm/uuid]
|
||||||
[:ref-file {:optional true} ::sm/uuid]
|
[:ref-file {:optional true} ::sm/uuid]
|
||||||
[:gradient {:optional true} [:maybe ::gradient]]
|
[:gradient {:optional true} [:maybe ::gradient]]
|
||||||
[:image {:optional true} [:maybe ::image-color]]]
|
[:image {:optional true} [:maybe ::image-color]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]
|
||||||
[::sm/contains-any {:strict true} [:color :gradient :image]]])
|
[::sm/contains-any {:strict true} [:color :gradient :image]]])
|
||||||
|
|
||||||
(sm/define! ::recent-color
|
(sm/define! ::recent-color
|
||||||
|
|
|
@ -35,7 +35,9 @@
|
||||||
[:path {:optional true} [:maybe :string]]
|
[:path {:optional true} [:maybe :string]]
|
||||||
[:modified-at {:optional true} ::sm/inst]
|
[:modified-at {:optional true} ::sm/inst]
|
||||||
[:objects {:optional true}
|
[:objects {:optional true}
|
||||||
[:map-of {:gen/max 10} ::sm/uuid :map]]])
|
[:map-of {:gen/max 10} ::sm/uuid :map]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||||
|
|
||||||
(def check-container!
|
(def check-container!
|
||||||
(sm/check-fn ::container))
|
(sm/check-fn ::container))
|
||||||
|
|
|
@ -57,7 +57,9 @@
|
||||||
[:typographies {:optional true}
|
[:typographies {:optional true}
|
||||||
[:map-of {:gen/max 2} ::sm/uuid ::cty/typography]]
|
[:map-of {:gen/max 2} ::sm/uuid ::cty/typography]]
|
||||||
[:media {:optional true}
|
[:media {:optional true}
|
||||||
[:map-of {:gen/max 5} ::sm/uuid ::media-object]]])
|
[:map-of {:gen/max 5} ::sm/uuid ::media-object]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||||
|
|
||||||
(def check-file-data!
|
(def check-file-data!
|
||||||
(sm/check-fn ::data))
|
(sm/check-fn ::data))
|
||||||
|
|
|
@ -43,7 +43,9 @@
|
||||||
[:flows {:optional true}
|
[:flows {:optional true}
|
||||||
[:vector {:gen/max 2} ::flow]]
|
[:vector {:gen/max 2} ::flow]]
|
||||||
[:guides {:optional true}
|
[:guides {:optional true}
|
||||||
[:map-of {:gen/max 2} ::sm/uuid ::guide]]]]])
|
[:map-of {:gen/max 2} ::sm/uuid ::guide]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]]]])
|
||||||
|
|
||||||
(def check-page-guide!
|
(def check-page-guide!
|
||||||
(sm/check-fn ::guide))
|
(sm/check-fn ::guide))
|
||||||
|
|
|
@ -186,7 +186,9 @@
|
||||||
[:vector {:gen/max 1} ::ctss/shadow]]
|
[:vector {:gen/max 1} ::ctss/shadow]]
|
||||||
[:blur {:optional true} ::ctsb/blur]
|
[:blur {:optional true} ::ctsb/blur]
|
||||||
[:grow-type {:optional true}
|
[:grow-type {:optional true}
|
||||||
[::sm/one-of #{:auto-width :auto-height :fixed}]]])
|
[::sm/one-of #{:auto-width :auto-height :fixed}]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||||
|
|
||||||
(sm/define! ::group-attrs
|
(sm/define! ::group-attrs
|
||||||
[:map {:title "GroupAttrs"}
|
[:map {:title "GroupAttrs"}
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
[:letter-spacing :string]
|
[:letter-spacing :string]
|
||||||
[:text-transform :string]
|
[:text-transform :string]
|
||||||
[:modified-at {:optional true} ::sm/inst]
|
[:modified-at {:optional true} ::sm/inst]
|
||||||
[:path {:optional true} [:maybe :string]]])
|
[:path {:optional true} [:maybe :string]]
|
||||||
|
[:plugin-data {:optional true}
|
||||||
|
[:map-of {:gen/max 5} :keyword ::sm/plugin-data]]])
|
||||||
|
|
||||||
(def check-typography!
|
(def check-typography!
|
||||||
(sm/check-fn ::typography))
|
(sm/check-fn ::typography))
|
||||||
|
|
|
@ -568,6 +568,35 @@
|
||||||
|
|
||||||
(rx/of (dch/commit-changes changes))))))
|
(rx/of (dch/commit-changes changes))))))
|
||||||
|
|
||||||
|
(defn set-plugin-data
|
||||||
|
([file-id type namespace key value]
|
||||||
|
(set-plugin-data file-id type nil nil namespace key value))
|
||||||
|
([file-id type id namespace key value]
|
||||||
|
(set-plugin-data file-id type id nil namespace key value))
|
||||||
|
([file-id type id page-id namespace key value]
|
||||||
|
(dm/assert! (contains? #{:file :page :shape :color :typography :component} type))
|
||||||
|
(dm/assert! (or (nil? id) (uuid? id)))
|
||||||
|
(dm/assert! (or (nil? page-id) (uuid? page-id)))
|
||||||
|
(dm/assert! (uuid? file-id))
|
||||||
|
(dm/assert! (keyword? namespace))
|
||||||
|
(dm/assert! (string? key))
|
||||||
|
(dm/assert! (or (nil? value) (string? value)))
|
||||||
|
|
||||||
|
(ptk/reify ::set-file-plugin-data
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [it state _]
|
||||||
|
(let [file-data
|
||||||
|
(if (= file-id (:current-file-id state))
|
||||||
|
(:workspace-data state)
|
||||||
|
(get-in state [:workspace-libraries file-id :data]))
|
||||||
|
|
||||||
|
changes
|
||||||
|
(-> (pcb/empty-changes it)
|
||||||
|
(pcb/with-file-data file-data)
|
||||||
|
(assoc :file-id file-id)
|
||||||
|
(pcb/mod-plugin-data type id page-id namespace key value))]
|
||||||
|
(rx/of (dch/commit-changes changes)))))))
|
||||||
|
|
||||||
(declare purge-page)
|
(declare purge-page)
|
||||||
(declare go-to-file)
|
(declare go-to-file)
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,8 @@
|
||||||
(defn open-plugin!
|
(defn open-plugin!
|
||||||
[{:keys [plugin-id name description host code icon permissions]}]
|
[{:keys [plugin-id name description host code icon permissions]}]
|
||||||
(.ɵloadPlugin
|
(.ɵloadPlugin
|
||||||
js/window #js
|
js/window
|
||||||
{:pluginId plugin-id
|
#js {:pluginId plugin-id
|
||||||
:name name
|
:name name
|
||||||
:description description
|
:description description
|
||||||
:host host
|
:host host
|
||||||
|
|
|
@ -26,5 +26,4 @@
|
||||||
(fn []
|
(fn []
|
||||||
(when (features/active-feature? @st/state "plugins/runtime")
|
(when (features/active-feature? @st/state "plugins/runtime")
|
||||||
(when-let [init-runtime (obj/get global "initPluginsRuntime")]
|
(when-let [init-runtime (obj/get global "initPluginsRuntime")]
|
||||||
(let [context (api/create-context)]
|
(init-runtime (fn [plugin-id] (api/create-context plugin-id)))))))))
|
||||||
(init-runtime context))))))))
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
||||||
;;
|
;;
|
||||||
(defn create-shape
|
(defn create-shape
|
||||||
[type]
|
[plugin-id type]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [page-id (:current-page-id @st/state)
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
page (dm/get-in @st/state [:workspace-data :pages-index page-id])
|
||||||
shape (cts/setup-shape {:type type
|
shape (cts/setup-shape {:type type
|
||||||
|
@ -46,13 +46,13 @@
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy (:id shape))))
|
(shape/shape-proxy plugin-id (:id shape))))
|
||||||
|
|
||||||
(deftype PenpotContext []
|
(deftype PenpotContext [$plugin]
|
||||||
Object
|
Object
|
||||||
(addListener
|
(addListener
|
||||||
[_ type callback]
|
[_ type callback]
|
||||||
(events/add-listener type callback))
|
(events/add-listener type $plugin callback))
|
||||||
|
|
||||||
(removeListener
|
(removeListener
|
||||||
[_ listener-id]
|
[_ listener-id]
|
||||||
|
@ -60,17 +60,17 @@
|
||||||
|
|
||||||
(getViewport
|
(getViewport
|
||||||
[_]
|
[_]
|
||||||
(viewport/create-proxy))
|
(viewport/create-proxy $plugin))
|
||||||
|
|
||||||
(getFile
|
(getFile
|
||||||
[_]
|
[_]
|
||||||
(file/file-proxy (:current-file-id @st/state)))
|
(file/file-proxy $plugin (:current-file-id @st/state)))
|
||||||
|
|
||||||
(getPage
|
(getPage
|
||||||
[_]
|
[_]
|
||||||
(let [file-id (:current-file-id @st/state)
|
(let [file-id (:current-file-id @st/state)
|
||||||
page-id (:current-page-id @st/state)]
|
page-id (:current-page-id @st/state)]
|
||||||
(page/page-proxy file-id page-id)))
|
(page/page-proxy $plugin file-id page-id)))
|
||||||
|
|
||||||
(getSelected
|
(getSelected
|
||||||
[_]
|
[_]
|
||||||
|
@ -80,11 +80,11 @@
|
||||||
(getSelectedShapes
|
(getSelectedShapes
|
||||||
[_]
|
[_]
|
||||||
(let [selection (get-in @st/state [:workspace-local :selected])]
|
(let [selection (get-in @st/state [:workspace-local :selected])]
|
||||||
(apply array (sequence (map shape/shape-proxy) selection))))
|
(apply array (sequence (map (partial shape/shape-proxy $plugin)) selection))))
|
||||||
|
|
||||||
(getRoot
|
(getRoot
|
||||||
[_]
|
[_]
|
||||||
(shape/shape-proxy uuid/zero))
|
(shape/shape-proxy $plugin uuid/zero))
|
||||||
|
|
||||||
(getTheme
|
(getTheme
|
||||||
[_]
|
[_]
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
|
|
||||||
(getCurrentUser
|
(getCurrentUser
|
||||||
[_]
|
[_]
|
||||||
(user/current-user-proxy (:session-id @st/state)))
|
(user/current-user-proxy $plugin (:session-id @st/state)))
|
||||||
|
|
||||||
(getActiveUsers
|
(getActiveUsers
|
||||||
[_]
|
[_]
|
||||||
|
@ -103,7 +103,7 @@
|
||||||
(->> (:workspace-presence @st/state)
|
(->> (:workspace-presence @st/state)
|
||||||
(vals)
|
(vals)
|
||||||
(remove #(= (:id %) (:session-id @st/state)))
|
(remove #(= (:id %) (:session-id @st/state)))
|
||||||
(map #(user/active-user-proxy (:id %))))))
|
(map #(user/active-user-proxy $plugin (:id %))))))
|
||||||
|
|
||||||
(uploadMediaUrl
|
(uploadMediaUrl
|
||||||
[_ name url]
|
[_ name url]
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
id (uuid/next)
|
id (uuid/next)
|
||||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||||
(st/emit! (dwg/group-shapes id ids))
|
(st/emit! (dwg/group-shapes id ids))
|
||||||
(shape/shape-proxy file-id page-id id)))
|
(shape/shape-proxy $plugin file-id page-id id)))
|
||||||
|
|
||||||
(ungroup
|
(ungroup
|
||||||
[_ group & rest]
|
[_ group & rest]
|
||||||
|
@ -132,15 +132,15 @@
|
||||||
|
|
||||||
(createFrame
|
(createFrame
|
||||||
[_]
|
[_]
|
||||||
(create-shape :frame))
|
(create-shape $plugin :frame))
|
||||||
|
|
||||||
(createRectangle
|
(createRectangle
|
||||||
[_]
|
[_]
|
||||||
(create-shape :rect))
|
(create-shape $plugin :rect))
|
||||||
|
|
||||||
(createEllipse
|
(createEllipse
|
||||||
[_]
|
[_]
|
||||||
(create-shape :circle))
|
(create-shape $plugin :circle))
|
||||||
|
|
||||||
(createPath
|
(createPath
|
||||||
[_]
|
[_]
|
||||||
|
@ -156,7 +156,7 @@
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy (:id shape))))
|
(shape/shape-proxy $plugin (:id shape))))
|
||||||
|
|
||||||
(createText
|
(createText
|
||||||
[_ text]
|
[_ text]
|
||||||
|
@ -172,7 +172,7 @@
|
||||||
(cb/with-objects (:objects page))
|
(cb/with-objects (:objects page))
|
||||||
(cb/add-object shape))]
|
(cb/add-object shape))]
|
||||||
(st/emit! (ch/commit-changes changes))
|
(st/emit! (ch/commit-changes changes))
|
||||||
(shape/shape-proxy file-id page-id (:id shape))))
|
(shape/shape-proxy $plugin file-id page-id (:id shape))))
|
||||||
|
|
||||||
(createShapeFromSvg
|
(createShapeFromSvg
|
||||||
[_ svg-string]
|
[_ svg-string]
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
file-id (:current-file-id @st/state)
|
file-id (:current-file-id @st/state)
|
||||||
page-id (:current-page-id @st/state)]
|
page-id (:current-page-id @st/state)]
|
||||||
(st/emit! (dwm/create-svg-shape id "svg" svg-string (gpt/point 0 0)))
|
(st/emit! (dwm/create-svg-shape id "svg" svg-string (gpt/point 0 0)))
|
||||||
(shape/shape-proxy file-id page-id id))))
|
(shape/shape-proxy $plugin file-id page-id id))))
|
||||||
|
|
||||||
(createBoolean [_ bool-type shapes]
|
(createBoolean [_ bool-type shapes]
|
||||||
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
|
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
|
||||||
|
@ -190,14 +190,15 @@
|
||||||
(if (contains? cts/bool-types bool-type)
|
(if (contains? cts/bool-types bool-type)
|
||||||
(let [id-ret (atom nil)]
|
(let [id-ret (atom nil)]
|
||||||
(st/emit! (dwb/create-bool bool-type ids {:id-ret id-ret}))
|
(st/emit! (dwb/create-bool bool-type ids {:id-ret id-ret}))
|
||||||
(shape/shape-proxy @id-ret))
|
(shape/shape-proxy $plugin @id-ret))
|
||||||
|
|
||||||
(utils/display-not-valid :bool-shape bool-type)))))
|
(utils/display-not-valid :bool-shape bool-type)))))
|
||||||
|
|
||||||
(defn create-context
|
(defn create-context
|
||||||
[]
|
[plugin-id]
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(PenpotContext.)
|
(PenpotContext. plugin-id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "root" :get #(.getRoot ^js %)}
|
{:name "root" :get #(.getRoot ^js %)}
|
||||||
{:name "currentFile" :get #(.getFile ^js %)}
|
{:name "currentFile" :get #(.getFile ^js %)}
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
|
@ -205,4 +206,4 @@
|
||||||
{:name "viewport" :get #(.getViewport ^js %)}
|
{:name "viewport" :get #(.getViewport ^js %)}
|
||||||
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
||||||
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
||||||
{:name "library" :get (fn [_] (library/library-subcontext))}))
|
{:name "library" :get (fn [_] (library/library-subcontext plugin-id))}))
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
(defmulti handle-state-change (fn [type _] type))
|
(defmulti handle-state-change (fn [type _] type))
|
||||||
|
|
||||||
(defmethod handle-state-change "finish"
|
(defmethod handle-state-change "finish"
|
||||||
[_ old-val new-val]
|
[_ _ old-val new-val]
|
||||||
(let [old-file-id (:current-file-id old-val)
|
(let [old-file-id (:current-file-id old-val)
|
||||||
new-file-id (:current-file-id new-val)]
|
new-file-id (:current-file-id new-val)]
|
||||||
(if (and (some? old-file-id) (nil? new-file-id))
|
(if (and (some? old-file-id) (nil? new-file-id))
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
::not-changed)))
|
::not-changed)))
|
||||||
|
|
||||||
(defmethod handle-state-change "filechange"
|
(defmethod handle-state-change "filechange"
|
||||||
[_ old-val new-val]
|
[_ plugin-id old-val new-val]
|
||||||
(let [old-file (:workspace-file old-val)
|
(let [old-file (:workspace-file old-val)
|
||||||
new-file (:workspace-file new-val)
|
new-file (:workspace-file new-val)
|
||||||
old-data (:workspace-data old-val)
|
old-data (:workspace-data old-val)
|
||||||
|
@ -31,10 +31,10 @@
|
||||||
(if (and (identical? old-file new-file)
|
(if (and (identical? old-file new-file)
|
||||||
(identical? old-data new-data))
|
(identical? old-data new-data))
|
||||||
::not-changed
|
::not-changed
|
||||||
(file/file-proxy (:id new-file)))))
|
(file/file-proxy plugin-id (:id new-file)))))
|
||||||
|
|
||||||
(defmethod handle-state-change "pagechange"
|
(defmethod handle-state-change "pagechange"
|
||||||
[_ old-val new-val]
|
[_ plugin-id old-val new-val]
|
||||||
(let [file-id (:current-file-id new-val)
|
(let [file-id (:current-file-id new-val)
|
||||||
old-page-id (:current-page-id old-val)
|
old-page-id (:current-page-id old-val)
|
||||||
new-page-id (:current-page-id new-val)
|
new-page-id (:current-page-id new-val)
|
||||||
|
@ -42,10 +42,10 @@
|
||||||
new-page (dm/get-in new-val [:workspace-data :pages-index new-page-id])]
|
new-page (dm/get-in new-val [:workspace-data :pages-index new-page-id])]
|
||||||
(if (identical? old-page new-page)
|
(if (identical? old-page new-page)
|
||||||
::not-changed
|
::not-changed
|
||||||
(page/page-proxy file-id new-page-id))))
|
(page/page-proxy plugin-id file-id new-page-id))))
|
||||||
|
|
||||||
(defmethod handle-state-change "selectionchange"
|
(defmethod handle-state-change "selectionchange"
|
||||||
[_ old-val new-val]
|
[_ _ old-val new-val]
|
||||||
(let [old-selection (get-in old-val [:workspace-local :selected])
|
(let [old-selection (get-in old-val [:workspace-local :selected])
|
||||||
new-selection (get-in new-val [:workspace-local :selected])]
|
new-selection (get-in new-val [:workspace-local :selected])]
|
||||||
(if (identical? old-selection new-selection)
|
(if (identical? old-selection new-selection)
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
(apply array (map str new-selection)))))
|
(apply array (map str new-selection)))))
|
||||||
|
|
||||||
(defmethod handle-state-change "themechange"
|
(defmethod handle-state-change "themechange"
|
||||||
[_ old-val new-val]
|
[_ _ old-val new-val]
|
||||||
(let [old-theme (get-in old-val [:profile :theme])
|
(let [old-theme (get-in old-val [:profile :theme])
|
||||||
new-theme (get-in new-val [:profile :theme])]
|
new-theme (get-in new-val [:profile :theme])]
|
||||||
(if (identical? old-theme new-theme)
|
(if (identical? old-theme new-theme)
|
||||||
|
@ -63,17 +63,17 @@
|
||||||
new-theme))))
|
new-theme))))
|
||||||
|
|
||||||
(defmethod handle-state-change :default
|
(defmethod handle-state-change :default
|
||||||
[_ _ _]
|
[_ _ _ _]
|
||||||
::not-changed)
|
::not-changed)
|
||||||
|
|
||||||
(defn add-listener
|
(defn add-listener
|
||||||
[type callback]
|
[type plugin-id callback]
|
||||||
(let [key (js/Symbol)
|
(let [key (js/Symbol)
|
||||||
callback (gf/debounce callback 10)]
|
callback (gf/debounce callback 10)]
|
||||||
(add-watch
|
(add-watch
|
||||||
st/state key
|
st/state key
|
||||||
(fn [_ _ old-val new-val]
|
(fn [_ _ old-val new-val]
|
||||||
(let [result (handle-state-change type old-val new-val)]
|
(let [result (handle-state-change type plugin-id old-val new-val)]
|
||||||
(when (not= ::not-changed result)
|
(when (not= ::not-changed result)
|
||||||
(callback result)))))
|
(callback result)))))
|
||||||
|
|
||||||
|
|
|
@ -9,15 +9,84 @@
|
||||||
(: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.main.data.workspace :as dw]
|
||||||
|
[app.main.store :as st]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
[app.plugins.utils :refer [locate-file proxy->file]]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(deftype FileProxy [$id]
|
(deftype FileProxy [$plugin $id]
|
||||||
Object
|
Object
|
||||||
(getPages [_]
|
(getPages [_]
|
||||||
(let [file (locate-file $id)]
|
(let [file (u/locate-file $id)]
|
||||||
(apply array (sequence (map #(page/page-proxy $id %)) (dm/get-in file [:data :pages]))))))
|
(apply array (sequence (map #(page/page-proxy $plugin $id %)) (dm/get-in file [:data :pages])))))
|
||||||
|
|
||||||
|
;; Plugin data
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :file-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $id :file (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(dm/get-in file [:data :plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :file-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $id :file (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
FileProxy
|
FileProxy
|
||||||
|
@ -25,16 +94,17 @@
|
||||||
:get (fn [] (str "FileProxy"))})
|
:get (fn [] (str "FileProxy"))})
|
||||||
|
|
||||||
(defn file-proxy
|
(defn file-proxy
|
||||||
[id]
|
[plugin-id id]
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
(FileProxy. id)
|
(FileProxy. plugin-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
:get #(dm/str (obj/get % "$id"))}
|
:get #(dm/str (obj/get % "$id"))}
|
||||||
|
|
||||||
{:name "name"
|
{:name "name"
|
||||||
:get #(-> % proxy->file :name)}
|
:get #(-> % u/proxy->file :name)}
|
||||||
|
|
||||||
{:name "pages"
|
{:name "pages"
|
||||||
:get #(.getPages ^js %)}))
|
:get #(.getPages ^js %)}))
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
(deftype FlexLayout [$file $page $id]
|
(deftype FlexLayout [$plugin $file $page $id]
|
||||||
Object
|
Object
|
||||||
(remove
|
(remove
|
||||||
[_]
|
[_]
|
||||||
|
@ -30,9 +30,10 @@
|
||||||
(ptk/data-event :layout/update {:ids [$id]})))))
|
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||||
|
|
||||||
(defn flex-layout-proxy
|
(defn flex-layout-proxy
|
||||||
[file-id page-id id]
|
[plugin-id file-id page-id id]
|
||||||
(-> (FlexLayout. file-id page-id id)
|
(-> (FlexLayout. plugin-id file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
@ -148,12 +149,13 @@
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||||
|
|
||||||
|
|
||||||
(deftype LayoutChildProxy [$file $page $id])
|
(deftype LayoutChildProxy [$plugin $file $page $id])
|
||||||
|
|
||||||
(defn layout-child-proxy
|
(defn layout-child-proxy
|
||||||
[file-id page-id id]
|
[plugin-id file-id page-id id]
|
||||||
(-> (LayoutChildProxy. file-id page-id id)
|
(-> (LayoutChildProxy. plugin-id file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
js/Object
|
js/Object
|
||||||
(apply array (->> tracks (map utils/to-js)))))
|
(apply array (->> tracks (map utils/to-js)))))
|
||||||
|
|
||||||
(deftype GridLayout [$file $page $id]
|
(deftype GridLayout [$plugin $file $page $id]
|
||||||
Object
|
Object
|
||||||
|
|
||||||
(addRow
|
(addRow
|
||||||
|
@ -75,9 +75,10 @@
|
||||||
(ptk/data-event :layout/update {:ids [$id]})))))
|
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||||
|
|
||||||
(defn grid-layout-proxy
|
(defn grid-layout-proxy
|
||||||
[file-id page-id id]
|
[plugin-id file-id page-id id]
|
||||||
(-> (GridLayout. file-id page-id id)
|
(-> (GridLayout. plugin-id file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
@ -164,7 +165,6 @@
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
||||||
|
|
||||||
|
|
||||||
{:name "topPadding"
|
{:name "topPadding"
|
||||||
:get #(-> % proxy->shape :layout-padding :p1)
|
:get #(-> % proxy->shape :layout-padding :p1)
|
||||||
:set
|
:set
|
||||||
|
@ -197,17 +197,18 @@
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||||
|
|
||||||
(deftype GridCellProxy [$file $page $id])
|
(deftype GridCellProxy [$plugin $file $page $id])
|
||||||
|
|
||||||
(defn layout-cell-proxy
|
(defn layout-cell-proxy
|
||||||
[file-id page-id id]
|
[plugin-id file-id page-id id]
|
||||||
(letfn [(locate-cell [_]
|
(letfn [(locate-cell [_]
|
||||||
(let [shape (locate-shape file-id page-id id)
|
(let [shape (locate-shape file-id page-id id)
|
||||||
parent (locate-shape file-id page-id (:parent-id shape))]
|
parent (locate-shape file-id page-id (:parent-id shape))]
|
||||||
(ctl/get-cell-by-shape-id parent id)))]
|
(ctl/get-cell-by-shape-id parent id)))]
|
||||||
|
|
||||||
(-> (GridCellProxy. file-id page-id id)
|
(-> (GridCellProxy. plugin-id file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
[app.common.types.color :as ctc]
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.typography :as ctt]
|
[app.common.types.typography :as ctt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.texts :as dwt]
|
[app.main.data.workspace.texts :as dwt]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
|
@ -26,7 +27,7 @@
|
||||||
(declare lib-color-proxy)
|
(declare lib-color-proxy)
|
||||||
(declare lib-typography-proxy)
|
(declare lib-typography-proxy)
|
||||||
|
|
||||||
(deftype LibraryColorProxy [$file $id]
|
(deftype LibraryColorProxy [$plugin $file $id]
|
||||||
Object
|
Object
|
||||||
|
|
||||||
(remove
|
(remove
|
||||||
|
@ -39,7 +40,7 @@
|
||||||
color (-> (u/locate-library-color $file $id)
|
color (-> (u/locate-library-color $file $id)
|
||||||
(assoc :id color-id))]
|
(assoc :id color-id))]
|
||||||
(st/emit! (dwl/add-color color {:rename? false}))
|
(st/emit! (dwl/add-color color {:rename? false}))
|
||||||
(lib-color-proxy $id color-id)))
|
(lib-color-proxy $plugin $id color-id)))
|
||||||
|
|
||||||
(asFill [_]
|
(asFill [_]
|
||||||
(let [color (u/locate-library-color $file $id)]
|
(let [color (u/locate-library-color $file $id)]
|
||||||
|
@ -63,15 +64,87 @@
|
||||||
:stroke-color-ref-id $id
|
:stroke-color-ref-id $id
|
||||||
:stroke-image (:image color)
|
:stroke-image (:image color)
|
||||||
:stroke-style :solid
|
:stroke-style :solid
|
||||||
:stroke-alignment :inner})))))
|
:stroke-alignment :inner}))))
|
||||||
|
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :color-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [color (u/proxy->library-color self)]
|
||||||
|
(dm/get-in color [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :color-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :color-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :color-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :color $id (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [color (u/proxy->library-color self)]
|
||||||
|
(apply array (keys (dm/get-in color [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :color-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [color (u/proxy->library-color self)]
|
||||||
|
(dm/get-in color [:plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :color-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :color-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :color-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :color $id (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :color-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [color (u/proxy->library-color self)]
|
||||||
|
(apply array (keys (dm/get-in color [:plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(defn lib-color-proxy
|
(defn lib-color-proxy
|
||||||
[file-id id]
|
[plugin-id file-id id]
|
||||||
(assert (uuid? file-id))
|
(assert (uuid? file-id))
|
||||||
(assert (uuid? id))
|
(assert (uuid? id))
|
||||||
|
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(LibraryColorProxy. file-id id)
|
(LibraryColorProxy. plugin-id file-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
|
|
||||||
|
@ -139,7 +212,7 @@
|
||||||
(st/emit! (dwl/update-color color file-id)))
|
(st/emit! (dwl/update-color color file-id)))
|
||||||
(u/display-not-valid :library-color-image value))))}))
|
(u/display-not-valid :library-color-image value))))}))
|
||||||
|
|
||||||
(deftype LibraryTypographyProxy [$file $id]
|
(deftype LibraryTypographyProxy [$plugin $file $id]
|
||||||
Object
|
Object
|
||||||
(remove
|
(remove
|
||||||
[_]
|
[_]
|
||||||
|
@ -151,7 +224,7 @@
|
||||||
typo (-> (u/locate-library-typography $file $id)
|
typo (-> (u/locate-library-typography $file $id)
|
||||||
(assoc :id typo-id))]
|
(assoc :id typo-id))]
|
||||||
(st/emit! (dwl/add-typography typo false))
|
(st/emit! (dwl/add-typography typo false))
|
||||||
(lib-typography-proxy $id typo-id)))
|
(lib-typography-proxy $plugin $id typo-id)))
|
||||||
|
|
||||||
(applyToText
|
(applyToText
|
||||||
[_ shape]
|
[_ shape]
|
||||||
|
@ -162,15 +235,88 @@
|
||||||
(applyToTextRange
|
(applyToTextRange
|
||||||
[_ _shape _from _to]
|
[_ _shape _from _to]
|
||||||
;; TODO
|
;; TODO
|
||||||
))
|
)
|
||||||
|
|
||||||
|
;; PLUGIN DATA
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :typography-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [typography (u/proxy->library-typography self)]
|
||||||
|
(dm/get-in typography [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :typography-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :typography-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :typography-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :typography $id (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [typography (u/proxy->library-typography self)]
|
||||||
|
(apply array (keys (dm/get-in typography [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :typography-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [typography (u/proxy->library-typography self)]
|
||||||
|
(dm/get-in typography [:plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :typography-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :typography-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :typography-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :typography $id (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :typography-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [typography (u/proxy->library-typography self)]
|
||||||
|
(apply array (keys (dm/get-in typography [:plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(defn lib-typography-proxy
|
(defn lib-typography-proxy
|
||||||
[file-id id]
|
[plugin-id file-id id]
|
||||||
(assert (uuid? file-id))
|
(assert (uuid? file-id))
|
||||||
(assert (uuid? id))
|
(assert (uuid? id))
|
||||||
|
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(LibraryTypographyProxy. file-id id)
|
(LibraryTypographyProxy. plugin-id file-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "id" :get (fn [_] (dm/str id))}
|
{:name "id" :get (fn [_] (dm/str id))}
|
||||||
|
@ -285,7 +431,7 @@
|
||||||
(st/emit! (dwl/update-typography typo file-id)))
|
(st/emit! (dwl/update-typography typo file-id)))
|
||||||
(u/display-not-valid :library-typography-text-transform value)))}))
|
(u/display-not-valid :library-typography-text-transform value)))}))
|
||||||
|
|
||||||
(deftype LibraryComponentProxy [$file $id]
|
(deftype LibraryComponentProxy [$plugin $file $id]
|
||||||
Object
|
Object
|
||||||
|
|
||||||
(remove
|
(remove
|
||||||
|
@ -296,15 +442,87 @@
|
||||||
[_]
|
[_]
|
||||||
(let [id-ref (atom nil)]
|
(let [id-ref (atom nil)]
|
||||||
(st/emit! (dwl/instantiate-component $file $id (gpt/point 0 0) {:id-ref id-ref}))
|
(st/emit! (dwl/instantiate-component $file $id (gpt/point 0 0) {:id-ref id-ref}))
|
||||||
(shapes/shape-proxy @id-ref))))
|
(shapes/shape-proxy $plugin @id-ref)))
|
||||||
|
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :component-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [component (u/proxy->library-component self)]
|
||||||
|
(dm/get-in component [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :component-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :component-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :component-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :component $id (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [component (u/proxy->library-component self)]
|
||||||
|
(apply array (keys (dm/get-in component [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :component-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [component (u/proxy->library-component self)]
|
||||||
|
(dm/get-in component [:plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
(cond
|
||||||
|
(not= $file (:current-file-id @st/state))
|
||||||
|
(u/display-not-valid :component-edit-non-local-library $file)
|
||||||
|
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :component-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :component-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :component $id (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :component-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [component (u/proxy->library-component self)]
|
||||||
|
(apply array (keys (dm/get-in component [:plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(defn lib-component-proxy
|
(defn lib-component-proxy
|
||||||
[file-id id]
|
[plugin-id file-id id]
|
||||||
(assert (uuid? file-id))
|
(assert (uuid? file-id))
|
||||||
(assert (uuid? id))
|
(assert (uuid? id))
|
||||||
|
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(LibraryComponentProxy. file-id id)
|
(LibraryComponentProxy. plugin-id file-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "id" :get (fn [_] (dm/str id))}
|
{:name "id" :get (fn [_] (dm/str id))}
|
||||||
|
@ -329,34 +547,102 @@
|
||||||
(st/emit! (dwl/rename-component id value)))
|
(st/emit! (dwl/rename-component id value)))
|
||||||
(u/display-not-valid :library-component-path value)))}))
|
(u/display-not-valid :library-component-path value)))}))
|
||||||
|
|
||||||
(deftype Library [$id]
|
(deftype Library [$plugin $id]
|
||||||
Object
|
Object
|
||||||
|
|
||||||
(createColor
|
(createColor
|
||||||
[_]
|
[_]
|
||||||
(let [color-id (uuid/next)]
|
(let [color-id (uuid/next)]
|
||||||
(st/emit! (dwl/add-color {:id color-id :name "Color" :color "#000000" :opacity 1} {:rename? false}))
|
(st/emit! (dwl/add-color {:id color-id :name "Color" :color "#000000" :opacity 1} {:rename? false}))
|
||||||
(lib-color-proxy $id color-id)))
|
(lib-color-proxy $plugin $id color-id)))
|
||||||
|
|
||||||
(createTypography
|
(createTypography
|
||||||
[_]
|
[_]
|
||||||
(let [typography-id (uuid/next)]
|
(let [typography-id (uuid/next)]
|
||||||
(st/emit! (dwl/add-typography (ctt/make-typography {:id typography-id :name "Typography"}) false))
|
(st/emit! (dwl/add-typography (ctt/make-typography {:id typography-id :name "Typography"}) false))
|
||||||
(lib-typography-proxy $id typography-id)))
|
(lib-typography-proxy $plugin $id typography-id)))
|
||||||
|
|
||||||
(createComponent
|
(createComponent
|
||||||
[_ shapes]
|
[_ shapes]
|
||||||
(let [id-ref (atom nil)
|
(let [id-ref (atom nil)
|
||||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||||
(st/emit! (dwl/add-component id-ref ids))
|
(st/emit! (dwl/add-component id-ref ids))
|
||||||
(lib-component-proxy $id @id-ref))))
|
(lib-component-proxy $plugin $id @id-ref)))
|
||||||
|
|
||||||
|
;; Plugin data
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :file-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $id :file (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(dm/get-in file [:data :plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :file-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :file-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $id :file (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [file (u/proxy->file self)]
|
||||||
|
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(defn library-proxy
|
(defn library-proxy
|
||||||
[file-id]
|
[plugin-id file-id]
|
||||||
(assert (uuid? file-id) "File id not valid")
|
(assert (uuid? file-id) "File id not valid")
|
||||||
|
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(Library. file-id)
|
(Library. plugin-id file-id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
|
@ -369,14 +655,14 @@
|
||||||
:get
|
:get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [file (u/locate-file file-id)
|
(let [file (u/locate-file file-id)
|
||||||
colors (->> file :data :colors keys (map #(lib-color-proxy file-id %)))]
|
colors (->> file :data :colors keys (map #(lib-color-proxy plugin-id file-id %)))]
|
||||||
(apply array colors)))}
|
(apply array colors)))}
|
||||||
|
|
||||||
{:name "typographies"
|
{:name "typographies"
|
||||||
:get
|
:get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [file (u/locate-file file-id)
|
(let [file (u/locate-file file-id)
|
||||||
typographies (->> file :data :typographies keys (map #(lib-typography-proxy file-id %)))]
|
typographies (->> file :data :typographies keys (map #(lib-typography-proxy plugin-id file-id %)))]
|
||||||
(apply array typographies)))}
|
(apply array typographies)))}
|
||||||
|
|
||||||
{:name "components"
|
{:name "components"
|
||||||
|
@ -388,10 +674,10 @@
|
||||||
:components
|
:components
|
||||||
(remove (comp :deleted second))
|
(remove (comp :deleted second))
|
||||||
(map first)
|
(map first)
|
||||||
(map #(lib-component-proxy file-id %)))]
|
(map #(lib-component-proxy plugin-id file-id %)))]
|
||||||
(apply array components)))}))
|
(apply array components)))}))
|
||||||
|
|
||||||
(deftype PenpotLibrarySubcontext []
|
(deftype PenpotLibrarySubcontext [$plugin]
|
||||||
Object
|
Object
|
||||||
(find
|
(find
|
||||||
[_ _name])
|
[_ _name])
|
||||||
|
@ -399,14 +685,15 @@
|
||||||
(find [_]))
|
(find [_]))
|
||||||
|
|
||||||
(defn library-subcontext
|
(defn library-subcontext
|
||||||
[]
|
[plugin-id]
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(PenpotLibrarySubcontext.)
|
(PenpotLibrarySubcontext. plugin-id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "local" :get
|
{:name "local" :get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(library-proxy (:current-file-id @st/state)))}
|
(library-proxy plugin-id (:current-file-id @st/state)))}
|
||||||
|
|
||||||
{:name "connected" :get
|
{:name "connected" :get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [libraries (get @st/state :workspace-libraries)]
|
(let [libraries (get @st/state :workspace-libraries)]
|
||||||
(apply array (->> libraries vals (map library-proxy)))))}))
|
(apply array (->> libraries keys (map (partial library-proxy plugin-id))))))}))
|
||||||
|
|
|
@ -17,23 +17,90 @@
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(deftype PageProxy [$file $id]
|
(deftype PageProxy [$plugin $file $id]
|
||||||
Object
|
Object
|
||||||
(getShapeById
|
(getShapeById
|
||||||
[_ shape-id]
|
[_ shape-id]
|
||||||
(let [shape-id (uuid/uuid shape-id)]
|
(let [shape-id (uuid/uuid shape-id)]
|
||||||
(shape/shape-proxy $file $id shape-id)))
|
(shape/shape-proxy $plugin $file $id shape-id)))
|
||||||
|
|
||||||
(getRoot
|
(getRoot
|
||||||
[_]
|
[_]
|
||||||
(shape/shape-proxy $file $id uuid/zero))
|
(shape/shape-proxy $plugin $file $id uuid/zero))
|
||||||
|
|
||||||
(findShapes
|
(findShapes
|
||||||
[_]
|
[_]
|
||||||
;; Returns a lazy (iterable) of all available shapes
|
;; Returns a lazy (iterable) of all available shapes
|
||||||
(when (and (some? $file) (some? $id))
|
(when (and (some? $file) (some? $id))
|
||||||
(let [page (u/locate-page $file $id)]
|
(let [page (u/locate-page $file $id)]
|
||||||
(apply array (sequence (map shape/shape-proxy) (keys (:objects page))))))))
|
(apply array (sequence (map (partial shape/shape-proxy $plugin)) (keys (:objects page)))))))
|
||||||
|
|
||||||
|
;; Plugin data
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :page-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [page (u/proxy->page self)]
|
||||||
|
(dm/get-in page [:options :plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :page-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :page-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :page $id (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [page (u/proxy->page self)]
|
||||||
|
(apply array (keys (dm/get-in page [:options :plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :page-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [page (u/proxy->page self)]
|
||||||
|
(dm/get-in page [:options :plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :page-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :page-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :page $id (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :page-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [page (u/proxy->page self)]
|
||||||
|
(apply array (keys (dm/get-in page [:options :plugin-data (keyword "shared" namespace)])))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
PageProxy
|
PageProxy
|
||||||
|
@ -41,9 +108,10 @@
|
||||||
:get (fn [] (str "PageProxy"))})
|
:get (fn [] (str "PageProxy"))})
|
||||||
|
|
||||||
(defn page-proxy
|
(defn page-proxy
|
||||||
[file-id id]
|
[plugin-id file-id id]
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
(PageProxy. file-id id)
|
(PageProxy. plugin-id file-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.colors :as clr]
|
[app.common.colors :as clr]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.rect :as grc]
|
[app.common.geom.rect :as grc]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
@ -20,7 +21,7 @@
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.types.shape.radius :as ctsr]
|
[app.common.types.shape.radius :as ctsr]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
|
@ -61,23 +62,90 @@
|
||||||
(dwt/current-paragraph-values {:shape shape :attrs txt/paragraph-attrs})
|
(dwt/current-paragraph-values {:shape shape :attrs txt/paragraph-attrs})
|
||||||
(dwt/current-text-values {:shape shape :attrs txt/text-node-attrs})))
|
(dwt/current-text-values {:shape shape :attrs txt/text-node-attrs})))
|
||||||
|
|
||||||
(deftype ShapeProxy [$file $page $id]
|
(deftype ShapeProxy [$plugin $file $page $id]
|
||||||
Object
|
Object
|
||||||
(resize
|
(resize
|
||||||
[_ width height]
|
[_ width height]
|
||||||
(st/emit! (udw/update-dimensions [$id] :width width)
|
(st/emit! (dw/update-dimensions [$id] :width width)
|
||||||
(udw/update-dimensions [$id] :height height)))
|
(dw/update-dimensions [$id] :height height)))
|
||||||
|
|
||||||
(clone
|
(clone
|
||||||
[_]
|
[_]
|
||||||
(let [ret-v (atom nil)]
|
(let [ret-v (atom nil)]
|
||||||
(st/emit! (dws/duplicate-shapes #{$id} :change-selection? false :return-ref ret-v))
|
(st/emit! (dws/duplicate-shapes #{$id} :change-selection? false :return-ref ret-v))
|
||||||
(shape-proxy (deref ret-v))))
|
(shape-proxy $plugin (deref ret-v))))
|
||||||
|
|
||||||
(remove
|
(remove
|
||||||
[_]
|
[_]
|
||||||
(st/emit! (dwsh/delete-shapes #{$id})))
|
(st/emit! (dwsh/delete-shapes #{$id})))
|
||||||
|
|
||||||
|
;; Plugin data
|
||||||
|
(getPluginData
|
||||||
|
[self key]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :shape-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [shape (u/proxy->shape self)]
|
||||||
|
(dm/get-in shape [:plugin-data (keyword "plugin" (str $plugin)) key]))))
|
||||||
|
|
||||||
|
(setPluginData
|
||||||
|
[_ key value]
|
||||||
|
(cond
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :shape-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :shape-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :shape $id $page (keyword "plugin" (str $plugin)) key value))))
|
||||||
|
|
||||||
|
(getPluginDataKeys
|
||||||
|
[self]
|
||||||
|
(let [shape (u/proxy->shape self)]
|
||||||
|
(apply array (keys (dm/get-in shape [:plugin-data (keyword "plugin" (str $plugin))])))))
|
||||||
|
|
||||||
|
(getSharedPluginData
|
||||||
|
[self namespace key]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :shape-plugin-data-key key)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [shape (u/proxy->shape self)]
|
||||||
|
(dm/get-in shape [:plugin-data (keyword "shared" namespace) key]))))
|
||||||
|
|
||||||
|
(setSharedPluginData
|
||||||
|
[_ namespace key value]
|
||||||
|
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
(not (string? key))
|
||||||
|
(u/display-not-valid :shape-plugin-data-key key)
|
||||||
|
|
||||||
|
(and (some? value) (not (string? value)))
|
||||||
|
(u/display-not-valid :shape-plugin-data value)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(st/emit! (dw/set-plugin-data $file :shape $id $page (keyword "shared" namespace) key value))))
|
||||||
|
|
||||||
|
(getSharedPluginDataKeys
|
||||||
|
[self namespace]
|
||||||
|
(cond
|
||||||
|
(not (string? namespace))
|
||||||
|
(u/display-not-valid :shape-plugin-data-namespace namespace)
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [shape (u/proxy->shape self)]
|
||||||
|
(apply array (keys (dm/get-in shape [:plugin-data (keyword "shared" namespace)]))))))
|
||||||
|
|
||||||
;; Only for frames + groups + booleans
|
;; Only for frames + groups + booleans
|
||||||
(getChildren
|
(getChildren
|
||||||
[_]
|
[_]
|
||||||
|
@ -85,7 +153,7 @@
|
||||||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||||
(apply array (->> (u/locate-shape $file $page $id)
|
(apply array (->> (u/locate-shape $file $page $id)
|
||||||
:shapes
|
:shapes
|
||||||
(map #(shape-proxy $file $page %))))
|
(map #(shape-proxy $plugin $file $page %))))
|
||||||
(u/display-not-valid :getChildren (:type shape)))))
|
(u/display-not-valid :getChildren (:type shape)))))
|
||||||
|
|
||||||
(appendChild
|
(appendChild
|
||||||
|
@ -93,7 +161,7 @@
|
||||||
(let [shape (u/locate-shape $file $page $id)]
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||||
(let [child-id (obj/get child "$id")]
|
(let [child-id (obj/get child "$id")]
|
||||||
(st/emit! (udw/relocate-shapes #{child-id} $id 0)))
|
(st/emit! (dw/relocate-shapes #{child-id} $id 0)))
|
||||||
(u/display-not-valid :appendChild (:type shape)))))
|
(u/display-not-valid :appendChild (:type shape)))))
|
||||||
|
|
||||||
(insertChild
|
(insertChild
|
||||||
|
@ -101,7 +169,7 @@
|
||||||
(let [shape (u/locate-shape $file $page $id)]
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
(if (or (cfh/frame-shape? shape) (cfh/group-shape? shape) (cfh/svg-raw-shape? shape) (cfh/bool-shape? shape))
|
||||||
(let [child-id (obj/get child "$id")]
|
(let [child-id (obj/get child "$id")]
|
||||||
(st/emit! (udw/relocate-shapes #{child-id} $id index)))
|
(st/emit! (dw/relocate-shapes #{child-id} $id index)))
|
||||||
(u/display-not-valid :insertChild (:type shape)))))
|
(u/display-not-valid :insertChild (:type shape)))))
|
||||||
|
|
||||||
;; Only for frames
|
;; Only for frames
|
||||||
|
@ -110,7 +178,7 @@
|
||||||
(let [shape (u/locate-shape $file $page $id)]
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
(if (cfh/frame-shape? shape)
|
(if (cfh/frame-shape? shape)
|
||||||
(do (st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false))
|
(do (st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false))
|
||||||
(grid/grid-layout-proxy $file $page $id))
|
(grid/grid-layout-proxy $plugin $file $page $id))
|
||||||
(u/display-not-valid :addFlexLayout (:type shape)))))
|
(u/display-not-valid :addFlexLayout (:type shape)))))
|
||||||
|
|
||||||
(addGridLayout
|
(addGridLayout
|
||||||
|
@ -118,7 +186,7 @@
|
||||||
(let [shape (u/locate-shape $file $page $id)]
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
(if (cfh/frame-shape? shape)
|
(if (cfh/frame-shape? shape)
|
||||||
(do (st/emit! (dwsl/create-layout-from-id $id :grid :from-frame? true :calculate-params? false))
|
(do (st/emit! (dwsl/create-layout-from-id $id :grid :from-frame? true :calculate-params? false))
|
||||||
(grid/grid-layout-proxy $file $page $id))
|
(grid/grid-layout-proxy $plugin $file $page $id))
|
||||||
(u/display-not-valid :addGridLayout (:type shape)))))
|
(u/display-not-valid :addGridLayout (:type shape)))))
|
||||||
|
|
||||||
;; Make masks for groups
|
;; Make masks for groups
|
||||||
|
@ -142,6 +210,14 @@
|
||||||
(let [shape (u/locate-shape $file $page $id)]
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
(if (cfh/path-shape? shape)
|
(if (cfh/path-shape? shape)
|
||||||
(upf/format-path (:content shape))
|
(upf/format-path (:content shape))
|
||||||
|
(u/display-not-valid :makeMask (:type shape)))))
|
||||||
|
|
||||||
|
;; Text shapes
|
||||||
|
(getRange
|
||||||
|
[_ _from _to]
|
||||||
|
(let [shape (u/locate-shape $file $page $id)]
|
||||||
|
(if (cfh/text-shape? shape)
|
||||||
|
nil ;; TODO
|
||||||
(u/display-not-valid :makeMask (:type shape))))))
|
(u/display-not-valid :makeMask (:type shape))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
|
@ -150,20 +226,21 @@
|
||||||
:get (fn [] (str "ShapeProxy"))})
|
:get (fn [] (str "ShapeProxy"))})
|
||||||
|
|
||||||
(defn shape-proxy
|
(defn shape-proxy
|
||||||
([id]
|
([plugin-id id]
|
||||||
(shape-proxy (:current-file-id @st/state) (:current-page-id @st/state) id))
|
(shape-proxy plugin-id (:current-file-id @st/state) (:current-page-id @st/state) id))
|
||||||
|
|
||||||
([page-id id]
|
([plugin-id page-id id]
|
||||||
(shape-proxy (:current-file-id @st/state) page-id id))
|
(shape-proxy plugin-id (:current-file-id @st/state) page-id id))
|
||||||
|
|
||||||
([file-id page-id id]
|
([plugin-id file-id page-id id]
|
||||||
(assert (uuid? file-id))
|
(assert (uuid? file-id))
|
||||||
(assert (uuid? page-id))
|
(assert (uuid? page-id))
|
||||||
(assert (uuid? id))
|
(assert (uuid? id))
|
||||||
|
|
||||||
(let [data (u/locate-shape file-id page-id id)]
|
(let [data (u/locate-shape file-id page-id id)]
|
||||||
(-> (ShapeProxy. file-id page-id id)
|
(-> (ShapeProxy. plugin-id file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
{:name "$id" :enumerable false :get (constantly id)}
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
@ -332,14 +409,14 @@
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (obj/get self "$id")]
|
(let [id (obj/get self "$id")]
|
||||||
(st/emit! (udw/update-position id {:x value}))))}
|
(st/emit! (dw/update-position id {:x value}))))}
|
||||||
|
|
||||||
{:name "y"
|
{:name "y"
|
||||||
:get #(-> % u/proxy->shape :y)
|
:get #(-> % u/proxy->shape :y)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (obj/get self "$id")]
|
(let [id (obj/get self "$id")]
|
||||||
(st/emit! (udw/update-position id {:y value}))))}
|
(st/emit! (dw/update-position id {:y value}))))}
|
||||||
|
|
||||||
{:name "parentX"
|
{:name "parentX"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
|
@ -353,7 +430,7 @@
|
||||||
parent-id (-> self u/proxy->shape :parent-id)
|
parent-id (-> self u/proxy->shape :parent-id)
|
||||||
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||||
parent-x (:x parent)]
|
parent-x (:x parent)]
|
||||||
(st/emit! (udw/update-position id {:x (+ parent-x value)}))))}
|
(st/emit! (dw/update-position id {:x (+ parent-x value)}))))}
|
||||||
|
|
||||||
{:name "parentY"
|
{:name "parentY"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
|
@ -368,7 +445,7 @@
|
||||||
parent-id (-> self u/proxy->shape :parent-id)
|
parent-id (-> self u/proxy->shape :parent-id)
|
||||||
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
parent (u/locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||||
parent-y (:y parent)]
|
parent-y (:y parent)]
|
||||||
(st/emit! (udw/update-position id {:y (+ parent-y value)}))))}
|
(st/emit! (dw/update-position id {:y (+ parent-y value)}))))}
|
||||||
|
|
||||||
{:name "frameX"
|
{:name "frameX"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
|
@ -383,7 +460,7 @@
|
||||||
frame-id (-> self u/proxy->shape :frame-id)
|
frame-id (-> self u/proxy->shape :frame-id)
|
||||||
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
frame-x (:x frame)]
|
frame-x (:x frame)]
|
||||||
(st/emit! (udw/update-position id {:x (+ frame-x value)}))))}
|
(st/emit! (dw/update-position id {:x (+ frame-x value)}))))}
|
||||||
|
|
||||||
{:name "frameY"
|
{:name "frameY"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
|
@ -398,7 +475,7 @@
|
||||||
frame-id (-> self u/proxy->shape :frame-id)
|
frame-id (-> self u/proxy->shape :frame-id)
|
||||||
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
frame (u/locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
frame-y (:y frame)]
|
frame-y (:y frame)]
|
||||||
(st/emit! (udw/update-position id {:y (+ frame-y value)}))))}
|
(st/emit! (dw/update-position id {:y (+ frame-y value)}))))}
|
||||||
|
|
||||||
{:name "width"
|
{:name "width"
|
||||||
:get #(-> % u/proxy->shape :width)}
|
:get #(-> % u/proxy->shape :width)}
|
||||||
|
@ -437,7 +514,7 @@
|
||||||
id (obj/get self "$id")
|
id (obj/get self "$id")
|
||||||
objects (u/locate-objects file-id page-id)]
|
objects (u/locate-objects file-id page-id)]
|
||||||
(when (ctl/any-layout-immediate-child-id? objects id)
|
(when (ctl/any-layout-immediate-child-id? objects id)
|
||||||
(flex/layout-child-proxy file-id page-id id))))}
|
(flex/layout-child-proxy plugin-id file-id page-id id))))}
|
||||||
|
|
||||||
{:name "layoutCell"
|
{:name "layoutCell"
|
||||||
:get
|
:get
|
||||||
|
@ -447,7 +524,7 @@
|
||||||
id (obj/get self "$id")
|
id (obj/get self "$id")
|
||||||
objects (u/locate-objects file-id page-id)]
|
objects (u/locate-objects file-id page-id)]
|
||||||
(when (ctl/grid-layout-immediate-child-id? objects id)
|
(when (ctl/grid-layout-immediate-child-id? objects id)
|
||||||
(grid/layout-cell-proxy file-id page-id id))))})
|
(grid/layout-cell-proxy plugin-id file-id page-id id))))})
|
||||||
|
|
||||||
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
@ -465,7 +542,7 @@
|
||||||
page-id (obj/get self "$page")
|
page-id (obj/get self "$page")
|
||||||
id (obj/get self "$id")]
|
id (obj/get self "$id")]
|
||||||
(when (= :grid layout)
|
(when (= :grid layout)
|
||||||
(grid/grid-layout-proxy file-id page-id id))))}
|
(grid/grid-layout-proxy plugin-id file-id page-id id))))}
|
||||||
|
|
||||||
{:name "flex"
|
{:name "flex"
|
||||||
:get
|
:get
|
||||||
|
@ -475,7 +552,7 @@
|
||||||
page-id (obj/get self "$page")
|
page-id (obj/get self "$page")
|
||||||
id (obj/get self "$id")]
|
id (obj/get self "$id")]
|
||||||
(when (= :flex layout)
|
(when (= :flex layout)
|
||||||
(flex/flex-layout-proxy file-id page-id id))))}
|
(flex/flex-layout-proxy plugin-id file-id page-id id))))}
|
||||||
|
|
||||||
{:name "guides"
|
{:name "guides"
|
||||||
:get #(-> % u/proxy->shape :grids u/array-to-js)
|
:get #(-> % u/proxy->shape :grids u/array-to-js)
|
||||||
|
|
|
@ -11,14 +11,18 @@
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(deftype CurrentUserProxy [$session])
|
(deftype CurrentUserProxy [$plugin $session])
|
||||||
(deftype ActiveUserProxy [$session])
|
(deftype ActiveUserProxy [$plugin $session])
|
||||||
|
|
||||||
(defn add-user-properties
|
(defn add-user-properties
|
||||||
[user-proxy]
|
[user-proxy]
|
||||||
(let [session-id (obj/get user-proxy "$session")]
|
(let [plugin-id (obj/get user-proxy "$plugin")
|
||||||
|
session-id (obj/get user-proxy "$session")]
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
user-proxy
|
user-proxy
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
|
{:name "$session" :enumerable false :get (constantly session-id)}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
:get (fn [_] (-> (u/locate-profile session-id) :id str))}
|
:get (fn [_] (-> (u/locate-profile session-id) :id str))}
|
||||||
|
|
||||||
|
@ -35,13 +39,13 @@
|
||||||
:get (fn [_] (str session-id))})))
|
:get (fn [_] (str session-id))})))
|
||||||
|
|
||||||
(defn current-user-proxy
|
(defn current-user-proxy
|
||||||
[session-id]
|
[plugin-id session-id]
|
||||||
(-> (CurrentUserProxy. session-id)
|
(-> (CurrentUserProxy. plugin-id session-id)
|
||||||
(add-user-properties)))
|
(add-user-properties)))
|
||||||
|
|
||||||
(defn active-user-proxy
|
(defn active-user-proxy
|
||||||
[session-id]
|
[plugin-id session-id]
|
||||||
(-> (ActiveUserProxy. session-id)
|
(-> (ActiveUserProxy. plugin-id session-id)
|
||||||
(add-user-properties)
|
(add-user-properties)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
{:name "position" :get (fn [_] (-> (u/locate-presence session-id) :point u/to-js))}
|
{:name "position" :get (fn [_] (-> (u/locate-presence session-id) :point u/to-js))}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(deftype ViewportProxy []
|
(deftype ViewportProxy [$plugin]
|
||||||
Object
|
Object
|
||||||
(zoomIntoView [_ shapes]
|
(zoomIntoView [_ shapes]
|
||||||
(let [ids
|
(let [ids
|
||||||
|
@ -33,9 +33,9 @@
|
||||||
:get (fn [] (str "ViewportProxy"))})
|
:get (fn [] (str "ViewportProxy"))})
|
||||||
|
|
||||||
(defn create-proxy
|
(defn create-proxy
|
||||||
[]
|
[plugin-id]
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
(ViewportProxy.)
|
(ViewportProxy. plugin-id)
|
||||||
{:name "center"
|
{:name "center"
|
||||||
:get
|
:get
|
||||||
(fn [_]
|
(fn [_]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue