0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-17 18:21:23 -05:00

Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2023-01-20 09:59:56 +01:00
commit 62aa6569f2
57 changed files with 896 additions and 677 deletions

View file

@ -57,6 +57,8 @@
- Fix max height in library dialog [Github #2335](https://github.com/penpot/penpot/issues/2335)
- Fix undo ungroup (shift+g) scrambles positions [Taiga #4674](https://tree.taiga.io/project/penpot/issue/4674)
- Fix justified text is stretched [Github #2539](https://github.com/penpot/penpot/issues/2539)
- Fix mousewheel on viewer inspector [Taiga #4221](https://tree.taiga.io/project/penpot/issue/4221)
- Fix path edition activated on boards [Taiga #4105](https://tree.taiga.io/project/penpot/issue/4105)
## 1.16.2-beta

View file

@ -45,10 +45,10 @@
(def default-features
(cond-> #{}
(contains? cf/flags :feature-storage-pointer-map)
(contains? cf/flags :fdata-storage-pointer-map)
(conj "storage/pointer-map")
(contains? cf/flags :feature-storage-objects-map)
(contains? cf/flags :fdata-storage-objects-map)
(conj "storage/objects-map")))
;; --- SPECS

View file

@ -29,7 +29,7 @@
:email email
:fullname fullname
:is-active true
:password (derive-password password)
:password password
:props {}}
profile (->> (cmd.auth/create-profile! conn params)
(cmd.auth/create-profile-rels! conn))]

View file

@ -60,7 +60,7 @@
(point v v)
(point-like? v)
(map->Point v)
(Point. (:x v) (:y v))
:else
(ex/raise :hint "invalid arguments (on pointer constructor)" :value v)))
@ -274,12 +274,12 @@
(Point. (mth/precision (dm/get-prop pt :x) decimals)
(mth/precision (dm/get-prop pt :y) decimals))))
(defn half-round
(defn round-step
"Round the coordinates to the closest half-point"
[pt]
[pt step]
(assert (point? pt) "expected point instance")
(Point. (mth/half-round (dm/get-prop pt :x))
(mth/half-round (dm/get-prop pt :y))))
(Point. (mth/round (dm/get-prop pt :x) step)
(mth/round (dm/get-prop pt :y) step)))
(defn transform
"Transform a point applying a matrix transformation."

View file

@ -359,7 +359,7 @@
to-reflow
(cond-> to-reflow
(and (ctl/layout-child-id? objects current)
(and (ctl/layout-descent? objects parent-base)
(not= uuid/zero (:frame-id parent-base)))
(conj (:frame-id parent-base)))]
(recur modif-tree
@ -382,15 +382,24 @@
result))
(defn set-objects-modifiers
([modif-tree objects ignore-constraints snap-pixel?]
(set-objects-modifiers nil modif-tree objects ignore-constraints snap-pixel?))
([modif-tree objects]
(set-objects-modifiers modif-tree objects nil))
([old-modif-tree modif-tree objects ignore-constraints snap-pixel?]
([modif-tree objects params]
(set-objects-modifiers nil modif-tree objects params))
([old-modif-tree modif-tree objects
{:keys [ignore-constraints snap-pixel? snap-precision snap-ignore-axis]
:or {ignore-constraints false snap-pixel? false snap-precision 1 snap-ignore-axis nil}}]
(let [objects (-> objects
(cond-> (some? old-modif-tree)
(apply-structure-modifiers old-modif-tree))
(apply-structure-modifiers modif-tree))
modif-tree
(cond-> modif-tree
snap-pixel? (gpp/adjust-pixel-precision objects snap-precision snap-ignore-axis))
bounds (d/lazy-map (keys objects) #(dm/get-in objects [% :points]))
bounds (cond-> bounds
(some? old-modif-tree)
@ -417,11 +426,7 @@
modif-tree
(if old-modif-tree
(merge-modif-tree old-modif-tree modif-tree)
modif-tree)
modif-tree
(cond-> modif-tree
snap-pixel? (gpp/adjust-pixel-precision objects))]
modif-tree)]
;;#?(:cljs
;; (.log js/console ">result" (modif->js modif-tree objects)))

View file

@ -18,7 +18,7 @@
[app.common.types.modifiers :as ctm]))
(defn size-pixel-precision
[modifiers shape points]
[modifiers shape points precision]
(let [origin (gpo/origin points)
curr-width (gpo/width-points points)
curr-height (gpo/height-points points)
@ -29,8 +29,8 @@
vertical-line? (and path? (<= curr-width 0.01))
horizontal-line? (and path? (<= curr-height 0.01))
target-width (if vertical-line? curr-width (max 1 (mth/round curr-width)))
target-height (if horizontal-line? curr-height (max 1 (mth/round curr-height)))
target-width (if vertical-line? curr-width (max 1 (mth/round curr-width precision)))
target-height (if horizontal-line? curr-height (max 1 (mth/round curr-height precision)))
ratio-width (/ target-width curr-width)
ratio-height (/ target-height curr-height)
@ -39,23 +39,32 @@
(ctm/resize scalev origin transform transform-inverse {:precise? true}))))
(defn position-pixel-precision
[modifiers _ points]
[modifiers _ points precision ignore-axis]
(let [bounds (gpr/bounds->rect points)
corner (gpt/point bounds)
target-corner (gpt/round corner)
target-corner
(cond-> corner
(= ignore-axis :x)
(update :y mth/round precision)
(= ignore-axis :y)
(update :x mth/round precision)
(nil? ignore-axis)
(gpt/round-step precision))
deltav (gpt/to-vec corner target-corner)]
(ctm/move modifiers deltav)))
(defn set-pixel-precision
"Adjust modifiers so they adjust to the pixel grid"
[modifiers shape]
[modifiers shape precision ignore-axis]
(let [points (-> shape :points (gco/transform-points (ctm/modifiers->transform modifiers)))
has-resize? (not (ctm/only-move? modifiers))
[modifiers points]
(let [modifiers
(cond-> modifiers
has-resize? (size-pixel-precision shape points))
has-resize? (size-pixel-precision shape points precision))
points
(if has-resize?
@ -63,16 +72,16 @@
(gco/transform-points (ctm/modifiers->transform modifiers)) )
points)]
[modifiers points])]
(position-pixel-precision modifiers shape points)))
(position-pixel-precision modifiers shape points precision ignore-axis)))
(defn adjust-pixel-precision
[modif-tree objects]
[modif-tree objects precision ignore-axis]
(let [update-modifiers
(fn [modif-tree shape]
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
(cond-> modif-tree
(ctm/has-geometry? modifiers)
(update-in [(:id shape) :modifiers] set-pixel-precision shape))))]
(update-in [(:id shape) :modifiers] set-pixel-precision shape precision ignore-axis))))]
(->> (keys modif-tree)
(map (d/getf objects))

View file

@ -238,7 +238,15 @@
points-transform-mtx
(gmt/translate-matrix center)))
transform-inverse (when transform (gmt/inverse transform))]
transform-inverse (when transform (gmt/inverse transform))
;; There is a rounding error when the matrix returned have float point values
;; when the matrix is unit we return a "pure" matrix so we don't accumulate
;; rounding problems
[transform transform-inverse]
(if (gmt/unit? transform)
[(gmt/matrix) (gmt/matrix)]
[transform transform-inverse])]
[sr transform transform-inverse]))

View file

