0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-24 15:56:11 -05:00

Improve selection handling on viewport.

This commit is contained in:
Andrey Antukh 2020-03-19 17:32:46 +01:00 committed by Alonso Torres
parent 16dab34864
commit 74a6bc8e06
2 changed files with 64 additions and 59 deletions

View file

@ -827,6 +827,52 @@
;; (->> (uwrk/initialize-alignment params) ;; (->> (uwrk/initialize-alignment params)
;; (rx/map #(activate-flag :grid-indexed)))))))) ;; (rx/map #(activate-flag :grid-indexed))))))))
;; --- Selection Rect
(declare select-shapes-by-current-selrect)
(declare deselect-all)
(defn update-selrect
[selrect]
(ptk/reify ::update-selrect
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:workspace-local :selrect] selrect))))
(def handle-selection
(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))]
{:type :rect
:x start-x
:y start-y
:width (- end-x start-x)
:height (- end-y start-y)}))]
(ptk/reify ::handle-selection
ptk/WatchEvent
(watch [_ state stream]
(let [stoper (rx/filter #(or (interrupt? %)
(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/map update-selrect)
(rx/take-until stoper))
(rx/of select-shapes-by-current-selrect
(update-selrect nil))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shapes events ;; Shapes events
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -10,8 +10,8 @@
[beicon.core :as rx] [beicon.core :as rx]
[goog.events :as events] [goog.events :as events]
[goog.object :as gobj] [goog.object :as gobj]
[potok.core :as ptk]
[lentes.core :as l] [lentes.core :as l]
[potok.core :as ptk]
[rumext.alpha :as mf] [rumext.alpha :as mf]
[uxbox.builtins.icons :as i] [uxbox.builtins.icons :as i]
[uxbox.main.constants :as c] [uxbox.main.constants :as c]
@ -21,17 +21,17 @@
[uxbox.main.store :as st] [uxbox.main.store :as st]
[uxbox.main.streams :as ms] [uxbox.main.streams :as ms]
[uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.workspace.grid :refer [grid]] [uxbox.main.ui.react-hooks :refer [use-rxsub]]
[uxbox.main.ui.workspace.ruler :refer [ruler]]
[uxbox.main.ui.workspace.drawarea :refer [start-drawing]]
[uxbox.main.ui.shapes :refer [shape-wrapper frame-wrapper]] [uxbox.main.ui.shapes :refer [shape-wrapper frame-wrapper]]
[uxbox.main.ui.workspace.drawarea :refer [draw-area]] [uxbox.main.ui.workspace.drawarea :refer [draw-area]]
[uxbox.main.ui.workspace.drawarea :refer [start-drawing]]
[uxbox.main.ui.workspace.grid :refer [grid]]
[uxbox.main.ui.workspace.ruler :refer [ruler]]
[uxbox.main.ui.workspace.selection :refer [selection-handlers]] [uxbox.main.ui.workspace.selection :refer [selection-handlers]]
[uxbox.main.ui.react-hooks :refer [use-rxsub]]
[uxbox.util.perf :as perf]
[uxbox.util.uuid :as uuid]
[uxbox.util.dom :as dom] [uxbox.util.dom :as dom]
[uxbox.util.geom.point :as gpt]) [uxbox.util.geom.point :as gpt]
[uxbox.util.perf :as perf]
[uxbox.util.uuid :as uuid])
(:import goog.events.EventType)) (:import goog.events.EventType))
;; --- Coordinates Widget ;; --- Coordinates Widget
@ -73,45 +73,7 @@
;; --- Selection Rect ;; --- Selection Rect
(defn- selection->rect (mf/defc selection-rect
[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))]
(assoc data
:type :rect
:x start-x
:y start-y
:width (- end-x start-x)
:height (- end-y start-y))))
(def ^:private handle-selrect
(letfn [(update-state [state position]
(let [selrect (get-in state [:workspace-local :selrect])]
(if selrect
(assoc-in state [:workspace-local :selrect]
(selection->rect (assoc selrect :stop position)))
(assoc-in state [:workspace-local :selrect]
(selection->rect {:start position :stop position})))))
(clear-state [state]
(update state :workspace-local dissoc :selrect))]
(ptk/reify ::handle-selrect
ptk/WatchEvent
(watch [_ state stream]
(let [stoper (rx/filter #(or (dw/interrupt? %) (ms/mouse-up? %)) stream)]
(rx/concat
(rx/of dw/deselect-all)
(->> ms/mouse-position
(rx/map (fn [pos] #(update-state % pos)))
(rx/take-until stoper))
(rx/of dw/select-shapes-by-current-selrect
clear-state)))))))
(mf/defc selrect
{:wrap [mf/wrap-memo]} {:wrap [mf/wrap-memo]}
[{:keys [data] :as props}] [{:keys [data] :as props}]
(when data (when data
@ -144,13 +106,7 @@
(declare remote-user-cursors) (declare remote-user-cursors)
(declare frames) (declare frames)
(defn- build-workspace-data-iref
[page-id]
(-> (l/in [:workspace-data page-id])
(l/derive st/state)))
(mf/defrc frames-wrapper (mf/defrc frames-wrapper
;; {:wrap [mf/wrap-memo]}
[props] [props]
(let [page (gobj/get props "page") (let [page (gobj/get props "page")
page-id (:id page) page-id (:id page)
@ -187,6 +143,8 @@
selected] selected]
:as local} (mf/deref refs/workspace-local) :as local} (mf/deref refs/workspace-local)
viewport-ref (mf/use-ref nil) viewport-ref (mf/use-ref nil)
last-position (mf/use-var nil)
zoom (or zoom 1) zoom (or zoom 1)
on-mouse-down on-mouse-down
@ -196,11 +154,12 @@
shift? (kbd/shift? event) shift? (kbd/shift? event)
opts {:shift? shift? opts {:shift? shift?
:ctrl? ctrl?}] :ctrl? ctrl?}]
(st/emit! (ms/->MouseEvent :down ctrl? shift?))) (st/emit! (ms/->MouseEvent :down ctrl? shift?))
(when (not edition) (when (and (not edition)
(if drawing-tool (= 1 (.-which (.-nativeEvent event))))
(st/emit! (start-drawing drawing-tool)) (if drawing-tool
(st/emit! handle-selrect)))) (st/emit! (start-drawing drawing-tool))
(st/emit! dw/handle-selection)))))
on-context-menu on-context-menu
(fn [event] (fn [event]
@ -337,7 +296,7 @@
[:& ruler {:zoom zoom :ruler (:ruler local)}]) [:& ruler {:zoom zoom :ruler (:ruler local)}])
[:& remote-user-cursors {:page page}] [:& remote-user-cursors {:page page}]
[:& selrect {:data (:selrect local)}]]])) [:& selection-rect {:data (:selrect local)}]]]))
(mf/defc remote-user-cursor (mf/defc remote-user-cursor