mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
Merge pull request #3863 from penpot/audriu-Ctrl-Plus-to-zoom-into-Canvas
✨ Override browser zoom with penpot zoom
This commit is contained in:
commit
3246c196d1
@ -7,6 +7,7 @@
|
|||||||
### :sparkles: New features
|
### :sparkles: New features
|
||||||
|
|
||||||
- Select through stroke only rectangle [Taiga #5484](https://tree.taiga.io/project/penpot/issue/5484)
|
- Select through stroke only rectangle [Taiga #5484](https://tree.taiga.io/project/penpot/issue/5484)
|
||||||
|
- Override browser Ctrl+ and Ctrl- zoom with Penpot Zoom [Taiga #3200](https://tree.taiga.io/project/penpot/us/3200)
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
[app.main.data.workspace.viewport :as dwv]
|
[app.main.data.workspace.viewport :as dwv]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
@ -37,7 +38,8 @@
|
|||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (dcm/retrieve-comment-threads file-id))
|
(rx/of (dcm/retrieve-comment-threads file-id))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter ms/mouse-click?)
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-click-event?)
|
||||||
(rx/switch-map #(rx/take 1 ms/mouse-position))
|
(rx/switch-map #(rx/take 1 ms/mouse-position))
|
||||||
(rx/with-latest-from ms/keyboard-space)
|
(rx/with-latest-from ms/keyboard-space)
|
||||||
(rx/filter (fn [[_ space]] (not space)) )
|
(rx/filter (fn [[_ space]] (not space)) )
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -76,7 +77,13 @@
|
|||||||
(ptk/reify ::handle-drawing
|
(ptk/reify ::handle-drawing
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stoper (rx/filter #(or (ms/mouse-up? %) (= % :interrupt)) stream)
|
(let [stoper (rx/merge
|
||||||
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter #(= % :interrupt))))
|
||||||
|
|
||||||
layout (get state :workspace-layout)
|
layout (get state :workspace-layout)
|
||||||
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
[app.main.data.workspace.drawing.common :as common]
|
[app.main.data.workspace.drawing.common :as common]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[app.util.path.simplify-curve :as ups]
|
[app.util.path.simplify-curve :as ups]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
@ -29,7 +30,8 @@
|
|||||||
|
|
||||||
(defn stoper-event?
|
(defn stoper-event?
|
||||||
[{:keys [type] :as event}]
|
[{:keys [type] :as event}]
|
||||||
(ms/mouse-event? event) (= type :up))
|
(and (mse/mouse-event? event)
|
||||||
|
(= type :up)))
|
||||||
|
|
||||||
(defn- insert-point
|
(defn- insert-point
|
||||||
[point]
|
[point]
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.data.workspace.undo :as dwu]
|
[app.main.data.workspace.undo :as dwu]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -187,7 +188,9 @@
|
|||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial-pos @ms/mouse-position
|
(let [initial-pos @ms/mouse-position
|
||||||
selected (wsh/lookup-selected state)
|
selected (wsh/lookup-selected state)
|
||||||
stopper (rx/filter ms/mouse-up? stream)]
|
stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))]
|
||||||
(when (= 1 (count selected))
|
(when (= 1 (count selected))
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
@ -295,7 +298,9 @@
|
|||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial-pos @ms/mouse-position
|
(let [initial-pos @ms/mouse-position
|
||||||
selected (wsh/lookup-selected state)
|
selected (wsh/lookup-selected state)
|
||||||
stopper (rx/filter ms/mouse-up? stream)]
|
stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))]
|
||||||
(when (= 1 (count selected))
|
(when (= 1 (count selected))
|
||||||
(let [page-id (:current-page-id state)
|
(let [page-id (:current-page-id state)
|
||||||
objects (wsh/lookup-page-objects state page-id)
|
objects (wsh/lookup-page-objects state page-id)
|
||||||
|
|||||||
@ -16,8 +16,8 @@
|
|||||||
[app.main.data.workspace.changes :as dch]
|
[app.main.data.workspace.changes :as dch]
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
[app.main.data.workspace.persistence :as dwp]
|
[app.main.data.workspace.persistence :as dwp]
|
||||||
[app.main.streams :as ms]
|
|
||||||
[app.util.globals :refer [global]]
|
[app.util.globals :refer [global]]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
@ -81,7 +81,7 @@
|
|||||||
;; Emit to all other connected users the current pointer
|
;; Emit to all other connected users the current pointer
|
||||||
;; position changes.
|
;; position changes.
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter ms/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
(rx/sample 50)
|
(rx/sample 50)
|
||||||
(rx/map #(handle-pointer-send file-id (:pt %)))))
|
(rx/map #(handle-pointer-send file-id (:pt %)))))
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
[app.main.data.workspace.path.streams :as streams]
|
[app.main.data.workspace.path.streams :as streams]
|
||||||
[app.main.data.workspace.path.undo :as undo]
|
[app.main.data.workspace.path.undo :as undo]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.streams :as ms]
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -122,16 +122,12 @@
|
|||||||
|
|
||||||
(declare close-path-drag-end)
|
(declare close-path-drag-end)
|
||||||
|
|
||||||
(defn close-path-drag-start [position]
|
(defn close-path-drag-start
|
||||||
|
[position]
|
||||||
(ptk/reify ::close-path-drag-start
|
(ptk/reify ::close-path-drag-start
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stop-stream
|
(let [content (st/get-path state :content)
|
||||||
(->> stream (rx/filter #(or (helpers/end-path-event? %)
|
|
||||||
(ms/mouse-up? %))))
|
|
||||||
|
|
||||||
content (st/get-path state :content)
|
|
||||||
|
|
||||||
handlers (-> (upc/content->handlers content)
|
handlers (-> (upc/content->handlers content)
|
||||||
(get position))
|
(get position))
|
||||||
|
|
||||||
@ -140,8 +136,14 @@
|
|||||||
|
|
||||||
drag-events-stream
|
drag-events-stream
|
||||||
(->> (streams/position-stream)
|
(->> (streams/position-stream)
|
||||||
(rx/take-until stop-stream)
|
(rx/map #(drag-handler position idx prefix %))
|
||||||
(rx/map #(drag-handler position idx prefix %)))]
|
(rx/take-until
|
||||||
|
(rx/merge
|
||||||
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter helpers/end-path-event?)))))]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (add-node position))
|
(rx/of (add-node position))
|
||||||
@ -163,12 +165,16 @@
|
|||||||
(ptk/reify ::start-path-from-point
|
(ptk/reify ::start-path-from-point
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ _ stream]
|
||||||
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
|
(let [stoper (rx/merge
|
||||||
(ms/mouse-up? %))))
|
(->> stream
|
||||||
drag-events (->> (streams/position-stream)
|
(rx/filter mse/mouse-event?)
|
||||||
(rx/take-until mouse-up)
|
(rx/filter mse/mouse-up-event?))
|
||||||
(rx/map #(drag-handler %)))]
|
(->> stream
|
||||||
|
(rx/filter helpers/end-path-event?)))
|
||||||
|
|
||||||
|
drag-events (->> (streams/position-stream)
|
||||||
|
(rx/map #(drag-handler %))
|
||||||
|
(rx/take-until stoper))]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (add-node position))
|
(rx/of (add-node position))
|
||||||
(streams/drag-stream
|
(streams/drag-stream
|
||||||
@ -185,13 +191,16 @@
|
|||||||
|
|
||||||
(defn make-drag-stream
|
(defn make-drag-stream
|
||||||
[stream down-event]
|
[stream down-event]
|
||||||
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
|
(let [stoper (rx/merge
|
||||||
(ms/mouse-up? %))))
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter helpers/end-path-event?)))
|
||||||
|
|
||||||
drag-events (->> (streams/position-stream)
|
drag-events (->> (streams/position-stream)
|
||||||
(rx/take-until mouse-up)
|
(rx/map #(drag-handler %))
|
||||||
(rx/map #(drag-handler %)))]
|
(rx/take-until stoper))]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (add-node down-event))
|
(rx/of (add-node down-event))
|
||||||
(streams/drag-stream
|
(streams/drag-stream
|
||||||
@ -209,8 +218,11 @@
|
|||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ _ stream]
|
||||||
(let [mouse-down (->> stream (rx/filter ms/mouse-down?))
|
(let [mouse-down (->> stream
|
||||||
end-path-events (->> stream (rx/filter helpers/end-path-event?))
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-down-event?))
|
||||||
|
end-path-events (->> stream
|
||||||
|
(rx/filter helpers/end-path-event?))
|
||||||
|
|
||||||
;; Mouse move preview
|
;; Mouse move preview
|
||||||
mousemove-events
|
mousemove-events
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
[app.main.data.workspace.path.undo :as undo]
|
[app.main.data.workspace.path.undo :as undo]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[app.util.path.tools :as upt]
|
[app.util.path.tools :as upt]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
@ -150,7 +151,10 @@
|
|||||||
(ptk/reify ::drag-selected-points
|
(ptk/reify ::drag-selected-points
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [stopper (->> stream (rx/filter ms/mouse-up?))
|
(let [stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
|
||||||
id (dm/get-in state [:workspace-local :edition])
|
id (dm/get-in state [:workspace-local :edition])
|
||||||
|
|
||||||
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
|
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
|
||||||
@ -263,8 +267,6 @@
|
|||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of (dch/update-shapes [id] upsp/convert-to-path))
|
(rx/of (dch/update-shapes [id] upsp/convert-to-path))
|
||||||
(->> (streams/move-handler-stream handler point handler opposite points)
|
(->> (streams/move-handler-stream handler point handler opposite points)
|
||||||
(rx/take-until (->> stream (rx/filter #(or (ms/mouse-up? %)
|
|
||||||
(streams/finish-edition? %)))))
|
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [{:keys [x y alt? shift?]}]
|
(fn [{:keys [x y alt? shift?]}]
|
||||||
(let [pos (cond-> (gpt/point x y)
|
(let [pos (cond-> (gpt/point x y)
|
||||||
@ -275,7 +277,15 @@
|
|||||||
prefix
|
prefix
|
||||||
(+ start-delta-x (- (:x pos) (:x handler)))
|
(+ start-delta-x (- (:x pos) (:x handler)))
|
||||||
(+ start-delta-y (- (:y pos) (:y handler)))
|
(+ start-delta-y (- (:y pos) (:y handler)))
|
||||||
(not alt?))))))
|
(not alt?)))))
|
||||||
|
(rx/take-until
|
||||||
|
(rx/merge
|
||||||
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter streams/finish-edition?)))))
|
||||||
|
|
||||||
(rx/concat (rx/of (apply-content-modifiers)))))))))
|
(rx/concat (rx/of (apply-content-modifiers)))))))))
|
||||||
|
|
||||||
(declare stop-path-edit)
|
(declare stop-path-edit)
|
||||||
|
|||||||
@ -14,16 +14,19 @@
|
|||||||
[app.common.svg.path.command :as upc]
|
[app.common.svg.path.command :as upc]
|
||||||
[app.common.svg.path.subpath :as ups]
|
[app.common.svg.path.subpath :as ups]
|
||||||
[app.main.data.workspace.path.common :as common]
|
[app.main.data.workspace.path.common :as common]
|
||||||
[app.main.streams :as ms]
|
[app.util.mouse :as mse]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
(defn end-path-event? [event]
|
(defn end-path-event?
|
||||||
(or (= (ptk/type event) ::common/finish-path)
|
[event]
|
||||||
(= (ptk/type event) :app.main.data.workspace.path.shortcuts/esc-pressed)
|
(let [type (ptk/type event)]
|
||||||
(= :app.main.data.workspace.common/clear-edition-mode (ptk/type event))
|
(or (= type ::common/finish-path)
|
||||||
(= :app.main.data.workspace/finalize-page (ptk/type event))
|
(= type :app.main.data.workspace.path.shortcuts/esc-pressed)
|
||||||
(= event :interrupt) ;; ESC
|
(= type :app.main.data.workspace.common/clear-edition-mode)
|
||||||
(ms/mouse-double-click? event)))
|
(= type :app.main.data.workspace/finalize-page)
|
||||||
|
(= event :interrupt) ;; ESC
|
||||||
|
(and ^boolean (mse/mouse-event? event)
|
||||||
|
^boolean (mse/mouse-double-click-event? event)))))
|
||||||
|
|
||||||
(defn content-center
|
(defn content-center
|
||||||
[content]
|
[content]
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.path.state :as st]
|
[app.main.data.workspace.path.state :as st]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -118,16 +119,21 @@
|
|||||||
(ptk/reify ::handle-area-selection
|
(ptk/reify ::handle-area-selection
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [zoom (get-in state [:workspace-local :zoom] 1)
|
(let [zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
stop? (fn [event] (or (dwc/interrupt? event) (ms/mouse-up? event)))
|
stoper (rx/merge
|
||||||
stoper (->> stream (rx/filter stop?))
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter dwc/interrupt?)))
|
||||||
|
|
||||||
from-p @ms/mouse-position]
|
from-p @ms/mouse-position]
|
||||||
(rx/concat
|
(rx/concat
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/take-until stoper)
|
|
||||||
(rx/map #(grc/points->rect [from-p %]))
|
(rx/map #(grc/points->rect [from-p %]))
|
||||||
(rx/filter (partial valid-rect? zoom))
|
(rx/filter (partial valid-rect? zoom))
|
||||||
(rx/map update-area-selection))
|
(rx/map update-area-selection)
|
||||||
|
(rx/take-until stoper))
|
||||||
|
|
||||||
(rx/of (select-node-area shift?)
|
(rx/of (select-node-area shift?)
|
||||||
(clear-area-selection))))))))
|
(clear-area-selection))))))))
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[okulary.core :as l]
|
[okulary.core :as l]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
@ -50,16 +51,20 @@
|
|||||||
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
|
||||||
|
|
||||||
start (-> @ms/mouse-position to-pixel-snap)
|
start (-> @ms/mouse-position to-pixel-snap)
|
||||||
mouse-up (->> st/stream
|
|
||||||
(rx/filter #(or (finish-edition? %)
|
stoper (rx/merge
|
||||||
(ms/mouse-up? %))))
|
(->> st/stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> st/stream
|
||||||
|
(rx/filter finish-edition?)))
|
||||||
|
|
||||||
position-stream
|
position-stream
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
(rx/take-until mouse-up)
|
|
||||||
(rx/map to-pixel-snap)
|
(rx/map to-pixel-snap)
|
||||||
(rx/filter (dragging? start zoom))
|
(rx/filter (dragging? start zoom))
|
||||||
(rx/take 1))]
|
(rx/take 1)
|
||||||
|
(rx/take-until stoper))]
|
||||||
|
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(->> position-stream
|
(->> position-stream
|
||||||
|
|||||||
@ -35,12 +35,15 @@
|
|||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.main.worker :as uw]
|
[app.main.worker :as uw]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
[linked.set :as lks]
|
[linked.set :as lks]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
(defn interrupt? [e] (= e :interrupt))
|
(defn interrupt?
|
||||||
|
[e]
|
||||||
|
(= e :interrupt))
|
||||||
|
|
||||||
;; --- Selection Rect
|
;; --- Selection Rect
|
||||||
|
|
||||||
@ -60,8 +63,12 @@
|
|||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [zoom (dm/get-in state [:workspace-local :zoom] 1)
|
(let [zoom (dm/get-in state [:workspace-local :zoom] 1)
|
||||||
stop? (fn [event] (or (interrupt? event) (ms/mouse-up? event)))
|
stoper (rx/merge
|
||||||
stoper (rx/filter stop? stream)
|
(->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
(->> stream
|
||||||
|
(rx/filter interrupt?)))
|
||||||
|
|
||||||
init-position @ms/mouse-position
|
init-position @ms/mouse-position
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,8 @@
|
|||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
|
[app.util.keyboard :as kbd]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -214,7 +216,9 @@
|
|||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial-position @ms/mouse-position
|
(let [initial-position @ms/mouse-position
|
||||||
stopper (rx/filter ms/mouse-up? stream)
|
stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
layout (:workspace-layout state)
|
layout (:workspace-layout state)
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
@ -305,7 +309,10 @@
|
|||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ stream]
|
(watch [_ _ stream]
|
||||||
(let [stoper (rx/filter ms/mouse-up? stream)
|
(let [stoper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
|
||||||
group (gsh/shapes->rect shapes)
|
group (gsh/shapes->rect shapes)
|
||||||
group-center (grc/rect->center group)
|
group-center (grc/rect->center group)
|
||||||
initial-angle (gpt/angle @ms/mouse-position group-center)
|
initial-angle (gpt/angle @ms/mouse-position group-center)
|
||||||
@ -369,7 +376,10 @@
|
|||||||
(watch [_ state stream]
|
(watch [_ state stream]
|
||||||
(let [initial (deref ms/mouse-position)
|
(let [initial (deref ms/mouse-position)
|
||||||
|
|
||||||
stopper (rx/filter ms/mouse-up? stream)
|
stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
|
||||||
zoom (get-in state [:workspace-local :zoom] 1)
|
zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
|
|
||||||
;; We toggle the selection so we don't have to wait for the event
|
;; We toggle the selection so we don't have to wait for the event
|
||||||
@ -443,7 +453,11 @@
|
|||||||
ids (if (nil? ids) selected ids)
|
ids (if (nil? ids) selected ids)
|
||||||
shapes (mapv #(get objects %) ids)
|
shapes (mapv #(get objects %) ids)
|
||||||
duplicate-move-started? (get-in state [:workspace-local :duplicate-move-started?] false)
|
duplicate-move-started? (get-in state [:workspace-local :duplicate-move-started?] false)
|
||||||
stopper (rx/filter ms/mouse-up? stream)
|
|
||||||
|
stopper (->> stream
|
||||||
|
(rx/filter mse/mouse-event?)
|
||||||
|
(rx/filter mse/mouse-up-event?))
|
||||||
|
|
||||||
layout (get state :workspace-layout)
|
layout (get state :workspace-layout)
|
||||||
zoom (get-in state [:workspace-local :zoom] 1)
|
zoom (get-in state [:workspace-local :zoom] 1)
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
@ -673,7 +687,8 @@
|
|||||||
(rx/switch-map #(rx/merge
|
(rx/switch-map #(rx/merge
|
||||||
(rx/timer 1000)
|
(rx/timer 1000)
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter ms/key-up?)
|
(rx/filter kbd/keyboard-event?)
|
||||||
|
(rx/filter kbd/key-up-event?)
|
||||||
(rx/delay 250))))
|
(rx/delay 250))))
|
||||||
(rx/take 1))
|
(rx/take 1))
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.streams :as ms]
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -155,7 +155,7 @@
|
|||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of #(-> % (assoc-in [:workspace-local :panning] true)))
|
(rx/of #(-> % (assoc-in [:workspace-local :panning] true)))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter ms/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
(rx/filter #(= :delta (:source %)))
|
(rx/filter #(= :delta (:source %)))
|
||||||
(rx/map :pt)
|
(rx/map :pt)
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
@ -118,7 +119,7 @@
|
|||||||
(rx/concat
|
(rx/concat
|
||||||
(rx/of #(-> % (assoc-in [:workspace-local :zooming] true)))
|
(rx/of #(-> % (assoc-in [:workspace-local :zooming] true)))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter ms/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
(rx/filter #(= :delta (:source %)))
|
(rx/filter #(= :delta (:source %)))
|
||||||
(rx/map :pt)
|
(rx/map :pt)
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
|
|||||||
@ -11,94 +11,43 @@
|
|||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.util.globals :as globals]
|
[app.util.globals :as globals]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]))
|
[beicon.core :as rx]))
|
||||||
|
|
||||||
;; --- User Events
|
;; --- User Events
|
||||||
|
|
||||||
(defrecord KeyboardEvent [type key shift ctrl alt meta editing])
|
|
||||||
|
|
||||||
(defn keyboard-event?
|
|
||||||
[v]
|
|
||||||
(instance? KeyboardEvent v))
|
|
||||||
|
|
||||||
(defn key-up?
|
|
||||||
[v]
|
|
||||||
(and (keyboard-event? v)
|
|
||||||
(= :up (:type v))))
|
|
||||||
|
|
||||||
(defn key-down?
|
|
||||||
[v]
|
|
||||||
(and (keyboard-event? v)
|
|
||||||
(= :down (:type v))))
|
|
||||||
|
|
||||||
(defrecord MouseEvent [type ctrl shift alt meta])
|
|
||||||
|
|
||||||
(defn mouse-event?
|
|
||||||
[v]
|
|
||||||
(instance? MouseEvent v))
|
|
||||||
|
|
||||||
(defn mouse-down?
|
|
||||||
[v]
|
|
||||||
(and (mouse-event? v)
|
|
||||||
(= :down (:type v))))
|
|
||||||
|
|
||||||
(defn mouse-up?
|
|
||||||
[v]
|
|
||||||
(and (mouse-event? v)
|
|
||||||
(= :up (:type v))))
|
|
||||||
|
|
||||||
(defn mouse-click?
|
|
||||||
[v]
|
|
||||||
(and (mouse-event? v)
|
|
||||||
(= :click (:type v))))
|
|
||||||
|
|
||||||
(defn mouse-double-click?
|
|
||||||
[v]
|
|
||||||
(and (mouse-event? v)
|
|
||||||
(= :double-click (:type v))))
|
|
||||||
|
|
||||||
(defrecord PointerEvent [source pt ctrl shift alt meta])
|
|
||||||
|
|
||||||
(defn pointer-event?
|
|
||||||
[v]
|
|
||||||
(instance? PointerEvent v))
|
|
||||||
|
|
||||||
(defrecord ScrollEvent [point])
|
|
||||||
|
|
||||||
(defn scroll-event?
|
|
||||||
[v]
|
|
||||||
(instance? ScrollEvent v))
|
|
||||||
|
|
||||||
(defn interaction-event?
|
(defn interaction-event?
|
||||||
[event]
|
[event]
|
||||||
(or (keyboard-event? event)
|
(or ^boolean (kbd/keyboard-event? event)
|
||||||
(mouse-event? event)))
|
^boolean (mse/mouse-event? event)))
|
||||||
|
|
||||||
;; --- Derived streams
|
;; --- Derived streams
|
||||||
|
|
||||||
|
(defonce ^:private pointer
|
||||||
|
(->> st/stream
|
||||||
|
(rx/filter mse/pointer-event?)
|
||||||
|
(rx/share)))
|
||||||
|
|
||||||
(defonce mouse-position
|
(defonce mouse-position
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> pointer
|
||||||
(rx/filter pointer-event?)
|
(rx/filter #(= :viewport (mse/get-pointer-source %)))
|
||||||
(rx/filter #(= :viewport (:source %)))
|
(rx/map mse/get-pointer-position))]
|
||||||
(rx/map :pt))]
|
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
(defonce mouse-position-ctrl
|
(defonce mouse-position-ctrl
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> pointer
|
||||||
(rx/filter pointer-event?)
|
(rx/map mse/get-pointer-ctrl-mod)
|
||||||
(rx/map :ctrl)
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
(defonce mouse-position-meta
|
(defonce mouse-position-meta
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> pointer
|
||||||
(rx/filter pointer-event?)
|
(rx/map mse/get-pointer-meta-mod)
|
||||||
(rx/map :meta)
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
@ -110,71 +59,68 @@
|
|||||||
|
|
||||||
(defonce mouse-position-shift
|
(defonce mouse-position-shift
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> pointer
|
||||||
(rx/filter pointer-event?)
|
(rx/map mse/get-pointer-shift-mod)
|
||||||
(rx/map :shift)
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
(defonce mouse-position-alt
|
(defonce mouse-position-alt
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> pointer
|
||||||
(rx/filter pointer-event?)
|
(rx/map mse/get-pointer-alt-mod)
|
||||||
(rx/map :alt)
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
|
(defonce ^:private window-blur
|
||||||
(defonce window-blur
|
|
||||||
(->> (rx/from-event globals/window "blur")
|
(->> (rx/from-event globals/window "blur")
|
||||||
|
(rx/map (constantly false))
|
||||||
|
(rx/share)))
|
||||||
|
|
||||||
|
(defonce keyboard
|
||||||
|
(->> st/stream
|
||||||
|
(rx/filter kbd/keyboard-event?)
|
||||||
(rx/share)))
|
(rx/share)))
|
||||||
|
|
||||||
(defonce keyboard-alt
|
(defonce keyboard-alt
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> (rx/merge
|
ob (->> keyboard
|
||||||
(->> st/stream
|
(rx/filter kbd/alt-key?)
|
||||||
(rx/filter keyboard-event?)
|
(rx/map kbd/key-down-event?)
|
||||||
(rx/filter kbd/alt-key?)
|
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||||
(rx/map #(= :down (:type %))))
|
;; shortcuts, that makes keyboard-alt stream
|
||||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
;; registering the key pressed but on blurring the
|
||||||
;; that makes keyboard-alt stream registering the key pressed but
|
;; window (unfocus) the key down is never arrived.
|
||||||
;; on blurring the window (unfocus) the key down is never arrived.
|
(rx/merge window-blur)
|
||||||
(->> window-blur
|
|
||||||
(rx/map (constantly false))))
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
(defonce keyboard-ctrl
|
(defonce keyboard-ctrl
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> (rx/merge
|
ob (->> keyboard
|
||||||
(->> st/stream
|
(rx/filter kbd/ctrl-key?)
|
||||||
(rx/filter keyboard-event?)
|
(rx/map kbd/key-down-event?)
|
||||||
(rx/filter kbd/ctrl-key?)
|
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||||
(rx/map #(= :down (:type %))))
|
;; shortcuts, that makes keyboard-alt stream
|
||||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
;; registering the key pressed but on blurring the
|
||||||
;; that makes keyboard-alt stream registering the key pressed but
|
;; window (unfocus) the key down is never arrived.
|
||||||
;; on blurring the window (unfocus) the key down is never arrived.
|
(rx/merge window-blur)
|
||||||
(->> window-blur
|
|
||||||
(rx/map (constantly false))))
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
(defonce keyboard-meta
|
(defonce keyboard-meta
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> (rx/merge
|
ob (->> keyboard
|
||||||
(->> st/stream
|
(rx/filter kbd/meta-key?)
|
||||||
(rx/filter keyboard-event?)
|
(rx/map kbd/key-down-event?)
|
||||||
(rx/filter kbd/meta-key?)
|
;; Fix a situation caused by using `ctrl+alt` kind of
|
||||||
(rx/map #(= :down (:type %))))
|
;; shortcuts, that makes keyboard-alt stream
|
||||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
;; registering the key pressed but on blurring the
|
||||||
;; that makes keyboard-alt stream registering the key pressed but
|
;; window (unfocus) the key down is never arrived.
|
||||||
;; on blurring the window (unfocus) the key down is never arrived.
|
(rx/merge window-blur)
|
||||||
(->> window-blur
|
|
||||||
(rx/map (constantly false))))
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
@ -186,33 +132,10 @@
|
|||||||
|
|
||||||
(defonce keyboard-space
|
(defonce keyboard-space
|
||||||
(let [sub (rx/behavior-subject nil)
|
(let [sub (rx/behavior-subject nil)
|
||||||
ob (->> st/stream
|
ob (->> keyboard
|
||||||
(rx/filter keyboard-event?)
|
|
||||||
(rx/filter kbd/space?)
|
(rx/filter kbd/space?)
|
||||||
(rx/filter (comp not kbd/editing?))
|
(rx/filter (complement kbd/editing-event?))
|
||||||
(rx/map #(= :down (:type %)))
|
(rx/map kbd/key-down-event?)
|
||||||
(rx/dedupe))]
|
|
||||||
(rx/subscribe-with ob sub)
|
|
||||||
sub))
|
|
||||||
|
|
||||||
(defonce keyboard-z
|
|
||||||
(let [sub (rx/behavior-subject nil)
|
|
||||||
ob (->> st/stream
|
|
||||||
(rx/filter keyboard-event?)
|
|
||||||
(rx/filter kbd/z?)
|
|
||||||
(rx/filter (comp not kbd/editing?))
|
|
||||||
(rx/map #(= :down (:type %)))
|
|
||||||
(rx/dedupe))]
|
|
||||||
(rx/subscribe-with ob sub)
|
|
||||||
sub))
|
|
||||||
|
|
||||||
(defonce keyboard-shift
|
|
||||||
(let [sub (rx/behavior-subject nil)
|
|
||||||
ob (->> st/stream
|
|
||||||
(rx/filter keyboard-event?)
|
|
||||||
(rx/filter kbd/shift-key?)
|
|
||||||
(rx/filter (comp not kbd/editing?))
|
|
||||||
(rx/map #(= :down (:type %)))
|
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|||||||
@ -348,34 +348,36 @@
|
|||||||
state))
|
state))
|
||||||
|
|
||||||
(defn use-dynamic-grid-item-width
|
(defn use-dynamic-grid-item-width
|
||||||
([]
|
([] (use-dynamic-grid-item-width nil))
|
||||||
(use-dynamic-grid-item-width nil))
|
|
||||||
|
|
||||||
([itemsize]
|
([itemsize]
|
||||||
(let [width (mf/use-state (:items-width @storage))
|
(let [;; NOTE: we pass a function to use-state for avoid repeatedly
|
||||||
rowref (mf/use-ref)
|
;; lookup `:items-width` on storage on each render
|
||||||
|
width* (mf/use-state #(:items-width @storage))
|
||||||
|
width (deref width*)
|
||||||
|
|
||||||
itemsize (cond
|
rowref (mf/use-ref)
|
||||||
(some? itemsize) itemsize
|
|
||||||
(>= @width 1030) 280
|
|
||||||
:else 230)
|
|
||||||
|
|
||||||
ratio (if (some? @width) (/ @width itemsize) 0)
|
itemsize (cond
|
||||||
nitems (mth/floor ratio)
|
(some? itemsize) itemsize
|
||||||
limit (min 10 nitems)
|
(>= width 1030) 280
|
||||||
limit (max 1 limit)]
|
:else 230)
|
||||||
|
|
||||||
(mf/with-effect
|
ratio (if (some? width) (/ width itemsize) 0)
|
||||||
|
nitems (mth/floor ratio)
|
||||||
|
limit (mth/min 10 nitems)
|
||||||
|
limit (mth/max 1 limit)]
|
||||||
|
|
||||||
|
(mf/with-effect []
|
||||||
(let [node (mf/ref-val rowref)
|
(let [node (mf/ref-val rowref)
|
||||||
mnt? (volatile! true)
|
mnt? (volatile! true)
|
||||||
sub (->> (wapi/observe-resize node)
|
sub (->> (wapi/observe-resize node)
|
||||||
(rx/observe-on :af)
|
(rx/observe-on :af)
|
||||||
(rx/subs (fn [entries]
|
(rx/subs (fn [entries]
|
||||||
(let [row (first entries)
|
(let [row (first entries)
|
||||||
row-rect (.-contentRect ^js row)
|
row-rect (.-contentRect ^js row)
|
||||||
row-width (.-width ^js row-rect)]
|
row-width (.-width ^js row-rect)]
|
||||||
(when @mnt?
|
(when @mnt?
|
||||||
(reset! width row-width)
|
(reset! width* row-width)
|
||||||
(swap! storage assoc :items-width row-width))))))]
|
(swap! storage assoc :items-width row-width))))))]
|
||||||
(fn []
|
(fn []
|
||||||
(vreset! mnt? false)
|
(vreset! mnt? false)
|
||||||
|
|||||||
@ -21,12 +21,12 @@
|
|||||||
[app.main.data.workspace.specialized-panel :as-alias dwsp]
|
[app.main.data.workspace.specialized-panel :as-alias dwsp]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
|
||||||
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
|
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.dom.dnd :as dnd]
|
[app.util.dom.dnd :as dnd]
|
||||||
[app.util.dom.normalize-wheel :as nw]
|
[app.util.dom.normalize-wheel :as nw]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.timers :as timers]
|
[app.util.timers :as timers]
|
||||||
[app.util.webapi :as wapi]
|
[app.util.webapi :as wapi]
|
||||||
@ -85,7 +85,7 @@
|
|||||||
|
|
||||||
left-click?
|
left-click?
|
||||||
(do
|
(do
|
||||||
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?)
|
(st/emit! (mse/->MouseEvent :down ctrl? shift? alt? meta?)
|
||||||
::dwsp/interrupt)
|
::dwsp/interrupt)
|
||||||
|
|
||||||
(when (and (not= edition id) (or text-editing? grid-editing?))
|
(when (and (not= edition id) (or text-editing? grid-editing?))
|
||||||
@ -173,7 +173,7 @@
|
|||||||
hovering? (some? @hover)
|
hovering? (some? @hover)
|
||||||
raw-pt (dom/get-client-position event)
|
raw-pt (dom/get-client-position event)
|
||||||
pt (uwvv/point->viewport raw-pt)]
|
pt (uwvv/point->viewport raw-pt)]
|
||||||
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt? meta?))
|
(st/emit! (mse/->MouseEvent :click ctrl? shift? alt? meta?))
|
||||||
|
|
||||||
(when (and hovering?
|
(when (and hovering?
|
||||||
(not @space?)
|
(not @space?)
|
||||||
@ -213,7 +213,7 @@
|
|||||||
|
|
||||||
grid-layout-id (->> @hover-ids reverse (d/seek (partial ctl/grid-layout? objects)))]
|
grid-layout-id (->> @hover-ids reverse (d/seek (partial ctl/grid-layout? objects)))]
|
||||||
|
|
||||||
(st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?))
|
(st/emit! (mse/->MouseEvent :double-click ctrl? shift? alt? meta?))
|
||||||
|
|
||||||
;; Emit asynchronously so the double click to exit shapes won't break
|
;; Emit asynchronously so the double click to exit shapes won't break
|
||||||
(timers/schedule
|
(timers/schedule
|
||||||
@ -283,7 +283,7 @@
|
|||||||
middle-click? (= 2 (.-which event))]
|
middle-click? (= 2 (.-which event))]
|
||||||
|
|
||||||
(when left-click?
|
(when left-click?
|
||||||
(st/emit! (ms/->MouseEvent :up ctrl? shift? alt? meta?)))
|
(st/emit! (mse/->MouseEvent :up ctrl? shift? alt? meta?)))
|
||||||
|
|
||||||
(when middle-click?
|
(when middle-click?
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
@ -314,29 +314,33 @@
|
|||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)
|
alt? (kbd/alt? event)
|
||||||
meta? (kbd/meta? event)
|
meta? (kbd/meta? event)
|
||||||
|
mod? (kbd/mod? event)
|
||||||
target (dom/get-target event)
|
target (dom/get-target event)
|
||||||
|
|
||||||
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
||||||
(= "rich-text" (obj/get target "className"))
|
(= "rich-text" (obj/get target "className"))
|
||||||
(= "INPUT" (obj/get target "tagName"))
|
(= "INPUT" (obj/get target "tagName"))
|
||||||
(= "TEXTAREA" (obj/get target "tagName")))]
|
(= "TEXTAREA" (obj/get target "tagName")))]
|
||||||
|
|
||||||
(when-not (.-repeat bevent)
|
(when-not (.-repeat bevent)
|
||||||
(st/emit! (ms/->KeyboardEvent :down key shift? ctrl? alt? meta? editing?)))))))
|
(st/emit! (kbd/->KeyboardEvent :down key shift? ctrl? alt? meta? mod? editing? event)))))))
|
||||||
|
|
||||||
(defn on-key-up []
|
(defn on-key-up []
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(let [key (.-key event)
|
(let [key (.-key event)
|
||||||
ctrl? (kbd/ctrl? event)
|
ctrl? (kbd/ctrl? event)
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)
|
alt? (kbd/alt? event)
|
||||||
meta? (kbd/meta? event)
|
meta? (kbd/meta? event)
|
||||||
|
mod? (kbd/mod? event)
|
||||||
target (dom/get-target event)
|
target (dom/get-target event)
|
||||||
|
|
||||||
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
editing? (or (some? (.closest ^js target ".public-DraftEditor-content"))
|
||||||
(= "rich-text" (obj/get target "className"))
|
(= "rich-text" (obj/get target "className"))
|
||||||
(= "INPUT" (obj/get target "tagName"))
|
(= "INPUT" (obj/get target "tagName"))
|
||||||
(= "TEXTAREA" (obj/get target "tagName")))]
|
(= "TEXTAREA" (obj/get target "tagName")))]
|
||||||
(st/emit! (ms/->KeyboardEvent :up key shift? ctrl? alt? meta? editing?))))))
|
(st/emit! (kbd/->KeyboardEvent :up key shift? ctrl? alt? meta? mod? editing? event))))))
|
||||||
|
|
||||||
(defn on-pointer-move [move-stream]
|
(defn on-pointer-move [move-stream]
|
||||||
(let [last-position (mf/use-var nil)]
|
(let [last-position (mf/use-var nil)]
|
||||||
@ -353,16 +357,16 @@
|
|||||||
|
|
||||||
(rx/push! move-stream pt)
|
(rx/push! move-stream pt)
|
||||||
(reset! last-position raw-pt)
|
(reset! last-position raw-pt)
|
||||||
(st/emit! (ms/->PointerEvent :delta delta
|
(st/emit! (mse/->PointerEvent :delta delta
|
||||||
(kbd/ctrl? event)
|
(kbd/ctrl? event)
|
||||||
(kbd/shift? event)
|
(kbd/shift? event)
|
||||||
(kbd/alt? event)
|
(kbd/alt? event)
|
||||||
(kbd/meta? event)))
|
(kbd/meta? event)))
|
||||||
(st/emit! (ms/->PointerEvent :viewport pt
|
(st/emit! (mse/->PointerEvent :viewport pt
|
||||||
(kbd/ctrl? event)
|
(kbd/ctrl? event)
|
||||||
(kbd/shift? event)
|
(kbd/shift? event)
|
||||||
(kbd/alt? event)
|
(kbd/alt? event)
|
||||||
(kbd/meta? event))))))))
|
(kbd/meta? event))))))))
|
||||||
|
|
||||||
(defn on-mouse-wheel [zoom]
|
(defn on-mouse-wheel [zoom]
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
|||||||
@ -15,8 +15,8 @@
|
|||||||
[app.main.data.workspace.colors :as dc]
|
[app.main.data.workspace.colors :as dc]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
|
[app.util.mouse :as mse]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
@ -154,14 +154,14 @@
|
|||||||
(mf/deps @moving-point from-p to-p width-p)
|
(mf/deps @moving-point from-p to-p width-p)
|
||||||
(fn []
|
(fn []
|
||||||
(let [subs (->> st/stream
|
(let [subs (->> st/stream
|
||||||
(rx/filter ms/pointer-event?)
|
(rx/filter mse/pointer-event?)
|
||||||
(rx/filter #(= :viewport (:source %)))
|
(rx/filter #(= :viewport (mse/get-pointer-source %)))
|
||||||
(rx/map :pt)
|
(rx/map mse/get-pointer-position)
|
||||||
(rx/subs
|
(rx/subs
|
||||||
(fn [pt]
|
(fn [pt]
|
||||||
(case @moving-point
|
(case @moving-point
|
||||||
:from-p (when on-change-start (on-change-start pt))
|
:from-p (when on-change-start (on-change-start pt))
|
||||||
:to-p (when on-change-finish (on-change-finish pt))
|
:to-p (when on-change-finish (on-change-finish pt))
|
||||||
:width-p (when on-change-width
|
:width-p (when on-change-width
|
||||||
(let [width-v (gpt/unit (gpt/to-vec from-p width-p))
|
(let [width-v (gpt/unit (gpt/to-vec from-p width-p))
|
||||||
distance (gpt/point-line-distance pt from-p to-p)
|
distance (gpt/point-line-distance pt from-p to-p)
|
||||||
|
|||||||
@ -31,6 +31,7 @@
|
|||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.globals :as globals]
|
[app.util.globals :as globals]
|
||||||
|
[app.util.keyboard :as kbd]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[goog.events :as events]
|
[goog.events :as events]
|
||||||
[rumext.v2 :as mf])
|
[rumext.v2 :as mf])
|
||||||
@ -99,14 +100,57 @@
|
|||||||
(when (not= @cursor new-cursor)
|
(when (not= @cursor new-cursor)
|
||||||
(reset! cursor new-cursor))))))
|
(reset! cursor new-cursor))))))
|
||||||
|
|
||||||
(defn setup-keyboard [alt? mod? space? z? shift?]
|
(defn setup-keyboard
|
||||||
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
|
[alt* mod* space* z* shift*]
|
||||||
(hooks/use-stream ms/keyboard-mod #(do
|
(let [kbd-zoom-s
|
||||||
(reset! mod? %)
|
(mf/with-memo []
|
||||||
(when-not % (reset! z? false)))) ;; In mac after command+z there is no event for the release of the z key
|
(->> ms/keyboard
|
||||||
(hooks/use-stream ms/keyboard-space #(reset! space? %))
|
(rx/filter kbd/key-down-event?)
|
||||||
(hooks/use-stream ms/keyboard-z #(reset! z? %))
|
(rx/filter kbd/mod-event?)
|
||||||
(hooks/use-stream ms/keyboard-shift #(reset! shift? %)))
|
(rx/filter (fn [kevent]
|
||||||
|
(or ^boolean (kbd/minus? kevent)
|
||||||
|
^boolean (kbd/underscore? kevent)
|
||||||
|
^boolean (kbd/equals? kevent)
|
||||||
|
^boolean (kbd/plus? kevent))))
|
||||||
|
(rx/dedupe)))
|
||||||
|
|
||||||
|
kbd-shift-s
|
||||||
|
(mf/with-memo []
|
||||||
|
(->> ms/keyboard
|
||||||
|
(rx/filter kbd/shift-key?)
|
||||||
|
(rx/filter (complement kbd/editing-event?))
|
||||||
|
(rx/map kbd/key-down-event?)
|
||||||
|
(rx/dedupe)))
|
||||||
|
|
||||||
|
kbd-z-s
|
||||||
|
(mf/with-memo []
|
||||||
|
(->> ms/keyboard
|
||||||
|
(rx/filter kbd/z?)
|
||||||
|
(rx/filter (complement kbd/editing-event?))
|
||||||
|
(rx/map kbd/key-down-event?)
|
||||||
|
(rx/dedupe)))]
|
||||||
|
|
||||||
|
(hooks/use-stream ms/keyboard-alt (partial reset! alt*))
|
||||||
|
(hooks/use-stream ms/keyboard-space (partial reset! space*))
|
||||||
|
(hooks/use-stream kbd-z-s (partial reset! z*))
|
||||||
|
(hooks/use-stream kbd-shift-s (partial reset! shift*))
|
||||||
|
(hooks/use-stream ms/keyboard-mod
|
||||||
|
(fn [value]
|
||||||
|
(reset! mod* value)
|
||||||
|
;; In mac after command+z there is no event
|
||||||
|
;; for the release of the z key
|
||||||
|
(when-not ^boolean value
|
||||||
|
(reset! z* false))))
|
||||||
|
|
||||||
|
(hooks/use-stream kbd-zoom-s
|
||||||
|
(fn [kevent]
|
||||||
|
(dom/prevent-default kevent)
|
||||||
|
(st/emit!
|
||||||
|
(if (or ^boolean (kbd/minus? kevent)
|
||||||
|
^boolean (kbd/underscore? kevent))
|
||||||
|
(dw/decrease-zoom)
|
||||||
|
(dw/increase-zoom)))))))
|
||||||
|
|
||||||
|
|
||||||
(defn group-empty-space?
|
(defn group-empty-space?
|
||||||
"Given a group `group-id` check if `hover-ids` contains any of its children. If it doesn't means
|
"Given a group `group-id` check if `hover-ids` contains any of its children. If it doesn't means
|
||||||
|
|||||||
@ -9,15 +9,44 @@
|
|||||||
[app.config :as cfg]
|
[app.config :as cfg]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
|
(defrecord KeyboardEvent [type key shift ctrl alt meta mod editing native-event]
|
||||||
|
Object
|
||||||
|
(preventDefault [_]
|
||||||
|
(.preventDefault native-event))
|
||||||
|
|
||||||
|
(stopPropagation [_]
|
||||||
|
(.stopPropagation native-event)))
|
||||||
|
|
||||||
|
(defn keyboard-event?
|
||||||
|
[o]
|
||||||
|
(instance? KeyboardEvent o))
|
||||||
|
|
||||||
|
(defn key-up-event?
|
||||||
|
[^KeyboardEvent event]
|
||||||
|
(= :up (.-type event)))
|
||||||
|
|
||||||
|
(defn key-down-event?
|
||||||
|
[^KeyboardEvent event]
|
||||||
|
(= :down (.-type event)))
|
||||||
|
|
||||||
|
(defn mod-event?
|
||||||
|
[^KeyboardEvent event]
|
||||||
|
(true? (.-mod event)))
|
||||||
|
|
||||||
|
(defn editing-event?
|
||||||
|
[^KeyboardEvent event]
|
||||||
|
(true? (.-editing event)))
|
||||||
|
|
||||||
(defn is-key?
|
(defn is-key?
|
||||||
[^string key]
|
[^string key]
|
||||||
(fn [^js e]
|
(fn [^KeyboardEvent e]
|
||||||
(= (.-key e) key)))
|
(= (.-key e) key)))
|
||||||
|
|
||||||
(defn is-key-ignore-case?
|
(defn is-key-ignore-case?
|
||||||
[^string key]
|
[^string key]
|
||||||
(fn [^js e]
|
(let [key (str/upper key)]
|
||||||
(= (str/upper (.-key e)) (str/upper key))))
|
(fn [^KeyboardEvent e]
|
||||||
|
(= (str/upper (.-key e)) key))))
|
||||||
|
|
||||||
(defn ^boolean alt?
|
(defn ^boolean alt?
|
||||||
[^js event]
|
[^js event]
|
||||||
@ -45,6 +74,10 @@
|
|||||||
(def enter? (is-key? "Enter"))
|
(def enter? (is-key? "Enter"))
|
||||||
(def space? (is-key? " "))
|
(def space? (is-key? " "))
|
||||||
(def z? (is-key-ignore-case? "z"))
|
(def z? (is-key-ignore-case? "z"))
|
||||||
|
(def equals? (is-key? "="))
|
||||||
|
(def plus? (is-key? "+"))
|
||||||
|
(def minus? (is-key? "-"))
|
||||||
|
(def underscore? (is-key? "_"))
|
||||||
(def up-arrow? (is-key? "ArrowUp"))
|
(def up-arrow? (is-key? "ArrowUp"))
|
||||||
(def down-arrow? (is-key? "ArrowDown"))
|
(def down-arrow? (is-key? "ArrowDown"))
|
||||||
(def left-arrow? (is-key? "ArrowLeft"))
|
(def left-arrow? (is-key? "ArrowLeft"))
|
||||||
@ -58,6 +91,3 @@
|
|||||||
(def home? (is-key? "Home"))
|
(def home? (is-key? "Home"))
|
||||||
(def tab? (is-key? "Tab"))
|
(def tab? (is-key? "Tab"))
|
||||||
|
|
||||||
(defn editing? [e]
|
|
||||||
(.-editing ^js e))
|
|
||||||
|
|
||||||
|
|||||||
63
frontend/src/app/util/mouse.cljs
Normal file
63
frontend/src/app/util/mouse.cljs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.util.mouse)
|
||||||
|
|
||||||
|
(defrecord MouseEvent [type ctrl shift alt meta])
|
||||||
|
(defrecord PointerEvent [source pt ctrl shift alt meta])
|
||||||
|
(defrecord ScrollEvent [point])
|
||||||
|
|
||||||
|
(defn mouse-event?
|
||||||
|
[v]
|
||||||
|
(instance? MouseEvent v))
|
||||||
|
|
||||||
|
(defn pointer-event?
|
||||||
|
[v]
|
||||||
|
(instance? PointerEvent v))
|
||||||
|
|
||||||
|
(defn scroll-event?
|
||||||
|
[v]
|
||||||
|
(instance? ScrollEvent v))
|
||||||
|
|
||||||
|
(defn mouse-down-event?
|
||||||
|
[^MouseEvent v]
|
||||||
|
(= :down (.-type v)))
|
||||||
|
|
||||||
|
(defn mouse-up-event?
|
||||||
|
[^MouseEvent v]
|
||||||
|
(= :up (.-type v)))
|
||||||
|
|
||||||
|
(defn mouse-click-event?
|
||||||
|
[^MouseEvent v]
|
||||||
|
(= :click (.-type v)))
|
||||||
|
|
||||||
|
(defn mouse-double-click-event?
|
||||||
|
[^MouseEvent v]
|
||||||
|
(= :double-click (.-type v)))
|
||||||
|
|
||||||
|
(defn get-pointer-source
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-source ev))
|
||||||
|
|
||||||
|
(defn get-pointer-position
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-pt ev))
|
||||||
|
|
||||||
|
(defn get-pointer-ctrl-mod
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-ctrl ev))
|
||||||
|
|
||||||
|
(defn get-pointer-meta-mod
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-meta ev))
|
||||||
|
|
||||||
|
(defn get-pointer-alt-mod
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-meta ev))
|
||||||
|
|
||||||
|
(defn get-pointer-shift-mod
|
||||||
|
[^PointerEvent ev]
|
||||||
|
(.-meta ev))
|
||||||
Loading…
x
Reference in New Issue
Block a user