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:
parent
16dab34864
commit
74a6bc8e06
2 changed files with 64 additions and 59 deletions
|
@ -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
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue