Incremental area selection

This commit is contained in:
alonso.torres 2021-07-08 17:37:21 +02:00
parent 3a64efd136
commit 55d2acdf13
9 changed files with 41 additions and 22 deletions

View file

@ -14,7 +14,8 @@
- Preserve components if possible, when pasted into a different file [Taiga #1063](https://tree.taiga.io/project/penpot/issue/1063). - Preserve components if possible, when pasted into a different file [Taiga #1063](https://tree.taiga.io/project/penpot/issue/1063).
- Add the ability to offload file data to a cheaper storage when file becomes inactive. - Add the ability to offload file data to a cheaper storage when file becomes inactive.
- Import/Export Penpot files from dashboard. - Import/Export Penpot files from dashboard.
- Double click won't make a shape a path until you change a node [Taiga #] - Double click won't make a shape a path until you change a node [Taiga #1796](https://tree.taiga.io/project/penpot/us/1796)
- Incremental area selection [#779](https://github.com/penpot/penpot/discussions/779)
### :bug: Bugs fixed ### :bug: Bugs fixed

View file

@ -208,3 +208,4 @@
(d/export gin/overlaps?) (d/export gin/overlaps?)
(d/export gin/has-point?) (d/export gin/has-point?)
(d/export gin/has-point-rect?) (d/export gin/has-point-rect?)
(d/export gin/rect-contains-shape?)

View file

@ -302,3 +302,9 @@
(let [lines (points->lines (:points shape))] (let [lines (points->lines (:points shape))]
;; TODO: Will only work for simple shapes ;; TODO: Will only work for simple shapes
(is-point-inside-evenodd? point lines))) (is-point-inside-evenodd? point lines)))
(defn rect-contains-shape?
[rect shape]
(->> shape
:points
(every? (partial has-point-rect? rect))))

View file

@ -1843,7 +1843,7 @@
(d/export dwc/select-shapes) (d/export dwc/select-shapes)
(d/export dws/shift-select-shapes) (d/export dws/shift-select-shapes)
(d/export dws/duplicate-selected) (d/export dws/duplicate-selected)
(d/export dws/handle-selection) (d/export dws/handle-area-selection)
(d/export dws/select-inside-group) (d/export dws/select-inside-group)
(d/export dwd/select-for-drawing) (d/export dwd/select-for-drawing)
(d/export dwc/clear-edition-mode) (d/export dwc/clear-edition-mode)

View file

@ -28,7 +28,7 @@
(d/export edition/move-selected) (d/export edition/move-selected)
;; Selection ;; Selection
(d/export selection/handle-selection) (d/export selection/handle-area-selection)
(d/export selection/select-node) (d/export selection/select-node)
(d/export selection/path-handler-enter) (d/export selection/path-handler-enter)
(d/export selection/path-handler-leave) (d/export selection/path-handler-leave)

View file

@ -101,12 +101,12 @@
(update [_ state] (update [_ state]
(update state :workspace-local dissoc :selrect)))) (update state :workspace-local dissoc :selrect))))
(defn handle-selection (defn handle-area-selection
[shift?] [shift?]
(letfn [(valid-rect? [{width :width height :height}] (letfn [(valid-rect? [{width :width height :height}]
(or (> width 10) (> height 10)))] (or (> width 10) (> height 10)))]
(ptk/reify ::handle-selection (ptk/reify ::handle-area-selection
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ stream] (watch [_ _ stream]
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event))) (let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))

View file

@ -45,7 +45,7 @@
(update [_ state] (update [_ state]
(assoc-in state [:workspace-local :selrect] selrect)))) (assoc-in state [:workspace-local :selrect] selrect))))
(defn handle-selection (defn handle-area-selection
[preserve?] [preserve?]
(letfn [(data->selrect [data] (letfn [(data->selrect [data]
(let [start (:start data) (let [start (:start data)
@ -59,10 +59,11 @@
:y start-y :y start-y
:width (mth/abs (- end-x start-x)) :width (mth/abs (- end-x start-x))
:height (mth/abs (- end-y start-y))}))] :height (mth/abs (- end-y start-y))}))]
(ptk/reify ::handle-selection (ptk/reify ::handle-area-selection
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ stream] (watch [_ state stream]
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event))) (let [zoom (get-in state [:workspace-local :zoom] 1)
stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
stoper (->> stream (rx/filter stop?))] stoper (->> stream (rx/filter stop?))]
(rx/concat (rx/concat
(when-not preserve? (when-not preserve?
@ -74,11 +75,16 @@
{:start pos :stop pos})) {:start pos :stop pos}))
nil) nil)
(rx/map data->selrect) (rx/map data->selrect)
(rx/filter #(or (> (:width %) 10) (rx/filter #(or (> (:width %) (/ 10 zoom))
(> (:height %) 10))) (> (:height %) (/ 10 zoom))))
(rx/map update-selrect)
(rx/flat-map
(fn [selrect]
(rx/of (update-selrect selrect)
(select-shapes-by-current-selrect preserve?))))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (select-shapes-by-current-selrect preserve?)))))))) (rx/of (update-selrect nil))))))))
;; --- Toggle shape's selection status (selected or deselected) ;; --- Toggle shape's selection status (selected or deselected)
@ -214,11 +220,12 @@
selrect (get-in state [:workspace-local :selrect]) selrect (get-in state [:workspace-local :selrect])
blocked? (fn [id] (get-in objects [id :blocked] false))] blocked? (fn [id] (get-in objects [id :blocked] false))]
(rx/merge (rx/merge
(rx/of (update-selrect nil))
(when selrect (when selrect
(->> (uw/ask! {:cmd :selection/query (->> (uw/ask! {:cmd :selection/query
:page-id page-id :page-id page-id
:rect selrect}) :rect selrect
:include-frames? true
:full-frame? true})
(rx/map #(cp/clean-loops objects %)) (rx/map #(cp/clean-loops objects %))
(rx/map #(into initial-set (filter (comp not blocked?)) %)) (rx/map #(into initial-set (filter (comp not blocked?)) %))
(rx/map select-shapes)))))))) (rx/map select-shapes))))))))

