mirror of
https://github.com/penpot/penpot.git
synced 2025-07-01 23:17:17 +02:00
Add better shapes selection algorithm.
This commit is contained in:
parent
59e327ae0e
commit
00679d9c68
2 changed files with 30 additions and 47 deletions
|
@ -311,36 +311,12 @@
|
||||||
|
|
||||||
;; --- Select Shapes
|
;; --- Select Shapes
|
||||||
|
|
||||||
(defn- not-blocked-group?
|
|
||||||
"Check if the shape is a blocked group."
|
|
||||||
[shape]
|
|
||||||
(and (not (:blocked shape))
|
|
||||||
(= :group (:type shape))))
|
|
||||||
|
|
||||||
(defn- has-blocked-parent?
|
|
||||||
"Check if shape has blocked parent."
|
|
||||||
[shape]
|
|
||||||
(geom/parent-satisfies? shape :blocked))
|
|
||||||
|
|
||||||
(defn- has-locked-parent?
|
|
||||||
[shape]
|
|
||||||
(geom/parent-satisfies? shape :locked))
|
|
||||||
|
|
||||||
(defrecord SelectShapes [selrect]
|
(defrecord SelectShapes [selrect]
|
||||||
rs/UpdateEvent
|
rs/UpdateEvent
|
||||||
(-apply-update [_ state]
|
(-apply-update [_ state]
|
||||||
(let [pageid (get-in state [:workspace :page])
|
(let [page (get-in state [:workspace :page])
|
||||||
xform (comp (filter #(= (:page %) pageid))
|
shapes (stsh/match-by-selrect state page selrect)]
|
||||||
(remove :hidden)
|
(assoc-in state [:workspace :selected] shapes))))
|
||||||
(remove :blocked)
|
|
||||||
(remove not-blocked-group?)
|
|
||||||
(remove has-locked-parent?)
|
|
||||||
(remove has-blocked-parent?)
|
|
||||||
(map geom/outer-rect)
|
|
||||||
(filter #(geom/contained-in? % selrect))
|
|
||||||
(map :id))]
|
|
||||||
(->> (into #{} xform (vals (:shapes-by-id state)))
|
|
||||||
(assoc-in state [:workspace :selected])))))
|
|
||||||
|
|
||||||
(defn select-shapes
|
(defn select-shapes
|
||||||
"Select shapes that matches the select rect."
|
"Select shapes that matches the select rect."
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns uxbox.state.shapes
|
(ns uxbox.state.shapes
|
||||||
"A collection of functions for manage shapes insinde the state."
|
"A collection of functions for manage shapes insinde the state."
|
||||||
(:require [uxbox.util.data :refer (index-of)]))
|
(:require [uxbox.util.data :refer (index-of)]
|
||||||
|
[uxbox.util.geom :as geom]))
|
||||||
|
|
||||||
;; --- Shape Creation
|
;; --- Shape Creation
|
||||||
|
|
||||||
|
@ -235,24 +236,30 @@
|
||||||
:bottom (drop-relative state :last shape)
|
:bottom (drop-relative state :last shape)
|
||||||
(throw (ex-info "Invalid data" {}))))
|
(throw (ex-info "Invalid data" {}))))
|
||||||
|
|
||||||
;; --- Shape Packing
|
;; --- Shape Selection
|
||||||
|
|
||||||
;; (defn- deep-scan-shape-ids
|
(defn- try-match-shape
|
||||||
;; [state acc id]
|
[xf selrect acc {:keys [type id items] :as shape}]
|
||||||
;; (let [shape (get-in state [:shapes-by-id id])]
|
(cond
|
||||||
;; (if (= (:type shape) :group)
|
(geom/contained-in? shape selrect)
|
||||||
;; (reduce (partial deep-scan-shape-ids state)
|
(conj acc id)
|
||||||
;; (conj acc id)
|
|
||||||
;; (:items shape))
|
|
||||||
;; (conj acc id))))
|
|
||||||
|
|
||||||
;; (defn pack-shape
|
(:locked shape)
|
||||||
;; [state id]
|
acc
|
||||||
;; (let [ids (deep-scan-shape-ids state #{} id)
|
|
||||||
;; index (reduce (fn [acc id]
|
(= type :group)
|
||||||
;; (let [shape (get-in state [:shapes-by-id id])]
|
(reduce (partial try-match-shape xf selrect)
|
||||||
;; (assoc acc id shape)))
|
acc (sequence xf items))
|
||||||
;; {} ids)]
|
|
||||||
;; {:type :packed-shape
|
:else
|
||||||
;; :index index
|
acc))
|
||||||
;; :id id}))
|
|
||||||
|
(defn match-by-selrect
|
||||||
|
[state page selrect]
|
||||||
|
(let [xf (comp (map #(get-in state [:shapes-by-id %]))
|
||||||
|
(remove :hidden)
|
||||||
|
(remove :blocked)
|
||||||
|
(map geom/outer-rect))
|
||||||
|
match (partial try-match-shape xf selrect)
|
||||||
|
shapes (get-in state [:pages-by-id page :shapes])]
|
||||||
|
(reduce match #{} (sequence xf shapes))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue