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

View file

@ -253,3 +253,4 @@
;; Intersection ;; Intersection
(d/export gin/overlaps?) (d/export gin/overlaps?)
(d/export gin/has-point?) (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 path?) (overlaps-path? shape rect))
(or (not circle?) (overlaps-ellipse? 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? (defn has-point?
"Check if the shape contains a point" "Check if the shape contains a point"
[shape point] [shape point]

View file

@ -19,6 +19,12 @@
(gpt/point (+ x width) (+ y height)) (gpt/point (+ x width) (+ y height))
(gpt/point x (+ 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 (defn points->rect
[points] [points]
(let [minx (transduce gco/map-x-xf min ##Inf points) (let [minx (transduce gco/map-x-xf min ##Inf points)

View file

@ -732,7 +732,23 @@
(-> state (-> state
(update-in [:workspace-local :edit-path id :selected-handlers] (fnil conj #{}) [index type])))))) (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/reify ::select-node
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -740,7 +756,7 @@
(-> state (-> state
(assoc-in [:workspace-local :edit-path id :selected-points] #{position})))))) (assoc-in [:workspace-local :edit-path id :selected-points] #{position}))))))
(defn deselect-node [position] (defn deselect-node [position shift?]
(ptk/reify ::deselect-node (ptk/reify ::deselect-node
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -858,3 +874,54 @@
(rx/filter #(= % :interrupt)) (rx/filter #(= % :interrupt))
(rx/take 1) (rx/take 1)
(rx/map #(stop-path-edit)))))))) (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/reify ::handle-selection
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(let [stoper (rx/filter #(or (dwc/interrupt? %) (let [stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
(ms/mouse-up? %)) stoper (->> stream (rx/filter stop?))]
stream)]
(rx/concat (rx/concat
(when-not preserve? (when-not preserve?
(rx/of (deselect-all))) (rx/of (deselect-all)))

View file

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

View file

@ -101,7 +101,7 @@
on-click (actions/on-click hover selected edition drawing-path? drawing-tool) on-click (actions/on-click hover selected edition drawing-path? drawing-tool)
on-context-menu (actions/on-context-menu hover) 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-enter (actions/on-drag-enter)
on-drag-over (actions/on-drag-over) on-drag-over (actions/on-drag-over)
on-drop (actions/on-drop file viewport-ref zoom) on-drop (actions/on-drop file viewport-ref zoom)

View file

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