0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-24 23:49:45 -05:00

Handling groups inside bool shapes

This commit is contained in:
alonso.torres 2021-09-17 14:38:44 +02:00
parent 6fd35ae5d9
commit c56f024a86
7 changed files with 155 additions and 51 deletions

View file

@ -11,6 +11,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes.common :as gsc]
[app.common.geom.shapes.path :as gsp]
[app.common.path.bool :as pb]
[app.common.path.commands :as pc]))
(def ^:const bezier-circle-c 0.551915024494)
@ -24,26 +25,31 @@
#{:rect
:circle
:image
:group})
:group
:bool})
(def ^:const style-group-properties
[:shadow
:blur])
(def ^:const style-properties
[:fill-color
:fill-opacity
:fill-color-gradient
:fill-color-ref-file
:fill-color-ref-id
:fill-image
:stroke-color
:stroke-color-ref-file
:stroke-color-ref-id
:stroke-opacity
:stroke-style
:stroke-width
:stroke-alignment
:stroke-cap-start
:stroke-cap-end
:shadow
:blur])
(d/concat
style-group-properties
[:fill-color
:fill-opacity
:fill-color-gradient
:fill-color-ref-file
:fill-color-ref-id
:fill-image
:stroke-color
:stroke-color-ref-file
:stroke-color-ref-id
:stroke-opacity
:stroke-style
:stroke-width
:stroke-alignment
:stroke-cap-start
:stroke-cap-end]))
(defn make-corner-arc
"Creates a curvle corner for border radius"
@ -142,7 +148,6 @@
(defn group-to-path
[group objects]
(let [xform (comp (map #(get objects %))
(map #(-> (convert-to-path % objects))))
@ -157,6 +162,22 @@
(merge head-data)
(d/without-keys dissoc-attrs))))
(defn bool-to-path
[shape objects]
(let [children (->> (:shapes shape)
(map #(get objects %))
(map #(convert-to-path % objects)))
head (first children)
head-data (select-keys head style-properties)
content (pb/content-bool (:bool-type shape) (mapv :content children))]
(-> shape
(assoc :type :path)
(assoc :content content)
(merge head-data)
(d/without-keys dissoc-attrs))))
(defn convert-to-path
"Transforms the given shape to a path"
[{:keys [type x y width height r1 r2 r3 r4 rx metadata] :as shape} objects]
@ -165,6 +186,9 @@
(= (:type shape) :group)
(group-to-path shape objects)
(= (:type shape) :bool)
(bool-to-path shape objects)
(contains? allowed-transform-types type)
(let [new-content
(case type

View file

@ -46,5 +46,13 @@
fill: $color-gray-40;
}
}
&.selected svg {
fill: $color-primary;
}
&.selected:hover svg {
fill: $color-white;
}
}
}

View file

@ -1098,13 +1098,9 @@
:text
(rx/of (dwc/start-edition-mode id))
:group
(:group :bool)
(rx/of (dwc/select-shapes (into (d/ordered-set) [(last shapes)])))
:bool
;; TODO
(js/alert "TODO")
:svg-raw
nil
@ -1995,3 +1991,6 @@
;; Boolean
(d/export dwb/create-bool)
(d/export dwb/group-to-bool)
(d/export dwb/bool-to-group)
(d/export dwb/change-bool-type)

View file

@ -45,11 +45,36 @@
(merge head-data)
(gsh/update-bool-selrect shapes objects))))
(defn group->bool
[group bool-type objects]
(let [shapes (->> (:shapes group)
(map #(get objects %))
(mapv #(stp/convert-to-path % objects)))
head (first shapes)
head-data (select-keys head stp/style-properties)]
(-> group
(assoc :type :bool)
(assoc :bool-type bool-type)
(merge head-data)
(gsh/update-bool-selrect shapes objects))))
(defn bool->group
[shape objects]
(let [children (->> (:shapes shape)
(mapv #(get objects %)))]
(-> shape
(assoc :type :group)
(dissoc :bool-type)
(d/without-keys stp/style-group-properties)
(gsh/update-group-selrect children))))
(defn create-bool
[bool-type]
(ptk/reify ::create-bool-union
ptk/WatchEvent
(watch [it state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state)
@ -66,3 +91,29 @@
(cb/change-parent shape-id shapes))]
(rx/of (dch/commit-changes changes)
(dwc/select-shapes (d/ordered-set shape-id)))))))))
(defn group-to-bool
[shape-id bool-type]
(ptk/reify ::group-to-bool
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)]
(rx/of (dch/update-shapes [shape-id] #(group->bool % bool-type objects)))))))
(defn bool-to-group
[shape-id]
(ptk/reify ::bool-to-group
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)]
(rx/of (dch/update-shapes [shape-id] #(bool->group % objects)))))))
(defn change-bool-type
[shape-id bool-type]
(ptk/reify ::change-bool-type
ptk/WatchEvent
(watch [_ _ _]
(rx/of (dch/update-shapes
[shape-id]
#(assoc % :bool-type bool-type))))))

View file

@ -266,8 +266,10 @@
(-> (:workspace-local state)
(select-keys [:modifiers :selected]))
modifiers (merge modifiers
(into #{} (map #(vector % disp-modifiers)) selected))]
modifiers
(d/deep-merge
modifiers
(into {} (map #(vector % {:modifiers disp-modifiers})) selected))]
(gsh/merge-modifiers children modifiers)))]
(l/derived selector st/state =)))

View file

@ -6,6 +6,8 @@
(ns app.main.ui.shapes.bool
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.path.bool :as pb]
[app.common.path.shapes-to-path :as stp]
[app.main.ui.hooks :refer [use-equal-memo]]
@ -27,12 +29,12 @@
(mf/use-memo
(mf/deps childs)
(fn []
(->> shape
:shapes
(map #(get childs %))
(map #(stp/convert-to-path % childs))
(mapv :content)
(pb/content-bool (:bool-type shape)))))]
(let [childs (d/mapm #(gsh/transform-shape %2) childs)]
(->> (:shapes shape)
(map #(get childs %))
(map #(stp/convert-to-path % childs))
(mapv :content)
(pb/content-bool (:bool-type shape))))))]
[:& shape-wrapper {:shape (-> shape
(assoc :type :path)

View file

@ -6,49 +6,67 @@
(ns app.main.ui.workspace.sidebar.options.menus.booleans
(:require
[app.main.data.workspace :as dw]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]
))
[rumext.alpha :as mf]))
(mf/defc booleans-options
[]
(let [selected (mf/deref refs/selected-shapes)
disabled (and (some? selected)
(<= (count selected) 1))
(let [selected (mf/deref refs/selected-objects)
disabled (or (empty? selected)
(and (<= (count selected) 1)
(not (contains? #{:group :bool} (:type (first selected))))))
do-boolean-union (st/emitf (dw/create-bool :union))
do-boolean-difference (st/emitf (dw/create-bool :difference))
do-boolean-intersection (st/emitf (dw/create-bool :intersection))
do-boolean-exclude (st/emitf (dw/create-bool :exclude))]
head (first selected)
is-group? (and (some? head) (= :group (:type head)))
is-bool? (and (some? head) (= :bool (:type head)))
head-bool-type (and (some? head) (:bool-type head))
set-bool
(fn [bool-type]
#(cond
(> (count selected) 1)
(st/emit! (dw/create-bool bool-type))
(and (= (count selected) 1) is-group?)
(st/emit! (dw/group-to-bool (:id head) bool-type))
(and (= (count selected) 1) is-bool?)
(if (= head-bool-type bool-type)
(st/emit! (dw/bool-to-group (:id head)))
(st/emit! (dw/change-bool-type (:id head) bool-type)))))]
[:div.align-options
[:div.align-group
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.shape.menu.union")
:class (when disabled "disabled")
:on-click do-boolean-union}
:class (dom/classnames :disabled disabled
:selected (= head-bool-type :union))
:on-click (set-bool :union)}
i/boolean-union]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.shape.menu.difference")
:class (when disabled "disabled")
:on-click do-boolean-difference}
:class (dom/classnames :disabled disabled
:selected (= head-bool-type :difference))
:on-click (set-bool :difference)}
i/boolean-difference]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.shape.menu.intersection")
:class (when disabled "disabled")
:on-click do-boolean-intersection}
:class (dom/classnames :disabled disabled
:selected (= head-bool-type :intersection))
:on-click (set-bool :intersection)}
i/boolean-intersection]
[:div.align-button.tooltip.tooltip-bottom
{:alt (tr "workspace.shape.menu.exclude")
:class (when disabled "disabled")
:on-click do-boolean-exclude}
:class (dom/classnames :disabled disabled
:selected (= head-bool-type :exclude))
:on-click (set-bool :exclude)}
i/boolean-exclude]]]))