mirror of
https://github.com/penpot/penpot.git
synced 2026-05-24 01:13:43 +00:00
98 lines
2.8 KiB
Clojure
98 lines
2.8 KiB
Clojure
(ns uxbox.ui.shapes.core
|
|
(:require [lentes.core :as l]
|
|
[cuerdas.core :as str]
|
|
[rum.core :as rum]
|
|
[beicon.core :as rx]
|
|
[uxbox.state :as st]
|
|
[uxbox.shapes :as sh]
|
|
[uxbox.ui.mixins :as mx]))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Implementation Api
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defmulti render-component
|
|
(fn [own shape] (:type shape))
|
|
:hierarchy #'sh/+hierarchy+)
|
|
|
|
(defmulti render-shape
|
|
sh/dispatch-by-type
|
|
:hierarchy #'sh/+hierarchy+)
|
|
|
|
(defmulti render-shape-svg
|
|
sh/dispatch-by-type
|
|
:hierarchy #'sh/+hierarchy+)
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Lenses
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(def ^:const selected-shapes-l
|
|
(as-> (l/in [:workspace :selected]) $
|
|
(l/focus-atom $ st/state)))
|
|
|
|
(defn- focus-shape
|
|
[id]
|
|
(as-> (l/in [:shapes-by-id id]) $
|
|
(l/focus-atom $ st/state)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Component Api
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defn- shape-render
|
|
[own id]
|
|
(let [shape-l (focus-shape id)
|
|
shape (rum/react shape-l)]
|
|
(when-not (:hidden shape)
|
|
(render-component own shape))))
|
|
|
|
(def ^:const shape
|
|
(mx/component
|
|
{:render shape-render
|
|
:name "shape"
|
|
:mixins [(mx/local) mx/static rum/reactive]}))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Attribute transformations
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(def ^:static ^:private +style-attrs+
|
|
#{:fill :opacity :stroke :stroke-opacity :stroke-width :stroke-type :rx :ry})
|
|
|
|
(defn- transform-stroke-type
|
|
[attrs]
|
|
(if-let [type (:stroke-type attrs)]
|
|
(let [value (case type
|
|
:mixed "5,5,1,5"
|
|
:dotted "5,5"
|
|
:dashed "10,10"
|
|
nil)]
|
|
(if value
|
|
(-> attrs
|
|
(assoc! :stroke-dasharray value)
|
|
(dissoc! :stroke-type))
|
|
(dissoc! attrs :stroke-type)))
|
|
attrs))
|
|
|
|
(defn- transform-stroke-attrs
|
|
[attrs]
|
|
(if (= (:stroke-type attrs :none) :none)
|
|
(dissoc! attrs :stroke-type :stroke-width :stroke-opacity :stroke)
|
|
(transform-stroke-type attrs)))
|
|
|
|
(defn- extract-style-attrs
|
|
"Extract predefinet attrs from shapes."
|
|
[shape]
|
|
(let [attrs (select-keys shape +style-attrs+)]
|
|
(-> (transient attrs)
|
|
(transform-stroke-attrs)
|
|
(persistent!))))
|
|
|
|
(defn- make-debug-attrs
|
|
[shape]
|
|
(let [attrs (select-keys shape [:rotation :width :height :x :y])
|
|
xf (map (fn [[x v]]
|
|
[(keyword (str "data-" (name x))) v]))]
|
|
(into {} xf attrs)))
|