mirror of
https://github.com/penpot/penpot.git
synced 2025-01-23 23:18:48 -05:00
✨ Fix problems moving frames
This commit is contained in:
parent
7caf4b9136
commit
c86d88834e
4 changed files with 77 additions and 54 deletions
|
@ -29,7 +29,7 @@
|
|||
|
||||
(defn frame-shape?
|
||||
([objects id]
|
||||
(= (get-in objects [id :type]) id))
|
||||
(frame-shape? (get objects id)))
|
||||
([{:keys [type]}]
|
||||
(= type :frame)))
|
||||
|
||||
|
@ -467,7 +467,6 @@
|
|||
|
||||
(defn selected-with-children
|
||||
[objects selected]
|
||||
|
||||
(into selected
|
||||
(mapcat #(get-children-ids objects %))
|
||||
selected))
|
||||
|
|
|
@ -224,16 +224,25 @@
|
|||
"Search for the top nested frame for positioning shapes when moving or creating.
|
||||
Looks for all the frames in a position and then goes in depth between the top-most and its
|
||||
children to find the target."
|
||||
[objects position]
|
||||
(let [frame-ids (all-frames-by-position objects position)
|
||||
frame-set (set frame-ids)]
|
||||
(loop [current-id (first frame-ids)]
|
||||
(let [current-shape (get objects current-id)
|
||||
child-frame-id (d/seek #(contains? frame-set %)
|
||||
(-> (:shapes current-shape) reverse))]
|
||||
(if (nil? child-frame-id)
|
||||
(or current-id uuid/zero)
|
||||
(recur child-frame-id))))))
|
||||
([objects position]
|
||||
(top-nested-frame objects position nil))
|
||||
|
||||
([objects position excluded]
|
||||
(assert (or (nil? excluded) (set? excluded)))
|
||||
|
||||
(let [frame-ids (cond->> (all-frames-by-position objects position)
|
||||
(some? excluded)
|
||||
(remove excluded))
|
||||
|
||||
frame-set (set frame-ids)]
|
||||
|
||||
(loop [current-id (first frame-ids)]
|
||||
(let [current-shape (get objects current-id)
|
||||
child-frame-id (d/seek #(contains? frame-set %)
|
||||
(-> (:shapes current-shape) reverse))]
|
||||
(if (nil? child-frame-id)
|
||||
(or current-id uuid/zero)
|
||||
(recur child-frame-id)))))))
|
||||
|
||||
(defn top-nested-frame-ids
|
||||
"Search the top nested frame in a list of ids"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace.changes :as dch]
|
||||
[app.main.data.workspace.comments :as-alias dwcm]
|
||||
[app.main.data.workspace.guides :as-alias dwg]
|
||||
|
@ -144,12 +145,11 @@
|
|||
(into {} (map #(vector % {:modifiers (get-modifier (get objects %))})) ids))
|
||||
|
||||
(defn build-change-frame-modifiers
|
||||
[modif-tree objects selected target-frame position]
|
||||
[modif-tree objects selected target-frame drop-index]
|
||||
|
||||
(let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
|
||||
layout? (get-in objects [target-frame :layout])
|
||||
child-set (set (get-in objects [target-frame :shapes]))
|
||||
drop-index (when layout? (gsl/get-drop-index target-frame objects position))
|
||||
layout? (ctl/layout? objects target-frame)
|
||||
|
||||
update-frame-modifiers
|
||||
(fn [modif-tree [original-frame shapes]]
|
||||
|
|
|
@ -353,7 +353,7 @@
|
|||
|
||||
(declare start-move)
|
||||
(declare start-move-duplicate)
|
||||
(declare calculate-frame-for-move)
|
||||
(declare move-shapes-to-frame)
|
||||
(declare get-displacement)
|
||||
|
||||
(defn start-move-selected
|
||||
|
@ -414,7 +414,6 @@
|
|||
(rx/take 1)
|
||||
(rx/map #(start-move from-position))))))
|
||||
|
||||
|
||||
(defn- start-move
|
||||
([from-position] (start-move from-position nil))
|
||||
([from-position ids]
|
||||
|
@ -436,13 +435,18 @@
|
|||
zoom (get-in state [:workspace-local :zoom] 1)
|
||||
focus (:workspace-focus-selected state)
|
||||
|
||||
fix-axis (fn [[position shift?]]
|
||||
(let [delta (gpt/to-vec from-position position)]
|
||||
(if shift?
|
||||
(if (> (mth/abs (:x delta)) (mth/abs (:y delta)))
|
||||
(gpt/point (:x delta) 0)
|
||||
(gpt/point 0 (:y delta)))
|
||||
delta)))
|
||||
exclude-frames (into #{}
|
||||
(filter (partial cph/frame-shape? objects))
|
||||
(cph/selected-with-children objects selected))
|
||||
|
||||
fix-axis
|
||||
(fn [[position shift?]]
|
||||
(let [delta (gpt/to-vec from-position position)]
|
||||
(if shift?
|
||||
(if (> (mth/abs (:x delta)) (mth/abs (:y delta)))
|
||||
(gpt/point (:x delta) 0)
|
||||
(gpt/point 0 (:y delta)))
|
||||
delta)))
|
||||
|
||||
position (->> ms/mouse-position
|
||||
(rx/with-latest-from ms/mouse-position-shift)
|
||||
|
@ -456,33 +460,48 @@
|
|||
(rx/switch-map
|
||||
(fn [pos]
|
||||
(->> (snap/closest-snap-move page-id shapes objects layout zoom focus pos)
|
||||
(rx/map #(vector pos %)))))))]
|
||||
(rx/map #(vector pos %)))))))
|
||||
|
||||
drop-frame (atom nil)]
|
||||
(if (empty? shapes)
|
||||
(rx/of (finish-transform))
|
||||
(rx/concat
|
||||
(rx/merge
|
||||
(->> position
|
||||
;; We ask for the snap position but we continue even if the result is not available
|
||||
(rx/with-latest vector snap-delta)
|
||||
(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)
|
||||
|
||||
;; 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)
|
||||
;; 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/map
|
||||
(fn [move-vector]
|
||||
(let [position (gpt/add from-position move-vector)
|
||||
target-frame (ctst/top-nested-frame objects position)]
|
||||
(-> (dwm/create-modif-tree ids (ctm/move move-vector))
|
||||
(dwm/build-change-frame-modifiers objects selected target-frame position)
|
||||
(dwm/set-modifiers)))))
|
||||
(rx/map
|
||||
(fn [move-vector]
|
||||
(let [position (gpt/add from-position move-vector)
|
||||
target-frame (ctst/top-nested-frame objects position exclude-frames)
|
||||
layout? (ctl/layout? objects target-frame)
|
||||
drop-index (when layout? (gsl/get-drop-index target-frame objects position))]
|
||||
[move-vector target-frame drop-index])))
|
||||
|
||||
(rx/take-until stopper)))
|
||||
(rx/take-until stopper))]
|
||||
|
||||
(rx/of (dwu/start-undo-transaction)
|
||||
(calculate-frame-for-move ids)
|
||||
(dwm/apply-modifiers {:undo-transation? false})
|
||||
(finish-transform)
|
||||
(dwu/commit-undo-transaction)))))))))
|
||||
(rx/merge
|
||||
;; Temporary modifiers stream
|
||||
(->> move-stream
|
||||
(rx/map
|
||||
(fn [[move-vector target-frame drop-index]]
|
||||
(-> (dwm/create-modif-tree ids (ctm/move move-vector))
|
||||
(dwm/build-change-frame-modifiers objects selected target-frame drop-index)
|
||||
(dwm/set-modifiers)))))
|
||||
|
||||
;; Last event will write the modifiers creating the changes
|
||||
(->> move-stream
|
||||
(rx/last)
|
||||
(rx/mapcat
|
||||
(fn [[move-vector target-frame drop-index]]
|
||||
(rx/of (dwu/start-undo-transaction)
|
||||
(move-shapes-to-frame ids target-frame drop-index)
|
||||
(dwm/apply-modifiers {:undo-transation? false})
|
||||
(finish-transform)
|
||||
(dwu/commit-undo-transaction)))))))))))))
|
||||
|
||||
(s/def ::direction #{:up :down :right :left})
|
||||
|
||||
|
@ -561,15 +580,13 @@
|
|||
(rx/of (dwm/set-modifiers modif-tree)
|
||||
(dwm/apply-modifiers))))))
|
||||
|
||||
(defn- calculate-frame-for-move
|
||||
[ids]
|
||||
(ptk/reify ::calculate-frame-for-move
|
||||
(defn- move-shapes-to-frame
|
||||
[ids frame-id drop-index]
|
||||
(ptk/reify ::move-shapes-to-frame
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(let [position @ms/mouse-position
|
||||
page-id (:current-page-id state)
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
frame-id (ctst/top-nested-frame objects position)
|
||||
layout? (get-in objects [frame-id :layout])
|
||||
lookup (d/getf objects)
|
||||
|
||||
|
@ -584,14 +601,12 @@
|
|||
(remove #(and (= (:frame-id %) frame-id)
|
||||
(not= (:parent-id %) frame-id))))
|
||||
|
||||
drop-index (when layout? (gsl/get-drop-index frame-id objects position))
|
||||
|
||||
changes
|
||||
(-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
(pcb/change-parent frame-id moving-shapes drop-index))]
|
||||
|
||||
(when-not (empty? changes)
|
||||
(when (and (some? frame-id) (not (empty? changes)))
|
||||
(rx/of (dch/commit-changes changes)
|
||||
(dwc/expand-collapse frame-id)))))))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue