mirror of
https://github.com/penpot/penpot.git
synced 2025-04-13 07:21:40 -05:00
Merge pull request #4783 from penpot/alotor-plugins-texts
Update plugins
This commit is contained in:
commit
c70d20f95d
21 changed files with 2445 additions and 765 deletions
|
@ -361,7 +361,7 @@
|
|||
|
||||
new-acc
|
||||
(cond
|
||||
(:children node)
|
||||
(not (is-text-node? node))
|
||||
(reduce #(rec-style-text-map %1 %2 node-style) acc (:children node))
|
||||
|
||||
(not= head-style node-style)
|
||||
|
@ -381,6 +381,28 @@
|
|||
(-> (rec-style-text-map [] node {})
|
||||
reverse)))
|
||||
|
||||
(defn content-range->text+styles
|
||||
"Given a root node of a text content extracts the texts with its associated styles"
|
||||
[node start end]
|
||||
(let [sss (content->text+styles node)]
|
||||
(loop [styles (seq sss)
|
||||
taking? false
|
||||
acc 0
|
||||
result []]
|
||||
(if styles
|
||||
(let [[node-style text] (first styles)
|
||||
from acc
|
||||
to (+ acc (count text))
|
||||
taking? (or taking? (and (<= from start) (< start to)))
|
||||
text (subs text (max 0 (- start acc)) (- end acc))
|
||||
result (cond-> result
|
||||
(and taking? (d/not-empty? text))
|
||||
(conj (assoc node-style :text text)))
|
||||
continue? (or (> from end) (>= end to))]
|
||||
(recur (when continue? (rest styles)) taking? to result))
|
||||
result))))
|
||||
|
||||
|
||||
(defn content->text
|
||||
"Given a root node of a text content extracts the texts with its associated styles"
|
||||
[content]
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
(:require
|
||||
[app.common.schema :as sm]))
|
||||
|
||||
(def export-types #{:png :jpeg :svg :pdf})
|
||||
|
||||
(sm/def! ::export
|
||||
[:map {:title "ShapeExport"}
|
||||
[:type :keyword]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -438,28 +438,28 @@
|
|||
;; - It consideres the center for everyshape instead of the center of the total selrect
|
||||
;; - The angle param is the desired final value, not a delta
|
||||
(defn set-delta-rotation-modifiers
|
||||
([angle shapes]
|
||||
(ptk/reify ::set-delta-rotation-modifiers
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
ids
|
||||
(->> shapes
|
||||
(remove #(get % :blocked false))
|
||||
(filter #(contains? (get editable-attrs (:type %)) :rotation))
|
||||
(map :id))
|
||||
[angle shapes {:keys [center delta?] :or {center nil delta? false}}]
|
||||
(ptk/reify ::set-delta-rotation-modifiers
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
ids
|
||||
(->> shapes
|
||||
(remove #(get % :blocked false))
|
||||
(filter #(contains? (get editable-attrs (:type %)) :rotation))
|
||||
(map :id))
|
||||
|
||||
get-modifier
|
||||
(fn [shape]
|
||||
(let [delta (- angle (:rotation shape))
|
||||
center (gsh/shape->center shape)]
|
||||
(ctm/rotation-modifiers shape center delta)))
|
||||
get-modifier
|
||||
(fn [shape]
|
||||
(let [delta (if delta? angle (- angle (:rotation shape)))
|
||||
center (or center (gsh/shape->center shape))]
|
||||
(ctm/rotation-modifiers shape center delta)))
|
||||
|
||||
modif-tree
|
||||
(-> (build-modif-tree ids objects get-modifier)
|
||||
(gm/set-objects-modifiers objects))]
|
||||
modif-tree
|
||||
(-> (build-modif-tree ids objects get-modifier)
|
||||
(gm/set-objects-modifiers objects))]
|
||||
|
||||
(assoc state :workspace-modifiers modif-tree))))))
|
||||
(assoc state :workspace-modifiers modif-tree)))))
|
||||
|
||||
(defn apply-modifiers
|
||||
([]
|
||||
|
|
|
@ -205,6 +205,102 @@
|
|||
|
||||
;; --- TEXT EDITION IMPL
|
||||
|
||||
(defn count-node-chars
|
||||
([node]
|
||||
(count-node-chars node false))
|
||||
([node last?]
|
||||
(case (:type node)
|
||||
("root" "paragraph-set")
|
||||
(apply + (concat (map count-node-chars (drop-last (:children node)))
|
||||
(map #(count-node-chars % true) (take-last 1 (:children node)))))
|
||||
|
||||
"paragraph"
|
||||
(+ (apply + (map count-node-chars (:children node))) (if last? 0 1))
|
||||
|
||||
(count (:text node)))))
|
||||
|
||||
|
||||
(defn decorate-range-info
|
||||
"Adds information about ranges inside the metadata of the text nodes"
|
||||
[content]
|
||||
(->> (with-meta content {:start 0 :end (count-node-chars content)})
|
||||
(txt/transform-nodes
|
||||
(fn [node]
|
||||
(d/update-when
|
||||
node
|
||||
:children
|
||||
(fn [children]
|
||||
(let [start (-> node meta (:start 0))]
|
||||
(->> children
|
||||
(reduce (fn [[result start] node]
|
||||
(let [end (+ start (count-node-chars node))]
|
||||
[(-> result
|
||||
(conj (with-meta node {:start start :end end})))
|
||||
end]))
|
||||
[[] start])
|
||||
(first)))))))))
|
||||
|
||||
(defn split-content-at
|
||||
[content position]
|
||||
(->> content
|
||||
(txt/transform-nodes
|
||||
(fn [node]
|
||||
(and (txt/is-paragraph-node? node)
|
||||
(< (-> node meta :start) position (-> node meta :end))))
|
||||
(fn [node]
|
||||
(letfn
|
||||
[(process-node [child]
|
||||
(let [start (-> child meta :start)
|
||||
end (-> child meta :end)]
|
||||
(if (< start position end)
|
||||
[(-> child
|
||||
(vary-meta assoc :end position)
|
||||
(update :text subs 0 (- position start)))
|
||||
(-> child
|
||||
(vary-meta assoc :start position)
|
||||
(update :text subs (- position start)))]
|
||||
[child])))]
|
||||
(-> node
|
||||
(d/update-when :children #(into [] (mapcat process-node) %))))))))
|
||||
|
||||
(defn update-content-range
|
||||
[content start end attrs]
|
||||
(->> content
|
||||
(txt/transform-nodes
|
||||
(fn [node]
|
||||
(and (txt/is-text-node? node)
|
||||
(and (>= (-> node meta :start) start)
|
||||
(<= (-> node meta :end) end))))
|
||||
#(d/patch-object % attrs))))
|
||||
|
||||
(defn- update-text-range-attrs
|
||||
[shape start end attrs]
|
||||
(let [new-content (-> (:content shape)
|
||||
(decorate-range-info)
|
||||
(split-content-at start)
|
||||
(split-content-at end)
|
||||
(update-content-range start end attrs))]
|
||||
(assoc shape :content new-content)))
|
||||
|
||||
(defn update-text-range
|
||||
[id start end attrs]
|
||||
(ptk/reify ::update-text-range
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
shape (get objects id)
|
||||
|
||||
update-fn
|
||||
(fn [shape]
|
||||
(cond-> shape
|
||||
(cfh/text-shape? shape)
|
||||
(update-text-range-attrs start end attrs)))
|
||||
|
||||
shape-ids (cond (cfh/text-shape? shape) [id]
|
||||
(cfh/group-shape? shape) (cfh/get-children-ids objects id))]
|
||||
|
||||
(rx/of (dwsh/update-shapes shape-ids update-fn))))))
|
||||
|
||||
(defn- update-text-content
|
||||
[shape pred-fn update-fn attrs]
|
||||
(let [update-attrs-fn #(update-fn % attrs)
|
||||
|
@ -278,7 +374,6 @@
|
|||
(cfh/group-shape? shape) (cfh/get-children-ids objects id))]
|
||||
(rx/of (dwsh/update-shapes shape-ids #(update-text-content % update-node? d/txt-merge attrs))))))))
|
||||
|
||||
|
||||
(defn migrate-node
|
||||
[node]
|
||||
(let [color-attrs (select-keys node [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient])]
|
||||
|
|
|
@ -400,17 +400,18 @@
|
|||
|
||||
(defn increase-rotation
|
||||
"Rotate shapes a fixed angle, from a keyboard action."
|
||||
[ids rotation]
|
||||
(ptk/reify ::increase-rotation
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
shapes (->> ids (map #(get objects %)))]
|
||||
(rx/concat
|
||||
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes))
|
||||
(rx/of (dwm/apply-modifiers)))))))
|
||||
([ids rotation]
|
||||
(increase-rotation ids rotation nil))
|
||||
([ids rotation params]
|
||||
(ptk/reify ::increase-rotation
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
shapes (->> ids (map #(get objects %)))]
|
||||
(rx/concat
|
||||
(rx/of (dwm/set-delta-rotation-modifiers rotation shapes params))
|
||||
(rx/of (dwm/apply-modifiers))))))))
|
||||
|
||||
|
||||
;; -- Move ----------------------------------------------------------
|
||||
|
@ -889,26 +890,32 @@
|
|||
|
||||
;; -- Flip ----------------------------------------------------------
|
||||
|
||||
(defn flip-horizontal-selected []
|
||||
(ptk/reify ::flip-horizontal-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/shapes->rect shapes)
|
||||
center (grc/rect->center selrect)
|
||||
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))
|
||||
(defn flip-horizontal-selected
|
||||
([]
|
||||
(flip-horizontal-selected nil))
|
||||
([ids]
|
||||
(ptk/reify ::flip-horizontal-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (or ids (wsh/lookup-selected state {:omit-blocked? true}))
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/shapes->rect shapes)
|
||||
center (grc/rect->center selrect)
|
||||
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))))
|
||||
|
||||
(defn flip-vertical-selected []
|
||||
(ptk/reify ::flip-vertical-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/shapes->rect shapes)
|
||||
center (grc/rect->center selrect)
|
||||
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))
|
||||
(defn flip-vertical-selected
|
||||
([]
|
||||
(flip-vertical-selected nil))
|
||||
([ids]
|
||||
(ptk/reify ::flip-vertical-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
selected (or ids (wsh/lookup-selected state {:omit-blocked? true}))
|
||||
shapes (map #(get objects %) selected)
|
||||
selrect (gsh/shapes->rect shapes)
|
||||
center (grc/rect->center selrect)
|
||||
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))))
|
||||
|
|
|
@ -72,15 +72,18 @@
|
|||
|
||||
(defn open-plugin!
|
||||
[{:keys [plugin-id name description host code icon permissions]}]
|
||||
(.ɵloadPlugin
|
||||
js/window
|
||||
#js {:pluginId plugin-id
|
||||
:name name
|
||||
:description description
|
||||
:host host
|
||||
:code code
|
||||
:icon icon
|
||||
:permissions (apply array permissions)}))
|
||||
(try
|
||||
(.ɵloadPlugin
|
||||
js/window
|
||||
#js {:pluginId plugin-id
|
||||
:name name
|
||||
:description description
|
||||
:host host
|
||||
:code code
|
||||
:icon icon
|
||||
:permissions (apply array permissions)})
|
||||
(catch :default e
|
||||
(.error js/console "Error" e))))
|
||||
|
||||
(mf/defc plugin-management-dialog
|
||||
{::mf/register modal/components
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.main.features :as features]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.api :as api]
|
||||
[app.plugins.public-utils]
|
||||
[app.util.globals :refer [global]]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
|
|
|
@ -21,11 +21,12 @@
|
|||
[app.main.store :as st]
|
||||
[app.plugins.events :as events]
|
||||
[app.plugins.file :as file]
|
||||
[app.plugins.fonts :as fonts]
|
||||
[app.plugins.library :as library]
|
||||
[app.plugins.page :as page]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.user :as user]
|
||||
[app.plugins.utils :as utils]
|
||||
[app.plugins.utils :as u]
|
||||
[app.plugins.viewport :as viewport]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
|
@ -60,7 +61,7 @@
|
|||
|
||||
(getViewport
|
||||
[_]
|
||||
(viewport/create-proxy $plugin))
|
||||
(viewport/viewport-proxy $plugin))
|
||||
|
||||
(getFile
|
||||
[_]
|
||||
|
@ -107,28 +108,50 @@
|
|||
|
||||
(uploadMediaUrl
|
||||
[_ name url]
|
||||
(let [file-id (:current-file-id @st/state)]
|
||||
(p/create
|
||||
(fn [resolve reject]
|
||||
(->> (dwm/upload-media-url name file-id url)
|
||||
(rx/map utils/to-js)
|
||||
(rx/take 1)
|
||||
(rx/subs! resolve reject))))))
|
||||
(cond
|
||||
(not (string? name))
|
||||
(u/display-not-valid :uploadMedia-name name)
|
||||
|
||||
(not (string? url))
|
||||
(u/display-not-valid :uploadMedia-url url)
|
||||
|
||||
:else
|
||||
(let [file-id (:current-file-id @st/state)]
|
||||
(p/create
|
||||
(fn [resolve reject]
|
||||
(->> (dwm/upload-media-url name file-id url)
|
||||
(rx/map u/to-js)
|
||||
(rx/take 1)
|
||||
(rx/subs! resolve reject)))))))
|
||||
|
||||
(group
|
||||
[_ shapes]
|
||||
(let [file-id (:current-file-id @st/state)
|
||||
page-id (:current-page-id @st/state)
|
||||
id (uuid/next)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwg/group-shapes id ids))
|
||||
(shape/shape-proxy $plugin file-id page-id id)))
|
||||
(cond
|
||||
(or (not (array? shapes)) (not (every? shape/shape-proxy? shapes)))
|
||||
(u/display-not-valid :group-shapes shapes)
|
||||
|
||||
:else
|
||||
(let [file-id (:current-file-id @st/state)
|
||||
page-id (:current-page-id @st/state)
|
||||
id (uuid/next)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwg/group-shapes id ids))
|
||||
(shape/shape-proxy $plugin file-id page-id id))))
|
||||
|
||||
(ungroup
|
||||
[_ group & rest]
|
||||
(let [shapes (concat [group] rest)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwg/ungroup-shapes ids))))
|
||||
|
||||
(cond
|
||||
(not (shape/shape-proxy? group))
|
||||
(u/display-not-valid :ungroup group)
|
||||
|
||||
(and (some? rest) (not (every? shape/shape-proxy? rest)))
|
||||
(u/display-not-valid :ungroup rest)
|
||||
|
||||
:else
|
||||
(let [shapes (concat [group] rest)
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (dwg/ungroup-shapes ids)))))
|
||||
|
||||
(createFrame
|
||||
[_]
|
||||
|
@ -160,23 +183,32 @@
|
|||
|
||||
(createText
|
||||
[_ text]
|
||||
(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])
|
||||
shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text text)
|
||||
(assoc :position-data nil))
|
||||
changes
|
||||
(-> (cb/empty-changes)
|
||||
(cb/with-page page)
|
||||
(cb/with-objects (:objects page))
|
||||
(cb/add-object shape))]
|
||||
(st/emit! (ch/commit-changes changes))
|
||||
(shape/shape-proxy $plugin file-id page-id (:id shape))))
|
||||
(cond
|
||||
(or (not (string? text)) (empty? text))
|
||||
(u/display-not-valid :createText text)
|
||||
|
||||
:else
|
||||
(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])
|
||||
shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text text)
|
||||
(assoc :position-data nil))
|
||||
changes
|
||||
(-> (cb/empty-changes)
|
||||
(cb/with-page page)
|
||||
(cb/with-objects (:objects page))
|
||||
(cb/add-object shape))]
|
||||
(st/emit! (ch/commit-changes changes))
|
||||
(shape/shape-proxy $plugin file-id page-id (:id shape)))))
|
||||
|
||||
(createShapeFromSvg
|
||||
[_ svg-string]
|
||||
(when (some? svg-string)
|
||||
(cond
|
||||
(or (not (string? svg-string)) (empty? svg-string))
|
||||
(u/display-not-valid :createShapeFromSvg svg-string)
|
||||
|
||||
:else
|
||||
(let [id (uuid/next)
|
||||
file-id (:current-file-id @st/state)
|
||||
page-id (:current-page-id @st/state)]
|
||||
|
@ -184,15 +216,19 @@
|
|||
(shape/shape-proxy $plugin file-id page-id id))))
|
||||
|
||||
(createBoolean [_ bool-type shapes]
|
||||
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
|
||||
bool-type (keyword bool-type)]
|
||||
(let [bool-type (keyword bool-type)]
|
||||
(cond
|
||||
(not (contains? cts/bool-types bool-type))
|
||||
(u/display-not-valid :createBoolean-boolType bool-type)
|
||||
|
||||
(if (contains? cts/bool-types bool-type)
|
||||
(let [id-ret (atom nil)]
|
||||
(or (not (array? shapes)) (empty? shapes) (not (every? shape/shape-proxy? shapes)))
|
||||
(u/display-not-valid :createBoolean-shapes shapes)
|
||||
|
||||
:else
|
||||
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
|
||||
id-ret (atom nil)]
|
||||
(st/emit! (dwb/create-bool bool-type ids {:id-ret id-ret}))
|
||||
(shape/shape-proxy $plugin @id-ret))
|
||||
|
||||
(utils/display-not-valid :bool-shape bool-type)))))
|
||||
(shape/shape-proxy $plugin @id-ret))))))
|
||||
|
||||
(defn create-context
|
||||
[plugin-id]
|
||||
|
@ -206,4 +242,5 @@
|
|||
{:name "viewport" :get #(.getViewport ^js %)}
|
||||
{:name "currentUser" :get #(.getCurrentUser ^js %)}
|
||||
{:name "activeUsers" :get #(.getActiveUsers ^js %)}
|
||||
{:name "fonts" :get (fn [_] (fonts/fonts-subcontext plugin-id))}
|
||||
{:name "library" :get (fn [_] (library/library-subcontext plugin-id))}))
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
(setPluginData
|
||||
[_ key value]
|
||||
(cond
|
||||
(not (string? key))
|
||||
(or (not (string? key)) (empty? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
|
@ -66,10 +66,10 @@
|
|||
[_ namespace key value]
|
||||
|
||||
(cond
|
||||
(not (string? namespace))
|
||||
(or (not (string? namespace)) (empty? namespace))
|
||||
(u/display-not-valid :file-plugin-data-namespace namespace)
|
||||
|
||||
(not (string? key))
|
||||
(or (not (string? key)) (empty? key))
|
||||
(u/display-not-valid :file-plugin-data-key key)
|
||||
|
||||
(and (some? value) (not (string? value)))
|
||||
|
@ -93,6 +93,9 @@
|
|||
{:name js/Symbol.toStringTag
|
||||
:get (fn [] (str "FileProxy"))})
|
||||
|
||||
(defn file-proxy? [p]
|
||||
(instance? FileProxy p))
|
||||
|
||||
(defn file-proxy
|
||||
[plugin-id id]
|
||||
(crc/add-properties!
|
||||
|
|
|
@ -13,10 +13,13 @@
|
|||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.utils :as utils :refer [proxy->shape]]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; Define in `app.plugins.shape` we do this way to prevent circular dependency
|
||||
(def shape-proxy? nil)
|
||||
|
||||
(deftype FlexLayout [$plugin $file $page $id]
|
||||
Object
|
||||
(remove
|
||||
|
@ -25,9 +28,17 @@
|
|||
|
||||
(appendChild
|
||||
[_ child]
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil nil)
|
||||
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||
(cond
|
||||
(not (shape-proxy? child))
|
||||
(u/display-not-valid :appendChild child)
|
||||
|
||||
:else
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil nil)
|
||||
(ptk/data-event :layout/update {:ids [$id]}))))))
|
||||
|
||||
(defn flex-layout-proxy? [p]
|
||||
(instance? FlexLayout p))
|
||||
|
||||
(defn flex-layout-proxy
|
||||
[plugin-id file-id page-id id]
|
||||
|
@ -39,118 +50,173 @@
|
|||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
||||
{:name "dir"
|
||||
:get #(-> % proxy->shape :layout-flex-dir d/name)
|
||||
:get #(-> % u/proxy->shape :layout-flex-dir d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/flex-direction-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-flex-dir value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/flex-direction-types value))
|
||||
(u/display-not-valid :dir value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-flex-dir value}))))))}
|
||||
|
||||
{:name "alignItems"
|
||||
:get #(-> % proxy->shape :layout-align-items d/name)
|
||||
:get #(-> % u/proxy->shape :layout-align-items d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/align-items-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/align-items-types value))
|
||||
(u/display-not-valid :alignItems value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value}))))))}
|
||||
|
||||
{:name "alignContent"
|
||||
:get #(-> % proxy->shape :layout-align-content d/name)
|
||||
:get #(-> % u/proxy->shape :layout-align-content d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/align-content-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/align-content-types value))
|
||||
(u/display-not-valid :alignContent value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value}))))))}
|
||||
|
||||
{:name "justifyItems"
|
||||
:get #(-> % proxy->shape :layout-justify-items d/name)
|
||||
:get #(-> % u/proxy->shape :layout-justify-items d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/justify-items-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/justify-items-types value))
|
||||
(u/display-not-valid :justifyItems value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value}))))))}
|
||||
|
||||
{:name "justifyContent"
|
||||
:get #(-> % proxy->shape :layout-justify-content d/name)
|
||||
:get #(-> % u/proxy->shape :layout-justify-content d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/justify-content-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/justify-content-types value))
|
||||
(u/display-not-valid :justifyContent value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value}))))))}
|
||||
|
||||
{:name "rowGap"
|
||||
:get #(-> % proxy->shape :layout-gap :row-gap)
|
||||
:get #(-> % u/proxy->shape :layout-gap :row-gap (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :rowGap value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}})))))}
|
||||
|
||||
{:name "columnGap"
|
||||
:get #(-> % proxy->shape :layout-gap :column-gap)
|
||||
:get #(-> % u/proxy->shape :layout-gap :column-gap (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :columnGap value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}})))))}
|
||||
|
||||
{:name "verticalPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p1)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :verticalPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}})))))}
|
||||
|
||||
{:name "horizontalPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p2)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :horizontalPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
||||
|
||||
|
||||
{:name "topPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p1)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :topPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}})))))}
|
||||
|
||||
{:name "rightPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p2)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :rightPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}})))))}
|
||||
|
||||
{:name "bottomPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p3)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p3 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :bottomPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}})))))}
|
||||
|
||||
{:name "leftPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p4)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p4 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :leftPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||
|
||||
|
||||
(deftype LayoutChildProxy [$plugin $file $page $id])
|
||||
|
||||
(defn layout-child-proxy? [p]
|
||||
(instance? LayoutChildProxy p))
|
||||
|
||||
(defn layout-child-proxy
|
||||
[plugin-id file-id page-id id]
|
||||
(-> (LayoutChildProxy. plugin-id file-id page-id id)
|
||||
|
@ -161,124 +227,184 @@
|
|||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
||||
{:name "absolute"
|
||||
:get #(-> % proxy->shape :layout-item-absolute boolean)
|
||||
:get #(-> % u/proxy->shape :layout-item-absolute boolean)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (boolean? value)
|
||||
(cond
|
||||
(not (boolean? value))
|
||||
(u/display-not-valid :absolute value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-item-absolute value})))))}
|
||||
|
||||
{:name "zIndex"
|
||||
:get #(-> % proxy->shape :layout-item-z-index (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-z-index (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(us/safe-int? value)
|
||||
(u/display-not-valid :zIndex value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-z-index value})))))}
|
||||
|
||||
{:name "horizontalSizing"
|
||||
:get #(-> % proxy->shape :layout-item-h-sizing (d/nilv :fix) d/name)
|
||||
:get #(-> % u/proxy->shape :layout-item-h-sizing (d/nilv :fix) d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/item-h-sizing-types value)
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-h-sizing value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/item-h-sizing-types value))
|
||||
(u/display-not-valid :horizontalPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-h-sizing value}))))))}
|
||||
|
||||
{:name "verticalSizing"
|
||||
:get #(-> % proxy->shape :layout-item-v-sizing (d/nilv :fix) d/name)
|
||||
:get #(-> % u/proxy->shape :layout-item-v-sizing (d/nilv :fix) d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/item-v-sizing-types value)
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-v-sizing value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/item-v-sizing-types value))
|
||||
(u/display-not-valid :verticalSizing value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-v-sizing value}))))))}
|
||||
|
||||
{:name "alignSelf"
|
||||
:get #(-> % proxy->shape :layout-item-align-self (d/nilv :auto) d/name)
|
||||
:get #(-> % u/proxy->shape :layout-item-align-self (d/nilv :auto) d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/item-align-self-types value)
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-align-self value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/item-align-self-types value))
|
||||
(u/display-not-valid :alignSelf value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-align-self value}))))))}
|
||||
|
||||
{:name "verticalMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :verticalMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value :m3 value}})))))}
|
||||
|
||||
{:name "horizontalMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :horizontalMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value :m4 value}})))))}
|
||||
|
||||
{:name "topMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :topMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value}})))))}
|
||||
|
||||
{:name "rightMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :rightMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value}})))))}
|
||||
|
||||
{:name "bottomMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m3 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m3 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :bottomMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m3 value}})))))}
|
||||
|
||||
{:name "leftMargin"
|
||||
:get #(-> % proxy->shape :layout-item-margin :m4 (d/nilv 0))
|
||||
:get #(-> % u/proxy->shape :layout-item-margin :m4 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :leftMargin value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m4 value}})))))}
|
||||
|
||||
{:name "maxWidth"
|
||||
:get #(-> % proxy->shape :layout-item-max-w)
|
||||
:get #(-> % u/proxy->shape :layout-item-max-w)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :maxWidth value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-w value})))))}
|
||||
|
||||
{:name "minWidth"
|
||||
:get #(-> % proxy->shape :layout-item-min-w)
|
||||
:get #(-> % u/proxy->shape :layout-item-min-w)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :minWidth value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-w value})))))}
|
||||
|
||||
{:name "maxHeight"
|
||||
:get #(-> % proxy->shape :layout-item-max-h)
|
||||
:get #(-> % u/proxy->shape :layout-item-max-h)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :maxHeight value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-h value})))))}
|
||||
|
||||
{:name "minHeight"
|
||||
:get #(-> % proxy->shape :layout-item-min-h)
|
||||
:get #(-> % u/proxy->shape :layout-item-min-h)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :minHeight value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-h value})))))})))
|
||||
|
|
127
frontend/src/app/plugins/fonts.cljs
Normal file
127
frontend/src/app/plugins/fonts.cljs
Normal file
|
@ -0,0 +1,127 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.plugins.fonts
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.record :as cr]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(deftype PenpotFontVariant [name fontVariantId fontWeight fontStyle])
|
||||
|
||||
(deftype PenpotFont [name fontId fontFamily fontStyle fontVariantId fontWeight variants]
|
||||
Object
|
||||
|
||||
(applyToText [_ text variant]
|
||||
(cond
|
||||
(not (shape/shape-proxy? text))
|
||||
(u/display-not-valid :applyToText text)
|
||||
|
||||
;; TODO: Check variant inside font variants
|
||||
|
||||
:else
|
||||
(let [id (obj/get text "$id")
|
||||
values {:font-id fontId
|
||||
:font-family fontFamily
|
||||
:font-style (d/nilv (obj/get variant "fontStyle") fontStyle)
|
||||
:font-variant-id (d/nilv (obj/get variant "fontVariantId") fontVariantId)
|
||||
:font-weight (d/nilv (obj/get variant "fontWeight") fontWeight)}]
|
||||
(st/emit! (dwt/update-attrs id values)))))
|
||||
|
||||
(applyToRange [_ range variant]
|
||||
(cond
|
||||
(not (shape/text-range? range))
|
||||
(u/display-not-valid :applyToRange range)
|
||||
|
||||
;; TODO: Check variant inside font variants
|
||||
|
||||
:else
|
||||
(let [id (obj/get range "$id")
|
||||
start (obj/get range "start")
|
||||
end (obj/get range "end")
|
||||
values {:font-id fontId
|
||||
:font-family fontFamily
|
||||
:font-style (d/nilv (obj/get variant "fontStyle") fontStyle)
|
||||
:font-variant-id (d/nilv (obj/get variant "fontVariantId") fontVariantId)
|
||||
:font-weight (d/nilv (obj/get variant "fontWeight") fontWeight)}]
|
||||
(st/emit! (dwt/update-text-range id start end values))))))
|
||||
|
||||
(defn font-proxy? [p]
|
||||
(instance? PenpotFont p))
|
||||
|
||||
(defn font-proxy
|
||||
[{:keys [id name variants] :as font}]
|
||||
(when (some? font)
|
||||
(let [default-variant (fonts/get-default-variant font)]
|
||||
(PenpotFont.
|
||||
name
|
||||
id
|
||||
id
|
||||
(:style default-variant)
|
||||
(:id default-variant)
|
||||
(:weight default-variant)
|
||||
(apply
|
||||
array
|
||||
(->> variants
|
||||
(map (fn [{:keys [id name style weight]}]
|
||||
(PenpotFontVariant. name id weight style)))))))))
|
||||
|
||||
(deftype PenpotFontsSubcontext [$plugin]
|
||||
Object
|
||||
(findById
|
||||
[_ id]
|
||||
(cond
|
||||
(not (string? id))
|
||||
(u/display-not-valid :findbyId id)
|
||||
|
||||
:else
|
||||
(font-proxy (d/seek #(str/includes? (str/lower (:id %)) (str/lower id)) (vals @fonts/fontsdb)))))
|
||||
|
||||
(findByName
|
||||
[_ name]
|
||||
(cond
|
||||
(not (string? name))
|
||||
(u/display-not-valid :findByName name)
|
||||
|
||||
:else
|
||||
(font-proxy (d/seek #(str/includes? (str/lower (:name %)) (str/lower name)) (vals @fonts/fontsdb)))))
|
||||
|
||||
(findAllById
|
||||
[_ id]
|
||||
(cond
|
||||
(not (string? id))
|
||||
(u/display-not-valid :findAllById name)
|
||||
|
||||
:else
|
||||
(apply array (->> (vals @fonts/fontsdb)
|
||||
(filter #(str/includes? (str/lower (:id %)) (str/lower id)))
|
||||
(map font-proxy)))))
|
||||
|
||||
(findAllByName
|
||||
[_ name]
|
||||
(cond
|
||||
(not (string? name))
|
||||
(u/display-not-valid :findAllByName name)
|
||||
|
||||
:else
|
||||
(apply array (->> (vals @fonts/fontsdb)
|
||||
(filter #(str/includes? (str/lower (:name %)) (str/lower name)))
|
||||
(map font-proxy))))))
|
||||
|
||||
(defn fonts-subcontext
|
||||
[plugin-id]
|
||||
(cr/add-properties!
|
||||
(PenpotFontsSubcontext. plugin-id)
|
||||
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||
{:name "all" :get
|
||||
(fn [_]
|
||||
(apply array (->> @fonts/fontsdb vals (map font-proxy))))}))
|
|
@ -13,15 +13,18 @@
|
|||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.data.workspace.transforms :as dwt]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.utils :as utils :refer [proxy->shape locate-shape]]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
;; Define in `app.plugins.shape` we do this way to prevent circular dependency
|
||||
(def shape-proxy? nil)
|
||||
|
||||
(defn- make-tracks
|
||||
[tracks]
|
||||
(.freeze
|
||||
js/Object
|
||||
(apply array (->> tracks (map utils/to-js)))))
|
||||
(apply array (->> tracks (map u/to-js)))))
|
||||
|
||||
(deftype GridLayout [$plugin $file $page $id]
|
||||
Object
|
||||
|
@ -29,40 +32,116 @@
|
|||
(addRow
|
||||
[_ type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value}))))
|
||||
(cond
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :addRow-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :fixed type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :addRow-value value)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value})))))
|
||||
|
||||
(addRowAtIndex
|
||||
[_ index type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value} index))))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :addRowAtIndex-index index)
|
||||
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :addRowAtIndex-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :fixed type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :addRowAtIndex-value value)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :row {:type type :value value} index)))))
|
||||
|
||||
(addColumn
|
||||
[_ type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value}))))
|
||||
(cond
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :addColumn-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :lex type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :addColumn-value value)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value})))))
|
||||
|
||||
(addColumnAtIndex
|
||||
[_ index type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value} index))))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :addColumnAtIndex-index index)
|
||||
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :addColumnAtIndex-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :fixed type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :addColumnAtIndex-value value)
|
||||
|
||||
:else
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/add-layout-track #{$id} :column {:type type :value value} index)))))
|
||||
|
||||
(removeRow
|
||||
[_ index]
|
||||
(st/emit! (dwsl/remove-layout-track #{$id} :row index)))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :removeRow index)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/remove-layout-track #{$id} :row index))))
|
||||
|
||||
(removeColumn
|
||||
[_ index]
|
||||
(st/emit! (dwsl/remove-layout-track #{$id} :column index)))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :removeColumn index)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/remove-layout-track #{$id} :column index))))
|
||||
|
||||
(setColumn
|
||||
[_ index type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/change-layout-track #{$id} :column index (d/without-nils {:type type :value value})))))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :setColumn-index index)
|
||||
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :setColumn-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :fixed type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :setColumn-value value)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/change-layout-track #{$id} :column index (d/without-nils {:type type :value value}))))))
|
||||
|
||||
(setRow
|
||||
[_ index type value]
|
||||
(let [type (keyword type)]
|
||||
(st/emit! (dwsl/change-layout-track #{$id} :row index (d/without-nils {:type type :value value})))))
|
||||
(cond
|
||||
(not (us/safe-int? index))
|
||||
(u/display-not-valid :setRow-index index)
|
||||
|
||||
(not (contains? ctl/grid-track-types type))
|
||||
(u/display-not-valid :setRow-type type)
|
||||
|
||||
(and (or (= :percent type) (= :flex type) (= :fixed type))
|
||||
(not (us/safe-number? value)))
|
||||
(u/display-not-valid :setRow-value value)
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/change-layout-track #{$id} :row index (d/without-nils {:type type :value value}))))))
|
||||
|
||||
(remove
|
||||
[_]
|
||||
|
@ -70,9 +149,23 @@
|
|||
|
||||
(appendChild
|
||||
[_ child row column]
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil [row column])
|
||||
(ptk/data-event :layout/update {:ids [$id]})))))
|
||||
(cond
|
||||
(not (shape-proxy? child))
|
||||
(u/display-not-valid :appendChild-child child)
|
||||
|
||||
(or (< row 0) (not (us/safe-int? row)))
|
||||
(u/display-not-valid :appendChild-row row)
|
||||
|
||||
(or (< column 0) (not (us/safe-int? column)))
|
||||
(u/display-not-valid :appendChild-column column)
|
||||
|
||||
:else
|
||||
(let [child-id (obj/get child "$id")]
|
||||
(st/emit! (dwt/move-shapes-to-frame #{child-id} $id nil [row column])
|
||||
(ptk/data-event :layout/update {:ids [$id]}))))))
|
||||
|
||||
(defn grid-layout-proxy? [p]
|
||||
(instance? GridLayout p))
|
||||
|
||||
(defn grid-layout-proxy
|
||||
[plugin-id file-id page-id id]
|
||||
|
@ -82,128 +175,184 @@
|
|||
{:name "$id" :enumerable false :get (constantly id)}
|
||||
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||
|
||||
{:name "dir"
|
||||
:get #(-> % proxy->shape :layout-grid-dir d/name)
|
||||
:get #(-> % u/proxy->shape :layout-grid-dir d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/grid-direction-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-grid-dir value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/grid-direction-types value))
|
||||
(u/display-not-valid :dir value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-grid-dir value}))))))}
|
||||
|
||||
{:name "rows"
|
||||
:get #(-> % proxy->shape :layout-grid-rows make-tracks)}
|
||||
:get #(-> % u/proxy->shape :layout-grid-rows make-tracks)}
|
||||
|
||||
{:name "columns"
|
||||
:get #(-> % proxy->shape :layout-grid-columns make-tracks)}
|
||||
:get #(-> % u/proxy->shape :layout-grid-columns make-tracks)}
|
||||
|
||||
{:name "alignItems"
|
||||
:get #(-> % proxy->shape :layout-align-items d/name)
|
||||
:get #(-> % u/proxy->shape :layout-align-items d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/align-items-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/align-items-types value))
|
||||
(u/display-not-valid :alignItems value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value}))))))}
|
||||
|
||||
{:name "alignContent"
|
||||
:get #(-> % proxy->shape :layout-align-content d/name)
|
||||
:get #(-> % u/proxy->shape :layout-align-content d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/align-content-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/align-content-types value))
|
||||
(u/display-not-valid :alignContent value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value}))))))}
|
||||
|
||||
{:name "justifyItems"
|
||||
:get #(-> % proxy->shape :layout-justify-items d/name)
|
||||
:get #(-> % u/proxy->shape :layout-justify-items d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/justify-items-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/justify-items-types value))
|
||||
(u/display-not-valid :justifyItems value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value}))))))}
|
||||
|
||||
{:name "justifyContent"
|
||||
:get #(-> % proxy->shape :layout-justify-content d/name)
|
||||
:get #(-> % u/proxy->shape :layout-justify-content d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/justify-content-types value)
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
|
||||
(let [value (keyword value)]
|
||||
(cond
|
||||
(not (contains? ctl/justify-content-types value))
|
||||
(u/display-not-valid :justifyContent value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value}))))))}
|
||||
|
||||
{:name "rowGap"
|
||||
:get #(-> % proxy->shape :layout-gap :row-gap)
|
||||
:get #(-> % u/proxy->shape :layout-gap :row-gap (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :rowGap value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}})))))}
|
||||
|
||||
{:name "columnGap"
|
||||
:get #(-> % proxy->shape :layout-gap :column-gap)
|
||||
:get #(-> % u/proxy->shape :layout-gap :column-gap (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :columnGap value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}})))))}
|
||||
|
||||
{:name "verticalPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p1)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :verticalPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}})))))}
|
||||
|
||||
{:name "horizontalPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p2)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :horizontalPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}})))))}
|
||||
|
||||
{:name "topPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p1)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p1 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :topPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}})))))}
|
||||
|
||||
{:name "rightPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p2)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p2 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :rightPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}})))))}
|
||||
|
||||
{:name "bottomPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p3)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p3 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :bottomPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}})))))}
|
||||
|
||||
{:name "leftPadding"
|
||||
:get #(-> % proxy->shape :layout-padding :p4)
|
||||
:get #(-> % u/proxy->shape :layout-padding :p4 (d/nilv 0))
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [id (obj/get self "$id")]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :leftPadding value)
|
||||
|
||||
:else
|
||||
(let [id (obj/get self "$id")]
|
||||
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}})))))})))
|
||||
|
||||
(deftype GridCellProxy [$plugin $file $page $id])
|
||||
|
||||
(defn layout-cell-proxy? [p]
|
||||
(instance? GridCellProxy p))
|
||||
|
||||
(defn layout-cell-proxy
|
||||
[plugin-id file-id page-id id]
|
||||
(letfn [(locate-cell [_]
|
||||
(let [shape (locate-shape file-id page-id id)
|
||||
parent (locate-shape file-id page-id (:parent-id shape))]
|
||||
(let [shape (u/locate-shape file-id page-id id)
|
||||
parent (u/locate-shape file-id page-id (:parent-id shape))]
|
||||
(ctl/get-cell-by-shape-id parent id)))]
|
||||
|
||||
(-> (GridCellProxy. plugin-id file-id page-id id)
|
||||
|
@ -217,73 +366,129 @@
|
|||
:get #(-> % locate-cell :row)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
cell (locate-cell self)]
|
||||
(when (us/safe-int? value)
|
||||
(let [cell (locate-cell self)
|
||||
shape (u/proxy->shape self)]
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :row value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row value})))))}
|
||||
|
||||
{:name "rowSpan"
|
||||
:get #(-> % locate-cell :row-span)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
cell (locate-cell self)]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :rowSpan-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :rowSpan-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row-span value})))))}
|
||||
|
||||
{:name "column"
|
||||
:get #(-> % locate-cell :column)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
cell (locate-cell self)]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :column-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :column-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column value})))))}
|
||||
|
||||
{:name "columnSpan"
|
||||
:get #(-> % locate-cell :column-span)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
cell (locate-cell self)]
|
||||
(when (us/safe-int? value)
|
||||
(cond
|
||||
(not (us/safe-int? value))
|
||||
(u/display-not-valid :columnSpan-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :columnSpan-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column-span value})))))}
|
||||
|
||||
{:name "areaName"
|
||||
:get #(-> % locate-cell :area-name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
cell (locate-cell self)]
|
||||
(when (string? value)
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :areaName-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :areaName-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:area-name value})))))}
|
||||
|
||||
{:name "position"
|
||||
:get #(-> % locate-cell :position d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
cell (locate-cell self)
|
||||
value (keyword value)]
|
||||
(when (contains? ctl/grid-position-types value)
|
||||
(cond
|
||||
(not (contains? ctl/grid-position-types value))
|
||||
(u/display-not-valid :position-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :position-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/change-cells-mode (:parent-id shape) #{(:id cell)} value)))))}
|
||||
|
||||
{:name "alignSelf"
|
||||
:get #(-> % locate-cell :align-self d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
value (keyword value)
|
||||
cell (locate-cell self)]
|
||||
(when (contains? ctl/grid-cell-align-self-types value)
|
||||
(cond
|
||||
(not (contains? ctl/grid-cell-align-self-types value))
|
||||
(u/display-not-valid :alignSelf-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :alignSelf-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:align-self value})))))}
|
||||
|
||||
{:name "justifySelf"
|
||||
:get #(-> % locate-cell :justify-self d/name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [shape (proxy->shape self)
|
||||
(let [shape (u/proxy->shape self)
|
||||
value (keyword value)
|
||||
cell (locate-cell self)]
|
||||
(when (contains? ctl/grid-cell-justify-self-types value)
|
||||
(cond
|
||||
(not (contains? ctl/grid-cell-justify-self-types value))
|
||||
(u/display-not-valid :justifySelf-value value)
|
||||
|
||||
(nil? cell)
|
||||
(u/display-not-valid :justifySelf-cell "cell not found")
|
||||
|
||||
:else
|
||||
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:justify-self value})))))}))))
|
||||
|
|
|
@ -14,13 +14,14 @@
|
|||
[app.common.record :as cr]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.shape :as shapes]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
|
@ -137,6 +138,9 @@
|
|||
(let [color (u/proxy->library-color self)]
|
||||
(apply array (keys (dm/get-in color [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-color-proxy? [p]
|
||||
(instance? LibraryColorProxy p))
|
||||
|
||||
(defn lib-color-proxy
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
|
@ -154,63 +158,81 @@
|
|||
:get #(-> % u/proxy->library-color :name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-color-name value)
|
||||
|
||||
:else
|
||||
(let [color (u/proxy->library-color self)
|
||||
value (dm/str (d/nilv (:path color) "") " / " value)]
|
||||
(st/emit! (dwl/rename-color file-id id value)))
|
||||
(u/display-not-valid :library-color-name value)))}
|
||||
(st/emit! (dwl/rename-color file-id id value)))))}
|
||||
|
||||
{:name "path"
|
||||
:get #(-> % u/proxy->library-color :path)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-color-path value)
|
||||
|
||||
:else
|
||||
(let [color (-> (u/proxy->library-color self)
|
||||
(update :name #(str value " / " %)))]
|
||||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-path value)))}
|
||||
(st/emit! (dwl/update-color color file-id)))))}
|
||||
|
||||
{:name "color"
|
||||
:get #(-> % u/proxy->library-color :color)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value) (cc/valid-hex-color? value))
|
||||
(cond
|
||||
(or (not (string? value)) (not (cc/valid-hex-color? value)))
|
||||
(u/display-not-valid :library-color-color value)
|
||||
|
||||
:else
|
||||
(let [color (-> (u/proxy->library-color self)
|
||||
(assoc :color value))]
|
||||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-color value)))}
|
||||
(st/emit! (dwl/update-color color file-id)))))}
|
||||
|
||||
{:name "opacity"
|
||||
:get #(-> % u/proxy->library-color :opacity)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (number? value) (>= value 0) (<= value 1))
|
||||
(cond
|
||||
(or (not (number? value)) (< value 0) (> value 1))
|
||||
(u/display-not-valid :library-color-opacity value)
|
||||
|
||||
:else
|
||||
(let [color (-> (u/proxy->library-color self)
|
||||
(assoc :opacity value))]
|
||||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-opacity value)))}
|
||||
(st/emit! (dwl/update-color color file-id)))))}
|
||||
|
||||
{:name "gradient"
|
||||
:get #(-> % u/proxy->library-color :gradient u/to-js)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [value (u/from-js value)]
|
||||
(if (sm/fast-check! ::ctc/gradient value)
|
||||
(cond
|
||||
(not (sm/validate ::ctc/gradient value))
|
||||
(u/display-not-valid :library-color-gradient value)
|
||||
|
||||
:else
|
||||
(let [color (-> (u/proxy->library-color self)
|
||||
(assoc :gradient value))]
|
||||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-gradient value))))}
|
||||
(st/emit! (dwl/update-color color file-id))))))}
|
||||
|
||||
{:name "image"
|
||||
:get #(-> % u/proxy->library-color :image u/to-js)
|
||||
:set
|
||||
(fn [self value]
|
||||
(let [value (u/from-js value)]
|
||||
(if (sm/fast-check! ::ctc/image-color value)
|
||||
(cond
|
||||
(not (sm/validate ::ctc/image-color value))
|
||||
(u/display-not-valid :library-color-image value)
|
||||
|
||||
:else
|
||||
(let [color (-> (u/proxy->library-color self)
|
||||
(assoc :image value))]
|
||||
(st/emit! (dwl/update-color color file-id)))
|
||||
(u/display-not-valid :library-color-image value))))}))
|
||||
(st/emit! (dwl/update-color color file-id))))))}))
|
||||
|
||||
(deftype LibraryTypographyProxy [$plugin $file $id]
|
||||
Object
|
||||
|
@ -228,14 +250,31 @@
|
|||
|
||||
(applyToText
|
||||
[_ shape]
|
||||
(let [shape-id (obj/get shape "$id")
|
||||
typography (u/locate-library-typography $file $id)]
|
||||
(st/emit! (dwt/apply-typography #{shape-id} typography $file))))
|
||||
(cond
|
||||
(not (shape/shape-proxy? shape))
|
||||
(u/display-not-valid :applyToText shape)
|
||||
|
||||
:else
|
||||
(let [shape-id (obj/get shape "$id")
|
||||
typography (u/locate-library-typography $file $id)]
|
||||
(st/emit! (dwt/apply-typography #{shape-id} typography $file)))))
|
||||
|
||||
(applyToTextRange
|
||||
[_ _shape _from _to]
|
||||
;; TODO
|
||||
)
|
||||
[self range]
|
||||
(cond
|
||||
(not (shape/text-range? range))
|
||||
(u/display-not-valid :applyToText range)
|
||||
|
||||
:else
|
||||
(let [shape-id (obj/get range "$id")
|
||||
start (obj/get range "start")
|
||||
end (obj/get range "end")
|
||||
typography (u/proxy->library-typography self)
|
||||
attrs (-> typography
|
||||
(assoc :typography-ref-file $file)
|
||||
(assoc :typography-ref-id (:id typography))
|
||||
(dissoc :id :name))]
|
||||
(st/emit! (dwt/update-text-range shape-id start end attrs)))))
|
||||
|
||||
;; PLUGIN DATA
|
||||
(getPluginData
|
||||
|
@ -309,6 +348,11 @@
|
|||
(let [typography (u/proxy->library-typography self)]
|
||||
(apply array (keys (dm/get-in typography [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-typography-proxy? [p]
|
||||
(instance? LibraryTypographyProxy p))
|
||||
|
||||
(set! shape/lib-typography-proxy? lib-typography-proxy?)
|
||||
|
||||
(defn lib-typography-proxy
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
|
@ -325,111 +369,144 @@
|
|||
:get #(-> % u/proxy->library-typography :name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-name value)
|
||||
|
||||
:else
|
||||
(let [typo (u/proxy->library-typography self)
|
||||
value (dm/str (d/nilv (:path typo) "") " / " value)]
|
||||
(st/emit! (dwl/rename-typography file-id id value)))
|
||||
(u/display-not-valid :library-typography-name value)))}
|
||||
(st/emit! (dwl/rename-typography file-id id value)))))}
|
||||
|
||||
{:name "path"
|
||||
:get #(-> % u/proxy->library-typography :path)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-path value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(update :name #(str value " / " %)))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-path value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontId"
|
||||
:get #(-> % u/proxy->library-typography :font-id)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-id value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-id value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-id value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontFamily"
|
||||
:get #(-> % u/proxy->library-typography :font-family)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-family value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-family value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-family value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontVariantId"
|
||||
:get #(-> % u/proxy->library-typography :font-variant-id)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-variant-id value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-variant-id value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-variant-id value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontSize"
|
||||
:get #(-> % u/proxy->library-typography :font-size)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-size value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-size value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-size value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontWeight"
|
||||
:get #(-> % u/proxy->library-typography :font-weight)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-weight value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-weight value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-weight value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "fontStyle"
|
||||
:get #(-> % u/proxy->library-typography :font-style)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-style value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-style value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-style value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "lineHeight"
|
||||
:get #(-> % u/proxy->library-typography :font-height)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-font-height value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :font-height value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-font-height value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "letterSpacing"
|
||||
:get #(-> % u/proxy->library-typography :letter-spacing)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-letter-spacing value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :letter-spacing value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-letter-spacing value)))}
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}
|
||||
|
||||
{:name "textTransform"
|
||||
:get #(-> % u/proxy->library-typography :text-transform)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-typography-text-transform value)
|
||||
|
||||
:else
|
||||
(let [typo (-> (u/proxy->library-typography self)
|
||||
(assoc :text-transform value))]
|
||||
(st/emit! (dwl/update-typography typo file-id)))
|
||||
(u/display-not-valid :library-typography-text-transform value)))}))
|
||||
(st/emit! (dwl/update-typography typo file-id)))))}))
|
||||
|
||||
(deftype LibraryComponentProxy [$plugin $file $id]
|
||||
Object
|
||||
|
@ -442,7 +519,7 @@
|
|||
[_]
|
||||
(let [id-ref (atom nil)]
|
||||
(st/emit! (dwl/instantiate-component $file $id (gpt/point 0 0) {:id-ref id-ref}))
|
||||
(shapes/shape-proxy $plugin @id-ref)))
|
||||
(shape/shape-proxy $plugin @id-ref)))
|
||||
|
||||
(getPluginData
|
||||
[self key]
|
||||
|
@ -515,6 +592,9 @@
|
|||
(let [component (u/proxy->library-component self)]
|
||||
(apply array (keys (dm/get-in component [:plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn lib-component-proxy? [p]
|
||||
(instance? LibraryComponentProxy p))
|
||||
|
||||
(defn lib-component-proxy
|
||||
[plugin-id file-id id]
|
||||
(assert (uuid? file-id))
|
||||
|
@ -531,21 +611,39 @@
|
|||
:get #(-> % u/proxy->library-component :name)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-component-name value)
|
||||
|
||||
:else
|
||||
(let [component (u/proxy->library-component self)
|
||||
value (dm/str (d/nilv (:path component) "") " / " value)]
|
||||
(st/emit! (dwl/rename-component id value)))
|
||||
(u/display-not-valid :library-component-name value)))}
|
||||
(st/emit! (dwl/rename-component id value)))))}
|
||||
|
||||
{:name "path"
|
||||
:get #(-> % u/proxy->library-component :path)
|
||||
:set
|
||||
(fn [self value]
|
||||
(if (and (some? value) (string? value))
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :library-component-path value)
|
||||
|
||||
:else
|
||||
(let [component (u/proxy->library-component self)
|
||||
value (dm/str value " / " (:name component))]
|
||||
(st/emit! (dwl/rename-component id value)))
|
||||
(u/display-not-valid :library-component-path value)))}))
|
||||
(st/emit! (dwl/rename-component id value)))))}
|
||||
|
||||
{:name "mainInstance"
|
||||
:get
|
||||
(fn [self]
|
||||
(let [file-id (obj/get self "$file")
|
||||
file (u/locate-file file-id)
|
||||
component (u/proxy->library-component self)
|
||||
root (ctf/get-component-root (:data file) component)]
|
||||
(when (some? root)
|
||||
(shape/shape-proxy plugin-id file-id (:main-instance-page component) (:id root)))))}))
|
||||
|
||||
(set! shape/lib-component-proxy lib-component-proxy)
|
||||
|
||||
(deftype Library [$plugin $id]
|
||||
Object
|
||||
|
@ -636,6 +734,9 @@
|
|||
(let [file (u/proxy->file self)]
|
||||
(apply array (keys (dm/get-in file [:data :plugin-data (keyword "shared" namespace)])))))))
|
||||
|
||||
(defn library-proxy? [p]
|
||||
(instance? Library p))
|
||||
|
||||
(defn library-proxy
|
||||
[plugin-id file-id]
|
||||
(assert (uuid? file-id) "File id not valid")
|
||||
|
|
|
@ -21,8 +21,13 @@
|
|||
Object
|
||||
(getShapeById
|
||||
[_ shape-id]
|
||||
(let [shape-id (uuid/uuid shape-id)]
|
||||
(shape/shape-proxy $plugin $file $id shape-id)))
|
||||
(cond
|
||||
(not (string? shape-id))
|
||||
(u/display-not-valid :getShapeById shape-id)
|
||||
|
||||
:else
|
||||
(let [shape-id (uuid/uuid shape-id)]
|
||||
(shape/shape-proxy $plugin $file $id shape-id))))
|
||||
|
||||
(getRoot
|
||||
[_]
|
||||
|
@ -107,6 +112,9 @@
|
|||
{:name js/Symbol.toStringTag
|
||||
:get (fn [] (str "PageProxy"))})
|
||||
|
||||
(defn page-proxy? [p]
|
||||
(instance? PageProxy p))
|
||||
|
||||
(defn page-proxy
|
||||
[plugin-id file-id id]
|
||||
(crc/add-properties!
|
||||
|
@ -122,9 +130,12 @@
|
|||
:get #(-> % u/proxy->page :name)
|
||||
:set
|
||||
(fn [_ value]
|
||||
(if (string? value)
|
||||
(st/emit! (dw/rename-page id value))
|
||||
(u/display-not-valid :page-name value)))}
|
||||
(cond
|
||||
(not (string? value))
|
||||
(u/display-not-valid :page-name value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/rename-page id value))))}
|
||||
|
||||
{:name "root"
|
||||
:enumerable false
|
||||
|
@ -135,6 +146,9 @@
|
|||
:get #(or (-> % u/proxy->page :options :background) cc/canvas)
|
||||
:set
|
||||
(fn [_ value]
|
||||
(if (and (some? value) (string? value) (cc/valid-hex-color? value))
|
||||
(st/emit! (dw/change-canvas-color id {:color value}))
|
||||
(u/display-not-valid :page-background-color value)))}))
|
||||
(cond
|
||||
(or (not (string? value)) (not (cc/valid-hex-color? value)))
|
||||
(u/display-not-valid :page-background-color value)
|
||||
|
||||
:else
|
||||
(st/emit! (dw/change-canvas-color id {:color value}))))}))
|
||||
|
|
25
frontend/src/app/plugins/public_utils.cljs
Normal file
25
frontend/src/app/plugins/public_utils.cljs
Normal file
|
@ -0,0 +1,25 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.plugins.public-utils
|
||||
"Utilities that will be exposed to plugins developers"
|
||||
(:require
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.utils :as u]))
|
||||
|
||||
(defn ^:export centerShapes
|
||||
[shapes]
|
||||
(cond
|
||||
(not (every? shape/shape-proxy? shapes))
|
||||
(u/display-not-valid :centerShapes shapes)
|
||||
|
||||
:else
|
||||
(let [shapes (->> shapes (map u/proxy->shape))]
|
||||
(-> (gsh/shapes->rect shapes)
|
||||
(grc/rect->center)
|
||||
(u/to-js)))))
|
File diff suppressed because it is too large
Load diff
|
@ -38,11 +38,17 @@
|
|||
{:name "sessionId"
|
||||
:get (fn [_] (str session-id))})))
|
||||
|
||||
(defn current-user-proxy? [p]
|
||||
(instance? CurrentUserProxy p))
|
||||
|
||||
(defn current-user-proxy
|
||||
[plugin-id session-id]
|
||||
(-> (CurrentUserProxy. plugin-id session-id)
|
||||
(add-user-properties)))
|
||||
|
||||
(defn active-user-proxy? [p]
|
||||
(instance? ActiveUserProxy p))
|
||||
|
||||
(defn active-user-proxy
|
||||
[plugin-id session-id]
|
||||
(-> (ActiveUserProxy. plugin-id session-id)
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.store :as st]
|
||||
[app.util.object :as obj]
|
||||
|
@ -62,6 +64,14 @@
|
|||
(let [{:keys [profile-id]} (locate-presence session-id)]
|
||||
(dm/get-in @st/state [:users profile-id])))
|
||||
|
||||
(defn locate-component
|
||||
[objects shape]
|
||||
(let [current-file-id (:current-file-id @st/state)
|
||||
workspace-data (:workspace-data @st/state)
|
||||
workspace-libraries (:workspace-libraries @st/state)
|
||||
root (ctn/get-instance-root objects shape)]
|
||||
[root (ctf/resolve-component root {:id current-file-id :data workspace-data} workspace-libraries {:include-deleted? true})]))
|
||||
|
||||
(defn proxy->file
|
||||
[proxy]
|
||||
(let [id (obj/get proxy "$id")]
|
||||
|
@ -177,9 +187,11 @@
|
|||
|
||||
(defn array-to-js
|
||||
[value]
|
||||
(.freeze
|
||||
js/Object
|
||||
(apply array (->> value (map to-js)))))
|
||||
(if (coll? value)
|
||||
(.freeze
|
||||
js/Object
|
||||
(apply array (->> value (map to-js))))
|
||||
value))
|
||||
|
||||
(defn result-p
|
||||
"Creates a pair of atom+promise. The promise will be resolved when the atom gets a value.
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
[app.main.data.workspace.viewport :as dwv]
|
||||
[app.main.data.workspace.zoom :as dwz]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(deftype ViewportProxy [$plugin]
|
||||
|
@ -32,7 +33,10 @@
|
|||
{:name js/Symbol.toStringTag
|
||||
:get (fn [] (str "ViewportProxy"))})
|
||||
|
||||
(defn create-proxy
|
||||
(defn viewport-proxy? [p]
|
||||
(instance? ViewportProxy p))
|
||||
|
||||
(defn viewport-proxy
|
||||
[plugin-id]
|
||||
(crc/add-properties!
|
||||
(ViewportProxy. plugin-id)
|
||||
|
@ -48,7 +52,14 @@
|
|||
(fn [_ value]
|
||||
(let [new-x (obj/get value "x")
|
||||
new-y (obj/get value "y")]
|
||||
(when (and (us/safe-number? new-x) (us/safe-number? new-y))
|
||||
(cond
|
||||
(not (us/safe-number? new-x))
|
||||
(u/display-not-valid :center-x new-x)
|
||||
|
||||
(not (us/safe-number? new-y))
|
||||
(u/display-not-valid :center-y new-y)
|
||||
|
||||
:else
|
||||
(let [vb (dm/get-in @st/state [:workspace-local :vbox])
|
||||
old-x (+ (:x vb) (/ (:width vb) 2))
|
||||
old-y (+ (:y vb) (/ (:height vb) 2))
|
||||
|
@ -65,7 +76,11 @@
|
|||
(dm/get-in @st/state [:workspace-local :zoom]))
|
||||
:set
|
||||
(fn [_ value]
|
||||
(when (us/safe-number? value)
|
||||
(cond
|
||||
(not (us/safe-number? value))
|
||||
(u/display-not-valid :zoom value)
|
||||
|
||||
:else
|
||||
(let [z (dm/get-in @st/state [:workspace-local :zoom])]
|
||||
(st/emit! (dwz/set-zoom (/ value z))))))}
|
||||
|
||||
|
|
260
frontend/test/frontend_tests/plugins/context_shapes_test.cljs
Normal file
260
frontend/test/frontend_tests/plugins/context_shapes_test.cljs
Normal file
|
@ -0,0 +1,260 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns frontend-tests.plugins.context-shapes-test
|
||||
(:require
|
||||
[app.common.math :as m]
|
||||
[app.common.test-helpers.files :as cthf]
|
||||
[app.common.test-helpers.ids-map :as cthi]
|
||||
[app.common.test-helpers.shapes :as cths]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.api :as api]
|
||||
[cljs.test :as t :include-macros true]
|
||||
[frontend-tests.helpers.state :as ths]))
|
||||
|
||||
(t/deftest test-common-shape-properties
|
||||
(let [;; ==== Setup
|
||||
store
|
||||
(ths/setup-store (cthf/sample-file :file1 :page-label :page1))
|
||||
|
||||
_ (set! st/state store)
|
||||
|
||||
context (api/create-context "tests")
|
||||
|
||||
page (. context -currentPage)
|
||||
|
||||
shape (.createRectangle context)
|
||||
|
||||
get-shape-path
|
||||
#(vector :workspace-data :pages-index (aget page "$id") :objects (aget shape "$id") %)]
|
||||
|
||||
(t/testing "Basic shape properites"
|
||||
(t/testing " - name"
|
||||
(set! (.-name shape) "TEST")
|
||||
(t/is (= (.-name shape) "TEST"))
|
||||
(t/is (= (get-in @store (get-shape-path :name)) "TEST")))
|
||||
|
||||
(t/testing " - x"
|
||||
(set! (.-x shape) 10)
|
||||
(t/is (= (.-x shape) 10))
|
||||
(t/is (= (get-in @store (get-shape-path :x)) 10))
|
||||
|
||||
(set! (.-x shape) "fail")
|
||||
(t/is (= (.-x shape) 10))
|
||||
(t/is (= (get-in @store (get-shape-path :x)) 10)))
|
||||
|
||||
(t/testing " - y"
|
||||
(set! (.-y shape) 50)
|
||||
(t/is (= (.-y shape) 50))
|
||||
(t/is (= (get-in @store (get-shape-path :y)) 50))
|
||||
|
||||
(set! (.-y shape) "fail")
|
||||
(t/is (= (.-y shape) 50))
|
||||
(t/is (= (get-in @store (get-shape-path :y)) 50)))
|
||||
|
||||
(t/testing " - resize"
|
||||
(.resize shape 250 300)
|
||||
(t/is (= (.-width shape) 250))
|
||||
(t/is (= (.-height shape) 300))
|
||||
(t/is (= (get-in @store (get-shape-path :width)) 250))
|
||||
(t/is (= (get-in @store (get-shape-path :height)) 300))
|
||||
|
||||
(.resize shape 0 0)
|
||||
(t/is (= (.-width shape) 250))
|
||||
(t/is (= (.-height shape) 300))
|
||||
(t/is (= (get-in @store (get-shape-path :width)) 250))
|
||||
(t/is (= (get-in @store (get-shape-path :height)) 300)))
|
||||
|
||||
(t/testing " - blocked"
|
||||
(set! (.-blocked shape) true)
|
||||
(t/is (= (.-blocked shape) true))
|
||||
(t/is (= (get-in @store (get-shape-path :blocked)) true))
|
||||
|
||||
(set! (.-blocked shape) false)
|
||||
(t/is (= (.-blocked shape) false))
|
||||
(t/is (= (get-in @store (get-shape-path :blocked)) false)))
|
||||
|
||||
(t/testing " - hidden"
|
||||
(set! (.-hidden shape) true)
|
||||
(t/is (= (.-hidden shape) true))
|
||||
(t/is (= (get-in @store (get-shape-path :hidden)) true))
|
||||
|
||||
(set! (.-hidden shape) false)
|
||||
(t/is (= (.-hidden shape) false))
|
||||
(t/is (= (get-in @store (get-shape-path :hidden)) false)))
|
||||
|
||||
(t/testing " - proportionLock"
|
||||
(set! (.-proportionLock shape) true)
|
||||
(t/is (= (.-proportionLock shape) true))
|
||||
(t/is (= (get-in @store (get-shape-path :proportion-lock)) true)))
|
||||
|
||||
(t/testing " - constraintsHorizontal"
|
||||
(set! (.-constraintsHorizontal shape) "fail")
|
||||
(t/is (not= (.-constraintsHorizontal shape) "fail"))
|
||||
(t/is (not= (get-in @store (get-shape-path :constraints-h)) "fail"))
|
||||
|
||||
(set! (.-constraintsHorizontal shape) "right")
|
||||
(t/is (= (.-constraintsHorizontal shape) "right"))
|
||||
(t/is (= (get-in @store (get-shape-path :constraints-h)) :right)))
|
||||
|
||||
(t/testing " - constraintsVertical"
|
||||
(set! (.-constraintsVertical shape) "fail")
|
||||
(t/is (not= (.-constraintsVertical shape) "fail"))
|
||||
(t/is (not= (get-in @store (get-shape-path :constraints-v)) "fail"))
|
||||
|
||||
(set! (.-constraintsVertical shape) "bottom")
|
||||
(t/is (= (.-constraintsVertical shape) "bottom"))
|
||||
(t/is (= (get-in @store (get-shape-path :constraints-v)) :bottom)))
|
||||
|
||||
(t/testing " - borderRadius"
|
||||
(set! (.-borderRadius shape) 10)
|
||||
(t/is (= (.-borderRadius shape) 10))
|
||||
(t/is (= (get-in @store (get-shape-path :rx)) 10))
|
||||
|
||||
(set! (.-borderRadiusTopLeft shape) 20)
|
||||
(t/is (= (.-borderRadiusTopLeft shape) 20))
|
||||
(t/is (= (get-in @store (get-shape-path :rx)) nil))
|
||||
(t/is (= (get-in @store (get-shape-path :r1)) 20))
|
||||
(t/is (= (get-in @store (get-shape-path :r2)) 10))
|
||||
(t/is (= (get-in @store (get-shape-path :r3)) 10))
|
||||
(t/is (= (get-in @store (get-shape-path :r4)) 10))
|
||||
|
||||
(set! (.-borderRadiusTopRight shape) 30)
|
||||
(set! (.-borderRadiusBottomRight shape) 40)
|
||||
(set! (.-borderRadiusBottomLeft shape) 50)
|
||||
(t/is (= (.-borderRadiusTopRight shape) 30))
|
||||
(t/is (= (.-borderRadiusBottomRight shape) 40))
|
||||
(t/is (= (.-borderRadiusBottomLeft shape) 50))
|
||||
|
||||
(t/is (= (get-in @store (get-shape-path :rx)) nil))
|
||||
(t/is (= (get-in @store (get-shape-path :r1)) 20))
|
||||
(t/is (= (get-in @store (get-shape-path :r2)) 30))
|
||||
(t/is (= (get-in @store (get-shape-path :r3)) 40))
|
||||
(t/is (= (get-in @store (get-shape-path :r4)) 50)))
|
||||
|
||||
(t/testing " - opacity"
|
||||
(set! (.-opacity shape) 0.5)
|
||||
(t/is (= (.-opacity shape) 0.5))
|
||||
(t/is (= (get-in @store (get-shape-path :opacity)) 0.5)))
|
||||
|
||||
(t/testing " - blendMode"
|
||||
(set! (.-blendMode shape) "multiply")
|
||||
(t/is (= (.-blendMode shape) "multiply"))
|
||||
(t/is (= (get-in @store (get-shape-path :blend-mode)) :multiply))
|
||||
|
||||
(set! (.-blendMode shape) "fail")
|
||||
(t/is (= (.-blendMode shape) "multiply"))
|
||||
(t/is (= (get-in @store (get-shape-path :blend-mode)) :multiply)))
|
||||
|
||||
(t/testing " - shadows"
|
||||
(let [shadow #js {:style "drop-shadow"
|
||||
:color #js {:color "#FABADA" :opacity 1}}]
|
||||
(set! (.-shadows shape) #js [shadow])
|
||||
(let [shadow-id (uuid/uuid (aget (aget (aget shape "shadows") 0) "id"))]
|
||||
(t/is (= (-> (. shape -shadows) (aget 0) (aget "style")) "drop-shadow"))
|
||||
(t/is (= (get-in @store (get-shape-path :shadow)) [{:id shadow-id
|
||||
:style :drop-shadow
|
||||
:offset-x 4
|
||||
:offset-y 4
|
||||
:blur 4
|
||||
:spread 0
|
||||
:color {:color "#FABADA" :opacity 1}
|
||||
:hidden false}]))))
|
||||
|
||||
(let [shadow #js {:style "fail"}]
|
||||
(set! (.-shadows shape) #js [shadow])
|
||||
(t/is (= (-> (. shape -shadows) (aget 0) (aget "style")) "drop-shadow"))))
|
||||
|
||||
(t/testing " - blur"
|
||||
(set! (.-blur shape) #js {:value 10})
|
||||
(t/is (= (-> (. shape -blur) (aget "type")) "layer-blur"))
|
||||
(t/is (= (-> (. shape -blur) (aget "value")) 10))
|
||||
(t/is (= (-> (. shape -blur) (aget "hidden")) false))
|
||||
(let [id (-> (. shape -blur) (aget "id") uuid/uuid)]
|
||||
(t/is (= (get-in @store (get-shape-path :blur)) {:id id :type :layer-blur :value 10 :hidden false}))))
|
||||
|
||||
(t/testing " - exports"
|
||||
(set! (.-exports shape) #js [#js {:type "pdf" :scale 2 :suffix "test"}])
|
||||
(t/is (= (-> (. shape -exports) (aget 0) (aget "type")) "pdf"))
|
||||
(t/is (= (-> (. shape -exports) (aget 0) (aget "scale")) 2))
|
||||
(t/is (= (-> (. shape -exports) (aget 0) (aget "suffix")) "test"))
|
||||
(t/is (= (get-in @store (get-shape-path :exports)) [{:type :pdf :scale 2 :suffix "test"}]))
|
||||
|
||||
(set! (.-exports shape) #js [#js {:type 10 :scale 2 :suffix "test"}])
|
||||
(t/is (= (get-in @store (get-shape-path :exports)) [{:type :pdf :scale 2 :suffix "test"}])))
|
||||
|
||||
(t/testing " - flipX"
|
||||
(set! (.-flipX shape) true)
|
||||
(t/is (= (.-flipX shape) true))
|
||||
(t/is (= (get-in @store (get-shape-path :flip-x)) true)))
|
||||
|
||||
(t/testing " - flipY"
|
||||
(set! (.-flipY shape) true)
|
||||
(t/is (= (.-flipY shape) true))
|
||||
(t/is (= (get-in @store (get-shape-path :flip-y)) true)))
|
||||
|
||||
(t/testing " - rotation"
|
||||
(set! (.-rotation shape) 45)
|
||||
(t/is (= (.-rotation shape) 45))
|
||||
(t/is (= (get-in @store (get-shape-path :rotation)) 45))
|
||||
|
||||
(set! (.-rotation shape) 0)
|
||||
(t/is (= (.-rotation shape) 0))
|
||||
(t/is (= (get-in @store (get-shape-path :rotation)) 0)))
|
||||
|
||||
(t/testing " - fills"
|
||||
(set! (.-fills shape) #js [#js {:fillColor 100}])
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "fillColor")) "#B1B2B5"))
|
||||
(t/is (= (get-in @store (get-shape-path :fills)) [{:fill-color "#B1B2B5" :fill-opacity 1}]))
|
||||
|
||||
(set! (.-fills shape) #js [#js {:fillColor "#FABADA" :fillOpacity 1}])
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "fillColor")) "#FABADA"))
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "fillOpacity")) 1))
|
||||
(t/is (= (get-in @store (get-shape-path :fills)) [{:fill-color "#FABADA" :fill-opacity 1}])))
|
||||
|
||||
(t/testing " - strokes"
|
||||
(set! (.-fills shape) #js [#js {:strokeColor "#FABADA" :strokeOpacity 1 :stroke-width 5}])
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "strokeColor")) "#FABADA"))
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "strokeOpacity")) 1))
|
||||
(t/is (= (-> (. shape -fills) (aget 0) (aget "strokeWidth")) 5))
|
||||
(t/is (= (get-in @store (get-shape-path :fills)) [{:stroke-color "#FABADA" :stroke-opacity 1 :stroke-width 5}]))))
|
||||
|
||||
(t/testing "Relative properties"
|
||||
(let [frame (.createFrame context)]
|
||||
(set! (.-x frame) 100)
|
||||
(set! (.-y frame) 200)
|
||||
(t/is (= (.-x frame) 100))
|
||||
(t/is (= (.-y frame) 200))
|
||||
(.appendChild frame shape)
|
||||
|
||||
(t/testing " - frameX"
|
||||
(set! (.-frameX shape) 10)
|
||||
(t/is (m/close? (.-frameX shape) 10))
|
||||
(t/is (m/close? (.-x shape) 110))
|
||||
(t/is (m/close? (get-in @store (get-shape-path :x)) 110)))
|
||||
|
||||
(t/testing " - frameY"
|
||||
(set! (.-frameY shape) 20)
|
||||
(t/is (m/close? (.-frameY shape) 20))
|
||||
(t/is (m/close? (.-y shape) 220))
|
||||
(t/is (m/close? (get-in @store (get-shape-path :y)) 220)))
|
||||
|
||||
(t/testing " - parentX"
|
||||
(set! (.-parentX shape) 30)
|
||||
(t/is (m/close? (.-parentX shape) 30))
|
||||
(t/is (m/close? (.-x shape) 130))
|
||||
(t/is (m/close? (get-in @store (get-shape-path :x)) 130)))
|
||||
|
||||
(t/testing " - parentY"
|
||||
(set! (.-parentY shape) 40)
|
||||
(t/is (m/close? (.-parentY shape) 40))
|
||||
(t/is (m/close? (.-y shape) 240))
|
||||
(t/is (m/close? (get-in @store (get-shape-path :y)) 240)))))
|
||||
|
||||
(t/testing "Clone")
|
||||
(t/testing "Remove")))
|
||||
|
Loading…
Add table
Reference in a new issue