0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-12 07:41:43 -05:00

Changes to the selection in workspace and layers

This commit is contained in:
alonso.torres 2021-01-12 11:20:36 +01:00 committed by Andrey Antukh
parent bb07c4b3b7
commit 5f0020a95c
8 changed files with 104 additions and 32 deletions

View file

@ -261,6 +261,7 @@
(d/export gco/center-selrect)
(d/export gco/center-rect)
(d/export gco/center-points)
(d/export gco/make-centered-rect)
(d/export gpr/rect->selrect)
(d/export gpr/rect->points)

View file

@ -1527,9 +1527,11 @@
(d/export dws/select-all)
(d/export dws/deselect-all)
(d/export dwc/select-shapes)
(d/export dws/shift-select-shapes)
(d/export dws/duplicate-selected)
(d/export dws/handle-selection)
(d/export dws/select-inside-group)
(d/export dws/select-last-layer)
(d/export dwd/select-for-drawing)
(d/export dwc/clear-edition-mode)
(d/export dwc/add-shape)

View file

@ -105,6 +105,20 @@
objects (dwc/lookup-page-objects state page-id)]
(rx/of (dwc/expand-all-parents [id] objects)))))))
(defn shift-select-shapes
([id]
(ptk/reify ::shift-select-shapes
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id)
selection (-> state
(get-in [:workspace-local :selected] #{})
(conj id))]
(-> state
(assoc-in [:workspace-local :selected]
(cp/expand-region-selection objects selection))))))))
(defn select-shapes
[ids]
(us/verify ::ordered-set-of-uuid ids)
@ -184,24 +198,51 @@
(rx/map select-shapes))))))))
(defn select-inside-group
[group-id position]
(ptk/reify ::select-inside-group
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id)
group (get objects group-id)
children (map #(get objects %) (:shapes group))
([group-id position] (select-inside-group group-id position false))
([group-id position deep-children]
(ptk/reify ::select-inside-group
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id)
group (get objects group-id)
children (map #(get objects %) (:shapes group))
;; We need to reverse the children because if two children
;; overlap we want to select the one that's over (and it's
;; in the later vector position
selected (->> children
reverse
(d/seek #(geom/has-point? % position)))]
(when selected
(rx/of (deselect-all) (select-shape (:id selected))))))))
;; We need to reverse the children because if two children
;; overlap we want to select the one that's over (and it's
;; in the later vector position
selected (->> children
reverse
(d/seek #(geom/has-point? % position)))]
(when selected
(rx/of (deselect-all) (select-shape (:id selected)))))))))
(defn select-last-layer
([position]
(ptk/reify ::select-last-layer
ptk/WatchEvent
(watch [_ state stream]
(let [page-id (:current-page-id state)
objects (dwc/lookup-page-objects state page-id)
find-shape
(fn [selection]
(when (seq selection)
(let [id (first selection)
shape (get objects id)]
(let [child-id (->> (cp/get-children id objects)
(map #(get objects %))
(remove (comp empty :shapes))
(filter #(geom/has-point? % position))
(first)
:id)]
(or child-id id)))))]
(->> (uw/ask! {:cmd :selection/query
:page-id page-id
:rect (geom/make-centered-rect position 1 1)})
(rx/first)
(rx/map find-shape)
(rx/filter #(not (nil? %)))
(rx/map #(select-shape % false))))))))
;; --- Duplicate Shapes
(declare prepare-duplicate-change)

View file

@ -50,13 +50,12 @@
edition @refs/selected-edition
selected? (contains? selected id)
drawing? @refs/selected-drawing-tool
button (.-which (.-nativeEvent event))]
button (.-which (.-nativeEvent event))
shift? (kbd/shift? event)
ctrl? (kbd/ctrl? event)]
(when-not blocked
(cond
(not= 1 button)
nil
drawing?
(or (not= 1 button) drawing? ctrl?)
nil
(= type :frame)
@ -68,13 +67,34 @@
:else
(do
(dom/stop-propagation event)
(if selected?
(when (kbd/shift? event)
(st/emit! (dw/select-shape id true)))
(do
(when-not (or (empty? selected) (kbd/shift? event))
(st/emit! (dw/deselect-all)))
(st/emit! (dw/select-shape id))))
(when (not= edition id)
(st/emit! (dw/start-move-selected))))))))))
(let [toggle-selected? (and selected? shift?)
deselect? (and (not selected?) (not (empty? selected)) (not shift?))]
(apply
st/emit!
(cond-> []
;; Deselect shapes before doing a selection or click outside
deselect?
(conj (dw/deselect-all))
;; Shift click to add a shape to the selection
toggle-selected?
(conj (dw/select-shape id true))
;; Simple click to select
(not selected?)
(conj (dw/select-shape id))
;; Mouse down to start moving a shape
(not= edition id)
(conj (dw/start-move-selected))))))))))))
(defn use-double-click
"This effect will consume the event and stop the propagation so double clicks on shapes
will not select the frame"
[{:keys [id]}]
(mf/use-callback
(mf/deps id)
(fn [event]
(dom/stop-propagation event)
(dom/prevent-default event))))

View file

@ -21,6 +21,7 @@
(let [shape (unchecked-get props "shape")]
[:> shape-container {:shape shape
:on-mouse-down (we/use-mouse-down shape)
:on-double-click (we/use-double-click shape)
:on-context-menu (we/use-context-menu shape)
:on-pointer-over (we/use-pointer-enter shape)
:on-pointer-out (we/use-pointer-leave shape)}

View file

@ -50,10 +50,11 @@
tag (get-in shape [:content :tag])
handle-mouse-down (we/use-mouse-down shape)
handle-mouse-down (we/use-mouse-down shape)
handle-context-menu (we/use-context-menu shape)
handle-pointer-enter (we/use-pointer-enter shape)
handle-pointer-leave (we/use-pointer-leave shape)
handle-double-click (we/use-double-click shape)
def-ctx? (mf/use-ctx muc/def-ctx)]
@ -74,6 +75,7 @@
:height height
:fill "transparent"
:on-mouse-down handle-mouse-down
:on-double-click handle-double-click
:on-context-menu handle-context-menu
:on-pointer-over handle-pointer-enter
:on-pointer-out handle-pointer-leave}])]

View file

@ -141,6 +141,9 @@
nil
(.-shiftKey event)
(st/emit! (dw/shift-select-shapes id))
(.-ctrlKey event)
(st/emit! (dw/select-shape id true))
(> (count selected) 1)

View file

@ -326,7 +326,9 @@
(let [ctrl? (kbd/ctrl? event)
shift? (kbd/shift? event)
alt? (kbd/alt? event)]
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?)))))
(if ctrl?
(st/emit! (dw/select-last-layer @ms/mouse-position))
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?))))))
on-double-click
(mf/use-callback