mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
♻️ Add substantial refactor on how types are organized
This mainly affects types related to colors, fills and texts, moving library based operations from color namespace.
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]))
|
||||
[app.common.types.text :as txt]))
|
||||
|
||||
(defn- get-attr
|
||||
[obj attr]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.grid :as ctg]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.path :as path]
|
||||
@@ -927,15 +928,15 @@
|
||||
|
||||
(defmethod process-change :add-color
|
||||
[data {:keys [color]}]
|
||||
(ctc/add-color data color))
|
||||
(ctl/add-color data color))
|
||||
|
||||
(defmethod process-change :mod-color
|
||||
[data {:keys [color]}]
|
||||
(ctc/set-color data color))
|
||||
(ctl/set-color data color))
|
||||
|
||||
(defmethod process-change :del-color
|
||||
[data {:keys [id]}]
|
||||
(ctc/delete-color data id))
|
||||
(ctl/delete-color data id))
|
||||
|
||||
;; DEPRECATED: remove before 2.3
|
||||
(defmethod process-change :add-recent-color
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
[app.common.math :as mth]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.svg :as csvg]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
@@ -32,7 +31,7 @@
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.shape.shadow :as ctss]
|
||||
[app.common.types.text :as cttx]
|
||||
[app.common.types.text :as types.text]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
@@ -623,7 +622,7 @@
|
||||
(let [invalid-node? (complement valid-node?)]
|
||||
(cond-> object
|
||||
(cfh/text-shape? object)
|
||||
(update :content #(txt/transform-nodes invalid-node? fix-node %)))))
|
||||
(update :content #(types.text/transform-nodes invalid-node? fix-node %)))))
|
||||
|
||||
(update-container [container]
|
||||
(d/update-when container :objects d/update-vals update-object))]
|
||||
@@ -730,7 +729,7 @@
|
||||
(let [shape (update-object shape)]
|
||||
(if (cfh/text-shape? shape)
|
||||
(-> shape
|
||||
(update :content (partial txt/transform-nodes identity update-fill))
|
||||
(update :content (partial types.text/transform-nodes identity update-fill))
|
||||
(d/update-when :position-data #(mapv update-object %)))
|
||||
shape)))
|
||||
|
||||
@@ -856,7 +855,7 @@
|
||||
|
||||
(update-object [object]
|
||||
(if (cfh/text-shape? object)
|
||||
(update object :content #(txt/transform-nodes txt/is-content-node? update-text-node %))
|
||||
(update object :content #(types.text/transform-nodes types.text/is-content-node? update-text-node %))
|
||||
object))
|
||||
|
||||
(update-container [container]
|
||||
@@ -1105,7 +1104,7 @@
|
||||
;; The text shape also can has fills on the text
|
||||
;; fragments so we need to fix fills there
|
||||
(cond-> (cfh/text-shape? object)
|
||||
(update :content (partial txt/transform-nodes txt/is-content-node? fix-fills)))))
|
||||
(update :content (partial types.text/transform-nodes types.text/is-content-node? fix-fills)))))
|
||||
|
||||
(update-container [container]
|
||||
(d/update-when container :objects d/update-vals update-object))]
|
||||
@@ -1423,7 +1422,7 @@
|
||||
|
||||
(update-object [object]
|
||||
(if (cfh/text-shape? object)
|
||||
(update object :content (partial txt/transform-nodes txt/is-content-node? fix-fills))
|
||||
(update object :content (partial types.text/transform-nodes types.text/is-content-node? fix-fills))
|
||||
object))
|
||||
|
||||
(update-container [container]
|
||||
@@ -1457,7 +1456,7 @@
|
||||
|
||||
;; Fixes shapes with nested :fills in the :fills attribute
|
||||
;; introduced in a migration `0006-fix-old-texts-fills` when
|
||||
;; txt/transform-nodes with identity pred was broken
|
||||
;; types.text/transform-nodes with identity pred was broken
|
||||
(remove-nested-fills [[fill :as fills]]
|
||||
(if (and (= 1 (count fills))
|
||||
(contains? fill :fills))
|
||||
@@ -1483,8 +1482,8 @@
|
||||
|
||||
(fix-text-content [content]
|
||||
(->> content
|
||||
(txt/transform-nodes txt/is-content-node? fix-object)
|
||||
(txt/transform-nodes txt/is-paragraph-set-node? #(dissoc % :fills))))
|
||||
(types.text/transform-nodes types.text/is-content-node? fix-object)
|
||||
(types.text/transform-nodes types.text/is-paragraph-set-node? #(dissoc % :fills))))
|
||||
|
||||
(update-shape [object]
|
||||
(-> object
|
||||
@@ -1539,7 +1538,7 @@
|
||||
ref-shape (ctf/find-ref-shape file page libs object
|
||||
{:include-deleted? true :with-context? true})
|
||||
partial-touched (when ref-shape
|
||||
(cttx/get-diff-type (:content object) (:content ref-shape)))]
|
||||
(types.text/get-diff-type (:content object) (:content ref-shape)))]
|
||||
(if (seq partial-touched)
|
||||
(update object :touched (fn [touched]
|
||||
(reduce #(ctk/set-touched-group %1 %2)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
(ns app.common.files.shapes-builder
|
||||
"A SVG to Shapes builder."
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.exceptions :as ex]
|
||||
@@ -21,6 +20,7 @@
|
||||
[app.common.math :as mth]
|
||||
[app.common.schema :as sm :refer [max-safe-int min-safe-int]]
|
||||
[app.common.svg :as csvg]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.path.segment :as path.segm]
|
||||
[app.common.types.shape :as cts]
|
||||
|
||||
@@ -17,19 +17,18 @@
|
||||
[app.common.logic.shapes :as cls]
|
||||
[app.common.logic.variant-properties :as clvp]
|
||||
[app.common.spec :as us]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.text :as cttx]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.token :as cto]
|
||||
[app.common.types.typography :as cty]
|
||||
[app.common.types.variant :as ctv]
|
||||
@@ -215,8 +214,8 @@
|
||||
[(:frame-id new-main-instance-shape)]
|
||||
(fn [shape objects]
|
||||
(cond-> shape
|
||||
(ctl/grid-layout? shape)
|
||||
(ctl/assign-cells objects)))
|
||||
(ctsl/grid-layout? shape)
|
||||
(ctsl/assign-cells objects)))
|
||||
{:with-objects? true}))]))
|
||||
|
||||
|
||||
@@ -277,7 +276,7 @@
|
||||
(->> ids-map vals (some #(= % (:parent-id first-shape))))
|
||||
|
||||
changes
|
||||
(if (and (ctl/grid-layout? objects (:parent-id first-shape)) (not duplicated-parent?))
|
||||
(if (and (ctsl/grid-layout? objects (:parent-id first-shape)) (not duplicated-parent?))
|
||||
(let [target-cell (-> position meta :cell)
|
||||
|
||||
[row column]
|
||||
@@ -288,10 +287,10 @@
|
||||
[(:parent-id first-shape)]
|
||||
(fn [shape objects]
|
||||
(-> shape
|
||||
(ctl/assign-cells objects)
|
||||
(ctsl/assign-cells objects)
|
||||
(cond-> (and (some? row) (some? column))
|
||||
(-> (ctl/push-into-cell [(:id first-shape)] row column)
|
||||
(ctl/assign-cells objects)))))
|
||||
(-> (ctsl/push-into-cell [(:id first-shape)] row column)
|
||||
(ctsl/assign-cells objects)))))
|
||||
{:with-objects? true})
|
||||
(pcb/reorder-grid-children [(:parent-id first-shape)])))
|
||||
changes)
|
||||
@@ -576,8 +575,8 @@
|
||||
(defmethod uses-assets? :colors
|
||||
[_ color-id shape library-id]
|
||||
(if (nil? color-id)
|
||||
(ctc/uses-library-colors? shape library-id)
|
||||
(ctc/uses-library-color? shape library-id color-id)))
|
||||
(cts/uses-library-colors? shape library-id)
|
||||
(cts/uses-library-color? shape library-id color-id)))
|
||||
|
||||
(defmethod uses-assets? :typographies
|
||||
[_ typography-id shape library-id]
|
||||
@@ -605,7 +604,7 @@
|
||||
(let [library-colors (get-in libraries [library-id :data :colors])]
|
||||
(pcb/update-shapes changes
|
||||
[(:id shape)]
|
||||
#(ctc/sync-shape-colors % library-id library-colors))))
|
||||
#(ctl/sync-colors % library-id library-colors))))
|
||||
|
||||
(defmethod generate-sync-shape :typographies
|
||||
[_ changes library-id container shape libraries _]
|
||||
@@ -854,7 +853,7 @@
|
||||
container
|
||||
omit-touched?)
|
||||
|
||||
(ctl/flex-layout? shape-main)
|
||||
(ctsl/flex-layout? shape-main)
|
||||
(update-flex-child-copy-attrs shape-main
|
||||
shape-inst
|
||||
library
|
||||
@@ -973,7 +972,7 @@
|
||||
|
||||
changes
|
||||
(cond-> changes
|
||||
(ctl/grid-layout? shape-inst)
|
||||
(ctsl/grid-layout? shape-inst)
|
||||
(update-grid-copy-attrs
|
||||
(:id shape-inst)
|
||||
shape-main
|
||||
@@ -1063,14 +1062,14 @@
|
||||
component-container
|
||||
{:copy-touched? true}))
|
||||
|
||||
(ctl/flex-layout? shape-main)
|
||||
(ctsl/flex-layout? shape-main)
|
||||
(update-flex-child-main-attrs shape-main
|
||||
shape-inst
|
||||
component-container
|
||||
container
|
||||
omit-touched?)
|
||||
|
||||
(ctl/grid-layout? shape-main)
|
||||
(ctsl/grid-layout? shape-main)
|
||||
(update-grid-main-attrs shape-main
|
||||
shape-inst
|
||||
component-container
|
||||
@@ -1670,16 +1669,16 @@
|
||||
untouched-content ;; The :content of the main component
|
||||
touched]
|
||||
|
||||
(let [main-comps-diff (cttx/get-diff-type touched-content untouched-content)
|
||||
(let [main-comps-diff (txt/get-diff-type touched-content untouched-content)
|
||||
diff-structure? (contains? main-comps-diff :text-content-structure)
|
||||
|
||||
touched-attrs (cttx/get-first-paragraph-text-attrs touched-content)
|
||||
touched-attrs (txt/get-first-paragraph-text-attrs touched-content)
|
||||
;; Have touched content an uniform style?
|
||||
thed-unif-style? (cttx/equal-attrs? touched-content touched-attrs)
|
||||
thed-unif-style? (txt/equal-attrs? touched-content touched-attrs)
|
||||
|
||||
untouched-attrs (cttx/get-first-paragraph-text-attrs untouched-content)
|
||||
untouched-attrs (txt/get-first-paragraph-text-attrs untouched-content)
|
||||
;; Have untouched content an uniform style?
|
||||
untched-unif-style? (cttx/equal-attrs? untouched-content untouched-attrs)]
|
||||
untched-unif-style? (txt/equal-attrs? untouched-content untouched-attrs)]
|
||||
(cond
|
||||
;; Both text and attrs has been touched, keep the
|
||||
;; touched-content
|
||||
@@ -1692,14 +1691,14 @@
|
||||
;; and both have uniform attributes, we keep the touched-content structure and
|
||||
;; texts, updating its attrs to make them like the untouched-content
|
||||
(if (and (not (touched :text-content-attribute)) thed-unif-style? untched-unif-style?)
|
||||
(cttx/copy-attrs-keys touched-content untouched-attrs)
|
||||
(txt/copy-attrs-keys touched-content untouched-attrs)
|
||||
;; In other case, we keep the touched content
|
||||
touched-content)
|
||||
|
||||
(touched :text-content-text)
|
||||
;; Keep the texts touched in touched-content, so copy the
|
||||
;; texts from touched-content into untouched-content
|
||||
(cttx/copy-text-keys touched-content untouched-content)
|
||||
(txt/copy-text-keys touched-content untouched-content)
|
||||
|
||||
(touched :text-content-attribute)
|
||||
;; The untouched content has a different structure, but the touched content had't
|
||||
@@ -1708,20 +1707,19 @@
|
||||
;; If both have uniform attributes, we keep the untouched-content structure and
|
||||
;; texts, updating its attrs to make them like the touched-content
|
||||
(if (and thed-unif-style? untched-unif-style?)
|
||||
(cttx/copy-attrs-keys untouched-content touched-attrs)
|
||||
(txt/copy-attrs-keys untouched-content touched-attrs)
|
||||
;; In other case, we keep the touched content
|
||||
touched-content)
|
||||
|
||||
;; Keep the attrs touched in touched-content, so copy the
|
||||
;; texts from untouched-content into touched-content
|
||||
(cttx/copy-text-keys untouched-content touched-content))
|
||||
(txt/copy-text-keys untouched-content touched-content))
|
||||
|
||||
|
||||
;; Nothing is touched
|
||||
:else
|
||||
untouched-content)))
|
||||
|
||||
|
||||
(defn- add-update-attr-operations
|
||||
[attr dest-shape roperations uoperations attr-val]
|
||||
(let [roperation {:type :set
|
||||
@@ -1852,20 +1850,20 @@
|
||||
(let [;; We need the differences between the contents on the main
|
||||
;; components. current-content is the content of a clean copy,
|
||||
;; so for all effects its the same as the content on its main
|
||||
main-comps-diff (cttx/get-diff-type ref-content current-content)
|
||||
main-comps-diff (txt/get-diff-type ref-content current-content)
|
||||
can-keep-text? (not (contains? main-comps-diff :text-content-text))
|
||||
can-keep-attr? (not (contains? main-comps-diff :text-content-attribute))
|
||||
main-diff-structure? (contains? main-comps-diff :text-content-structure)
|
||||
|
||||
current-attrs (cttx/get-first-paragraph-text-attrs current-content)
|
||||
current-attrs (txt/get-first-paragraph-text-attrs current-content)
|
||||
;; Have current content an uniform style?
|
||||
curr-unif-style? (cttx/equal-attrs? current-content current-attrs)
|
||||
prev-attrs (cttx/get-first-paragraph-text-attrs prev-content)
|
||||
curr-unif-style? (txt/equal-attrs? current-content current-attrs)
|
||||
prev-attrs (txt/get-first-paragraph-text-attrs prev-content)
|
||||
;; Have prev content an uniform style?
|
||||
prev-unif-style? (cttx/equal-attrs? prev-content prev-attrs)
|
||||
ref-attrs (cttx/get-first-paragraph-text-attrs ref-content)
|
||||
prev-unif-style? (txt/equal-attrs? prev-content prev-attrs)
|
||||
ref-attrs (txt/get-first-paragraph-text-attrs ref-content)
|
||||
;; Have ref content an uniform style?
|
||||
ref-unif-style? (cttx/equal-attrs? ref-content ref-attrs)]
|
||||
ref-unif-style? (txt/equal-attrs? ref-content ref-attrs)]
|
||||
(cond
|
||||
;; When the main components have a difference in structure
|
||||
;; (different number of paragraph or text entries)
|
||||
@@ -1879,7 +1877,7 @@
|
||||
ref-unif-style?
|
||||
prev-unif-style?
|
||||
(= ref-attrs current-attrs))
|
||||
(cttx/copy-attrs-keys current-content prev-attrs)
|
||||
(txt/copy-attrs-keys current-content prev-attrs)
|
||||
;; In any other case of structure change, we discard all
|
||||
;; the overrides and keep the content of the current-shape
|
||||
current-content)
|
||||
@@ -1903,8 +1901,8 @@
|
||||
curr-unif-style?
|
||||
prev-unif-style?)
|
||||
(if can-keep-text?
|
||||
(cttx/copy-attrs-keys prev-content current-attrs)
|
||||
(cttx/copy-attrs-keys current-content prev-attrs))
|
||||
(txt/copy-attrs-keys prev-content current-attrs)
|
||||
(txt/copy-attrs-keys current-content prev-attrs))
|
||||
|
||||
;; In any other case of structure change, we discard all
|
||||
;; the overrides and keep the content of the current-shape
|
||||
@@ -1916,14 +1914,14 @@
|
||||
;; previous-shape over the attrs of current-shape
|
||||
(and
|
||||
(touched :text-content-text) can-keep-text?)
|
||||
(cttx/copy-text-keys prev-content current-content)
|
||||
(txt/copy-text-keys prev-content current-content)
|
||||
|
||||
;; When there is a change on :text-content-attribute,
|
||||
;; and we can keep it, we copy the texts from current-shape
|
||||
;; over the attrs of previous-shape
|
||||
(and
|
||||
(touched :text-content-attribute) can-keep-attr?)
|
||||
(cttx/copy-text-keys current-content prev-content)
|
||||
(txt/copy-text-keys current-content prev-content)
|
||||
|
||||
;; In any other case, we discard all the overrides
|
||||
;; and keep the content of the current-shape
|
||||
@@ -2159,11 +2157,11 @@
|
||||
(update cell :shapes #(filterv child? %)))))))
|
||||
;; Take cells from main and remap the shapes to assign it to the copy
|
||||
copy-cells (-> shape-copy :layout-grid-cells (remove-orphan-cells shape-copy))
|
||||
main-cells (-> shape-main (ctl/remap-grid-cells ids-map) :layout-grid-cells)]
|
||||
main-cells (-> shape-main (ctsl/remap-grid-cells ids-map) :layout-grid-cells)]
|
||||
(-> shape-copy
|
||||
(assoc :layout-grid-cells
|
||||
(ctl/merge-cells main-cells copy-cells omit-touched?))
|
||||
(ctl/assign-cells objects))))
|
||||
(ctsl/merge-cells main-cells copy-cells omit-touched?))
|
||||
(ctsl/assign-cells objects))))
|
||||
{:ignore-touched true :with-objects? true})))
|
||||
|
||||
(defn- update-grid-main-attrs
|
||||
@@ -2187,7 +2185,7 @@
|
||||
[(:id shape-main)]
|
||||
(fn [shape-main]
|
||||
;; Take cells from copy and remap the shapes to assign it to the copy
|
||||
(let [new-cells (-> (ctl/remap-grid-cells shape-copy ids-map) :layout-grid-cells)]
|
||||
(let [new-cells (-> (ctsl/remap-grid-cells shape-copy ids-map) :layout-grid-cells)]
|
||||
(assoc shape-main :layout-grid-cells new-cells)))
|
||||
{:ignore-touched true}))]
|
||||
(pcb/concat-changes changes new-changes)))
|
||||
@@ -2300,8 +2298,8 @@
|
||||
parent-id (:parent-id shape)
|
||||
|
||||
insert-before?
|
||||
(and (ctl/flex-layout? objects parent-id)
|
||||
(not (ctl/reverse? objects parent-id)))
|
||||
(and (ctsl/flex-layout? objects parent-id)
|
||||
(not (ctsl/reverse? objects parent-id)))
|
||||
|
||||
objects
|
||||
(-> objects
|
||||
@@ -2317,7 +2315,7 @@
|
||||
(pcb/with-objects objects)
|
||||
(pcb/resize-parents new-objects-ids)
|
||||
;; Fix the order of the children inside the parent
|
||||
(cond-> (ctl/any-layout? objects parent-id)
|
||||
(cond-> (ctsl/any-layout? objects parent-id)
|
||||
(pcb/reorder-children parent-id (get-in objects [parent-id :shapes]))))]
|
||||
(assoc changes :file-id library-id)))
|
||||
|
||||
@@ -2654,8 +2652,8 @@
|
||||
(gsh/move delta)
|
||||
(d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))
|
||||
|
||||
(cond-> (ctl/grid-layout? obj)
|
||||
(ctl/remap-grid-cells ids-map))
|
||||
(cond-> (ctsl/grid-layout? obj)
|
||||
(ctsl/remap-grid-cells ids-map))
|
||||
|
||||
(cond-> (ctk/is-variant-container? parent)
|
||||
(assoc :variant-id parent-id))
|
||||
@@ -2671,8 +2669,8 @@
|
||||
;; We want the first added object to touch it's parent, but not subsequent children
|
||||
changes (-> (pcb/add-object changes new-obj {:ignore-touched (and duplicating-component? child?)})
|
||||
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] ctl/assign-cells {:with-objects? true})
|
||||
(cond-> (ctsl/grid-layout? objects (:parent-id obj))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] ctsl/assign-cells {:with-objects? true})
|
||||
(pcb/reorder-grid-children [(:parent-id obj)]))))
|
||||
|
||||
changes (cond-> changes
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.shape :as cts]))
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.text :as txt]))
|
||||
|
||||
;; ----- File building
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
(defn add-text
|
||||
[file text-label content & {:keys [text-params] :as text}]
|
||||
(let [shape (-> (cts/setup-shape {:type :text :x 0 :y 0})
|
||||
(txt/change-text content))]
|
||||
(update :content txt/change-text content))]
|
||||
(ths/add-sample-shape file text-label
|
||||
(merge shape
|
||||
text-params))))
|
||||
@@ -74,7 +74,7 @@
|
||||
(defn add-frame-with-text
|
||||
[file frame-label child-label text & {:keys [frame-params child-params]}]
|
||||
(let [shape (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text text)
|
||||
(update :content txt/change-text text)
|
||||
(assoc :position-data nil
|
||||
:parent-label frame-label))]
|
||||
(-> file
|
||||
|
||||
@@ -6,18 +6,18 @@
|
||||
|
||||
(ns app.common.test-helpers.shapes
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.typographies-list :as cttl]
|
||||
[app.common.types.typography :as ctt]))
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
(defn add-sample-library-color
|
||||
[file label & {:keys [] :as params}]
|
||||
(let [color (sample-library-color label params)]
|
||||
(update file :data ctc/add-color color)))
|
||||
(update file :data ctl/add-color color)))
|
||||
|
||||
(defn sample-typography
|
||||
[label & {:keys [] :as params}]
|
||||
@@ -149,4 +149,4 @@
|
||||
(fn [file-data]
|
||||
(ctpl/update-page file-data
|
||||
(:id page)
|
||||
#(ctst/set-shape % (assoc origin :interactions interactions)))))))
|
||||
#(ctst/set-shape % (assoc origin :interactions interactions)))))))
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
[app.common.test-helpers.components :as thc]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape :as cts]))
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.text :as txt]))
|
||||
|
||||
(defn add-variant
|
||||
[file variant-label component1-label root1-label component2-label root2-label
|
||||
@@ -60,11 +60,11 @@
|
||||
[file variant-label component1-label root1-label component2-label root2-label child1-label child2-label text1 text2
|
||||
& {:keys [text1-params text2-params]}]
|
||||
(let [text1 (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text text1)
|
||||
(update :content txt/change-text text1)
|
||||
(assoc :position-data nil
|
||||
:parent-label root1-label))
|
||||
text2 (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text text2)
|
||||
(update :content txt/change-text text2)
|
||||
(assoc :position-data nil
|
||||
:parent-label root2-label))
|
||||
|
||||
|
||||
@@ -5,186 +5,16 @@
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.text
|
||||
"Legacy editor helpers (draftjs).
|
||||
|
||||
NOTE: this namespace should be not used for new code related to texts"
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.transit :as t]
|
||||
[clojure.walk :as walk]
|
||||
[app.common.types.text :as types.text]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; -- Attrs
|
||||
|
||||
(def text-typography-attrs
|
||||
[:typography-ref-id
|
||||
:typography-ref-file])
|
||||
|
||||
(def text-fill-attrs
|
||||
[:fill-color
|
||||
:fill-opacity
|
||||
:fill-color-ref-id
|
||||
:fill-color-ref-file
|
||||
:fill-color-gradient])
|
||||
|
||||
(def text-font-attrs
|
||||
[:font-id
|
||||
:font-family
|
||||
:font-variant-id
|
||||
:font-size
|
||||
:font-weight
|
||||
:font-style])
|
||||
|
||||
(def text-align-attrs
|
||||
[:text-align])
|
||||
|
||||
(def text-direction-attrs
|
||||
[:text-direction])
|
||||
|
||||
(def text-spacing-attrs
|
||||
[:line-height
|
||||
:letter-spacing])
|
||||
|
||||
(def text-valign-attrs
|
||||
[:vertical-align])
|
||||
|
||||
(def text-decoration-attrs
|
||||
[:text-decoration])
|
||||
|
||||
(def text-transform-attrs
|
||||
[:text-transform])
|
||||
|
||||
(def text-fills
|
||||
[:fills])
|
||||
|
||||
(def shape-attrs
|
||||
[:grow-type])
|
||||
|
||||
(def root-attrs
|
||||
text-valign-attrs)
|
||||
|
||||
(def paragraph-attrs
|
||||
(d/concat-vec
|
||||
text-align-attrs
|
||||
text-direction-attrs))
|
||||
|
||||
(def text-node-attrs
|
||||
(d/concat-vec
|
||||
text-typography-attrs
|
||||
text-font-attrs
|
||||
text-spacing-attrs
|
||||
text-decoration-attrs
|
||||
text-transform-attrs
|
||||
text-fills))
|
||||
|
||||
(def text-all-attrs (d/concat-set shape-attrs root-attrs paragraph-attrs text-node-attrs))
|
||||
|
||||
(def text-style-attrs
|
||||
(d/concat-vec root-attrs paragraph-attrs text-node-attrs))
|
||||
|
||||
(def default-root-attrs
|
||||
{:vertical-align "top"})
|
||||
|
||||
(def default-text-attrs
|
||||
{:typography-ref-file nil
|
||||
:typography-ref-id nil
|
||||
:font-id "sourcesanspro"
|
||||
:font-family "sourcesanspro"
|
||||
:font-variant-id "regular"
|
||||
:font-size "14"
|
||||
:font-weight "400"
|
||||
:font-style "normal"
|
||||
:line-height "1.2"
|
||||
:letter-spacing "0"
|
||||
:text-transform "none"
|
||||
:text-align "left"
|
||||
:text-decoration "none"
|
||||
:text-direction "ltr"
|
||||
:fills [{:fill-color clr/black
|
||||
:fill-opacity 1}]})
|
||||
|
||||
(def default-attrs
|
||||
(merge default-root-attrs default-text-attrs))
|
||||
|
||||
(def typography-fields
|
||||
[:font-id
|
||||
:font-family
|
||||
:font-variant-id
|
||||
:font-size
|
||||
:font-weight
|
||||
:font-style
|
||||
:line-height
|
||||
:letter-spacing
|
||||
:text-transform])
|
||||
|
||||
(def default-typography
|
||||
(merge
|
||||
{:name "Source Sans Pro Regular"}
|
||||
(select-keys default-text-attrs typography-fields)))
|
||||
|
||||
(defn node-seq
|
||||
([root] (node-seq identity root))
|
||||
([match? root]
|
||||
(->> (tree-seq map? :children root)
|
||||
(filter match?)
|
||||
(seq))))
|
||||
|
||||
(defn is-text-node?
|
||||
[node]
|
||||
(and (nil? (:type node))
|
||||
(string? (:text node))))
|
||||
|
||||
(defn is-paragraph-set-node?
|
||||
[node]
|
||||
(= "paragraph-set" (:type node)))
|
||||
|
||||
(defn is-paragraph-node?
|
||||
[node]
|
||||
(= "paragraph" (:type node)))
|
||||
|
||||
(defn is-root-node?
|
||||
[node]
|
||||
(= "root" (:type node)))
|
||||
|
||||
(defn is-node?
|
||||
[node]
|
||||
(or ^boolean (is-text-node? node)
|
||||
^boolean (is-paragraph-node? node)
|
||||
^boolean (is-paragraph-set-node? node)
|
||||
^boolean (is-root-node? node)))
|
||||
|
||||
(defn is-content-node?
|
||||
"Only matches content nodes, ignoring the paragraph-set nodes."
|
||||
[node]
|
||||
(or ^boolean (is-text-node? node)
|
||||
^boolean (is-paragraph-node? node)
|
||||
^boolean (is-root-node? node)))
|
||||
|
||||
(defn transform-nodes
|
||||
([transform root]
|
||||
(transform-nodes identity transform root))
|
||||
([pred transform root]
|
||||
(walk/postwalk
|
||||
(fn [item]
|
||||
(if (and (is-node? item) (pred item))
|
||||
(transform item)
|
||||
item))
|
||||
root)))
|
||||
|
||||
(defn update-text-content
|
||||
[shape pred-fn update-fn attrs]
|
||||
(let [update-attrs-fn #(update-fn % attrs)
|
||||
transform #(transform-nodes pred-fn update-attrs-fn %)]
|
||||
(-> shape
|
||||
(update :content transform))))
|
||||
|
||||
(defn generate-shape-name
|
||||
[text]
|
||||
(subs text 0 (min 280 (count text))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; DraftJS <-> Penpot Conversion
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn encode-style-value
|
||||
[v]
|
||||
(t/encode-str v))
|
||||
@@ -369,7 +199,7 @@
|
||||
:entityRanges []
|
||||
:inlineStyleRanges (calc-ranges paragraph)})]
|
||||
|
||||
{:blocks (reduce #(conj %1 (build-block %2)) [] (node-seq #(= (:type %) "paragraph") root))
|
||||
{:blocks (reduce #(conj %1 (build-block %2)) [] (types.text/node-seq #(= (:type %) "paragraph") root))
|
||||
:entityMap {}}))
|
||||
|
||||
(defn content->text+styles
|
||||
@@ -377,13 +207,13 @@
|
||||
[node]
|
||||
(letfn
|
||||
[(rec-style-text-map [acc node style]
|
||||
(let [node-style (merge style (select-keys node text-all-attrs))
|
||||
(let [node-style (merge style (select-keys node types.text/text-all-attrs))
|
||||
head (or (-> acc first) [{} ""])
|
||||
[head-style head-text] head
|
||||
|
||||
new-acc
|
||||
(cond
|
||||
(not (is-text-node? node))
|
||||
(not (types.text/is-text-node? node))
|
||||
(reduce #(rec-style-text-map %1 %2 node-style) acc (:children node))
|
||||
|
||||
(not= head-style node-style)
|
||||
@@ -403,82 +233,6 @@
|
||||
(-> (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]
|
||||
(letfn [(add-node [acc node]
|
||||
(cond
|
||||
(is-paragraph-node? node)
|
||||
(conj acc [])
|
||||
|
||||
(is-text-node? node)
|
||||
(let [i (dec (count acc))]
|
||||
(update acc i conj (:text node)))
|
||||
|
||||
:else
|
||||
acc))]
|
||||
(->> (node-seq content)
|
||||
(reduce add-node [])
|
||||
(map #(str/join "" %))
|
||||
(str/join "\n"))))
|
||||
|
||||
(defn change-text
|
||||
"Changes the content of the text shape to use the text as argument. Will use the styles of the
|
||||
first paragraph and text that is present in the shape (and override the rest)"
|
||||
[shape text]
|
||||
(let [content (:content shape)
|
||||
|
||||
root-styles (select-keys content root-attrs)
|
||||
|
||||
paragraph-style (merge
|
||||
default-text-attrs
|
||||
(select-keys (->> content (node-seq is-paragraph-node?) first) text-all-attrs))
|
||||
text-style (merge
|
||||
default-text-attrs
|
||||
(select-keys (->> content (node-seq is-text-node?) first) text-all-attrs))
|
||||
|
||||
paragraph-texts (str/split text "\n")
|
||||
|
||||
paragraphs
|
||||
(->> paragraph-texts
|
||||
(mapv
|
||||
(fn [pt]
|
||||
(merge
|
||||
paragraph-style
|
||||
{:type "paragraph"
|
||||
:children [(merge {:text pt} text-style)]}))))
|
||||
|
||||
new-content
|
||||
(d/patch-object
|
||||
{:type "root"
|
||||
:children
|
||||
[{:type "paragraph-set"
|
||||
:children paragraphs}]}
|
||||
root-styles)]
|
||||
|
||||
(assoc shape :content new-content)))
|
||||
|
||||
(defn index-content
|
||||
"Adds a property `$id` that identifies the current node inside"
|
||||
([content]
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.types.color
|
||||
(:refer-clojure :exclude [test])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]
|
||||
[app.common.media :as cm]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.schema.generators :as sg]
|
||||
[app.common.schema.openapi :as-alias oapi]
|
||||
[app.common.text :as txt]
|
||||
[app.common.time :as dt]
|
||||
[app.common.types.plugins :as ctpg]
|
||||
[clojure.set :as set]
|
||||
[cuerdas.core :as str]))
|
||||
@@ -163,11 +163,183 @@
|
||||
(def check-color
|
||||
(sm/check-fn schema:color :hint "expected valid color"))
|
||||
|
||||
;: FIXME: maybe declare it under types.library ?
|
||||
(def check-library-color
|
||||
(sm/check-fn schema:library-color :hint "expected valid color"))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; HELPERS
|
||||
;; CONSTANTS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(def ^:const black "#000000")
|
||||
(def ^:const default-layout "#DE4762")
|
||||
(def ^:const gray-20 "#B1B2B5")
|
||||
(def ^:const info "#59B9E2")
|
||||
(def ^:const test "#fabada")
|
||||
(def ^:const white "#FFFFFF")
|
||||
(def ^:const warning "#FC8802")
|
||||
|
||||
;; new-css-system colors
|
||||
(def ^:const new-primary "#7efff5")
|
||||
(def ^:const new-danger "#ff3277")
|
||||
(def ^:const new-warning "#fe4811")
|
||||
(def ^:const new-primary-light "#6911d4")
|
||||
(def ^:const background-quaternary "#2e3434")
|
||||
(def ^:const background-quaternary-light "#eef0f2")
|
||||
(def ^:const canvas "#E8E9EA")
|
||||
|
||||
(def names
|
||||
{"aliceblue" "#f0f8ff"
|
||||
"antiquewhite" "#faebd7"
|
||||
"aqua" "#00ffff"
|
||||
"aquamarine" "#7fffd4"
|
||||
"azure" "#f0ffff"
|
||||
"beige" "#f5f5dc"
|
||||
"bisque" "#ffe4c4"
|
||||
"black" "#000000"
|
||||
"blanchedalmond" "#ffebcd"
|
||||
"blue" "#0000ff"
|
||||
"blueviolet" "#8a2be2"
|
||||
"brown" "#a52a2a"
|
||||
"burlywood" "#deb887"
|
||||
"cadetblue" "#5f9ea0"
|
||||
"chartreuse" "#7fff00"
|
||||
"chocolate" "#d2691e"
|
||||
"coral" "#ff7f50"
|
||||
"cornflowerblue" "#6495ed"
|
||||
"cornsilk" "#fff8dc"
|
||||
"crimson" "#dc143c"
|
||||
"cyan" "#00ffff"
|
||||
"darkblue" "#00008b"
|
||||
"darkcyan" "#008b8b"
|
||||
"darkgoldenrod" "#b8860b"
|
||||
"darkgray" "#a9a9a9"
|
||||
"darkgreen" "#006400"
|
||||
"darkgrey" "#a9a9a9"
|
||||
"darkkhaki" "#bdb76b"
|
||||
"darkmagenta" "#8b008b"
|
||||
"darkolivegreen" "#556b2f"
|
||||
"darkorange" "#ff8c00"
|
||||
"darkorchid" "#9932cc"
|
||||
"darkred" "#8b0000"
|
||||
"darksalmon" "#e9967a"
|
||||
"darkseagreen" "#8fbc8f"
|
||||
"darkslateblue" "#483d8b"
|
||||
"darkslategray" "#2f4f4f"
|
||||
"darkslategrey" "#2f4f4f"
|
||||
"darkturquoise" "#00ced1"
|
||||
"darkviolet" "#9400d3"
|
||||
"deeppink" "#ff1493"
|
||||
"deepskyblue" "#00bfff"
|
||||
"dimgray" "#696969"
|
||||
"dimgrey" "#696969"
|
||||
"dodgerblue" "#1e90ff"
|
||||
"firebrick" "#b22222"
|
||||
"floralwhite" "#fffaf0"
|
||||
"forestgreen" "#228b22"
|
||||
"fuchsia" "#ff00ff"
|
||||
"gainsboro" "#dcdcdc"
|
||||
"ghostwhite" "#f8f8ff"
|
||||
"gold" "#ffd700"
|
||||
"goldenrod" "#daa520"
|
||||
"gray" "#808080"
|
||||
"green" "#008000"
|
||||
"greenyellow" "#adff2f"
|
||||
"grey" "#808080"
|
||||
"honeydew" "#f0fff0"
|
||||
"hotpink" "#ff69b4"
|
||||
"indianred" "#cd5c5c"
|
||||
"indigo" "#4b0082"
|
||||
"ivory" "#fffff0"
|
||||
"khaki" "#f0e68c"
|
||||
"lavender" "#e6e6fa"
|
||||
"lavenderblush" "#fff0f5"
|
||||
"lawngreen" "#7cfc00"
|
||||
"lemonchiffon" "#fffacd"
|
||||
"lightblue" "#add8e6"
|
||||
"lightcoral" "#f08080"
|
||||
"lightcyan" "#e0ffff"
|
||||
"lightgoldenrodyellow" "#fafad2"
|
||||
"lightgray" "#d3d3d3"
|
||||
"lightgreen" "#90ee90"
|
||||
"lightgrey" "#d3d3d3"
|
||||
"lightpink" "#ffb6c1"
|
||||
"lightsalmon" "#ffa07a"
|
||||
"lightseagreen" "#20b2aa"
|
||||
"lightskyblue" "#87cefa"
|
||||
"lightslategray" "#778899"
|
||||
"lightslategrey" "#778899"
|
||||
"lightsteelblue" "#b0c4de"
|
||||
"lightyellow" "#ffffe0"
|
||||
"lime" "#00ff00"
|
||||
"limegreen" "#32cd32"
|
||||
"linen" "#faf0e6"
|
||||
"magenta" "#ff00ff"
|
||||
"maroon" "#800000"
|
||||
"mediumaquamarine" "#66cdaa"
|
||||
"mediumblue" "#0000cd"
|
||||
"mediumorchid" "#ba55d3"
|
||||
"mediumpurple" "#9370db"
|
||||
"mediumseagreen" "#3cb371"
|
||||
"mediumslateblue" "#7b68ee"
|
||||
"mediumspringgreen" "#00fa9a"
|
||||
"mediumturquoise" "#48d1cc"
|
||||
"mediumvioletred" "#c71585"
|
||||
"midnightblue" "#191970"
|
||||
"mintcream" "#f5fffa"
|
||||
"mistyrose" "#ffe4e1"
|
||||
"moccasin" "#ffe4b5"
|
||||
"navajowhite" "#ffdead"
|
||||
"navy" "#000080"
|
||||
"oldlace" "#fdf5e6"
|
||||
"olive" "#808000"
|
||||
"olivedrab" "#6b8e23"
|
||||
"orange" "#ffa500"
|
||||
"orangered" "#ff4500"
|
||||
"orchid" "#da70d6"
|
||||
"palegoldenrod" "#eee8aa"
|
||||
"palegreen" "#98fb98"
|
||||
"paleturquoise" "#afeeee"
|
||||
"palevioletred" "#db7093"
|
||||
"papayawhip" "#ffefd5"
|
||||
"peachpuff" "#ffdab9"
|
||||
"peru" "#cd853f"
|
||||
"pink" "#ffc0cb"
|
||||
"plum" "#dda0dd"
|
||||
"powderblue" "#b0e0e6"
|
||||
"purple" "#800080"
|
||||
"red" "#ff0000"
|
||||
"rosybrown" "#bc8f8f"
|
||||
"royalblue" "#4169e1"
|
||||
"saddlebrown" "#8b4513"
|
||||
"salmon" "#fa8072"
|
||||
"sandybrown" "#f4a460"
|
||||
"seagreen" "#2e8b57"
|
||||
"seashell" "#fff5ee"
|
||||
"sienna" "#a0522d"
|
||||
"silver" "#c0c0c0"
|
||||
"skyblue" "#87ceeb"
|
||||
"slateblue" "#6a5acd"
|
||||
"slategray" "#708090"
|
||||
"slategrey" "#708090"
|
||||
"snow" "#fffafa"
|
||||
"springgreen" "#00ff7f"
|
||||
"steelblue" "#4682b4"
|
||||
"tan" "#d2b48c"
|
||||
"teal" "#008080"
|
||||
"thistle" "#d8bfd8"
|
||||
"tomato" "#ff6347"
|
||||
"turquoise" "#40e0d0"
|
||||
"violet" "#ee82ee"
|
||||
"wheat" "#f5deb3"
|
||||
"white" "#ffffff"
|
||||
"whitesmoke" "#f5f5f5"
|
||||
"yellow" "#ffff00"
|
||||
"yellowgreen" "#9acd32"})
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; HELPERS (FIXME: this helpers are not in the correct place)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn library-color->color
|
||||
@@ -181,42 +353,6 @@
|
||||
:path (get lcolor :path)
|
||||
:name (get lcolor :name))))
|
||||
|
||||
;; --- fill
|
||||
|
||||
(defn fill->color
|
||||
[fill]
|
||||
(d/without-nils
|
||||
{:color (:fill-color fill)
|
||||
:opacity (:fill-opacity fill)
|
||||
:gradient (:fill-color-gradient fill)
|
||||
:image (:fill-image fill)
|
||||
:ref-id (:fill-color-ref-id fill)
|
||||
:ref-file (:fill-color-ref-file fill)}))
|
||||
|
||||
(defn set-fill-color
|
||||
[shape position color opacity gradient image]
|
||||
(update-in shape [:fills position]
|
||||
(fn [fill]
|
||||
(d/without-nils (assoc fill
|
||||
:fill-color color
|
||||
:fill-opacity opacity
|
||||
:fill-color-gradient gradient
|
||||
:fill-image image)))))
|
||||
|
||||
(defn attach-fill-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:fills position]
|
||||
(fn [fill]
|
||||
(-> fill
|
||||
(assoc :fill-color-ref-file ref-file)
|
||||
(assoc :fill-color-ref-id ref-id)))))
|
||||
|
||||
(defn detach-fill-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:fills position] dissoc :fill-color-ref-id :fill-color-ref-file))
|
||||
|
||||
;; stroke
|
||||
|
||||
(defn stroke->color
|
||||
[stroke]
|
||||
(d/without-nils
|
||||
@@ -227,59 +363,10 @@
|
||||
:ref-id (:stroke-color-ref-id stroke)
|
||||
:ref-file (:stroke-color-ref-file stroke)}))
|
||||
|
||||
(defn set-stroke-color
|
||||
[shape position color opacity gradient image]
|
||||
(d/update-in-when shape [:strokes position]
|
||||
(fn [stroke]
|
||||
(-> stroke
|
||||
(assoc :stroke-color color)
|
||||
(assoc :stroke-opacity opacity)
|
||||
(assoc :stroke-color-gradient gradient)
|
||||
(assoc :stroke-image image)
|
||||
(d/without-nils)))))
|
||||
|
||||
(defn attach-stroke-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:strokes position]
|
||||
(fn [stroke]
|
||||
(-> stroke
|
||||
(assoc :stroke-color-ref-id ref-id)
|
||||
(assoc :stroke-color-ref-file ref-file)))))
|
||||
|
||||
(defn detach-stroke-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:strokes position] dissoc :stroke-color-ref-id :stroke-color-ref-file))
|
||||
|
||||
;; shadow
|
||||
|
||||
(defn shadow->color
|
||||
[shadow]
|
||||
(:color shadow))
|
||||
|
||||
(defn set-shadow-color
|
||||
[shape position color opacity gradient]
|
||||
(d/update-in-when shape [:shadow position :color]
|
||||
(fn [shadow-color]
|
||||
(-> shadow-color
|
||||
(assoc :color color)
|
||||
(assoc :opacity opacity)
|
||||
(assoc :gradient gradient)
|
||||
(d/without-nils)))))
|
||||
|
||||
(defn attach-shadow-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:shadow position :color]
|
||||
(fn [color]
|
||||
(-> color
|
||||
(assoc :ref-id ref-id)
|
||||
(assoc :ref-file ref-file)))))
|
||||
|
||||
(defn detach-shadow-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:shadow position :color] dissoc :ref-id :ref-file))
|
||||
|
||||
;; grid
|
||||
|
||||
;: FIXME: revisit colors...... WTF
|
||||
(defn grid->color
|
||||
[grid]
|
||||
@@ -291,291 +378,375 @@
|
||||
:ref-id (-> color :id)
|
||||
:ref-file (-> color :file-id)})))
|
||||
|
||||
(defn set-grid-color
|
||||
[shape position color opacity gradient]
|
||||
(d/update-in-when shape [:grids position :params :color]
|
||||
(fn [grid-color]
|
||||
(-> grid-color
|
||||
(assoc :color color)
|
||||
(assoc :opacity opacity)
|
||||
(assoc :gradient gradient)
|
||||
(d/without-nils)))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; HELPERS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn attach-grid-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:grids position :params :color]
|
||||
(fn [color]
|
||||
(-> color
|
||||
(assoc :ref-id ref-id)
|
||||
(assoc :ref-file ref-file)))))
|
||||
(def ^:private hex-color-re
|
||||
#"\#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})")
|
||||
|
||||
(defn detach-grid-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:grids position :params :color] dissoc :ref-id :ref-file))
|
||||
(def ^:private rgb-color-re
|
||||
#"(?:|rgb)\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\)")
|
||||
|
||||
;; --- Helpers for all colors in a shape
|
||||
|
||||
(defn get-text-node-colors
|
||||
"Get all colors used by a node of a text shape"
|
||||
[node]
|
||||
(concat (map fill->color (:fills node))
|
||||
(map stroke->color (:strokes node))))
|
||||
|
||||
(defn get-all-colors
|
||||
"Get all colors used by a shape, in any section."
|
||||
[shape]
|
||||
(concat (map fill->color (:fills shape))
|
||||
(map stroke->color (:strokes shape))
|
||||
(map shadow->color (:shadow shape))
|
||||
(when (= (:type shape) :frame)
|
||||
(map grid->color (:grids shape)))
|
||||
(when (= (:type shape) :text)
|
||||
(reduce (fn [colors node]
|
||||
(concat colors (get-text-node-colors node)))
|
||||
()
|
||||
(txt/node-seq (:content shape))))))
|
||||
|
||||
(defn uses-library-colors?
|
||||
"Check if the shape uses any color in the given library."
|
||||
[shape library-id]
|
||||
(let [all-colors (get-all-colors shape)]
|
||||
(some #(and (some? (:ref-id %))
|
||||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn uses-library-color?
|
||||
"Check if the shape uses the given library color."
|
||||
[shape library-id color-id]
|
||||
(let [all-colors (get-all-colors shape)]
|
||||
(some #(and (= (:ref-id %) color-id)
|
||||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn- process-shape-colors
|
||||
"Execute an update function on all colors of a shape."
|
||||
[shape process-fn]
|
||||
(let [process-fill (fn [shape [position fill]]
|
||||
(process-fn shape
|
||||
position
|
||||
(fill->color fill)
|
||||
set-fill-color
|
||||
attach-fill-color
|
||||
detach-fill-color))
|
||||
|
||||
process-stroke (fn [shape [position stroke]]
|
||||
(process-fn shape
|
||||
position
|
||||
(stroke->color stroke)
|
||||
set-stroke-color
|
||||
attach-stroke-color
|
||||
detach-stroke-color))
|
||||
|
||||
process-shadow (fn [shape [position shadow]]
|
||||
(process-fn shape
|
||||
position
|
||||
(shadow->color shadow)
|
||||
set-shadow-color
|
||||
attach-shadow-color
|
||||
detach-shadow-color))
|
||||
|
||||
process-grid (fn [shape [position grid]]
|
||||
(process-fn shape
|
||||
position
|
||||
(grid->color grid)
|
||||
set-grid-color
|
||||
attach-grid-color
|
||||
detach-grid-color))
|
||||
|
||||
process-text-node (fn [node]
|
||||
(as-> node $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))))
|
||||
|
||||
process-text (fn [shape]
|
||||
(let [content (:content shape)
|
||||
new-content (txt/transform-nodes process-text-node content)]
|
||||
(if (not= content new-content)
|
||||
(assoc shape :content new-content)
|
||||
shape)))]
|
||||
|
||||
(as-> shape $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))
|
||||
(reduce process-shadow $ (d/enumerate (:shadow $)))
|
||||
(reduce process-grid $ (d/enumerate (:grids $)))
|
||||
(process-text $))))
|
||||
|
||||
(defn remap-colors
|
||||
"Change the shape so that any use of the given color now points to
|
||||
the given library."
|
||||
[shape library-id color]
|
||||
(letfn [(remap-color [shape position shape-color _ attach-fn _]
|
||||
(if (= (:ref-id shape-color) (:id color))
|
||||
(attach-fn shape
|
||||
position
|
||||
(:id color)
|
||||
library-id)
|
||||
shape))]
|
||||
|
||||
(process-shape-colors shape remap-color)))
|
||||
|
||||
(defn sync-shape-colors
|
||||
"Look for usage of any color of the given library inside the shape,
|
||||
and, in this case, copy the library color into the shape."
|
||||
[shape library-id library-colors]
|
||||
(letfn [(sync-color [shape position shape-color set-fn _ detach-fn]
|
||||
(if (= (:ref-file shape-color) library-id)
|
||||
(let [library-color (get library-colors (:ref-id shape-color))]
|
||||
(if (some? library-color)
|
||||
(set-fn shape
|
||||
position
|
||||
(:color library-color)
|
||||
(:opacity library-color)
|
||||
(:gradient library-color)
|
||||
(:image library-color))
|
||||
(detach-fn shape position)))
|
||||
shape))]
|
||||
|
||||
(process-shape-colors shape sync-color)))
|
||||
|
||||
(defn- stroke->color-att
|
||||
[stroke file-id libraries]
|
||||
(let [ref-file (:stroke-color-ref-file stroke)
|
||||
ref-id (:stroke-color-ref-id stroke)
|
||||
shared-colors (dm/get-in libraries [ref-file :data :colors])
|
||||
is-shared? (contains? shared-colors ref-id)
|
||||
has-color? (or (:stroke-color stroke)
|
||||
(:stroke-color-gradient stroke))
|
||||
attrs (cond-> (stroke->color stroke)
|
||||
(not (or is-shared? (= ref-file file-id)))
|
||||
(dissoc :ref-id :ref-file))]
|
||||
(when has-color?
|
||||
{:attrs attrs
|
||||
:prop :stroke
|
||||
:shape-id (:shape-id stroke)
|
||||
:index (:index stroke)})))
|
||||
|
||||
(defn- shadow->color-att
|
||||
[shadow file-id libraries]
|
||||
(let [color (get shadow :color)
|
||||
ref-file (get color :ref-file)
|
||||
ref-id (get color :ref-id)
|
||||
shared-colors (dm/get-in libraries [ref-file :data :colors])
|
||||
is-shared? (contains? shared-colors ref-id)
|
||||
attrs (cond-> (shadow->color shadow)
|
||||
(not (or is-shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
{:attrs attrs
|
||||
:prop :shadow
|
||||
:shape-id (:shape-id shadow)
|
||||
:index (:index shadow)}))
|
||||
|
||||
(defn- text->color-att
|
||||
[fill file-id libraries]
|
||||
(let [ref-file (:fill-color-ref-file fill)
|
||||
ref-id (:fill-color-ref-id fill)
|
||||
shared-colors (dm/get-in libraries [ref-file :data :colors])
|
||||
is-shared? (contains? shared-colors ref-id)
|
||||
attrs (cond-> (fill->color fill)
|
||||
(not (or is-shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
|
||||
{: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 libraries]
|
||||
(->> (txt/node-seq txt/is-text-node? (:content text))
|
||||
(map :fills)
|
||||
(mapcat #(treat-node % (:id text)))
|
||||
(map #(text->color-att % file-id libraries))))
|
||||
|
||||
(defn- fill->color-att
|
||||
[fill file-id libraries]
|
||||
(let [ref-file (:fill-color-ref-file fill)
|
||||
ref-id (:fill-color-ref-id fill)
|
||||
shared-colors (dm/get-in libraries [ref-file :data :colors])
|
||||
is-shared? (contains? shared-colors ref-id)
|
||||
has-color? (or (:fill-color fill)
|
||||
(:fill-color-gradient fill))
|
||||
attrs (cond-> (fill->color fill)
|
||||
(not (or is-shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
|
||||
(when has-color?
|
||||
{:attrs attrs
|
||||
:prop :fill
|
||||
:shape-id (:shape-id fill)
|
||||
:index (:index fill)})))
|
||||
|
||||
(defn extract-all-colors
|
||||
[shapes file-id libraries]
|
||||
(reduce
|
||||
(fn [result 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))
|
||||
(-> result
|
||||
(into (map #(stroke->color-att % file-id libraries)) stroke-obj)
|
||||
(into (map #(shadow->color-att % file-id libraries)) shadow-obj)
|
||||
(into (extract-text-colors shape file-id libraries)))
|
||||
|
||||
(-> result
|
||||
(into (map #(fill->color-att % file-id libraries)) fill-obj)
|
||||
(into (map #(stroke->color-att % file-id libraries)) stroke-obj)
|
||||
(into (map #(shadow->color-att % file-id libraries)) shadow-obj)))))
|
||||
[]
|
||||
shapes))
|
||||
|
||||
(defn colors-seq
|
||||
[file-data]
|
||||
(vals (:colors file-data)))
|
||||
|
||||
(defn- touch
|
||||
(defn valid-hex-color?
|
||||
[color]
|
||||
(assoc color :modified-at (dt/now)))
|
||||
(and (string? color)
|
||||
(some? (re-matches hex-color-re color))))
|
||||
|
||||
(defn add-color
|
||||
[file-data color]
|
||||
(update file-data :colors assoc (:id color) (touch color)))
|
||||
(defn parse-rgb
|
||||
[color]
|
||||
(let [result (re-matches rgb-color-re color)]
|
||||
(when (some? result)
|
||||
(let [r (parse-long (nth result 1))
|
||||
g (parse-long (nth result 2))
|
||||
b (parse-long (nth result 3))]
|
||||
(when (and (<= 0 r 255) (<= 0 g 255) (<= 0 b 255))
|
||||
[r g b])))))
|
||||
|
||||
(defn get-color
|
||||
[file-data color-id]
|
||||
(get-in file-data [:colors color-id]))
|
||||
(defn valid-rgb-color?
|
||||
[color]
|
||||
(if (string? color)
|
||||
(let [result (parse-rgb color)]
|
||||
(some? result))
|
||||
false))
|
||||
|
||||
(defn get-ref-color
|
||||
[library-data color]
|
||||
(when (= (:ref-file color) (:id library-data))
|
||||
(get-color library-data (:ref-id color))))
|
||||
(defn- normalize-hex
|
||||
[color]
|
||||
(if (= (count color) 4) ; of the form #RGB
|
||||
(-> color
|
||||
(str/replace #"\#(.)(.)(.)" "#$1$1$2$2$3$3")
|
||||
(str/lower))
|
||||
(str/lower color)))
|
||||
|
||||
(defn set-color
|
||||
[file-data color]
|
||||
(d/assoc-in-when file-data [:colors (:id color)] (touch color)))
|
||||
(defn rgb->str
|
||||
[[r g b a]]
|
||||
(if (some? a)
|
||||
(str/ffmt "rgba(%,%,%,%)" r g b a)
|
||||
(str/ffmt "rgb(%,%,%)" r g b)))
|
||||
|
||||
(defn update-color
|
||||
[file-data color-id f & args]
|
||||
(d/update-in-when file-data [:colors color-id] #(-> (apply f % args)
|
||||
(touch))))
|
||||
(defn rgb->hsv
|
||||
[[red green blue]]
|
||||
(let [max (d/max red green blue)
|
||||
min (d/min red green blue)
|
||||
val max]
|
||||
(if (= min max)
|
||||
[0 0 val]
|
||||
(let [delta (- max min)
|
||||
sat (/ delta max)
|
||||
hue (if (= red max)
|
||||
(/ (- green blue) delta)
|
||||
(if (= green max)
|
||||
(+ 2 (/ (- blue red) delta))
|
||||
(+ 4 (/ (- red green) delta))))
|
||||
hue (* 60 hue)
|
||||
hue (if (< hue 0)
|
||||
(+ hue 360)
|
||||
hue)
|
||||
hue (if (> hue 360)
|
||||
(- hue 360)
|
||||
hue)]
|
||||
[hue sat val]))))
|
||||
|
||||
(defn delete-color
|
||||
[file-data color-id]
|
||||
(update file-data :colors dissoc color-id))
|
||||
(defn hsv->rgb
|
||||
[[h s brightness]]
|
||||
(if (= s 0)
|
||||
[brightness brightness brightness]
|
||||
(let [sextant (int (mth/floor (/ h 60)))
|
||||
remainder (- (/ h 60) sextant)
|
||||
brightness (d/nilv brightness 0)
|
||||
val1 (int (* brightness (- 1 s)))
|
||||
val2 (int (* brightness (- 1 (* s remainder))))
|
||||
val3 (int (* brightness (- 1 (* s (- 1 remainder)))))]
|
||||
(case sextant
|
||||
1 [val2 brightness val1]
|
||||
2 [val1 brightness val3]
|
||||
3 [val1 val2 brightness]
|
||||
4 [val3 val1 brightness]
|
||||
5 [brightness val1 val2]
|
||||
6 [brightness val3 val1]
|
||||
0 [brightness val3 val1]))))
|
||||
|
||||
(defn used-colors-changed-since
|
||||
"Find all usages of any color in the library by the given shape, of colors
|
||||
that have ben modified after the date."
|
||||
[shape library since-date]
|
||||
(->> (get-all-colors shape)
|
||||
(keep #(get-ref-color (:data library) %))
|
||||
(remove #(< (:modified-at %) since-date)) ;; Note that :modified-at may be nil
|
||||
(map (fn [color] {:shape-id (:id shape)
|
||||
:asset-id (:id color)
|
||||
:asset-type :color}))))
|
||||
(defn hex->rgb
|
||||
[color]
|
||||
(try
|
||||
(let [rgb #?(:clj (Integer/parseInt (subs color 1) 16)
|
||||
:cljs (js/parseInt (subs color 1) 16))
|
||||
r (bit-shift-right rgb 16)
|
||||
g (bit-and (bit-shift-right rgb 8) 255)
|
||||
b (bit-and rgb 255)]
|
||||
[r g b])
|
||||
(catch #?(:clj Throwable :cljs :default) _cause
|
||||
[0 0 0])))
|
||||
|
||||
(defn hex->lum
|
||||
[color]
|
||||
(let [[r g b] (hex->rgb color)]
|
||||
(mth/sqrt (+ (* 0.241 r)
|
||||
(* 0.691 g)
|
||||
(* 0.068 b)))))
|
||||
|
||||
(defn- int->hex
|
||||
"Convert integer to hex string"
|
||||
[v]
|
||||
#?(:clj (Integer/toHexString v)
|
||||
:cljs (.toString v 16)))
|
||||
|
||||
(defn rgb->hex
|
||||
[[r g b]]
|
||||
(let [r (int r)
|
||||
g (int g)
|
||||
b (int b)]
|
||||
(if (or (not= r (bit-and r 255))
|
||||
(not= g (bit-and g 255))
|
||||
(not= b (bit-and b 255)))
|
||||
(throw (ex-info "not valid rgb" {:r r :g g :b b}))
|
||||
(let [rgb (bit-or (bit-shift-left r 16)
|
||||
(bit-shift-left g 8) b)]
|
||||
(if (< r 16)
|
||||
(dm/str "#" (subs (int->hex (bit-or 0x1000000 rgb)) 1))
|
||||
(dm/str "#" (int->hex rgb)))))))
|
||||
|
||||
(defn rgb->hsl
|
||||
[[r g b]]
|
||||
(let [norm-r (/ r 255.0)
|
||||
norm-g (/ g 255.0)
|
||||
norm-b (/ b 255.0)
|
||||
max (d/max norm-r norm-g norm-b)
|
||||
min (d/min norm-r norm-g norm-b)
|
||||
l (/ (+ max min) 2.0)
|
||||
h (if (= max min) 0
|
||||
(if (= max norm-r)
|
||||
(* 60 (/ (- norm-g norm-b) (- max min)))
|
||||
(if (= max norm-g)
|
||||
(+ 120 (* 60 (/ (- norm-b norm-r) (- max min))))
|
||||
(+ 240 (* 60 (/ (- norm-r norm-g) (- max min)))))))
|
||||
s (if (and (> l 0) (<= l 0.5))
|
||||
(/ (- max min) (* 2 l))
|
||||
(/ (- max min) (- 2 (* 2 l))))]
|
||||
[(mod (+ h 360) 360) s l]))
|
||||
|
||||
(defn hex->hsv
|
||||
[v]
|
||||
(-> v hex->rgb rgb->hsv))
|
||||
|
||||
(defn hex->rgba
|
||||
[data opacity]
|
||||
(-> (hex->rgb data)
|
||||
(conj opacity)))
|
||||
|
||||
(defn hex->hsl [hex]
|
||||
(try
|
||||
(-> hex hex->rgb rgb->hsl)
|
||||
(catch #?(:clj Throwable :cljs :default) _e
|
||||
[0 0 0])))
|
||||
|
||||
(defn hex->hsla
|
||||
[data opacity]
|
||||
(-> (hex->hsl data)
|
||||
(conj opacity)))
|
||||
|
||||
(defn format-hsla
|
||||
[[h s l a]]
|
||||
(let [precision 2
|
||||
rounded-h (int h)
|
||||
rounded-s (d/format-number (* 100 s) precision)
|
||||
rounded-l (d/format-number (* 100 l) precision)
|
||||
rounded-a (d/format-number a precision)]
|
||||
(str/concat "" rounded-h ", " rounded-s "%, " rounded-l "%, " rounded-a)))
|
||||
|
||||
(defn format-rgba
|
||||
[[r g b a]]
|
||||
(let [precision 2
|
||||
rounded-a (d/format-number a precision)]
|
||||
(str/ffmt "%, %, %, %" r g b rounded-a)))
|
||||
|
||||
(defn- hue->rgb
|
||||
"Helper for hsl->rgb"
|
||||
[v1 v2 vh]
|
||||
(let [vh (if (< vh 0)
|
||||
(+ vh 1)
|
||||
(if (> vh 1)
|
||||
(- vh 1)
|
||||
vh))]
|
||||
(cond
|
||||
(< (* 6 vh) 1) (+ v1 (* (- v2 v1) 6 vh))
|
||||
(< (* 2 vh) 1) v2
|
||||
(< (* 3 vh) 2) (+ v1 (* (- v2 v1) (- (/ 2 3) vh) 6))
|
||||
:else v1)))
|
||||
|
||||
(defn hsl->rgb
|
||||
[[h s l]]
|
||||
(if (= s 0)
|
||||
(let [o (* l 255)]
|
||||
[o o o])
|
||||
(let [norm-h (/ h 360.0)
|
||||
temp2 (if (< l 0.5)
|
||||
(* l (+ 1 s))
|
||||
(- (+ l s)
|
||||
(* s l)))
|
||||
temp1 (- (* l 2) temp2)]
|
||||
|
||||
[(mth/round (* 255 (hue->rgb temp1 temp2 (+ norm-h (/ 1 3)))))
|
||||
(mth/round (* 255 (hue->rgb temp1 temp2 norm-h)))
|
||||
(mth/round (* 255 (hue->rgb temp1 temp2 (- norm-h (/ 1 3)))))])))
|
||||
|
||||
(defn hsl->hex
|
||||
[v]
|
||||
(-> v hsl->rgb rgb->hex))
|
||||
|
||||
(defn hsl->hsv
|
||||
[hsl]
|
||||
(-> hsl hsl->rgb rgb->hsv))
|
||||
|
||||
(defn hsv->hex
|
||||
[hsv]
|
||||
(-> hsv hsv->rgb rgb->hex))
|
||||
|
||||
(defn hsv->hsl
|
||||
[hsv]
|
||||
(-> hsv hsv->hex hex->hsl))
|
||||
|
||||
(defn expand-hex
|
||||
[v]
|
||||
(cond
|
||||
(re-matches #"^[0-9A-Fa-f]$" v)
|
||||
(dm/str v v v v v v)
|
||||
|
||||
(re-matches #"^[0-9A-Fa-f]{2}$" v)
|
||||
(dm/str v v v)
|
||||
|
||||
(re-matches #"^[0-9A-Fa-f]{3}$" v)
|
||||
(let [a (nth v 0)
|
||||
b (nth v 1)
|
||||
c (nth v 2)]
|
||||
(dm/str a a b b c c))
|
||||
|
||||
:else
|
||||
v))
|
||||
|
||||
(defn prepend-hash
|
||||
[color]
|
||||
(if (= "#" (subs color 0 1))
|
||||
color
|
||||
(dm/str "#" color)))
|
||||
|
||||
(defn remove-hash
|
||||
[color]
|
||||
(if (str/starts-with? color "#")
|
||||
(subs color 1)
|
||||
color))
|
||||
|
||||
(defn color-string?
|
||||
[color]
|
||||
(and (string? color)
|
||||
(or (valid-hex-color? color)
|
||||
(valid-rgb-color? color)
|
||||
(contains? names color))))
|
||||
|
||||
(defn parse
|
||||
[color]
|
||||
(when (string? color)
|
||||
(if (or (valid-hex-color? color)
|
||||
(valid-hex-color? (dm/str "#" color)))
|
||||
(normalize-hex color)
|
||||
(or (some-> (parse-rgb color) (rgb->hex))
|
||||
(get names (str/lower color))))))
|
||||
|
||||
(def color-names
|
||||
(into [] (keys names)))
|
||||
|
||||
(def empty-color
|
||||
(into {} (map #(vector % nil)) [:color :id :file-id :gradient :opacity]))
|
||||
|
||||
(defn next-rgb
|
||||
"Given a color in rgb returns the next color"
|
||||
[[r g b]]
|
||||
(cond
|
||||
(and (= 255 r) (= 255 g) (= 255 b))
|
||||
(throw (ex-info "cannot get next color" {:r r :g g :b b}))
|
||||
|
||||
(and (= 255 g) (= 255 b))
|
||||
[(inc r) 0 0]
|
||||
|
||||
(= 255 b)
|
||||
[r (inc g) 0]
|
||||
|
||||
:else
|
||||
[r g (inc b)]))
|
||||
|
||||
(defn reduce-range
|
||||
[value range]
|
||||
(/ (mth/floor (* value range)) range))
|
||||
|
||||
(defn sort-colors
|
||||
[a b]
|
||||
(let [[ah _ av] (hex->hsv (:color a))
|
||||
[bh _ bv] (hex->hsv (:color b))
|
||||
ah (reduce-range (/ ah 60) 8)
|
||||
bh (reduce-range (/ bh 60) 8)
|
||||
av (/ av 255)
|
||||
bv (/ bv 255)
|
||||
a (+ (* ah 100) (* av 10))
|
||||
b (+ (* bh 100) (* bv 10))]
|
||||
(compare a b)))
|
||||
|
||||
(defn interpolate-color
|
||||
[c1 c2 offset]
|
||||
(cond
|
||||
(<= offset (:offset c1)) (assoc c1 :offset offset)
|
||||
(>= offset (:offset c2)) (assoc c2 :offset offset)
|
||||
|
||||
:else
|
||||
(let [tr-offset (/ (- offset (:offset c1)) (- (:offset c2) (:offset c1)))
|
||||
[r1 g1 b1] (hex->rgb (:color c1))
|
||||
[r2 g2 b2] (hex->rgb (:color c2))
|
||||
a1 (:opacity c1)
|
||||
a2 (:opacity c2)
|
||||
r (+ r1 (* (- r2 r1) tr-offset))
|
||||
g (+ g1 (* (- g2 g1) tr-offset))
|
||||
b (+ b1 (* (- b2 b1) tr-offset))
|
||||
a (+ a1 (* (- a2 a1) tr-offset))]
|
||||
{:color (rgb->hex [r g b])
|
||||
:opacity a
|
||||
:r r
|
||||
:g g
|
||||
:b b
|
||||
:alpha a
|
||||
:offset offset})))
|
||||
|
||||
(defn- offset-spread
|
||||
[from to num]
|
||||
(->> (range 0 num)
|
||||
(map #(mth/precision (+ from (* (/ (- to from) (dec num)) %)) 2))))
|
||||
|
||||
(defn uniform-spread?
|
||||
"Checks if the gradient stops are spread uniformly"
|
||||
[stops]
|
||||
(let [cs (count stops)
|
||||
from (first stops)
|
||||
to (last stops)
|
||||
expect-vals (offset-spread (:offset from) (:offset to) cs)
|
||||
|
||||
calculate-expected
|
||||
(fn [expected-offset stop]
|
||||
(and (mth/close? (:offset stop) expected-offset)
|
||||
(let [ec (interpolate-color from to expected-offset)]
|
||||
(and (= (:color ec) (:color stop))
|
||||
(= (:opacity ec) (:opacity stop))))))]
|
||||
(->> (map calculate-expected expect-vals stops)
|
||||
(every? true?))))
|
||||
|
||||
(defn uniform-spread
|
||||
"Assign an uniform spread to the offset values for the gradient"
|
||||
[from to num-stops]
|
||||
(->> (offset-spread (:offset from) (:offset to) num-stops)
|
||||
(mapv (fn [offset]
|
||||
(interpolate-color from to offset)))))
|
||||
|
||||
(defn interpolate-gradient
|
||||
[stops offset]
|
||||
(let [idx (d/index-of-pred stops #(<= offset (:offset %)))
|
||||
start (if (= idx 0) (first stops) (get stops (dec idx)))
|
||||
end (if (nil? idx) (last stops) (get stops idx))]
|
||||
(interpolate-color start end offset)))
|
||||
|
||||
|
||||
@@ -16,15 +16,17 @@
|
||||
[app.common.geom.shapes.tree-seq :as gsts]
|
||||
[app.common.logging :as l]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as ct]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.library :as ctlb]
|
||||
[app.common.types.page :as ctp]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.plugins :refer [schema:plugin-data]]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.tokens-lib :refer [schema:tokens-lib]]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.types.typography :as cty]
|
||||
@@ -521,7 +523,7 @@
|
||||
|
||||
(defmethod uses-asset? :color
|
||||
[_ shape library-id color]
|
||||
(ctc/uses-library-color? shape library-id (:id color)))
|
||||
(cts/uses-library-color? shape library-id (:id color)))
|
||||
|
||||
(defmethod uses-asset? :typography
|
||||
[_ shape library-id typography]
|
||||
@@ -533,10 +535,10 @@
|
||||
|
||||
Returns a list ((asset ((container shapes) (container shapes)...))...)"
|
||||
[file-data library-data asset-type]
|
||||
(let [assets-seq (case asset-type
|
||||
:component (ctkl/components-seq library-data)
|
||||
:color (ctc/colors-seq library-data)
|
||||
:typography (ctyl/typographies-seq library-data))
|
||||
(let [assets (case asset-type
|
||||
:component (ctkl/components-seq library-data)
|
||||
:color (vals (ctlb/get-colors library-data))
|
||||
:typography (ctyl/typographies-seq library-data))
|
||||
|
||||
find-usages-in-container
|
||||
(fn [container asset]
|
||||
@@ -553,7 +555,7 @@
|
||||
(let [instances (find-asset-usages file-data asset)]
|
||||
(when (d/not-empty? instances)
|
||||
[[asset instances]])))
|
||||
assets-seq)))
|
||||
assets)))
|
||||
|
||||
(defn used-in?
|
||||
"Checks if a specific asset is used in a given file (by any shape in its pages or in
|
||||
@@ -574,7 +576,7 @@
|
||||
(letfn [(used-assets-shape [shape]
|
||||
(concat
|
||||
(ctkl/used-components-changed-since shape library since-date)
|
||||
(ctc/used-colors-changed-since shape library since-date)
|
||||
(ctlb/used-colors-changed-since shape library since-date)
|
||||
(ctyl/used-typographies-changed-since shape library since-date)))
|
||||
|
||||
(used-assets-container [container]
|
||||
@@ -693,11 +695,12 @@
|
||||
|
||||
(add-component-grid file-data (sort-by #(:name (first %)) used-components))))
|
||||
|
||||
;: FIXME: this can be moved to library
|
||||
(defn- absorb-colors
|
||||
[file-data used-colors]
|
||||
(let [absorb-color
|
||||
(fn [file-data [color usages]]
|
||||
(let [remap-shape #(ctc/remap-colors % (:id file-data) color)
|
||||
(let [remap-shape #(cts/remap-colors % (:id file-data) color)
|
||||
|
||||
remap-shapes
|
||||
(fn [file-data [container shapes]]
|
||||
@@ -710,7 +713,7 @@
|
||||
%
|
||||
shapes)))]
|
||||
(as-> file-data $
|
||||
(ctc/add-color $ color)
|
||||
(ctlb/add-color $ color)
|
||||
(reduce remap-shapes $ usages))))]
|
||||
|
||||
(reduce absorb-color
|
||||
@@ -1046,7 +1049,7 @@
|
||||
(let [detach-text
|
||||
(fn [content]
|
||||
(->> content
|
||||
(ct/transform-nodes
|
||||
(txt/transform-nodes
|
||||
#(cond-> %
|
||||
(not= file-id (:fill-color-ref-file %))
|
||||
(dissoc :fill-color-ref-id :fill-color-ref-file)
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.common.types.fills
|
||||
(:refer-clojure :exclude [assoc update])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.flags :as flags]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.fills.impl :as impl]
|
||||
[clojure.core :as c]
|
||||
[clojure.set :as set]))
|
||||
|
||||
(def ^:const MAX-GRADIENT-STOPS impl/MAX-GRADIENT-STOPS)
|
||||
@@ -85,12 +89,13 @@
|
||||
;; HELPERS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; FIXME: duplicated of `assoc`
|
||||
(defn assoc-fill
|
||||
[fills position fill]
|
||||
(if (nil? fills)
|
||||
(impl/from-plain [fill])
|
||||
(-> (coerce fills)
|
||||
(assoc position fill))))
|
||||
(c/assoc position fill))))
|
||||
|
||||
(defn get-image-ids
|
||||
[fills]
|
||||
@@ -108,3 +113,52 @@
|
||||
(defn write-to
|
||||
[fills buffer offset]
|
||||
(impl/-write-to fills buffer offset))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; TRANSFORMATION & CREATION HELPERS
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn assoc
|
||||
[fills position fill]
|
||||
(if (contains? flags/*current* :frontend-binary-fills)
|
||||
(if (nil? fills)
|
||||
(impl/from-plain [fill])
|
||||
(-> (coerce fills)
|
||||
(c/assoc position fill)))
|
||||
(if (nil? fills)
|
||||
[fill]
|
||||
(-> (coerce fills)
|
||||
(c/assoc position fill)))))
|
||||
|
||||
(defn update
|
||||
[fills f & args]
|
||||
(let [fills (vec fills)
|
||||
fills (apply f fills args)]
|
||||
(if (contains? flags/*current* :frontend-binary-fills)
|
||||
(impl/from-plain fills)
|
||||
fills)))
|
||||
|
||||
(defn create
|
||||
[& elements]
|
||||
(let [fills (vec elements)]
|
||||
(if (contains? flags/*current* :frontend-binary-fills)
|
||||
(impl/from-plain fills)
|
||||
fills)))
|
||||
|
||||
(defn prepend
|
||||
"Prepend a fill to existing fills"
|
||||
[fills fill]
|
||||
(let [fills (into [fill] fills)]
|
||||
(if (contains? flags/*current* :frontend-binary-fills)
|
||||
(impl/from-plain fills)
|
||||
fills)))
|
||||
|
||||
(defn fill->color
|
||||
[fill]
|
||||
(d/without-nils
|
||||
{:color (:fill-color fill)
|
||||
:opacity (:fill-opacity fill)
|
||||
:gradient (:fill-color-gradient fill)
|
||||
:image (:fill-image fill)
|
||||
:ref-id (:fill-color-ref-id fill)
|
||||
:ref-file (:fill-color-ref-file fill)}))
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
(ns app.common.types.grid
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :refer [schema:hex-color]]))
|
||||
[app.common.types.color :as clr]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; SCHEMA
|
||||
@@ -16,7 +15,7 @@
|
||||
|
||||
(def schema:grid-color
|
||||
[:map {:title "PageGridColor"}
|
||||
[:color schema:hex-color]
|
||||
[:color clr/schema:hex-color]
|
||||
[:opacity ::sm/safe-number]])
|
||||
|
||||
(def schema:column-params
|
||||
|
||||
87
common/src/app/common/types/library.cljc
Normal file
87
common/src/app/common/types/library.cljc
Normal file
@@ -0,0 +1,87 @@
|
||||
;; 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.common.types.library
|
||||
"Exposes file library type data helpers.
|
||||
|
||||
WARNING: It belongs to FILE types in hierarchy of types so: file
|
||||
types can import this ns but, but this ns can't import file types."
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.time :as dt]
|
||||
[app.common.types.shape :as types.shape]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; COLOR LIBRARY
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn get-colors
|
||||
[file-data]
|
||||
(:colors file-data))
|
||||
|
||||
(defn get-color
|
||||
[file-data color-id]
|
||||
(dm/get-in file-data [:colors color-id]))
|
||||
|
||||
(defn get-ref-color
|
||||
[library-data color]
|
||||
(when (= (:ref-file color) (:id library-data))
|
||||
(get-color library-data (:ref-id color))))
|
||||
|
||||
(defn- touch
|
||||
[color]
|
||||
(assoc color :modified-at (dt/now)))
|
||||
|
||||
(defn add-color
|
||||
[file-data color]
|
||||
(update file-data :colors assoc (:id color) (touch color)))
|
||||
|
||||
(defn set-color
|
||||
[file-data color]
|
||||
(d/assoc-in-when file-data [:colors (:id color)] (touch color)))
|
||||
|
||||
(defn update-color
|
||||
[file-data color-id f & args]
|
||||
(d/update-in-when file-data [:colors color-id] #(-> (apply f % args)
|
||||
(touch))))
|
||||
(defn delete-color
|
||||
[file-data color-id]
|
||||
(update file-data :colors dissoc color-id))
|
||||
|
||||
(defn used-colors-changed-since
|
||||
"Find all usages of any color in the library by the given shape, of colors
|
||||
that have ben modified after the date."
|
||||
[shape library since-date]
|
||||
(->> (types.shape/get-all-colors shape)
|
||||
(keep #(get-ref-color (:data library) %))
|
||||
(remove #(< (:modified-at %) since-date)) ;; Note that :modified-at may be nil
|
||||
(map (fn [color]
|
||||
{:shape-id (:id shape)
|
||||
:asset-id (:id color)
|
||||
:asset-type :color}))))
|
||||
|
||||
;: FIXME: revisit the API of this, i think we should pass the whole
|
||||
;; library data here instead of only colors
|
||||
(defn sync-colors
|
||||
"Look for usage of any color of the given library inside the shape,
|
||||
and, in this case, copy the library color into the shape."
|
||||
[shape library-id library-colors]
|
||||
(letfn [(sync-color [shape position shape-color set-fn _ detach-fn]
|
||||
(if (= (:ref-file shape-color) library-id)
|
||||
(let [library-color (get library-colors (:ref-id shape-color))]
|
||||
(if (some? library-color)
|
||||
(set-fn shape
|
||||
position
|
||||
(:color library-color)
|
||||
(:opacity library-color)
|
||||
(:gradient library-color)
|
||||
(:image library-color))
|
||||
(detach-fn shape position)))
|
||||
shape))]
|
||||
|
||||
(types.shape/process-shape-colors shape sync-color)))
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
[app.common.geom.shapes.effects :as gse]
|
||||
[app.common.geom.shapes.strokes :as gss]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.text :as txt]
|
||||
[clojure.core :as c]))
|
||||
|
||||
;; --- Modifiers
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
(ns app.common.types.path.bool
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.path.helpers :as helpers]
|
||||
[app.common.types.path.segment :as segment]
|
||||
[app.common.types.path.subpath :as subpath]))
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
(ns app.common.types.shape
|
||||
(:require
|
||||
#?(:clj [app.common.fressian :as fres])
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
@@ -18,10 +17,9 @@
|
||||
[app.common.record :as cr]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.schema.generators :as sg]
|
||||
[app.common.text :as txt]
|
||||
[app.common.transit :as t]
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.fills :refer [schema:fill]]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.fills :refer [schema:fill fill->color]]
|
||||
[app.common.types.grid :as ctg]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.path.segment :as path.segment]
|
||||
@@ -33,6 +31,7 @@
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.shape.shadow :as ctss]
|
||||
[app.common.types.shape.text :as ctsx]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.token :as cto]
|
||||
[app.common.types.variant :as ctv]
|
||||
[app.common.uuid :as uuid]
|
||||
@@ -148,9 +147,9 @@
|
||||
[::sm/one-of stroke-caps]]
|
||||
[:stroke-cap-end {:optional true}
|
||||
[::sm/one-of stroke-caps]]
|
||||
[:stroke-color {:optional true} types.color/schema:hex-color]
|
||||
[:stroke-color-gradient {:optional true} types.color/schema:gradient]
|
||||
[:stroke-image {:optional true} types.color/schema:image]])
|
||||
[:stroke-color {:optional true} clr/schema:hex-color]
|
||||
[:stroke-color-gradient {:optional true} clr/schema:gradient]
|
||||
[:stroke-image {:optional true} clr/schema:image]])
|
||||
|
||||
(def stroke-attrs
|
||||
"A set of attrs that corresponds to stroke data type"
|
||||
@@ -755,3 +754,201 @@
|
||||
(d/patch-object (select-keys props basic-extract-props))
|
||||
(cond-> (cfh/text-shape? shape) (patch-text-props props))
|
||||
(cond-> (cfh/frame-shape? shape) (patch-layout-props props)))))
|
||||
|
||||
|
||||
|
||||
(defn- set-fill-color
|
||||
[shape position color opacity gradient image]
|
||||
(update-in shape [:fills position]
|
||||
(fn [fill]
|
||||
(d/without-nils (assoc fill
|
||||
:fill-color color
|
||||
:fill-opacity opacity
|
||||
:fill-color-gradient gradient
|
||||
:fill-image image)))))
|
||||
|
||||
|
||||
(defn- attach-fill-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:fills position]
|
||||
(fn [fill]
|
||||
(-> fill
|
||||
(assoc :fill-color-ref-file ref-file)
|
||||
(assoc :fill-color-ref-id ref-id)))))
|
||||
|
||||
(defn- detach-fill-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:fills position] dissoc :fill-color-ref-id :fill-color-ref-file))
|
||||
|
||||
|
||||
(defn- set-stroke-color
|
||||
[shape position color opacity gradient image]
|
||||
(d/update-in-when shape [:strokes position]
|
||||
(fn [stroke]
|
||||
(-> stroke
|
||||
(assoc :stroke-color color)
|
||||
(assoc :stroke-opacity opacity)
|
||||
(assoc :stroke-color-gradient gradient)
|
||||
(assoc :stroke-image image)
|
||||
(d/without-nils)))))
|
||||
|
||||
(defn- attach-stroke-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:strokes position]
|
||||
(fn [stroke]
|
||||
(-> stroke
|
||||
(assoc :stroke-color-ref-id ref-id)
|
||||
(assoc :stroke-color-ref-file ref-file)))))
|
||||
|
||||
(defn- detach-stroke-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:strokes position] dissoc :stroke-color-ref-id :stroke-color-ref-file))
|
||||
|
||||
(defn- set-shadow-color
|
||||
[shape position color opacity gradient]
|
||||
(d/update-in-when shape [:shadow position :color]
|
||||
(fn [shadow-color]
|
||||
(-> shadow-color
|
||||
(assoc :color color)
|
||||
(assoc :opacity opacity)
|
||||
(assoc :gradient gradient)
|
||||
(d/without-nils)))))
|
||||
|
||||
(defn- attach-shadow-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:shadow position :color]
|
||||
(fn [color]
|
||||
(-> color
|
||||
(assoc :ref-id ref-id)
|
||||
(assoc :ref-file ref-file)))))
|
||||
|
||||
(defn- detach-shadow-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:shadow position :color] dissoc :ref-id :ref-file))
|
||||
|
||||
(defn- set-grid-color
|
||||
[shape position color opacity gradient]
|
||||
(d/update-in-when shape [:grids position :params :color]
|
||||
(fn [grid-color]
|
||||
(-> grid-color
|
||||
(assoc :color color)
|
||||
(assoc :opacity opacity)
|
||||
(assoc :gradient gradient)
|
||||
(d/without-nils)))))
|
||||
|
||||
(defn- attach-grid-color
|
||||
[shape position ref-id ref-file]
|
||||
(d/update-in-when shape [:grids position :params :color]
|
||||
(fn [color]
|
||||
(-> color
|
||||
(assoc :ref-id ref-id)
|
||||
(assoc :ref-file ref-file)))))
|
||||
|
||||
(defn- detach-grid-color
|
||||
[shape position]
|
||||
(d/update-in-when shape [:grids position :params :color] dissoc :ref-id :ref-file))
|
||||
|
||||
(defn process-shape-colors
|
||||
"Execute an update function on all colors of a shape."
|
||||
[shape process-fn]
|
||||
(let [process-fill (fn [shape [position fill]]
|
||||
(process-fn shape
|
||||
position
|
||||
(fill->color fill)
|
||||
set-fill-color
|
||||
attach-fill-color
|
||||
detach-fill-color))
|
||||
|
||||
process-stroke (fn [shape [position stroke]]
|
||||
(process-fn shape
|
||||
position
|
||||
(clr/stroke->color stroke)
|
||||
set-stroke-color
|
||||
attach-stroke-color
|
||||
detach-stroke-color))
|
||||
|
||||
process-shadow (fn [shape [position shadow]]
|
||||
(process-fn shape
|
||||
position
|
||||
(clr/shadow->color shadow)
|
||||
set-shadow-color
|
||||
attach-shadow-color
|
||||
detach-shadow-color))
|
||||
|
||||
process-grid (fn [shape [position grid]]
|
||||
(process-fn shape
|
||||
position
|
||||
(clr/grid->color grid)
|
||||
set-grid-color
|
||||
attach-grid-color
|
||||
detach-grid-color))
|
||||
|
||||
process-text-node (fn [node]
|
||||
(as-> node $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))))
|
||||
|
||||
process-text (fn [shape]
|
||||
(let [content (:content shape)
|
||||
new-content (txt/transform-nodes process-text-node content)]
|
||||
(if (not= content new-content)
|
||||
(assoc shape :content new-content)
|
||||
shape)))]
|
||||
|
||||
(as-> shape $
|
||||
(reduce process-fill $ (d/enumerate (:fills $)))
|
||||
(reduce process-stroke $ (d/enumerate (:strokes $)))
|
||||
(reduce process-shadow $ (d/enumerate (:shadow $)))
|
||||
(reduce process-grid $ (d/enumerate (:grids $)))
|
||||
(process-text $))))
|
||||
|
||||
(defn- get-text-node-colors
|
||||
"Get all colors used by a node of a text shape"
|
||||
[node]
|
||||
(concat (map fill->color (:fills node))
|
||||
(map clr/stroke->color (:strokes node))))
|
||||
|
||||
(defn get-all-colors
|
||||
"Get all colors used by a shape, in any section."
|
||||
[shape]
|
||||
;; FIXME: all this functions should be really in color?
|
||||
(concat (map fill->color (:fills shape))
|
||||
(map clr/stroke->color (:strokes shape))
|
||||
(map clr/shadow->color (:shadow shape))
|
||||
(when (= (:type shape) :frame)
|
||||
(map clr/grid->color (:grids shape)))
|
||||
(when (= (:type shape) :text)
|
||||
(reduce (fn [colors node]
|
||||
(concat colors (get-text-node-colors node)))
|
||||
()
|
||||
(txt/node-seq (:content shape))))))
|
||||
|
||||
(defn uses-library-color?
|
||||
"Check if the shape uses the given library color."
|
||||
[shape library-id color-id]
|
||||
(let [all-colors (get-all-colors shape)]
|
||||
(some #(and (= (:ref-id %) color-id)
|
||||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn uses-library-colors?
|
||||
"Check if the shape uses any color in the given library."
|
||||
[shape library-id]
|
||||
(let [all-colors (get-all-colors shape)]
|
||||
(some #(and (some? (:ref-id %))
|
||||
(= (:ref-file %) library-id))
|
||||
all-colors)))
|
||||
|
||||
(defn remap-colors
|
||||
"Change the shape so that any use of the given color now points to
|
||||
the given library."
|
||||
[shape library-id color]
|
||||
(letfn [(remap-color [shape position shape-color _ attach-fn _]
|
||||
(if (= (:ref-id shape-color) (:id color))
|
||||
(attach-fn shape
|
||||
position
|
||||
(:id color)
|
||||
library-id)
|
||||
shape))]
|
||||
|
||||
(process-shape-colors shape remap-color)))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
(ns app.common.types.shape.attrs
|
||||
(:require
|
||||
[app.common.colors :as clr]))
|
||||
[app.common.types.color :as clr]))
|
||||
|
||||
(def default-color clr/gray-20)
|
||||
|
||||
|
||||
@@ -6,8 +6,180 @@
|
||||
|
||||
(ns app.common.types.text
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[clojure.set :as set]))
|
||||
[app.common.types.color :as clr]
|
||||
[clojure.set :as set]
|
||||
[clojure.walk :as walk]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
;; -- Attrs
|
||||
|
||||
(def text-typography-attrs
|
||||
[:typography-ref-id
|
||||
:typography-ref-file])
|
||||
|
||||
(def text-fill-attrs
|
||||
[:fill-color
|
||||
:fill-opacity
|
||||
:fill-color-ref-id
|
||||
:fill-color-ref-file
|
||||
:fill-color-gradient])
|
||||
|
||||
(def text-font-attrs
|
||||
[:font-id
|
||||
:font-family
|
||||
:font-variant-id
|
||||
:font-size
|
||||
:font-weight
|
||||
:font-style])
|
||||
|
||||
(def text-align-attrs
|
||||
[:text-align])
|
||||
|
||||
(def text-direction-attrs
|
||||
[:text-direction])
|
||||
|
||||
(def text-spacing-attrs
|
||||
[:line-height
|
||||
:letter-spacing])
|
||||
|
||||
(def text-valign-attrs
|
||||
[:vertical-align])
|
||||
|
||||
(def text-decoration-attrs
|
||||
[:text-decoration])
|
||||
|
||||
(def text-transform-attrs
|
||||
[:text-transform])
|
||||
|
||||
(def text-fills
|
||||
[:fills])
|
||||
|
||||
(def shape-attrs
|
||||
[:grow-type])
|
||||
|
||||
(def root-attrs
|
||||
text-valign-attrs)
|
||||
|
||||
(def paragraph-attrs
|
||||
(d/concat-vec
|
||||
text-align-attrs
|
||||
text-direction-attrs))
|
||||
|
||||
(def text-node-attrs
|
||||
(d/concat-vec
|
||||
text-typography-attrs
|
||||
text-font-attrs
|
||||
text-spacing-attrs
|
||||
text-decoration-attrs
|
||||
text-transform-attrs
|
||||
text-fills))
|
||||
|
||||
(def text-all-attrs (d/concat-set shape-attrs root-attrs paragraph-attrs text-node-attrs))
|
||||
|
||||
(def text-style-attrs
|
||||
(d/concat-vec root-attrs paragraph-attrs text-node-attrs))
|
||||
|
||||
(def default-root-attrs
|
||||
{:vertical-align "top"})
|
||||
|
||||
(def default-text-attrs
|
||||
{:typography-ref-file nil
|
||||
:typography-ref-id nil
|
||||
:font-id "sourcesanspro"
|
||||
:font-family "sourcesanspro"
|
||||
:font-variant-id "regular"
|
||||
:font-size "14"
|
||||
:font-weight "400"
|
||||
:font-style "normal"
|
||||
:line-height "1.2"
|
||||
:letter-spacing "0"
|
||||
:text-transform "none"
|
||||
:text-align "left"
|
||||
:text-decoration "none"
|
||||
:text-direction "ltr"
|
||||
:fills [{:fill-color clr/black
|
||||
:fill-opacity 1}]})
|
||||
|
||||
(def default-attrs
|
||||
(merge default-root-attrs default-text-attrs))
|
||||
|
||||
(def typography-fields
|
||||
[:font-id
|
||||
:font-family
|
||||
:font-variant-id
|
||||
:font-size
|
||||
:font-weight
|
||||
:font-style
|
||||
:line-height
|
||||
:letter-spacing
|
||||
:text-transform])
|
||||
|
||||
(def default-typography
|
||||
(merge
|
||||
{:name "Source Sans Pro Regular"}
|
||||
(select-keys default-text-attrs typography-fields)))
|
||||
|
||||
(defn node-seq
|
||||
([root] (node-seq identity root))
|
||||
([match? root]
|
||||
(->> (tree-seq map? :children root)
|
||||
(filter match?)
|
||||
(seq))))
|
||||
|
||||
(defn is-text-node?
|
||||
[node]
|
||||
(and (nil? (:type node))
|
||||
(string? (:text node))))
|
||||
|
||||
(defn is-paragraph-set-node?
|
||||
[node]
|
||||
(= "paragraph-set" (:type node)))
|
||||
|
||||
(defn is-paragraph-node?
|
||||
[node]
|
||||
(= "paragraph" (:type node)))
|
||||
|
||||
(defn is-root-node?
|
||||
[node]
|
||||
(= "root" (:type node)))
|
||||
|
||||
(defn is-node?
|
||||
[node]
|
||||
(or ^boolean (is-text-node? node)
|
||||
^boolean (is-paragraph-node? node)
|
||||
^boolean (is-paragraph-set-node? node)
|
||||
^boolean (is-root-node? node)))
|
||||
|
||||
(defn is-content-node?
|
||||
"Only matches content nodes, ignoring the paragraph-set nodes."
|
||||
[node]
|
||||
(or ^boolean (is-text-node? node)
|
||||
^boolean (is-paragraph-node? node)
|
||||
^boolean (is-root-node? node)))
|
||||
|
||||
(defn transform-nodes
|
||||
([transform root]
|
||||
(transform-nodes identity transform root))
|
||||
([pred transform root]
|
||||
(walk/postwalk
|
||||
(fn [item]
|
||||
(if (and (is-node? item) (pred item))
|
||||
(transform item)
|
||||
item))
|
||||
root)))
|
||||
|
||||
(defn update-text-content
|
||||
[shape pred-fn update-fn attrs]
|
||||
(let [update-attrs-fn #(update-fn % attrs)
|
||||
transform #(transform-nodes pred-fn update-attrs-fn %)]
|
||||
(-> shape
|
||||
(update :content transform))))
|
||||
|
||||
(defn generate-shape-name
|
||||
[text]
|
||||
(subs text 0 (min 280 (count text))))
|
||||
|
||||
(defn- compare-text-content
|
||||
"Given two content text structures, conformed by maps and vectors,
|
||||
@@ -158,3 +330,91 @@
|
||||
(if (= :children k)
|
||||
[k (vec (map #(copy-attrs-keys %1 attrs) v))]
|
||||
[k (get attrs k v)]))))
|
||||
|
||||
|
||||
(defn content->text
|
||||
"Given a root node of a text content extracts the texts with its associated styles"
|
||||
[content]
|
||||
(letfn [(add-node [acc node]
|
||||
(cond
|
||||
(is-paragraph-node? node)
|
||||
(conj acc [])
|
||||
|
||||
(is-text-node? node)
|
||||
(let [i (dec (count acc))]
|
||||
(update acc i conj (:text node)))
|
||||
|
||||
:else
|
||||
acc))]
|
||||
(->> (node-seq content)
|
||||
(reduce add-node [])
|
||||
(map #(str/join "" %))
|
||||
(str/join "\n"))))
|
||||
|
||||
(defn content->text+styles
|
||||
"Given a root node of a text content extracts the texts with its associated styles"
|
||||
[node]
|
||||
(letfn
|
||||
[(rec-style-text-map [acc node style]
|
||||
(let [node-style (merge style (select-keys node text-all-attrs))
|
||||
head (or (-> acc first) [{} ""])
|
||||
[head-style head-text] head
|
||||
|
||||
new-acc
|
||||
(cond
|
||||
(not (is-text-node? node))
|
||||
(reduce #(rec-style-text-map %1 %2 node-style) acc (:children node))
|
||||
|
||||
(not= head-style node-style)
|
||||
(cons [node-style (:text node "")] acc)
|
||||
|
||||
:else
|
||||
(cons [node-style (dm/str head-text "" (:text node))] (rest acc)))
|
||||
|
||||
;; We add an end-of-line when finish a paragraph
|
||||
new-acc
|
||||
(if (= (:type node) "paragraph")
|
||||
(let [[hs ht] (first new-acc)]
|
||||
(cons [hs (dm/str ht "\n")] (rest new-acc)))
|
||||
new-acc)]
|
||||
new-acc))]
|
||||
|
||||
(-> (rec-style-text-map [] node {})
|
||||
reverse)))
|
||||
|
||||
(defn change-text
|
||||
"Changes the content of the text shape to use the text as argument. Will use the styles of the
|
||||
first paragraph and text that is present in the shape (and override the rest)"
|
||||
[content text]
|
||||
(let [root-styles (select-keys content root-attrs)
|
||||
|
||||
paragraph-style
|
||||
(merge
|
||||
default-text-attrs
|
||||
(select-keys (->> content (node-seq is-paragraph-node?) first) text-all-attrs))
|
||||
|
||||
text-style
|
||||
(merge
|
||||
default-text-attrs
|
||||
(select-keys (->> content (node-seq is-text-node?) first) text-all-attrs))
|
||||
|
||||
paragraph-texts
|
||||
(str/split text "\n")
|
||||
|
||||
paragraphs
|
||||
(->> paragraph-texts
|
||||
(mapv
|
||||
(fn [pt]
|
||||
(merge
|
||||
paragraph-style
|
||||
{:type "paragraph"
|
||||
:children [(merge {:text pt} text-style)]}))))]
|
||||
|
||||
|
||||
(d/patch-object
|
||||
{:type "root"
|
||||
:children
|
||||
[{:type "paragraph-set"
|
||||
:children paragraphs}]}
|
||||
root-styles)))
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
(ns app.common.types.typographies-list
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.time :as dt]))
|
||||
[app.common.time :as dt]
|
||||
[app.common.types.text :as txt]))
|
||||
|
||||
(defn typographies-seq
|
||||
[file-data]
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.plugins :as ctpg]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
@@ -59,6 +59,8 @@
|
||||
:text-transform (or text-transform "none")}
|
||||
(d/without-nils)))
|
||||
|
||||
|
||||
;; FIXME: this function should not be here it belongs to shape and not typography
|
||||
(defn uses-library-typographies?
|
||||
"Check if the shape uses any typography in the given library."
|
||||
[shape library-id]
|
||||
@@ -70,6 +72,7 @@
|
||||
#(and (some? (:typography-ref-id %))
|
||||
(= (:typography-ref-file %) library-id))))))
|
||||
|
||||
;; FIXME: this function should not be here it belongs to shape and not typography
|
||||
(defn uses-library-typography?
|
||||
"Check if the shape uses the given library typography."
|
||||
[shape library-id typography-id]
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
(ns common-tests.colors-test
|
||||
(:require
|
||||
#?(:cljs [goog.color :as gcolors])
|
||||
[app.common.colors :as colors]
|
||||
[app.common.data :as d]
|
||||
[app.common.types.color :as colors]
|
||||
[clojure.test :as t]))
|
||||
|
||||
(t/deftest valid-hex-color
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.test-helpers.tokens :as tht]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.token :as cto]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[clojure.test :as t]))
|
||||
|
||||
@@ -12,12 +12,12 @@
|
||||
[app.common.test-helpers.files :as thf]
|
||||
[app.common.test-helpers.ids-map :as thi]
|
||||
[app.common.test-helpers.shapes :as ths]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[clojure.test :as t]))
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
_ (thf/validate-file! file')
|
||||
|
||||
;; Get
|
||||
colors' (ctc/colors-seq (ctf/file-data file'))
|
||||
colors' (vals (ctl/get-colors (ctf/file-data file')))
|
||||
shape1' (ths/get-shape file' :shape1)
|
||||
fill' (first (:fills shape1'))]
|
||||
|
||||
|
||||
@@ -12,21 +12,32 @@
|
||||
[app.common.types.text :as cttx]
|
||||
[clojure.test :as t :include-macros true]))
|
||||
|
||||
(def content-base (-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(txt/change-text "hello world")
|
||||
(assoc :position-data nil)
|
||||
:content))
|
||||
(def content-base
|
||||
(-> (cts/setup-shape {:type :text :x 0 :y 0 :grow-type :auto-width})
|
||||
(get :content)
|
||||
(cttx/change-text "hello world")))
|
||||
|
||||
(def content-changed-text (assoc-in content-base [:children 0 :children 0 :children 0 :text] "changed"))
|
||||
(def content-changed-attr (assoc-in content-base [:children 0 :children 0 :children 0 :font-size] "32"))
|
||||
(def content-changed-both (-> content-base
|
||||
(assoc-in [:children 0 :children 0 :children 0 :text] "changed")
|
||||
(assoc-in [:children 0 :children 0 :children 0 :font-size] "32")))
|
||||
(def line (get-in content-base [:children 0 :children 0 :children 0]))
|
||||
(def content-changed-structure (update-in content-base [:children 0 :children 0 :children]
|
||||
#(conj % (assoc line :font-weight "700"))))
|
||||
(def content-changed-structure-same-attrs (update-in content-base [:children 0 :children 0 :children]
|
||||
#(conj % line)))
|
||||
(def content-changed-text
|
||||
(assoc-in content-base [:children 0 :children 0 :children 0 :text] "changed"))
|
||||
|
||||
(def content-changed-attr
|
||||
(assoc-in content-base [:children 0 :children 0 :children 0 :font-size] "32"))
|
||||
|
||||
(def content-changed-both
|
||||
(-> content-base
|
||||
(assoc-in [:children 0 :children 0 :children 0 :text] "changed")
|
||||
(assoc-in [:children 0 :children 0 :children 0 :font-size] "32")))
|
||||
|
||||
(def line
|
||||
(get-in content-base [:children 0 :children 0 :children 0]))
|
||||
|
||||
(def content-changed-structure
|
||||
(update-in content-base [:children 0 :children 0 :children]
|
||||
#(conj % (assoc line :font-weight "700"))))
|
||||
|
||||
|
||||
(def content-changed-structure-same-attrs
|
||||
(update-in content-base [:children 0 :children 0 :children] #(conj % line)))
|
||||
|
||||
(t/deftest test-get-diff-type
|
||||
(let [diff-text (cttx/get-diff-type content-base content-changed-text)
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
[app.common.geom.shapes.grid-layout :as gslg]
|
||||
[app.common.logic.libraries :as cll]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.transit :as t]
|
||||
[app.common.types.component :as ctc]
|
||||
[app.common.types.container :as ctn]
|
||||
@@ -28,6 +27,7 @@
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.shape.text :as types.text]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
|
||||
(ns app.main.data.workspace.colors
|
||||
(: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.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.shape :as shp]
|
||||
[app.common.types.shape.shadow :refer [check-shadow]]
|
||||
[app.common.types.text :as txt]
|
||||
[app.config :as cfg]
|
||||
[app.main.broadcast :as mbc]
|
||||
[app.main.data.event :as ev]
|
||||
@@ -190,7 +190,7 @@
|
||||
(assert (every? uuid? ids) "expect a coll of uuids for `ids`")
|
||||
(assert (number? position) "expect a number for position")
|
||||
|
||||
(let [color (types.color/check-color color)]
|
||||
(let [color (clr/check-color color)]
|
||||
(ptk/reify ::change-fill
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
@@ -219,7 +219,7 @@
|
||||
([ids color options]
|
||||
|
||||
(assert (every? uuid? ids) "expected a valid coll of uuid's")
|
||||
(let [color (types.color/check-color color)]
|
||||
(let [color (clr/check-color color)]
|
||||
(ptk/reify ::add-fill
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
@@ -560,7 +560,7 @@
|
||||
(assoc-in [:workspace-global :picking-color?] true)
|
||||
(assoc ::md/modal {:id (random-uuid)
|
||||
:type :colorpicker
|
||||
:props {:data {:color cc/black
|
||||
:props {:data {:color clr/black
|
||||
:opacity 1}
|
||||
:disable-opacity false
|
||||
:disable-gradient false
|
||||
@@ -601,17 +601,9 @@
|
||||
|
||||
(defn change-color-in-selected
|
||||
[operations new-color old-color]
|
||||
|
||||
(assert (check-change-color-operations operations)
|
||||
"expected valid color operations")
|
||||
|
||||
(assert
|
||||
(types.color/check-color new-color)
|
||||
"expected valid color structure")
|
||||
|
||||
(assert
|
||||
(types.color/check-color old-color)
|
||||
"expected valid color structure")
|
||||
(assert (check-change-color-operations operations))
|
||||
(assert (clr/check-color new-color))
|
||||
(assert (clr/check-color old-color))
|
||||
|
||||
(ptk/reify ::change-color-in-selected
|
||||
ptk/WatchEvent
|
||||
@@ -632,7 +624,7 @@
|
||||
|
||||
(defn apply-color-from-palette
|
||||
[color stroke?]
|
||||
(let [color (types.color/check-color color)]
|
||||
(let [color (clr/check-color color)]
|
||||
(ptk/reify ::apply-color-from-palette
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
@@ -667,7 +659,7 @@
|
||||
|
||||
(defn apply-color-from-colorpicker
|
||||
[color]
|
||||
(let [color (types.color/check-color color)]
|
||||
(let [color (clr/check-color color)]
|
||||
(ptk/reify ::apply-color-from-colorpicker
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
@@ -708,7 +700,7 @@
|
||||
|
||||
(defn add-recent-color
|
||||
[color]
|
||||
(let [color (types.color/check-color color)]
|
||||
(let [color (clr/check-color color)]
|
||||
(ptk/reify ::add-recent-color
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
@@ -728,11 +720,11 @@
|
||||
|
||||
(defn apply-color-from-assets
|
||||
[file-id color stroke?]
|
||||
(let [color (types.color/check-library-color color)]
|
||||
(let [color (clr/check-library-color color)]
|
||||
(ptk/reify ::apply-color-from-asserts
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [color (types.color/library-color->color color file-id)]
|
||||
(let [color (clr/library-color->color color file-id)]
|
||||
(rx/of (apply-color-from-palette color stroke?)
|
||||
(add-recent-color color)))))))
|
||||
|
||||
@@ -742,9 +734,9 @@
|
||||
|
||||
(defn split-color-components
|
||||
[{:keys [color opacity] :as data}]
|
||||
(let [value (if (cc/valid-hex-color? color) color cc/black)
|
||||
[r g b] (cc/hex->rgb value)
|
||||
[h s v] (cc/hex->hsv value)]
|
||||
(let [value (if (clr/valid-hex-color? color) color clr/black)
|
||||
[r g b] (clr/hex->rgb value)
|
||||
[h s v] (clr/hex->hsv value)]
|
||||
(merge data
|
||||
{:hex (or value "000000")
|
||||
:alpha (or opacity 1)
|
||||
@@ -895,9 +887,9 @@
|
||||
(let [cap-stops? (or (features/active-feature? state "render-wasm/v1") (contains? cfg/flags :frontend-binary-fills))
|
||||
can-add-stop? (or (not cap-stops?) (< (count stops) types.fills/MAX-GRADIENT-STOPS))]
|
||||
(if can-add-stop?
|
||||
(if (cc/uniform-spread? stops)
|
||||
(if (clr/uniform-spread? stops)
|
||||
;; Add to uniform
|
||||
(let [stops (->> (cc/uniform-spread (first stops) (last stops) (inc (count stops)))
|
||||
(let [stops (->> (clr/uniform-spread (first stops) (last stops) (inc (count stops)))
|
||||
(mapv split-color-components))]
|
||||
(-> state
|
||||
(assoc :current-color (get stops editing-stop))
|
||||
@@ -918,7 +910,7 @@
|
||||
half-point-offset
|
||||
(+ from-offset (/ (- to-offset from-offset) 2))
|
||||
|
||||
new-stop (-> (cc/interpolate-gradient stops half-point-offset)
|
||||
new-stop (-> (clr/interpolate-gradient stops half-point-offset)
|
||||
(split-color-components))
|
||||
|
||||
stops (conj stops new-stop)
|
||||
@@ -938,18 +930,24 @@
|
||||
(update state :colorpicker
|
||||
(fn [state]
|
||||
(let [stops (:stops state)
|
||||
cap-stops? (or (features/active-feature? state "render-wasm/v1") (contains? cfg/flags :frontend-binary-fills))
|
||||
can-add-stop? (or (not cap-stops?) (< (count stops) types.fills/MAX-GRADIENT-STOPS))]
|
||||
(if can-add-stop? (let [new-stop (-> (cc/interpolate-gradient stops offset)
|
||||
(split-color-components))
|
||||
stops (conj stops new-stop)
|
||||
stops (into [] (sort-by :offset stops))
|
||||
editing-stop (d/index-of-pred stops #(= new-stop %))]
|
||||
(-> state
|
||||
(assoc :editing-stop editing-stop)
|
||||
(assoc :current-color (get stops editing-stop))
|
||||
(assoc :stops stops)))
|
||||
state)))))))
|
||||
cap-stops?
|
||||
(or (features/active-feature? state "render-wasm/v1")
|
||||
(contains? cfg/flags :frontend-binary-fills))
|
||||
|
||||
can-add-stop?
|
||||
(or (not cap-stops?) (< (count stops) types.fills/MAX-GRADIENT-STOPS))]
|
||||
|
||||
(if can-add-stop?
|
||||
(let [new-stop (-> (clr/interpolate-gradient stops offset)
|
||||
(split-color-components))
|
||||
stops (conj stops new-stop)
|
||||
stops (into [] (sort-by :offset stops))
|
||||
editing-stop (d/index-of-pred stops #(= new-stop %))]
|
||||
(-> state
|
||||
(assoc :editing-stop editing-stop)
|
||||
(assoc :current-color (get stops editing-stop))
|
||||
(assoc :stops stops)))
|
||||
state)))))))
|
||||
|
||||
(defn update-colorpicker-stops
|
||||
[stops]
|
||||
@@ -1148,3 +1146,115 @@
|
||||
:position :right})
|
||||
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
|
||||
:asset-type "color"}))))))
|
||||
|
||||
(defn- stroke->color-att
|
||||
[stroke file-id libraries]
|
||||
(let [ref-file (:stroke-color-ref-file stroke)
|
||||
ref-id (:stroke-color-ref-id stroke)
|
||||
|
||||
colors (-> libraries
|
||||
(get ref-file)
|
||||
(get :data)
|
||||
(ctl/get-colors))
|
||||
|
||||
is-shared? (contains? colors ref-id)
|
||||
has-color? (or (:stroke-color stroke)
|
||||
(:stroke-color-gradient stroke))
|
||||
attrs (cond-> (clr/stroke->color stroke)
|
||||
(not (or is-shared? (= ref-file file-id)))
|
||||
(dissoc :ref-id :ref-file))]
|
||||
|
||||
(when has-color?
|
||||
{:attrs attrs
|
||||
:prop :stroke
|
||||
:shape-id (:shape-id stroke)
|
||||
:index (:index stroke)})))
|
||||
|
||||
(defn- shadow->color-att
|
||||
[shadow file-id libraries]
|
||||
(let [color (get shadow :color)
|
||||
ref-file (get color :ref-file)
|
||||
ref-id (get color :ref-id)
|
||||
colors (-> libraries
|
||||
(get ref-id)
|
||||
(get :data)
|
||||
(ctl/get-colors))
|
||||
shared? (contains? colors ref-id)
|
||||
attrs (cond-> (clr/shadow->color shadow)
|
||||
(not (or shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
{:attrs attrs
|
||||
:prop :shadow
|
||||
:shape-id (:shape-id shadow)
|
||||
:index (:index shadow)}))
|
||||
|
||||
(defn- text->color-att
|
||||
[fill file-id libraries]
|
||||
(let [ref-file (:fill-color-ref-file fill)
|
||||
ref-id (:fill-color-ref-id fill)
|
||||
colors (-> libraries
|
||||
(get ref-id)
|
||||
(get :data)
|
||||
(ctl/get-colors))
|
||||
|
||||
shared? (contains? colors ref-id)
|
||||
attrs (cond-> (types.fills/fill->color fill)
|
||||
(not (or shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
|
||||
{:attrs attrs
|
||||
:prop :content
|
||||
:shape-id (:shape-id fill)
|
||||
:index (:index fill)}))
|
||||
|
||||
(defn- extract-text-colors
|
||||
[text file-id libraries]
|
||||
(let [treat-node
|
||||
(fn [node shape-id]
|
||||
(map-indexed #(assoc %2 :shape-id shape-id :index %1) node))]
|
||||
(->> (txt/node-seq txt/is-text-node? (:content text))
|
||||
(map :fills)
|
||||
(mapcat #(treat-node % (:id text)))
|
||||
(map #(text->color-att % file-id libraries)))))
|
||||
|
||||
(defn- fill->color-att
|
||||
[fill file-id libraries]
|
||||
(let [ref-file (:fill-color-ref-file fill)
|
||||
ref-id (:fill-color-ref-id fill)
|
||||
|
||||
colors (-> libraries
|
||||
(get ref-id)
|
||||
(get :data)
|
||||
(ctl/get-colors))
|
||||
shared? (contains? colors ref-id)
|
||||
has-color? (or (:fill-color fill)
|
||||
(:fill-color-gradient fill))
|
||||
attrs (cond-> (types.fills/fill->color fill)
|
||||
(not (or shared? (= ref-file file-id)))
|
||||
(dissoc :ref-file :ref-id))]
|
||||
|
||||
(when has-color?
|
||||
{:attrs attrs
|
||||
:prop :fill
|
||||
:shape-id (:shape-id fill)
|
||||
:index (:index fill)})))
|
||||
|
||||
(defn extract-all-colors
|
||||
[shapes file-id libraries]
|
||||
(reduce
|
||||
(fn [result 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))
|
||||
(-> result
|
||||
(into (keep #(stroke->color-att % file-id libraries)) stroke-obj)
|
||||
(into (map #(shadow->color-att % file-id libraries)) shadow-obj)
|
||||
(into (extract-text-colors shape file-id libraries)))
|
||||
|
||||
(-> result
|
||||
(into (keep #(fill->color-att % file-id libraries)) fill-obj)
|
||||
(into (keep #(stroke->color-att % file-id libraries)) stroke-obj)
|
||||
(into (map #(shadow->color-att % file-id libraries)) shadow-obj)))))
|
||||
[]
|
||||
shapes))
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.main.data.workspace.fix-deleted-fonts
|
||||
(:require
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.changes :as dwc]
|
||||
[app.main.data.helpers :as dsh]
|
||||
[app.main.fonts :as fonts]
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
@@ -195,7 +196,7 @@
|
||||
(if (str/empty? new-name)
|
||||
(rx/empty)
|
||||
(let [data (dsh/lookup-file-data state)
|
||||
color (-> (ctc/get-color data id)
|
||||
color (-> (ctl/get-color data id)
|
||||
(assoc :name new-name)
|
||||
(d/without-nils)
|
||||
(ctc/check-library-color))]
|
||||
@@ -962,8 +963,8 @@
|
||||
orig-shapes (when keep-touched? (cfh/get-children-with-self objects (:id shape)))
|
||||
|
||||
;; If the target parent is a grid layout we need to pass the target cell
|
||||
target-cell (when (ctl/grid-layout? parent)
|
||||
(ctl/get-cell-by-shape-id parent (:id shape)))
|
||||
target-cell (when (ctsl/grid-layout? parent)
|
||||
(ctsl/get-cell-by-shape-id parent (:id shape)))
|
||||
|
||||
index (find-shape-index objects (:parent-id shape) (:id shape))
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
(ns app.main.data.workspace.shape-layout
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
@@ -16,6 +15,7 @@
|
||||
[app.common.geom.shapes.flex-layout :as flex]
|
||||
[app.common.geom.shapes.grid-layout :as grid]
|
||||
[app.common.logic.libraries :as cll]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.component :as ctc]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.shortcuts :as ds]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.helpers :as dsh]
|
||||
@@ -905,9 +905,9 @@
|
||||
(ptk/reify ::v2-update-text-editor-styles
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [merged-styles (d/merge txt/default-text-attrs
|
||||
(get-in state [:workspace-global :default-font])
|
||||
new-styles)]
|
||||
(let [merged-styles (merge txt/default-text-attrs
|
||||
(get-in state [:workspace-global :default-font])
|
||||
new-styles)]
|
||||
(update-in state [:workspace-v2-editor-state id] (fnil merge {}) merged-styles)))))
|
||||
|
||||
(defn v2-update-text-shape-position-data
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.token :as ctt]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.common.types.typography :as cty]
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
(ns app.main.data.workspace.variants
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.files.changes-builder :as pcb]
|
||||
[app.common.files.helpers :as cfh]
|
||||
@@ -14,6 +13,7 @@
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.logic.variant-properties :as clvp]
|
||||
[app.common.logic.variants :as clv]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.component :as ctc]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.shape.layout :as ctsl]
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.logging :as log]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.config :as cf]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.globals :as globals]
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
(:require
|
||||
["react-dom/server" :as rds]
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
@@ -23,6 +22,7 @@
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.logging :as l]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
(ns app.main.ui.components.color-input
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.types.color :as cc]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.globals :as globals]
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"Assets exportation common components."
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.exports.assets :as de]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.refs :as refs]
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
(ns app.main.ui.inspect.attributes.common
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.media :as cm]
|
||||
[app.common.types.color :as cc]
|
||||
[app.config :as cf]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.main.ui.inspect.attributes.fill
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.main.ui.components.title-bar :refer [inspect-title-bar*]]
|
||||
[app.main.ui.inspect.attributes.common :refer [color-row]]
|
||||
[app.util.code-gen.style-css :as css]
|
||||
@@ -31,7 +31,7 @@
|
||||
;; FIXME: this looks broken code, because shape does not
|
||||
;; longer contains :fill-xxxx attributes but it is preserved
|
||||
;; as it was just moved the impl; this need to be fixed
|
||||
color (types.color/fill->color shape)
|
||||
color (types.fills/fill->color shape)
|
||||
on-change
|
||||
(mf/use-fn
|
||||
(fn [format]
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
@@ -18,8 +18,6 @@
|
||||
[app.main.ui.components.title-bar :refer [inspect-title-bar*]]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.inspect.attributes.common :refer [color-row]]
|
||||
[app.util.code-gen.style-css-formats :refer [format-color]]
|
||||
[app.util.color :as uc]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
@@ -43,21 +41,6 @@
|
||||
(map #(dm/str (d/name %) ": " (get style %) ";"))
|
||||
(str/join "\n")))
|
||||
|
||||
(defn- format-gradient-css
|
||||
"Converts a gradient object to a CSS string."
|
||||
[gradient]
|
||||
(str "background-image: " (uc/gradient->css gradient) ";"
|
||||
"background-clip: text;"
|
||||
"color: transparent;"))
|
||||
|
||||
(defn- copy-color-data
|
||||
"Converts a fill object to CSS color string in the specified format."
|
||||
[fill format]
|
||||
(let [color (ctc/fill->color fill)]
|
||||
(if-let [gradient (:gradient color)]
|
||||
(format-gradient-css gradient)
|
||||
(format-color color {:format format}))))
|
||||
|
||||
(mf/defc typography-block
|
||||
[{:keys [text style]}]
|
||||
(let [typography-library-ref
|
||||
@@ -83,10 +66,10 @@
|
||||
(when (:fills style)
|
||||
(for [[idx fill] (map-indexed vector (:fills style))]
|
||||
[:& color-row {:key idx
|
||||
:format color-format*
|
||||
:color (ctc/fill->color fill)
|
||||
:copy-data (copy-color-data fill color-format*)
|
||||
:on-change-format #(reset! color-format! %)}]))
|
||||
:format @color-format*
|
||||
:color (types.fills/fill->color fill)
|
||||
:copy-data (copy-style-data fill :fill-color :fill-color-gradient)
|
||||
:on-change-format #(reset! color-format* %)}]))
|
||||
|
||||
(when (:typography-ref-id style)
|
||||
[:div {:class (stl/css :text-row)}
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
|
||||
(ns app.main.ui.shapes.attrs
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.json :as json]
|
||||
[app.common.svg :as csvg]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.shape :refer [stroke-caps-line stroke-caps-marker]]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.util.object :as obj]
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
|
||||
(ns app.main.ui.shapes.filters
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.uuid :as uuid]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
(ns app.main.ui.shapes.text
|
||||
(:require
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.shapes.text.fo-text :as fo]
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
(ns app.main.ui.shapes.text.fo-text
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.color :as cc]
|
||||
[app.main.ui.shapes.text.styles :as sts]
|
||||
[app.util.object :as obj]
|
||||
[cuerdas.core :as str]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.text :as legacy.txt]
|
||||
[app.main.ui.shapes.text.styles :as sts]
|
||||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
@@ -99,7 +99,7 @@
|
||||
code? (obj/get props "code?")
|
||||
{:keys [id x y width height content]} shape
|
||||
|
||||
content (if code? (txt/index-content content) content)
|
||||
content (if code? (legacy.txt/index-content content) content)
|
||||
|
||||
style
|
||||
(when-not code?
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
(ns app.main.ui.shapes.text.styles
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.transit :as transit]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.util.color :as uc]
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.interactions :as ctsi]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.comments :as dcm]
|
||||
[app.main.data.viewer :as dv]
|
||||
[app.main.data.viewer.shortcuts :as sc]
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.workspace.colors :as mdc]
|
||||
[app.main.refs :as refs]
|
||||
@@ -170,7 +171,8 @@
|
||||
;; how it was saved first time
|
||||
(if (and ref-id ref-file)
|
||||
(let [fdata (dm/get-in libraries [ref-file :data])]
|
||||
(or (some-> (ctc/get-color fdata ref-id)
|
||||
;; FIXME: get a direct helper for obtain plain color
|
||||
(or (some-> (ctl/get-color fdata ref-id)
|
||||
(ctc/library-color->color ref-file))
|
||||
(dissoc color :ref-id :ref-file)))
|
||||
color)))
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
(ns app.main.ui.workspace.colorpicker
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.event :as-alias ev]
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
(ns app.main.ui.workspace.colorpicker.color-inputs
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
(ns app.main.ui.workspace.colorpicker.gradients
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.config :as cfg]
|
||||
[app.main.features :as features]
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
(ns app.main.ui.workspace.colorpicker.harmony
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.main.ui.workspace.colorpicker.hsva
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.types.color :as cc]
|
||||
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
(ns app.main.ui.workspace.colorpicker.libraries
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as c]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as ctc]
|
||||
@@ -109,7 +108,7 @@
|
||||
(map-indexed (fn [index color]
|
||||
(let [color (if (map? color) color {:color color})]
|
||||
(vary-meta color assoc ::id (dm/str index)))))
|
||||
(sort c/sort-colors))
|
||||
(sort ctc/sort-colors))
|
||||
(->> (dm/get-in libraries [file-id :data :colors])
|
||||
(vals)
|
||||
(filter valid-color?)
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
(ns app.main.ui.workspace.colorpicker.ramp
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.main.ui.components.color-bullet :as cb]
|
||||
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]
|
||||
[app.util.dom :as dom]
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.library :as ctl]
|
||||
[app.common.types.typographies-list :as ctyl]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.dashboard :as dd]
|
||||
@@ -407,7 +407,7 @@
|
||||
(sort-by #(str/lower (:name %)))
|
||||
(truncate :components))
|
||||
colors (->> color-ids
|
||||
(map #(ctc/get-color (:data library) %))
|
||||
(map #(ctl/get-color (:data library) %))
|
||||
(sort-by #(str/lower (:name %)))
|
||||
(truncate :colors))
|
||||
typographies (->> typography-ids
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.text :as gst]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]
|
||||
[app.common.text :as legacy.txt]
|
||||
[app.config :as cf]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
@@ -65,7 +65,7 @@
|
||||
(-> ^js (.getData content)
|
||||
(.toJS)
|
||||
(js->clj :keywordize-keys true))
|
||||
(txt/styles-to-attrs styles))]
|
||||
(legacy.txt/styles-to-attrs styles))]
|
||||
(sts/generate-text-styles shape data {:show-text? false})))
|
||||
|
||||
(def default-decorator
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.text :as gst]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.config :as cf]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
style-defaults
|
||||
(styles/get-style-defaults
|
||||
(merge txt/default-attrs default-font))
|
||||
(merge txt/default-text-attrs txt/default-root-attrs default-font))
|
||||
|
||||
options
|
||||
#js {:styleDefaults style-defaults
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.text :as gsht]
|
||||
[app.common.math :as mth]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.modifiers :as mdwm]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.data.workspace.colors :as dwc]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
@@ -20,7 +19,7 @@
|
||||
|
||||
(defn- prepare-colors
|
||||
[shapes file-id libraries]
|
||||
(let [data (into [] (remove nil? (ctc/extract-all-colors shapes file-id libraries)))
|
||||
(let [data (into [] (remove nil? (dwc/extract-all-colors shapes file-id libraries)))
|
||||
groups (d/group-by :attrs #(dissoc % :attrs) data)
|
||||
all-colors (distinct (mapv :attrs data))
|
||||
|
||||
@@ -82,7 +81,7 @@
|
||||
(mf/set-ref-val! prev-colors-ref
|
||||
(conj prev-colors color))))
|
||||
|
||||
(st/emit! (dc/change-color-in-selected cops new-color old-color)))))
|
||||
(st/emit! (dwc/change-color-in-selected cops new-color old-color)))))
|
||||
|
||||
on-open
|
||||
(mf/use-fn #(mf/set-ref-val! prev-colors-ref []))
|
||||
@@ -96,7 +95,7 @@
|
||||
(let [groups (mf/ref-val groups-ref)
|
||||
cops (get groups color)
|
||||
color' (dissoc color :id :file-id)]
|
||||
(st/emit! (dc/change-color-in-selected cops color' color)))))
|
||||
(st/emit! (dwc/change-color-in-selected cops color' color)))))
|
||||
|
||||
select-only
|
||||
(mf/use-fn
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.fill
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.common.types.shape.attrs :refer [default-color]]
|
||||
[app.config :as cfg]
|
||||
@@ -34,7 +34,7 @@
|
||||
xf:enumerate
|
||||
(map-indexed
|
||||
(fn [index item]
|
||||
(let [color (ctc/fill->color item)]
|
||||
(let [color (types.fills/fill->color item)]
|
||||
(with-meta item {:index index :color color})))))
|
||||
|
||||
(def ^:private ^boolean binary-fills-enabled?
|
||||
@@ -125,8 +125,7 @@
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [color index]
|
||||
(let [color (select-keys color ctc/color-attrs)]
|
||||
(st/emit! (udw/trigger-bounding-box-cloaking ids))
|
||||
(let [color (select-keys color clr/color-attrs)]
|
||||
(st/emit! (dc/change-fill ids color index)))))
|
||||
|
||||
on-reorder
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.shadow
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.shape.shadow :as ctss]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.stroke
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.store :as st]
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.constants :refer [max-input-length]]
|
||||
[app.main.data.common :as dcm]
|
||||
[app.main.data.fonts :as fts]
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
"Page options menu entries."
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
(ns app.main.ui.workspace.sidebar.options.rows.color-row
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.color :as types.color]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.shape.attrs :refer [default-color]]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.colors :as dwc]
|
||||
@@ -116,7 +115,7 @@
|
||||
(let [color (-> color
|
||||
(assoc :color value)
|
||||
(dissoc :gradient)
|
||||
(select-keys types.color/color-attrs))]
|
||||
(select-keys clr/color-attrs))]
|
||||
(st/emit! (dwc/add-recent-color color)
|
||||
(on-change color index)))))
|
||||
|
||||
@@ -127,7 +126,7 @@
|
||||
(let [color (-> color
|
||||
(assoc :opacity (/ value 100))
|
||||
(dissoc :ref-id :ref-file)
|
||||
(select-keys types.color/color-attrs))]
|
||||
(select-keys clr/color-attrs))]
|
||||
(st/emit! (dwc/add-recent-color color)
|
||||
(on-change color index)))))
|
||||
|
||||
@@ -256,7 +255,7 @@
|
||||
[:span {:class (stl/css :color-input-wrapper)}
|
||||
[:> color-input* {:value (if multiple-colors?
|
||||
""
|
||||
(-> color :color cc/remove-hash))
|
||||
(-> color :color clr/remove-hash))
|
||||
:placeholder (tr "settings.multiple")
|
||||
:data-index index
|
||||
:class (stl/css :color-input)
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
[app.common.attrs :as attrs]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.shape.attrs :refer [editable-attrs]]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-attrs blur-menu]]
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.svg-raw
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
(ns app.main.ui.workspace.sidebar.options.shapes.text
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
(ns app.main.ui.workspace.tokens.management.create.form
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as c]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.tokens :as cft]
|
||||
[app.common.types.color :as c]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.constants :refer [max-input-length]]
|
||||
[app.main.data.modal :as modal]
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
(ns app.main.ui.workspace.viewport
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape-tree :as ctt]
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
(ns app.main.ui.workspace.viewport.gradients
|
||||
"Gradients handlers and renders"
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
@@ -15,6 +14,7 @@
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.points :as gsp]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.types.fills :as types.fills]
|
||||
[app.config :as cfg]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
(ns app.main.ui.workspace.viewport.guides
|
||||
(:require
|
||||
[app.common.colors :as colors]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as colors]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
|
||||
(ns app.main.ui.workspace.viewport.scroll-bars
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.rect :as grc]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :refer [point->viewport]]
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
(ns app.main.ui.workspace.viewport-wasm
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.path :as path]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.changes :as ch]
|
||||
[app.main.data.common :as dcm]
|
||||
@@ -174,7 +174,7 @@
|
||||
file-id (:current-file-id @st/state)
|
||||
shared-libs (:files @st/state)]
|
||||
|
||||
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||
(->> (dwc/extract-all-colors shapes file-id shared-libs)
|
||||
(group-by :attrs)
|
||||
(format/format-array format/format-color-result)))))
|
||||
|
||||
@@ -202,7 +202,7 @@
|
||||
(mapcat #(cfh/get-children-with-self objects %)))
|
||||
|
||||
shapes-by-color
|
||||
(->> (ctc/extract-all-colors shapes file-id shared-libs)
|
||||
(->> (dwc/extract-all-colors shapes file-id shared-libs)
|
||||
(group-by :attrs))]
|
||||
|
||||
(when-let [operations (get shapes-by-color old-color)]
|
||||
|
||||
@@ -7,12 +7,11 @@
|
||||
(ns app.plugins.library
|
||||
"RPC for plugins runtime."
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.color :as ctc]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.typography :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
@@ -91,7 +90,7 @@
|
||||
:set
|
||||
(fn [self value]
|
||||
(cond
|
||||
(or (not (string? value)) (not (cc/valid-hex-color? value)))
|
||||
(or (not (string? value)) (not (clr/valid-hex-color? value)))
|
||||
(u/display-not-valid :color value)
|
||||
|
||||
(not (r/check-permission plugin-id "library:write"))
|
||||
@@ -126,7 +125,7 @@
|
||||
(fn [self value]
|
||||
(let [value (parser/parse-gradient value)]
|
||||
(cond
|
||||
(not (sm/validate ctc/schema:gradient value))
|
||||
(not (sm/validate clr/schema:gradient value))
|
||||
(u/display-not-valid :gradient value)
|
||||
|
||||
(not (r/check-permission plugin-id "library:write"))
|
||||
@@ -144,7 +143,7 @@
|
||||
(fn [self value]
|
||||
(let [value (parser/parse-image-data value)]
|
||||
(cond
|
||||
(not (sm/validate ctc/schema:image value))
|
||||
(not (sm/validate clr/schema:image value))
|
||||
(u/display-not-valid :image value)
|
||||
|
||||
(not (r/check-permission plugin-id "library:write"))
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
|
||||
(ns app.plugins.page
|
||||
(: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.geom.point :as gpt]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.color :as cc]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.comments :as dc]
|
||||
[app.main.data.common :as dcm]
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
(ns app.plugins.shape
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
@@ -16,7 +15,7 @@
|
||||
[app.common.schema :as sm]
|
||||
[app.common.spec :as us]
|
||||
[app.common.svg.path :as svg.path]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.color :as clr]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
@@ -31,6 +30,7 @@
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.shape.radius :as ctsr]
|
||||
[app.common.types.shape.shadow :as ctss]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.plugins :as dp]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.record :as crc]
|
||||
[app.common.schema :as sm]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape :as cts]
|
||||
[app.common.types.text :as txt]
|
||||
[app.main.data.workspace.shapes :as dwsh]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.fonts :as fonts]
|
||||
@@ -59,6 +59,27 @@
|
||||
(dwt/current-paragraph-values {:shape shape :attrs txt/paragraph-attrs})
|
||||
(dwt/current-text-values {:shape shape :attrs txt/text-node-attrs})))
|
||||
|
||||
(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 (txt/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 text-range-proxy?
|
||||
[range]
|
||||
(obj/type-of? range "TextRange"))
|
||||
@@ -80,7 +101,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :text) (str/join ""))))}
|
||||
|
||||
:fontId
|
||||
@@ -88,7 +109,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-id) u/mixed-value)))
|
||||
|
||||
:set
|
||||
@@ -110,7 +131,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-family) u/mixed-value)))
|
||||
|
||||
:set
|
||||
@@ -132,7 +153,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-variant-id) u/mixed-value)))
|
||||
:set
|
||||
(fn [self value]
|
||||
@@ -153,7 +174,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-size) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -173,7 +194,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-weight) u/mixed-value)))
|
||||
|
||||
:set
|
||||
@@ -200,7 +221,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :font-style) u/mixed-value)))
|
||||
:set
|
||||
(fn [self value]
|
||||
@@ -226,7 +247,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :line-height) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -246,7 +267,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :letter-spacing) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -266,7 +287,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :text-transform) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -285,7 +306,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :text-decoration) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -304,7 +325,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :direction) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -323,7 +344,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :text-align) u/mixed-value)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -342,7 +363,7 @@
|
||||
:get
|
||||
(fn [self]
|
||||
(let [range-data
|
||||
(-> self u/proxy->shape :content (txt/content-range->text+styles start end))]
|
||||
(-> self u/proxy->shape :content (content-range->text+styles start end))]
|
||||
(->> range-data (map :fills) u/mixed-value format/format-fills)))
|
||||
:set
|
||||
(fn [_ value]
|
||||
@@ -388,14 +409,15 @@
|
||||
(let [shape (u/proxy->shape self)
|
||||
editor
|
||||
(-> shape
|
||||
(get :content)
|
||||
(txt/change-text value)
|
||||
:content
|
||||
ted/import-content
|
||||
ted/create-editor-state)]
|
||||
(st/emit! (dwt/update-editor-state shape editor)))
|
||||
|
||||
:else
|
||||
(st/emit! (dwsh/update-shapes [id] #(txt/change-text % value))))))}
|
||||
(st/emit! (dwsh/update-shapes [id]
|
||||
#(update % :content txt/change-text value))))))}
|
||||
|
||||
{:name "growType"
|
||||
:get #(-> % u/proxy->shape :grow-type d/name)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
(ns app.render-wasm.api.texts
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.fills.impl :as types.fills.impl]
|
||||
[app.render-wasm.api.fonts :as f]
|
||||
[app.render-wasm.helpers :as h]
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.text :as txt]
|
||||
[app.common.text :as legacy.txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.text :as types.text]
|
||||
[app.main.ui.shapes.text.styles :as sts]
|
||||
[app.util.code-gen.common :as cgc]
|
||||
[app.util.code-gen.style-css-formats :refer [format-value format-shadow]]
|
||||
@@ -232,8 +233,8 @@ body {
|
||||
(let [selector (cgc/shape->selector shape)]
|
||||
(->> shape
|
||||
:content
|
||||
(txt/index-content)
|
||||
(txt/node-seq)
|
||||
(legacy.txt/index-content)
|
||||
(types.text/node-seq)
|
||||
(map #(node->css shape selector %))
|
||||
(str/join "\n"))))
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
"FIXME: this is legacy namespace, all functions of this ns should be
|
||||
relocated under app.common.types on the respective colors related
|
||||
namespace. All generic color conversion and other helpers are moved to
|
||||
app.common.colors namespace."
|
||||
app.common.types.color namespace."
|
||||
(:require
|
||||
[app.common.colors :as cc]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.math :as mth]
|
||||
[app.common.types.color :as cc]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.util.text.content.from-dom
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.util.text.content.styles :as styles]))
|
||||
|
||||
(defn is-text-node
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
(ns app.util.text.content.styles
|
||||
(:require
|
||||
[app.common.text :as txt]
|
||||
[app.common.transit :as transit]
|
||||
[app.common.types.text :as txt]
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(defn encode
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
(ns app.util.text.content.to-dom
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.text.content.styles :as styles]))
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"Draft related abstraction functions."
|
||||
(:require
|
||||
["@penpot/draft-js" :as impl]
|
||||
[app.common.text :as txt]))
|
||||
[app.common.text :as legacy.txt]))
|
||||
|
||||
;; --- CONVERSION
|
||||
|
||||
@@ -33,14 +33,14 @@
|
||||
|
||||
(defn import-content
|
||||
[content]
|
||||
(-> content txt/convert-to-draft clj->js impl/convertFromRaw))
|
||||
(-> content legacy.txt/convert-to-draft clj->js impl/convertFromRaw))
|
||||
|
||||
(defn export-content
|
||||
[content]
|
||||
(-> content
|
||||
(impl/convertToRaw)
|
||||
(js->clj :keywordize-keys true)
|
||||
(txt/convert-from-draft)))
|
||||
(legacy.txt/convert-from-draft)))
|
||||
|
||||
(defn get-editor-current-plain-text
|
||||
[state]
|
||||
@@ -81,7 +81,7 @@
|
||||
(if (impl/isCurrentEmpty state)
|
||||
(get-editor-current-block-data state)
|
||||
(-> (.getCurrentInlineStyle ^js state)
|
||||
(txt/styles-to-attrs)
|
||||
(legacy.txt/styles-to-attrs)
|
||||
(dissoc :text-align :text-direction))))
|
||||
|
||||
(defn update-editor-current-block-data
|
||||
@@ -96,20 +96,20 @@
|
||||
(impl/updateBlockData state block-key (clj->js attrs))
|
||||
|
||||
(let [attrs (-> (impl/getInlineStyle state block-key 0)
|
||||
(txt/styles-to-attrs)
|
||||
(legacy.txt/styles-to-attrs)
|
||||
(dissoc :text-align :text-direction))]
|
||||
(impl/updateBlockData state block-key (clj->js attrs)))))
|
||||
|
||||
state (impl/applyInlineStyle state (txt/attrs-to-styles attrs))
|
||||
state (impl/applyInlineStyle state (legacy.txt/attrs-to-styles attrs))
|
||||
selected (impl/getSelectedBlocks state)]
|
||||
(reduce update-blocks state selected)))
|
||||
|
||||
(defn update-editor-current-inline-styles-fn
|
||||
[state update-fn]
|
||||
(let [attrs (-> (.getCurrentInlineStyle ^js state)
|
||||
(txt/styles-to-attrs)
|
||||
(legacy.txt/styles-to-attrs)
|
||||
(update-fn))]
|
||||
(impl/applyInlineStyle state (txt/attrs-to-styles attrs))))
|
||||
(impl/applyInlineStyle state (legacy.txt/attrs-to-styles attrs))))
|
||||
|
||||
(defn editor-split-block
|
||||
[state]
|
||||
@@ -148,13 +148,13 @@
|
||||
(js->clj :keywordize-keys true))]
|
||||
(-> state
|
||||
(impl/selectBlock bkey)
|
||||
(impl/applyInlineStyle (txt/attrs-to-styles attrs)))))]
|
||||
(impl/applyInlineStyle (legacy.txt/attrs-to-styles attrs)))))]
|
||||
(as-> state $
|
||||
(reduce redfn $ blocks)
|
||||
(impl/setSelection $ selection)))))
|
||||
|
||||
(defn insert-text [state text attrs]
|
||||
(let [style (txt/attrs-to-styles attrs)]
|
||||
(let [style (legacy.txt/attrs-to-styles attrs)]
|
||||
(impl/insertText state text (clj->js attrs) (clj->js style))))
|
||||
|
||||
(defn get-style-override [state]
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
|
||||
(ns frontend-tests.helpers-shapes-test
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.pprint :refer [pprint]]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(ns frontend-tests.test-helpers-shapes
|
||||
(:require
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.types.color :as clr]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.test-helpers.events :as the]
|
||||
[app.test-helpers.libraries :as thl]
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
[app.common.test-helpers.files :as cthf]
|
||||
[app.common.test-helpers.ids-map :as cthi]
|
||||
[app.common.test-helpers.shapes :as cths]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.text :as txt]
|
||||
[app.common.types.tokens-lib :as ctob]
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[cljs.test :as t :include-macros true]
|
||||
|
||||
Reference in New Issue
Block a user