mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Place children after carrying variant geometry overrides
A switch can retain the copy root's resized geometry while leaving its untouched children in the old frame. After geometry carry, sync the new subtree from the updated builder objects so constraints place its children without adding overrides. Reuse the direct component sync entry point. The portable rotated-root regression fails before the fix with a 30px child offset. Swap and variant suites pass 108 tests / 539 assertions; the pure golden master matches 1149 assertions unchanged. Full frontend: 1517 tests / 8436 assertions. Live ws1 WASM retains the resized root and child placement, with no exception or pending reflow. Benchmark ratios: main 10/100/1000 copies 0.48/0.56/0.57; three levels 0.49; chain 0.48; library 0.50; many shapes 0.45; variant switch 0.61. No slowdown flags. AI-assisted-by: GPT-6
This commit is contained in:
parent
8a2c2b7246
commit
955650c618
@ -48,3 +48,8 @@ The clean target already has the copy's rotation, which can turn 100 into
|
||||
99.99999999999994. Exact dimension equality drops valid resize overrides
|
||||
(F160). Fixed layout sizes and composite geometry use the same tolerance;
|
||||
nongeometry scalar attributes still compare exactly.
|
||||
|
||||
After carrying geometry, the switch syncs its new subtree once from the
|
||||
updated builder objects. Untouched children must follow a retained root
|
||||
size through constraints; copying only root attrs leaves them in the old
|
||||
frame (F162). The direct sync keeps carried groups and child swaps.
|
||||
|
||||
@ -285,7 +285,7 @@
|
||||
(reduce #(update %1 %2 turn) objects
|
||||
(cfh/get-children-ids-with-self objects (:id shape-main)))))))))
|
||||
|
||||
(defn- generate-sync-shape-direct
|
||||
(defn generate-sync-shape-direct
|
||||
"Generate changes to synchronize one shape that is the root of a component
|
||||
instance, and all its children, from the given component."
|
||||
[changes file libraries container shape-id reset?]
|
||||
|
||||
@ -430,7 +430,14 @@
|
||||
(ctk/touched-group? % :geometry-group)) orig-touched)
|
||||
(keep-orientation-override original-shape new-shape page
|
||||
(or (get-in libraries [(:component-file new-shape) :data]) ldata)
|
||||
(:component-id new-shape) nil))]
|
||||
(:component-id new-shape) nil))
|
||||
;; A carried size changes the frame its untouched children follow.
|
||||
;; Place them through the same constraints as an ordinary copy sync.
|
||||
changes (cond-> changes
|
||||
(some #(ctk/touched-group? % :geometry-group) orig-touched)
|
||||
(cll/generate-sync-shape-direct
|
||||
nil libraries (assoc container :objects (pcb/get-objects changes))
|
||||
(:id new-shape) false))]
|
||||
[changes (mapv (comp :parent-id :new) pairs)]))
|
||||
|
||||
(defn- shape-index
|
||||
|
||||
@ -49,6 +49,34 @@
|
||||
(t/is (mth/close? 80 (get-in copy [:selrect :height]) 1e-10))
|
||||
(t/is (contains? (:touched copy) :geometry-group)))))
|
||||
|
||||
(t/deftest switch-places-children-through-a-carried-root-resize
|
||||
(doseq [angle [0 45]]
|
||||
(let [root-params {:width 100 :height 100}
|
||||
child-params {:x 10 :y 10 :width 20 :height 20
|
||||
:constraints-h :left :constraints-v :top}
|
||||
file (-> (thf/sample-file :file1)
|
||||
(thv/add-variant-with-child
|
||||
:v01 :c01 :m01 :c02 :m02 :r01 :r02
|
||||
{:variant1-params root-params :variant2-params root-params
|
||||
:child1-params child-params :child2-params child-params})
|
||||
(thc/instantiate-component :c01 :copy01))
|
||||
file (reduce (fn [file modifiers]
|
||||
(let [shape (ths/get-shape file :copy01)]
|
||||
(thf/apply-changes file
|
||||
(n/transform-changes (thf/current-page file) shape
|
||||
(modifiers shape)))))
|
||||
file [#(ctm/rotation-modifiers % (gsh/shape->center %) angle)
|
||||
#(ctm/change-size % nil 80)])
|
||||
switched (tho/swap-component-in-shape file :copy01 :c02 {:keep-touched? true})
|
||||
relative (fn [file]
|
||||
(let [root (ths/get-shape file :copy01)
|
||||
child (get-in (thf/current-page file) [:objects (first (:shapes root))])]
|
||||
(gpt/subtract (first (:points child)) (first (:points root)))))
|
||||
child (get-in (thf/current-page switched)
|
||||
[:objects (first (:shapes (ths/get-shape switched :copy01)))])]
|
||||
(t/is (< (gpt/distance (relative file) (relative switched)) 0.01))
|
||||
(t/is (empty? (:touched child))))))
|
||||
|
||||
;; ============================================================
|
||||
;; BASIC SWITCH TESTS (no overrides)
|
||||
;; ============================================================
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user