From ddf8aaf68f250ae7b1e60191277ce35da3d18878 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 14 Sep 2022 12:27:48 +0200 Subject: [PATCH] :bug: Fix problem when moving shapes inside nested frames --- CHANGES.md | 3 ++- common/src/app/common/pages/helpers.cljc | 20 +++++++++++++++++ frontend/src/app/main/data/workspace.cljs | 4 ++-- .../app/main/data/workspace/drawing/box.cljs | 2 +- .../main/data/workspace/drawing/curve.cljs | 2 +- .../data/workspace/libraries_helpers.cljs | 2 +- .../app/main/data/workspace/path/drawing.cljs | 2 +- .../src/app/main/data/workspace/shapes.cljs | 5 ++--- .../app/main/data/workspace/svg_upload.cljs | 2 +- .../app/main/data/workspace/transforms.cljs | 22 ++++++++++--------- 10 files changed, 43 insertions(+), 21 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8ed3fb5f6..b1a9c6d97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,7 +9,8 @@ - Fix overlay closed on clicked outside [Taiga #4027](https://tree.taiga.io/project/penpot/issue/4027) - Fix animate multiple overlays [Taiga #3993](https://tree.taiga.io/project/penpot/issue/3993) - Fix problem with snap to grids [#2221](https://github.com/penpot/penpot/issues/2221) -- Fix issue when scaling to value 0 [Taiga #4109](https://tree.taiga.io/project/penpot/issue/4109) +- Fix issue when scaling to value 0 [#2252](https://github.com/penpot/penpot/issues/2252) +- Fix problem when moving shapes inside nested frames [Taiga #4113](https://tree.taiga.io/project/penpot/issue/4113) ## 1.15.3-beta diff --git a/common/src/app/common/pages/helpers.cljc b/common/src/app/common/pages/helpers.cljc index d31fe916f..79571d489 100644 --- a/common/src/app/common/pages/helpers.cljc +++ b/common/src/app/common/pages/helpers.cljc @@ -287,6 +287,26 @@ (d/seek #(and position (gsh/has-point? (get objects %) position))))] (or top-frame uuid/zero))) +(defn all-frames-by-position + [objects position] + (->> (get-frames-ids objects) + (sort-z-index objects) + (filterv #(and position (gsh/has-point? (get objects %) position))))) + +(defn top-nested-frame + "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)))))) + (defn frame-by-position [objects position] (let [frame-id (frame-id-by-position objects position)] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index b31a77e6d..d986be7bb 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1344,7 +1344,7 @@ [frame-id frame-id delta]) (empty? page-selected) - (let [frame-id (cph/frame-id-by-position page-objects mouse-pos) + (let [frame-id (cph/top-nested-frame page-objects mouse-pos) delta (gpt/subtract mouse-pos orig-pos)] [frame-id frame-id delta]) @@ -1456,7 +1456,7 @@ height 16 page-id (:current-page-id state) frame-id (-> (wsh/lookup-page-objects state page-id) - (cph/frame-id-by-position @ms/mouse-position)) + (cph/top-nested-frame @ms/mouse-position)) shape (cp/setup-rect-selrect {:id id :type :text diff --git a/frontend/src/app/main/data/workspace/drawing/box.cljs b/frontend/src/app/main/data/workspace/drawing/box.cljs index bdffbe1f7..fe1a62864 100644 --- a/frontend/src/app/main/data/workspace/drawing/box.cljs +++ b/frontend/src/app/main/data/workspace/drawing/box.cljs @@ -65,7 +65,7 @@ focus (:workspace-focus-selected state) zoom (get-in state [:workspace-local :zoom] 1) - fid (cph/frame-id-by-position objects initial) + fid (cph/top-nested-frame objects initial) shape (get-in state [:workspace-drawing :object]) shape (-> shape diff --git a/frontend/src/app/main/data/workspace/drawing/curve.cljs b/frontend/src/app/main/data/workspace/drawing/curve.cljs index d60cc040c..fe036657e 100644 --- a/frontend/src/app/main/data/workspace/drawing/curve.cljs +++ b/frontend/src/app/main/data/workspace/drawing/curve.cljs @@ -47,7 +47,7 @@ (let [objects (wsh/lookup-page-objects state) content (get-in state [:workspace-drawing :object :content] []) position (get-in content [0 :params] nil) - frame-id (cph/frame-id-by-position objects position)] + frame-id (cph/top-nested-frame objects position)] (-> state (assoc-in [:workspace-drawing :object :frame-id] frame-id)))))) diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index a1e50c89f..0282148fb 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -146,7 +146,7 @@ objects (:objects page) unames (volatile! (un/retrieve-used-names objects)) - frame-id (cph/frame-id-by-position objects (gpt/add orig-pos delta)) + frame-id (cph/top-nested-frame objects (gpt/add orig-pos delta)) update-new-shape (fn [new-shape original-shape] diff --git a/frontend/src/app/main/data/workspace/path/drawing.cljs b/frontend/src/app/main/data/workspace/path/drawing.cljs index ff61c094a..3d1943413 100644 --- a/frontend/src/app/main/data/workspace/path/drawing.cljs +++ b/frontend/src/app/main/data/workspace/path/drawing.cljs @@ -258,7 +258,7 @@ (let [objects (wsh/lookup-page-objects state) content (get-in state [:workspace-drawing :object :content] []) position (get-in content [0 :params] nil) - frame-id (cph/frame-id-by-position objects position)] + frame-id (cph/top-nested-frame objects position)] (-> state (assoc-in [:workspace-drawing :object :frame-id] frame-id)))))) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index a072e3023..39cb1569f 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -35,7 +35,7 @@ ;; Calculate the frame over which we're drawing (let [position @ms/mouse-position - frame-id (:frame-id attrs (cph/frame-id-by-position objects position)) + frame-id (:frame-id attrs (cph/top-nested-frame objects position)) shape (when-not (empty? selected) (cph/get-base-shape objects selected))] @@ -252,7 +252,6 @@ (ptk/reify ::create-and-add-shape ptk/WatchEvent (watch [_ state _] - (prn ">>>create-") (let [{:keys [width height]} data [vbc-x vbc-y] (viewport-center state) @@ -260,7 +259,7 @@ y (:y data (- vbc-y (/ height 2))) page-id (:current-page-id state) frame-id (-> (wsh/lookup-page-objects state page-id) - (cph/frame-id-by-position {:x frame-x :y frame-y})) + (cph/top-nested-frame {:x frame-x :y frame-y})) shape (-> (cp/make-minimal-shape type) (merge data) (merge {:x x :y y}) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 3c830bd59..528abce80 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -437,7 +437,7 @@ (try (let [page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) - frame-id (cph/frame-id-by-position objects position) + frame-id (cph/top-nested-frame objects position) selected (wsh/lookup-selected state) [vb-x vb-y vb-width vb-height] (svg-dimensions svg-data) diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 6595caf87..cb2e2f082 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -864,7 +864,7 @@ (let [position @ms/mouse-position page-id (:current-page-id state) objects (wsh/lookup-page-objects state page-id) - frame-id (cph/frame-id-by-position objects position) + frame-id (cph/top-nested-frame objects position) moving-shapes (->> ids @@ -878,15 +878,17 @@ changes (-> (pcb/empty-changes it page-id) (pcb/with-objects objects) - (pcb/update-shapes moving-frames (fn [shape] - ;; Hide in viwer must be enabled just when a board is moved inside another artboard an nested to it, we have to avoid situations like: - ;; - Moving inside the same frame - ;; - Moving outside the frame - (cond-> shape - (and (not= frame-id (:id shape)) - (not= frame-id (:frame-id shape)) - (not= frame-id uuid/zero)) - (assoc :hide-in-viewer true)))) + (pcb/update-shapes + moving-frames + (fn [shape] + ;; Hide in viwer must be enabled just when a board is moved inside another artboard an nested to it, we have to avoid situations like: + ;; - Moving inside the same frame + ;; - Moving outside the frame + (cond-> shape + (and (not= frame-id (:id shape)) + (not= frame-id (:frame-id shape)) + (not= frame-id uuid/zero)) + (assoc :hide-in-viewer true)))) (pcb/change-parent frame-id moving-shapes))] (when-not (empty? changes)