diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index 7884b123a..1823ebd22 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -24,6 +24,7 @@ [app.main.data.workspace.state-helpers :as wsh] [app.main.snap :as snap] [app.main.streams :as ms] + [app.util.array :as array] [app.util.mouse :as mse] [beicon.v2.core :as rx] [potok.v2.core :as ptk])) @@ -128,12 +129,11 @@ (->> ms/mouse-position (rx/filter #(> (gpt/distance % initial) (/ 2 zoom))) - (rx/with-latest vector ms/mouse-position-shift) - (rx/with-latest conj ms/mouse-position-mod) + (rx/with-latest-from ms/mouse-position-shift ms/mouse-position-mod) (rx/switch-map (fn [[point :as current]] (->> (snap/closest-snap-point page-id [shape] objects layout zoom focus point) - (rx/map #(conj current %))))) + (rx/map (partial array/conj current))))) (rx/map (fn [[_ shift? mod? point]] #(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift? mod?))))) diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index 8152b7a23..64007cc8f 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -46,7 +46,8 @@ command (helpers/next-node shape position last-point prev-handler)] (assoc-in state [:workspace-local :edit-path id :preview] command))))) -(defn add-node [{:keys [x y shift?]}] +(defn add-node + [{:keys [x y shift?]}] (ptk/reify ::add-node ptk/UpdateEvent (update [_ state] @@ -135,7 +136,7 @@ (first handlers)) drag-events-stream - (->> (streams/position-stream) + (->> (streams/position-stream state) (rx/map #(drag-handler position idx prefix %)) (rx/take-until (rx/merge @@ -164,7 +165,7 @@ (defn start-path-from-point [position] (ptk/reify ::start-path-from-point ptk/WatchEvent - (watch [_ _ stream] + (watch [_ state stream] (let [stoper (rx/merge (->> stream (rx/filter mse/mouse-event?) @@ -172,7 +173,7 @@ (->> stream (rx/filter helpers/end-path-event?))) - drag-events (->> (streams/position-stream) + drag-events (->> (streams/position-stream state) (rx/map #(drag-handler %)) (rx/take-until stoper))] (rx/concat @@ -190,7 +191,12 @@ (rx/merge-map #(rx/empty)))) (defn make-drag-stream - [stream down-event] + [state stream down-event] + + (dm/assert! + "should be a pointer" + (gpt/point? down-event)) + (let [stoper (rx/merge (->> stream (rx/filter mse/mouse-event?) @@ -198,7 +204,7 @@ (->> stream (rx/filter helpers/end-path-event?))) - drag-events (->> (streams/position-stream) + drag-events (->> (streams/position-stream state) (rx/map #(drag-handler %)) (rx/take-until stoper))] (rx/concat @@ -217,7 +223,7 @@ (assoc-in state [:workspace-local :edit-path id :edit-mode] :draw))) ptk/WatchEvent - (watch [_ _ stream] + (watch [_ state stream] (let [mouse-down (->> stream (rx/filter mse/mouse-event?) (rx/filter mse/mouse-down-event?)) @@ -226,7 +232,7 @@ ;; Mouse move preview mousemove-events - (->> (streams/position-stream) + (->> (streams/position-stream state) (rx/take-until end-path-events) (rx/map #(preview-next-point %))) @@ -234,12 +240,13 @@ mousedown-events (->> mouse-down (rx/take-until end-path-events) - (rx/with-latest merge (streams/position-stream)) - + ;; We just ignore the mouse event and stream down the + ;; last position event + (rx/with-latest-from #(-> %2) (streams/position-stream state)) ;; We change to the stream that emits the first event (rx/switch-map #(rx/race (make-node-events-stream stream) - (make-drag-stream stream %))))] + (make-drag-stream state stream %))))] (rx/concat (rx/of (undo/start-path-undo)) diff --git a/frontend/src/app/main/data/workspace/path/streams.cljs b/frontend/src/app/main/data/workspace/path/streams.cljs index 2acc5ceba..3c429d666 100644 --- a/frontend/src/app/main/data/workspace/path/streams.cljs +++ b/frontend/src/app/main/data/workspace/path/streams.cljs @@ -115,7 +115,6 @@ (defn move-handler-stream [start-point node handler opposite points] - (let [zoom (get-in @st/state [:workspace-local :zoom] 1) ranges (snap/create-ranges points) d-pos (/ snap/snap-path-accuracy zoom) @@ -145,16 +144,20 @@ (let [snap (snap/get-snap-delta [handler] ranges d-pos)] (merge position (gpt/add position snap))))) position))] + (->> ms/mouse-position (rx/map to-pixel-snap) - (rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %)))) - (rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %)))) + (rx/with-latest-from + (fn [position shift? alt?] + (assoc position :shift? shift? :alt? alt?)) + ms/mouse-position-shift + ms/mouse-position-alt) (rx/with-latest-from (snap-toggled-stream)) (rx/map check-path-snap)))) (defn position-stream - [] - (let [zoom (get-in @st/state [:workspace-local :zoom] 1) + [state] + (let [zoom (get-in state [:workspace-local :zoom] 1) d-pos (/ snap/snap-path-accuracy zoom) get-content #(pst/get-path % :content) @@ -169,12 +172,14 @@ (->> ms/mouse-position (rx/map to-pixel-snap) - (rx/with-latest vector ranges-stream) - (rx/with-latest-from (snap-toggled-stream)) - (rx/map (fn [[[position ranges] snap-toggled]] + (rx/with-latest-from ranges-stream (snap-toggled-stream)) + (rx/map (fn [[position ranges snap-toggled]] (if snap-toggled (let [snap (snap/get-snap-delta [position] ranges d-pos)] (gpt/add position snap)) position))) - (rx/with-latest merge (->> ms/mouse-position-shift (rx/map #(hash-map :shift? %)))) - (rx/with-latest merge (->> ms/mouse-position-alt (rx/map #(hash-map :alt? %))))))) + (rx/with-latest-from + (fn [position shift? alt?] + (assoc position :shift? shift? :alt? alt?)) + ms/mouse-position-shift + ms/mouse-position-alt)))) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index fa44b8746..cc514517b 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -32,6 +32,7 @@ [app.main.data.workspace.undo :as dwu] [app.main.snap :as snap] [app.main.streams :as ms] + [app.util.array :as array] [app.util.dom :as dom] [app.util.keyboard :as kbd] [app.util.mouse :as mse] @@ -109,7 +110,7 @@ "Enter mouse resize mode, until mouse button is released." [handler ids shape] (letfn [(resize - [shape initial layout [point lock? center? point-snap]] + [shape initial layout [point lock? center? point-snap]] (let [{:keys [width height]} (:selrect shape) {:keys [rotation]} shape @@ -333,10 +334,9 @@ angle))] (rx/concat (->> ms/mouse-position - (rx/with-latest vector ms/mouse-position-mod) - (rx/with-latest vector ms/mouse-position-shift) + (rx/with-latest-from ms/mouse-position-mod ms/mouse-position-shift) (rx/map - (fn [[[pos mod?] shift?]] + (fn [[pos mod? shift?]] (let [delta-angle (calculate-angle pos mod? shift?)] (dwm/set-rotation-modifiers delta-angle shapes group-center)))) (rx/take-until stoper)) @@ -354,8 +354,8 @@ objects (wsh/lookup-page-objects state page-id) shapes (->> ids (map #(get objects %)))] (rx/concat - (rx/of (dwm/set-delta-rotation-modifiers rotation shapes)) - (rx/of (dwm/apply-modifiers))))))) + (rx/of (dwm/set-delta-rotation-modifiers rotation shapes)) + (rx/of (dwm/apply-modifiers))))))) ;; -- Move ---------------------------------------------------------- @@ -395,7 +395,7 @@ (rx/map #(gpt/length %)) (rx/filter #(> % (/ 10 zoom))) (rx/take 1) - (rx/with-latest vector ms/mouse-position-alt) + (rx/with-latest-from ms/mouse-position-alt) (rx/mapcat (fn [[_ alt?]] (rx/concat @@ -480,22 +480,23 @@ ;; We send the nil first so the stream is not waiting for the first value (rx/of nil) (->> position + ;; FIXME: performance throttle (rx/throttle 20) (rx/switch-map (fn [pos] (->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos) - (rx/map #(vector pos %)))))))] + (rx/map #(array pos %)))))))] (if (empty? shapes) (rx/of (finish-transform)) (let [move-stream (->> position ;; We ask for the snap position but we continue even if the result is not available - (rx/with-latest vector snap-delta) + (rx/with-latest-from snap-delta) ;; We try to use the previous snap so we don't have to wait for the result of the new (rx/map snap/correct-snap-point) - (rx/with-latest vector ms/mouse-position-mod) + (rx/with-latest-from ms/mouse-position-mod) (rx/map (fn [[move-vector mod?]] @@ -506,16 +507,16 @@ grid-layout? (ctl/grid-layout? objects target-frame) drop-index (when flex-layout? (gslf/get-drop-index target-frame objects position)) cell-data (when (and grid-layout? (not mod?)) (gslg/get-drop-cell target-frame objects position))] - [move-vector target-frame drop-index cell-data]))) + (array move-vector target-frame drop-index cell-data)))) (rx/take-until stopper))] (rx/merge ;; Temporary modifiers stream (->> move-stream - (rx/with-latest-from ms/mouse-position-shift) + (rx/with-latest-from array/conj ms/mouse-position-shift) (rx/map - (fn [[[move-vector target-frame drop-index cell-data] shift?]] + (fn [[move-vector target-frame drop-index cell-data shift?]] (let [x-disp? (> (mth/abs (:x move-vector)) (mth/abs (:y move-vector))) [move-vector snap-ignore-axis] (cond @@ -538,15 +539,15 @@ (dwm/set-modifiers false false {:snap-ignore-axis snap-ignore-axis})))))) (->> move-stream - (rx/with-latest-from ms/mouse-position-alt) - (rx/filter (fn [[_ alt?]] alt?)) - (rx/take 1) - (rx/mapcat - (fn [[_ alt?]] - (if (and (not duplicate-move-started?) alt?) - (rx/of (start-move-duplicate from-position) - (dws/duplicate-selected false true)) - (rx/empty))))) + (rx/with-latest-from array/conj ms/mouse-position-alt) + (rx/filter (fn [[_ alt?]] alt?)) + (rx/take 1) + (rx/mapcat + (fn [[_ alt?]] + (if (and (not duplicate-move-started?) alt?) + (rx/of (start-move-duplicate from-position) + (dws/duplicate-selected false true)) + (rx/empty))))) (->> move-stream (rx/map (comp set-ghost-displacement first))) @@ -743,7 +744,7 @@ cpos (gpt/point (:x bbox) (:y bbox)) pos (gpt/point (or (:x position) (:x bbox)) - (or (:y position) (:y bbox))) + (or (:y position) (:y bbox))) delta (gpt/subtract pos cpos) diff --git a/frontend/src/app/util/array.cljs b/frontend/src/app/util/array.cljs index fa128c37e..2c85375e9 100644 --- a/frontend/src/app/util/array.cljs +++ b/frontend/src/app/util/array.cljs @@ -6,10 +6,15 @@ (ns app.util.array "A collection of helpers for work with javascript arrays." - (:refer-clojure :exclude [conj!])) + (:refer-clojure :exclude [conj! conj])) + +(defn conj + "A conj like function for js arrays." + [a v] + (js* "[...~{}, ~{}]" a v)) (defn conj! - "A conj like function for js arrays." + "A conj! like function for js arrays." [a v] (.push ^js a v) a)