mirror of
https://github.com/penpot/penpot.git
synced 2025-05-04 21:45:53 +02:00
✨ Plugins retrieve selection colors
This commit is contained in:
parent
f86156b619
commit
5771f2f8aa
3 changed files with 157 additions and 122 deletions
|
@ -7,6 +7,7 @@
|
||||||
(ns app.common.types.color
|
(ns app.common.types.color
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
[app.common.schema.openapi :as-alias oapi]
|
[app.common.schema.openapi :as-alias oapi]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
|
@ -14,7 +15,8 @@
|
||||||
[app.common.types.color.gradient :as-alias color-gradient]
|
[app.common.types.color.gradient :as-alias color-gradient]
|
||||||
[app.common.types.color.gradient.stop :as-alias color-gradient-stop]
|
[app.common.types.color.gradient.stop :as-alias color-gradient-stop]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.test.check.generators :as tgen]))
|
[clojure.test.check.generators :as tgen]
|
||||||
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; SCHEMAS
|
;; SCHEMAS
|
||||||
|
@ -383,3 +385,121 @@
|
||||||
(and (some? (:color c1))
|
(and (some? (:color c1))
|
||||||
(some? (:color c2))
|
(some? (:color c2))
|
||||||
(= (:color c1) (:color c2)))))
|
(= (:color c1) (:color c2)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn stroke->color-att
|
||||||
|
[stroke file-id shared-libs]
|
||||||
|
(let [color-file-id (:stroke-color-ref-file stroke)
|
||||||
|
color-id (:stroke-color-ref-id stroke)
|
||||||
|
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
||||||
|
is-shared? (contains? shared-libs-colors color-id)
|
||||||
|
has-color? (or (not (nil? (:stroke-color stroke))) (not (nil? (:stroke-color-gradient stroke))))
|
||||||
|
attrs (if (or is-shared? (= color-file-id file-id))
|
||||||
|
(d/without-nils {:color (str/lower (:stroke-color stroke))
|
||||||
|
:opacity (:stroke-opacity stroke)
|
||||||
|
:id color-id
|
||||||
|
:file-id color-file-id
|
||||||
|
:gradient (:stroke-color-gradient stroke)})
|
||||||
|
(d/without-nils {:color (str/lower (:stroke-color stroke))
|
||||||
|
:opacity (:stroke-opacity stroke)
|
||||||
|
:gradient (:stroke-color-gradient stroke)}))]
|
||||||
|
(when has-color?
|
||||||
|
{:attrs attrs
|
||||||
|
:prop :stroke
|
||||||
|
:shape-id (:shape-id stroke)
|
||||||
|
:index (:index stroke)})))
|
||||||
|
|
||||||
|
(defn shadow->color-att
|
||||||
|
[shadow file-id shared-libs]
|
||||||
|
(let [color-file-id (dm/get-in shadow [:color :file-id])
|
||||||
|
color-id (dm/get-in shadow [:color :id])
|
||||||
|
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
||||||
|
is-shared? (contains? shared-libs-colors color-id)
|
||||||
|
attrs (if (or is-shared? (= color-file-id file-id))
|
||||||
|
(d/without-nils {:color (str/lower (dm/get-in shadow [:color :color]))
|
||||||
|
:opacity (dm/get-in shadow [:color :opacity])
|
||||||
|
:id color-id
|
||||||
|
:file-id (dm/get-in shadow [:color :file-id])
|
||||||
|
:gradient (dm/get-in shadow [:color :gradient])})
|
||||||
|
(d/without-nils {:color (str/lower (dm/get-in shadow [:color :color]))
|
||||||
|
:opacity (dm/get-in shadow [:color :opacity])
|
||||||
|
:gradient (dm/get-in shadow [:color :gradient])}))]
|
||||||
|
|
||||||
|
|
||||||
|
{:attrs attrs
|
||||||
|
:prop :shadow
|
||||||
|
:shape-id (:shape-id shadow)
|
||||||
|
:index (:index shadow)}))
|
||||||
|
|
||||||
|
(defn text->color-att
|
||||||
|
[fill file-id shared-libs]
|
||||||
|
(let [color-file-id (:fill-color-ref-file fill)
|
||||||
|
color-id (:fill-color-ref-id fill)
|
||||||
|
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
||||||
|
is-shared? (contains? shared-libs-colors color-id)
|
||||||
|
attrs (if (or is-shared? (= color-file-id file-id))
|
||||||
|
(d/without-nils {:color (str/lower (:fill-color fill))
|
||||||
|
:opacity (:fill-opacity fill)
|
||||||
|
:id color-id
|
||||||
|
:file-id color-file-id
|
||||||
|
:gradient (:fill-color-gradient fill)})
|
||||||
|
(d/without-nils {:color (str/lower (:fill-color fill))
|
||||||
|
:opacity (:fill-opacity fill)
|
||||||
|
:gradient (:fill-color-gradient fill)}))]
|
||||||
|
{:attrs attrs
|
||||||
|
:prop :content
|
||||||
|
:shape-id (:shape-id fill)
|
||||||
|
:index (:index fill)}))
|
||||||
|
|
||||||
|
(defn treat-node
|
||||||
|
[node shape-id]
|
||||||
|
(map-indexed #(assoc %2 :shape-id shape-id :index %1) node))
|
||||||
|
|
||||||
|
(defn extract-text-colors
|
||||||
|
[text file-id shared-libs]
|
||||||
|
(let [content (txt/node-seq txt/is-text-node? (:content text))
|
||||||
|
content-filtered (map :fills content)
|
||||||
|
indexed (mapcat #(treat-node % (:id text)) content-filtered)]
|
||||||
|
(map #(text->color-att % file-id shared-libs) indexed)))
|
||||||
|
|
||||||
|
(defn fill->color-att
|
||||||
|
[fill file-id shared-libs]
|
||||||
|
(let [color-file-id (:fill-color-ref-file fill)
|
||||||
|
color-id (:fill-color-ref-id fill)
|
||||||
|
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
||||||
|
is-shared? (contains? shared-libs-colors color-id)
|
||||||
|
has-color? (or (not (nil? (:fill-color fill))) (not (nil? (:fill-color-gradient fill))))
|
||||||
|
attrs (if (or is-shared? (= color-file-id file-id))
|
||||||
|
(d/without-nils {:color (str/lower (:fill-color fill))
|
||||||
|
:opacity (:fill-opacity fill)
|
||||||
|
:id color-id
|
||||||
|
:file-id color-file-id
|
||||||
|
:gradient (:fill-color-gradient fill)})
|
||||||
|
(d/without-nils {:color (str/lower (:fill-color fill))
|
||||||
|
:opacity (:fill-opacity fill)
|
||||||
|
:gradient (:fill-color-gradient fill)}))]
|
||||||
|
(when has-color?
|
||||||
|
{:attrs attrs
|
||||||
|
:prop :fill
|
||||||
|
:shape-id (:shape-id fill)
|
||||||
|
:index (:index fill)})))
|
||||||
|
|
||||||
|
(defn extract-all-colors
|
||||||
|
[shapes file-id shared-libs]
|
||||||
|
(reduce
|
||||||
|
(fn [list shape]
|
||||||
|
(let [fill-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:fills shape))
|
||||||
|
stroke-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:strokes shape))
|
||||||
|
shadow-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:shadow shape))]
|
||||||
|
(if (= :text (:type shape))
|
||||||
|
(-> list
|
||||||
|
(into (map #(stroke->color-att % file-id shared-libs)) stroke-obj)
|
||||||
|
(into (map #(shadow->color-att % file-id shared-libs)) shadow-obj)
|
||||||
|
(into (extract-text-colors shape file-id shared-libs)))
|
||||||
|
|
||||||
|
(-> list
|
||||||
|
(into (map #(fill->color-att % file-id shared-libs)) fill-obj)
|
||||||
|
(into (map #(stroke->color-att % file-id shared-libs)) stroke-obj)
|
||||||
|
(into (map #(shadow->color-att % file-id shared-libs)) shadow-obj)))))
|
||||||
|
[]
|
||||||
|
shapes))
|
||||||
|
|
|
@ -9,143 +9,24 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.text :as txt]
|
[app.common.types.color :as ctc]
|
||||||
[app.main.data.workspace.colors :as dc]
|
[app.main.data.workspace.colors :as dc]
|
||||||
[app.main.data.workspace.selection :as dws]
|
[app.main.data.workspace.selection :as dws]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||||
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
[app.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[cuerdas.core :as str]
|
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn fill->color-att
|
|
||||||
[fill file-id shared-libs]
|
|
||||||
(let [color-file-id (:fill-color-ref-file fill)
|
|
||||||
color-id (:fill-color-ref-id fill)
|
|
||||||
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
|
||||||
is-shared? (contains? shared-libs-colors color-id)
|
|
||||||
has-color? (or (not (nil? (:fill-color fill))) (not (nil? (:fill-color-gradient fill))))
|
|
||||||
attrs (if (or is-shared? (= color-file-id file-id))
|
|
||||||
(d/without-nils {:color (str/lower (:fill-color fill))
|
|
||||||
:opacity (:fill-opacity fill)
|
|
||||||
:id color-id
|
|
||||||
:file-id color-file-id
|
|
||||||
:gradient (:fill-color-gradient fill)})
|
|
||||||
(d/without-nils {:color (str/lower (:fill-color fill))
|
|
||||||
:opacity (:fill-opacity fill)
|
|
||||||
:gradient (:fill-color-gradient fill)}))]
|
|
||||||
(when has-color?
|
|
||||||
{:attrs attrs
|
|
||||||
:prop :fill
|
|
||||||
:shape-id (:shape-id fill)
|
|
||||||
:index (:index fill)})))
|
|
||||||
|
|
||||||
(defn stroke->color-att
|
|
||||||
[stroke file-id shared-libs]
|
|
||||||
(let [color-file-id (:stroke-color-ref-file stroke)
|
|
||||||
color-id (:stroke-color-ref-id stroke)
|
|
||||||
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
|
||||||
is-shared? (contains? shared-libs-colors color-id)
|
|
||||||
has-color? (or (not (nil? (:stroke-color stroke))) (not (nil? (:stroke-color-gradient stroke))))
|
|
||||||
attrs (if (or is-shared? (= color-file-id file-id))
|
|
||||||
(d/without-nils {:color (str/lower (:stroke-color stroke))
|
|
||||||
:opacity (:stroke-opacity stroke)
|
|
||||||
:id color-id
|
|
||||||
:file-id color-file-id
|
|
||||||
:gradient (:stroke-color-gradient stroke)})
|
|
||||||
(d/without-nils {:color (str/lower (:stroke-color stroke))
|
|
||||||
:opacity (:stroke-opacity stroke)
|
|
||||||
:gradient (:stroke-color-gradient stroke)}))]
|
|
||||||
(when has-color?
|
|
||||||
{:attrs attrs
|
|
||||||
:prop :stroke
|
|
||||||
:shape-id (:shape-id stroke)
|
|
||||||
:index (:index stroke)})))
|
|
||||||
|
|
||||||
(defn shadow->color-att
|
|
||||||
[shadow file-id shared-libs]
|
|
||||||
(let [color-file-id (dm/get-in shadow [:color :file-id])
|
|
||||||
color-id (dm/get-in shadow [:color :id])
|
|
||||||
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
|
||||||
is-shared? (contains? shared-libs-colors color-id)
|
|
||||||
attrs (if (or is-shared? (= color-file-id file-id))
|
|
||||||
(d/without-nils {:color (str/lower (dm/get-in shadow [:color :color]))
|
|
||||||
:opacity (dm/get-in shadow [:color :opacity])
|
|
||||||
:id color-id
|
|
||||||
:file-id (dm/get-in shadow [:color :file-id])
|
|
||||||
:gradient (dm/get-in shadow [:color :gradient])})
|
|
||||||
(d/without-nils {:color (str/lower (dm/get-in shadow [:color :color]))
|
|
||||||
:opacity (dm/get-in shadow [:color :opacity])
|
|
||||||
:gradient (dm/get-in shadow [:color :gradient])}))]
|
|
||||||
|
|
||||||
|
|
||||||
{:attrs attrs
|
|
||||||
:prop :shadow
|
|
||||||
:shape-id (:shape-id shadow)
|
|
||||||
:index (:index shadow)}))
|
|
||||||
|
|
||||||
(defn text->color-att
|
|
||||||
[fill file-id shared-libs]
|
|
||||||
(let [color-file-id (:fill-color-ref-file fill)
|
|
||||||
color-id (:fill-color-ref-id fill)
|
|
||||||
shared-libs-colors (dm/get-in shared-libs [color-file-id :data :colors])
|
|
||||||
is-shared? (contains? shared-libs-colors color-id)
|
|
||||||
attrs (if (or is-shared? (= color-file-id file-id))
|
|
||||||
(d/without-nils {:color (str/lower (:fill-color fill))
|
|
||||||
:opacity (:fill-opacity fill)
|
|
||||||
:id color-id
|
|
||||||
:file-id color-file-id
|
|
||||||
:gradient (:fill-color-gradient fill)})
|
|
||||||
(d/without-nils {:color (str/lower (:fill-color fill))
|
|
||||||
:opacity (:fill-opacity fill)
|
|
||||||
:gradient (:fill-color-gradient fill)}))]
|
|
||||||
{:attrs attrs
|
|
||||||
:prop :content
|
|
||||||
:shape-id (:shape-id fill)
|
|
||||||
:index (:index fill)}))
|
|
||||||
|
|
||||||
(defn treat-node
|
|
||||||
[node shape-id]
|
|
||||||
(map-indexed #(assoc %2 :shape-id shape-id :index %1) node))
|
|
||||||
|
|
||||||
(defn extract-text-colors
|
|
||||||
[text file-id shared-libs]
|
|
||||||
(let [content (txt/node-seq txt/is-text-node? (:content text))
|
|
||||||
content-filtered (map :fills content)
|
|
||||||
indexed (mapcat #(treat-node % (:id text)) content-filtered)]
|
|
||||||
(map #(text->color-att % file-id shared-libs) indexed)))
|
|
||||||
|
|
||||||
(defn- extract-all-colors
|
|
||||||
[shapes file-id shared-libs]
|
|
||||||
(reduce
|
|
||||||
(fn [list shape]
|
|
||||||
(let [fill-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:fills shape))
|
|
||||||
stroke-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:strokes shape))
|
|
||||||
shadow-obj (map-indexed #(assoc %2 :shape-id (:id shape) :index %1) (:shadow shape))]
|
|
||||||
(if (= :text (:type shape))
|
|
||||||
(-> list
|
|
||||||
(into (map #(stroke->color-att % file-id shared-libs)) stroke-obj)
|
|
||||||
(into (map #(shadow->color-att % file-id shared-libs)) shadow-obj)
|
|
||||||
(into (extract-text-colors shape file-id shared-libs)))
|
|
||||||
|
|
||||||
(-> list
|
|
||||||
(into (map #(fill->color-att % file-id shared-libs)) fill-obj)
|
|
||||||
(into (map #(stroke->color-att % file-id shared-libs)) stroke-obj)
|
|
||||||
(into (map #(shadow->color-att % file-id shared-libs)) shadow-obj)))))
|
|
||||||
[]
|
|
||||||
shapes))
|
|
||||||
|
|
||||||
(defn- prepare-colors
|
(defn- prepare-colors
|
||||||
[shapes file-id shared-libs]
|
[shapes file-id shared-libs]
|
||||||
(let [data (into [] (remove nil? (extract-all-colors shapes file-id shared-libs)))
|
(let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id shared-libs)))
|
||||||
grouped-colors (group-by :attrs data)
|
grouped-colors (group-by :attrs data)
|
||||||
all-colors (distinct (mapv :attrs data))
|
all-colors (distinct (mapv :attrs data))
|
||||||
|
|
||||||
tmp (group-by #(some? (:id %)) all-colors)
|
tmp (group-by #(some? (:id %)) all-colors)
|
||||||
library-colors (get tmp true)
|
library-colors (get tmp true)
|
||||||
colors (get tmp false)]
|
colors (get tmp false)]
|
||||||
|
|
||||||
{:grouped-colors grouped-colors
|
{:grouped-colors grouped-colors
|
||||||
:all-colors all-colors
|
:all-colors all-colors
|
||||||
:colors colors
|
:colors colors
|
||||||
|
|
|
@ -7,11 +7,14 @@
|
||||||
(ns app.plugins.api
|
(ns app.plugins.api
|
||||||
"RPC for plugins runtime."
|
"RPC for plugins runtime."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.files.changes-builder :as cb]
|
[app.common.files.changes-builder :as cb]
|
||||||
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.record :as cr]
|
[app.common.record :as cr]
|
||||||
[app.common.text :as txt]
|
[app.common.text :as txt]
|
||||||
|
[app.common.types.color :as ctc]
|
||||||
[app.common.types.shape :as cts]
|
[app.common.types.shape :as cts]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.changes :as ch]
|
[app.main.data.changes :as ch]
|
||||||
|
@ -28,6 +31,7 @@
|
||||||
[app.plugins.user :as user]
|
[app.plugins.user :as user]
|
||||||
[app.plugins.utils :as u]
|
[app.plugins.utils :as u]
|
||||||
[app.plugins.viewport :as viewport]
|
[app.plugins.viewport :as viewport]
|
||||||
|
[app.util.code-gen :as cg]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[beicon.v2.core :as rx]
|
[beicon.v2.core :as rx]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
@ -83,6 +87,36 @@
|
||||||
(let [selection (get-in @st/state [:workspace-local :selected])]
|
(let [selection (get-in @st/state [:workspace-local :selected])]
|
||||||
(apply array (sequence (map (partial shape/shape-proxy $plugin)) selection))))
|
(apply array (sequence (map (partial shape/shape-proxy $plugin)) selection))))
|
||||||
|
|
||||||
|
(getColors
|
||||||
|
[_ shapes]
|
||||||
|
(let [objects (u/locate-objects)
|
||||||
|
shapes (->> shapes
|
||||||
|
(map #(obj/get % "$id"))
|
||||||
|
(mapcat #(cfh/get-children-with-self objects %)))
|
||||||
|
|
||||||
|
file-id (:current-file-id @st/state)
|
||||||
|
shared-libs (:workspace-libraries @st/state)
|
||||||
|
|
||||||
|
colors
|
||||||
|
(apply
|
||||||
|
array
|
||||||
|
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||||
|
(group-by :attrs)
|
||||||
|
(map (fn [[color attrs]]
|
||||||
|
(let [shapes-info (apply array (map (fn [{:keys [prop shape-id index]}]
|
||||||
|
#js {:property (d/name prop)
|
||||||
|
:index index
|
||||||
|
:shapeId (str shape-id)}) attrs))
|
||||||
|
color (u/to-js color)]
|
||||||
|
(obj/set! color "shapeInfo" shapes-info)
|
||||||
|
color)))))]
|
||||||
|
colors))
|
||||||
|
|
||||||
|
(changeColor
|
||||||
|
[_ _shapes _old-color _new-color]
|
||||||
|
;; TODO
|
||||||
|
)
|
||||||
|
|
||||||
(getRoot
|
(getRoot
|
||||||
[_]
|
[_]
|
||||||
(shape/shape-proxy $plugin uuid/zero))
|
(shape/shape-proxy $plugin uuid/zero))
|
||||||
|
|
Loading…
Add table
Reference in a new issue