@ -104,15 +104,16 @@
(defn round
"Returns the value of a number rounded to
the nearest integer."
[v]
#?(:cljs (js/Math.round v)
:clj (Math/round (float v))))
the nearest integer.
If given step rounds to the next closest step, for example:
(round 13.4 0.5) => 13.5
(round 13.4 0.3) => 13.3"
([v step]
(* (round (/ v step)) step))
(defn half-round
"Returns a value rounded to the next point or half point"
[v]
(/ (round (* v 2)) 2))
([v]
#?(:cljs (js/Math.round v)
:clj (Math/round (float v)))))
(defn ceil
"Returns the smallest integer greater than

View file

@ -265,7 +265,8 @@
(move-objects [objects]
(let [valid? (every? (partial is-valid-move? objects) shapes)
parent (get objects parent-id)
index (if (nil? after-shape) index (inc (d/index-of (:shapes parent) after-shape)))
after-shape-index (d/index-of (:shapes parent) after-shape)
index (if (nil? after-shape-index) index (inc after-shape-index))
frame-id (if (= :frame (:type parent))
(:id parent)
(:frame-id parent))]

View file

@ -19,84 +19,88 @@
;; in the main component, none of the attributes of the same group is changed.
(def component-sync-attrs
{:name :name-group
:fills :fill-group
:fill-color :fill-group
:fill-opacity :fill-group
:fill-color-gradient :fill-group
:fill-color-ref-file :fill-group
:fill-color-ref-id :fill-group
:hide-fill-on-export :fill-group
:content :content-group
:position-data :content-group
:hidden :visibility-group
:blocked :modifiable-group
:grow-type :text-font-group
:font-family :text-font-group
:font-size :text-font-group
:font-style :text-font-group
:font-weight :text-font-group
:letter-spacing :text-display-group
:line-height :text-display-group
:text-align :text-display-group
:strokes :stroke-group
:stroke-color :stroke-group
:stroke-color-gradient :stroke-group
:stroke-color-ref-file :stroke-group
:stroke-color-ref-id :stroke-group
:stroke-opacity :stroke-group
:stroke-style :stroke-group
:stroke-width :stroke-group
:stroke-alignment :stroke-group
:stroke-cap-start :stroke-group
:stroke-cap-end :stroke-group
:rx :radius-group
:ry :radius-group
:r1 :radius-group
:r2 :radius-group
:r3 :radius-group
:r4 :radius-group
:type :geometry-group
:selrect :geometry-group
:points :geometry-group
:locked :geometry-group
:proportion :geometry-group
:proportion-lock :geometry-group
:x :geometry-group
:y :geometry-group
:width :geometry-group
:height :geometry-group
:rotation :geometry-group
:transform :geometry-group
:transform-inverse :geometry-group
:opacity :layer-effects-group
:blend-mode :layer-effects-group
:shadow :shadow-group
:blur :blur-group
:masked-group? :mask-group
:constraints-h :constraints-group
:constraints-v :constraints-group
:fixed-scroll :constraints-group
:exports :exports-group
{:name :name-group
:fills :fill-group
:fill-color :fill-group
:fill-opacity :fill-group
:fill-color-gradient :fill-group
:fill-color-ref-file :fill-group
:fill-color-ref-id :fill-group
:hide-fill-on-export :fill-group
:content :content-group
:position-data :content-group
:hidden :visibility-group
:blocked :modifiable-group
:grow-type :text-font-group
:font-family :text-font-group
:font-size :text-font-group
:font-style :text-font-group
:font-weight :text-font-group
:letter-spacing :text-display-group
:line-height :text-display-group
:text-align :text-display-group
:strokes :stroke-group
:stroke-color :stroke-group
:stroke-color-gradient :stroke-group
:stroke-color-ref-file :stroke-group
:stroke-color-ref-id :stroke-group
:stroke-opacity :stroke-group
:stroke-style :stroke-group
:stroke-width :stroke-group
:stroke-alignment :stroke-group
:stroke-cap-start :stroke-group
:stroke-cap-end :stroke-group
:rx :radius-group
:ry :radius-group
:r1 :radius-group
:r2 :radius-group
:r3 :radius-group
:r4 :radius-group
:type :geometry-group
:selrect :geometry-group
:points :geometry-group
:locked :geometry-group
:proportion :geometry-group
:proportion-lock :geometry-group
:x :geometry-group
:y :geometry-group
:width :geometry-group
:height :geometry-group
:rotation :geometry-group
:transform :geometry-group
:transform-inverse :geometry-group
:opacity :layer-effects-group
:blend-mode :layer-effects-group
:shadow :shadow-group
:blur :blur-group
:masked-group? :mask-group
:constraints-h :constraints-group
:constraints-v :constraints-group
:fixed-scroll :constraints-group
:exports :exports-group
:layout :layout-container
:layout-dir :layout-container
:layout-gap :layout-container
:layout-wrap-type :layout-container
:layout-padding-type :layout-container
:layout-padding :layout-container
:layout-h-orientation :layout-container
:layout-v-orientation :layout-container
:layout :layout-container
:layout-align-content :layout-container
:layout-align-items :layout-container
:layout-flex-dir :layout-container
:layout-gap :layout-container
:layout-gap-type :layout-container
:layout-justify-content :layout-container
:layout-wrap-type :layout-container
:layout-padding-type :layout-container
:layout-padding :layout-container
:layout-h-orientation :layout-container
:layout-v-orientation :layout-container
:layout-item-margin :layout-item
:layout-item-margin-type :layout-item
:layout-item-h-sizing :layout-item
:layout-item-v-sizing :layout-item
:layout-item-max-h :layout-item
:layout-item-min-h :layout-item
:layout-item-max-w :layout-item
:layout-item-min-w :layout-item
:layout-item-align-self :layout-item})
:layout-item-margin :layout-item
:layout-item-margin-type :layout-item
:layout-item-h-sizing :layout-item
:layout-item-v-sizing :layout-item
:layout-item-max-h :layout-item
:layout-item-min-h :layout-item
:layout-item-max-w :layout-item
:layout-item-min-w :layout-item
:layout-item-align-self :layout-item})
;; Attributes that may directly be edited by the user with forms
(def editable-attrs

View file

@ -353,6 +353,16 @@
(filter (comp (into #{} ids) second))
(map second)))
(defn get-index-replacement
"Given a collection of shapes, calculate their positions
in the parent, find first index and return next one"
[shapes objects]
(->> shapes
(order-by-indexed-shapes objects)
first
(get-position-on-parent objects)
inc))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SHAPES ORGANIZATION (PATH MANAGEMENT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -125,7 +125,7 @@
update-new-shape
(fn [new-shape original-shape]
(let [new-name (ctst/generate-unique-name @unames (:name new-shape))]
(let [new-name (:name new-shape)]
(when (nil? (:parent-id original-shape))
(vswap! unames conj new-name))

View file

@ -278,7 +278,7 @@
(def ^:private minimal-shapes
[{:type :rect
:name "Rect-1"
:name "Rectangle"
:fills [{:fill-color default-color
:fill-opacity 1}]
:strokes []
@ -292,13 +292,13 @@
:strokes []}
{:type :circle
:name "Circle-1"
:name "Ellipse"
:fills [{:fill-color default-color
:fill-opacity 1}]
:strokes []}
{:type :path
:name "Path-1"
:name "Path"
:fills []
:strokes [{:stroke-style :solid
:stroke-alignment :center
@ -307,7 +307,7 @@
:stroke-opacity 1}]}
{:type :frame
:name "Board-1"
:name "Board"
:fills [{:fill-color clr/white
:fill-opacity 1}]
:strokes []
@ -320,7 +320,7 @@
:ry 0}
{:type :text
:name "Text-1"
:name "Text"
:content nil}
{:type :svg-raw}])

View file

@ -6,6 +6,7 @@
(ns app.common.types.shape.layout
(:require
[app.common.data.macros :as dm]
[app.common.spec :as us]
[clojure.spec.alpha :as s]))
@ -99,15 +100,21 @@
([shape]
(and (= :frame (:type shape)) (= :flex (:layout shape)))))
(defn layout-child? [objects shape]
(defn layout-immediate-child? [objects shape]
(let [parent-id (:parent-id shape)
parent (get objects parent-id)]
(layout? parent)))
(defn layout-immediate-child-id? [objects id]
(let [parent-id (dm/get-in objects [id :parent-id])
parent (get objects parent-id)]
(layout? parent)))
(defn layout-descent? [objects shape]
(let [frame-id (:frame-id shape)
frame (get objects frame-id)]
(layout? frame)))
(defn layout-child-id? [objects id]
(let [shape (get objects id)]
(layout-child? objects shape)))
(defn inside-layout?
"Check if the shape is inside a layout"
[objects shape]

View file

@ -304,6 +304,8 @@
[used basename]
(us/assert! ::set-of-strings used)
(us/assert! ::us/string basename)
;; We have add a condition because UX doesn't want numbers on
;; layer names.
(if-not (contains? used basename)
basename
(let [[prefix initial] (extract-numeric-suffix basename)]

View file

@ -203,7 +203,7 @@
(t/deftest halft-round-point
(let [p1 (gpt/point 1.34567 3.34567)
rs (gpt/half-round p1)]
rs (gpt/round-step p1 0.5)]
(t/is (gpt/point? rs))
(t/is (mth/close? 1.5 (:x rs)))
(t/is (mth/close? 3.5 (:y rs)))))

View file

@ -348,11 +348,21 @@
cursor: pointer;
font-size: $fs14;
display: flex;
gap: 0 10px;
justify-content: start;
padding: $size-2;
span {
color: $color-gray-20;
margin-left: auto;
display: flex;
justify-content: start;
align-items: center;
}
.check-icon {
min-width: 25px;
color: $color-gray-20;
justify-content: center;
}
&.dropdown-separator:not(:last-child) {
@ -375,11 +385,8 @@
& li.checked-element {
padding-left: 0;
display: flex;
justify-content: space-around;
& span {
margin: 0;
color: $color-black;
}

View file

@ -190,3 +190,5 @@
{:name "YouTube thumb"
:width 1280
:height 720}])
(def zoom-half-pixel-precision 8)

View file

@ -846,8 +846,8 @@
:text
(rx/of (dwe/start-edition-mode id))
(:group :bool)
(rx/of (dws/select-shapes (into (d/ordered-set) [(last shapes)])))
(:group :bool :frame)
(rx/of (dws/select-shapes (into (d/ordered-set) shapes)))
:svg-raw
nil

View file

@ -11,7 +11,6 @@
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph]
[app.common.path.shapes-to-path :as stp]
[app.common.types.shape-tree :as ctt]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.selection :as dws]
@ -85,9 +84,7 @@
(watch [it state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state)
base-name (-> bool-type d/name str/capital (str "-1"))
name (-> (ctt/retrieve-used-names objects)
(ctt/generate-unique-name base-name))
name (-> bool-type d/name str/capital)
ids (selected-shapes-idx state)
ordered-indexes (cph/order-by-indexed-shapes objects ids)
shapes (->> ordered-indexes

View file

@ -16,6 +16,7 @@
[app.common.types.shape-tree :as ctst]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[app.main.constants :refer [zoom-half-pixel-precision]]
[app.main.data.workspace.drawing.common :as common]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.snap :as snap]
@ -70,14 +71,15 @@
(let [stoper? #(or (ms/mouse-up? %) (= % :interrupt))
stoper (rx/filter stoper? stream)
layout (get state :workspace-layout)
zoom (get-in state [:workspace-local :zoom] 1)
snap-pixel? (contains? layout :snap-pixel-grid)
initial (cond-> @ms/mouse-position snap-pixel? gpt/round)
snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1)
initial (cond-> @ms/mouse-position snap-pixel? (gpt/round-step snap-precision))
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
focus (:workspace-focus-selected state)
zoom (get-in state [:workspace-local :zoom] 1)
fid (ctst/top-nested-frame objects initial)
layout? (ctl/layout? objects fid)
@ -119,7 +121,7 @@
(rx/map #(conj current %)))))
(rx/map
(fn [[_ shift? point]]
#(update-drawing % initial (cond-> point snap-pixel? gpt/round) shift?)))))
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-precision)) shift?)))))
(rx/take-until stoper))
(->> (rx/of (common/handle-finish-drawing))

View file

@ -12,7 +12,6 @@
[app.common.pages.helpers :as cph]
[app.common.types.component :as ctk]
[app.common.types.shape :as cts]
[app.common.types.shape-tree :as ctst]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.state-helpers :as wsh]
@ -73,8 +72,7 @@
(= (count shapes) 1)
(= (:type (first shapes)) :group))
(:name (first shapes))
(-> (ctst/retrieve-used-names objects)
(ctst/generate-unique-name base-name)))
base-name)
selrect (gsh/selection-rect shapes)
group-idx (->> shapes
@ -162,7 +160,7 @@
shapes (shapes-for-grouping objects selected)]
(when-not (empty? shapes)
(let [[group changes]
(prepare-create-group it objects page-id shapes "Group-1" false)]
(prepare-create-group it objects page-id shapes "Group" false)]
(rx/of (dch/commit-changes changes)
(dws/select-shapes (d/ordered-set (:id group))))))))))
@ -221,7 +219,7 @@
(= (:type (first shapes)) :group))
[first-shape (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects))]
(prepare-create-group it objects page-id shapes "Group-1" true))
(prepare-create-group it objects page-id shapes "Mask" true))
changes (-> changes
(pcb/update-shapes (:shapes group)
@ -237,10 +235,14 @@
:points (:points first-shape)
:transform (:transform first-shape)
:transform-inverse (:transform-inverse first-shape))))
(pcb/resize-parents [(:id group)]))]
(pcb/resize-parents [(:id group)]))
undo-id (js/Symbol)]
(rx/of (dch/commit-changes changes)
(dws/select-shapes (d/ordered-set (:id group))))))))))
(rx/of (dwu/start-undo-transaction undo-id)
(dch/commit-changes changes)
(dws/select-shapes (d/ordered-set (:id group)))
(ptk/data-event :layout/update [(:id group)])
(dwu/commit-undo-transaction undo-id))))))))
(def unmask-group
(ptk/reify ::unmask-group

View file

@ -22,7 +22,6 @@
[app.common.types.file :as ctf]
[app.common.types.file.media-object :as ctfm]
[app.common.types.pages-list :as ctpl]
[app.common.types.shape-tree :as ctst]
[app.common.types.typography :as ctt]
[app.common.uuid :as uuid]
[app.main.data.dashboard :as dd]
@ -373,9 +372,7 @@
(watch [it state _]
(let [libraries (wsh/get-libraries state)
component (cph/get-component libraries id)
all-components (-> state :workspace-data :components vals)
unames (into #{} (map :name) all-components)
new-name (ctst/generate-unique-name unames (:name component))
new-name (:name component)
components-v2 (features/active-feature? state :components-v2)

View file

@ -8,6 +8,7 @@
(:require
[app.common.exceptions :as ex]
[app.common.logging :as log]
[app.common.math :as mth]
[app.common.pages.changes-builder :as pcb]
[app.common.spec :as us]
[app.common.types.container :as ctn]
@ -52,8 +53,8 @@
shape {:name name
:width width
:height height
:x (- x (/ width 2))
:y (- y (/ height 2))
:x (mth/round (- x (/ width 2)))
:y (mth/round (- y (/ height 2)))
:metadata {:width width
:height height
:mtype mtype

View file

@ -17,6 +17,7 @@
[app.common.spec :as us]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]
[app.main.constants :refer [zoom-half-pixel-precision]]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.comments :as-alias dwcm]
[app.main.data.workspace.guides :as-alias dwg]
@ -218,7 +219,7 @@
result
(let [[id text-modifier] (first modifiers)]
(recur (rest modifiers)
(update objects id apply-text-modifier text-modifier))))))
(d/update-when result id apply-text-modifier text-modifier))))))
#_(defn apply-path-modifiers
[objects path-modifiers]
@ -240,16 +241,26 @@
(calculate-modifiers state false false modif-tree))
([state ignore-constraints ignore-snap-pixel modif-tree]
(calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree nil))
([state ignore-constraints ignore-snap-pixel modif-tree params]
(let [objects
(wsh/lookup-page-objects state)
snap-pixel?
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))]
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
zoom (dm/get-in state [:workspace-local :zoom])
snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1)]
(as-> objects $
(apply-text-modifiers $ (get state :workspace-text-modifier))
;;(apply-path-modifiers $ (get-in state [:workspace-local :edit-path]))
(gsh/set-objects-modifiers modif-tree $ ignore-constraints snap-pixel?)))))
(gsh/set-objects-modifiers modif-tree $ (merge
params
{:ignore-constraints ignore-constraints
:snap-pixel? snap-pixel?
:snap-precision snap-precision}))))))
(defn- calculate-update-modifiers
[old-modif-tree state ignore-constraints ignore-snap-pixel modif-tree]
@ -259,10 +270,13 @@
snap-pixel?
(and (not ignore-snap-pixel) (contains? (:workspace-layout state) :snap-pixel-grid))
zoom (dm/get-in state [:workspace-local :zoom])
snap-precision (if (>= zoom zoom-half-pixel-precision) 0.5 1)
objects
(-> objects
(apply-text-modifiers (get state :workspace-text-modifier)))]
(gsh/set-objects-modifiers old-modif-tree modif-tree objects ignore-constraints snap-pixel?)))
(gsh/set-objects-modifiers old-modif-tree modif-tree objects {:ignore-constraints ignore-constraints :snap-pixel? snap-pixel? :snap-precision snap-precision})))
(defn update-modifiers
([modif-tree]
@ -285,10 +299,13 @@
(set-modifiers modif-tree ignore-constraints false))
([modif-tree ignore-constraints ignore-snap-pixel]
(set-modifiers modif-tree ignore-constraints ignore-snap-pixel nil))
([modif-tree ignore-constraints ignore-snap-pixel params]
(ptk/reify ::set-modifiers
ptk/UpdateEvent
(update [_ state]
(assoc state :workspace-modifiers (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree))))))
(assoc state :workspace-modifiers (calculate-modifiers state ignore-constraints ignore-snap-pixel modif-tree params))))))
;; Rotation use different algorithm to calculate children modifiers (and do not use child constraints).
(defn set-rotation-modifiers
@ -312,7 +329,7 @@
modif-tree
(-> (build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false false))]
(gsh/set-objects-modifiers objects))]
(assoc state :workspace-modifiers modif-tree))))))