View file

@ -67,10 +67,10 @@
node-editing? node-editing?
;; Handle path node area selection ;; Handle path node area selection
(st/emit! (dwdp/handle-selection shift?)) (st/emit! (dwdp/handle-area-selection shift?))
(or (not id) (and frame? (not selected?))) (or (not id) (and frame? (not selected?)))
(st/emit! (dw/handle-selection shift?)) (st/emit! (dw/handle-area-selection shift?))
(not drawing-tool) (not drawing-tool)
(st/emit! (when (or shift? (not selected?)) (st/emit! (when (or shift? (not selected?))

View file

@ -84,7 +84,7 @@
(create-index new-objects))) (create-index new-objects)))
(defn- query-index (defn- query-index
[{index :index z-index :z-index} rect frame-id include-frames? include-groups? reverse?] [{index :index z-index :z-index} rect frame-id include-frames? full-frame? include-groups? reverse?]
(let [result (-> (qdt/search index (clj->js rect)) (let [result (-> (qdt/search index (clj->js rect))
(es6-iterator-seq)) (es6-iterator-seq))
@ -97,7 +97,11 @@
(case (:type shape) (case (:type shape)
:frame include-frames? :frame include-frames?
:group include-groups? :group include-groups?
true))) true)
(or (not full-frame?)
(not= :frame (:type shape))
(gsh/rect-contains-shape? rect shape))))
overlaps? overlaps?
(fn [shape] (fn [shape]
@ -151,10 +155,10 @@
nil) nil)
(defmethod impl/handler :selection/query (defmethod impl/handler :selection/query
[{:keys [page-id rect frame-id include-frames? include-groups? reverse?] [{:keys [page-id rect frame-id include-frames? full-frame? include-groups? reverse?]
:or {include-groups? true reverse? false} :as message}] :or {include-groups? true reverse? false include-frames? false full-frame? false} :as message}]
(when-let [index (get @state page-id)] (when-let [index (get @state page-id)]
(query-index index rect frame-id include-frames? include-groups? reverse?))) (query-index index rect frame-id include-frames? full-frame? include-groups? reverse?)))
(defmethod impl/handler :selection/query-z-index (defmethod impl/handler :selection/query-z-index
[{:keys [page-id objects ids]}] [{:keys [page-id objects ids]}]