mirror of
https://github.com/penpot/penpot.git
synced 2025-05-03 19:55:52 +02:00
♻️ Refactor plugins proxies internal data
This commit is contained in:
parent
b59dae57ca
commit
d6de1fdbdf
7 changed files with 454 additions and 429 deletions
|
@ -32,12 +32,6 @@
|
||||||
;;
|
;;
|
||||||
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
||||||
;;
|
;;
|
||||||
(def ^:private
|
|
||||||
xf-map-shape-proxy
|
|
||||||
(comp
|
|
||||||
(map val)
|
|
||||||
(map shape/data->shape-proxy)))
|
|
||||||
|
|
||||||
(defn create-shape
|
(defn create-shape
|
||||||
[type]
|
[type]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [page-id (:current-page-id @st/state)
|
||||||
|
@ -50,7 +44,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/data->shape-proxy shape)))
|
(shape/shape-proxy (:id shape))))
|
||||||
|
|
||||||
(deftype PenpotContext []
|
(deftype PenpotContext []
|
||||||
Object
|
Object
|
||||||
|
@ -64,13 +58,13 @@
|
||||||
|
|
||||||
(getFile
|
(getFile
|
||||||
[_]
|
[_]
|
||||||
(file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state)))
|
(file/file-proxy (:current-file-id @st/state)))
|
||||||
|
|
||||||
(getPage
|
(getPage
|
||||||
[_]
|
[_]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [file-id (:current-file-id @st/state)
|
||||||
page (dm/get-in @st/state [:workspace-data :pages-index page-id])]
|
page-id (:current-page-id @st/state)]
|
||||||
(page/data->page-proxy page)))
|
(page/page-proxy file-id page-id)))
|
||||||
|
|
||||||
(getSelected
|
(getSelected
|
||||||
[_]
|
[_]
|
||||||
|
@ -79,17 +73,12 @@
|
||||||
|
|
||||||
(getSelectedShapes
|
(getSelectedShapes
|
||||||
[_]
|
[_]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [selection (get-in @st/state [:workspace-local :selected])]
|
||||||
selection (get-in @st/state [:workspace-local :selected])
|
(apply array (sequence (map shape/shape-proxy) selection))))
|
||||||
objects (dm/get-in @st/state [:workspace-data :pages-index page-id :objects])
|
|
||||||
shapes (select-keys objects selection)]
|
|
||||||
(apply array (sequence xf-map-shape-proxy shapes))))
|
|
||||||
|
|
||||||
(getRoot
|
(getRoot
|
||||||
[_]
|
[_]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(shape/shape-proxy uuid/zero))
|
||||||
root (dm/get-in @st/state [:workspace-data :pages-index page-id :objects uuid/zero])]
|
|
||||||
(shape/data->shape-proxy root)))
|
|
||||||
|
|
||||||
(getTheme
|
(getTheme
|
||||||
[_]
|
[_]
|
||||||
|
@ -100,7 +89,7 @@
|
||||||
|
|
||||||
(uploadMediaUrl
|
(uploadMediaUrl
|
||||||
[_ name url]
|
[_ name url]
|
||||||
(let [file-id (get-in @st/state [:workspace-file :id])]
|
(let [file-id (:current-file-id @st/state)]
|
||||||
(p/create
|
(p/create
|
||||||
(fn [resolve reject]
|
(fn [resolve reject]
|
||||||
(->> (dwm/upload-media-url name file-id url)
|
(->> (dwm/upload-media-url name file-id url)
|
||||||
|
@ -110,17 +99,17 @@
|
||||||
|
|
||||||
(group
|
(group
|
||||||
[_ shapes]
|
[_ shapes]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [file-id (:current-file-id @st/state)
|
||||||
|
page-id (:current-page-id @st/state)
|
||||||
id (uuid/next)
|
id (uuid/next)
|
||||||
ids (into #{} (map #(get (obj/get % "_data") :id)) shapes)]
|
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||||
(st/emit! (dwg/group-shapes id ids))
|
(st/emit! (dwg/group-shapes id ids))
|
||||||
(shape/data->shape-proxy
|
(shape/shape-proxy file-id page-id id)))
|
||||||
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects id]))))
|
|
||||||
|
|
||||||
(ungroup
|
(ungroup
|
||||||
[_ group & rest]
|
[_ group & rest]
|
||||||
(let [shapes (concat [group] rest)
|
(let [shapes (concat [group] rest)
|
||||||
ids (into #{} (map #(get (obj/get % "_data") :id)) shapes)]
|
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||||
(st/emit! (dwg/ungroup-shapes ids))))
|
(st/emit! (dwg/ungroup-shapes ids))))
|
||||||
|
|
||||||
(createFrame
|
(createFrame
|
||||||
|
@ -133,7 +122,8 @@
|
||||||
|
|
||||||
(createText
|
(createText
|
||||||
[_ text]
|
[_ text]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [file-id (:current-file-id @st/state)
|
||||||
|
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 :text :x 0 :y 0 :grow-type :auto-width})
|
shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||||
(txt/change-text text)
|
(txt/change-text text)
|
||||||
|
@ -144,22 +134,23 @@
|
||||||
(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/data->shape-proxy shape)))
|
(shape/shape-proxy file-id page-id (:id shape))))
|
||||||
|
|
||||||
(createShapeFromSvg
|
(createShapeFromSvg
|
||||||
[_ svg-string]
|
[_ svg-string]
|
||||||
(when (some? svg-string)
|
(when (some? svg-string)
|
||||||
(let [id (uuid/next)
|
(let [id (uuid/next)
|
||||||
|
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/data->shape-proxy
|
(shape/shape-proxy file-id page-id id)))))
|
||||||
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects id]))))))
|
|
||||||
|
|
||||||
(defn create-context
|
(defn create-context
|
||||||
[]
|
[]
|
||||||
(cr/add-properties!
|
(cr/add-properties!
|
||||||
(PenpotContext.)
|
(PenpotContext.)
|
||||||
{:name "root" :get #(.getRoot ^js %)}
|
{:name "root" :get #(.getRoot ^js %)}
|
||||||
|
{:name "currentFile" :get #(.getFile ^js %)}
|
||||||
{:name "currentPage" :get #(.getPage ^js %)}
|
{:name "currentPage" :get #(.getPage ^js %)}
|
||||||
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
{:name "selection" :get #(.getSelectedShapes ^js %)}
|
||||||
{:name "viewport" :get #(.getViewport ^js %)}
|
{:name "viewport" :get #(.getViewport ^js %)}
|
||||||
|
|
|
@ -23,17 +23,18 @@
|
||||||
(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/data->file-proxy new-file new-data))))
|
(file/file-proxy (:id new-file)))))
|
||||||
|
|
||||||
(defmethod handle-state-change "pagechange"
|
(defmethod handle-state-change "pagechange"
|
||||||
[_ old-val new-val]
|
[_ old-val new-val]
|
||||||
(let [old-page-id (:current-page-id old-val)
|
(let [file-id (:current-file-id new-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)
|
||||||
old-page (dm/get-in old-val [:workspace-data :pages-index old-page-id])
|
old-page (dm/get-in old-val [:workspace-data :pages-index old-page-id])
|
||||||
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/data->page-proxy new-page))))
|
(page/page-proxy file-id new-page-id))))
|
||||||
|
|
||||||
(defmethod handle-state-change "selectionchange"
|
(defmethod handle-state-change "selectionchange"
|
||||||
[_ old-val new-val]
|
[_ old-val new-val]
|
||||||
|
|
|
@ -7,38 +7,34 @@
|
||||||
(ns app.plugins.file
|
(ns app.plugins.file
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
[app.plugins.page :as page]
|
[app.plugins.page :as page]
|
||||||
[app.plugins.utils :refer [get-data-fn]]))
|
[app.plugins.utils :refer [locate-file proxy->file]]
|
||||||
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(def ^:private
|
(deftype FileProxy [$id]
|
||||||
xf-map-page-proxy
|
|
||||||
(comp
|
|
||||||
(map val)
|
|
||||||
(map page/data->page-proxy)))
|
|
||||||
|
|
||||||
(deftype FileProxy [#_:clj-kondo/ignore _data]
|
|
||||||
Object
|
Object
|
||||||
(getPages [_]
|
(getPages [_]
|
||||||
;; Returns a lazy (iterable) of all available pages
|
(let [file (locate-file $id)]
|
||||||
(apply array (sequence xf-map-page-proxy (:pages-index _data)))))
|
(apply array (sequence (map #(page/page-proxy $id %)) (dm/get-in file [:data :pages]))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
FileProxy
|
FileProxy
|
||||||
{:name js/Symbol.toStringTag
|
{:name js/Symbol.toStringTag
|
||||||
:get (fn [] (str "FileProxy"))})
|
:get (fn [] (str "FileProxy"))})
|
||||||
|
|
||||||
(defn data->file-proxy
|
(defn file-proxy
|
||||||
[file data]
|
[id]
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
(FileProxy. (merge file data))
|
(FileProxy. id)
|
||||||
{:name "_data" :enumerable false}
|
{:name "$id" :enumerable false}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
:get (get-data-fn :id str)}
|
:get #(dm/str (obj/get % "$id"))}
|
||||||
|
|
||||||
{:name "name"
|
{:name "name"
|
||||||
:get (get-data-fn :name)}
|
:get #(-> % proxy->file :name)}
|
||||||
|
|
||||||
{:name "pages"
|
{:name "pages"
|
||||||
:get #(.getPages ^js %)}))
|
:get #(.getPages ^js %)}))
|
||||||
|
|
|
@ -10,11 +10,10 @@
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.data.workspace.transforms :as dwt]
|
[app.main.data.workspace.transforms :as dwt]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.utils :as utils :refer [get-data get-state]]
|
[app.plugins.utils :as utils :refer [proxy->shape]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[potok.v2.core :as ptk]))
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
@ -24,183 +23,176 @@
|
||||||
js/Object
|
js/Object
|
||||||
(apply array (->> tracks (map utils/to-js)))))
|
(apply array (->> tracks (map utils/to-js)))))
|
||||||
|
|
||||||
(deftype GridLayout [_data]
|
(deftype GridLayout [$file $page $id]
|
||||||
Object
|
Object
|
||||||
|
|
||||||
(addRow
|
(addRow
|
||||||
[self type value]
|
[_ type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value}))))
|
||||||
(st/emit! (dwsl/add-layout-track #{id} :row {:type type :value value}))))
|
|
||||||
|
|
||||||
(addRowAtIndex
|
(addRowAtIndex
|
||||||
[self index type value]
|
[_ index type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value} index))))
|
||||||
(st/emit! (dwsl/add-layout-track #{id} :row {:type type :value value} index))))
|
|
||||||
|
|
||||||
(addColumn
|
(addColumn
|
||||||
[self type value]
|
[_ type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value}))))
|
||||||
(st/emit! (dwsl/add-layout-track #{id} :column {:type type :value value}))))
|
|
||||||
|
|
||||||
(addColumnAtIndex
|
(addColumnAtIndex
|
||||||
[self index type value]
|
[_ index type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value} index))))
|
||||||
(st/emit! (dwsl/add-layout-track #{id} :column {:type type :value value} index))))
|
|
||||||
|
|
||||||
(removeRow
|
(removeRow
|
||||||
[self index]
|
[_ index]
|
||||||
(let [id (get-data self :id)]
|
(st/emit! (dwsl/remove-layout-track #{$id} :row index)))
|
||||||
(st/emit! (dwsl/remove-layout-track #{id} :row index))))
|
|
||||||
|
|
||||||
(removeColumn
|
(removeColumn
|
||||||
[self index]
|
[_ index]
|
||||||
(let [id (get-data self :id)]
|
(st/emit! (dwsl/remove-layout-track #{$id} :column index)))
|
||||||
(st/emit! (dwsl/remove-layout-track #{id} :column index))))
|
|
||||||
|
|
||||||
(setColumn
|
(setColumn
|
||||||
[self index type value]
|
[_ index type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/change-layout-track #{$id} :column index (d/without-nils {:type type :value value})))))
|
||||||
(st/emit! (dwsl/change-layout-track #{id} :column index (d/without-nils {:type type :value value})))))
|
|
||||||
|
|
||||||
(setRow
|
(setRow
|
||||||
[self index type value]
|
[_ index type value]
|
||||||
(let [id (get-data self :id)
|
(let [type (keyword type)]
|
||||||
type (keyword type)]
|
(st/emit! (dwsl/change-layout-track #{$id} :row index (d/without-nils {:type type :value value})))))
|
||||||
(st/emit! (dwsl/change-layout-track #{id} :row index (d/without-nils {:type type :value value})))))
|
|
||||||
|
|
||||||
(remove
|
(remove
|
||||||
[self]
|
[_]
|
||||||
(let [id (get-data self :id)]
|
(st/emit! (dwsl/remove-layout #{$id})))
|
||||||
(st/emit! (dwsl/remove-layout #{id}))))
|
|
||||||
|
|
||||||
(appendChild
|
(appendChild
|
||||||
[self child row column]
|
[_ child row column]
|
||||||
(let [parent-id (get-data self :id)
|
(let [child-id (obj/get child "$id")]
|
||||||
child-id (uuid/uuid (obj/get child "id"))]
|
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil [row column])
|
||||||
(st/emit! (dwt/move-shapes-to-frame #{child-id} parent-id nil [row column])
|
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||||
(ptk/data-event :layout/update {:ids [parent-id]})))))
|
|
||||||
|
|
||||||
(defn grid-layout-proxy
|
(defn grid-layout-proxy
|
||||||
[data]
|
[file-id page-id id]
|
||||||
(-> (GridLayout. data)
|
(-> (GridLayout. file-id page-id id)
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$page" :enumerable false}
|
||||||
{:name "dir"
|
{:name "dir"
|
||||||
:get #(get-state % :layout-grid-dir d/name)
|
:get #(-> % proxy->shape :layout-grid-dir d/name)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(when (contains? ctl/grid-direction-types value)
|
(when (contains? ctl/grid-direction-types value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-grid-dir value})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-grid-dir value})))))}
|
||||||
|
|
||||||
{:name "rows"
|
{:name "rows"
|
||||||
:get #(get-state % :layout-grid-rows make-tracks)}
|
:get #(-> % proxy->shape :layout-grid-rows make-tracks)}
|
||||||
|
|
||||||
{:name "columns"
|
{:name "columns"
|
||||||
:get #(get-state % :layout-grid-columns make-tracks)}
|
:get #(-> % proxy->shape :layout-grid-columns make-tracks)}
|
||||||
|
|
||||||
{:name "alignItems"
|
{:name "alignItems"
|
||||||
:get #(get-state % :layout-align-items d/name)
|
:get #(-> % proxy->shape :layout-align-items d/name)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(when (contains? ctl/align-items-types value)
|
(when (contains? ctl/align-items-types value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
|
||||||
|
|
||||||
{:name "alignContent"
|
{:name "alignContent"
|
||||||
:get #(get-state % :layout-align-content d/name)
|
:get #(-> % proxy->shape :layout-align-content d/name)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(when (contains? ctl/align-content-types value)
|
(when (contains? ctl/align-content-types value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
|
||||||
|
|
||||||
{:name "justifyItems"
|
{:name "justifyItems"
|
||||||
:get #(get-state % :layout-justify-items d/name)
|
:get #(-> % proxy->shape :layout-justify-items d/name)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(when (contains? ctl/justify-items-types value)
|
(when (contains? ctl/justify-items-types value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
|
||||||
|
|
||||||
{:name "justifyContent"
|
{:name "justifyContent"
|
||||||
:get #(get-state % :layout-justify-content d/name)
|
:get #(-> % proxy->shape :layout-justify-content d/name)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (keyword value)]
|
value (keyword value)]
|
||||||
(when (contains? ctl/justify-content-types value)
|
(when (contains? ctl/justify-content-types value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
|
||||||
|
|
||||||
{:name "rowGap"
|
{:name "rowGap"
|
||||||
:get #(:row-gap (get-state % :layout-gap))
|
:get #(-> % proxy->shape :layout-gap :row-gap)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}})))))}
|
||||||
|
|
||||||
{:name "columnGap"
|
{:name "columnGap"
|
||||||
:get #(:column-gap (get-state % :layout-gap))
|
:get #(-> % proxy->shape :layout-gap :column-gap)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}})))))}
|
||||||
|
|
||||||
{:name "verticalPadding"
|
{:name "verticalPadding"
|
||||||
:get #(:p1 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p1)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}})))))}
|
||||||
|
|
||||||
{:name "horizontalPadding"
|
{:name "horizontalPadding"
|
||||||
:get #(:p2 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p2)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(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 #(:p1 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p1)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}})))))}
|
||||||
|
|
||||||
{:name "rightPadding"
|
{:name "rightPadding"
|
||||||
:get #(:p2 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p2)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}})))))}
|
||||||
|
|
||||||
{:name "bottomPadding"
|
{:name "bottomPadding"
|
||||||
:get #(:p3 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p3)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}})))))}
|
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}})))))}
|
||||||
|
|
||||||
{:name "leftPadding"
|
{:name "leftPadding"
|
||||||
:get #(:p4 (get-state % :layout-padding))
|
:get #(-> % proxy->shape :layout-padding :p4)
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(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}})))))})))
|
||||||
|
|
|
@ -7,46 +7,48 @@
|
||||||
(ns app.plugins.page
|
(ns app.plugins.page
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.plugins.shape :as shape]
|
[app.plugins.shape :as shape]
|
||||||
[app.plugins.utils :refer [get-data-fn]]))
|
[app.plugins.utils :refer [locate-page proxy->page]]
|
||||||
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(def ^:private
|
(deftype PageProxy [$file $id]
|
||||||
xf-map-shape-proxy
|
|
||||||
(comp
|
|
||||||
(map val)
|
|
||||||
(map shape/data->shape-proxy)))
|
|
||||||
|
|
||||||
(deftype PageProxy [#_:clj-kondo/ignore _data]
|
|
||||||
Object
|
Object
|
||||||
(getShapeById [_ id]
|
(getShapeById
|
||||||
(shape/data->shape-proxy (get (:objects _data) (uuid/uuid id))))
|
[_ shape-id]
|
||||||
|
(let [shape-id (uuid/uuid shape-id)]
|
||||||
|
(shape/shape-proxy $file $id shape-id)))
|
||||||
|
|
||||||
(getRoot [_]
|
(getRoot
|
||||||
(shape/data->shape-proxy (get (:objects _data) uuid/zero)))
|
[_]
|
||||||
|
(shape/shape-proxy $file $id uuid/zero))
|
||||||
|
|
||||||
(findShapes [_]
|
(findShapes
|
||||||
|
[_]
|
||||||
;; Returns a lazy (iterable) of all available shapes
|
;; Returns a lazy (iterable) of all available shapes
|
||||||
(apply array (sequence xf-map-shape-proxy (:objects _data)))))
|
(let [page (locate-page $file $id)]
|
||||||
|
(apply array (sequence (map shape/shape-proxy) (keys (:objects page)))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
PageProxy
|
PageProxy
|
||||||
{:name js/Symbol.toStringTag
|
{:name js/Symbol.toStringTag
|
||||||
:get (fn [] (str "PageProxy"))})
|
:get (fn [] (str "PageProxy"))})
|
||||||
|
|
||||||
(defn data->page-proxy
|
(defn page-proxy
|
||||||
[data]
|
[file-id id]
|
||||||
|
|
||||||
(crc/add-properties!
|
(crc/add-properties!
|
||||||
(PageProxy. data)
|
(PageProxy. file-id id)
|
||||||
{:name "_data" :enumerable false}
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
|
||||||
{:name "id"
|
{:name "id"
|
||||||
:get (get-data-fn :id str)}
|
:get #(dm/str (obj/get % "$id"))}
|
||||||
|
|
||||||
{:name "name"
|
{:name "name"
|
||||||
:get (get-data-fn :name)}
|
:get #(-> % proxy->page :name)}
|
||||||
|
|
||||||
{:name "root"
|
{:name "root"
|
||||||
|
:enumerable false
|
||||||
:get #(.getRoot ^js %)}))
|
:get #(.getRoot ^js %)}))
|
||||||
|
|
|
@ -8,13 +8,11 @@
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
[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.record :as crc]
|
[app.common.record :as crc]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[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.selection :as dws]
|
||||||
|
@ -22,350 +20,353 @@
|
||||||
[app.main.data.workspace.shapes :as dwsh]
|
[app.main.data.workspace.shapes :as dwsh]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.grid :as grid]
|
[app.plugins.grid :as grid]
|
||||||
[app.plugins.utils :as utils :refer [get-data get-data-fn get-state]]
|
[app.plugins.utils :as utils :refer [locate-shape proxy->shape array-to-js]]
|
||||||
[app.util.object :as obj]))
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
(declare data->shape-proxy)
|
(declare shape-proxy)
|
||||||
|
|
||||||
(defn- array-to-js
|
(deftype ShapeProxy [$file $page $id]
|
||||||
[value]
|
|
||||||
(.freeze
|
|
||||||
js/Object
|
|
||||||
(apply array (->> value (map utils/to-js)))))
|
|
||||||
|
|
||||||
(defn- locate-shape
|
|
||||||
[shape-id]
|
|
||||||
(let [page-id (:current-page-id @st/state)]
|
|
||||||
(dm/get-in @st/state [:workspace-data :pages-index page-id :objects shape-id])))
|
|
||||||
|
|
||||||
(deftype ShapeProxy [#_:clj-kondo/ignore _data]
|
|
||||||
Object
|
Object
|
||||||
(resize
|
(resize
|
||||||
[self width height]
|
[_ width height]
|
||||||
(let [id (get-data self :id)]
|
(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 [self]
|
(clone
|
||||||
(let [id (get-data self :id)
|
[_]
|
||||||
page-id (:current-page-id @st/state)
|
(let [ret-v (atom nil)]
|
||||||
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))))
|
||||||
(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]
|
(remove
|
||||||
(let [id (get-data self :id)]
|
[_]
|
||||||
(st/emit! (dwsh/delete-shapes #{id}))))
|
(st/emit! (dwsh/delete-shapes #{$id})))
|
||||||
|
|
||||||
;; Only for frames + groups + booleans
|
;; Only for frames + groups + booleans
|
||||||
(getChildren
|
(getChildren
|
||||||
[self]
|
[_]
|
||||||
(apply array (->> (get-state self :shapes)
|
(apply array (->> (locate-shape $file $page $id)
|
||||||
(map locate-shape)
|
:shapes
|
||||||
(map data->shape-proxy))))
|
(map #(shape-proxy $file $page %)))))
|
||||||
|
|
||||||
(appendChild [self child]
|
(appendChild
|
||||||
(let [parent-id (get-data self :id)
|
[_ child]
|
||||||
child-id (uuid/uuid (obj/get child "id"))]
|
(let [child-id (obj/get child "$id")]
|
||||||
(st/emit! (udw/relocate-shapes #{child-id} parent-id 0))))
|
(st/emit! (udw/relocate-shapes #{child-id} $id 0))))
|
||||||
|
|
||||||
(insertChild [self index child]
|
(insertChild
|
||||||
(let [parent-id (get-data self :id)
|
[_ index child]
|
||||||
child-id (uuid/uuid (obj/get child "id"))]
|
(let [child-id (obj/get child "$id")]
|
||||||
(st/emit! (udw/relocate-shapes #{child-id} parent-id index))))
|
(st/emit! (udw/relocate-shapes #{child-id} $id index))))
|
||||||
|
|
||||||
;; Only for frames
|
;; Only for frames
|
||||||
(addFlexLayout [self]
|
(addFlexLayout
|
||||||
(let [id (get-data self :id)]
|
[_]
|
||||||
(st/emit! (dwsl/create-layout-from-id id :flex :from-frame? true :calculate-params? false))))
|
(st/emit! (dwsl/create-layout-from-id $id :flex :from-frame? true :calculate-params? false)))
|
||||||
|
|
||||||
(addGridLayout [self]
|
(addGridLayout
|
||||||
(let [id (get-data self :id)]
|
[_]
|
||||||
(st/emit! (dwsl/create-layout-from-id id :grid :from-frame? true :calculate-params? false))
|
(st/emit! (dwsl/create-layout-from-id $id :grid :from-frame? true :calculate-params? false))
|
||||||
(grid/grid-layout-proxy (obj/get self "_data")))))
|
(grid/grid-layout-proxy $file $page $id)))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
ShapeProxy
|
ShapeProxy
|
||||||
{:name js/Symbol.toStringTag
|
{:name js/Symbol.toStringTag
|
||||||
:get (fn [] (str "ShapeProxy"))})
|
:get (fn [] (str "ShapeProxy"))})
|
||||||
|
|
||||||
(defn data->shape-proxy
|
(defn shape-proxy
|
||||||
[data]
|
([id]
|
||||||
|
(shape-proxy (:current-file-id @st/state) (:current-page-id @st/state) id))
|
||||||
|
|
||||||
(-> (ShapeProxy. data)
|
([page-id id]
|
||||||
(crc/add-properties!
|
(shape-proxy (:current-file-id @st/state) page-id id))
|
||||||
{:name "_data"
|
|
||||||
:enumerable false}
|
|
||||||
|
|
||||||
{:name "id"
|
([file-id page-id id]
|
||||||
:get (get-data-fn :id str)}
|
(assert (uuid? file-id))
|
||||||
|
(assert (uuid? page-id))
|
||||||
|
(assert (uuid? id))
|
||||||
|
|
||||||
{:name "type"
|
(let [data (locate-shape file-id page-id id)]
|
||||||
:get (get-data-fn :type name)}
|
(-> (ShapeProxy. file-id page-id id)
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "$id" :enumerable false}
|
||||||
|
{:name "$file" :enumerable false}
|
||||||
|
{:name "$page" :enumerable false}
|
||||||
|
|
||||||
{:name "name"
|
{:name "id"
|
||||||
:get #(get-state % :name)
|
:get #(-> % proxy->shape :id str)}
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :name value)))))}
|
|
||||||
|
|
||||||
{:name "blocked"
|
{:name "type"
|
||||||
:get #(get-state % :blocked boolean)
|
:get #(-> % proxy->shape :type name)}
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :blocked value)))))}
|
|
||||||
|
|
||||||
{:name "hidden"
|
{:name "name"
|
||||||
:get #(get-state % :hidden boolean)
|
:get #(-> % proxy->shape :name)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :hidden value)))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :name value)))))}
|
||||||
|
|
||||||
{:name "proportionLock"
|
{:name "blocked"
|
||||||
:get #(get-state % :proportion-lock boolean)
|
:get #(-> % proxy->shape :blocked boolean)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :proportion-lock value)))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :blocked value)))))}
|
||||||
|
|
||||||
{:name "constraintsHorizontal"
|
{:name "hidden"
|
||||||
:get #(get-state % :constraints-h d/name)
|
:get #(-> % proxy->shape :hidden boolean)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")]
|
||||||
value (keyword value)]
|
(st/emit! (dwc/update-shapes [id] #(assoc % :hidden value)))))}
|
||||||
(when (contains? cts/horizontal-constraint-types value)
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :constraints-h value))))))}
|
|
||||||
|
|
||||||
{:name "constraintsVertical"
|
{:name "proportionLock"
|
||||||
:get #(get-state % :constraints-v d/name)
|
:get #(-> % proxy->shape :proportion-lock boolean)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")]
|
||||||
value (keyword value)]
|
(st/emit! (dwc/update-shapes [id] #(assoc % :proportion-lock value)))))}
|
||||||
(when (contains? cts/vertical-constraint-types value)
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :constraints-v value))))))}
|
|
||||||
|
|
||||||
{:name "borderRadius"
|
{:name "constraintsHorizontal"
|
||||||
:get #(get-state % :rx)
|
:get #(-> % proxy->shape :constraints-h d/name)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")
|
||||||
(when (us/safe-int? value)
|
value (keyword value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :rx value :ry value))))))}
|
(when (contains? cts/horizontal-constraint-types value)
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :constraints-h value))))))}
|
||||||
|
|
||||||
{:name "borderRadiusTopLeft"
|
{:name "constraintsVertical"
|
||||||
:get #(get-state % :r1)
|
:get #(-> % proxy->shape :constraints-v d/name)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")
|
||||||
(when (us/safe-int? value)
|
value (keyword value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :r1 value))))))}
|
(when (contains? cts/vertical-constraint-types value)
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :constraints-v value))))))}
|
||||||
|
|
||||||
{:name "borderRadiusTopRight"
|
{:name "borderRadius"
|
||||||
:get #(get-state % :r2)
|
:get #(-> % proxy->shape :rx)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :r2 value))))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :rx value :ry value))))))}
|
||||||
|
|
||||||
{:name "borderRadiusBottomRight"
|
{:name "borderRadiusTopLeft"
|
||||||
:get #(get-state % :r3)
|
:get #(-> % proxy->shape :r1)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :r3 value))))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :r1 value))))))}
|
||||||
|
|
||||||
{:name "borderRadiusBottomLeft"
|
{:name "borderRadiusTopRight"
|
||||||
:get #(get-state % :r4)
|
:get #(-> % proxy->shape :r2)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (us/safe-int? value)
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :r4 value))))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :r2 value))))))}
|
||||||
|
|
||||||
{:name "opacity"
|
{:name "borderRadiusBottomRight"
|
||||||
:get #(get-state % :opacity)
|
:get #(-> % proxy->shape :r3)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)]
|
(let [id (obj/get self "$id")]
|
||||||
(when (and (us/safe-number? value) (>= value 0) (<= value 1))
|
(when (us/safe-int? value)
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :opacity value))))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :r3 value))))))}
|
||||||
|
|
||||||
{:name "blendMode"
|
{:name "borderRadiusBottomLeft"
|
||||||
:get #(get-state % :blend-mode d/name)
|
:get #(-> % proxy->shape :r4)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")]
|
||||||
value (keyword value)]
|
(when (us/safe-int? value)
|
||||||
(when (contains? cts/blend-modes value)
|
(st/emit! (dwc/update-shapes [id] #(assoc % :r4 value))))))}
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :blend-mode value))))))}
|
|
||||||
|
|
||||||
{:name "shadows"
|
{:name "opacity"
|
||||||
:get #(get-state % :shadow array-to-js)
|
:get #(-> % proxy->shape :opacity)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")]
|
||||||
value (mapv #(utils/from-js %) value)]
|
(when (and (us/safe-number? value) (>= value 0) (<= value 1))
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :shadows value)))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :opacity value))))))}
|
||||||
|
|
||||||
{:name "blur"
|
{:name "blendMode"
|
||||||
:get #(get-state % :blur utils/to-js)
|
:get #(-> % proxy->shape :blend-mode (d/nilv :normal) d/name)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (utils/from-js value)]
|
value (keyword value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :blur value)))))}
|
(when (contains? cts/blend-modes value)
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :blend-mode value))))))}
|
||||||
|
|
||||||
{:name "exports"
|
{:name "shadows"
|
||||||
:get #(get-state % :exports array-to-js)
|
:get #(-> % proxy->shape :shadow array-to-js)
|
||||||
:set (fn [self value]
|
:set (fn [self value]
|
||||||
(let [id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
value (mapv #(utils/from-js %) value)]
|
value (mapv #(utils/from-js %) value)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :exports value)))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :shadows value)))))}
|
||||||
|
|
||||||
;; Geometry properties
|
{:name "blur"
|
||||||
{:name "x"
|
:get #(-> % proxy->shape :blur utils/to-js)
|
||||||
:get #(get-state % :x)
|
:set (fn [self value]
|
||||||
:set
|
(let [id (obj/get self "$id")
|
||||||
(fn [self value]
|
value (utils/from-js value)]
|
||||||
(let [id (get-data self :id)]
|
(st/emit! (dwc/update-shapes [id] #(assoc % :blur value)))))}
|
||||||
(st/emit! (udw/update-position id {:x value}))))}
|
|
||||||
|
|
||||||
{:name "y"
|
{:name "exports"
|
||||||
:get #(get-state % :y)
|
:get #(-> % proxy->shape :exports array-to-js)
|
||||||
:set
|
:set (fn [self value]
|
||||||
(fn [self value]
|
(let [id (obj/get self "$id")
|
||||||
(let [id (get-data self :id)]
|
value (mapv #(utils/from-js %) value)]
|
||||||
(st/emit! (udw/update-position id {:y value}))))}
|
(st/emit! (dwc/update-shapes [id] #(assoc % :exports value)))))}
|
||||||
|
|
||||||
{:name "parentX"
|
;; Geometry properties
|
||||||
:get (fn [self]
|
{:name "x"
|
||||||
(let [page-id (:current-page-id @st/state)
|
:get #(-> % proxy->shape :x)
|
||||||
parent-id (get-state self :parent-id)
|
:set
|
||||||
parent-x (dm/get-in @st/state [:workspace-data :pages-index page-id :objects parent-id :x])]
|
(fn [self value]
|
||||||
(- (get-state self :x) parent-x)))
|
(let [id (obj/get self "$id")]
|
||||||
:set
|
(st/emit! (udw/update-position id {:x value}))))}
|
||||||
(fn [self value]
|
|
||||||
(let [page-id (:current-page-id @st/state)
|
|
||||||
id (get-data self :id)
|
|
||||||
parent-id (get-state self :parent-id)
|
|
||||||
parent-x (dm/get-in @st/state [:workspace-data :pages-index page-id :objects parent-id :x])]
|
|
||||||
(st/emit! (udw/update-position id {:x (+ parent-x value)}))))}
|
|
||||||
|
|
||||||
{:name "parentY"
|
{:name "y"
|
||||||
:get (fn [self]
|
:get #(-> % proxy->shape :y)
|
||||||
(let [page-id (:current-page-id @st/state)
|
:set
|
||||||
parent-id (get-state self :parent-id)
|
(fn [self value]
|
||||||
parent-y (dm/get-in @st/state [:workspace-data :pages-index page-id :objects parent-id :y])]
|
(let [id (obj/get self "$id")]
|
||||||
(- (get-state self :y) parent-y)))
|
(st/emit! (udw/update-position id {:y value}))))}
|
||||||
:set
|
|
||||||
(fn [self value]
|
|
||||||
(let [page-id (:current-page-id @st/state)
|
|
||||||
id (get-data self :id)
|
|
||||||
parent-id (get-state self :parent-id)
|
|
||||||
parent-y (dm/get-in @st/state [:workspace-data :pages-index page-id :objects parent-id :y])]
|
|
||||||
(st/emit! (udw/update-position id {:y (+ parent-y value)}))))}
|
|
||||||
|
|
||||||
{:name "frameX"
|
{:name "parentX"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [shape (proxy->shape self)
|
||||||
frame-id (get-state self :frame-id)
|
parent-id (:parent-id shape)
|
||||||
frame-x (dm/get-in @st/state [:workspace-data :pages-index page-id :objects frame-id :x])]
|
parent (locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)]
|
||||||
(- (get-state self :x) frame-x)))
|
(- (:x shape) (:x parent))))
|
||||||
:set
|
:set
|
||||||
(fn [self value]
|
(fn [self value]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [id (obj/get self "$id")
|
||||||
id (get-data self :id)
|
parent-id (-> self proxy->shape :parent-id)
|
||||||
frame-id (get-state self :frame-id)
|
parent (locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||||
frame-x (dm/get-in @st/state [:workspace-data :pages-index page-id :objects frame-id :x])]
|
parent-x (:x parent)]
|
||||||
(st/emit! (udw/update-position id {:x (+ frame-x value)}))))}
|
(st/emit! (udw/update-position id {:x (+ parent-x value)}))))}
|
||||||
|
|
||||||
{:name "frameY"
|
{:name "parentY"
|
||||||
:get (fn [self]
|
:get (fn [self]
|
||||||
(let [page-id (:current-page-id @st/state)
|
(let [shape (proxy->shape self)
|
||||||
frame-id (get-state self :frame-id)
|
parent-id (:parent-id shape)
|
||||||
frame-y (dm/get-in @st/state [:workspace-data :pages-index page-id :objects frame-id :y])]
|
parent (locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||||
(- (get-state self :y) frame-y)))
|
parent-y (:y parent)]
|
||||||
:set
|
(- (:y shape) parent-y)))
|
||||||
(fn [self value]
|
:set
|
||||||
(let [page-id (:current-page-id @st/state)
|
(fn [self value]
|
||||||
id (get-data self :id)
|
(let [id (obj/get self "$id")
|
||||||
frame-id (get-state self :frame-id)
|
parent-id (-> self proxy->shape :parent-id)
|
||||||
frame-y (dm/get-in @st/state [:workspace-data :pages-index page-id :objects frame-id :y])]
|
parent (locate-shape (obj/get self "$file") (obj/get self "$page") parent-id)
|
||||||
(st/emit! (udw/update-position id {:y (+ frame-y value)}))))}
|
parent-y (:y parent)]
|
||||||
|
(st/emit! (udw/update-position id {:y (+ parent-y value)}))))}
|
||||||
|
|
||||||
{:name "width"
|
{:name "frameX"
|
||||||
:get #(get-state % :width)}
|
:get (fn [self]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
frame-id (:parent-id shape)
|
||||||
|
frame (locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
|
frame-x (:x frame)]
|
||||||
|
(- (:x shape) frame-x)))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
frame-id (-> self proxy->shape :frame-id)
|
||||||
|
frame (locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
|
frame-x (:x frame)]
|
||||||
|
(st/emit! (udw/update-position id {:x (+ frame-x value)}))))}
|
||||||
|
|
||||||
{:name "height"
|
{:name "frameY"
|
||||||
:get #(get-state % :height)}
|
:get (fn [self]
|
||||||
|
(let [shape (proxy->shape self)
|
||||||
|
frame-id (:parent-id shape)
|
||||||
|
frame (locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
|
frame-y (:y frame)]
|
||||||
|
(- (:y shape) frame-y)))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
frame-id (-> self proxy->shape :frame-id)
|
||||||
|
frame (locate-shape (obj/get self "$file") (obj/get self "$page") frame-id)
|
||||||
|
frame-y (:y frame)]
|
||||||
|
(st/emit! (udw/update-position id {:y (+ frame-y value)}))))}
|
||||||
|
|
||||||
{:name "flipX"
|
{:name "width"
|
||||||
:get #(get-state % :flip-x)}
|
:get #(-> % proxy->shape :width)}
|
||||||
|
|
||||||
{:name "flipY"
|
{:name "height"
|
||||||
:get #(get-state % :flip-y)}
|
:get #(-> % proxy->shape :height)}
|
||||||
|
|
||||||
;; Strokes and fills
|
{:name "flipX"
|
||||||
{:name "fills"
|
:get #(-> % proxy->shape :flip-x)}
|
||||||
:get #(get-state % :fills array-to-js)
|
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)
|
|
||||||
value (mapv #(utils/from-js %) value)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :fills value)))))}
|
|
||||||
|
|
||||||
{:name "strokes"
|
{:name "flipY"
|
||||||
:get #(get-state % :strokes array-to-js)
|
:get #(-> % proxy->shape :flip-y)}
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)
|
|
||||||
value (mapv #(utils/from-js %) value)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :strokes value)))))})
|
|
||||||
|
|
||||||
(cond-> (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data))
|
;; Strokes and fills
|
||||||
(crc/add-properties!
|
{:name "fills"
|
||||||
{:name "children"
|
:get #(-> % proxy->shape :fills array-to-js)
|
||||||
:get #(.getChildren ^js %)}))
|
:set (fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (mapv #(utils/from-js %) value)]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :fills value)))))}
|
||||||
|
|
||||||
(cond-> (not (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data)))
|
{:name "strokes"
|
||||||
(-> (obj/unset! "appendChild")
|
:get #(-> % proxy->shape :strokes array-to-js)
|
||||||
(obj/unset! "insertChild")
|
:set (fn [self value]
|
||||||
(obj/unset! "getChildren")))
|
(let [id (obj/get self "$id")
|
||||||
|
value (mapv #(utils/from-js %) value)]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :strokes value)))))})
|
||||||
|
|
||||||
(cond-> (cfh/frame-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!
|
||||||
{:name "grid"
|
{:name "children"
|
||||||
:get
|
:enumerable false
|
||||||
(fn [self]
|
:get #(.getChildren ^js %)}))
|
||||||
(let [layout (get-state self :layout)]
|
|
||||||
(when (= :grid layout)
|
|
||||||
(grid/grid-layout-proxy data))))}
|
|
||||||
|
|
||||||
{:name "guides"
|
(cond-> (not (or (cfh/frame-shape? data) (cfh/group-shape? data) (cfh/svg-raw-shape? data) (cfh/bool-shape? data)))
|
||||||
:get #(get-state % :grids array-to-js)
|
(-> (obj/unset! "appendChild")
|
||||||
:set (fn [self value]
|
(obj/unset! "insertChild")
|
||||||
(let [id (get-data self :id)
|
(obj/unset! "getChildren")))
|
||||||
value (mapv #(utils/from-js %) value)]
|
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :grids value)))))})
|
|
||||||
|
|
||||||
;; TODO: Flex properties
|
(cond-> (cfh/frame-shape? data)
|
||||||
#_(crc/add-properties!
|
(-> (crc/add-properties!
|
||||||
{:name "flex"
|
{:name "grid"
|
||||||
:get
|
:get
|
||||||
(fn [self]
|
(fn [self]
|
||||||
(let [layout (get-state self :layout)]
|
(let [layout (-> self proxy->shape :layout)
|
||||||
(when (= :flex layout)
|
file-id (obj/get self "$file")
|
||||||
(flex-layout-proxy data))))})))
|
page-id (obj/get self "$page")
|
||||||
|
id (obj/get self "$id")]
|
||||||
|
(when (= :grid layout)
|
||||||
|
(grid/grid-layout-proxy file-id page-id id))))}
|
||||||
|
|
||||||
(cond-> (not (cfh/frame-shape? data))
|
{:name "guides"
|
||||||
(-> (obj/unset! "addGridLayout")
|
:get #(-> % proxy->shape :grids array-to-js)
|
||||||
(obj/unset! "addFlexLayout")))
|
:set (fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (mapv #(utils/from-js %) value)]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :grids value)))))})
|
||||||
|
|
||||||
(cond-> (cfh/text-shape? data)
|
;; TODO: Flex properties
|
||||||
(-> (crc/add-properties!
|
#_(crc/add-properties!
|
||||||
{:name "characters"
|
{:name "flex"
|
||||||
:get #(get-state % :content txt/content->text)
|
:get
|
||||||
:set (fn [self value]
|
(fn [self]
|
||||||
(let [id (get-data self :id)]
|
(let [layout (-> self proxy->shape :layout)]
|
||||||
(st/emit! (dwc/update-shapes [id] #(txt/change-text % value)))))})
|
(when (= :flex layout)
|
||||||
|
(flex-layout-proxy (proxy->shape self)))))})))
|
||||||
|
|
||||||
(crc/add-properties!
|
(cond-> (not (cfh/frame-shape? data))
|
||||||
{:name "growType"
|
(-> (obj/unset! "addGridLayout")
|
||||||
:get #(get-state % :grow-type d/name)
|
(obj/unset! "addFlexLayout")))
|
||||||
:set (fn [self value]
|
|
||||||
(let [id (get-data self :id)
|
(cond-> (cfh/text-shape? data)
|
||||||
value (keyword value)]
|
(-> (crc/add-properties!
|
||||||
(when (contains? #{:auto-width :auto-height :fixed} value)
|
{:name "characters"
|
||||||
(st/emit! (dwc/update-shapes [id] #(assoc % :grow-type value))))))})))))
|
:get #(-> % proxy->shape :content txt/content->text)
|
||||||
|
:set (fn [self value]
|
||||||
|
(let [id (obj/get self "$id")]
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(txt/change-text % value)))))})
|
||||||
|
|
||||||
|
(crc/add-properties!
|
||||||
|
{:name "growType"
|
||||||
|
:get #(-> % proxy->shape :grow-type d/name)
|
||||||
|
:set (fn [self value]
|
||||||
|
(let [id (obj/get self "$id")
|
||||||
|
value (keyword value)]
|
||||||
|
(when (contains? #{:auto-width :auto-height :fixed} value)
|
||||||
|
(st/emit! (dwc/update-shapes [id] #(assoc % :grow-type value))))))})))))))
|
||||||
|
|
|
@ -16,6 +16,42 @@
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|
||||||
|
(defn locate-file
|
||||||
|
[id]
|
||||||
|
(assert (uuid? id) "File not valid uuid")
|
||||||
|
(if (= id (:current-file-id @st/state))
|
||||||
|
(-> (:workspace-file @st/state)
|
||||||
|
(assoc :data (:workspace-data @st/state)))
|
||||||
|
(dm/get-in @st/state [:workspace-libraries id])))
|
||||||
|
|
||||||
|
(defn locate-page
|
||||||
|
[file-id id]
|
||||||
|
(assert (uuid? id) "Page not valid uuid")
|
||||||
|
(dm/get-in (locate-file file-id) [:data :pages-index id]))
|
||||||
|
|
||||||
|
(defn locate-shape
|
||||||
|
[file-id page-id id]
|
||||||
|
(assert (uuid? id) "Shape not valid uuid")
|
||||||
|
(dm/get-in (locate-page file-id page-id) [:objects id]))
|
||||||
|
|
||||||
|
(defn proxy->file
|
||||||
|
[proxy]
|
||||||
|
(let [id (obj/get proxy "$id")]
|
||||||
|
(locate-file id)))
|
||||||
|
|
||||||
|
(defn proxy->page
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
id (obj/get proxy "$id")]
|
||||||
|
(locate-page file-id id)))
|
||||||
|
|
||||||
|
(defn proxy->shape
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
page-id (obj/get proxy "$page")
|
||||||
|
id (obj/get proxy "$id")]
|
||||||
|
(locate-shape file-id page-id id)))
|
||||||
|
|
||||||
(defn get-data
|
(defn get-data
|
||||||
([self attr]
|
([self attr]
|
||||||
(-> (obj/get self "_data")
|
(-> (obj/get self "_data")
|
||||||
|
@ -77,6 +113,12 @@
|
||||||
obj)]
|
obj)]
|
||||||
(clj->js result)))
|
(clj->js result)))
|
||||||
|
|
||||||
|
(defn array-to-js
|
||||||
|
[value]
|
||||||
|
(.freeze
|
||||||
|
js/Object
|
||||||
|
(apply array (->> value (map to-js)))))
|
||||||
|
|
||||||
(defn result-p
|
(defn result-p
|
||||||
"Creates a pair of atom+promise. The promise will be resolved when the atom gets a value.
|
"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
|
We use this to return the promise to the library clients and resolve its value when a value is passed
|
||||||
|
|
Loading…
Add table
Reference in a new issue