mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 06:58:58 -05:00
🐛 Fix edit attrs of groups
This commit is contained in:
parent
cf108e110f
commit
8de55ce054
5 changed files with 127 additions and 60 deletions
|
@ -856,34 +856,63 @@
|
|||
:else srect))))
|
||||
|
||||
(defn get-attrs-multi
|
||||
[values attrs]
|
||||
;; Extract some attributes of a list of shape values.
|
||||
[shapes attrs]
|
||||
;; Extract some attributes of a list of shapes.
|
||||
;; For each attribute, if the value is the same in all shapes,
|
||||
;; wll take this value. If there is any shape that is different,
|
||||
;; the value of the attribute will be the keyword :multiple.
|
||||
;;
|
||||
;; If some shape has the value nil in any attribute, it's
|
||||
;; considered a different value. If the shape does not contain
|
||||
;; the attribute, it's ignored in the final result.
|
||||
;;
|
||||
;; Example:
|
||||
;; (def values [{:stroke-color "#ff0000'
|
||||
;; (def shapes [{:stroke-color "#ff0000"
|
||||
;; :stroke-width 3
|
||||
;; :x 1000 :y 2000}
|
||||
;; {:stroke-width "#ff0000'
|
||||
;; :fill-color "#0000ff"
|
||||
;; :x 1000 :y 2000 :rx nil}
|
||||
;; {:stroke-width "#ff0000"
|
||||
;; :stroke-width 5
|
||||
;; :x 1500 :y 2000}])
|
||||
;;
|
||||
;; (get-attrs-multi values [:stroke-color :stroke-width :fill-color])
|
||||
;; >>> {:stroke-color "#ff0000'
|
||||
;; (get-attrs-multi shapes [:stroke-color
|
||||
;; :stroke-width
|
||||
;; :fill-color
|
||||
;; :rx
|
||||
;; :ry])
|
||||
;; >>> {:stroke-color "#ff0000"
|
||||
;; :stroke-width :multiple
|
||||
;; :fill-color nil}
|
||||
;; :fill-color "#0000ff"
|
||||
;; :rx nil
|
||||
;; :ry nil}
|
||||
;;
|
||||
(let [defined-values (filter some? values)
|
||||
(let [defined-shapes (filter some? shapes)
|
||||
|
||||
combine-value #(if (= %1 %2) %1 :multiple)
|
||||
combine-value (fn [v1 v2] (cond
|
||||
(= v1 v2) v1
|
||||
(= v1 :undefined) v2
|
||||
(= v2 :undefined) v1
|
||||
:else :multiple))
|
||||
|
||||
combine-values (fn [attrs shape values]
|
||||
(map #(combine-value (get shape %) (get values %)) attrs))
|
||||
(map #(combine-value (get shape % :undefined)
|
||||
(get values % :undefined)) attrs))
|
||||
|
||||
select-attrs (fn [shape attrs]
|
||||
(zipmap attrs (map #(get shape % :undefined) attrs)))
|
||||
|
||||
reducer (fn [result shape]
|
||||
(zipmap attrs (combine-values attrs shape result)))]
|
||||
(zipmap attrs (combine-values attrs shape result)))
|
||||
|
||||
(reduce reducer (select-keys (first defined-values) attrs) (rest defined-values))))
|
||||
combined (reduce reducer
|
||||
(select-attrs (first defined-shapes) attrs)
|
||||
(rest defined-shapes))
|
||||
|
||||
cleanup-value (fn [value]
|
||||
(if (= value :undefined) nil value))
|
||||
|
||||
cleanup (fn [result]
|
||||
(zipmap attrs (map #(cleanup-value (get result %)) attrs)))]
|
||||
|
||||
(cleanup combined)))
|
||||
|
||||
|
|
|
@ -233,36 +233,61 @@
|
|||
[{:type :rect
|
||||
:name "Rect"
|
||||
:fill-color default-color
|
||||
:stroke-alignment :center
|
||||
:rx 0
|
||||
:ry 0}
|
||||
{:type :image}
|
||||
{:type :icon}
|
||||
{:type :circle
|
||||
:name "Circle"
|
||||
:fill-color default-color}
|
||||
{:type :path
|
||||
:name "Path"
|
||||
:stroke-style :solid
|
||||
:stroke-color "#000000"
|
||||
:stroke-width 2
|
||||
:stroke-alignment :center
|
||||
:fill-color "#000000"
|
||||
:fill-opacity 0
|
||||
:segments []}
|
||||
{:type :frame
|
||||
:fill-opacity 1
|
||||
:stroke-style :none
|
||||
:stroke-alignment :center
|
||||
:name "Artboard"}
|
||||
{:type :curve
|
||||
:name "Path"
|
||||
:stroke-style :solid
|
||||
:stroke-width 0
|
||||
:stroke-color "#000000"
|
||||
:stroke-width 2
|
||||
:stroke-opacity 0
|
||||
:rx 0
|
||||
:ry 0}
|
||||
|
||||
{:type :image}
|
||||
|
||||
{:type :icon}
|
||||
|
||||
{:type :circle
|
||||
:name "Circle"
|
||||
:fill-color default-color
|
||||
:fill-opacity 1
|
||||
:stroke-style :none
|
||||
:stroke-alignment :center
|
||||
:stroke-width 0
|
||||
:stroke-color "#000000"
|
||||
:stroke-opacity 0}
|
||||
|
||||
{:type :path
|
||||
:name "Path"
|
||||
:fill-color "#000000"
|
||||
:fill-opacity 0
|
||||
:stroke-style :solid
|
||||
:stroke-alignment :center
|
||||
:stroke-width 2
|
||||
:stroke-color "#000000"
|
||||
:stroke-opacity 1
|
||||
:segments []}
|
||||
|
||||
{:type :frame
|
||||
:name "Artboard"
|
||||
:fill-color "#ffffff"
|
||||
:fill-opacity 1
|
||||
:stroke-style :none
|
||||
:stroke-alignment :center
|
||||
:stroke-width 0
|
||||
:stroke-color "#000000"
|
||||
:stroke-opacity 0}
|
||||
|
||||
{:type :curve
|
||||
:name "Path"
|
||||
:fill-color "#000000"
|
||||
:fill-opacity 0
|
||||
:stroke-style :solid
|
||||
:stroke-alignment :center
|
||||
:stroke-width 2
|
||||
:stroke-color "#000000"
|
||||
:stroke-opacity 1
|
||||
:segments []}
|
||||
|
||||
{:type :text
|
||||
:name "Text"
|
||||
:content nil}])
|
||||
|
|
|
@ -136,6 +136,16 @@
|
|||
(into selected children)))]
|
||||
(l/derived selector st/state)))
|
||||
|
||||
(def selected-objects-with-children
|
||||
(letfn [(selector [state]
|
||||
(let [selected (get-in state [:workspace-local :selected])
|
||||
page-id (get-in state [:workspace-page :id])
|
||||
objects (get-in state [:workspace-data page-id :objects])
|
||||
children (mapcat #(cph/get-children % objects) selected)
|
||||
accumulated (into selected children)]
|
||||
(mapv #(get objects %) accumulated)))]
|
||||
(l/derived selector st/state)))
|
||||
|
||||
(defn make-selected
|
||||
[id]
|
||||
(l/derived #(contains? % id) selected-shapes))
|
||||
|
|
|
@ -37,11 +37,11 @@
|
|||
|
||||
(mf/defc shape-options
|
||||
{::mf/wrap [#(mf/throttle % 60)]}
|
||||
[{:keys [shape page] :as props}]
|
||||
[{:keys [shape shapes-with-children page] :as props}]
|
||||
[:*
|
||||
(case (:type shape)
|
||||
:frame [:& frame/options {:shape shape}]
|
||||
:group [:& group/options {:shape shape}]
|
||||
:group [:& group/options {:shape shape :shape-with-children shapes-with-children}]
|
||||
:text [:& text/options {:shape shape}]
|
||||
:rect [:& rect/options {:shape shape}]
|
||||
:icon [:& icon/options {:shape shape}]
|
||||
|
@ -55,7 +55,7 @@
|
|||
|
||||
(mf/defc options-content
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [section shapes page] :as props}]
|
||||
[{:keys [section shapes shapes-with-children page] :as props}]
|
||||
(let [locale (mf/deref i18n/locale)]
|
||||
[:div.tool-window
|
||||
[:div.tool-window-content
|
||||
|
@ -67,8 +67,8 @@
|
|||
[:& align-options]
|
||||
(case (count shapes)
|
||||
0 [:& page/options {:page page}]
|
||||
1 [:& shape-options {:shape (first shapes)}]
|
||||
[:& multiple/options {:shapes shapes}])]]
|
||||
1 [:& shape-options {:shape (first shapes) :shapes-with-children shapes-with-children}]
|
||||
[:& multiple/options {:shapes shapes-with-children}])]]
|
||||
|
||||
[:& tab-element {:id :prototype
|
||||
:title (t locale "workspace.options.prototype")}
|
||||
|
@ -79,9 +79,11 @@
|
|||
(mf/defc options-toolbox
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [page local] :as props}]
|
||||
(let [section (:options-mode local)
|
||||
shapes (mf/deref refs/selected-objects)]
|
||||
(let [section (:options-mode local)
|
||||
shapes (mf/deref refs/selected-objects)
|
||||
shapes-with-children (mf/deref refs/selected-objects-with-children)]
|
||||
[:& options-content {:shapes shapes
|
||||
:shapes-with-children shapes-with-children
|
||||
:page page
|
||||
:section section}]))
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
(:require
|
||||
[rumext.alpha :as mf]
|
||||
[uxbox.common.geom.shapes :as geom]
|
||||
[uxbox.common.pages-helpers :as cph]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.data.workspace.texts :as dwt]
|
||||
[uxbox.main.ui.workspace.sidebar.options.multiple :refer [get-shape-attrs]]
|
||||
|
@ -28,19 +29,19 @@
|
|||
text-menu]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [shape] :as props}]
|
||||
(let [child-ids (:shapes shape)
|
||||
children (mf/deref (refs/objects-by-id child-ids))
|
||||
text-ids (map :id (filter #(= (:type %) :text) children))
|
||||
other-ids (map :id (filter #(not= (:type %) :text) children))
|
||||
[{:keys [shape shape-with-children] :as props}]
|
||||
(let [id (:id shape)
|
||||
ids-with-children (map :id shape-with-children)
|
||||
text-ids (map :id (filter #(= (:type %) :text) shape-with-children))
|
||||
other-ids (map :id (filter #(not= (:type %) :text) shape-with-children))
|
||||
|
||||
type (:type shape)
|
||||
type (:type shape) ; always be :group
|
||||
|
||||
measure-values
|
||||
(select-keys shape measure-attrs)
|
||||
|
||||
fill-values
|
||||
(geom/get-attrs-multi children fill-attrs)
|
||||
(geom/get-attrs-multi shape-with-children fill-attrs)
|
||||
|
||||
stroke-values
|
||||
(geom/get-attrs-multi (map #(get-shape-attrs
|
||||
|
@ -49,7 +50,7 @@
|
|||
nil
|
||||
nil
|
||||
nil)
|
||||
children)
|
||||
shape-with-children)
|
||||
stroke-attrs)
|
||||
|
||||
font-values
|
||||
|
@ -59,7 +60,7 @@
|
|||
text-font-attrs
|
||||
nil
|
||||
dwt/current-text-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-font-attrs)
|
||||
|
||||
align-values
|
||||
|
@ -69,7 +70,7 @@
|
|||
text-align-attrs
|
||||
nil
|
||||
dwt/current-paragraph-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-align-attrs)
|
||||
|
||||
spacing-values
|
||||
|
@ -79,7 +80,7 @@
|
|||
text-spacing-attrs
|
||||
nil
|
||||
dwt/current-text-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-spacing-attrs)
|
||||
|
||||
valign-values
|
||||
|
@ -89,7 +90,7 @@
|
|||
text-valign-attrs
|
||||
nil
|
||||
dwt/current-root-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-valign-attrs)
|
||||
|
||||
decoration-values
|
||||
|
@ -99,7 +100,7 @@
|
|||
text-decoration-attrs
|
||||
nil
|
||||
dwt/current-text-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-decoration-attrs)
|
||||
|
||||
transform-values
|
||||
|
@ -109,17 +110,17 @@
|
|||
text-transform-attrs
|
||||
nil
|
||||
dwt/current-text-values)
|
||||
children)
|
||||
shape-with-children)
|
||||
text-transform-attrs)]
|
||||
[:*
|
||||
[:& measures-menu {:ids [(:id shape)]
|
||||
[:& measures-menu {:ids [id]
|
||||
:type type
|
||||
:values measure-values}]
|
||||
[:& fill-menu {:ids child-ids
|
||||
[:& fill-menu {:ids ids-with-children
|
||||
:type type
|
||||
:values fill-values}]
|
||||
(when-not (empty? other-ids)
|
||||
[:& stroke-menu {:ids child-ids
|
||||
[:& stroke-menu {:ids other-ids
|
||||
:type type
|
||||
:values stroke-values}])
|
||||
(when-not (empty? text-ids)
|
||||
|
|
Loading…
Add table
Reference in a new issue