View file

@ -8,7 +8,6 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes.flex-layout :as gsl]
[app.common.geom.shapes.path :as upg]
[app.common.path.commands :as upc]
[app.common.path.shapes-to-path :as upsp]
[app.common.spec :as us]
@ -125,14 +124,11 @@
(ptk/reify ::close-path-drag-start
ptk/WatchEvent
(watch [_ state stream]
(let [id (st/get-path-id state)
stop-stream
(let [stop-stream
(->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
content (st/get-path state :content)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
points (upg/content->points content)
handlers (-> (upc/content->handlers content)
(get position))
@ -141,7 +137,7 @@
(first handlers))
drag-events-stream
(->> (streams/position-stream snap-toggled points)
(->> (streams/position-stream)
(rx/take-until stop-stream)
(rx/map #(drag-handler position idx prefix %)))]
@ -164,16 +160,10 @@
(defn start-path-from-point [position]
(ptk/reify ::start-path-from-point
ptk/WatchEvent
(watch [_ state stream]
(watch [_ _ stream]
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
content (st/get-path state :content)
points (upg/content->points content)
id (st/get-path-id state)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
drag-events (->> (streams/position-stream snap-toggled points)
drag-events (->> (streams/position-stream)
(rx/take-until mouse-up)
(rx/map #(drag-handler %)))]
@ -192,11 +182,11 @@
(rx/merge-map #(rx/empty))))
(defn make-drag-stream
[stream snap-toggled _zoom points down-event]
[stream down-event]
(let [mouse-up (->> stream (rx/filter #(or (helpers/end-path-event? %)
(ms/mouse-up? %))))
drag-events (->> (streams/position-stream snap-toggled points)
drag-events (->> (streams/position-stream)
(rx/take-until mouse-up)
(rx/map #(drag-handler %)))]
@ -217,20 +207,13 @@
(assoc-in [:workspace-local :edit-path id :edit-mode] :draw))))
ptk/WatchEvent
(watch [_ state stream]
(let [zoom (get-in state [:workspace-local :zoom])
mouse-down (->> stream (rx/filter ms/mouse-down?))
(watch [_ _ stream]
(let [mouse-down (->> stream (rx/filter ms/mouse-down?))
end-path-events (->> stream (rx/filter helpers/end-path-event?))
content (st/get-path state :content)
points (upg/content->points content)
id (st/get-path-id state)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
;; Mouse move preview
mousemove-events
(->> (streams/position-stream snap-toggled points)
(->> (streams/position-stream)
(rx/take-until end-path-events)
(rx/map #(preview-next-point %)))
@ -238,12 +221,12 @@
mousedown-events
(->> mouse-down
(rx/take-until end-path-events)
(rx/with-latest merge (streams/position-stream snap-toggled points))
(rx/with-latest merge (streams/position-stream))
;; We change to the stream that emits the first event
(rx/switch-map
#(rx/race (make-node-events-stream stream)
(make-drag-stream stream snap-toggled zoom points %))))]
(make-drag-stream stream %))))]
(rx/concat
(rx/of (undo/start-path-undo))
@ -279,11 +262,14 @@
state)))
ptk/WatchEvent
(watch [_ _ _]
(rx/of (setup-frame-path)
(dwdc/handle-finish-drawing)
(dwe/start-edition-mode shape-id)
(change-edit-mode :draw)))))
(watch [_ state _]
(let [content (get-in state [:workspace-drawing :object :content] [])]
(if (seq content)
(rx/of (setup-frame-path)
(dwdc/handle-finish-drawing)
(dwe/start-edition-mode shape-id)
(change-edit-mode :draw))
(rx/of (dwdc/handle-finish-drawing)))))))
(defn handle-new-shape
"Creates a new path shape"
@ -293,7 +279,7 @@
(update [_ state]
(let [id (st/get-path-id state)]
(-> state
(assoc-in [:workspace-local :edit-path id :snap-toggled] true))))
(assoc-in [:workspace-local :edit-path id :snap-toggled] false))))
ptk/WatchEvent
(watch [_ state stream]

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.path.edition
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as upg]
[app.common.path.commands :as upc]
@ -35,8 +36,8 @@
(let [content (st/get-path state :content)
modifiers (helpers/move-handler-modifiers content index prefix false match-opposite? dx dy)
[cx cy] (if (= prefix :c1) [:c1x :c1y] [:c2x :c2y])
point (gpt/point (+ (get-in content [index :params cx]) dx)
(+ (get-in content [index :params cy]) dy))]
point (gpt/point (+ (dm/get-in content [index :params cx]) dx)
(+ (dm/get-in content [index :params cy]) dy))]
(-> state
(update-in [:workspace-local :edit-path id :content-modifiers] merge modifiers)
@ -51,7 +52,7 @@
id (st/get-path-id state)
page-id (:current-page-id state)
shape (st/get-path state)
content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers])
content (:content shape)
new-content (upc/apply-content-modifiers content content-modifiers)
@ -98,7 +99,7 @@
(let [id (st/get-path-id state)
content (st/get-path state :content)
modifiers-reducer (partial modify-content-point content move-modifier)
content-modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
content-modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {})
content-modifiers (->> points
(reduce modifiers-reducer content-modifiers))]
@ -115,9 +116,9 @@
modifiers-reducer (partial modify-content-point content delta)
points (get-in state [:workspace-local :edit-path id :selected-points] #{})
points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers] {})
modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers] {})
modifiers (->> points
(reduce modifiers-reducer modifiers))]
@ -132,8 +133,8 @@
(ptk/reify ::start-move-path-point
ptk/WatchEvent
(watch [_ state _]
(let [id (get-in state [:workspace-local :edition])
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
(let [id (dm/get-in state [:workspace-local :edition])
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
selected? (contains? selected-points position)]
(streams/drag-stream
(rx/of
@ -148,10 +149,9 @@
ptk/WatchEvent
(watch [_ state stream]
(let [stopper (->> stream (rx/filter ms/mouse-up?))
id (get-in state [:workspace-local :edition])
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])
id (dm/get-in state [:workspace-local :edition])
selected-points (get-in state [:workspace-local :edit-path id :selected-points] #{})
selected-points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
content (st/get-path state :content)
points (upg/content->points content)]
@ -159,7 +159,7 @@
(rx/concat
;; This stream checks the consecutive mouse positions to do the dragging
(->> points
(streams/move-points-stream snap-toggled start-position selected-points)
(streams/move-points-stream start-position selected-points)
(rx/map #(move-selected-path-point start-position %))
(rx/take-until stopper))
(rx/of (apply-content-modifiers)))))))
@ -178,7 +178,7 @@
(ptk/reify ::finish-move-selected
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])]
(let [id (dm/get-in state [:workspace-local :edition])]
(-> state
(update-in [:workspace-local :edit-path id] dissoc :current-move))))))
@ -192,8 +192,8 @@
ptk/UpdateEvent
(update [_ state]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(let [id (dm/get-in state [:workspace-local :edition])
current-move (dm/get-in state [:workspace-local :edit-path id :current-move])]
(if (nil? current-move)
(-> state
(assoc-in [:workspace-local :edit-path id :moving-nodes] true)
@ -202,11 +202,11 @@
ptk/WatchEvent
(watch [_ state stream]
(let [id (get-in state [:workspace-local :edition])
current-move (get-in state [:workspace-local :edit-path id :current-move])]
(let [id (dm/get-in state [:workspace-local :edition])
current-move (dm/get-in state [:workspace-local :edit-path id :current-move])]
;; id can be null if we just selected the tool but we didn't start drawing
(if (and id (= same-event current-move))
(let [points (get-in state [:workspace-local :edit-path id :selected-points] #{})
(let [points (dm/get-in state [:workspace-local :edit-path id :selected-points] #{})
move-events (->> stream
(rx/filter (ptk/type? ::move-selected))
@ -238,13 +238,13 @@
(ptk/reify ::start-move-handler
ptk/WatchEvent
(watch [_ state stream]
(let [id (get-in state [:workspace-local :edition])
(let [id (dm/get-in state [:workspace-local :edition])
cx (d/prefix-keyword prefix :x)
cy (d/prefix-keyword prefix :y)
start-point @ms/mouse-position
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
start-delta-x (get-in modifiers [index cx] 0)
start-delta-y (get-in modifiers [index cy] 0)
modifiers (dm/get-in state [:workspace-local :edit-path id :content-modifiers])
start-delta-x (dm/get-in modifiers [index cx] 0)
start-delta-y (dm/get-in modifiers [index cy] 0)
content (st/get-path state :content)
points (upg/content->points content)
@ -253,14 +253,12 @@
handler (-> content (get index) (upc/get-handler prefix))
[op-idx op-prefix] (upc/opposite-index content index prefix)
opposite (upc/handler->point content op-idx op-prefix)
snap-toggled (get-in state [:workspace-local :edit-path id :snap-toggled])]
opposite (upc/handler->point content op-idx op-prefix)]
(streams/drag-stream
(rx/concat
(rx/of (dch/update-shapes [id] upsp/convert-to-path))
(->> (streams/move-handler-stream snap-toggled start-point point handler opposite points)
(->> (streams/move-handler-stream start-point point handler opposite points)
(rx/take-until (->> stream (rx/filter #(or (ms/mouse-up? %)
(streams/finish-edition? %)))))
(rx/map
@ -283,21 +281,21 @@
(ptk/reify ::start-path-edit
ptk/UpdateEvent
(update [_ state]
(let [edit-path (get-in state [:workspace-local :edit-path id])
(let [edit-path (dm/get-in state [:workspace-local :edit-path id])
content (st/get-path state :content)
state (st/set-content state (ups/close-subpaths content))]
(cond-> state
(or (not edit-path) (= :draw (:edit-mode edit-path)))
(assoc-in [:workspace-local :edit-path id] {:edit-mode :move
:selected #{}
:snap-toggled true})
:snap-toggled false})
(and (some? edit-path) (= :move (:edit-mode edit-path)))
(assoc-in [:workspace-local :edit-path id :edit-mode] :draw))))
ptk/WatchEvent
(watch [_ state stream]
(let [mode (get-in state [:workspace-local :edit-path id :edit-mode])
(let [mode (dm/get-in state [:workspace-local :edit-path id :edit-mode])
stopper (->> stream
(rx/filter #(or
(= (ptk/type %) ::dwe/clear-edition-mode)

View file

@ -6,9 +6,11 @@
(ns app.main.data.workspace.path.streams
(:require
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as upg]
[app.main.data.workspace.path.state :as state]
[app.main.constants :refer [zoom-half-pixel-precision]]
[app.main.data.workspace.path.state :as pst]
[app.main.snap :as snap]
[app.main.store :as st]
[app.main.streams :as ms]
@ -17,7 +19,6 @@
[potok.core :as ptk]))
(defonce drag-threshold 5)
(def zoom-half-pixel-precision 8)
(defn dragging? [start zoom]
(fn [current]
@ -36,7 +37,7 @@
position
(>= zoom zoom-half-pixel-precision)
(gpt/half-round position)
(gpt/round-step position 0.5)
:else
(gpt/round position))))
@ -71,15 +72,23 @@
(->> position-stream
(rx/merge-map (fn [] to-stream)))))))
(defn snap-toggled-stream
[]
(let [get-snap (fn [state]
(let [id (pst/get-path-id state)]
(dm/get-in state [:workspace-local :edit-path id :snap-toggled])))]
(-> (l/derived get-snap st/state)
(rx/from-atom {:emit-current-value? true}))))
(defn move-points-stream
[snap-toggled start-point selected-points points]
[start-point selected-points points]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
ranges (snap/create-ranges points selected-points)
d-pos (/ snap/snap-path-accuracy zoom)
check-path-snap
(fn [position]
(fn [[position snap-toggled]]
(if snap-toggled
(let [delta (gpt/subtract position start-point)
moved-points (->> selected-points (mapv #(gpt/add % delta)))
@ -88,6 +97,7 @@
position))]
(->> ms/mouse-position
(rx/map to-pixel-snap)
(rx/with-latest-from (snap-toggled-stream))
(rx/map check-path-snap))))
(defn get-angle [node handler opposite]
@ -99,7 +109,7 @@
[rot-angle rot-sign])))
(defn move-handler-stream
[snap-toggled start-point node handler opposite points]
[start-point node handler opposite points]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
ranges (snap/create-ranges points)
@ -108,7 +118,7 @@
[initial-angle] (get-angle node handler opposite)
check-path-snap
(fn [position]
(fn [[position snap-toggled]]
(if snap-toggled
(let [delta (gpt/subtract position start-point)
handler (gpt/add handler delta)
@ -134,13 +144,14 @@
(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 (snap-toggled-stream))
(rx/map check-path-snap))))
(defn position-stream
[snap-toggled _points]
[]
(let [zoom (get-in @st/state [:workspace-local :zoom] 1)
d-pos (/ snap/snap-path-accuracy zoom)
get-content #(state/get-path % :content)
get-content #(pst/get-path % :content)
content-stream
(-> (l/derived get-content st/state)
@ -154,7 +165,8 @@
(->> ms/mouse-position
(rx/map to-pixel-snap)
(rx/with-latest vector ranges-stream)
(rx/map (fn [[position ranges]]
(rx/with-latest-from (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))

View file

@ -327,8 +327,7 @@
(defn- prepare-duplicate-frame-change
[changes objects page unames update-unames! ids-map obj delta]
(let [new-id (ids-map (:id obj))
frame-name (ctt/generate-unique-name @unames (:name obj))
_ (update-unames! frame-name)
frame-name (:name obj)
new-frame (-> obj
(assoc :id new-id
@ -361,8 +360,7 @@
(if (some? obj)
(let [new-id (ids-map (:id obj))
parent-id (or parent-id frame-id)
name (ctt/generate-unique-name @unames (:name obj))
_ (update-unames! name)
name (:name obj)
new-obj (-> obj
(assoc :id new-id

View file

@ -12,6 +12,7 @@
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages.helpers :as cph]
[app.common.types.component :as ctc]
[app.common.types.modifiers :as ctm]
[app.common.types.shape-tree :as ctt]
[app.common.types.shape.layout :as ctl]
@ -153,18 +154,23 @@
selected-shapes (map (d/getf objects) selected)
single? (= (count selected-shapes) 1)
has-group? (->> selected-shapes (d/seek cph/group-shape?))
is-group? (and single? has-group?)]
is-group? (and single? has-group?)
has-mask? (->> selected-shapes (d/seek cph/mask-shape?))
is-mask? (and single? has-mask?)
has-component? (some true? (map ctc/instance-root? selected-shapes))
is-component? (and single? has-component?)]
(if is-group?
(if (and (not is-component?) is-group? (not is-mask?))
(let [new-shape-id (uuid/next)
parent-id (:parent-id (first selected-shapes))
shapes-ids (:shapes (first selected-shapes))
ordered-ids (into (d/ordered-set) shapes-ids)
undo-id (js/Symbol)]
undo-id (js/Symbol)
group-index (cph/get-index-replacement selected objects)]
(rx/of
(dwu/start-undo-transaction undo-id)
(dwse/select-shapes ordered-ids)
(dws/create-artboard-from-selection new-shape-id parent-id)
(dws/create-artboard-from-selection new-shape-id parent-id group-index)
(cl/remove-all-fills [new-shape-id] {:color clr/black
:opacity 1})
(create-layout-from-id [new-shape-id] type)

View file

@ -87,9 +87,7 @@
selected (wsh/lookup-selected state)
id (or (:id attrs) (uuid/next))
name (-> objects
(ctst/retrieve-used-names)
(ctst/generate-unique-name (:name attrs)))
name (:name attrs)
shape (make-new-shape
(assoc attrs :id id :name name)
@ -361,6 +359,8 @@
([id]
(create-artboard-from-selection id nil))
([id parent-id]
(create-artboard-from-selection id parent-id nil))
([id parent-id index]
(ptk/reify ::create-artboard-from-selection
ptk/WatchEvent
(watch [_ state _]
@ -369,11 +369,8 @@
selected (wsh/lookup-selected state)
selected (cph/clean-loops objects selected)
selected-objs (map #(get objects %) selected)
new-index (->> selected
(cph/order-by-indexed-shapes objects)
first
(cph/get-position-on-parent objects)
inc)]
new-index (or index
(cph/get-index-replacement selected objects))]
(when (d/not-empty? selected)
(let [srect (gsh/selection-rect selected-objs)
frame-id (get-in objects [(first selected) :frame-id])

View file

@ -11,6 +11,7 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph]
[app.common.spec :as us :refer [max-safe-int min-safe-int]]
@ -21,6 +22,7 @@
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.undo :as dwu]
[app.main.repo :as rp]
[app.util.color :as uc]
[app.util.path.parser :as upp]
@ -361,7 +363,7 @@
(let [{:keys [tag attrs hidden]} element-data
attrs (usvg/format-styles attrs)
element-data (cond-> element-data (map? element-data) (assoc :attrs attrs))
name (ctst/generate-unique-name unames (or (:id attrs) (tag->name tag)))
name (or (:id attrs) (tag->name tag))
att-refs (usvg/find-attr-references attrs)
references (usvg/find-def-references (:defs svg-data) att-refs)
@ -477,20 +479,21 @@
(rx/reduce (fn [acc [url image]] (assoc acc url image)) {})))
(defn create-svg-shapes
[svg-data {:keys [x y] :as position} objects frame-id parent-id selected center?]
[svg-data {:keys [x y]} objects frame-id parent-id selected center?]
(try
(let [[vb-x vb-y vb-width vb-height] (svg-dimensions svg-data)
x (if center?
(- x vb-x (/ vb-width 2))
x)
y (if center?
(- y vb-y (/ vb-height 2))
y)
x (mth/round
(if center?
(- x vb-x (/ vb-width 2))
x))
y (mth/round
(if center?
(- y vb-y (/ vb-height 2))
y))
unames (ctst/retrieve-used-names objects)
svg-name (->> (str/replace (:name svg-data) ".svg" "")
(ctst/generate-unique-name unames))
svg-name (str/replace (:name svg-data) ".svg" "")
svg-data (-> svg-data
(assoc :x x
@ -583,7 +586,11 @@
(filter #(= :add-obj (:type %)))
(map :id)
reverse
vec))]
vec))
undo-id (js/Symbol)]
(rx/of (dch/commit-changes changes)
(dws/select-shapes (d/ordered-set (:id new-shape))))))))
(rx/of (dwu/start-undo-transaction undo-id)
(dch/commit-changes changes)
(dws/select-shapes (d/ordered-set (:id new-shape)))
(ptk/data-event :layout/update [(:id new-shape)])
(dwu/commit-undo-transaction undo-id))))))

View file

@ -15,7 +15,6 @@
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.common.types.modifiers :as ctm]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc]
[app.main.data.workspace.modifiers :as dwm]
@ -318,16 +317,25 @@
(defn not-changed? [old-dim new-dim]
(> (mth/abs (- old-dim new-dim)) 1))
(defn resize-text
[id new-width new-height]
(ptk/reify ::resize-text
(defn commit-resize-text
[]
(ptk/reify ::commit-resize-text
ptk/WatchEvent
(watch [_ state _]
(let [shape (wsh/lookup-shape state id)
(let [props (::resize-text-debounce-props state)
objects (wsh/lookup-page-objects state)
undo-id (js/Symbol)]
(letfn [(update-fn [shape]
(let [{:keys [selrect grow-type]} shape
{shape-width :width shape-height :height} selrect
(letfn [(changed-text? [id]
(let [shape (get objects id)
[new-width new-height] (get props id)]
(or (and (not-changed? (:width shape) new-width) (= (:grow-type shape) :auto-width))
(and (not-changed? (:height shape) new-height)
(or (= (:grow-type shape) :auto-height) (= (:grow-type shape) :auto-width))))))
(update-fn [{:keys [id selrect grow-type] :as shape}]
(let [{shape-width :width shape-height :height} selrect
[new-width new-height] (get props id)
shape
(cond-> shape
@ -342,14 +350,39 @@
shape))]
(when (or (and (not-changed? (:width shape) new-width) (= (:grow-type shape) :auto-width))
(and (not-changed? (:height shape) new-height)
(or (= (:grow-type shape) :auto-height) (= (:grow-type shape) :auto-width))))
(let [ids (->> (keys props) (filter changed-text?))]
(rx/of (dwu/start-undo-transaction undo-id)
(dch/update-shapes [id] update-fn {:reg-objects? true :save-undo? true})
(ptk/data-event :layout/update [id])
(dch/update-shapes ids update-fn {:reg-objects? true :save-undo? true})
(ptk/data-event :layout/update ids)
(dwu/commit-undo-transaction undo-id))))))))
(defn resize-text
[id new-width new-height]
(let [cur-event (js/Symbol)]
(ptk/reify ::resize-text
ptk/UpdateEvent
(update [_ state]
(-> state
(update ::resize-text-debounce-props (fnil assoc {}) id [new-width new-height])
(cond-> (nil? (::resize-text-debounce-event state))
(assoc ::resize-text-debounce-event cur-event))))
ptk/WatchEvent
(watch [_ state stream]
(if (= (::resize-text-debounce-event state) cur-event)
(let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))]
(rx/concat
(rx/merge
(->> stream
(rx/filter (ptk/type? ::resize-text))
(rx/debounce 50)
(rx/take 1)
(rx/map #(commit-resize-text))
(rx/take-until stopper))
(rx/of (resize-text id new-width new-height)))
(rx/of #(dissoc % ::resize-text-debounce-props ::resize-text-debounce-event))))
(rx/empty))))))
(defn save-font
[data]
@ -384,37 +417,43 @@
new-shape))
(defn update-text-modifier-state
[id props]
(ptk/reify ::update-text-modifier-state
ptk/UpdateEvent
(update [_ state]
(update-in state [:workspace-text-modifier id] (fnil merge {}) props))))
(defn commit-update-text-modifier
[]
(ptk/reify ::commit-update-text-modifier
ptk/WatchEvent
(watch [_ state _]
(let [ids (::update-text-modifier-debounce-ids state)]
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
(rx/of (dwm/update-modifiers modif-tree false true)))))))
(defn update-text-modifier
[id props]
(ptk/reify ::update-text-modifier
ptk/WatchEvent
(watch [_ state _]
(let [modifiers (get-in (:workspace-modifiers state) [id :modifiers])
shape (-> (wsh/lookup-shape state id)
(gsh/transform-shape modifiers))
(let [cur-event (js/Symbol)]
(ptk/reify ::update-text-modifier
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:workspace-text-modifier id] (fnil merge {}) props)
(update ::update-text-modifier-debounce-ids (fnil conj #{}) id)
(cond-> (nil? (::update-text-modifier-debounce-event state))
(assoc ::update-text-modifier-debounce-event cur-event))))
current-width (:width shape)
current-height (:height shape)]
(rx/concat
(rx/of (update-text-modifier-state id props))
(if (or (and (some? (:width props))
(not (mth/close? (:width props) current-width)))
(and (some? (:height props))
(not (mth/close? (:height props) current-height))))
(let [modif-tree (dwm/create-modif-tree [id] (ctm/reflow-modifiers))]
(->> (rx/of (dwm/update-modifiers modif-tree false true))
(rx/observe-on :async)))
(rx/empty)))))))
ptk/WatchEvent
(watch [_ state stream]
(if (= (::update-text-modifier-debounce-event state) cur-event)
(let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))]
(rx/concat
(rx/merge
(->> stream
(rx/filter (ptk/type? ::update-text-modifier))
(rx/debounce 50)
(rx/take 1)
(rx/map #(commit-update-text-modifier))
(rx/take-until stopper))
(rx/of (update-text-modifier id props)))
(rx/of #(dissoc % ::update-text-modifier-debounce-event ::update-text-modifier-debounce-ids))))
(rx/empty))))))
(defn clean-text-modifier
[id]
@ -464,18 +503,18 @@
(defn update-position-data
[id position-data]
(let [start (uuid/next)]
(let [cur-event (js/Symbol)]
(ptk/reify ::update-position-data
ptk/UpdateEvent
(update [_ state]
(let [state (assoc-in state [:workspace-text-modifier id :position-data] position-data)]
(if (nil? (::update-position-data-debounce state))
(assoc state ::update-position-data-debounce start)
(assoc state ::update-position-data-debounce cur-event)
(assoc-in state [::update-position-data id] position-data))))
ptk/WatchEvent
(watch [_ state stream]
(if (= (::update-position-data-debounce state) start)
(if (= (::update-position-data-debounce state) cur-event)
(let [stopper (->> stream (rx/filter (ptk/type? :app.main.data.workspace/finalize)))]
(rx/merge
(->> stream

View file

@ -85,8 +85,7 @@
(rx/merge
;; Update the local copy of the thumbnails so we don't need to request it again
(rx/of #(update % :workspace-thumbnails assoc object-id data))
(->> (rx/timer 5000)
(rx/flat-map #(rp/cmd! :upsert-file-object-thumbnail params))
(->> (rp/cmd! :upsert-file-object-thumbnail params)
(rx/catch #(rx/empty))
(rx/ignore))))

View file

@ -240,14 +240,12 @@
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
snap-pixel? (and (contains? (:workspace-layout state) :snap-pixel-grid)
(int? value))
get-modifier
(fn [shape] (ctm/change-dimensions-modifiers shape attr value))
modif-tree
(-> (dwm/build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false snap-pixel?))]
(gsh/set-objects-modifiers objects))]
(assoc state :workspace-modifiers modif-tree)))
@ -265,14 +263,13 @@
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
snap-pixel? (contains? (get state :workspace-layout) :snap-pixel-grid)
get-modifier
(fn [shape] (ctm/change-orientation-modifiers shape orientation))
modif-tree
(-> (dwm/build-modif-tree ids objects get-modifier)
(gsh/set-objects-modifiers objects false snap-pixel?))]
(gsh/set-objects-modifiers objects))]
(assoc state :workspace-modifiers modif-tree)))
@ -443,21 +440,11 @@
exclude-frames-siblings
(into exclude-frames
(comp (mapcat (partial cph/get-siblings-ids objects))
(filter (partial ctl/layout-child-id? objects)))
(filter (partial ctl/layout-immediate-child-id? 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)
(rx/map #(fix-axis %)))
(rx/map #(gpt/to-vec from-position %)))
snap-delta (rx/concat
;; We send the nil first so the stream is not waiting for the first value
@ -494,11 +481,24 @@
(rx/merge
;; Temporary modifiers stream
(->> move-stream
(rx/with-latest-from ms/mouse-position-shift)
(rx/map
(fn [[move-vector target-frame drop-index]]
(-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector))
(dwm/build-change-frame-modifiers objects selected target-frame drop-index)
(dwm/set-modifiers)))))
(fn [[[move-vector target-frame drop-index] shift?]]
(let [x-disp? (> (mth/abs (:x move-vector)) (mth/abs (:y move-vector)))
[move-vector snap-ignore-axis]
(cond
(and shift? x-disp?)
[(assoc move-vector :y 0) :y]
shift?
[(assoc move-vector :x 0) :x]
:else
[move-vector nil])]
(-> (dwm/create-modif-tree ids (ctm/move-modifiers move-vector))
(dwm/build-change-frame-modifiers objects selected target-frame drop-index)
(dwm/set-modifiers false false {:snap-ignore-axis snap-ignore-axis}))))))
(->> move-stream
(rx/map (comp set-ghost-displacement first)))
@ -623,7 +623,7 @@
(->> move-events
(rx/scan #(gpt/add %1 mov-vec) (gpt/point 0 0))
(rx/map #(dwm/create-modif-tree selected (ctm/move-modifiers %)))
(rx/map (partial dwm/set-modifiers))
(rx/map #(dwm/set-modifiers % false true))
(rx/take-until stopper))
(rx/of (nudge-selected-shapes direction shift?)))
@ -643,7 +643,7 @@
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state {:omit-blocked? true})
selected-shapes (->> selected (map (d/getf objects)))]
(if (every? (partial ctl/layout-child? objects) selected-shapes)
(if (every? (partial ctl/layout-immediate-child? objects) selected-shapes)
(rx/of (reorder-selected-layout-child direction))
(rx/of (nudge-selected-shapes direction shift?)))))))
@ -669,11 +669,12 @@
cpos (gpt/point (:x bbox) (:y bbox))
pos (gpt/point (or (:x position) (:x bbox))
(or (:y position) (:y bbox)))
delta (gpt/subtract pos cpos)
modif-tree (dwm/create-modif-tree [id] (ctm/move-modifiers delta))]
(rx/of (dwm/set-modifiers modif-tree)
(rx/of (dwm/set-modifiers modif-tree false true)
(dwm/apply-modifiers))))))
(defn- move-shapes-to-frame
@ -688,7 +689,6 @@
shapes (->> ids (cph/clean-loops objects) (keep lookup))
moving-shapes
(cond->> shapes
(not layout?)
@ -753,36 +753,22 @@
(ptk/reify ::flip-horizontal-selected
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes)
origin (gpt/point (:x selrect) (+ (:y selrect) (/ (:height selrect) 2)))
modif-tree (dwm/create-modif-tree
selected
(-> (ctm/empty)
(ctm/resize (gpt/point -1.0 1.0) origin)
(ctm/move (gpt/point (:width selrect) 0))))]
(rx/of (dwm/set-modifiers modif-tree true)
(dwm/apply-modifiers))))))
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes)
center (gsh/center-selrect selrect)
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))]
(rx/of (dwm/apply-modifiers {:modifiers modifiers}))))))
(defn flip-vertical-selected []
(ptk/reify ::flip-vertical-selected
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes)
origin (gpt/point (+ (:x selrect) (/ (:width selrect) 2)) (:y selrect))
modif-tree (dwm/create-modif-tree
selected
(-> (ctm/empty)
(ctm/resize (gpt/point 1.0 -1.0) origin)
(ctm/move (gpt/point 0 (:height selrect)))))]
(rx/of (dwm/set-modifiers modif-tree true)
(dwm/apply-modifiers))))))
(let [objects (wsh/lookup-page-objects state)
selected (wsh/lookup-selected state {:omit-blocked? true})
shapes (map #(get objects %) selected)
selrect (gsh/selection-rect shapes)
center (gsh/center-selrect selrect)
modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))]
(rx/of (dwm/apply-modifiers {:modifiers modifiers}))))))

View file

@ -402,7 +402,7 @@
(let [objects (wsh/lookup-page-objects state)]
(into []
(comp (map (d/getf objects))
(filter (partial ctl/layout-child? objects)))
(filter (partial ctl/layout-immediate-child? objects)))
ids)))
st/state =))
@ -481,7 +481,7 @@
(fn [objects]
(->> ids
(map (d/getf objects))
(some (partial ctl/layout-child? objects))))
(some (partial ctl/layout-immediate-child? objects))))
workspace-page-objects))
(defn get-flex-child-viewer
@ -491,7 +491,7 @@
(let [objects (wsh/lookup-viewer-objects state page-id)]
(into []
(comp (map (d/getf objects))
(filter (partial ctl/layout-child? objects)))
(filter (partial ctl/layout-immediate-child? objects)))
ids)))
st/state =))

View file

@ -292,34 +292,37 @@
;; used to render thumbnails on assets panel.
(mf/defc component-svg
{::mf/wrap [mf/memo #(mf/deferred % ts/idle-then-raf)]}
[{:keys [objects group zoom] :or {zoom 1} :as props}]
(let [group-id (:id group)
[{:keys [objects root-shape zoom] :or {zoom 1} :as props}]
(let [root-shape-id (:id root-shape)
include-metadata? (mf/use-ctx export/include-metadata-ctx)
vector
(mf/use-memo
(mf/deps (:x group) (:y group))
(mf/deps (:x root-shape) (:y root-shape))
(fn []
(-> (gpt/point (:x group) (:y group))
(-> (gpt/point (:x root-shape) (:y root-shape))
(gpt/negate))))
objects
(mf/use-memo
(mf/deps vector objects group-id)
(mf/deps vector objects root-shape-id)
(fn []
(let [children-ids (cons group-id (cph/get-children-ids objects group-id))
(let [children-ids (cons root-shape-id (cph/get-children-ids objects root-shape-id))
update-fn #(update %1 %2 gsh/transform-shape (ctm/move-modifiers vector))]
(reduce update-fn objects children-ids))))
group (get objects group-id)
width (* (:width group) zoom)
height (* (:height group) zoom)
vbox (format-viewbox {:width (:width group 0)
:height (:height group 0)})
group-wrapper
root-shape (get objects root-shape-id)
width (* (:width root-shape) zoom)
height (* (:height root-shape) zoom)
vbox (format-viewbox {:width (:width root-shape 0)
:height (:height root-shape 0)})
root-shape-wrapper
(mf/use-memo
(mf/deps objects)
(fn [] (group-wrapper-factory objects)))]
(mf/deps objects root-shape)
(fn []
(case (:type root-shape)
:group (group-wrapper-factory objects)
:frame (frame-wrapper-factory objects))))]
[:svg {:view-box vbox
:width (ust/format-precision width viewbox-decimal-precision)
@ -330,8 +333,8 @@
:xmlns:penpot (when include-metadata? "https://penpot.app/xmlns")
:fill "none"}
[:> shape-container {:shape group}
[:& group-wrapper {:shape group :view-box vbox}]]]))
[:> shape-container {:shape root-shape}
[:& root-shape-wrapper {:shape root-shape :view-box vbox}]]]))
(mf/defc object-svg
{::mf/wrap [mf/memo]}
@ -375,12 +378,12 @@
(mf/defc component-symbol
[{:keys [id data] :as props}]
(let [name (:name data)
path (:path data)
objects (-> (:objects data)
(adapt-objects-for-shape id))
object (get objects id)
selrect (:selrect object)
(let [name (:name data)
path (:path data)
objects (-> (:objects data)
(adapt-objects-for-shape id))
root-shape (get objects id)
selrect (:selrect root-shape)
main-instance-id (:main-instance-id data)
main-instance-page (:main-instance-page data)
@ -394,8 +397,11 @@
group-wrapper
(mf/use-memo
(mf/deps objects)
(fn [] (group-wrapper-factory objects)))]
(mf/deps objects root-shape)
(fn []
(case (:type root-shape)
:group (group-wrapper-factory objects)
:frame (frame-wrapper-factory objects))))]
[:> "symbol" #js {:id (str id)
:viewBox vbox
@ -405,8 +411,8 @@
"penpot:main-instance-x" main-instance-x
"penpot:main-instance-y" main-instance-y}
[:title name]
[:> shape-container {:shape object}
[:& group-wrapper {:shape object :view-box vbox}]]]))
[:> shape-container {:shape root-shape}
[:& group-wrapper {:shape root-shape :view-box vbox}]]]))
(mf/defc components-sprite-svg
{::mf/wrap-props false}

View file

@ -172,5 +172,5 @@
{:key (str (:id @state) "-" index)
:class (when (= (str value) (-> @state :current-value)) "is-selected")
:on-click (select-item value)}
[:span.checked-element-value label]
[:span.check-icon i/tick]])))]]]))
[:span.check-icon i/tick]
[:span.checked-element-value label]])))]]]))

View file

@ -52,7 +52,7 @@
{:p1 p1}
(= 4 (count (set values)))
{:p1 p1 :p2 p2 :p3 p3}
{:p1 p1 :p2 p2 :p3 p3 :p4 p4}
(and (= p1 p3) (= p2 p4))
{:p1 p1 :p3 p3}

View file

@ -36,7 +36,8 @@
(mf/defc viewport
[{:keys [local file page frame index viewer-pagination size]}]
(let [on-mouse-wheel
(let [inspect-svg-container-ref (mf/use-ref nil)
on-mouse-wheel
(fn [event]
(when (kbd/mod? event)
(dom/prevent-default event)
@ -45,14 +46,30 @@
(.-deltaX ^js event))]
(if (pos? delta)
(st/emit! dv/decrease-zoom)
(st/emit! dv/increase-zoom)))))
(st/emit! dv/increase-zoom))))
(when-not (kbd/mod? event)
(let [event (.getBrowserEvent ^js event)
shift? (kbd/shift? event)
inspect-svg-container (mf/ref-val inspect-svg-container-ref)
delta (+ (.-deltaY ^js event)
(.-deltaX ^js event))
scroll-pos (if shift?
(dom/get-h-scroll-pos inspect-svg-container)
(dom/get-scroll-pos inspect-svg-container))
new-scroll-pos (+ scroll-pos delta)]
(do
(dom/prevent-default event)
(dom/stop-propagation event)
(if shift?
(dom/set-h-scroll-pos! inspect-svg-container new-scroll-pos)
(dom/set-scroll-pos! inspect-svg-container new-scroll-pos))))))
on-mount
(fn []
;; bind with passive=false to allow the event to be cancelled
;; https://stackoverflow.com/a/57582286/3219895
(let [key1 (events/listen goog/global EventType.WHEEL
on-mouse-wheel #js {"passive" false})]
on-mouse-wheel #js {"passive" false "capture" true})]
(fn []
(events/unlistenByKey key1))))]
@ -69,7 +86,7 @@
:page page}]
[:div.inspect-svg-wrapper {:on-click (handle-select-frame frame)}
[:& viewer-pagination {:index index :num-frames (count (:frames page)) :left-bar true :right-bar true}]
[:div.inspect-svg-container
[:div.inspect-svg-container {:ref inspect-svg-container-ref}
[:& render-frame-svg {:frame frame :page page :local local :size size}]]]
[:& right-sidebar {:frame frame

View file

@ -68,6 +68,7 @@
[{:keys [padding type]}]
(let [values (fm/format-padding-margin-shorthand (vals padding))]
[:div.attributes-value
{:title (str (str/join "px " (vals values)) "px")}
(for [[k v] values]
[:span.items {:key (str type "-" k "-" v)} v "px"])]))

View file

@ -88,9 +88,44 @@
on-select-library-color
(mf/use-fn
(fn [color]
(st/emit! (dc/update-colorpicker color))
(on-change color)))
(fn [state color]
(let [type-origin (:type state)
editig-stop-origin (:editing-stop state)
is-gradient? (some? (:gradient color))
change-to (fn [new-color]
(st/emit! (dc/update-colorpicker new-color))
(on-change new-color))
clean-stop (fn [stops index color]
(-> (nth stops index)
(merge color)
(assoc :offset index)
(dissoc :r)
(dissoc :g)
(dissoc :b)
(dissoc :alpha)
(dissoc :s)
(dissoc :h)
(dissoc :v)
(dissoc :hex)))
set-new-gradient (fn [state color index]
(let [old-stops (:stops state)
old-gradient (:gradient state)
new-gradient (-> old-gradient
(cond-> (= index 0) (assoc :stops [(clean-stop old-stops 0 color) (nth old-stops 1)]))
(cond-> (= index 1) (assoc :stops [(nth old-stops 0) (clean-stop old-stops 1 color)]))
(dissoc :shape-id))]
(change-to {:gradient new-gradient})))]
;; If we have any kind of gradient and:
;; Click on a solid color -> This color is applied to the selected offset
;; Click on a color with transparency -> The same to solid color will happend
;; Click on any kind of gradient -> The color changes completly to new gradient
;; If we have a non gradient color the new color is applied without any change
(if (or (= :radial-gradient type-origin) (= :linear-gradient type-origin))
(if is-gradient?
(change-to color)
(set-new-gradient state color editig-stop-origin))
(change-to color)))))
on-add-library-color
(mf/use-fn
@ -230,7 +265,8 @@
:on-change handle-change-color}]
[:& libraries
{:current-color current-color
{:state state
:current-color current-color
:disable-gradient disable-gradient
:disable-opacity disable-opacity
:on-select-color on-select-library-color

View file

@ -7,18 +7,22 @@
(ns app.main.ui.workspace.colorpicker.libraries
(:require
[app.common.data.macros :as dm]
[app.main.data.events :as ev]
[app.main.data.workspace :as dw]
[app.main.data.workspace.colors :as mdc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.color-bullet :refer [color-bullet]]
[app.main.ui.hooks :as h]
[app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.timers :as ts]
[rumext.v2 :as mf]))
(mf/defc libraries
[{:keys [on-select-color on-add-library-color disable-gradient disable-opacity]}]
[{:keys [state on-select-color on-add-library-color disable-gradient disable-opacity]}]
(let [selected (h/use-shared-state mdc/colorpicker-selected-broadcast-key :recent)
current-colors (mf/use-state [])
@ -81,11 +85,16 @@
i/plus])
[:div.color-bullet.button {:style {:background-color "var(--color-white)"}
:on-click #(st/emit! (mdc/show-palette @selected))}
:on-click(fn []
(r/set-resize-type! :bottom)
(dom/add-class! (dom/get-element-by-class "color-palette") "fade-out-down")
(ts/schedule 300 #(st/emit! (dw/remove-layout-flag :textpalette)
(-> (dw/toggle-layout-flag :colorpalette)
(vary-meta assoc ::ev/origin "workspace-colorpicker")))))}
i/palette]
(for [[idx color] (map-indexed vector @current-colors)]
[:& color-bullet
{:key (dm/str "color-" idx)
:color color
:on-click on-select-color}])]]))
:on-click (partial on-select-color state)}])]]))

View file

@ -10,6 +10,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.common.types.component :as ctk]
[app.common.types.components-list :as ctkl]
[app.common.types.file :as ctf]
[app.common.types.page :as ctp]
@ -372,27 +373,25 @@
has-frame? (->> shapes (d/seek cph/frame-shape?))
is-frame? (and single? has-frame?)
is-flex-container? (and is-frame? (= :flex (:layout (first shapes))))
has-group? (->> shapes (d/seek cph/group-shape?))
is-group? (and single? has-group?)
ids (->> shapes (map :id))
add-flex #(st/emit! (if is-frame?
(dwsl/create-layout-from-id ids :flex)
(dwsl/create-layout-from-selection :flex)))
remove-flex #(st/emit! (dwsl/remove-layout ids))]
(cond
(or single? (and is-frame? (not is-flex-container?)) is-group?)
[:*
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.add-flex")
:shortcut (sc/get-tooltip :toggle-layout-flex)
:on-click add-flex}]]
is-flex-container?
[:*
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.remove-flex")
:shortcut (sc/get-tooltip :toggle-layout-flex)
:on-click remove-flex}]])))
[:*
(when (not is-flex-container?)
[:div
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.add-flex")
:shortcut (sc/get-tooltip :toggle-layout-flex)
:on-click add-flex}]])
(when is-flex-container?
[:div
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.remove-flex")
:shortcut (sc/get-tooltip :toggle-layout-flex)
:on-click remove-flex}]])]))
(mf/defc context-menu-component
[{:keys [shapes]}]
@ -400,6 +399,7 @@
has-component? (some true? (map #(contains? % :component-id) shapes))
is-component? (and single? (-> shapes first :component-id some?))
is-non-root? (and single? (ctk/in-component-instance-not-root? (first shapes)))
shape-id (-> shapes first :id)
component-id (-> shapes first :component-id)
@ -454,10 +454,12 @@
:on-accept do-update-component-in-bulk}))]
[:*
[:*
[:& menu-separator]
[:& menu-entry {:title (tr "workspace.shape.menu.create-component")
:shortcut (sc/get-tooltip :create-component)
:on-click do-add-component}]
(when (or (not is-non-root?) (and has-component? (not single?)))
[:& menu-separator])
(when-not is-non-root?
[:& menu-entry {:title (tr "workspace.shape.menu.create-component")
:shortcut (sc/get-tooltip :create-component)
:on-click do-add-component}])
(when (and has-component? (not single?))
[:*
[:& menu-entry {:title (tr "workspace.shape.menu.detach-instances-in-bulk")
@ -470,7 +472,6 @@
;; WARNING: this menu is the same as the context menu at the sidebar.
;; If you change it, you must change equally the file
;; app/main/ui/workspace/sidebar/options/menus/component.cljs
[:*
[:& menu-separator]
(if main-component?

View file

@ -11,6 +11,7 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.pages.helpers :as cph]
[app.common.types.modifiers :as ctm]
[app.main.store :as st]
[app.main.ui.hooks :as hooks]
@ -30,14 +31,14 @@
(defn get-nodes
"Retrieve the DOM nodes to apply the matrix transformation"
[base-node {:keys [id type masked-group?] :as shape}]
[base-node {:keys [id parent-id] :as shape}]
(when (some? base-node)
(let [shape-node (get-shape-node base-node id)
frame? (= :frame type)
group? (= :group type)
text? (= :text type)
mask? (and group? masked-group?)]
(let [shape-node (get-shape-node base-node id)
parent-node (get-shape-node base-node parent-id)
frame? (cph/frame-shape? shape)
group? (cph/group-shape? shape)
text? (cph/text-shape? shape)
masking-child? (:masking-child? (meta shape))]
(cond
frame?
[shape-node
@ -48,9 +49,10 @@
;; For groups we don't want to transform the whole group but only
;; its filters/masks
mask?
[(dom/query shape-node ".mask-clip-path")
(dom/query shape-node ".mask-shape")]
masking-child?
[shape-node
(dom/query parent-node ".mask-clip-path")
(dom/query parent-node ".mask-shape")]
group?
(let [shape-defs (dom/query shape-node "defs")]
@ -74,10 +76,12 @@
(-> (dom/get-attribute node "data-old-width") d/parse-double)
(-> (dom/get-attribute node "data-old-height") d/parse-double))
(gsh/transform-selrect modifiers))]
(dom/set-attribute! node "x" x)
(dom/set-attribute! node "y" y)
(dom/set-attribute! node "width" width)
(dom/set-attribute! node "height" height)))
(when (and (some? x) (some? y) (some? width) (some? height))
(dom/set-attribute! node "x" x)
(dom/set-attribute! node "y" y)
(dom/set-attribute! node "width" width)
(dom/set-attribute! node "height" height))))
(defn start-transform!
[base-node shapes]
@ -169,11 +173,19 @@
(or (= (dom/get-tag-name node) "mask")
(= (dom/get-tag-name node) "filter"))
(do
(dom/set-attribute! node "x" (dom/get-attribute node "data-old-x"))
(dom/set-attribute! node "y" (dom/get-attribute node "data-old-y"))
(dom/set-attribute! node "width" (dom/get-attribute node "data-old-width"))
(dom/set-attribute! node "height" (dom/get-attribute node "data-old-height"))
(dom/remove-attribute! node "data-old-x")
(dom/remove-attribute! node "data-old-y")
(dom/remove-attribute! node "data-old-width")
(dom/remove-attribute! node "data-old-height"))
(dom/class? node "frame-title")
(dom/remove-attribute! node "data-old-transform")
:else
(let [old-transform (dom/get-attribute node "data-old-transform")]
(if (some? old-transform)
@ -190,6 +202,18 @@
(-> modifiers
(ctm/resize scalev (-> shape' :points first) (:transform shape') (:transform-inverse shape')))))
(defn add-masking-child?
"Adds to the object the information about if the current shape is a masking child. We use the metadata
to not adding new parameters to the object."
[objects]
(fn [{:keys [id parent-id] :as shape}]
(let [parent (get objects parent-id)
masking-child? (and (cph/mask-shape? parent) (= id (first (:shapes parent))))]
(cond-> shape
masking-child?
(with-meta {:masking-child? true})))))
(defn use-dynamic-modifiers
[objects node modifiers]
@ -198,11 +222,15 @@
(mf/deps modifiers)
(fn []
(when (some? modifiers)
(d/mapm (fn [id {modifiers :modifiers}]
(d/mapm (fn [id {current-modifiers :modifiers}]
(let [shape (get objects id)
adapt-text? (and (= :text (:type shape)) (not (ctm/only-move? modifiers)))
modifiers (cond-> modifiers adapt-text? (adapt-text-modifiers shape))]
(ctm/modifiers->transform modifiers)))
adapt-text? (and (= :text (:type shape)) (not (ctm/only-move? current-modifiers)))
current-modifiers
(cond-> current-modifiers
adapt-text?
(adapt-text-modifiers shape))]
(ctm/modifiers->transform current-modifiers)))
modifiers))))
add-children (mf/use-memo (mf/deps modifiers) #(ctm/added-children-frames modifiers))
@ -215,7 +243,7 @@
(fn []
(->> (keys transforms)
(filter #(some? (get transforms %)))
(mapv (d/getf objects)))))
(mapv (comp (add-masking-child? objects) (d/getf objects))))))
prev-shapes (mf/use-var nil)
prev-modifiers (mf/use-var nil)
@ -252,7 +280,6 @@
(mf/use-layout-effect
(mf/deps transforms)
(fn []
(let [curr-shapes-set (into #{} (map :id) shapes)
prev-shapes-set (into #{} (map :id) @prev-shapes)
@ -266,7 +293,7 @@
(update-transform! node shapes transforms modifiers))
(when (d/not-empty? removed-shapes)
(remove-transform! node @prev-shapes)))
(remove-transform! node removed-shapes)))
(reset! prev-modifiers modifiers)
(reset! prev-transforms transforms)

View file

@ -6,7 +6,10 @@
(ns app.main.ui.workspace.shapes.path.common
(:require
[app.common.data.macros :as dm]
[app.main.data.workspace.path.state :as pst]
[app.main.refs :as refs]
[app.main.store :as st]
[okulary.core :as l]
[rumext.v2 :as mf]))
@ -17,10 +20,11 @@
(def gray-color "var(--color-gray-20)")
(def current-edit-path-ref
(let [selfn (fn [local]
(let [id (:edition local)]
(get-in local [:edit-path id])))]
(l/derived selfn refs/workspace-local)))
(l/derived
(fn [state]
(let [id (pst/get-path-id state)]
(dm/get-in state [:workspace-local :edit-path id])))
st/state))
(defn make-edit-path-ref [id]
(mf/use-memo

View file

@ -327,14 +327,15 @@
[:g.path-node {:key (dm/str index "-" (:x position) "-" (:y position))}
[:g.point-handlers {:pointer-events (when (= edit-mode :draw) "none")}
(for [[index prefix] pos-handlers]
(let [handler-position (upc/handler->point content index prefix)
handler-hover? (contains? hover-handlers [index prefix])
(for [[hindex prefix] pos-handlers]
(let [handler-position (upc/handler->point content hindex prefix)
handler-hover? (contains? hover-handlers [hindex prefix])
moving-handler? (= handler-position moving-handler)
matching-handler? (matching-handler? content position pos-handlers)]
[:& path-handler {:point position
[:& path-handler {:key (dm/str (dm/str index "-" (:x position) "-" (:y position)) "-" hindex "-" (d/name prefix))
:point position
:handler handler-position
:index index
:index hindex
:prefix prefix
:zoom zoom
:hover? handler-hover?

View file

@ -12,6 +12,7 @@
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.text :as txt]
[app.common.types.component :as ctk]
[app.config :as cf]
[app.main.data.events :as ev]
[app.main.data.modal :as modal]
@ -434,7 +435,7 @@
:on-drag-over on-drag-over
:on-drop on-drop}
[:& component-svg {:group (get-in component [:objects (:id component)])
[:& component-svg {:root-shape (ctk/get-component-root component)
:objects (:objects component)}]
(let [renaming? (= renaming (:id component))]
[:*

View file

@ -44,7 +44,7 @@
shape (gsh/transform-shape shape modifiers)]
[:*
(case (:type shape)
:frame [:& frame/options {:shape shape}]
:frame [:& frame/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}]
:group [:& group/options {:shape shape :shape-with-children shapes-with-children :file-id file-id :shared-libs shared-libs}]
:text [:& text/options {:shape shape :file-id file-id :shared-libs shared-libs}]
:rect [:& rect/options {:shape shape}]

View file

@ -36,6 +36,7 @@
main-instance? (if components-v2
(:main-instance? values)
true)
main-component? (:main-instance? values)
local-component? (= library-id current-file-id)
workspace-data (deref refs/workspace-data)
workspace-libraries (deref refs/workspace-libraries)
@ -101,7 +102,7 @@
[:& context-menu {:on-close on-menu-close
:show (:menu-open @local)
:options
(if main-instance?
(if main-component?
[[(tr "workspace.shape.menu.show-in-assets") do-show-in-assets]]
(if local-component?
(if is-dangling?

View file

@ -6,9 +6,12 @@
(ns app.main.ui.workspace.sidebar.options.shapes.frame
(:require
[app.common.data :as d]
[app.common.types.shape.layout :as ctl]
[app.main.refs :as refs]
[app.main.ui.workspace.sidebar.options.menus.blur :refer [blur-menu]]
[app.main.ui.workspace.sidebar.options.menus.color-selection :refer [color-selection-menu]]
[app.main.ui.workspace.sidebar.options.menus.component :refer [component-attrs component-menu]]
[app.main.ui.workspace.sidebar.options.menus.constraints :refer [constraint-attrs constraints-menu]]
[app.main.ui.workspace.sidebar.options.menus.fill :refer [fill-attrs-shape fill-menu]]
[app.main.ui.workspace.sidebar.options.menus.frame-grid :refer [frame-grid]]
@ -21,16 +24,17 @@
[rumext.v2 :as mf]))
(mf/defc options
[{:keys [shape] :as props}]
[{:keys [shape file-id shape-with-children shared-libs] :as props}]
(let [ids [(:id shape)]
type (:type shape)
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
stroke-values (select-keys shape stroke-attrs)
layer-values (select-keys shape layer-attrs)
measure-values (select-measure-keys shape)
constraint-values (select-keys shape constraint-attrs)
layout-container-values (select-keys shape layout-container-flex-attrs)
layout-item-values (select-keys shape layout-item-attrs)
[comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)]
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref)
@ -40,6 +44,9 @@
:values measure-values
:type type
:shape shape}]
[:& component-menu {:ids comp-ids
:values comp-values
:shape-name (:name shape)}]
(when (not is-layout-child?)
[:& constraints-menu {:ids ids
:values constraint-values}])
@ -63,6 +70,11 @@
[:& stroke-menu {:ids ids
:type type
:values stroke-values}]
(when (> (count objects) 2)
[:& color-selection-menu {:type type
:shapes (vals objects)
:file-id file-id
:shared-libs shared-libs}])
[:& shadow-menu {:ids ids
:values (select-keys shape [:shadow])}]
[:& blur-menu {:ids ids

View file

@ -106,9 +106,7 @@
on-toggle-snap
(mf/use-callback
(fn [_]
(st/emit! (drp/toggle-snap))))
]
(st/emit! (drp/toggle-snap))))]
[:div.path-actions
[:div.viewport-actions-group

View file

@ -22,6 +22,7 @@
[app.main.ui.workspace.viewport.path-actions :refer [path-actions]]
[app.main.ui.workspace.viewport.utils :as vwu]
[app.util.dom :as dom]
[app.util.timers :as ts]
[debug :refer [debug?]]
[rumext.v2 :as mf]))
@ -49,12 +50,13 @@
(mf/defc viewport-actions
{::mf/wrap [mf/memo]}
[]
(let [edition (mf/deref refs/selected-edition)
selected (mf/deref refs/selected-objects)
shape (-> selected first)]
(when (and (= (count selected) 1)
(= (:id shape) edition)
(not= :text (:type shape)))
(let [edition (mf/deref refs/selected-edition)
selected (mf/deref refs/selected-objects)
drawing (mf/deref refs/workspace-drawing)
drawing-obj (:object drawing)
shape (or drawing-obj (-> selected first))]
(when (or (and (= (count selected) 1) (= (:id shape) edition) (not= :text (:type shape)))
(and (some? drawing-obj) (= :path (:type drawing-obj))))
[:div.viewport-actions
[:& path-actions {:shape shape}]])))
@ -86,7 +88,8 @@
(mf/defc frame-title
{::mf/wrap [mf/memo]}
{::mf/wrap [mf/memo
#(mf/deferred % ts/raf)]}
[{:keys [frame selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}]
(let [workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
on-mouse-down

View file

@ -82,7 +82,7 @@
grid-y-data (get-grids-snap-points frame :y)]
(cond-> page-data
(not (ctl/layout-child? objects frame))
(not (ctl/layout-descent? objects frame))
(-> ;; Update root frame information
(assoc-in [uuid/zero :objects-data frame-id] frame-data)
@ -106,7 +106,7 @@
:id (:id shape)
:pt %)))]
(cond-> page-data
(not (ctl/layout-child? objects shape))
(not (ctl/layout-descent? objects shape))
(-> (assoc-in [frame-id :objects-data (:id shape)] shape-data)
(update-in [frame-id :x] (make-insert-tree-data shape-data :x))
(update-in [frame-id :y] (make-insert-tree-data shape-data :y))))))

View file

@ -87,7 +87,7 @@
:obj shape}]))))
(defn group-shapes
([state label ids] (group-shapes state label ids "Group-1"))
([state label ids] (group-shapes state label ids "Group"))
([state label ids prefix]
(let [page (current-page state)
shapes (dwg/shapes-for-grouping (:objects page) ids)]

View file

@ -55,12 +55,12 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1* ---> Rect 1 (color, opacity)
; #{:fill-group}
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
(let [[[group shape1] [c-group c-shape1] component]
@ -68,14 +68,14 @@
new-state
(thp/id :instance1))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:touched shape1) #{:fill-group}))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:fill-opacity shape1) 0.5))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:touched c-shape1) nil))
@ -110,13 +110,13 @@
;
; [Page]
; Root Frame
; Rect 1-1* #--> Rect 1-1
; Rect 1 * #--> Rect 1
; #{:shapes-group}
; Circle 1
; Rect 1 ---> Rect 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
(let [[[group shape1 shape2] [c-group c-shape1] component]
@ -124,7 +124,7 @@
new-state
(thp/id :instance1))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) #{:shapes-group}))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -133,7 +133,7 @@
(t/is (= (:touched shape2) nil))
(t/is (not= (:shape-ref shape2) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:shape-ref c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
@ -305,7 +305,7 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> <Library 1> Rect 1-1
; Rect 1 #--> <Library 1> Rect 1
; Rect 1* ---> <Library 1> Rect 1 (color, opacity)
; #{:fill-group}
;
@ -314,14 +314,14 @@
new-state
(thp/id :instance2))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:touched shape1) #{:fill-group}))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:fill-opacity shape1) 0.5))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:touched c-shape1) nil))
@ -367,19 +367,19 @@
;
; [Page]
; Root Frame
; Group-1* #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group * #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1* ---> Circle 1 (color, opacity)
; #{:fill-group}
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1
;
@ -391,9 +391,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) #{:fill-group}))
@ -404,9 +404,9 @@
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -456,19 +456,19 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1* ---> Rect 1 (color, opacity)
; #{:fill-group}
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1
;
@ -480,9 +480,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -493,9 +493,9 @@
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:fill-opacity shape2) 0.5))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -545,18 +545,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1* ---> Rect 1 (color, opacity)
; #{:fill-group}
; Circle 1
@ -569,9 +569,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -582,9 +582,9 @@
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:fill-opacity shape2) 0.5))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -628,7 +628,7 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1
;
; [Rect 1]
@ -640,14 +640,14 @@
new-state
(:id instance1))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/white))
(t/is (= (:fill-opacity shape1) 1))
(t/is (= (:touched shape1) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/white))
@ -683,11 +683,11 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
(let [[[group shape1] [c-group c-shape1] component]
@ -695,14 +695,14 @@
new-state
(thp/id :instance1))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (not= (:shape-ref group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:touched shape1) nil))
(t/is (not= (:shape-ref shape1) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:shape-ref c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
@ -881,7 +881,7 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> <Library 1> Rect 1-1
; Rect 1 #--> <Library 1> Rect 1
; Rect 1 ---> <Library 1> Rect 1
;
(let [[[group shape1] [c-group c-shape1] component]
@ -889,14 +889,14 @@
new-state
(:id instance2))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/white))
(t/is (= (:fill-opacity shape1) 1))
(t/is (= (:touched shape1) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/white))
@ -943,18 +943,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1
;
@ -964,11 +964,11 @@
new-state
(thp/id :instance2))]
; TODO: get and check the instance inside component [Group-1]
; TODO: get and check the instance inside component [Group]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -979,9 +979,9 @@
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -1032,18 +1032,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1 (color, opacity)
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1
;
@ -1053,11 +1053,11 @@
new-state
(thp/id :instance2))]
; TODO: get and check the instance inside component [Group-1]
; TODO: get and check the instance inside component [Group]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -1068,9 +1068,9 @@
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -1122,18 +1122,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; #{:fill-group}
; Circle 1
@ -1146,9 +1146,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -1159,9 +1159,9 @@
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -1209,13 +1209,13 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Rect 1-2
; Rect 1 ---> Rect 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1 (color, opacity)
;
(let [[[instance1 shape1] [c-instance1 c-shape1] component1]
@ -1228,21 +1228,21 @@
new-state
(:id instance2))]
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:fill-opacity shape1) 0.5))
(t/is (= (:touched shape1) nil))
(t/is (= (:name instance2) "Rect 1-2"))
(t/is (= (:name instance2) "Rect 1"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:touched shape2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/test))
@ -1289,13 +1289,13 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Rect 1-2 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1 (color, opacity)
;
(let [[[instance1 shape1] [c-instance1 c-shape1] component1]
@ -1308,21 +1308,21 @@
new-state
(:id instance2))]
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:fill-opacity shape1) 0.5))
(t/is (= (:touched shape1) nil))
(t/is (= (:name instance2) "Rect 1-2"))
(t/is (= (:name instance2) "Rect 1"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:fill-opacity shape2) 0.5))
(t/is (= (:touched shape2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/test))
@ -1375,9 +1375,9 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1 ---> Rect 1 (color, stroke)
; Rect 1-2 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Rect 1* ---> Rect 1 (color, stroke2)
; #{:stroke-group}
;
@ -1395,21 +1395,21 @@
new-state
(:id instance2))]
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:stroke-width shape1) 0.5))
(t/is (= (:touched shape1) nil))
(t/is (= (:name instance2) "Rect 1-2"))
(t/is (= (:name instance2) "Rect 1"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name shape2) "Rect 1"))
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:stroke-width shape2) 0.2))
(t/is (= (:touched shape2) #{:stroke-group}))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/test))
@ -1452,12 +1452,12 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> Rect 1-1
; Rect 1 #--> Rect 1
; Circle 1 ---> Circle 1
; Rect 1 ---> Rect 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Circle 1
; Rect 1
;
@ -1467,7 +1467,7 @@
new-state
(thp/id :instance1))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (not= (:shape-ref group) nil))
(t/is (= (:name shape1) "Circle 1"))
@ -1477,7 +1477,7 @@
(t/is (= (:touched shape2) nil))
(t/is (not= (:shape-ref shape2) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:shape-ref c-group) nil))
(t/is (= (:name c-shape1) "Circle 1"))
@ -1654,7 +1654,7 @@
;
; [Page]
; Root Frame
; Rect 1-1 #--> <Library 1> Rect 1-1 (color, opacity)
; Rect 1 #--> <Library 1> Rect 1 (color, opacity)
; Rect 1 ---> <Library 1> Rect 1
;
(let [[[group shape1] [c-group c-shape1] component]
@ -1662,14 +1662,14 @@
new-state
(:id instance2))]
(t/is (= (:name group) "Rect 1-1"))
(t/is (= (:name group) "Rect 1"))
(t/is (= (:touched group) nil))
(t/is (= (:name shape1) "Rect 1"))
(t/is (= (:fill-color shape1) clr/test))
(t/is (= (:fill-opacity shape1) 0.5))
(t/is (= (:touched shape1) nil))
(t/is (= (:name c-group) "Rect 1-1"))
(t/is (= (:name c-group) "Rect 1"))
(t/is (= (:touched c-group) nil))
(t/is (= (:name c-shape1) "Rect 1"))
(t/is (= (:fill-color c-shape1) clr/test))
@ -1716,18 +1716,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1 ---> Circle 1 (color, opacity)
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1 (color, opacity)
;
@ -1739,9 +1739,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -1752,9 +1752,9 @@
(t/is (= (:fill-color shape2) clr/white))
(t/is (= (:fill-opacity shape2) 1))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -1805,18 +1805,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Circle 1
;
@ -1828,9 +1828,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -1841,9 +1841,9 @@
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:fill-opacity shape2) 0.5))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))
@ -1895,18 +1895,18 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect 1-1 @--> Rect 1-1
; Group #--> Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1 (color, opacity)
; Circle 1 ---> Circle 1
;
; [Rect 1]
; Rect 1-1
; Rect 1
; Rect 1 (color, opacity)
;
; [Group-1]
; Group-1
; Rect 1-1 @--> Rect 1-1
; [Group]
; Group
; Rect 1 @--> Rect 1
; Rect 1 ---> Rect 1
; Circle 1
;
@ -1918,9 +1918,9 @@
; TODO: get and check the instance inside component [Group-1]
(t/is (= (:name instance2) "Group-1"))
(t/is (= (:name instance2) "Group"))
(t/is (= (:touched instance2) nil))
(t/is (= (:name instance1) "Rect 1-1"))
(t/is (= (:name instance1) "Rect 1"))
(t/is (= (:touched instance1) nil))
(t/is (= (:name shape1) "Circle 1"))
(t/is (= (:touched shape1) nil))
@ -1931,9 +1931,9 @@
(t/is (= (:fill-color shape2) clr/test))
(t/is (= (:fill-opacity shape2) 0.5))
(t/is (= (:name c-instance2) "Group-1"))
(t/is (= (:name c-instance2) "Group"))
(t/is (= (:touched c-instance2) nil))
(t/is (= (:name c-instance1) "Rect 1-1"))
(t/is (= (:name c-instance1) "Rect 1"))
(t/is (= (:touched c-instance1) nil))
(t/is (= (:name c-shape1) "Circle 1"))
(t/is (= (:touched c-shape1) nil))

