0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-10 00:58:26 -05:00

Reusable shape container refactor

This commit is contained in:
alonso.torres 2020-10-16 11:40:49 +02:00
parent 5e299551b7
commit 57c93f80e2
7 changed files with 123 additions and 155 deletions

View file

@ -27,8 +27,7 @@
[app.main.ui.shapes.rect :as rect]
[app.main.ui.shapes.text :as text]
[app.main.ui.shapes.group :as group]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
[app.main.ui.shapes.shape :refer [shape-container]]))
(def ^:private default-color "#E8E9EA") ;; $color-canvas
@ -57,14 +56,9 @@
(mf/fnc frame-wrapper
[{:keys [shape] :as props}]
(let [childs (mapv #(get objects %) (:shapes shape))
shape (geom/transform-shape shape)
render-id (mf/use-memo #(str (uuid/next)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.frame
[:defs
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& frame-shape {:shape shape :childs childs}]]]))))
shape (geom/transform-shape shape)]
[:> shape-container {:shape shape}
[:& frame-shape {:shape shape :childs childs}]]))))
(defn group-wrapper-factory
[objects]
@ -86,25 +80,19 @@
frame-wrapper (mf/use-memo (mf/deps objects) #(frame-wrapper-factory objects))]
(when (and shape (not (:hidden shape)))
(let [shape (geom/transform-shape frame shape)
opts #js {:shape shape}
render-id (mf/use-memo #(str (uuid/next)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g {:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
(case (:type shape)
:curve [:> path/path-shape opts]
:text [:> text/text-shape opts]
:icon [:> icon/icon-shape opts]
:rect [:> rect/rect-shape opts]
:path [:> path/path-shape opts]
:image [:> image/image-shape opts]
:circle [:> circle/circle-shape opts]
:frame [:> frame-wrapper {:shape shape}]
:group [:> group-wrapper {:shape shape :frame frame}]
nil)]])))))
opts #js {:shape shape}]
[:> shape-container {:shape shape}
(case (:type shape)
:curve [:> path/path-shape opts]
:text [:> text/text-shape opts]
:icon [:> icon/icon-shape opts]
:rect [:> rect/rect-shape opts]
:path [:> path/path-shape opts]
:image [:> image/image-shape opts]
:circle [:> circle/circle-shape opts]
:frame [:> frame-wrapper {:shape shape}]
:group [:> group-wrapper {:shape shape :frame frame}]
nil)])))))
(mf/defc page-svg
{::mf/wrap [mf/memo]}

View file

@ -7,5 +7,33 @@
;;
;; Copyright (c) 2020 UXBOX Labs SL
(ns app.main.ui.shapes.shape)
(ns app.main.ui.shapes.shape
(:require
[rumext.alpha :as mf]
[app.util.object :as obj]
[app.common.uuid :as uuid]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
(mf/defc shape-container
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
children (unchecked-get props "children")
render-id (mf/use-memo #(str (uuid/next)))
filter-id (str "filter_" render-id)
group-props (-> props
(obj/clone)
(obj/without ["shape" "children"])
(obj/set! "className" "shape")
(obj/set! "filter" (filters/filter-str filter-id shape)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:> :g group-props
[:defs
[:& filters/filters {:shape shape :filter-id filter-id}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
children]]))

View file

@ -30,9 +30,7 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
[app.main.ui.shapes.shape :refer [shape-container]]))
(defn on-mouse-down
[event {:keys [interactions] :as shape}]
@ -57,31 +55,24 @@
on-mouse-down (mf/use-callback
(mf/deps shape)
#(on-mouse-down % shape))
#(on-mouse-down % shape))]
render-id (mf/use-memo #(str (uuid/next)))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-mouse-down on-mouse-down
:cursor (when (:interactions shape) "pointer")
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& component {:shape shape
:frame frame
:childs childs
:is-child-selected? true}]
(when (and (:interactions shape) show-interactions?)
[:rect {:x (- x 1)
:y (- y 1)
:width (+ width 2)
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width 1
:fill-opacity 0.2}])]])))
[:> shape-container {:shape shape
:on-mouse-down on-mouse-down
:cursor (when (:interactions shape) "pointer")}
[:& component {:shape shape
:frame frame
:childs childs
:is-child-selected? true}]
(when (and (:interactions shape) show-interactions?)
[:rect {:x (- x 1)
:y (- y 1)
:width (+ width 2)
:height (+ height 2)
:fill "#31EFB8"
:stroke "#31EFB8"
:stroke-width 1
:fill-opacity 0.2}])])))
(defn frame-wrapper
[shape-container show-interactions?]

View file

@ -14,14 +14,11 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.keyboard :as kbd]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.gradients :as grad]
[app.util.dom :as dom]
[app.common.uuid :as uuid]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.main.ui.context :as muc]))
[app.main.ui.shapes.shape :refer [shape-container]]))
(defn- on-mouse-down
[event {:keys [id type] :as shape}]
@ -73,18 +70,11 @@
#(on-mouse-down % shape))
on-context-menu (mf/use-callback
(mf/deps shape)
#(on-context-menu % shape))
render-id (mf/use-memo #(str (uuid/next)))]
#(on-context-menu % shape))]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& component {:shape shape}]]])))
[:> shape-container {:shape shape
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu}
[:& component {:shape shape}]])))

View file

