mirror of
https://github.com/penpot/penpot.git
synced 2025-06-13 23:21:38 +02:00
✨ Add support to guides for plugins
This commit is contained in:
parent
9e94cf7b99
commit
dd0c5b7806
7 changed files with 238 additions and 7 deletions
|
@ -15,6 +15,7 @@
|
||||||
[app.plugins.grid :as grid]
|
[app.plugins.grid :as grid]
|
||||||
[app.plugins.library :as library]
|
[app.plugins.library :as library]
|
||||||
[app.plugins.public-utils]
|
[app.plugins.public-utils]
|
||||||
|
[app.plugins.ruler-guides :as rg]
|
||||||
[app.plugins.shape :as shape]
|
[app.plugins.shape :as shape]
|
||||||
[app.util.globals :refer [global]]
|
[app.util.globals :refer [global]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
@ -43,6 +44,8 @@
|
||||||
(set! flex/shape-proxy? shape/shape-proxy?)
|
(set! flex/shape-proxy? shape/shape-proxy?)
|
||||||
(set! grid/shape-proxy? shape/shape-proxy?)
|
(set! grid/shape-proxy? shape/shape-proxy?)
|
||||||
(set! format/shape-proxy shape/shape-proxy)
|
(set! format/shape-proxy shape/shape-proxy)
|
||||||
|
(set! rg/shape-proxy shape/shape-proxy)
|
||||||
|
(set! rg/shape-proxy? shape/shape-proxy?)
|
||||||
|
|
||||||
(set! shape/lib-typography-proxy? library/lib-typography-proxy?)
|
(set! shape/lib-typography-proxy? library/lib-typography-proxy?)
|
||||||
(set! shape/lib-component-proxy library/lib-component-proxy)
|
(set! shape/lib-component-proxy library/lib-component-proxy)
|
||||||
|
|
|
@ -592,3 +592,9 @@
|
||||||
:url (:url interaction)}
|
:url (:url interaction)}
|
||||||
|
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
|
(defn axis->orientation
|
||||||
|
[axis]
|
||||||
|
(case axis
|
||||||
|
:y "horizontal"
|
||||||
|
:x "vertical"))
|
||||||
|
|
|
@ -5,19 +5,22 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.plugins.page
|
(ns app.plugins.page
|
||||||
"RPC for plugins runtime."
|
|
||||||
(:require
|
(:require
|
||||||
[app.common.colors :as cc]
|
[app.common.colors :as cc]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.record :as crc]
|
[app.common.record :as crc]
|
||||||
|
[app.common.spec :as us]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
[app.main.data.workspace.guides :as dwgu]
|
||||||
[app.main.data.workspace.interactions :as dwi]
|
[app.main.data.workspace.interactions :as dwi]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.plugins.format :as format]
|
[app.plugins.format :as format]
|
||||||
[app.plugins.parser :as parser]
|
[app.plugins.parser :as parser]
|
||||||
[app.plugins.register :as r]
|
[app.plugins.register :as r]
|
||||||
|
[app.plugins.ruler-guides :as rg]
|
||||||
[app.plugins.shape :as shape]
|
[app.plugins.shape :as shape]
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
@ -52,7 +55,7 @@
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwi/update-flow page-id id #(assoc % :name value)))))}
|
(st/emit! (dwi/update-flow page-id id #(assoc % :name value)))))}
|
||||||
|
|
||||||
{:name "startingFrame"
|
{:name "startingBoard"
|
||||||
:get
|
:get
|
||||||
(fn [self]
|
(fn [self]
|
||||||
(let [frame (-> self u/proxy->flow :starting-frame)]
|
(let [frame (-> self u/proxy->flow :starting-frame)]
|
||||||
|
@ -61,7 +64,7 @@
|
||||||
(fn [_ value]
|
(fn [_ value]
|
||||||
(cond
|
(cond
|
||||||
(not (shape/shape-proxy? value))
|
(not (shape/shape-proxy? value))
|
||||||
(u/display-not-valid :startingFrame value)
|
(u/display-not-valid :startingBoard value)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwi/update-flow page-id id #(assoc % :starting-frame (obj/get value "$id"))))))}))
|
(st/emit! (dwi/update-flow page-id id #(assoc % :starting-frame (obj/get value "$id"))))))}))
|
||||||
|
@ -209,7 +212,48 @@
|
||||||
(u/display-not-valid :removeFlow-flow flow)
|
(u/display-not-valid :removeFlow-flow flow)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwi/remove-flow $id (obj/get flow "$id"))))))
|
(st/emit! (dwi/remove-flow $id (obj/get flow "$id")))))
|
||||||
|
|
||||||
|
(addRulerGuide
|
||||||
|
[self orientation value board]
|
||||||
|
(let [shape (u/proxy->shape board)]
|
||||||
|
(cond
|
||||||
|
(not (us/safe-number? value))
|
||||||
|
(u/display-not-valid :addRulerGuide "Value not a safe number")
|
||||||
|
|
||||||
|
(not (contains? #{"vertical" "horizontal"} orientation))
|
||||||
|
(u/display-not-valid :addRulerGuide "Orientation should be either 'vertical' or 'horizontal'")
|
||||||
|
|
||||||
|
(or (not (shape/shape-proxy? shape))
|
||||||
|
(not (cfh/frame-shape? shape)))
|
||||||
|
(u/display-not-valid :addRulerGuide "The shape is not a board")
|
||||||
|
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :addRulerGuide "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:ellse
|
||||||
|
(let [id (uuid/next)]
|
||||||
|
(st/emit!
|
||||||
|
(dwgu/update-guides
|
||||||
|
(d/without-nils
|
||||||
|
{:id id
|
||||||
|
:axis (parser/orientation->axis orientation)
|
||||||
|
:position value
|
||||||
|
:frame-id (when board (obj/get board "$id"))})))
|
||||||
|
(rg/ruler-guide-proxy $plugin $file $id id)))))
|
||||||
|
|
||||||
|
(removeRulerGuide
|
||||||
|
[_ value]
|
||||||
|
(cond
|
||||||
|
(not (rg/ruler-guide-proxy? value))
|
||||||
|
(u/display-not-valid :removeRulerGuide "Guide not provided")
|
||||||
|
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :removeRulerGuide "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [guide (u/proxy->ruler-guide value)]
|
||||||
|
(st/emit! (dwgu/remove-guide guide))))))
|
||||||
|
|
||||||
(crc/define-properties!
|
(crc/define-properties!
|
||||||
PageProxy
|
PageProxy
|
||||||
|
@ -267,4 +311,13 @@
|
||||||
:get
|
:get
|
||||||
(fn [self]
|
(fn [self]
|
||||||
(let [flows (d/nilv (-> (u/proxy->page self) :options :flows) [])]
|
(let [flows (d/nilv (-> (u/proxy->page self) :options :flows) [])]
|
||||||
(format/format-array #(flow-proxy plugin-id file-id id (:id %)) flows)))}))
|
(format/format-array #(flow-proxy plugin-id file-id id (:id %)) flows)))}
|
||||||
|
|
||||||
|
{:name "rulerGuides"
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [guides (-> (u/proxy->page self) :options :guides)]
|
||||||
|
(->> guides
|
||||||
|
(vals)
|
||||||
|
(filter #(nil? (:frame-id %)))
|
||||||
|
(format/format-array #(rg/ruler-guide-proxy plugin-id file-id id (:id %))))))}))
|
||||||
|
|
|
@ -569,3 +569,9 @@
|
||||||
action (parse-action action)]
|
action (parse-action action)]
|
||||||
(d/without-nils
|
(d/without-nils
|
||||||
(d/patch-object {:event-type trigger :delay delay} action)))))
|
(d/patch-object {:event-type trigger :delay delay} action)))))
|
||||||
|
|
||||||
|
(defn orientation->axis
|
||||||
|
[axis]
|
||||||
|
(case axis
|
||||||
|
"horizontal" :y
|
||||||
|
"vertical" :x))
|
||||||
|
|
99
frontend/src/app/plugins/ruler_guides.cljs
Normal file
99
frontend/src/app/plugins/ruler_guides.cljs
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
;; 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.ruler-guides
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
|
[app.common.record :as crc]
|
||||||
|
[app.common.spec :as us]
|
||||||
|
[app.main.data.workspace.guides :as dwgu]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.plugins.format :as format]
|
||||||
|
[app.plugins.register :as r]
|
||||||
|
[app.plugins.utils :as u]
|
||||||
|
[app.util.object :as obj]))
|
||||||
|
|
||||||
|
(def shape-proxy)
|
||||||
|
(def shape-proxy?)
|
||||||
|
|
||||||
|
(deftype RulerGuideProxy [$plugin $file $page $id]
|
||||||
|
Object
|
||||||
|
(remove [self]
|
||||||
|
(let [guide (u/proxy->ruler-guide self)]
|
||||||
|
(st/emit! (dwgu/remove-guide guide)))))
|
||||||
|
|
||||||
|
(defn ruler-guide-proxy? [p]
|
||||||
|
(instance? RulerGuideProxy p))
|
||||||
|
|
||||||
|
(defn ruler-guide-proxy
|
||||||
|
[plugin-id file-id page-id id]
|
||||||
|
(crc/add-properties!
|
||||||
|
(RulerGuideProxy. plugin-id file-id page-id id)
|
||||||
|
{:name "$plugin" :enumerable false :get (constantly plugin-id)}
|
||||||
|
{:name "$file" :enumerable false :get (constantly file-id)}
|
||||||
|
{:name "$page" :enumerable false :get (constantly page-id)}
|
||||||
|
{:name "$id" :enumerable false :get (constantly id)}
|
||||||
|
|
||||||
|
{:name "board" :enumerable false
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [board-id (-> self u/proxy->ruler-guide :frame-id)]
|
||||||
|
(when board-id
|
||||||
|
(shape-proxy plugin-id file-id page-id board-id))))
|
||||||
|
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(let [shape (u/locate-shape file-id page-id (obj/get value "$id"))]
|
||||||
|
(cond
|
||||||
|
(not (shape-proxy? value))
|
||||||
|
(u/display-not-valid :board "The board is not a shape proxy")
|
||||||
|
|
||||||
|
(not (cfh/frame-shape? shape))
|
||||||
|
(u/display-not-valid :board "The shape is not a board")
|
||||||
|
|
||||||
|
(not (r/check-permission plugin-id "content:write"))
|
||||||
|
(u/display-not-valid :board "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [board-id (when value (obj/get value "$id"))
|
||||||
|
guide (-> self u/proxy->ruler-guide)]
|
||||||
|
(st/emit! (dwgu/update-guides (assoc guide :frame-id board-id)))))))}
|
||||||
|
|
||||||
|
{:name "orientation"
|
||||||
|
:get #(-> % u/proxy->ruler-guide :axis format/axis->orientation)}
|
||||||
|
|
||||||
|
{:name "position"
|
||||||
|
:get
|
||||||
|
(fn [self]
|
||||||
|
(let [guide (u/proxy->ruler-guide self)]
|
||||||
|
(if (:frame-id guide)
|
||||||
|
(let [objects (u/locate-objects file-id page-id)
|
||||||
|
board-pos (dm/get-in objects [(:frame-id guide) (:axis guide)])
|
||||||
|
position (:position guide)]
|
||||||
|
(- position board-pos))
|
||||||
|
|
||||||
|
;; No frame
|
||||||
|
(:position guide))))
|
||||||
|
:set
|
||||||
|
(fn [self value]
|
||||||
|
(cond
|
||||||
|
(not (us/safe-number? value))
|
||||||
|
(u/display-not-valid :position "Not valid position")
|
||||||
|
|
||||||
|
(not (r/check-permission plugin-id "content:write"))
|
||||||
|
(u/display-not-valid :position "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [guide (u/proxy->ruler-guide self)
|
||||||
|
position
|
||||||
|
(if (:frame-id guide)
|
||||||
|
(let [objects (u/locate-objects file-id page-id)
|
||||||
|
board-pos (dm/get-in objects [(:frame-id guide) (:axis guide)])]
|
||||||
|
(+ board-pos value))
|
||||||
|
|
||||||
|
value)]
|
||||||
|
(st/emit! (dwgu/update-guides (assoc guide :position position))))))}))
|
|
@ -5,7 +5,6 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.plugins.shape
|
(ns app.plugins.shape
|
||||||
"RPC for plugins runtime."
|
|
||||||
(:require
|
(:require
|
||||||
[app.common.colors :as clr]
|
[app.common.colors :as clr]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
@ -33,6 +32,7 @@
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
|
[app.main.data.workspace.guides :as dwgu]
|
||||||
[app.main.data.workspace.interactions :as dwi]
|
[app.main.data.workspace.interactions :as dwi]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
[app.plugins.grid :as grid]
|
[app.plugins.grid :as grid]
|
||||||
[app.plugins.parser :as parser]
|
[app.plugins.parser :as parser]
|
||||||
[app.plugins.register :as r]
|
[app.plugins.register :as r]
|
||||||
|
[app.plugins.ruler-guides :as rg]
|
||||||
[app.plugins.text :as text]
|
[app.plugins.text :as text]
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
@ -571,7 +572,52 @@
|
||||||
(u/display-not-valid :removeInteraction interaction)
|
(u/display-not-valid :removeInteraction interaction)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwi/remove-interaction {:id $id} (obj/get interaction "$index"))))))
|
(st/emit! (dwi/remove-interaction {:id $id} (obj/get interaction "$index")))))
|
||||||
|
|
||||||
|
;; Ruler guides
|
||||||
|
(addRulerGuide
|
||||||
|
[self orientation value]
|
||||||
|
(let [shape (u/proxy->shape self)]
|
||||||
|
(cond
|
||||||
|
(not (us/safe-number? value))
|
||||||
|
(u/display-not-valid :addRulerGuide "Value not a safe number")
|
||||||
|
|
||||||
|
(not (contains? #{"vertical" "horizontal"} orientation))
|
||||||
|
(u/display-not-valid :addRulerGuide "Orientation should be either 'vertical' or 'horizontal'")
|
||||||
|
|
||||||
|
(not (cfh/frame-shape? shape))
|
||||||
|
(u/display-not-valid :addRulerGuide "The shape is not a board")
|
||||||
|
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :addRulerGuide "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:ellse
|
||||||
|
(let [id (uuid/next)
|
||||||
|
axis (parser/orientation->axis orientation)
|
||||||
|
objects (u/locate-objects $file $page)
|
||||||
|
frame (get objects $id)
|
||||||
|
board-pos (get frame axis)
|
||||||
|
position (+ board-pos value)]
|
||||||
|
(st/emit!
|
||||||
|
(dwgu/update-guides
|
||||||
|
{:id id
|
||||||
|
:axis axis
|
||||||
|
:position position
|
||||||
|
:frame-id $id}))
|
||||||
|
(rg/ruler-guide-proxy $plugin $file $page id)))))
|
||||||
|
|
||||||
|
(removeRulerGuide
|
||||||
|
[_ value]
|
||||||
|
(cond
|
||||||
|
(not (rg/ruler-guide-proxy? value))
|
||||||
|
(u/display-not-valid :removeRulerGuide "Guide not provided")
|
||||||
|
|
||||||
|
(not (r/check-permission $plugin "content:write"))
|
||||||
|
(u/display-not-valid :removeRulerGuide "Plugin doesn't have 'content:write' permission")
|
||||||
|
|
||||||
|
:else
|
||||||
|
(let [guide (u/proxy->ruler-guide value)]
|
||||||
|
(st/emit! (dwgu/remove-guide guide))))))
|
||||||
|
|
||||||
(defn shape-proxy? [p]
|
(defn shape-proxy? [p]
|
||||||
(instance? ShapeProxy p))
|
(instance? ShapeProxy p))
|
||||||
|
@ -1202,6 +1248,15 @@
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwsh/update-shapes [id] #(assoc % :grids value))))))}
|
(st/emit! (dwsh/update-shapes [id] #(assoc % :grids value))))))}
|
||||||
|
|
||||||
|
{:name "rulerGuides"
|
||||||
|
:get
|
||||||
|
(fn [_]
|
||||||
|
(let [guides (-> (u/locate-page file-id page-id) :options :guides)]
|
||||||
|
(->> guides
|
||||||
|
(vals)
|
||||||
|
(filter #(= id (:frame-id %)))
|
||||||
|
(format/format-array #(rg/ruler-guide-proxy plugin-id file-id page-id (:id %))))))}
|
||||||
|
|
||||||
{:name "horizontalSizing"
|
{:name "horizontalSizing"
|
||||||
:get #(-> % u/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
|
:set
|
||||||
|
|
|
@ -122,6 +122,15 @@
|
||||||
(when (some? page)
|
(when (some? page)
|
||||||
(d/seek #(= (:id %) flow-id) (-> page :options :flows)))))
|
(d/seek #(= (:id %) flow-id) (-> page :options :flows)))))
|
||||||
|
|
||||||
|
(defn proxy->ruler-guide
|
||||||
|
[proxy]
|
||||||
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
page-id (obj/get proxy "$page")
|
||||||
|
ruler-id (obj/get proxy "$id")
|
||||||
|
page (locate-page file-id page-id)]
|
||||||
|
(when (some? page)
|
||||||
|
(d/seek #(= (:id %) ruler-id) (-> page :options :guides vals)))))
|
||||||
|
|
||||||
(defn proxy->interaction
|
(defn proxy->interaction
|
||||||
[proxy]
|
[proxy]
|
||||||
(let [file-id (obj/get proxy "$file")
|
(let [file-id (obj/get proxy "$file")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue