;; 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) 2016-2019 Andrey Antukh (ns uxbox.main.ui.shapes.path (:require [cuerdas.core :as str :include-macros true] [rumext.alpha :as mf] [uxbox.main.data.workspace :as dw] [uxbox.main.geom :as geom] [uxbox.main.refs :as refs] [uxbox.main.store :as st] [uxbox.main.ui.shapes.attrs :as attrs] [uxbox.main.ui.shapes.common :as common] [uxbox.util.data :refer [classnames normalize-props]] [uxbox.util.geom.matrix :as gmt])) ;; --- Path Component (declare path-shape) (mf/defc path-component [{:keys [shape] :as props}] (let [selected (mf/deref refs/selected-shapes) selected? (contains? selected (:id shape))] (letfn [(on-mouse-down [event] (common/on-mouse-down event shape selected)) (on-double-click [event] (when selected? (prn "path-component$on-double-click") (st/emit! (dw/start-edition-mode (:id shape)))))] [:g.shape {:class (when selected? "selected") :on-double-click on-double-click :on-mouse-down on-mouse-down} [:& path-shape {:shape shape :background? true}]]))) ;; --- Path Shape (defn- render-path [{:keys [segments close?] :as shape}] (let [numsegs (count segments)] (loop [buffer [] index 0] (cond (>= index numsegs) (if close? (str/join " " (conj buffer "Z")) (str/join " " buffer)) (zero? index) (let [{:keys [x y] :as segment} (nth segments index) buffer (conj buffer (str/istr "M~{x},~{y}"))] (recur buffer (inc index))) :else (let [{:keys [x y] :as segment} (nth segments index) buffer (conj buffer (str/istr "L~{x},~{y}"))] (recur buffer (inc index))))))) (mf/defc path-shape [{:keys [shape background?] :as props}] (let [modifier-mtx (:modifier-mtx shape) shape (cond (gmt/matrix? modifier-mtx) (geom/transform shape modifier-mtx) :else shape) moving? (boolean modifier-mtx) pdata (render-path shape) props {:id (str (:id shape)) :class (classnames :move-cursor moving?) :d pdata} attrs (merge (attrs/extract-style-attrs shape) props)] (if background? [:g [:path {:stroke "transparent" :fill "transparent" :stroke-width "20px" :d pdata}] [:> :path (normalize-props attrs)]] [:> :path (normalize-props attrs)])))