@ -19,16 +19,13 @@
[app.main.ui.workspace.shapes.common :as common]
[app.main.data.workspace.selection :as dws]
[app.main.ui.shapes.frame :as frame]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.shapes.filters :as filters]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.util.dom :as dom]
[app.main.streams :as ms]
[app.util.timers :as ts]
[app.main.ui.context :as muc]
[app.common.uuid :as uuid]))
[app.main.ui.shapes.shape :refer [shape-container]]))
(defn- frame-wrapper-factory-equals?
[np op]
@ -115,9 +112,7 @@
(mf/use-callback
(mf/deps (:id shape))
(fn []
(st/emit! (dws/change-hover-state (:id shape) false))))
render-id (mf/use-memo #(str (uuid/next)))]
(st/emit! (dws/change-hover-state (:id shape) false))))]
(when-not (:hidden shape)
[:g {:class (when selected? "selected")
@ -130,14 +125,8 @@
:on-double-click on-double-click
:on-mouse-down on-mouse-down}]
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.frame {:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& frame-shape
{:shape shape
:childs children}]]]])))))
[:> shape-container {:shape shape}
[:& frame-shape
{:shape shape
:childs children}]]])))))

View file

@ -11,22 +11,19 @@
(:require
[rumext.alpha :as mf]
[app.common.data :as d]
[app.util.dom :as dom]
[app.util.timers :as ts]
[app.main.streams :as ms]
[app.main.constants :as c]
[app.main.data.workspace :as dw]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.data.workspace :as dw]
[app.main.data.workspace.drawing :as dr]
[app.main.ui.keyboard :as kbd]
[app.main.ui.shapes.path :as path]
[app.main.ui.shapes.filters :as filters]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.workspace.shapes.common :as common]
[app.main.data.workspace.drawing :as dr]
[app.util.dom :as dom]
[app.main.streams :as ms]
[app.util.timers :as ts]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc]))
[app.main.ui.shapes.shape :refer [shape-container]]
[app.main.ui.workspace.shapes.common :as common]))
(mf/defc path-wrapper
{::mf/wrap-props false}
@ -46,20 +43,13 @@
(do
(dom/stop-propagation event)
(dom/prevent-default event)
(st/emit! (dw/start-edition-mode (:id shape)))))))
(st/emit! (dw/start-edition-mode (:id shape)))))))]
render-id (mf/use-memo #(str (uuid/next)))]
[:> shape-container {:shape shape
:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu}
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:& path/path-shape {:shape shape
:background? true}]]]))
[:& path/path-shape {:shape shape
:background? true}]]))

View file

@ -9,35 +9,34 @@
(ns app.main.ui.workspace.shapes.text
(:require
[cuerdas.core :as str]
["slate" :as slate]
["slate-react" :as rslate]
[goog.events :as events]
[goog.object :as gobj]
[cuerdas.core :as str]
[rumext.alpha :as mf]
[beicon.core :as rx]
[app.util.color :as color]
[app.util.dom :as dom]
[app.util.text :as ut]
[app.util.object :as obj]
[app.util.color :as uc]
[app.util.timers :as timers]
[app.common.data :as d]
[app.common.geom.shapes :as geom]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.fonts :as fonts]
[app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.texts :as dwt]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.cursors :as cur]
[app.main.ui.workspace.shapes.common :as common]
[app.main.ui.shapes.text :as text]
[app.main.ui.keyboard :as kbd]
[app.main.ui.context :as muc]
[app.main.ui.shapes.filters :as filters]
[app.main.fonts :as fonts]
[app.util.color :as color]
[app.util.dom :as dom]
[app.util.text :as ut]
[app.common.geom.shapes :as geom]
[app.util.object :as obj]
[app.util.color :as uc]
[app.util.timers :as timers]
["slate" :as slate]
["slate-react" :as rslate]
[app.common.uuid :as uuid]
[app.main.ui.shapes.gradients :as grad]
[app.main.ui.context :as muc])
[app.main.ui.shapes.shape :refer [shape-container]])
(:import
goog.events.EventType
goog.events.KeyCodes))
@ -81,9 +80,7 @@
(dom/stop-propagation event)
(dom/prevent-default event)
(when selected?
(st/emit! (dw/start-edition-mode (:id shape)))))
render-id (mf/use-memo #(str (uuid/next)))]
(st/emit! (dw/start-edition-mode (:id shape)))))]
(mf/use-effect
(mf/deps shape edition selected? current-transform)
@ -91,30 +88,25 @@
selected?
(not edition?)
(not embed-resources?)
(nil? current-transform))]
(timers/schedule #(reset! render-editor check?)))))
(nil? current-transform))
result (timers/schedule #(reset! render-editor check?))]
#(rx/dispose! result))))
[:& (mf/provider muc/render-ctx) {:value render-id}
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu
:filter (filters/filter-str (str "filter_" render-id) shape)}
[:defs
[:& filters/filters {:shape shape}]
[:& grad/gradient {:shape shape :attr :fill-color-gradient}]
[:& grad/gradient {:shape shape :attr :stroke-color-gradient}]]
[:*
(when @render-editor
[:g {:opacity 0
:style {:pointer-events "none"}}
;; We only render the component for its side-effect
[:& text-shape-edit {:shape shape
:read-only? true}]])
[:> shape-container {:shape shape
:on-double-click on-double-click
:on-mouse-down on-mouse-down
:on-context-menu on-context-menu}
(when @render-editor
[:g {:opacity 0
:style {:pointer-events "none"}}
;; We only render the component for its side-effect
[:& text-shape-edit {:shape shape
:read-only? true}]])
(if edition?
[:& text-shape-edit {:shape shape}]
[:& text/text-shape {:shape shape
:selected? selected?}])]]]))
(if edition?
[:& text-shape-edit {:shape shape}]
[:& text/text-shape {:shape shape
:selected? selected?}])]))
;; --- Text Editor Rendering