From 9822c52573623a837dbbe9a0baa8daaa511598c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Moya?= Date: Fri, 11 Dec 2020 15:12:07 +0100 Subject: [PATCH] :sparkles: Allow select multiple frames and extend selrect with shift --- .../app/main/data/workspace/selection.cljs | 51 +++++++++++-------- .../app/main/ui/workspace/shapes/frame.cljs | 14 +++-- .../src/app/main/ui/workspace/viewport.cljs | 2 +- 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 629b4bb83..db1eff536 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -46,7 +46,8 @@ (update [_ state] (assoc-in state [:workspace-local :selrect] selrect)))) -(def handle-selection +(defn handle-selection + [preserve?] (letfn [(data->selrect [data] (let [start (:start data) stop (:stop data) @@ -66,19 +67,20 @@ (ms/mouse-up? %)) stream)] (rx/concat - (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-selrect) - (rx/take-until stoper)) - (rx/of select-shapes-by-current-selrect))))))) + (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-selrect) + (rx/take-until stoper)) + (rx/of (select-shapes-by-current-selrect preserve?)))))))) ;; --- Toggle shape's selection status (selected or deselected) @@ -157,24 +159,29 @@ ;; --- Select Shapes (By selrect) -(def select-shapes-by-current-selrect +(defn select-shapes-by-current-selrect + [preserve?] (ptk/reify ::select-shapes-by-current-selrect ptk/WatchEvent (watch [_ state stream] (let [page-id (:current-page-id state) + selected (get-in state [:workspace-local :selected]) + initial-set (if preserve? + selected + lks/empty-linked-set) selrect (get-in state [:workspace-local :selrect]) is-not-blocked (fn [shape-id] (not (get-in state [:workspace-data :pages-index page-id :objects shape-id :blocked] false)))] (rx/merge - (rx/of (update-selrect nil)) - (when selrect - (->> (uw/ask! {:cmd :selection/query - :page-id page-id - :rect selrect}) - (rx/map #(into lks/empty-linked-set (filter is-not-blocked) %)) - (rx/map select-shapes)))))))) + (rx/of (update-selrect nil)) + (when selrect + (->> (uw/ask! {:cmd :selection/query + :page-id page-id + :rect selrect}) + (rx/map #(into initial-set (filter is-not-blocked) %)) + (rx/map select-shapes)))))))) (defn select-inside-group [group-id position] diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index 1b6bef2cf..a2a0965e4 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -14,6 +14,7 @@ [app.main.data.workspace :as dw] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.keyboard :as kbd] [app.main.ui.shapes.frame :as frame] [app.main.ui.shapes.shape :refer [shape-container]] [app.main.ui.workspace.effects :as we] @@ -44,9 +45,16 @@ (mf/use-callback (mf/deps id) (fn [event] + (let [selected @refs/selected-shapes + selected? (contains? selected id)] (dom/prevent-default event) - (st/emit! (dw/deselect-all) - (dw/select-shape id))))) + (if selected? + (when (kbd/shift? event) + (st/emit! (dw/select-shape id true))) + (do + (when-not (or (empty? selected) (kbd/shift? event)) + (st/emit! (dw/deselect-all))) + (st/emit! (dw/select-shape id)))))))) ;; Ensure that the label has always the same font ;; size, regardless of zoom @@ -72,7 +80,7 @@ :height 20 :class "workspace-frame-label" :transform (text-transform label-pos zoom) - :on-click handle-click + :on-mouse-down handle-click :on-pointer-over handle-pointer-enter :on-pointer-out handle-pointer-leave} (:name frame)])) diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index 1a97b663e..b3816720f 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -241,7 +241,7 @@ (if drawing-tool (when (not (#{:comments :path} drawing-tool)) (st/emit! (dd/start-drawing drawing-tool))) - (st/emit! dw/handle-selection)) + (st/emit! (dw/handle-selection shift?))) (and (= 2 (.-which event))) (handle-viewport-positioning viewport-ref)))))