mirror of
https://github.com/penpot/penpot.git
synced 2025-07-30 23:48:33 +02:00
125 lines
4.8 KiB
Clojure
125 lines
4.8 KiB
Clojure
;; 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.main.ui.workspace.shapes
|
|
"A workspace specific shapes wrappers.
|
|
|
|
Shapes that has some peculiarities are defined in its own
|
|
namespace under app.ui.workspace.shapes.* prefix, all the
|
|
others are defined using a generic wrapper implemented in
|
|
common."
|
|
(:require
|
|
[app.common.data.macros :as dm]
|
|
[app.common.geom.rect :as grc]
|
|
[app.common.pages.helpers :as cph]
|
|
[app.common.uuid :as uuid]
|
|
[app.main.ui.context :as ctx]
|
|
[app.main.ui.shapes.circle :as circle]
|
|
[app.main.ui.shapes.image :as image]
|
|
[app.main.ui.shapes.rect :as rect]
|
|
[app.main.ui.shapes.text.fontfaces :as ff]
|
|
[app.main.ui.workspace.shapes.bool :as bool]
|
|
[app.main.ui.workspace.shapes.common :as common]
|
|
[app.main.ui.workspace.shapes.frame :as frame]
|
|
[app.main.ui.workspace.shapes.group :as group]
|
|
[app.main.ui.workspace.shapes.path :as path]
|
|
[app.main.ui.workspace.shapes.svg-raw :as svg-raw]
|
|
[app.main.ui.workspace.shapes.text :as text]
|
|
[app.util.object :as obj]
|
|
[rumext.v2 :as mf]))
|
|
|
|
(declare shape-wrapper)
|
|
(declare group-wrapper)
|
|
(declare svg-raw-wrapper)
|
|
(declare bool-wrapper)
|
|
(declare root-frame-wrapper)
|
|
(declare nested-frame-wrapper)
|
|
|
|
(def circle-wrapper (common/generic-wrapper-factory circle/circle-shape))
|
|
(def image-wrapper (common/generic-wrapper-factory image/image-shape))
|
|
(def rect-wrapper (common/generic-wrapper-factory rect/rect-shape))
|
|
|
|
(mf/defc root-shape
|
|
"Draws the root shape of the viewport and recursively all the shapes"
|
|
{::mf/wrap [mf/memo]
|
|
::mf/wrap-props false}
|
|
[props]
|
|
(let [objects (obj/get props "objects")
|
|
active-frames (obj/get props "active-frames")
|
|
shapes (cph/get-immediate-children objects)
|
|
vbox (mf/use-ctx ctx/current-vbox)
|
|
|
|
shapes (mf/with-memo [shapes vbox]
|
|
(if (some? vbox)
|
|
(filter (fn [shape]
|
|
(grc/overlaps-rects? vbox (dm/get-prop shape :selrect)))
|
|
shapes)
|
|
shapes))]
|
|
|
|
[:g {:id (dm/str "shape-" uuid/zero)}
|
|
[:& (mf/provider ctx/active-frames) {:value active-frames}
|
|
;; Render font faces only for shapes that are part of the root
|
|
;; frame but don't belongs to any other frame.
|
|
(let [xform (comp
|
|
(remove cph/frame-shape?)
|
|
(mapcat #(cph/get-children-with-self objects (:id %))))]
|
|
[:& ff/fontfaces-style {:shapes (into [] xform shapes)}])
|
|
|
|
[:g.frame-children
|
|
(for [shape shapes]
|
|
[:g.ws-shape-wrapper {:key (dm/str (dm/get-prop shape :id))}
|
|
(if ^boolean (cph/frame-shape? shape)
|
|
[:& root-frame-wrapper
|
|
{:shape shape
|
|
:thumbnail? (not (contains? active-frames (dm/get-prop shape :id)))}]
|
|
[:& shape-wrapper {:shape shape}])])]]]))
|
|
|
|
(mf/defc shape-wrapper
|
|
{::mf/wrap [#(mf/memo' % common/check-shape-props)]
|
|
::mf/wrap-props false}
|
|
[props]
|
|
(let [shape (unchecked-get props "shape")
|
|
shape-type (dm/get-prop shape :type)
|
|
shape-id (dm/get-prop shape :id)
|
|
|
|
;; FIXME: WARN: this breaks react rule of hooks (hooks can't be under conditional)
|
|
active-frames
|
|
(when (cph/root-frame? shape)
|
|
(mf/use-ctx ctx/active-frames))
|
|
|
|
thumbnail?
|
|
(and (some? active-frames)
|
|
(not (contains? active-frames shape-id)))
|
|
|
|
props #js {:shape shape :thumbnail? thumbnail?}
|
|
|
|
rawsvg? (= :svg-raw shape-type)
|
|
wrapper-elem (if ^boolean rawsvg? mf/Fragment "g")
|
|
wrapper-props (if ^boolean rawsvg?
|
|
#js {:className "workspace-shape-wrapper"}
|
|
#js {})]
|
|
|
|
(when (and (some? shape)
|
|
(not ^boolean (:hidden shape)))
|
|
[:> wrapper-elem wrapper-props
|
|
(case shape-type
|
|
:path [:> path/path-wrapper props]
|
|
:text [:> text/text-wrapper props]
|
|
:group [:> group-wrapper props]
|
|
:rect [:> rect-wrapper props]
|
|
:image [:> image-wrapper props]
|
|
:circle [:> circle-wrapper props]
|
|
:svg-raw [:> svg-raw-wrapper props]
|
|
:bool [:> bool-wrapper props]
|
|
:frame [:> nested-frame-wrapper props]
|
|
|
|
nil)])))
|
|
|
|
(def group-wrapper (group/group-wrapper-factory shape-wrapper))
|
|
(def svg-raw-wrapper (svg-raw/svg-raw-wrapper-factory shape-wrapper))
|
|
(def bool-wrapper (bool/bool-wrapper-factory shape-wrapper))
|
|
(def root-frame-wrapper (frame/root-frame-wrapper-factory shape-wrapper))
|
|
(def nested-frame-wrapper (frame/nested-frame-wrapper-factory shape-wrapper))
|