mirror of
https://github.com/penpot/penpot.git
synced 2025-04-15 16:31:25 -05:00
🐛 Fix box selection for components and nested frames
This commit is contained in:
parent
9e24ba7b39
commit
942f6167b0
4 changed files with 67 additions and 32 deletions
frontend/src/app
|
@ -59,7 +59,7 @@
|
|||
(assoc-in state [:workspace-local :selrect] selrect))))
|
||||
|
||||
(defn handle-area-selection
|
||||
[preserve? ignore-groups?]
|
||||
[preserve?]
|
||||
(ptk/reify ::handle-area-selection
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
|
@ -114,7 +114,20 @@
|
|||
(rx/buffer-time 100)
|
||||
(rx/map last)
|
||||
(rx/pipe (rxo/distinct-contiguous))
|
||||
(rx/map #(select-shapes-by-current-selrect preserve? ignore-groups?))))
|
||||
(rx/with-latest-from ms/keyboard-mod ms/keyboard-shift)
|
||||
(rx/map
|
||||
(fn [[_ mod? shift?]]
|
||||
(select-shapes-by-current-selrect shift? mod?))))
|
||||
|
||||
;; The last "tick" from the mouse cannot be buffered so we are sure
|
||||
;; a selection is returned. Without this we can have empty selections on
|
||||
;; very fast movement
|
||||
(->> selrect-stream
|
||||
(rx/last)
|
||||
(rx/with-latest-from ms/keyboard-mod ms/keyboard-shift)
|
||||
(rx/map
|
||||
(fn [[_ mod? shift?]]
|
||||
(select-shapes-by-current-selrect shift? mod? false)))))
|
||||
|
||||
(->> (rx/of (update-selrect nil))
|
||||
;; We need the async so the current event finishes before updating the selrect
|
||||
|
@ -307,34 +320,39 @@
|
|||
;; --- Select Shapes (By selrect)
|
||||
|
||||
(defn select-shapes-by-current-selrect
|
||||
[preserve? ignore-groups?]
|
||||
(ptk/reify ::select-shapes-by-current-selrect
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state)
|
||||
initial-set (if preserve?
|
||||
selected
|
||||
lks/empty-linked-set)
|
||||
selrect (dm/get-in state [:workspace-local :selrect])
|
||||
blocked? (fn [id] (dm/get-in objects [id :blocked] false))]
|
||||
([preserve? ignore-groups?]
|
||||
(select-shapes-by-current-selrect preserve? ignore-groups? true))
|
||||
([preserve? ignore-groups? buffered?]
|
||||
(ptk/reify ::select-shapes-by-current-selrect
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state)
|
||||
selected (wsh/lookup-selected state)
|
||||
initial-set (if preserve?
|
||||
selected
|
||||
lks/empty-linked-set)
|
||||
selrect (dm/get-in state [:workspace-local :selrect])
|
||||
blocked? (fn [id] (dm/get-in objects [id :blocked] false))
|
||||
|
||||
(when selrect
|
||||
(rx/empty)
|
||||
(->> (uw/ask-buffered!
|
||||
{:cmd :selection/query
|
||||
:page-id page-id
|
||||
:rect selrect
|
||||
:include-frames? true
|
||||
:ignore-groups? ignore-groups?
|
||||
:full-frame? true
|
||||
:using-selrect? true})
|
||||
(rx/map #(cfh/clean-loops objects %))
|
||||
(rx/map #(into initial-set (comp
|
||||
(filter (complement blocked?))
|
||||
(remove (partial cfh/hidden-parent? objects))) %))
|
||||
(rx/map select-shapes)))))))
|
||||
ask-worker (if buffered? uw/ask-buffered! uw/ask!)]
|
||||
|
||||
(if (some? selrect)
|
||||
(->> (ask-worker
|
||||
{:cmd :selection/query
|
||||
:page-id page-id
|
||||
:rect selrect
|
||||
:include-frames? true
|
||||
:ignore-groups? ignore-groups?
|
||||
:full-frame? true
|
||||
:using-selrect? true})
|
||||
(rx/filter some?)
|
||||
(rx/map #(cfh/clean-loops objects %))
|
||||
(rx/map #(into initial-set (comp
|
||||
(filter (complement blocked?))
|
||||
(remove (partial cfh/hidden-parent? objects))) %))
|
||||
(rx/map select-shapes))
|
||||
(rx/empty)))))))
|
||||
|
||||
(defn select-inside-group
|
||||
[group-id position]
|
||||
|
|
|
@ -112,6 +112,20 @@
|
|||
(rx/sub! ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-shift
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> keyboard
|
||||
(rx/filter kbd/shift-key?)
|
||||
(rx/map kbd/key-down-event?)
|
||||
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||
;; shortcuts, that makes keyboard-alt stream
|
||||
;; registering the key pressed but on blurring the
|
||||
;; window (unfocus) the key down is never arrived.
|
||||
(rx/merge window-blur)
|
||||
(rx/pipe (rxo/distinct-contiguous)))]
|
||||
(rx/sub! ob sub)
|
||||
sub))
|
||||
|
||||
(defonce keyboard-meta
|
||||
(let [sub (rx/behavior-subject nil)
|
||||
ob (->> keyboard
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
(st/emit! (dd/start-drawing drawing-tool)))
|
||||
|
||||
(or (not id) mod?)
|
||||
(st/emit! (dw/handle-area-selection shift? mod?))
|
||||
(st/emit! (dw/handle-area-selection shift?))
|
||||
|
||||
(not drawing-tool)
|
||||
(when-not workspace-read-only?
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
match-criteria?
|
||||
(fn [shape]
|
||||
(and (not (:hidden shape))
|
||||
(or (= :frame (:type shape)) ;; We return frames even if blocked
|
||||
(or (cfh/frame-shape? shape) ;; We return frames even if blocked
|
||||
(not (:blocked shape)))
|
||||
(or (not frame-id) (= frame-id (:frame-id shape)))
|
||||
(case (:type shape)
|
||||
|
@ -135,8 +135,11 @@
|
|||
(:bool :group) (not ignore-groups?)
|
||||
true)
|
||||
|
||||
;; This condition controls when to check for overlapping. Otherwise the
|
||||
;; shape needs to be fully contained.
|
||||
(or (not full-frame?)
|
||||
(not= :frame (:type shape))
|
||||
(and (not ignore-groups?) (contains? shape :component-id))
|
||||
(and (not ignore-groups?) (not (cfh/root-frame? shape)))
|
||||
(and (d/not-empty? (:shapes shape))
|
||||
(gsh/rect-contains-shape? rect shape))
|
||||
(and (empty? (:shapes shape))
|
||||
|
|
Loading…
Add table
Reference in a new issue