mirror of
https://github.com/penpot/penpot.git
synced 2025-05-29 23:36:11 +02:00
✨ Allow selection of elements inside group
This commit is contained in:
parent
57b2141166
commit
9d0b71a36c
3 changed files with 65 additions and 19 deletions
|
@ -1485,6 +1485,27 @@
|
||||||
(when-not (empty? rch)
|
(when-not (empty? rch)
|
||||||
(rx/of (commit-changes rch uch {:commit-local? true}))))))))
|
(rx/of (commit-changes rch uch {:commit-local? true}))))))))
|
||||||
|
|
||||||
|
(defn- adjust-group-shapes [state ids]
|
||||||
|
(let [page-id (::page-id state)
|
||||||
|
objects (get-in state [:workspace-data page-id :objects])
|
||||||
|
groups-to-adjust (->> ids
|
||||||
|
(map #(helpers/get-parent % objects))
|
||||||
|
(map #(get objects %))
|
||||||
|
(filter #(= (:type %) :group))
|
||||||
|
(map #(:id %))
|
||||||
|
distinct)
|
||||||
|
|
||||||
|
update-group
|
||||||
|
(fn [group]
|
||||||
|
(let [group-objects (map #(get objects %) (:shapes group))
|
||||||
|
selrect (geom/selection-rect group-objects)]
|
||||||
|
(merge group (select-keys selrect [:x :y :width :height]))))
|
||||||
|
|
||||||
|
reduce-fn
|
||||||
|
#(update-in %1 [:workspace-data page-id :objects %2] update-group)]
|
||||||
|
|
||||||
|
(reduce reduce-fn state groups-to-adjust)))
|
||||||
|
|
||||||
(defn assoc-resize-modifier-in-bulk
|
(defn assoc-resize-modifier-in-bulk
|
||||||
[ids xfmt]
|
[ids xfmt]
|
||||||
(us/verify ::set-of-uuid ids)
|
(us/verify ::set-of-uuid ids)
|
||||||
|
@ -1530,7 +1551,10 @@
|
||||||
(-> state
|
(-> state
|
||||||
(materialize-shape id mtx)
|
(materialize-shape id mtx)
|
||||||
(materialize-children id mtx)))))]
|
(materialize-children id mtx)))))]
|
||||||
(reduce update-shapes state ids)))
|
|
||||||
|
(as-> state $
|
||||||
|
(reduce update-shapes $ ids)
|
||||||
|
(adjust-group-shapes $ ids))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
|
@ -1558,6 +1582,7 @@
|
||||||
(assoc-in state [:workspace-data page-id :objects id]))))]
|
(assoc-in state [:workspace-data page-id :objects id]))))]
|
||||||
(reduce rfn state ids)))))
|
(reduce rfn state ids)))))
|
||||||
|
|
||||||
|
|
||||||
(defn materialize-displacement-in-bulk
|
(defn materialize-displacement-in-bulk
|
||||||
[ids]
|
[ids]
|
||||||
(ptk/reify ::materialize-displacement-in-bulk
|
(ptk/reify ::materialize-displacement-in-bulk
|
||||||
|
@ -1590,7 +1615,9 @@
|
||||||
(materialize-shape id mtx)
|
(materialize-shape id mtx)
|
||||||
(materialize-children id mtx))))]
|
(materialize-children id mtx))))]
|
||||||
|
|
||||||
(reduce update-shapes state ids)))
|
(as-> state $
|
||||||
|
(reduce update-shapes $ ids)
|
||||||
|
(adjust-group-shapes $ ids))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
(:require [lentes.core :as l]
|
(:require [lentes.core :as l]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[uxbox.main.constants :as c]
|
[uxbox.main.constants :as c]
|
||||||
[uxbox.main.store :as st]))
|
[uxbox.main.store :as st]
|
||||||
|
[uxbox.main.data.helpers :as helpers]))
|
||||||
|
|
||||||
(def profile
|
(def profile
|
||||||
(-> (l/key :profile)
|
(-> (l/key :profile)
|
||||||
|
@ -62,10 +63,24 @@
|
||||||
|
|
||||||
(defn objects-by-id [ids]
|
(defn objects-by-id [ids]
|
||||||
(let [set-ids (set ids)]
|
(let [set-ids (set ids)]
|
||||||
(-> (l/lens #(let [page-id (get-in % [:workspace-page :id])
|
(-> (l/lens (fn [state]
|
||||||
objects (get-in % [:workspace-data page-id :objects])]
|
(let [page-id (get-in state [:workspace-page :id])
|
||||||
(filter (fn [it] (set-ids (:id it))) (vals objects))))
|
objects (get-in state [:workspace-data page-id :objects])]
|
||||||
(l/derive st/state))))
|
(mapv #(get objects %) set-ids))))
|
||||||
|
(l/derive st/state))))
|
||||||
|
|
||||||
|
(defn is-child-selected? [id]
|
||||||
|
(let [is-child-selector
|
||||||
|
(fn [state]
|
||||||
|
(let [page-id (get-in state [:workspace-page :id])
|
||||||
|
objects (get-in state [:workspace-data page-id :objects])
|
||||||
|
selected (get-in state [:workspace-local :selected])
|
||||||
|
shape (get objects id)
|
||||||
|
children (helpers/get-children id objects)]
|
||||||
|
(some selected children)))]
|
||||||
|
|
||||||
|
(-> (l/lens is-child-selector)
|
||||||
|
(l/derive st/state))))
|
||||||
|
|
||||||
(def selected-shapes
|
(def selected-shapes
|
||||||
(-> (l/key :selected)
|
(-> (l/key :selected)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
[uxbox.main.ui.shapes.common :as common]
|
[uxbox.main.ui.shapes.common :as common]
|
||||||
[uxbox.main.ui.shapes.attrs :as attrs]))
|
[uxbox.main.ui.shapes.attrs :as attrs]))
|
||||||
|
|
||||||
(defonce ^:dynamic *debug* (atom false))
|
(defonce ^:dynamic *debug* (atom true))
|
||||||
|
|
||||||
(declare translate-to-frame)
|
(declare translate-to-frame)
|
||||||
(declare group-shape)
|
(declare group-shape)
|
||||||
|
@ -29,6 +29,7 @@
|
||||||
on-mouse-down #(common/on-mouse-down % shape)
|
on-mouse-down #(common/on-mouse-down % shape)
|
||||||
on-context-menu #(common/on-context-menu % shape)
|
on-context-menu #(common/on-context-menu % shape)
|
||||||
children (-> (refs/objects-by-id (:shapes shape)) mf/deref)
|
children (-> (refs/objects-by-id (:shapes shape)) mf/deref)
|
||||||
|
is-child-selected? (-> (refs/is-child-selected? (:id shape)) mf/deref)
|
||||||
on-double-click
|
on-double-click
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
|
@ -40,7 +41,8 @@
|
||||||
:on-double-click on-double-click}
|
:on-double-click on-double-click}
|
||||||
[:& (group-shape shape-wrapper) {:frame frame
|
[:& (group-shape shape-wrapper) {:frame frame
|
||||||
:shape (geom/transform-shape frame shape)
|
:shape (geom/transform-shape frame shape)
|
||||||
:children children}]])))
|
:children children
|
||||||
|
:is-child-selected? is-child-selected?}]])))
|
||||||
|
|
||||||
(defn group-shape [shape-wrapper]
|
(defn group-shape [shape-wrapper]
|
||||||
(mf/fnc group-shape
|
(mf/fnc group-shape
|
||||||
|
@ -49,6 +51,7 @@
|
||||||
(let [frame (unchecked-get props "frame")
|
(let [frame (unchecked-get props "frame")
|
||||||
shape (unchecked-get props "shape")
|
shape (unchecked-get props "shape")
|
||||||
children (unchecked-get props "children")
|
children (unchecked-get props "children")
|
||||||
|
is-child-selected? (unchecked-get props "is-child-selected?")
|
||||||
{:keys [id x y width height rotation
|
{:keys [id x y width height rotation
|
||||||
displacement-modifier
|
displacement-modifier
|
||||||
resize-modifier]} shape
|
resize-modifier]} shape
|
||||||
|
@ -61,17 +64,18 @@
|
||||||
[:g {:transform transform}
|
[:g {:transform transform}
|
||||||
(for [item children]
|
(for [item children]
|
||||||
[:& shape-wrapper {:frame frame
|
[:& shape-wrapper {:frame frame
|
||||||
:shape (-> item
|
:shape (cond-> item
|
||||||
(assoc :displacement-modifier displacement-modifier)
|
displacement-modifier (assoc :displacement-modifier displacement-modifier)
|
||||||
(assoc :resize-modifier resize-modifier))
|
resize-modifier (assoc :resize-modifier resize-modifier))
|
||||||
:key (:id item)}])
|
:key (:id item)}])
|
||||||
|
|
||||||
[:rect {:x x
|
(when (not is-child-selected?)
|
||||||
:y y
|
[:rect {:x x
|
||||||
:fill (if (deref *debug*) "red" "transparent")
|
:y y
|
||||||
:opacity 0.8
|
:fill (if (deref *debug*) "red" "transparent")
|
||||||
:id (str "group-" id)
|
:opacity 0.8
|
||||||
:width width
|
:id (str "group-" id)
|
||||||
:height height}]])))
|
:width width
|
||||||
|
:height height}])])))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue