mirror of
https://github.com/penpot/penpot.git
synced 2025-04-04 11:01:20 -05: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.library :as library]
|
||||
[app.plugins.public-utils]
|
||||
[app.plugins.ruler-guides :as rg]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.util.globals :refer [global]]
|
||||
[app.util.object :as obj]
|
||||
|
@ -43,6 +44,8 @@
|
|||
(set! flex/shape-proxy? shape/shape-proxy?)
|
||||
(set! grid/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-component-proxy library/lib-component-proxy)
|
||||
|
|
|
@ -592,3 +592,9 @@
|
|||
:url (:url interaction)}
|
||||
|
||||
nil))))
|
||||
|
||||
(defn axis->orientation
|
||||
[axis]
|
||||
(case axis
|
||||
:y "horizontal"
|
||||
:x "vertical"))
|
||||
|
|
|
@ -5,19 +5,22 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.plugins.page
|
||||
"RPC for plugins runtime."
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.record :as crc]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.guides :as dwgu]
|
||||
[app.main.data.workspace.interactions :as dwi]
|
||||
[app.main.store :as st]
|
||||
[app.plugins.format :as format]
|
||||
[app.plugins.parser :as parser]
|
||||
[app.plugins.register :as r]
|
||||
[app.plugins.ruler-guides :as rg]
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
|
@ -52,7 +55,7 @@
|
|||
:else
|
||||
(st/emit! (dwi/update-flow page-id id #(assoc % :name value)))))}
|
||||
|
||||
{:name "startingFrame"
|
||||
{:name "startingBoard"
|
||||
:get
|
||||
(fn [self]
|
||||
(let [frame (-> self u/proxy->flow :starting-frame)]
|
||||
|
@ -61,7 +64,7 @@
|
|||
(fn [_ value]
|
||||
(cond
|
||||
(not (shape/shape-proxy? value))
|
||||
(u/display-not-valid :startingFrame value)
|
||||
(u/display-not-valid :startingBoard value)
|
||||
|
||||
:else
|
||||
(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)
|
||||
|
||||
: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!
|
||||
PageProxy
|
||||
|
@ -267,4 +311,13 @@
|
|||
:get
|
||||
(fn [self]
|
||||
(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)]
|
||||
(d/without-nils
|
||||
(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
|
||||
|
||||
(ns app.plugins.shape
|
||||
"RPC for plugins runtime."
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
|
@ -33,6 +32,7 @@
|
|||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
[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.libraries :as dwl]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
|
@ -46,6 +46,7 @@
|
|||
[app.plugins.grid :as grid]
|
||||
[app.plugins.parser :as parser]
|
||||
[app.plugins.register :as r]
|
||||
[app.plugins.ruler-guides :as rg]
|
||||
[app.plugins.text :as text]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
|
@ -571,7 +572,52 @@
|
|||
(u/display-not-valid :removeInteraction interaction)
|
||||
|
||||
: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]
|
||||
(instance? ShapeProxy p))
|
||||
|
@ -1202,6 +1248,15 @@
|
|||
:else
|
||||
(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"
|
||||
:get #(-> % u/proxy->shape :layout-item-h-sizing (d/nilv :fix) d/name)
|
||||
:set
|
||||
|
|
|
@ -122,6 +122,15 @@
|
|||
(when (some? page)
|
||||
(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
|
||||
[proxy]
|
||||
(let [file-id (obj/get proxy "$file")
|
||||
|
|
Loading…
Add table
Reference in a new issue