mirror of
https://github.com/penpot/penpot.git
synced 2025-05-22 01:26:11 +02:00
Merge pull request #3678 from penpot/alotor-codegen-fixes
Codegen & grid fixes
This commit is contained in:
commit
828082ea47
13 changed files with 379 additions and 329 deletions
|
@ -205,3 +205,6 @@
|
|||
|
||||
;; Modifiers
|
||||
(dm/export gsm/set-objects-modifiers)
|
||||
|
||||
;; Rect
|
||||
(dm/export grc/rect->points)
|
||||
|
|
|
@ -107,9 +107,7 @@
|
|||
margin
|
||||
(if ignore-margin?
|
||||
0
|
||||
(->> strokes
|
||||
(map #(shape-stroke-margin % stroke-width))
|
||||
(reduce d/max 0)))
|
||||
(shape-stroke-margin shape stroke-width))
|
||||
|
||||
shadow-width
|
||||
(->> (:shadow shape)
|
||||
|
@ -125,8 +123,8 @@
|
|||
0))
|
||||
(reduce d/max 0))]
|
||||
|
||||
{:horizontal (+ stroke-width margin shadow-width)
|
||||
:vertical (+ stroke-width margin shadow-height)})))
|
||||
{:horizontal (mth/ceil (+ stroke-width margin shadow-width))
|
||||
:vertical (mth/ceil (+ stroke-width margin shadow-height))})))
|
||||
|
||||
(defn- add-padding
|
||||
[bounds padding]
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
[app.common.types.components-list :as ctkl]
|
||||
[app.common.types.pages-list :as ctpl]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -265,7 +266,7 @@
|
|||
(gpt/add orig-pos delta)
|
||||
{:skip-components? true
|
||||
:bottom-frames? true}))
|
||||
frame-ids-map (volatile! {})
|
||||
ids-map (volatile! {})
|
||||
|
||||
update-new-shape
|
||||
(fn [new-shape original-shape]
|
||||
|
@ -275,8 +276,7 @@
|
|||
(when (nil? (:parent-id original-shape))
|
||||
(vswap! unames conj new-name))
|
||||
|
||||
(when (= (:type original-shape) :frame)
|
||||
(vswap! frame-ids-map assoc (:id original-shape) (:id new-shape)))
|
||||
(vswap! ids-map assoc (:id original-shape) (:id new-shape))
|
||||
|
||||
(cond-> new-shape
|
||||
:always
|
||||
|
@ -307,7 +307,8 @@
|
|||
(dissoc :component-root))))
|
||||
|
||||
[new-shape new-shapes _]
|
||||
(ctst/clone-object component-shape
|
||||
(ctst/clone-object
|
||||
component-shape
|
||||
nil
|
||||
(if components-v2 (:objects component-page) (:objects component))
|
||||
update-new-shape
|
||||
|
@ -318,13 +319,17 @@
|
|||
;; If frame-id points to a shape inside the component, remap it to the
|
||||
;; corresponding new frame shape. If not, set it to the destination frame.
|
||||
;; Also fix empty parent-id.
|
||||
remap-frame-id (fn [shape]
|
||||
remap-ids
|
||||
(fn [shape]
|
||||
(as-> shape $
|
||||
(update $ :frame-id #(get @frame-ids-map % frame-id))
|
||||
(update $ :parent-id #(or % (:frame-id $)))))]
|
||||
(update $ :frame-id #(get @ids-map % frame-id))
|
||||
(update $ :parent-id #(or % (:frame-id $)))
|
||||
(cond-> $
|
||||
(ctl/grid-layout? shape)
|
||||
(ctl/remap-grid-cells @ids-map))))]
|
||||
|
||||
[(remap-frame-id new-shape)
|
||||
(map remap-frame-id new-shapes)])))
|
||||
[(remap-ids new-shape)
|
||||
(map remap-ids new-shapes)])))
|
||||
|
||||
(defn get-top-instance
|
||||
"The case of having an instance that contains another instances.
|
||||
|
|
|
@ -1177,3 +1177,15 @@
|
|||
(for [r (range first-row (inc last-row))
|
||||
c (range first-column (inc last-column))]
|
||||
[r c]))))
|
||||
|
||||
(defn remap-grid-cells
|
||||
"Remaps the shapes inside the cells"
|
||||
[shape ids-map]
|
||||
(let [do-remap-cells
|
||||
(fn [cell]
|
||||
(-> cell
|
||||
(update :shapes #(mapv ids-map %))))
|
||||
shape
|
||||
(-> shape
|
||||
(update :layout-grid-cells update-vals do-remap-cells))]
|
||||
shape))
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(ns common-tests.types-shape-interactions-test
|
||||
(:require
|
||||
[app.common.math :as mth]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.rect :as grc]
|
||||
|
@ -332,56 +333,56 @@
|
|||
(t/testing "Overlay top-center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 0))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 0))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :top-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 70))
|
||||
(t/is (= (:y overlay-pos) 0))
|
||||
(t/is (mth/close? (:x overlay-pos) 70))
|
||||
(t/is (mth/close? (:y overlay-pos) 0))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 0))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (mth/close? (:x overlay-pos) 0))
|
||||
(t/is (mth/close? (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :bottom-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 70))
|
||||
(t/is (= (:y overlay-pos) 80))
|
||||
(t/is (mth/close? (:x overlay-pos) 70))
|
||||
(t/is (mth/close? (:y overlay-pos) 80))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 40))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 40))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay manual relative to auto"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-auto :center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 40))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 40))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
|
@ -390,64 +391,64 @@
|
|||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (mth/close? (:x overlay-pos) 17))
|
||||
(t/is (mth/close? (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 5))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (mth/close? (:x overlay-pos) 5))
|
||||
(t/is (mth/close? (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (mth/close? (:x overlay-pos) 40))
|
||||
(t/is (mth/close? (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :top-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 75))
|
||||
(t/is (= (:y overlay-pos) 5))
|
||||
(t/is (mth/close? (:x overlay-pos) 75))
|
||||
(t/is (mth/close? (:y overlay-pos) 5))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 5))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (mth/close? (:x overlay-pos) 5))
|
||||
(t/is (mth/close? (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (mth/close? (:x overlay-pos) 40))
|
||||
(t/is (mth/close? (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :bottom-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 75))
|
||||
(t/is (= (:y overlay-pos) 85))
|
||||
(t/is (mth/close? (:x overlay-pos) 75))
|
||||
(t/is (mth/close? (:y overlay-pos) 85))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to base-frame"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-base-frame :center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 40))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 40))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
|
@ -456,64 +457,64 @@
|
|||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects base-frame base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (mth/close? (:x overlay-pos) 17))
|
||||
(t/is (mth/close? (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 15))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 15))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :bottom-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 30))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 30))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
|
@ -522,64 +523,64 @@
|
|||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 27))
|
||||
(t/is (= (:y overlay-pos) 77))
|
||||
(t/is (mth/close? (:x overlay-pos) 27))
|
||||
(t/is (mth/close? (:y overlay-pos) 77))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-left relative to popup"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-popup :top-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects popup base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 15))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay top-center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay top-right relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :top-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 15))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 15))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay bottom-left relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-left base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 15))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 15))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :left))))
|
||||
|
||||
(t/testing "Overlay bottom-center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
(t/testing "Overlay bottom-right relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :bottom-right base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 35))
|
||||
(t/is (= (:y overlay-pos) 45))
|
||||
(t/is (mth/close? (:x overlay-pos) 35))
|
||||
(t/is (mth/close? (:y overlay-pos) 45))
|
||||
(t/is (= snap-v :bottom))
|
||||
(t/is (= snap-h :right))))
|
||||
|
||||
(t/testing "Overlay center relative to rect"
|
||||
(let [i2 (ctsi/set-overlay-pos-type interaction-rect :center base-frame objects)
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 25))
|
||||
(t/is (= (:y overlay-pos) 30))
|
||||
(t/is (mth/close? (:x overlay-pos) 25))
|
||||
(t/is (mth/close? (:y overlay-pos) 30))
|
||||
(t/is (= snap-v :center))
|
||||
(t/is (= snap-h :center))))
|
||||
|
||||
|
@ -588,8 +589,8 @@
|
|||
(ctsi/set-overlay-pos-type :manual base-frame objects)
|
||||
(ctsi/set-overlay-position (gpt/point 12 62)))
|
||||
[overlay-pos [snap-v snap-h]] (ctsi/calc-overlay-position i2 rect objects rect base-frame overlay-frame frame-offset)]
|
||||
(t/is (= (:x overlay-pos) 17))
|
||||
(t/is (= (:y overlay-pos) 67))
|
||||
(t/is (mth/close? (:x overlay-pos) 17))
|
||||
(t/is (mth/close? (:y overlay-pos) 67))
|
||||
(t/is (= snap-v :top))
|
||||
(t/is (= snap-h :left))))))
|
||||
|
||||
|
|
|
@ -330,17 +330,6 @@
|
|||
(when selected
|
||||
(rx/of (select-shape (:id selected))))))))
|
||||
|
||||
(defn remap-grid-cells
|
||||
"Remaps the shapes inside the cells"
|
||||
[shape ids-map]
|
||||
|
||||
(let [do-remap-cells
|
||||
(fn [cell]
|
||||
(-> cell
|
||||
(update :shapes #(mapv ids-map %))))]
|
||||
|
||||
(update shape :layout-grid-cells update-vals do-remap-cells)))
|
||||
|
||||
;; --- Duplicate Shapes
|
||||
(declare prepare-duplicate-shape-change)
|
||||
(declare prepare-duplicate-flows)
|
||||
|
@ -463,8 +452,7 @@
|
|||
(d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))
|
||||
|
||||
(cond-> (ctl/grid-layout? obj)
|
||||
(-> (ctl/check-deassigned-cells)
|
||||
(remap-grid-cells ids-map))))
|
||||
(ctl/remap-grid-cells ids-map)))
|
||||
|
||||
new-obj (cond-> new-obj
|
||||
(not duplicating-component?)
|
||||
|
@ -474,7 +462,7 @@
|
|||
changes (-> (pcb/add-object changes new-obj {:ignore-touched (and duplicating-component? child?)})
|
||||
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] ctl/assign-cells)
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] (fn [shape] (-> shape ctl/assign-cells ctl/check-deassigned-cells)))
|
||||
(pcb/reorder-grid-children [(:parent-id obj)]))))
|
||||
|
||||
changes (cond-> changes
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
handle-load
|
||||
(mf/use-callback
|
||||
(fn [data width height]
|
||||
(prn "handle-load" data)
|
||||
(reset! last-data* data)
|
||||
(let [iframe-dom (mf/ref-val iframe-ref)]
|
||||
(when iframe-dom
|
||||
(-> iframe-dom (aset "width" width))
|
||||
(-> iframe-dom (aset "height" height))
|
||||
(-> iframe-dom (aset "width" (+ width 64)))
|
||||
(-> iframe-dom (aset "height" (+ height 64)))
|
||||
(-> iframe-dom .-contentWindow .-document .open)
|
||||
(-> iframe-dom .-contentWindow .-document (.write data))
|
||||
(-> iframe-dom .-contentWindow .-document .close)))))
|
||||
|
@ -59,13 +58,13 @@
|
|||
[:div {:style {:display "flex" :width "100%" :height "100%" :flex-direction "column" :overflow "auto" :align-items "center"}}
|
||||
[:input {:id "zoom-input"
|
||||
:ref zoom-ref
|
||||
:type "range" :min 1 :max 200 :default-value 100
|
||||
:type "range" :min 1 :max 400 :default-value 100
|
||||
:on-change change-zoom
|
||||
:style {:max-width "500px"}}]
|
||||
|
||||
[:div {:style {:width "100%" :height "100%" :overflow "auto"}}
|
||||
[:iframe {:ref load-ref
|
||||
:frameborder "0"
|
||||
:frame-border "0"
|
||||
:scrolling "no"
|
||||
:style {:transform-origin "top center"
|
||||
:style {:transform-origin "top left"
|
||||
:transform (str "scale(" zoom ")")}}]]]))
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def small-size-limit 60)
|
||||
(def medium-size-limit 110)
|
||||
|
||||
(defn apply-to-point [result next-fn]
|
||||
(conj result (next-fn (last result))))
|
||||
|
||||
|
@ -630,6 +633,10 @@
|
|||
[(:x text-p) (- (:y text-p) (/ 36 zoom)) (max 0 (:size track-data)) (/ 36 zoom)]
|
||||
[(- (:x text-p) (max 0 (:size track-data))) (- (:y text-p) (/ 36 zoom)) (max 0 (:size track-data)) (/ 36 zoom)])
|
||||
|
||||
trackwidth (* text-width zoom)
|
||||
medium? (and (>= trackwidth small-size-limit) (< trackwidth medium-size-limit))
|
||||
small? (< trackwidth small-size-limit)
|
||||
|
||||
track-before (get-in layout-data [track-list-prop (dec index)])]
|
||||
|
||||
(mf/use-effect
|
||||
|
@ -644,14 +651,15 @@
|
|||
(dm/str (gmt/transform-in text-p (:transform shape)))
|
||||
(dm/str (gmt/transform-in text-p (gmt/rotate (:transform shape) -90))))}
|
||||
|
||||
(when hovering?
|
||||
[:rect {:x (+ text-x (/ 5 zoom))
|
||||
(when (and hovering? (not small?))
|
||||
[:rect {:x (+ text-x (/ 18 zoom))
|
||||
:y text-y
|
||||
:width (- text-width (/ 10 zoom))
|
||||
:width (- text-width (/ 36 zoom))
|
||||
:height (- text-height (/ 5 zoom))
|
||||
:rx (/ 3 zoom)
|
||||
:fill "var(--color-distance)"
|
||||
:opacity 0.2}])
|
||||
(when (not small?)
|
||||
[:foreignObject {:x text-x :y text-y :width text-width :height text-height}
|
||||
[:div {:class (css :grid-editor-wrapper)}
|
||||
[:input
|
||||
|
@ -663,9 +671,9 @@
|
|||
:data-default-value (format-size track-data)
|
||||
:on-key-down handle-keydown-track-input
|
||||
:on-blur handle-blur-track-input}]
|
||||
(when hovering?
|
||||
(when (and hovering? (not medium?) (not small?))
|
||||
[:button {:class (css :grid-editor-button)
|
||||
:on-click handle-remove-track} i/trash])]]]
|
||||
:on-click handle-remove-track} i/trash])]])]
|
||||
|
||||
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
|
||||
[:& track-marker
|
||||
|
@ -782,6 +790,7 @@
|
|||
(fn []
|
||||
#(st/emit! (dwge/stop-grid-layout-editing (:id shape)))))
|
||||
|
||||
(when (and (not (:hidden shape)) (not (:blocked shape)))
|
||||
[:g.grid-editor {:pointer-events (when view-only "none")
|
||||
:on-pointer-down handle-pointer-down}
|
||||
[:g.cells
|
||||
|
@ -884,4 +893,4 @@
|
|||
:type :row
|
||||
:track-before (last row-tracks)
|
||||
:snap-pixel? snap-pixel?
|
||||
:zoom zoom}]]))])]))
|
||||
:zoom zoom}]]))])])))
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: calc(10px / var(--zoom));
|
||||
right: calc(20px / var(--zoom));
|
||||
width: calc(20px / var(--zoom));
|
||||
height: calc(20px / var(--zoom));
|
||||
|
||||
|
@ -80,12 +80,12 @@
|
|||
.grid-cell-outline {
|
||||
fill: transparent;
|
||||
stroke: var(--color-distance);
|
||||
stroke-linecap: round;
|
||||
stroke-width: calc(2 / var(--zoom));
|
||||
stroke-dasharray: 0 calc(8 / var(--zoom));
|
||||
stroke-opacity: 0.5;
|
||||
stroke-width: calc(1 / var(--zoom));
|
||||
|
||||
&.hover,
|
||||
&.selected {
|
||||
stroke-dasharray: initial;
|
||||
stroke-opacity: 1;
|
||||
stroke-width: calc(2 / var(--zoom));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,5 +58,6 @@
|
|||
[objects shape]
|
||||
;; Layout children with a transform should be wrapped
|
||||
(and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (ctl/layout-absolute? shape))
|
||||
(not (gmt/unit? (:transform shape)))))
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
(generate-html objects shape 0))
|
||||
|
||||
([objects shape level]
|
||||
(when (and (some? shape) (some? (:selrect shape)))
|
||||
(let [indent (str/repeat " " level)
|
||||
maybe-reverse (if (ctl/any-layout? shape) reverse identity)
|
||||
|
||||
|
@ -81,10 +82,10 @@
|
|||
shape-html)
|
||||
|
||||
shape-html)]
|
||||
(dm/fmt "%<!-- % -->\n%" indent (dm/str (d/name (:type shape)) ": " (:name shape)) shape-html))))
|
||||
(dm/fmt "%<!-- % -->\n%" indent (dm/str (d/name (:type shape)) ": " (:name shape)) shape-html)))))
|
||||
|
||||
(defn generate-markup
|
||||
[objects shapes]
|
||||
(->> shapes
|
||||
(map #(generate-html objects %))
|
||||
(keep #(generate-html objects %))
|
||||
(str/join "\n")))
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.bounds :as gsb]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.text :as txt]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
|
@ -38,13 +39,6 @@ body {
|
|||
gap: 2rem;
|
||||
}
|
||||
|
||||
svg {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
@ -64,7 +58,10 @@ svg {
|
|||
:justify-self
|
||||
:grid-column
|
||||
:grid-row
|
||||
:z-index})
|
||||
:z-index
|
||||
:top
|
||||
:left
|
||||
:position})
|
||||
|
||||
(def shape-css-properties
|
||||
[:position
|
||||
|
@ -139,12 +136,16 @@ svg {
|
|||
[shape objects]
|
||||
(when (and (ctl/any-layout-immediate-child? objects shape)
|
||||
(not (gmt/unit? (:transform shape))))
|
||||
(let [{:keys [width height]} (gsh/shapes->rect [shape])]
|
||||
(cond-> [[:position "relative"]
|
||||
[:width width]
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
bounds (gpo/parent-coords-bounds (:points shape) (:points parent))
|
||||
width (gpo/width-points bounds)
|
||||
height (gpo/height-points bounds)]
|
||||
(cond-> [[:width width]
|
||||
[:height height]]
|
||||
(ctl/flex-layout-immediate-child? objects shape)
|
||||
(conj [:flex-shrink 0])))))
|
||||
|
||||
(or (not (ctl/any-layout-immediate-child? objects shape))
|
||||
(not (ctl/layout-absolute? shape)))
|
||||
(conj [:position "relative"])))))
|
||||
|
||||
(defn shape->wrapper-child-css-properties
|
||||
[shape objects]
|
||||
|
@ -153,6 +154,16 @@ svg {
|
|||
[:left "50%"]
|
||||
[:top "50%"]]))
|
||||
|
||||
(defn shape->svg-props
|
||||
[shape objects]
|
||||
(let [bounds (gsb/get-object-bounds objects shape)]
|
||||
[[:position "absolute"]
|
||||
[:top 0]
|
||||
[:left 0]
|
||||
[:transform (dm/fmt "translate(%,%)"
|
||||
(dm/str (- (:x bounds) (-> shape :selrect :x)) "px")
|
||||
(dm/str (- (:y bounds) (-> shape :selrect :y)) "px"))]]))
|
||||
|
||||
(defn shape->css-properties
|
||||
"Given a shape extract the CSS properties in the format of list [property value]"
|
||||
[shape objects properties]
|
||||
|
@ -235,9 +246,11 @@ svg {
|
|||
(get-shape-css-selector shape objects nil))
|
||||
|
||||
([shape objects options]
|
||||
(when (and (some? shape) (some? (:selrect shape)))
|
||||
(let [selector (cgc/shape->selector shape)
|
||||
|
||||
wrapper? (cgc/has-wrapper? objects shape)
|
||||
svg? (cgc/svg-markup? shape)
|
||||
|
||||
css-properties
|
||||
(if wrapper?
|
||||
|
@ -260,6 +273,12 @@ svg {
|
|||
(when wrapper?
|
||||
(-> shape
|
||||
(shape->wrapper-child-css-properties objects)
|
||||
(format-css-properties options)))
|
||||
|
||||
svg-child-props
|
||||
(when svg?
|
||||
(-> shape
|
||||
(shape->svg-props objects)
|
||||
(format-css-properties options)))]
|
||||
|
||||
(str/join
|
||||
|
@ -267,8 +286,9 @@ svg {
|
|||
(filter some? [(str/fmt "/* %s */" (:name shape))
|
||||
(when wrapper? (str/fmt ".%s-wrapper {\n%s\n}" selector wrapper-properties))
|
||||
(when wrapper? (str/fmt ".%s-wrapper > * {\n%s\n}" selector wrapper-child-properties))
|
||||
(when svg? (str/fmt ".%s > svg {\n%s\n}" selector svg-child-props))
|
||||
(str/fmt ".%s {\n%s\n}" selector properties)
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))])))))
|
||||
(when (cph/text-shape? shape) (generate-text-css shape))]))))))
|
||||
|
||||
(defn get-css-property
|
||||
([objects shape property]
|
||||
|
@ -294,5 +314,5 @@ svg {
|
|||
(dm/str
|
||||
prelude
|
||||
(->> shapes
|
||||
(map #(get-shape-css-selector % objects options))
|
||||
(keep #(get-shape-css-selector % objects options))
|
||||
(str/join "\n\n")))))
|
||||
|
|
|
@ -49,12 +49,14 @@
|
|||
(when (and (not (cph/root-frame? shape))
|
||||
(or (not (ctl/any-layout-immediate-child? objects shape))
|
||||
(ctl/layout-absolute? shape)))
|
||||
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
|
||||
parent-value (dm/get-in parent [:selrect coord])
|
||||
|
||||
[selrect _ _]
|
||||
(-> (:points shape)
|
||||
(gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent))
|
||||
(gsh/transform-points (gsh/shape->center parent) (:transform-inverse parent (gmt/matrix)))
|
||||
(gsh/calculate-geometry))
|
||||
|
||||
shape-value (get selrect coord)]
|
||||
|
@ -117,7 +119,17 @@
|
|||
|
||||
(defmethod get-value :transform
|
||||
[_ shape objects]
|
||||
(when-not (cgc/svg-markup? shape)
|
||||
(if (cgc/svg-markup? shape)
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
transform
|
||||
(:transform-inverse parent (gmt/matrix))
|
||||
|
||||
transform-str (when-not (gmt/unit? transform) (fmt/format-matrix transform))]
|
||||
|
||||
(if (cgc/has-wrapper? objects shape)
|
||||
(dm/str "translate(-50%, -50%) " (d/nilv transform-str ""))
|
||||
transform-str))
|
||||
|
||||
(let [parent (get objects (:parent-id shape))
|
||||
|
||||
transform
|
||||
|
@ -207,6 +219,7 @@
|
|||
(defmethod get-value :overflow
|
||||
[_ shape _]
|
||||
(when (and (cph/frame-shape? shape)
|
||||
(not (cgc/svg-markup? shape))
|
||||
(not (:show-content shape)))
|
||||
"hidden"))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue