0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-16 00:41:25 -05:00

Select path nodes in area

This commit is contained in:
alonso.torres 2021-03-30 17:13:05 +02:00 committed by Andrés Moya
parent bb719d6211
commit a06a8c648e
8 changed files with 112 additions and 26 deletions
common/app/common/geom
frontend/src/app/main
data/workspace
ui/workspace

View file

@ -253,3 +253,4 @@
;; Intersection
(d/export gin/overlaps?)
(d/export gin/has-point?)
(d/export gin/has-point-rect?)

View file

@ -285,6 +285,11 @@
(or (not path?) (overlaps-path? shape rect))
(or (not circle?) (overlaps-ellipse? shape rect))))))
(defn has-point-rect?
[rect point]
(let [lines (gpr/rect->lines rect)]
(is-point-inside-evenodd? point lines)))
(defn has-point?
"Check if the shape contains a point"
[shape point]

View file

@ -19,6 +19,12 @@
(gpt/point (+ x width) (+ y height))
(gpt/point x (+ y height))])
(defn rect->lines [{:keys [x y width height]}]
[[(gpt/point x y) (gpt/point (+ x width) y)]
[(gpt/point (+ x width) y) (gpt/point (+ x width) (+ y height))]
[(gpt/point (+ x width) (+ y height)) (gpt/point x (+ y height))]
[(gpt/point x (+ y height)) (gpt/point x y)]])
(defn points->rect
[points]
(let [minx (transduce gco/map-x-xf min ##Inf points)

View file

@ -732,7 +732,23 @@
(-> state
(update-in [:workspace-local :edit-path id :selected-handlers] (fnil conj #{}) [index type]))))))
(defn select-node [position]
(defn select-node-area [shift?]
(ptk/reify ::select-node-area
ptk/UpdateEvent
(update [_ state]
(let [selrect (get-in state [:workspace-local :selrect])
id (get-in state [:workspace-local :edition])
content (get-in state (get-path state :content))
selected-point? (fn [point]
(gsh/has-point-rect? selrect point))
positions (into #{}
(comp (map (comp gpt/point :params))
(filter selected-point?))
content)]
(-> state
(assoc-in [:workspace-local :edit-path id :selected-points] positions))))))
(defn select-node [position shift?]
(ptk/reify ::select-node
ptk/UpdateEvent
(update [_ state]
@ -740,7 +756,7 @@
(-> state
(assoc-in [:workspace-local :edit-path id :selected-points] #{position}))))))
(defn deselect-node [position]
(defn deselect-node [position shift?]
(ptk/reify ::deselect-node
ptk/UpdateEvent
(update [_ state]
@ -858,3 +874,54 @@
(rx/filter #(= % :interrupt))
(rx/take 1)
(rx/map #(stop-path-edit))))))))
(defn update-area-selection
[selrect]
(ptk/reify ::update-area-selection
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :selrect] selrect))))
(defn clear-area-selection
[]
(ptk/reify ::clear-area-selection
ptk/UpdateEvent
(update [_ state]
(update state :workspace-local dissoc :selrect))))
(defn handle-selection
[shift?]
(letfn [(data->selrect [data]
(let [start (:start data)
stop (:stop data)
start-x (min (:x start) (:x stop))
start-y (min (:y start) (:y stop))
end-x (max (:x start) (:x stop))
end-y (max (:y start) (:y stop))]
{:x start-x
:y start-y
:width (mth/abs (- end-x start-x))
:height (mth/abs (- end-y start-y))}))]
(ptk/reify ::handle-selection
ptk/WatchEvent
(watch [_ state stream]
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
stoper (->> stream (rx/filter stop?))]
(rx/concat
#_(when-not preserve?
(rx/of (deselect-all)))
(->> ms/mouse-position
(rx/scan (fn [data pos]
(if data
(assoc data :stop pos)
{:start pos :stop pos}))
nil)
(rx/map data->selrect)
(rx/filter #(or (> (:width %) 10)
(> (:height %) 10)))
(rx/map update-area-selection)
(rx/take-until stoper))
(rx/of (select-node-area shift?)
(clear-area-selection))
#_(rx/of (select-shapes-by-current-selrect preserve?))))))))

View file

@ -60,9 +60,8 @@
(ptk/reify ::handle-selection
ptk/WatchEvent
(watch [_ state stream]
(let [stoper (rx/filter #(or (dwc/interrupt? %)
(ms/mouse-up? %))
stream)]
(let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
stoper (->> stream (rx/filter stop?))]
(rx/concat
(when-not preserve?
(rx/of (deselect-all)))

View file

@ -15,7 +15,9 @@
[app.util.dom :as dom]
[app.util.geom.path :as ugp]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.alpha :as mf]
[app.util.keyboard :as kbd])
(:import goog.events.EventType))
(mf/defc path-point [{:keys [position zoom edit-mode hover? selected? preview? start-path? last-p?]}]
@ -35,12 +37,13 @@
(dom/stop-propagation event)
(dom/prevent-default event)
(cond
(and (= edit-mode :move) (not selected?))
(st/emit! (drp/select-node position))
(let [shift? (kbd/shift? event)]
(cond
(and (= edit-mode :move) (not selected?))
(st/emit! (drp/select-node position shift?))
(and (= edit-mode :move) selected?)
(st/emit! (drp/deselect-node position)))))
(and (= edit-mode :move) selected?)
(st/emit! (drp/deselect-node position shift?))))))
on-mouse-down
@ -177,23 +180,24 @@
last-p (->> content last ugp/command->point)
handlers (ugp/content->handlers content)
handle-click-outside
(fn [event]
(let [current (dom/get-target event)
editor-dom (mf/ref-val editor-ref)]
(when-not (or (.contains editor-dom current)
(dom/class? current "viewport-actions-entry"))
(st/emit! (drp/deselect-all)))))
;;handle-click-outside
;;(fn [event]
;; (let [current (dom/get-target event)
;; editor-dom (mf/ref-val editor-ref)]
;; (when-not (or (.contains editor-dom current)
;; (dom/class? current "viewport-actions-entry"))
;; (st/emit! (drp/deselect-all)))))
handle-double-click-outside
(fn [event]
(when (= edit-mode :move)
(st/emit! :interrupt)))]
(st/emit! :interrupt)))
]
(mf/use-layout-effect
(mf/deps edit-mode)
(fn []
(let [keys [(events/listen (dom/get-root) EventType.CLICK handle-click-outside)
(let [keys [;;(events/listen (dom/get-root) EventType.CLICK handle-click-outside)
(events/listen (dom/get-root) EventType.DBLCLICK handle-double-click-outside)]]
#(doseq [key keys]
(events/unlistenByKey key)))))

View file

@ -101,7 +101,7 @@
on-click (actions/on-click hover selected edition drawing-path? drawing-tool)
on-context-menu (actions/on-context-menu hover)
on-double-click (actions/on-double-click hover hover-ids drawing-path? objects)
on-double-click (actions/on-double-click hover hover-ids drawing-path? objects edition)
on-drag-enter (actions/on-drag-enter)
on-drag-over (actions/on-drag-over)
on-drop (actions/on-drop file viewport-ref zoom)

View file

@ -15,6 +15,7 @@
[app.main.store :as st]
[app.main.streams :as ms]
[app.main.ui.workspace.viewport.utils :as utils]
[app.main.data.workspace.drawing.path :as dwdp]
[app.util.dom :as dom]
[app.util.dom.dnd :as dnd]
[app.util.keyboard :as kbd]
@ -57,13 +58,16 @@
(st/emit! dw/clear-edition-mode))
(when (and (or (not edition) (not= edition id)) (not blocked) (not hidden) (not (#{:comments :path} drawing-tool)))
(not= edition id))
(not blocked)
(not hidden))
(cond
drawing-tool
(st/emit! (dd/start-drawing drawing-tool))
(and edit-path (contains? edit-path edition))
;; Handle node select-drawing. NOP at the moment
nil
;; Handle path node area selection
(st/emit! (dwdp/handle-selection shift?))
(or (not id) (and frame? (not selected?)))
(st/emit! (dw/handle-selection shift?))
@ -142,9 +146,9 @@
(st/emit! (dw/select-shape (:id @hover)))))))))
(defn on-double-click
[hover hover-ids drawing-path? objects]
[hover hover-ids drawing-path? objects edition]
(mf/use-callback
(mf/deps @hover @hover-ids drawing-path?)
(mf/deps @hover @hover-ids drawing-path? edition)
(fn [event]
(dom/stop-propagation event)
(let [ctrl? (kbd/ctrl? event)
@ -170,7 +174,7 @@
(reset! hover-ids (into [] (rest @hover-ids)))
(st/emit! (dw/select-shape (:id selected))))
(or text? path?)
(and (not= id edition) (or text? path?))
(st/emit! (dw/select-shape id)
(dw/start-editing-selected))