View file

@ -43,11 +43,11 @@
;
; [Page]
; Root Frame
; Rect-2 #--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-2]
; Rect-2
; [Rect-1]
; Rect-1
; Rect-1
;
(let [shape1 (thp/get-shape new-state :shape1)
@ -60,10 +60,10 @@
file (wsh/get-local-file new-state)]
(t/is (= (:name shape1) "Rect-1"))
(t/is (= (:name group) "Rect-2"))
(t/is (= (:name component) "Rect-2"))
(t/is (= (:name group) "Rect-1"))
(t/is (= (:name component) "Rect-1"))
(t/is (= (:name c-shape1) "Rect-1"))
(t/is (= (:name c-group) "Rect-2"))
(t/is (= (:name c-group) "Rect-1"))
(thl/is-from-file group file))))]
@ -179,12 +179,12 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Group #--> Group
; Rect-1 ---> Rect-1
; Rect-2 ---> Rect-2
;
; [Group-1]
; Group-1
; [Group]
; Group
; Rect-1
; Rect-2
;
@ -199,11 +199,11 @@
(t/is (= (:name shape1) "Rect-1"))
(t/is (= (:name shape2) "Rect-2"))
(t/is (= (:name group) "Group-1"))
(t/is (= (:name component) "Group-1"))
(t/is (= (:name group) "Group"))
(t/is (= (:name component) "Group"))
(t/is (= (:name c-shape1) "Rect-1"))
(t/is (= (:name c-shape2) "Rect-2"))
(t/is (= (:name c-group) "Group-1"))
(t/is (= (:name c-group) "Group"))
(thl/is-from-file group file))))]
@ -229,17 +229,17 @@
;
; [Page]
; Root Frame
; Rect-3 #--> Rect-3
; Rect-2 @--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-2]
; Rect-2
; [Rect-1]
; Rect-1
; Rect-1
;
; [Rect-2]
; Rect-3
; Rect-2 @--> Rect-2
; [Rect-1]
; Rect-1
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
(let [[[instance1 shape1]
@ -258,18 +258,18 @@
(:parent-id instance1))]
(t/is (= (:name shape1) "Rect-1"))
(t/is (= (:name instance1) "Rect-2"))
(t/is (= (:name component1) "Rect-2"))
(t/is (= (:name instance1) "Rect-1"))
(t/is (= (:name component1) "Rect-1"))
(t/is (= (:name c-shape1) "Rect-1"))
(t/is (= (:name c-instance1) "Rect-2"))
(t/is (= (:name c-instance1) "Rect-1"))
(t/is (= (:name shape1') "Rect-1"))
(t/is (= (:name instance1') "Rect-2"))
(t/is (= (:name instance2) "Rect-3"))
(t/is (= (:name component2) "Rect-3"))
(t/is (= (:name instance1') "Rect-1"))
(t/is (= (:name instance2) "Rect-1"))
(t/is (= (:name component2) "Rect-1"))
(t/is (= (:name c-shape1') "Rect-1"))
(t/is (= (:name c-instance1') "Rect-2"))
(t/is (= (:name c-instance2) "Rect-3")))))]
(t/is (= (:name c-instance1') "Rect-1"))
(t/is (= (:name c-instance2) "Rect-1")))))]
(ptk/emit!
store
@ -332,15 +332,15 @@
;
; [Page]
; Root Frame
; Rect-2 #--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-1]
; Rect-2
; Rect-1
; Rect-1
;
; [Rect-3]
; Rect-2
; [Rect-1]
; Rect-1
; Rect-1
;
(let [new-component-id (->> (get-in new-state
@ -363,7 +363,7 @@
new-state
new-component-id)]
(t/is (= (:name component2) "Rect-3")))))]
(t/is (= (:name component2) "Rect-1")))))]
(ptk/emit!
store
@ -434,13 +434,13 @@
;
; [Page]
; Root Frame
; Rect-2 #--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 ---> Rect-1
; Rect-3 #--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-2]
; Rect-2
; [Rect-1]
; Rect-1
; Rect-1
;
(let [new-instance-id (-> new-state
@ -456,9 +456,9 @@
(t/is (not= (:id instance1) (:id instance2)))
(t/is (= (:id component) component-id))
(t/is (= (:name instance2) "Rect-3"))
(t/is (= (:name instance2) "Rect-1"))
(t/is (= (:name shape2) "Rect-1"))
(t/is (= (:name c-instance2) "Rect-2"))
(t/is (= (:name c-instance2) "Rect-1"))
(t/is (= (:name c-shape2) "Rect-1"))
(t/is (= (:component-file instance2)
thp/current-file-id)))))]
@ -491,7 +491,7 @@
;
; [Page]
; Root Frame
; Rect-2 #--> <Library 1> Rect-2
; Rect-1 #--> <Library 1> Rect-1
; Rect-1 ---> <Library 1> Rect-1
;
(let [new-instance-id (-> new-state
@ -506,9 +506,9 @@
new-instance-id)]
(t/is (= (:id component) component-id))
(t/is (= (:name instance2) "Rect-2"))
(t/is (= (:name instance2) "Rect-1"))
(t/is (= (:name shape2) "Rect-1"))
(t/is (= (:name c-instance2) "Rect-2"))
(t/is (= (:name c-instance2) "Rect-1"))
(t/is (= (:name c-shape2) "Rect-1"))
(t/is (= (:component-file instance2) library-id)))))]
@ -576,17 +576,17 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect-2 @--> Rect-2
; Group #--> Group
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-1]
; Rect-2
; Rect-1
; Rect-1
;
; [Group-1]
; Group-1
; Rect-2 @--> Rect-2
; [Group]
; Group
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
(let [page (thp/current-page new-state)
@ -600,12 +600,12 @@
new-state
(:parent-id parent1))]
(t/is (= (:name group) "Group-1"))
(t/is (= (:name shape1) "Rect-2"))
(t/is (= (:name group) "Group"))
(t/is (= (:name shape1) "Rect-1"))
(t/is (= (:name shape2) "Rect-1"))
(t/is (= (:name component) "Group-1"))
(t/is (= (:name c-group) "Group-1"))
(t/is (= (:name c-shape1) "Rect-2"))
(t/is (= (:name component) "Group"))
(t/is (= (:name c-group) "Group"))
(t/is (= (:name c-shape1) "Rect-1"))
(t/is (= (:name c-shape2) "Rect-1")))))]
(ptk/emit!
@ -641,20 +641,20 @@
;
; [Page]
; Root Frame
; Rect-2 #--> Rect-2
; Rect-2 @--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
; Rect-3 #--> Rect-2
; Rect-2 @--> Rect-2
; Rect-1 #--> Rect-1
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
; [Rect-1]
; Rect-2
; Rect-1
; Rect-1
;
; [Rect-2]
; Rect-2
; Rect-2 @--> Rect-2
; [Rect-1]
; Rect-1
; Rect-1 @--> Rect-1
; Rect-1 ---> Rect-1
;
(let [new-instance-id (-> new-state
@ -672,11 +672,11 @@
(t/is (not= (:id instance1) (:id instance3)))
(t/is (= (:id component) component-id))
(t/is (= (:name instance3) "Rect-3"))
(t/is (= (:name shape3) "Rect-2"))
(t/is (= (:name instance3) "Rect-1"))
(t/is (= (:name shape3) "Rect-1"))
(t/is (= (:name shape4) "Rect-1"))
(t/is (= (:name c-instance3) "Rect-2"))
(t/is (= (:name c-shape3) "Rect-2"))
(t/is (= (:name c-instance3) "Rect-1"))
(t/is (= (:name c-shape3) "Rect-1"))
(t/is (= (:name c-shape4) "Rect-1")))))]
(ptk/emit!
@ -710,13 +710,13 @@
;
; [Page]
; Root Frame
; Group-1 #--> Group-1
; Rect-2 @--> <Library 1> Rect-2
; Group #--> Group
; Rect-1 @--> <Library 1> Rect-1
; Rect-1 ---> <Library 1> Rect-1
;
; [Group-1]
; Group-1
; Rect-2 @--> <Library 1> Rect-2
; [Group]
; Group
; Rect-1 @--> <Library 1> Rect-1
; Rect-1 ---> <Library 1> Rect-1
;
(let [instance2 (thp/get-shape new-state :instance2)
@ -726,11 +726,11 @@
new-state
(:parent-id instance2))]
(t/is (= (:name group1) "Group-1"))
(t/is (= (:name shape1) "Rect-2"))
(t/is (= (:name group1) "Group"))
(t/is (= (:name shape1) "Rect-1"))
(t/is (= (:name shape2) "Rect-1"))
(t/is (= (:name c-group1) "Group-1"))
(t/is (= (:name c-shape1) "Rect-2"))
(t/is (= (:name c-group1) "Group"))
(t/is (= (:name c-shape1) "Rect-1"))
(t/is (= (:name c-shape2) "Rect-1"))
(t/is (= (:component-file group1) thp/current-file-id))
(t/is (= (:component-file shape1) library-id))