0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 16:21:57 -05:00

♻️ Refactor common.page.helpers namespace.

This commit is contained in:
Andrey Antukh 2022-02-07 12:37:54 +01:00 committed by Andrés Moya
parent 24724e3340
commit a1da4d4233
55 changed files with 1235 additions and 1348 deletions

View file

@ -7,7 +7,7 @@
(ns app.rpc.queries.files
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.pages.migrations :as pmg]
[app.common.spec :as us]
[app.common.uuid :as uuid]
@ -242,13 +242,10 @@
(defn- trim-file-data
[file {:keys [page-id object-id]}]
(let [page (get-in file [:data :pages-index page-id])
objects (->> (:objects page)
(cp/get-object-with-children object-id)
(map #(dissoc % :thumbnail)))
objects (d/index-by :id objects)
objects (->> (cph/get-children-with-self (:objects page) object-id)
(map #(dissoc % :thumbnail))
(d/index-by :id))
page (assoc page :objects objects)]
(-> file
(update :data assoc :pages-index {page-id page})
(update :data assoc :pages [page-id]))))

View file

@ -10,7 +10,6 @@
[app.common.data :as d]
[app.common.pages.changes :as changes]
[app.common.pages.common :as common]
[app.common.pages.helpers :as helpers]
[app.common.pages.indices :as indices]
[app.common.pages.init :as init]))
@ -20,55 +19,6 @@
(d/export common/default-color)
(d/export common/component-sync-attrs)
;; Helpers
(d/export helpers/walk-pages)
(d/export helpers/select-objects)
(d/export helpers/update-object-list)
(d/export helpers/get-component-shape)
(d/export helpers/get-root-shape)
(d/export helpers/make-container)
(d/export helpers/page?)
(d/export helpers/component?)
(d/export helpers/get-container)
(d/export helpers/get-shape)
(d/export helpers/get-component)
(d/export helpers/is-main-of)
(d/export helpers/get-component-root)
(d/export helpers/get-children)
(d/export helpers/get-children-objects)
(d/export helpers/get-object-with-children)
(d/export helpers/select-children)
(d/export helpers/is-shape-grouped)
(d/export helpers/get-parent)
(d/export helpers/get-parents)
(d/export helpers/get-frame)
(d/export helpers/clean-loops)
(d/export helpers/calculate-invalid-targets)
(d/export helpers/valid-frame-target)
(d/export helpers/position-on-parent)
(d/export helpers/insert-at-index)
(d/export helpers/append-at-the-end)
(d/export helpers/select-toplevel-shapes)
(d/export helpers/select-frames)
(d/export helpers/clone-object)
(d/export helpers/indexed-shapes)
(d/export helpers/expand-region-selection)
(d/export helpers/frame-id-by-position)
(d/export helpers/set-touched-group)
(d/export helpers/touched-group?)
(d/export helpers/get-base-shape)
(d/export helpers/is-parent?)
(d/export helpers/get-index-in-parent)
(d/export helpers/split-path)
(d/export helpers/join-path)
(d/export helpers/parse-path-name)
(d/export helpers/merge-path-item)
(d/export helpers/compact-path)
(d/export helpers/compact-name)
(d/export helpers/unframed-shape?)
(d/export helpers/children-seq)
;; Indices
(d/export indices/calculate-z-index)
(d/export indices/update-z-index)

View file

@ -160,7 +160,7 @@
(let [lookup (d/getf objects)
update-fn #(d/update-when %1 %2 update-group %1)
xform (comp
(mapcat #(cons % (cph/get-parents % objects)))
(mapcat #(cons % (cph/get-parent-ids objects %)))
(filter #(contains? #{:group :bool} (-> % lookup :type)))
(distinct))]
@ -202,11 +202,16 @@
(defmethod process-change :mov-objects
[data {:keys [parent-id shapes index page-id component-id ignore-touched]}]
(letfn [(is-valid-move? [objects shape-id]
(let [invalid-targets (cph/calculate-invalid-targets shape-id objects)]
(letfn [(calculate-invalid-targets [objects shape-id]
(let [reduce-fn #(into %1 (calculate-invalid-targets objects %2))]
(->> (get-in objects [shape-id :shapes])
(reduce reduce-fn #{shape-id}))))
(is-valid-move? [objects shape-id]
(let [invalid-targets (calculate-invalid-targets objects shape-id)]
(and (contains? objects shape-id)
(not (invalid-targets parent-id))
(cph/valid-frame-target shape-id parent-id objects))))
(cph/valid-frame-target? objects parent-id shape-id))))
(insert-items [prev-shapes index shapes]
(let [prev-shapes (or prev-shapes [])]

View file

@ -7,8 +7,7 @@
(ns app.common.pages.changes-builder
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.helpers :as h]))
[app.common.pages.helpers :as cph]))
;; Auxiliary functions to help create a set of changes (undo + redo)
@ -78,7 +77,7 @@
:page-id (::page-id (meta changes))
:parent-id (:parent-id shape)
:shapes [(:id shape)]
:index (cp/position-on-parent (:id shape) objects)}))]
:index (cph/get-position-on-parent objects (:id shape))}))]
(-> changes
(update :redo-changes conj set-parent-change)
@ -171,7 +170,7 @@
:page-id page-id
:parent-id (:parent-id shape)
:shapes [id]
:index (h/position-on-parent id objects)
:index (cph/get-position-on-parent objects id)
:ignore-touched true})))]
(-> changes

View file

@ -9,43 +9,234 @@
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.spec :as us]
[app.common.spec.interactions :as cti]
[app.common.spec.page :as spec.page]
[app.common.uuid :as uuid]
[cuerdas.core :as str]))
(defn walk-pages
"Go through all pages of a file and apply a function to each one"
;; The function receives two parameters (page-id and page), and
;; returns the updated page.
[f data]
(update data :pages-index #(d/mapm f %)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GENERIC SHAPE SELECTORS AND PREDICATES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn select-objects
"Get a list of all objects in a container (a page or a component) that
satisfy a condition"
[f container]
(filter f (vals (get container :objects))))
(defn ^boolean root-frame?
[{:keys [id type]}]
(and (= type :frame)
(= id uuid/zero)))
(defn update-object-list
"Update multiple objects in a page at once"
[page objects-list]
(update page :objects
#(into % (d/index-by :id objects-list))))
(defn ^boolean frame-shape?
[{:keys [type]}]
(= type :frame))
(defn ^boolean group-shape?
[{:keys [type]}]
(= type :group))
(defn ^boolean text-shape?
[{:keys [type]}]
(= type :text))
(defn ^boolean unframed-shape?
"Checks if it's a non-frame shape in the top level."
[shape]
(and (not (frame-shape? shape))
(= (:frame-id shape) uuid/zero)))
(defn get-shape
[container shape-id]
(us/assert ::spec.page/container container)
(us/assert ::us/uuid shape-id)
(-> container
(get :objects)
(get shape-id)))
(defn get-children-ids
[objects id]
(if-let [shapes (-> (get objects id) :shapes (some-> vec))]
(into shapes (mapcat #(get-children-ids objects %)) shapes)
[]))
(defn get-children
[objects id]
(mapv (d/getf objects) (get-children-ids objects id)))
(defn get-children-with-self
[objects id]
(let [lookup (d/getf objects)]
(into [(lookup id)] (map lookup) (get-children-ids objects id))))
(defn get-parent
"Retrieve the id of the parent for the shape-id (if exists)"
[objects id]
(let [lookup (d/getf objects)]
(-> id lookup :parent-id lookup)))
(defn get-parent-id
"Retrieve the id of the parent for the shape-id (if exists)"
[objects id]
(-> objects (get id) :parent-id))
(defn get-parent-ids
"Returns a vector of parents of the specified shape."
[objects shape-id]
(loop [result [] id shape-id]
(if-let [parent-id (->> id (get objects) :parent-id)]
(recur (conj result parent-id) parent-id)
result)))
(defn get-frame
"Get the frame that contains the shape. If the shape is already a
frame, get itself. If no shape is provided, returns the root frame."
([objects]
(get objects uuid/zero))
([objects shape-or-id]
(cond
(map? shape-or-id)
(if (frame-shape? shape-or-id)
shape-or-id
(get objects (:frame-id shape-or-id)))
(= uuid/zero shape-or-id)
(get objects uuid/zero)
:else
(some->> shape-or-id
(get objects)
(get-frame objects)))))
(defn valid-frame-target?
[objects parent-id shape-id]
(let [shape (get objects shape-id)]
(or (not (frame-shape? shape))
(= parent-id uuid/zero))))
(defn get-position-on-parent
[objects id]
(let [obj (get objects id)
pid (:parent-id obj)
prt (get objects pid)]
(d/index-of (:shapes prt) id)))
(defn get-immediate-children
"Retrieve resolved shape objects that are immediate children
of the specified shape-id"
([objects] (get-immediate-children objects uuid/zero))
([objects shape-id]
(let [lookup (d/getf objects)]
(->> (lookup shape-id)
(:shapes)
(keep lookup)))))
(defn get-frames
"Retrieves all frame objects as vector. It is not implemented in
function of `get-immediate-children` for performance reasons. This
function is executed in the render hot path."
[objects]
(let [lookup (d/getf objects)
xform (comp (keep lookup)
(filter frame-shape?))]
(->> (:shapes (lookup uuid/zero))
(into [] xform))))
(defn frame-id-by-position
[objects position]
(let [frames (get-frames objects)]
(or
(->> frames
(reverse)
(d/seek #(and position (gsh/has-point? % position)))
:id)
uuid/zero)))
(declare indexed-shapes)
(defn get-base-shape
"Selects the shape that will be the base to add the shapes over"
[objects selected]
(let [;; Gets the tree-index for all the shapes
indexed-shapes (indexed-shapes objects)
;; Filters the selected and retrieve a list of ids
sorted-ids (->> indexed-shapes
(filter (comp selected second))
(map second))]
;; The first id will be the top-most
(get objects (first sorted-ids))))
(defn is-parent?
"Check if `parent-candidate` is parent of `shape-id`"
[objects shape-id parent-candidate]
(loop [current (get objects parent-candidate)
done #{}
pending (:shapes current)]
(cond
(contains? done (:id current))
(recur (get objects (first pending))
done
(rest pending))
(empty? pending) false
(and current (contains? (set (:shapes current)) shape-id)) true
:else
(recur (get objects (first pending))
(conj done (:id current))
(concat (rest pending) (:shapes current))))))
(defn get-index-in-parent
"Retrieves the index in the parent"
[objects shape-id]
(let [shape (get objects shape-id)
parent (get objects (:parent-id shape))
[parent-idx _] (d/seek (fn [[_idx child-id]] (= child-id shape-id))
(d/enumerate (:shapes parent)))]
parent-idx))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COMPONENTS HELPERS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn set-touched-group
[touched group]
(conj (or touched #{}) group))
(defn touched-group?
[shape group]
((or (:touched shape) #{}) group))
(defn get-component
"Retrieve a component from libraries, if no library-id is provided, we
iterate over all libraries and find the component on it."
([libraries component-id]
(some #(-> % :components (get component-id)) (vals libraries)))
([libraries library-id component-id]
(get-in libraries [library-id :components component-id])))
(defn ^boolean is-main-of?
[shape-main shape-inst]
(and (:shape-ref shape-inst)
(or (= (:shape-ref shape-inst) (:id shape-main))
(= (:shape-ref shape-inst) (:shape-ref shape-main)))))
(defn get-component-root
[component]
(get-in component [:objects (:id component)]))
(defn get-component-shape
"Get the parent shape linked to a component for this shape, if any"
[shape objects]
[objects shape]
(if-not (:shape-ref shape)
nil
(if (:component-id shape)
shape
(if-let [parent-id (:parent-id shape)]
(get-component-shape (get objects parent-id) objects)
(get-component-shape objects (get objects parent-id))
nil))))
(defn get-root-shape
"Get the root shape linked to a component for this shape, if any"
[shape objects]
"Get the root shape linked to a component for this shape, if any."
[objects shape]
(cond
(some? (:component-root? shape))
@ -57,12 +248,10 @@
(defn make-container
[page-or-component type]
(assoc page-or-component
:type type))
(assoc page-or-component :type type))
(defn page?
[container]
(us/assert some? (:type container))
(= (:type container) :page))
(defn component?
@ -70,120 +259,32 @@
(= (:type container) :component))
(defn get-container
[id type local-file]
(assert (some? type))
[file type id]
(us/assert map? file)
(us/assert keyword? type)
(us/assert uuid? id)
(-> (if (= type :page)
(get-in local-file [:pages-index id])
(get-in local-file [:components id]))
(get-in file [:pages-index id])
(get-in file [:components id]))
(assoc :type type)))
(defn get-shape
[container shape-id]
(get-in container [:objects shape-id]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ALGORITHMS & TRANSFORMATIONS FOR SHAPES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn get-component
[component-id library-id local-library libraries]
(assert (some? (:id local-library)))
(let [file (if (= library-id (:id local-library))
local-library
(get-in libraries [library-id :data]))]
(get-in file [:components component-id])))
(defn walk-pages
"Go through all pages of a file and apply a function to each one"
;; The function receives two parameters (page-id and page), and
;; returns the updated page.
[f data]
(update data :pages-index #(d/mapm f %)))
(defn is-main-of
[shape-main shape-inst]
(and (:shape-ref shape-inst)
(or (= (:shape-ref shape-inst) (:id shape-main))
(= (:shape-ref shape-inst) (:shape-ref shape-main)))))
(defn get-component-root
[component]
(get-in component [:objects (:id component)]))
(defn get-children [id objects]
(if-let [shapes (-> (get objects id) :shapes (some-> vec))]
(into shapes (mapcat #(get-children % objects)) shapes)
[]))
(defn get-children-objects
"Retrieve all children objects recursively for a given object"
[id objects]
(mapv #(get objects %) (get-children id objects)))
(defn get-object-with-children
"Retrieve a vector with an object and all of its children"
[id objects]
(mapv #(get objects %) (cons id (get-children id objects))))
(defn select-children [id objects]
(->> (get-children id objects)
(select-keys objects)))
(defn is-shape-grouped
"Checks if a shape is inside a group"
[shape-id objects]
(let [contains-shape-fn (fn [{:keys [shapes]}] ((set shapes) shape-id))
shapes (remove #(= (:type %) :frame) (vals objects))]
(some contains-shape-fn shapes)))
(defn get-top-frame
[objects]
(get objects uuid/zero))
(defn get-parent
"Retrieve the id of the parent for the shape-id (if exists)"
[shape-id objects]
(let [obj (get objects shape-id)]
(:parent-id obj)))
(defn get-parents
[shape-id objects]
(when-let [parent-id (->> shape-id (get objects) :parent-id)]
(lazy-seq (cons parent-id (get-parents parent-id objects)))))
(defn get-frame
"Get the frame that contains the shape. If the shape is already a frame, get itself."
[shape objects]
(if (= (:type shape) :frame)
shape
(get objects (:frame-id shape))))
(defn clean-loops
"Clean a list of ids from circular references."
[objects ids]
(let [parent-selected?
(fn [id]
(let [parents (get-parents id objects)]
(some ids parents)))
add-element
(fn [result id]
(cond-> result
(not (parent-selected? id))
(conj id)))]
(reduce add-element (d/ordered-set) ids)))
(defn calculate-invalid-targets
[shape-id objects]
(let [result #{shape-id}
children (get-in objects [shape-id :shapes])
reduce-fn (fn [result child-id]
(into result (calculate-invalid-targets child-id objects)))]
(reduce reduce-fn result children)))
(defn valid-frame-target
[shape-id parent-id objects]
(let [shape (get objects shape-id)]
(or (not= (:type shape) :frame)
(= parent-id uuid/zero))))
(defn position-on-parent
[id objects]
(let [obj (get objects id)
pid (:parent-id obj)
prt (get objects pid)]
(d/index-of (:shapes prt) id)))
(defn update-object-list
"Update multiple objects in a page at once"
[page objects-list]
(update page :objects
#(into % (d/index-by :id objects-list))))
(defn insert-at-index
[objects index ids]
@ -203,41 +304,22 @@
(vec prev-ids)
ids))
(defn select-toplevel-shapes
([objects] (select-toplevel-shapes objects nil))
([objects {:keys [include-frames? include-frame-children?]
:or {include-frames? false
include-frame-children? true}}]
(defn clean-loops
"Clean a list of ids from circular references."
[objects ids]
(let [lookup #(get objects %)
root (lookup uuid/zero)
root-children (:shapes root)
(let [parent-selected?
(fn [id]
(let [parents (get-parent-ids objects id)]
(some ids parents)))
lookup-shapes
(fn [result id]
(if (nil? id)
result
(let [obj (lookup id)
typ (:type obj)
children (:shapes obj)]
add-element
(fn [result id]
(cond-> result
(not (parent-selected? id))
(conj id)))]
(cond-> result
(or (not= :frame typ) include-frames?)
(conj obj)
(and (= :frame typ) include-frame-children?)
(into (map lookup) children)))))]
(reduce lookup-shapes [] root-children))))
(defn select-frames
[objects]
(let [lookup #(get objects %)
frame? #(= :frame (:type %))
xform (comp (map lookup)
(filter frame?))]
(->> (:shapes (lookup uuid/zero))
(into [] xform))))
(reduce add-element (d/ordered-set) ids)))
(defn clone-object
"Gets a copy of the object and all its children, with new ids
@ -304,8 +386,6 @@
(reduce red-fn cur-idx (reverse (:shapes object)))))]
(into {} (rec-index '() uuid/zero))))
(defn expand-region-selection
"Given a selection selects all the shapes between the first and last in
an indexed manner (shift selection)"
@ -322,67 +402,9 @@
(map second)
(into #{}))))
(defn frame-id-by-position [objects position]
(let [frames (select-frames objects)]
(or
(->> frames
(reverse)
(d/seek #(and position (gsh/has-point? % position)))
:id)
uuid/zero)))
(defn set-touched-group
[touched group]
(conj (or touched #{}) group))
(defn touched-group?
[shape group]
((or (:touched shape) #{}) group))
(defn get-base-shape
"Selects the shape that will be the base to add the shapes over"
[objects selected]
(let [;; Gets the tree-index for all the shapes
indexed-shapes (indexed-shapes objects)
;; Filters the selected and retrieve a list of ids
sorted-ids (->> indexed-shapes
(filter (comp selected second))
(map second))]
;; The first id will be the top-most
(get objects (first sorted-ids))))
(defn is-parent?
"Check if `parent-candidate` is parent of `shape-id`"
[objects shape-id parent-candidate]
(loop [current (get objects parent-candidate)
done #{}
pending (:shapes current)]
(cond
(contains? done (:id current))
(recur (get objects (first pending))
done
(rest pending))
(empty? pending) false
(and current (contains? (set (:shapes current)) shape-id)) true
:else
(recur (get objects (first pending))
(conj done (:id current))
(concat (rest pending) (:shapes current))))))
(defn get-index-in-parent
"Retrieves the index in the parent"
[objects shape-id]
(let [shape (get objects shape-id)
parent (get objects (:parent-id shape))
[parent-idx _] (d/seek (fn [[_idx child-id]] (= child-id shape-id))
(d/enumerate (:shapes parent)))]
parent-idx))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SHAPES ORGANIZATION (PATH MANAGEMENT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn split-path
"Decompose a string in the form 'one / two / three' into
@ -442,26 +464,3 @@
[path name]
(let [path-split (split-path path)]
(merge-path-item (first path-split) name)))
(defn connected-frame?
"Check if some frame is origin or destination of any navigate interaction
in the page"
[frame-id objects]
(let [children (get-object-with-children frame-id objects)]
(or (some cti/flow-origin? (map :interactions children))
(some #(cti/flow-to? % frame-id) (map :interactions (vals objects))))))
(defn unframed-shape?
"Checks if it's a non-frame shape in the top level."
[shape]
(and (not= (:type shape) :frame)
(= (:frame-id shape) uuid/zero)))
(defn children-seq
"Creates a sequence of shapes through the objects tree"
[shape objects]
(let [getter (partial get objects)]
(tree-seq #(d/not-empty? (get shape :shapes))
#(->> (get % :shapes) (map getter))
shape)))

View file

@ -7,7 +7,7 @@
(ns app.common.pages.indices
(:require
[app.common.data :as d]
[app.common.pages.helpers :as helpers]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[clojure.set :as set]))
@ -45,7 +45,7 @@
means is displayed over other shapes with less index."
[objects]
(let [frames (helpers/select-frames objects)
(let [frames (cph/get-frames objects)
z-index (calculate-frame-z-index {} uuid/zero objects)]
(->> frames
(map :id)
@ -61,7 +61,7 @@
changed-frames (set/union old-frames new-frames)
frames (->> (helpers/select-frames new-objects)
frames (->> (cph/get-frames new-objects)
(map :id)
(filter #(contains? changed-frames %)))
@ -84,13 +84,10 @@
(generate-child-all-parents-index objects (vals objects)))
([objects shapes]
(let [shape->parents
(fn [shape]
(->> (helpers/get-parents (:id shape) objects)
(into [])))]
(->> shapes
(map #(vector (:id %) (shape->parents %)))
(into {})))))
(let [xf-parents (comp
(map :id)
(map #(vector % (cph/get-parent-ids objects %))))]
(into {} xf-parents shapes))))
(defn create-clip-index
"Retrieves the mask information for an object"

View file

@ -11,7 +11,6 @@
[app.common.spec.shape :as shape]
[clojure.spec.alpha :as s]))
;; --- Grid options
(s/def :internal.grid.color/color string?)

View file

@ -8,7 +8,7 @@
(:require
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.interactions :as cti]
[app.common.uuid :as uuid]
@ -571,7 +571,7 @@
(conj id))]
(-> state
(assoc-in [:viewer-local :selected]
(cp/expand-region-selection objects selection)))))))
(cph/expand-region-selection objects selection)))))))
(defn select-all
[]

View file

@ -484,7 +484,7 @@
(initialize [state local]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
shapes (cp/select-toplevel-shapes objects {:include-frames? true})
shapes (cph/get-immediate-children objects)
srect (gsh/selection-rect shapes)
local (assoc local :vport size :zoom 1)]
(cond
@ -675,7 +675,7 @@
(update [_ state]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
shapes (cp/select-toplevel-shapes objects {:include-frames? true})
shapes (cph/get-immediate-children objects)
srect (gsh/selection-rect shapes)]
(if (empty? shapes)
state
@ -794,7 +794,7 @@
:frame-id (:frame-id obj)
:page-id page-id
:shapes [id]
:index (cp/position-on-parent id objects)}))
:index (cph/get-position-on-parent objects id)}))
selected)]
;; TODO: maybe missing the :reg-objects event?
(rx/of (dch/commit-changes {:redo-changes rchanges
@ -821,7 +821,7 @@
{:type :mov-objects
:parent-id (:parent-id obj)
:page-id page-id
:index (cp/position-on-parent id objects)
:index (cph/get-position-on-parent objects id)
:shapes [id]}))
(reverse ids))
@ -1023,11 +1023,11 @@
objects (wsh/lookup-page-objects state page-id)
;; Ignore any shape whose parent is also intented to be moved
ids (cp/clean-loops objects ids)
ids (cph/clean-loops objects ids)
;; If we try to move a parent into a child we remove it
ids (filter #(not (cp/is-parent? objects parent-id %)) ids)
parents (into #{parent-id} (map #(cp/get-parent % objects)) ids)
ids (filter #(not (cph/is-parent? objects parent-id %)) ids)
parents (into #{parent-id} (map #(cph/get-parent-id objects %)) ids)
groups-to-delete
(loop [current-id (first parents)
@ -1045,7 +1045,7 @@
(empty? (remove removed-id? (:shapes group))))
;; Adds group to the remove and check its parent
(let [to-check (concat to-check [(cp/get-parent current-id objects)])]
(let [to-check (concat to-check [(cph/get-parent-id objects current-id)])]
(recur (first to-check)
(rest to-check)
(conj removed-id? current-id)
@ -1090,8 +1090,8 @@
(not (:component-root? shape)))
parent (get objects parent-id)
component-shape (cph/get-component-shape shape objects)
component-shape-parent (cph/get-component-shape parent objects)
component-shape (cph/get-component-shape objects shape)
component-shape-parent (cph/get-component-shape objects parent)
detach? (and instance-part? (not= (:id component-shape)
(:id component-shape-parent)))
@ -1099,7 +1099,7 @@
reroot? (and sub-instance? (not component-shape-parent))
ids-to-detach (when detach?
(cons id (cph/get-children id objects)))]
(cons id (cph/get-children-ids objects id)))]
[(cond-> shapes-to-detach detach? (into ids-to-detach))
(cond-> shapes-to-deroot deroot? (conj id))
@ -1286,7 +1286,7 @@
(boolean? blocked) (assoc :blocked blocked)
(boolean? hidden) (assoc :hidden hidden)))
objects (wsh/lookup-page-objects state)
ids (into ids (->> ids (mapcat #(cp/get-children % objects))))]
ids (into ids (->> ids (mapcat #(cph/get-children-ids objects %))))]
(rx/of (dch/update-shapes ids update-fn))))))
(defn toggle-visibility-selected
@ -1483,7 +1483,7 @@
(watch [_ state _]
(let [selected (wsh/lookup-selected state)
objects (wsh/lookup-page-objects state)
all-selected (into [] (mapcat #(cp/get-object-with-children % objects)) selected)
all-selected (into [] (mapcat #(cph/get-children-with-self objects %)) selected)
head (get objects (first selected))
not-group-like? (and (= (count selected) 1)
@ -1588,7 +1588,7 @@
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (->> (wsh/lookup-selected state)
(cp/clean-loops objects))
(cph/clean-loops objects))
pdata (reduce (partial collect-object-ids objects) {} selected)
initial {:type :copied-shapes
:file-id (:current-file-id state)
@ -1771,18 +1771,18 @@
[frame-id frame-id delta])
(empty? page-selected)
(let [frame-id (cp/frame-id-by-position page-objects mouse-pos)
(let [frame-id (cph/frame-id-by-position page-objects mouse-pos)
delta (gpt/subtract mouse-pos orig-pos)]
[frame-id frame-id delta])
:else
(let [base (cp/get-base-shape page-objects page-selected)
index (cp/position-on-parent (:id base) page-objects)
frame-id (:frame-id base)
(let [base (cph/get-base-shape page-objects page-selected)
index (cph/get-position-on-parent page-objects (:id base))
frame-id (:frame-id base)
parent-id (:parent-id base)
delta (if in-viewport?
(gpt/subtract mouse-pos orig-pos)
(gpt/subtract (gpt/point (:selrect base)) orig-pos))]
delta (if in-viewport?
(gpt/subtract mouse-pos orig-pos)
(gpt/subtract (gpt/point (:selrect base)) orig-pos))]
[frame-id parent-id delta index]))))
;; Change the indexes if the paste is done with an element selected
@ -1804,7 +1804,7 @@
;; Check if the shape is an instance whose master is defined in a
;; library that is not linked to the current file
(foreign-instance? [shape paste-objects state]
(let [root (cph/get-root-shape shape paste-objects)
(let [root (cph/get-root-shape paste-objects shape)
root-file-id (:component-file root)]
(and (some? root)
(not= root-file-id (:current-file-id state))
@ -1896,7 +1896,7 @@
height 16
page-id (:current-page-id state)
frame-id (-> (wsh/lookup-page-objects state page-id)
(cp/frame-id-by-position @ms/mouse-position))
(cph/frame-id-by-position @ms/mouse-position))
shape (gsh/setup-selrect
{:id id
:type :text
@ -1987,7 +1987,7 @@
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
shapes (cp/select-toplevel-shapes objects {:include-frames? true})
shapes (cph/get-immediate-children objects)
selected (wsh/lookup-selected state)
selected-objs (map #(get objects %) selected)
has-frame? (some #(= (:type %) :frame) selected-objs)]

View file

@ -9,8 +9,8 @@
[app.common.colors :as clr]
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.changes-builder :as cb]
[app.common.pages.helpers :as cph]
[app.common.path.shapes-to-path :as stp]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
@ -22,12 +22,12 @@
(defn selected-shapes
[state]
(let [objects (wsh/lookup-page-objects state)]
(let [objects (wsh/lookup-page-objects state)]
(->> (wsh/lookup-selected state)
(cp/clean-loops objects)
(map #(get objects %))
(filter #(not= :frame (:type %)))
(map #(assoc % ::index (cp/position-on-parent (:id %) objects)))
(cph/clean-loops objects)
(map (d/getf objects))
(remove cph/frame-shape?)
(map #(assoc % ::index (cph/get-position-on-parent objects (:id %))))
(sort-by ::index))))
(defn create-bool-data
@ -51,7 +51,7 @@
(merge head-data)
(gsh/update-bool-selrect shapes objects))]
[bool-shape (cp/position-on-parent (:id head) objects)]))
[bool-shape (cph/get-position-on-parent objects (:id head))]))
(defn group->bool
[group bool-type objects]

View file

@ -11,6 +11,7 @@
[app.common.geom.shapes :as gsh]
[app.common.logging :as log]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.interactions :as csi]
[app.common.spec.page :as csp]
@ -58,12 +59,13 @@
;; --- Common Helpers & Events
;; TODO: looks duplicate
(defn get-frame-at-point
[objects point]
(let [frames (cp/select-frames objects)]
(let [frames (cph/get-frames objects)]
(d/seek #(gsh/has-point? % point) frames)))
(defn- extract-numeric-suffix
[basename]
(if-let [[_ p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
@ -195,9 +197,9 @@
(let [expand-fn (fn [expanded]
(merge expanded
(->> ids
(map #(cp/get-parents % objects))
(map #(cph/get-parent-ids objects %))
flatten
(filter #(not= % uuid/zero))
(remove #(= % uuid/zero))
(map (fn [id] {id true}))
(into {}))))]
(update-in state [:workspace-local :expanded] expand-fn)))))
@ -264,9 +266,9 @@
;; Calculate the frame over which we're drawing
(let [position @ms/mouse-position
frame-id (:frame-id attrs (cp/frame-id-by-position objects position))
frame-id (:frame-id attrs (cph/frame-id-by-position objects position))
shape (when-not (empty? selected)
(cp/get-base-shape objects selected))]
(cph/get-base-shape objects selected))]
;; When no shapes has been selected or we're over a different frame
;; we add it as the latest shape of that frame
@ -274,7 +276,7 @@
[frame-id frame-id nil]
;; Otherwise, we add it to next to the selected shape
(let [index (cp/position-on-parent (:id shape) objects)
(let [index (cph/get-position-on-parent objects (:id shape))
{:keys [frame-id parent-id]} shape]
[frame-id parent-id (inc index)])))))
@ -356,8 +358,9 @@
(watch [it state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
to-move-shapes (->> (cp/select-toplevel-shapes objects {:include-frames? false})
(filterv #(= (:frame-id %) uuid/zero))
to-move-shapes (->> (cph/get-immediate-children objects)
(remove cph/frame-shape?)
(mapv :id)
(d/enumerate)
(filterv (comp shapes second)))
@ -394,7 +397,7 @@
objects (wsh/lookup-page-objects state page-id)
options (wsh/lookup-page-options state page-id)
ids (cp/clean-loops objects ids)
ids (cph/clean-loops objects ids)
flows (:flows options)
groups-to-unmask
@ -434,14 +437,14 @@
all-parents
(reduce (fn [res id]
(into res (cp/get-parents id objects)))
(into res (cph/get-parent-ids objects id)))
(d/ordered-set)
ids)
all-children
(->> ids
(reduce (fn [res id]
(into res (cp/get-children id objects)))
(into res (cph/get-children-ids objects id)))
[])
(reverse)
(into (d/ordered-set)))
@ -463,7 +466,7 @@
{:type :add-obj
:id (:id item)
:page-id page-id
:index (cp/position-on-parent id objects)
:index (cph/get-position-on-parent objects id)
:frame-id (:frame-id item)
:parent-id (:parent-id item)
:obj item}))))
@ -588,7 +591,7 @@
y (:y data (- vbc-y (/ height 2)))
page-id (:current-page-id state)
frame-id (-> (wsh/lookup-page-objects state page-id)
(cp/frame-id-by-position {:x frame-x :y frame-y}))
(cph/frame-id-by-position {:x frame-x :y frame-y}))
shape (-> (cp/make-minimal-shape type)
(merge data)
(merge {:x x :y y})

View file

@ -9,7 +9,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.data.workspace.drawing.common :as common]
[app.main.data.workspace.state-helpers :as wsh]
@ -62,7 +62,7 @@
layout (get state :workspace-layout)
zoom (get-in state [:workspace-local :zoom] 1)
frames (cp/select-frames objects)
frames (cph/get-frames objects)
fid (or (->> frames
(filter #(gsh/has-point? % initial))
first

View file

@ -8,7 +8,7 @@
(:require
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.path :as gsp]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.workspace.drawing.common :as common]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.streams :as ms]
@ -44,10 +44,10 @@
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
content (get-in state [:workspace-drawing :object :content] [])
(let [objects (wsh/lookup-page-objects state)
content (get-in state [:workspace-drawing :object :content] [])
position (get-in content [0 :params] nil)
frame-id (cp/frame-id-by-position objects position)]
frame-id (cph/frame-id-by-position objects position)]
(-> state
(assoc-in [:workspace-drawing :object :frame-id] frame-id))))))

View file

@ -10,6 +10,7 @@
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.changes-builder :as cb]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc]
@ -22,7 +23,7 @@
(->> selected
(map #(get objects %))
(filter #(not= :frame (:type %)))
(map #(assoc % ::index (cp/position-on-parent (:id %) objects)))
(map #(assoc % ::index (cph/get-position-on-parent objects (:id %))))
(sort-by ::index)))
(defn- get-empty-groups-after-group-creation
@ -34,10 +35,8 @@
group, one (or many) groups can become empty because they have had a
single shape which is moved to the created group."
[objects parent-id shapes]
(let [ids (cp/clean-loops objects (into #{} (map :id) shapes))
parents (->> ids
(reduce #(conj %1 (cp/get-parent %2 objects))
#{}))]
(let [ids (cph/clean-loops objects (into #{} (map :id) shapes))
parents (into #{} (map #(cph/get-parent-id objects %)) ids)]
(loop [current-id (first parents)
to-check (rest parents)
removed-id? ids
@ -53,7 +52,7 @@
(empty? (remove removed-id? (:shapes group))))
;; Adds group to the remove and check its parent
(let [to-check (concat to-check [(cp/get-parent current-id objects)]) ]
(let [to-check (concat to-check [(cph/get-parent-id objects current-id)]) ]
(recur (first to-check)
(rest to-check)
(conj removed-id? current-id)
@ -139,7 +138,7 @@
(defn prepare-remove-group
[it page-id group objects]
(let [children (mapv #(get objects %) (:shapes group))
parent-id (cp/get-parent (:id group) objects)
parent-id (cph/get-parent-id objects (:id group))
parent (get objects parent-id)
index-in-parent
@ -149,7 +148,7 @@
(ffirst))
ids-to-detach (when (:component-id group)
(cp/get-children (:id group) objects))
(cph/get-children-ids objects (:id group)))
detach-fn (fn [attrs]
(dissoc attrs
@ -202,7 +201,7 @@
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
selected (cp/clean-loops objects selected)
selected (cph/clean-loops objects selected)
shapes (shapes-for-grouping objects selected)]
(when-not (empty? shapes)
(let [[group rchanges uchanges]
@ -241,7 +240,7 @@
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
selected (wsh/lookup-selected state)
selected (cp/clean-loops objects selected)
selected (cph/clean-loops objects selected)
shapes (shapes-for-grouping objects selected)]
(when-not (empty? shapes)
(let [;; If the selected shape is a group, we can use it. If not,

View file

@ -126,6 +126,14 @@
;; --- Interactions
(defn- connected-frame?
"Check if some frame is origin or destination of any navigate interaction
in the page"
[objects frame-id]
(let [children (cph/get-children-with-self objects frame-id)]
(or (some csi/flow-origin? (map :interactions children))
(some #(csi/flow-to? % frame-id) (map :interactions (vals objects))))))
(defn add-new-interaction
([shape] (add-new-interaction shape nil))
([shape destination]
@ -134,7 +142,7 @@
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame (cph/get-frame shape objects)
frame (cph/get-frame objects shape)
flows (get-in state [:workspace-data
:pages-index
page-id
@ -149,7 +157,7 @@
destination)]
(update shape :interactions
csi/add-interaction new-interaction)))))
(when (and (not (cph/connected-frame? (:id frame) objects))
(when (and (not (connected-frame? objects (:id frame)))
(nil? flow))
(rx/of (add-flow (:id frame))))))))))
@ -278,7 +286,7 @@
overlay-pos (-> shape
(get-in [:interactions index])
:overlay-position)
orig-frame (cph/get-frame shape objects)
orig-frame (cph/get-frame objects shape)
frame-pos (gpt/point (:x orig-frame) (:y orig-frame))
offset (-> initial-pos
(gpt/subtract overlay-pos)

View file

@ -11,6 +11,7 @@
[app.common.geom.shapes :as geom]
[app.common.logging :as log]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.change :as spec.change]
[app.common.spec.color :as spec.color]
@ -132,7 +133,7 @@
(ptk/reify ::update-color
ptk/WatchEvent
(watch [it state _]
(let [[path name] (cp/parse-path-name (:name color))
(let [[path name] (cph/parse-path-name (:name color))
color (assoc color :path path :name name)
prev (get-in state [:workspace-data :colors id])
rchg {:type :mod-color
@ -184,7 +185,7 @@
ptk/WatchEvent
(watch [it state _]
(let [object (get-in state [:workspace-data :media id])
[path name] (cp/parse-path-name new-name)
[path name] (cph/parse-path-name new-name)
rchanges [{:type :mod-media
:object {:id id
@ -244,7 +245,7 @@
(ptk/reify ::update-typography
ptk/WatchEvent
(watch [it state _]
(let [[path name] (cp/parse-path-name (:name typography))
(let [[path name] (cph/parse-path-name (:name typography))
typography (assoc typography :path path :name name)
prev (get-in state [:workspace-data :typographies (:id typography)])
rchg {:type :mod-typography
@ -307,7 +308,7 @@
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (->> (wsh/lookup-selected state)
(cp/clean-loops objects))]
(cph/clean-loops objects))]
(rx/of (add-component2 selected))))))
(defn rename-component
@ -318,7 +319,7 @@
(ptk/reify ::rename-component
ptk/WatchEvent
(watch [it state _]
(let [[path name] (cp/parse-path-name new-name)
(let [[path name] (cph/parse-path-name new-name)
component (get-in state [:workspace-data :components id])
objects (get component :objects)
; Give the same name to the root shape
@ -348,12 +349,10 @@
(ptk/reify ::duplicate-component
ptk/WatchEvent
(watch [it state _]
(let [component (cp/get-component id
(:current-file-id state)
(dwlh/get-local-file state)
nil)
all-components (vals (get-in state [:workspace-data :components]))
unames (set (map :name all-components))
(let [libraries (dwlh/get-libraries state)
component (cph/get-component libraries id)
all-components (-> state :workspace-data :components vals)
unames (into #{} (map :name) all-components)
new-name (dwc/generate-unique-name unames (:name component))
[new-shape new-shapes _updated-shapes]
@ -404,10 +403,9 @@
(ptk/reify ::instantiate-component
ptk/WatchEvent
(watch [it state _]
(let [local-library (dwlh/get-local-file state)
libraries (get state :workspace-libraries)
component (cp/get-component component-id file-id local-library libraries)
component-shape (cp/get-shape component component-id)
(let [libraries (dwlh/get-libraries state)
component (cph/get-component libraries file-id component-id)
component-shape (cph/get-shape component component-id)
orig-pos (gpt/point (:x component-shape) (:y component-shape))
delta (gpt/subtract position orig-pos)
@ -416,7 +414,7 @@
objects (wsh/lookup-page-objects state page-id)
unames (volatile! (dwc/retrieve-used-names objects))
frame-id (cp/frame-id-by-position objects (gpt/add orig-pos delta))
frame-id (cph/frame-id-by-position objects (gpt/add orig-pos delta))
update-new-shape
(fn [new-shape original-shape]
@ -447,10 +445,10 @@
(dissoc :component-root?))))
[new-shape new-shapes _]
(cp/clone-object component-shape
nil
(get component :objects)
update-new-shape)
(cph/clone-object component-shape
nil
(get component :objects)
update-new-shape)
rchanges (mapv (fn [obj]
{:type :add-obj
@ -482,13 +480,12 @@
(ptk/reify ::detach-component
ptk/WatchEvent
(watch [it state _]
(let [local-library (dwlh/get-local-file state)
container (cp/get-container (get state :current-page-id)
:page
local-library)
(let [file (dwlh/get-local-file state)
page-id (get state :current-page-id)
container (cph/get-container file :page page-id)
[rchanges uchanges]
(dwlh/generate-detach-instance id container)]
(dwlh/generate-detach-instance container id)]
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
@ -498,20 +495,19 @@
(ptk/reify ::detach-selected-components
ptk/WatchEvent
(watch [it state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
local-library (dwlh/get-local-file state)
container (cp/get-container page-id :page local-library)
selected (->> state
(wsh/lookup-selected)
(cp/clean-loops objects))
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
file (dwlh/get-local-file state)
container (cph/get-container file :page page-id)
selected (->> state
(wsh/lookup-selected)
(cph/clean-loops objects))
[rchanges uchanges]
(reduce (fn [changes id]
(dwlh/concat-changes
changes
(dwlh/generate-detach-instance id container)))
(dwlh/generate-detach-instance container id)))
dwlh/empty-changes
selected)]
@ -557,21 +553,18 @@
ptk/WatchEvent
(watch [it state _]
(log/info :msg "RESET-COMPONENT of shape" :id (str id))
(let [local-library (dwlh/get-local-file state)
libraries (dwlh/get-libraries state)
container (cp/get-container (get state :current-page-id)
:page
local-library)
(let [file (dwlh/get-local-file state)
libraries (dwlh/get-libraries state)
page-id (:current-page-id state)
container (cph/get-container file :page page-id)
[rchanges uchanges]
(dwlh/generate-sync-shape-direct container
id
local-library
libraries
true)]
(dwlh/generate-sync-shape-direct libraries container id true)]
(log/debug :msg "RESET-COMPONENT finished" :js/rchanges (log-changes
rchanges
local-library))
file))
(rx/of (dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it}))))))
@ -592,17 +585,16 @@
(watch [it state _]
(log/info :msg "UPDATE-COMPONENT of shape" :id (str id))
(let [page-id (get state :current-page-id)
local-library (dwlh/get-local-file state)
local-file (dwlh/get-local-file state)
libraries (dwlh/get-libraries state)
[rchanges uchanges]
(dwlh/generate-sync-shape-inverse page-id
id
local-library
libraries)
container (cph/get-container local-file :page page-id)
shape (cph/get-shape container id)
[rchanges uchanges]
(dwlh/generate-sync-shape-inverse libraries container id)
container (cp/get-container page-id :page local-library)
shape (cp/get-shape container id)
file-id (:component-file shape)
file (dwlh/get-file state file-id)
@ -623,21 +615,22 @@
(log/debug :msg "UPDATE-COMPONENT finished"
:js/local-rchanges (log-changes
local-rchanges
local-library)
file)
:js/rchanges (log-changes
rchanges
file))
(rx/of (when (seq local-rchanges)
(dch/commit-changes {:redo-changes local-rchanges
:undo-changes local-uchanges
:origin it
:file-id (:id local-library)}))
(when (seq rchanges)
(dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it
:file-id file-id})))))))
(rx/of
(when (seq local-rchanges)
(dch/commit-changes {:redo-changes local-rchanges
:undo-changes local-uchanges
:origin it
:file-id (:id local-file)}))
(when (seq rchanges)
(dch/commit-changes {:redo-changes rchanges
:undo-changes uchanges
:origin it
:file-id file-id})))))))
(defn update-component-sync
[shape-id file-id]

View file

@ -11,6 +11,7 @@
[app.common.geom.shapes :as geom]
[app.common.logging :as log]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.text :as txt]
[app.main.data.workspace.groups :as dwg]
@ -57,7 +58,7 @@
(letfn [(concat-changes' [[rchanges1 uchanges1] [rchanges2 uchanges2]]
[(d/concat-vec rchanges1 rchanges2)
(d/concat-vec uchanges1 uchanges2)])]
(transduce (remove nil?) concat-changes' empty-changes rest)))
(transduce (remove nil?) (completing concat-changes') empty-changes rest)))
(defn get-local-file
[state]
@ -70,8 +71,11 @@
(get-in state [:workspace-libraries file-id :data])))
(defn get-libraries
"Retrieve all libraries, including the local file."
[state]
(get state :workspace-libraries))
(let [{:keys [id] :as local} (:workspace-data state)]
(-> (:workspace-libraries state)
(assoc id local))))
(defn pretty-file
[file-id state]
@ -120,7 +124,7 @@
(some? (:parent-id new-shape))
(dissoc :component-root?)))]
(cp/clone-object shape nil objects update-new-shape update-original-shape)))
(cph/clone-object shape nil objects update-new-shape update-original-shape)))
(defn generate-add-component
"If there is exactly one id, and it's a group, use it as root. Otherwise,
@ -204,18 +208,18 @@
"Clone the root shape of the component and all children. Generate new
ids from all of them."
[component]
(let [component-root (cp/get-component-root component)]
(cp/clone-object component-root
nil
(get component :objects)
identity)))
(let [component-root (cph/get-component-root component)]
(cph/clone-object component-root
nil
(get component :objects)
identity)))
(defn generate-detach-instance
"Generate changes to remove the links between a shape and all its children
with a component."
[shape-id container]
[container shape-id]
(log/debug :msg "Detach instance" :shape-id shape-id :container (:id container))
(let [shapes (cp/get-object-with-children shape-id (:objects container))
(let [shapes (cph/get-children-with-self (:objects container) shape-id)
rchanges (mapv (fn [obj]
(make-change
container
@ -293,7 +297,7 @@
(generate-sync-container asset-type
library-id
state
(cp/make-container page :page))]
(cph/make-container page :page))]
(recur (next pages)
(into rchanges page-rchanges)
(into uchanges page-uchanges)))
@ -319,8 +323,7 @@
(generate-sync-container asset-type
library-id
state
(cp/make-container local-component
:component))]
(cph/make-container local-component :component))]
(recur (next local-components)
(into rchanges comp-rchanges)
(into uchanges comp-uchanges)))
@ -331,12 +334,13 @@
or a component) that use assets of the given type in the given library."
[asset-type library-id state container]
(if (cp/page? container)
(if (cph/page? container)
(log/debug :msg "Sync page in local file" :page-id (:id container))
(log/debug :msg "Sync component in local library" :component-id (:id container)))
(let [has-asset-reference? (has-asset-reference-fn asset-type library-id (cp/page? container))
linked-shapes (cp/select-objects has-asset-reference? container)]
(let [has-asset-reference? (has-asset-reference-fn asset-type library-id (cph/page? container))
linked-shapes (->> (vals (:objects container))
(filter has-asset-reference?))]
(loop [shapes (seq linked-shapes)
rchanges []
uchanges []]
@ -398,11 +402,9 @@
(defmethod generate-sync-shape :components
[_ _ state container shape]
(generate-sync-shape-direct container
(:id shape)
(get-local-file state)
(get-libraries state)
false))
(let [shape-id (:id shape)
libraries (get-libraries state)]
(generate-sync-shape-direct libraries container shape-id false)))
(defn- generate-sync-text-shape
[shape container update-node]
@ -624,19 +626,18 @@
(defn generate-sync-shape-direct
"Generate changes to synchronize one shape that the root of a component
instance, and all its children, from the given component."
[container shape-id local-library libraries reset?]
[libraries container shape-id reset?]
(log/debug :msg "Sync shape direct" :shape (str shape-id) :reset? reset?)
(let [shape-inst (cp/get-shape container shape-id)
component (cp/get-component (:component-id shape-inst)
(:component-file shape-inst)
local-library
libraries)
shape-main (cp/get-shape component (:shape-ref shape-inst))
(let [shape-inst (cph/get-shape container shape-id)
component (cph/get-component libraries
(:component-file shape-inst)
(:component-id shape-inst))
shape-main (cph/get-shape component (:shape-ref shape-inst))
initial-root? (:component-root? shape-inst)
root-inst shape-inst
root-main (cp/get-component-root component)]
root-main (cph/get-component-root component)]
(if component
(generate-sync-shape-direct-recursive container
@ -683,9 +684,9 @@
(when set-remote-synced?
(change-remote-synced shape-inst container true)))
children-inst (mapv #(cp/get-shape container %)
children-inst (mapv #(cph/get-shape container %)
(:shapes shape-inst))
children-main (mapv #(cp/get-shape component %)
children-main (mapv #(cph/get-shape component %)
(:shapes shape-main))
only-inst (fn [child-inst]
@ -743,20 +744,18 @@
(defn generate-sync-shape-inverse
"Generate changes to update the component a shape is linked to, from
the values in the shape and all its children."
[page-id shape-id local-library libraries]
[libraries container shape-id]
(log/debug :msg "Sync shape inverse" :shape (str shape-id))
(let [container (cp/get-container page-id :page local-library)
shape-inst (cp/get-shape container shape-id)
component (cp/get-component (:component-id shape-inst)
(:component-file shape-inst)
local-library
libraries)
shape-main (cp/get-shape component (:shape-ref shape-inst))
(let [shape-inst (cph/get-shape container shape-id)
component (cph/get-component libraries
(:component-file shape-inst)
(:component-id shape-inst))
shape-main (cph/get-shape component (:shape-ref shape-inst))
initial-root? (:component-root? shape-inst)
root-inst shape-inst
root-main (cp/get-component-root component)]
root-main (cph/get-component-root component)]
(if component
(generate-sync-shape-inverse-recursive container
@ -777,7 +776,7 @@
(if (nil? shape-main)
;; This should not occur, but protect against it in any case
empty-changes
(let [component-container (cp/make-container component :component)
(let [component-container (cph/make-container component :component)
omit-touched? false
set-remote-synced? (not initial-root?)
@ -805,9 +804,9 @@
(when set-remote-synced?
(change-remote-synced shape-inst container true)))
children-inst (mapv #(cp/get-shape container %)
children-inst (mapv #(cph/get-shape container %)
(:shapes shape-inst))
children-main (mapv #(cp/get-shape component %)
children-main (mapv #(cph/get-shape component %)
(:shapes shape-main))
only-inst (fn [child-inst]
@ -885,13 +884,13 @@
(transduce (map only-inst-cb) concat-changes changes children-inst)
:else
(if (cp/is-main-of child-main child-inst)
(if (cph/is-main-of? child-main child-inst)
(recur (next children-inst)
(next children-main)
(concat-changes changes (both-cb child-inst child-main)))
(let [child-inst' (d/seek #(cp/is-main-of child-main %) children-inst)
child-main' (d/seek #(cp/is-main-of % child-inst) children-main)]
(let [child-inst' (d/seek #(cph/is-main-of? child-main %) children-inst)
child-main' (d/seek #(cph/is-main-of? % child-inst) children-main)]
(cond
(nil? child-inst')
(recur children-inst
@ -919,13 +918,13 @@
(defn- add-shape-to-instance
[component-shape index component container root-instance root-main omit-touched? set-remote-synced?]
(log/info :msg (str "ADD [P] " (:name component-shape)))
(let [component-parent-shape (cp/get-shape component (:parent-id component-shape))
parent-shape (d/seek #(cp/is-main-of component-parent-shape %)
(cp/get-object-with-children (:id root-instance)
(:objects container)))
all-parents (vec (cons (:id parent-shape)
(cp/get-parents (:id parent-shape)
(:objects container))))
(let [component-parent-shape (cph/get-shape component (:parent-id component-shape))
parent-shape (d/seek #(cph/is-main-of? component-parent-shape %)
(cph/get-children-with-self (:objects container)
(:id root-instance)))
all-parents (into [(:id parent-shape)]
(cph/get-parent-ids (:objects container)
(:id parent-shape)))
update-new-shape (fn [new-shape original-shape]
(let [new-shape (reposition-shape new-shape
@ -945,11 +944,11 @@
original-shape)
[_ new-shapes _]
(cp/clone-object component-shape
(:id parent-shape)
(get component :objects)
update-new-shape
update-original-shape)
(cph/clone-object component-shape
(:id parent-shape)
(get component :objects)
update-new-shape
update-original-shape)
rchanges (d/concat-vec
(map (fn [shape']
@ -978,20 +977,20 @@
:ignore-touched true}))
new-shapes)]
(if (and (cp/touched-group? parent-shape :shapes-group) omit-touched?)
(if (and (cph/touched-group? parent-shape :shapes-group) omit-touched?)
empty-changes
[rchanges uchanges])))
(defn- add-shape-to-main
[shape index component page root-instance root-main]
(log/info :msg (str "ADD [C] " (:name shape)))
(let [parent-shape (cp/get-shape page (:parent-id shape))
component-parent-shape (d/seek #(cp/is-main-of % parent-shape)
(cp/get-object-with-children (:id root-main)
(:objects component)))
all-parents (vec (cons (:id component-parent-shape)
(cp/get-parents (:id component-parent-shape)
(:objects component))))
(let [parent-shape (cph/get-shape page (:parent-id shape))
component-parent-shape (d/seek #(cph/is-main-of? % parent-shape)
(cph/get-children-with-self (:objects component)
(:id root-main)))
all-parents (into [(:id component-parent-shape)]
(cph/get-parent-ids (:objects component)
(:id component-parent-shape)))
update-new-shape (fn [new-shape _original-shape]
(reposition-shape new-shape
@ -1005,11 +1004,11 @@
original-shape))
[_new-shape new-shapes updated-shapes]
(cp/clone-object shape
(:id component-parent-shape)
(get page :objects)
update-new-shape
update-original-shape)
(cph/clone-object shape
(:id component-parent-shape)
(get page :objects)
update-new-shape
update-original-shape)
rchanges (d/concat-vec
(map (fn [shape']
@ -1057,12 +1056,12 @@
(defn- remove-shape
[shape container omit-touched?]
(log/info :msg (str "REMOVE-SHAPE "
(if (cp/page? container) "[P] " "[C] ")
(if (cph/page? container) "[P] " "[C] ")
(:name shape)))
(let [objects (get container :objects)
parents (cp/get-parents (:id shape) objects)
parents (cph/get-parent-ids objects (:id shape))
parent (first parents)
children (cp/get-children (:id shape) objects)
children (cph/get-children-ids objects (:id shape))
rchanges [(make-change
container
@ -1080,7 +1079,7 @@
container
(as-> {:type :add-obj
:id id
:index (cp/position-on-parent id objects)
:index (cph/get-position-on-parent objects id)
:parent-id (:parent-id shape')
:ignore-touched true
:obj shape'} $
@ -1096,20 +1095,20 @@
{:type :reg-objects
:shapes (vec parents)})])]
(if (and (cp/touched-group? parent :shapes-group) omit-touched?)
(if (and (cph/touched-group? parent :shapes-group) omit-touched?)
empty-changes
[rchanges uchanges])))
(defn- move-shape
[shape index-before index-after container omit-touched?]
(log/info :msg (str "MOVE "
(if (cp/page? container) "[P] " "[C] ")
(if (cph/page? container) "[P] " "[C] ")
(:name shape)
" "
index-before
" -> "
index-after))
(let [parent (cp/get-shape container (:parent-id shape))
(let [parent (cph/get-shape container (:parent-id shape))
rchanges [(make-change
container
@ -1126,7 +1125,7 @@
:index index-before
:ignore-touched true})]]
(if (and (cp/touched-group? parent :shapes-group) omit-touched?)
(if (and (cph/touched-group? parent :shapes-group) omit-touched?)
empty-changes
[rchanges uchanges])))
@ -1138,7 +1137,7 @@
empty-changes
(do
(log/info :msg (str "CHANGE-TOUCHED "
(if (cp/page? container) "[P] " "[C] ")
(if (cph/page? container) "[P] " "[C] ")
(:name dest-shape))
:options options)
(let [new-touched (cond
@ -1174,7 +1173,7 @@
empty-changes
(do
(log/info :msg (str "CHANGE-REMOTE-SYNCED? "
(if (cp/page? container) "[P] " "[C] ")
(if (cph/page? container) "[P] " "[C] ")
(:name shape))
:remote-synced? remote-synced?)
(let [rchanges [(make-change
@ -1205,7 +1204,7 @@
(log/info :msg (str "SYNC "
(:name origin-shape)
" -> "
(if (cp/page? container) "[P] " "[C] ")
(if (cph/page? container) "[P] " "[C] ")
(:name dest-shape)))
(let [; To synchronize geometry attributes we need to make a prior
@ -1224,8 +1223,8 @@
(let [attr (first attrs)]
(if (nil? attr)
(let [all-parents (vec (or (cp/get-parents (:id dest-shape)
(:objects container)) []))
(let [all-parents (cph/get-parent-ids (:objects container)
(:id dest-shape))
rchanges [(make-change
container
{:type :mod-obj
@ -1285,7 +1284,7 @@
(defn- make-change
[container change]
(if (cp/page? container)
(if (cph/page? container)
(assoc change :page-id (:id container))
(assoc change :component-id (:id container))))

View file

@ -6,7 +6,7 @@
(ns app.main.data.workspace.path.changes
(:require
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.path.helpers :as helpers]
@ -24,7 +24,7 @@
(let [shape-id (:id shape)
frame-id (:frame-id shape)
parent-id (:parent-id shape)
parent-index (cp/position-on-parent shape-id objects)
parent-index (cph/get-position-on-parent objects shape-id)
[old-points old-selrect] (helpers/content->points+selrect shape old-content)
[new-points new-selrect] (helpers/content->points+selrect shape new-content)

View file

@ -8,7 +8,7 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes.path :as upg]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.path.commands :as upc]
[app.common.path.shapes-to-path :as upsp]
[app.common.spec :as us]
@ -255,10 +255,10 @@
(ptk/reify ::setup-frame-path
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
content (get-in state [:workspace-drawing :object :content] [])
(let [objects (wsh/lookup-page-objects state)
content (get-in state [:workspace-drawing :object :content] [])
position (get-in content [0 :params] nil)
frame-id (cp/frame-id-by-position objects position)]
frame-id (cph/frame-id-by-position objects position)]
(-> state
(assoc-in [:workspace-drawing :object :frame-id] frame-id))))))

View file

@ -6,8 +6,8 @@
(ns app.main.data.workspace.path.shapes-to-path
(:require
[app.common.pages :as cp]
[app.common.pages.changes-builder :as cb]
[app.common.pages.helpers :as cph]
[app.common.path.shapes-to-path :as upsp]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.state-helpers :as wsh]
@ -24,7 +24,7 @@
children-ids
(into #{}
(mapcat #(cp/get-children % objects))
(mapcat #(cph/get-children-ids objects %))
selected)
changes

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.change :as spec.change]
[app.common.spec.file :as spec.file]
@ -658,7 +659,7 @@
(rx/map extract-frame-changes)
(rx/share))
frames (-> state wsh/lookup-page-objects cp/select-frames)
frames (-> state wsh/lookup-page-objects cph/get-frames)
no-thumb-frames (->> frames
(filter (comp nil? :thumbnail))
(mapv :id))]

View file

@ -10,7 +10,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.common.spec.interactions :as cti]
[app.common.uuid :as uuid]
@ -151,7 +151,7 @@
(conj id))]
(-> state
(assoc-in [:workspace-local :selected]
(cp/expand-region-selection objects selection))))))))
(cph/expand-region-selection objects selection))))))))
(defn select-shapes
[ids]
@ -171,39 +171,23 @@
(ptk/reify ::select-all
ptk/WatchEvent
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
new-selected (let [selected-objs
(->> (wsh/lookup-selected state)
(map #(get objects %)))
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame-ids
(reduce #(conj %1 (:frame-id %2))
#{}
selected-objs)
selected (let [frame-ids (into #{} (comp
(map (d/getf objects))
(map :frame-id))
(wsh/lookup-selected state))
frame-id (if (= 1 (count frame-ids))
(first frame-ids)
uuid/zero)]
(cph/get-immediate-children objects frame-id))
common-frame-id
(when (= (count frame-ids) 1) (first frame-ids))]
selected (into (d/ordered-set)
(remove :blocked)
selected)]
(if (and common-frame-id
(not= (:id common-frame-id) uuid/zero))
(-> (get objects common-frame-id)
:shapes)
(->> (cp/select-toplevel-shapes objects
{:include-frames? true
:include-frame-children? false})
(map :id))))
is-not-blocked (fn [shape-id] (not (get-in state [:workspace-data
:pages-index page-id
:objects shape-id
:blocked] false)))
selected-ids (into lks/empty-linked-set
(comp (filter some?)
(filter is-not-blocked))
new-selected)]
(rx/of (select-shapes selected-ids))))))
(rx/of (select-shapes selected))))))
(defn deselect-all
"Clear all possible state of drawing, edition
@ -250,7 +234,7 @@
:include-frames? true
:ignore-groups? ignore-groups?
:full-frame? true})
(rx/map #(cp/clean-loops objects %))
(rx/map #(cph/clean-loops objects %))
(rx/map #(into initial-set (filter (comp not blocked?)) %))
(rx/map select-shapes)))))))
@ -314,11 +298,8 @@
[objects page-id unames ids delta]
(let [unames (volatile! unames)
update-unames! (fn [new-name] (vswap! unames conj new-name))
all-ids (reduce (fn [ids-set id]
(into ids-set (cons id (cp/get-children id objects))))
#{}
ids)
ids-map (into {} (map #(vector % (uuid/next)) all-ids))]
all-ids (reduce #(into %1 (cons %2 (cph/get-children-ids objects %2))) #{} ids)
ids-map (into {} (map #(vector % (uuid/next))) all-ids)]
(loop [ids (seq ids)
chgs []]
(if ids
@ -337,7 +318,7 @@
(let [process-id
(fn [index-map id]
(let [parent-id (get-in objects [id :parent-id])
parent-index (cp/position-on-parent id objects)]
parent-index (cph/get-position-on-parent objects id)]
(update index-map parent-id (fnil conj []) [id parent-index])))
index-map (reduce process-id {} ids)]
(-> changes (update-indices index-map))))
@ -345,7 +326,7 @@
(defn- prepare-duplicate-change
[objects page-id unames update-unames! ids-map id delta]
(let [obj (get objects id)]
(if (= :frame (:type obj))
(if (cph/frame-shape? obj)
(prepare-duplicate-frame-change objects page-id unames update-unames! ids-map obj delta)
(prepare-duplicate-shape-change objects page-id unames update-unames! ids-map obj delta (:frame-id obj) (:parent-id obj)))))
@ -449,7 +430,7 @@
;; The default is leave normal shapes in place, but put
;; new frames to the right of the original.
(if (= (:type obj) :frame)
(if (cph/frame-shape? obj)
(gpt/point (+ (:width obj) 50) 0)
(gpt/point 0 0))

View file

@ -7,7 +7,7 @@
(ns app.main.data.workspace.state-helpers
(:require
[app.common.data :as d]
[app.common.pages :as cp]))
[app.common.pages.helpers :as cph]))
(defn lookup-page
([state]
@ -43,7 +43,7 @@
:or {omit-blocked? false}}]
(let [objects (lookup-page-objects state)
selected (->> (get-in state [:workspace-local :selected])
(cp/clean-loops objects))
(cph/clean-loops objects))
selectable? (fn [id]
(and (contains? objects id)
(or (not omit-blocked?)

View file

@ -12,7 +12,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :refer [max-safe-int min-safe-int]]
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
@ -454,9 +454,9 @@
ptk/WatchEvent
(watch [it state _]
(try
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame-id (cp/frame-id-by-position objects position)
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame-id (cph/frame-id-by-position objects position)
selected (wsh/lookup-selected state)
[vb-x vb-y vb-width vb-height] (svg-dimensions svg-data)

View file

@ -10,7 +10,7 @@
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc]
@ -160,8 +160,9 @@
shape (get objects id)
update-fn #(update-shape % txt/is-root-node? attrs/merge attrs)
shape-ids (cond (= (:type shape) :text) [id]
(= (:type shape) :group) (cp/get-children id objects))]
shape-ids (cond (cph/text-shape? shape) [id]
(cph/group-shape? shape) (cph/get-children-ids objects id))]
(rx/of (dch/update-shapes shape-ids update-fn))))))
@ -186,8 +187,9 @@
attrs))
update-fn #(update-shape % txt/is-paragraph-node? merge-fn attrs)
shape-ids (cond (= (:type shape) :text) [id]
(= (:type shape) :group) (cp/get-children id objects))]
shape-ids (cond
(cph/text-shape? shape) [id]
(cph/group-shape? shape) (cph/get-children-ids objects id))]
(rx/of (dch/update-shapes shape-ids update-fn))))))))
@ -208,8 +210,9 @@
(txt/is-paragraph-node? node)))
update-fn #(update-shape % update-node? attrs/merge attrs)
shape-ids (cond (= (:type shape) :text) [id]
(= (:type shape) :group) (cp/get-children id objects))]
shape-ids (cond
(cph/text-shape? shape) [id]
(cph/group-shape? shape) (cph/get-children-ids objects id))]
(rx/of (dch/update-shapes shape-ids update-fn)))))))
;; --- RESIZE UTILS

View file

@ -12,7 +12,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.common :as dwc]
@ -144,9 +144,7 @@
(let [objects (wsh/lookup-page-objects state)
shapes (->> shapes
(remove #(get % :blocked false))
(mapcat (fn [shape]
(->> (cp/get-children (:id shape) objects)
(map #(get objects %)))))
(mapcat #(cph/get-children objects (:id %)))
(concat shapes))
update-shape
@ -156,8 +154,6 @@
(update state :workspace-modifiers #(reduce update-shape % shapes)))))))
(defn- apply-modifiers
[ids]
(us/verify (s/coll-of uuid?) ids)
@ -165,8 +161,7 @@
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
children-ids (->> ids (mapcat #(cp/get-children % objects)))
ids-with-children (d/concat-vec children-ids ids)
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids)
object-modifiers (get state :workspace-modifiers)
ignore-tree (get-ignore-tree object-modifiers objects ids)]
@ -203,7 +198,7 @@
shape
(nil? root)
(cp/get-root-shape shape objects)
(cph/get-root-shape objects shape)
:else root)
@ -213,7 +208,7 @@
transformed-shape
(nil? transformed-root)
(cp/get-root-shape transformed-shape objects)
(cph/get-root-shape objects transformed-shape)
:else transformed-root)
@ -663,10 +658,10 @@
(let [position @ms/mouse-position
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame-id (cp/frame-id-by-position objects position)
frame-id (cph/frame-id-by-position objects position)
moving-shapes (->> ids
(cp/clean-loops objects)
(cph/clean-loops objects)
(map #(get objects %))
(remove #(or (nil? %)
(= (:frame-id %) frame-id))))
@ -683,7 +678,7 @@
{:type :mov-objects
:page-id page-id
:parent-id (:parent-id shape)
:index (cp/get-index-in-parent objects (:id shape))
:index (cph/get-index-in-parent objects (:id shape))
:shapes [(:id shape)]})))]
(when-not (empty? uch)

View file

@ -9,7 +9,7 @@
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.path.commands :as upc]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.store :as st]
@ -218,7 +218,7 @@
:media
:typographies
:components]))
st/state))
st/state =))
(def workspace-libraries
(l/derived :workspace-libraries st/state))
@ -246,7 +246,7 @@
(l/derived :options workspace-page))
(def workspace-frames
(l/derived cp/select-frames workspace-page-objects =))
(l/derived cph/get-frames workspace-page-objects =))
(def workspace-editor
(l/derived :workspace-editor st/state))
@ -276,9 +276,11 @@
(defn select-bool-children [id]
(let [selector
(fn [state]
(let [objects (wsh/lookup-page-objects state)
modifiers (:workspace-modifiers state)]
(as-> (cp/select-children id objects) $
(let [objects (wsh/lookup-page-objects state)
modifiers (:workspace-modifiers state)
children (->> (cph/get-children-ids objects id)
(select-keys objects))]
(as-> children $
(gsh/merge-modifiers $ modifiers)
(d/mapm (set-content-modifiers state) $))))]
(l/derived selector st/state =)))
@ -293,7 +295,7 @@
(defn is-child-selected?
[id]
(letfn [(selector [{:keys [selected objects]}]
(let [children (cp/get-children id objects)]
(let [children (cph/get-children-ids objects id)]
(some #(contains? selected %) children)))]
(l/derived selector selected-data =)))
@ -307,7 +309,7 @@
(def selected-shapes-with-children
(letfn [(selector [{:keys [selected objects]}]
(let [xform (comp (remove nil?)
(mapcat #(cp/get-children % objects)))
(mapcat #(cph/get-children-ids objects %)))
shapes (into selected xform selected)]
(mapv (d/getf objects) shapes)))]
(l/derived selector selected-data =)))

View file

@ -19,8 +19,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.uuid :as uuid]
[app.common.pages.helpers :as cph]
[app.config :as cfg]
[app.main.fonts :as fonts]
[app.main.ui.shapes.bool :as bool]
@ -59,12 +58,11 @@
(defn- calculate-dimensions
[{:keys [objects] :as data} vport]
(let [shapes (cp/select-toplevel-shapes objects {:include-frames? true
:include-frame-children? false})
(let [shapes (cph/get-immediate-children objects)
to-finite (fn [val fallback] (if (not (mth/finite? val)) fallback val))
rect (cond->> (gsh/selection-rect shapes)
(some? vport)
(gal/adjust-to-viewport vport))]
rect (cond->> (gsh/selection-rect shapes)
(some? vport)
(gal/adjust-to-viewport vport))]
(-> rect
(update :x to-finite 0)
(update :y to-finite 0)
@ -101,11 +99,9 @@
bool-shape (bool/bool-shape shape-wrapper)]
(mf/fnc bool-wrapper
[{:keys [shape] :as props}]
(let [childs (mf/use-memo
(mf/deps (:id shape) objects)
(fn []
(->> (cp/get-children (:id shape) objects)
(select-keys objects))))]
(let [childs (mf/with-memo [(:id shape) objects]
(->> (cph/get-children-ids objects (:id shape))
(select-keys objects)))]
[:& bool-shape {:shape shape :childs childs}]))))
(defn svg-raw-wrapper-factory
@ -166,15 +162,12 @@
[{:keys [data width height thumbnails? embed? include-metadata?] :as props
:or {embed? false include-metadata? false}}]
(let [objects (:objects data)
root (get objects uuid/zero)
shapes
(->> (:shapes root)
(map #(get objects %)))
shapes (cph/get-immediate-children objects)
root-children
(->> shapes
(filter #(not= :frame (:type %)))
(mapcat #(cp/get-object-with-children (:id %) objects)))
(remove cph/frame-shape?)
(mapcat #(cph/get-children-with-self objects (:id %))))
vport (when (and (some? width) (some? height))
{:width width :height height})
@ -237,7 +230,7 @@
objects
(mf/with-memo [frame-id objects modifier]
(let [update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)]
(->> (cp/get-children frame-id objects)
(->> (cph/get-children-ids objects frame-id)
(into [frame-id])
(reduce update-fn objects))))
@ -280,7 +273,7 @@
(mf/use-memo
(mf/deps modifier objects group-id)
(fn []
(let [modifier-ids (concat [group-id] (cp/get-children group-id objects))
(let [modifier-ids (cons group-id (cph/get-children-ids objects group-id))
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
modifiers (reduce update-fn {} modifier-ids)]
(gsh/merge-modifiers objects modifiers))))
@ -334,7 +327,7 @@
(mf/use-memo
(mf/deps modifier id objects)
(fn []
(let [modifier-ids (concat [id] (cp/get-children id objects))
(let [modifier-ids (cons id (cph/get-children-ids objects id))
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)]
(reduce update-fn objects modifier-ids))))

View file

@ -10,7 +10,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :refer [zero]]
[app.main.refs :as refs]
[app.main.worker :as uw]
@ -202,9 +202,9 @@
:frame-id (->> shapes first :frame-id)
:include-frames? true
:rect area-selrect})
(rx/map #(cp/clean-loops objects %))
(rx/map #(cph/clean-loops objects %))
(rx/map #(set/difference % (into #{} (map :id shapes))))
(rx/map (fn [ids] (map #(get objects %) ids)))))
(rx/map #(map (d/getf objects) %))))
(defn closest-distance-snap
[page-id shapes objects zoom movev]

View file

@ -10,7 +10,7 @@
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.data.fonts :as df]
[app.main.render :as render]
@ -60,7 +60,7 @@
(gpt/negate)
(gmt/translate-matrix))
mod-ids (cons frame-id (cp/get-children frame-id objects))
mod-ids (cons frame-id (cph/get-children-ids objects frame-id))
updt-fn #(-> %1
(assoc-in [%2 :modifiers :displacement] modifier)
(update %2 gsh/transform-shape))
@ -133,7 +133,7 @@
[objects object-id]
(if (uuid/zero? object-id)
(let [object (get objects object-id)
shapes (cp/select-toplevel-shapes objects {:include-frames? true})
shapes (cph/get-immediate-children objects)
srect (gsh/selection-rect shapes)
object (merge object (select-keys srect [:x :y :width :height]))
object (gsh/transform-shape object)

View file

@ -8,7 +8,7 @@
"The main container for a frame in handoff mode"
(:require
[app.common.geom.shapes :as geom]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.viewer :as dv]
[app.main.store :as st]
[app.main.ui.shapes.bool :as bool]
@ -116,12 +116,12 @@
(mf/fnc bool-container
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
children-ids (cp/get-children (:id shape) objects)
childs (select-keys objects children-ids)
props (-> (obj/new)
(obj/merge! props)
(obj/merge! #js {:childs childs}))]
(let [shape (unchecked-get props "shape")
children (->> (cph/get-children-ids objects (:id shape))
(select-keys objects))
props (-> (obj/new)
(obj/merge! props)
(obj/merge! #js {:childs children}))]
[:> bool-wrapper props]))))
(defn svg-raw-container-factory

View file

@ -9,7 +9,7 @@
[app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec.page :as csp]
[app.main.data.comments :as dcm]
[app.main.data.viewer :as dv]
@ -35,11 +35,10 @@
update-fn #(d/update-when %1 %2 assoc-in [:modifiers :displacement] modifier)]
(->> (cp/get-children frame-id objects)
(->> (cph/get-children-ids objects frame-id)
(into [frame-id])
(reduce update-fn objects)))))
(mf/defc viewport
{::mf/wrap [mf/memo]}
[{:keys [page interactions-mode frame base-frame frame-offset size]}]

View file

@ -10,7 +10,7 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as geom]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec.interactions :as cti]
[app.main.data.viewer :as dv]
[app.main.refs :as refs]
@ -330,7 +330,8 @@
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
childs (select-keys objects (cp/get-children (:id shape) objects))
childs (->> (cph/get-children-ids objects (:id shape))
(select-keys objects))
props (obj/merge! #js {} props
#js {:childs childs
:objects objects})]
@ -399,7 +400,7 @@
update-fn #(assoc-in %1 [%2 :modifiers :displacement] modifier)
frame-id (:id frame)
modifier-ids (into [frame-id] (cp/get-children frame-id objects))
modifier-ids (into [frame-id] (cph/get-children-ids objects frame-id))
objects (reduce update-fn objects modifier-ids)
frame (assoc-in frame [:modifiers :displacement] modifier)

View file

@ -100,13 +100,11 @@
(mf/defc menu
[{:keys [layout project file team-id page-id] :as props}]
(let [show-menu? (mf/use-state false)
(let [show-menu? (mf/use-state false)
show-sub-menu? (mf/use-state false)
editing? (mf/use-state false)
frames (mf/deref refs/workspace-frames)
editing? (mf/use-state false)
edit-input-ref (mf/use-ref nil)
frames (mf/deref refs/workspace-frames)
add-shared-fn
(st/emitf (dw/set-file-shared (:id file) true))

View file

@ -12,9 +12,7 @@
others are defined using a generic wrapper implemented in
common."
(:require
[app.common.pages :as cp]
[app.common.uuid :as uuid]
[app.main.refs :as refs]
[app.common.pages.helpers :as cph]
[app.main.ui.shapes.circle :as circle]
[app.main.ui.shapes.image :as image]
[app.main.ui.shapes.rect :as rect]
@ -29,7 +27,6 @@
[app.main.ui.workspace.shapes.text :as text]
[app.util.object :as obj]
[debug :refer [debug?]]
[okulary.core :as l]
[rumext.alpha :as mf]))
(declare shape-wrapper)
@ -42,31 +39,23 @@
(def image-wrapper (common/generic-wrapper-factory image/image-shape))
(def rect-wrapper (common/generic-wrapper-factory rect/rect-shape))
(defn make-is-moving-ref
[id]
(fn []
(let [check-moving (fn [local]
(and (= :move (:transform local))
(contains? (:selected local) id)))]
(l/derived check-moving refs/workspace-local))))
(mf/defc root-shape
"Draws the root shape of the viewport and recursively all the shapes"
{::mf/wrap-props false}
[props]
(let [objects (obj/get props "objects")
active-frames (obj/get props "active-frames")
root-shapes (get-in objects [uuid/zero :shapes])
shapes (->> root-shapes (mapv #(get objects %)))
root-children (->> shapes
(filter #(not= :frame (:type %)))
(mapcat #(cp/get-object-with-children (:id %) objects)))]
shapes (cph/get-immediate-children objects)]
[:*
[:& ff/fontfaces-style {:shapes root-children}]
;; Render font faces only for shapes that are part of the root
;; frame but don't belongs to any other frame.
(let [xform (comp
(remove cph/frame-shape?)
(mapcat #(cph/get-children-with-self objects (:id %))))]
[:& ff/fontfaces-style {:shapes (into [] xform shapes)}])
(for [item shapes]
(if (= (:type item) :frame)
(if (cph/frame-shape? item)
[:& frame-wrapper {:shape item
:key (:id item)
:objects objects

View file

@ -7,7 +7,7 @@
(ns app.main.ui.workspace.shapes.frame
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.ui.hooks :as hooks]
[app.main.ui.shapes.frame :as frame]
[app.main.ui.shapes.shape :refer [shape-container]]
@ -105,7 +105,7 @@
(hooks/use-equal-memo))
all-children
(-> (cp/get-children-objects (:id shape) objects)
(-> (cph/get-children objects (:id shape))
(hooks/use-equal-memo))
show-thumbnail?

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
(ns app.main.ui.workspace.sidebar.layers
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.data.workspace :as dw]
[app.main.data.workspace.common :as dwc]
@ -58,18 +58,16 @@
(when (kbd/enter? event) (accept-edit))
(when (kbd/esc? event) (cancel-edit)))]
(mf/use-effect
(mf/deps shape-for-rename)
#(when (and (= shape-for-rename (:id shape))
(not (:edition @local)))
(start-edit)))
(mf/with-effect [shape-for-rename]
(when (and (= shape-for-rename (:id shape))
(not (:edition @local)))
(start-edit)))
(mf/use-effect
(mf/deps (:edition @local))
#(when (:edition @local)
(let [name-input (mf/ref-val name-ref)]
(dom/select-text! name-input))
nil))
(mf/with-effect [(:edition @local)]
(when (:edition @local)
(let [name-input (mf/ref-val name-ref)]
(dom/select-text! name-input)
nil)))
(if (:edition @local)
[:input.element-name
@ -92,9 +90,10 @@
(mf/defc layer-item
[{:keys [index item selected objects] :as props}]
(let [id (:id item)
selected? (contains? selected id)
container? (or (= (:type item) :frame) (= (:type item) :group))
(let [id (:id item)
selected? (contains? selected id)
container? (or (cph/frame-shape? item)
(cph/group-shape? item))
disable-drag (mf/use-state false)
@ -160,7 +159,7 @@
(if (= side :center)
(st/emit! (dw/relocate-selected-shapes (:id item) 0))
(let [to-index (if (= side :top) (inc index) index)
parent-id (cp/get-parent (:id item) objects)]
parent-id (cph/get-parent-id objects (:id item))]
(st/emit! (dw/relocate-selected-shapes parent-id to-index)))))
on-hold

View file

@ -6,7 +6,7 @@
(ns app.main.ui.workspace.sidebar.options.menus.component
(:require
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.modal :as modal]
[app.main.data.workspace :as dw]
[app.main.data.workspace.libraries :as dwl]
@ -16,7 +16,7 @@
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t]]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
(def component-attrs [:component-id :component-file :shape-ref])
@ -25,47 +25,59 @@
[{:keys [ids values] :as props}]
(let [current-file-id (mf/use-ctx ctx/current-file-id)
id (first ids)
locale (mf/deref i18n/locale)
local (mf/use-state {:menu-open false})
id (first ids)
local (mf/use-state {:menu-open false})
show? (some? (:component-id values))
local-library (mf/deref refs/workspace-local-library)
libraries (mf/deref refs/workspace-libraries)
{:keys [component-id component-file]} values
component-id (:component-id values)
library-id (:component-file values)
component (cp/get-component component-id component-file local-library libraries)
local-file (deref refs/workspace-local-library)
libraries (deref refs/workspace-libraries)
on-menu-click (mf/use-callback
(fn [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(swap! local assoc :menu-open true)))
;; NOTE: this is necessary because the `cph/get-component`
;; expects a map of all libraries, including the local one.
libraries (assoc libraries (:id local-file) local-file)
on-menu-close (mf/use-callback
#(swap! local assoc :menu-open false))
component (cph/get-component libraries library-id component-id)
show? (some? component-id)
do-detach-component (st/emitf (dwl/detach-component id))
do-reset-component (st/emitf (dwl/reset-component id))
do-update-component (st/emitf (dwl/update-component-sync id component-file))
on-menu-click
(mf/use-callback
(fn [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(swap! local assoc :menu-open true)))
on-menu-close
(mf/use-callback
#(swap! local assoc :menu-open false))
do-detach-component
(st/emitf (dwl/detach-component id))
do-reset-component
(st/emitf (dwl/reset-component id))
do-update-component
(st/emitf (dwl/update-component-sync id library-id))
do-update-remote-component
(st/emitf (modal/show
{:type :confirm
:message ""
:title (t locale "modals.update-remote-component.message")
:hint (t locale "modals.update-remote-component.hint")
:cancel-label (t locale "modals.update-remote-component.cancel")
:accept-label (t locale "modals.update-remote-component.accept")
:title (tr "modals.update-remote-component.message")
:hint (tr "modals.update-remote-component.hint")
:cancel-label (tr "modals.update-remote-component.cancel")
:accept-label (tr "modals.update-remote-component.accept")
:accept-style :primary
:on-accept do-update-component}))
do-show-component (st/emitf (dw/go-to-component component-id))
do-navigate-component-file (st/emitf (dwl/nav-to-component-file component-file))]
do-navigate-component-file (st/emitf (dwl/nav-to-component-file library-id))]
(when show?
[:div.element-set
[:div.element-set-title
[:span (t locale "workspace.options.component")]]
[:span (tr "workspace.options.component")]]
[:div.element-set-content
[:div.row-flex.component-row
i/component
@ -78,14 +90,14 @@
;; app/main/ui/workspace/context_menu.cljs
[:& context-menu {:on-close on-menu-close
:show (:menu-open @local)
:options (if (= (:component-file values) current-file-id)
[[(t locale "workspace.shape.menu.detach-instance") do-detach-component]
[(t locale "workspace.shape.menu.reset-overrides") do-reset-component]
[(t locale "workspace.shape.menu.update-main") do-update-component]
[(t locale "workspace.shape.menu.show-main") do-show-component]]
:options (if (= library-id current-file-id)
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
[(tr "workspace.shape.menu.update-main") do-update-component]
[(tr "workspace.shape.menu.show-main") do-show-component]]
[[(t locale "workspace.shape.menu.detach-instance") do-detach-component]
[(t locale "workspace.shape.menu.reset-overrides") do-reset-component]
[(t locale "workspace.shape.menu.go-main") do-navigate-component-file]
[(t locale "workspace.shape.menu.update-main") do-update-remote-component]])}]]]]])))
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
[(tr "workspace.shape.menu.go-main") do-navigate-component-file]
[(tr "workspace.shape.menu.update-main") do-update-remote-component]])}]]]]])))

View file

@ -7,7 +7,7 @@
(ns app.main.ui.workspace.sidebar.options.menus.interactions
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec.interactions :as csi]
[app.common.spec.page :as csp]
[app.common.uuid :as uuid]
@ -178,10 +178,10 @@
(mf/defc interaction-entry
[{:keys [index shape interaction update-interaction remove-interaction]}]
(let [objects (deref refs/workspace-page-objects)
destination (get objects (:destination interaction))
frames (mf/use-memo (mf/deps objects)
#(cp/select-frames objects))
(let [objects (deref refs/workspace-page-objects)
destination (get objects (:destination interaction))
frames (mf/with-memo [objects]
(cph/get-frames objects))
overlay-pos-type (:overlay-pos-type interaction)
close-click-outside? (:close-click-outside interaction false)
@ -190,10 +190,10 @@
way (-> interaction :animation :way)
direction (-> interaction :animation :direction)
extended-open? (mf/use-state false)
extended-open? (mf/use-state false)
ext-delay-ref (mf/use-ref nil)
ext-duration-ref (mf/use-ref nil)
ext-delay-ref (mf/use-ref nil)
ext-duration-ref (mf/use-ref nil)
select-text
(fn [ref] (fn [_] (dom/select-text! (mf/ref-val ref))))
@ -550,7 +550,7 @@
[:& page-flows {:flows flows}])
[:div.element-set.interactions-options
(when (and shape (not (cp/unframed-shape? shape)))
(when (and shape (not (cph/unframed-shape? shape)))
[:div.element-set-title
[:span (tr "workspace.options.interactions")]
[:div.add-page {:on-click add-interaction}
@ -558,7 +558,7 @@
[:div.element-set-content
(when (= (count interactions) 0)
[:*
(when (and shape (not (cp/unframed-shape? shape)))
(when (and shape (not (cph/unframed-shape? shape)))
[:*
[:div.interactions-help-icon i/plus]
[:div.interactions-help.separator (tr "workspace.options.add-interaction")]])

View file

@ -9,7 +9,7 @@
["react-virtualized" :as rvt]
[app.common.data :as d]
[app.common.exceptions :as ex]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.text :as txt]
[app.main.data.fonts :as fts]
[app.main.data.shortcuts :as dsc]
@ -575,7 +575,7 @@
[:input.element-name.adv-typography-name
{:type "text"
:ref name-input-ref
:default-value (cp/merge-path-item (:path typography) (:name typography))
:default-value (cph/merge-path-item (:path typography) (:name typography))
:on-blur on-name-blur
:on-change on-name-change}]

View file

@ -8,7 +8,7 @@
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.shortcuts :as dsc]
[app.main.data.workspace :as dw]
[app.main.data.workspace.path.shortcuts :as psc]
@ -154,13 +154,13 @@
selected (mf/ref-val selected-ref)
remove-xfm (mapcat #(cp/get-parents % objects))
remove-xfm (mapcat #(cph/get-parent-ids objects %))
remove-id? (cond-> (into #{} remove-xfm selected)
@ctrl?
(into (filter is-group?) ids))
hover-shape (->> ids
(filterv (comp not remove-id?))
(filter (comp not remove-id?))
(first)
(get objects))]
(reset! hover hover-shape)

View file

@ -9,7 +9,7 @@
(:require
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec.interactions :as cti]
[app.main.data.workspace :as dw]
[app.main.refs :as refs]
@ -210,7 +210,7 @@
(st/emit! (dw/start-move-overlay-pos index)))]
(when dest-shape
(let [orig-frame (cp/get-frame orig-shape objects)
(let [orig-frame (cph/get-frame objects orig-shape)
marker-x (+ (:x orig-frame) (:x position))
marker-y (+ (:y orig-frame) (:y position))
width (:width dest-shape)
@ -326,7 +326,7 @@
:objects objects
:hover-disabled? hover-disabled?}]))])))
(when (and shape
(not (cp/unframed-shape? shape))
(not (cph/unframed-shape? shape))
(not (#{:move :rotate} current-transform)))
[:& interaction-handle {:key (:id shape)
:index nil

View file

@ -8,7 +8,7 @@
(:require
[app.common.exceptions :as ex]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.refs :as refs]
[app.util.object :as obj]
[app.util.path.format :as upf]
@ -89,7 +89,7 @@
transform (mf/deref refs/current-transform)
outlines-ids (->> (set/union selected hover)
(cp/clean-loops objects))
(cph/clean-loops objects))
show-outline? (fn [shape] (and (not (:hidden shape))
(not (:blocked shape))))

View file

@ -50,13 +50,10 @@
vbox-x (:x vbox)
vbox-y (:y vbox)
base-objects-rect
(mf/use-memo
(mf/deps objects)
(fn []
(let [root-shapes (-> objects cph/get-top-frame :shapes)
shapes (->> root-shapes (mapv #(get objects %)))]
(gsh/selection-rect shapes))))
base-objects-rect (mf/with-memo [objects]
(-> objects
(cph/get-immediate-children)
(gsh/selection-rect)))
inv-zoom (/ 1 zoom)
vbox-height (- (:height vbox) (* inv-zoom scroll-height))

View file

@ -9,7 +9,7 @@
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.refs :as refs]
[app.main.worker :as uw]
[beicon.core :as rx]
@ -225,7 +225,7 @@
:frame-id (:id frame)
:include-frames? true
:rect rect})
(rx/map #(cp/clean-loops @refs/workspace-page-objects %))
(rx/map #(cph/clean-loops @refs/workspace-page-objects %))
(rx/map #(set/difference % selected))
(rx/map #(->> % (map (partial get @refs/workspace-page-objects)))))
(rx/of nil))))]

View file

@ -9,7 +9,8 @@
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.spec :as us]
[app.main.snap :as snap]
[app.util.geom.snap-points :as sp]
[beicon.core :as rx]
@ -151,18 +152,14 @@
(mf/defc snap-points
{::mf/wrap [mf/memo]}
[{:keys [layout zoom objects selected page-id drawing transform modifiers] :as props}]
(let [shapes (into [] (keep (d/getf objects)) selected)
(us/assert set? selected)
(let [shapes (into [] (keep (d/getf objects)) selected)
filter-shapes
(into #{}
(comp (mapcat #(cp/get-object-with-children % objects))
(map :id))
selected)
(into selected (mapcat #(cph/get-children-ids objects %)) selected)
remove-snap? (mf/use-memo
(mf/deps layout filter-shapes)
#(snap/make-remove-snap layout filter-shapes))
remove-snap? (mf/with-memo [layout filter-shapes]
(snap/make-remove-snap layout filter-shapes))
shapes (if drawing [drawing] shapes)]
(when (or drawing transform)

View file

@ -8,7 +8,7 @@
(:require
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.workspace :as dw]
[app.main.data.workspace.interactions :as dwi]
[app.main.refs :as refs]
@ -161,7 +161,7 @@
on-frame-enter (unchecked-get props "on-frame-enter")
on-frame-leave (unchecked-get props "on-frame-leave")
on-frame-select (unchecked-get props "on-frame-select")
frames (cp/select-frames objects)]
frames (cph/get-frames objects)]
[:g.frame-titles
(for [frame frames]

View file

@ -10,8 +10,8 @@
https://en.wikipedia.org/wiki/Range_tree"
(:require
[app.common.data :as d]
[app.common.pages :as cp]
[app.common.pages.diff :as diff]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.util.geom.grid :as gg]
[app.util.geom.snap-points :as snap]
@ -187,9 +187,9 @@
(defn add-page
"Adds page information"
[snap-data {:keys [objects options] :as page}]
(let [frames (cp/select-frames objects)
shapes (cp/select-objects #(not= :frame (:type %)) page)
(let [frames (cph/get-frames objects)
shapes (->> (vals (:objects page))
(remove cph/frame-shape?))
guides (vals (:guides options))
page-data
@ -233,7 +233,7 @@
(reduce remove-guide $ removed-guides)
(reduce update-guide $ updated-guides)
(reduce add-guide $ new-guides)))))
;; Page doesn't exist, we create a new entry
(add-page snap-data page)))

View file

@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.util.quadtree :as qdt]
[app.worker.impl :as impl]
@ -86,7 +87,7 @@
changed-ids (into #{}
(comp (filter #(not= % uuid/zero))
(filter changes?)
(mapcat #(into [%] (cp/get-children % new-objects))))
(mapcat #(into [%] (cph/get-children-ids new-objects %))))
(set/union (set (keys old-objects))
(set (keys new-objects))))

View file

@ -8,11 +8,11 @@
(:require
[app.common.data :as d]
[app.common.math :as mth]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.transit :as t]
[app.common.uuid :as uuid]
[app.main.data.workspace :as dw]
[app.main.data.workspace.changes :as dwc]
[app.main.data.workspace.changes :as dwc]
[app.main.store :as st]
[app.util.object :as obj]
[app.util.timers :as timers]
@ -208,7 +208,7 @@
(show-component [shape objects]
(if (nil? (:shape-ref shape))
""
(let [root-shape (cp/get-component-shape shape objects)
(let [root-shape (cph/get-component-shape objects shape)
component-id (when root-shape (:component-id root-shape))
component-file-id (when root-shape (:component-file root-shape))
component-file (when component-file-id (get libraries component-file-id nil))

View file

@ -197,13 +197,10 @@
"Renamed component"))
(rx/do
(fn [new-state]
(let [file (dwlh/get-local-file new-state)
component (cph/get-component
(:component-id instance1)
(:component-file instance1)
file
{})]
(let [libs (dwlh/get-libraries new-state)
component (cph/get-component libs
(:component-file instance1)
(:component-id instance1))]
(t/is (= (:name component)
"Renamed component")))))
@ -274,13 +271,10 @@
new-state
(:id instance1))
file (dwlh/get-local-file new-state)
component (cph/get-component
(:component-id instance1)
(:component-file instance1)
file
{})]
libs (dwlh/get-libraries new-state)
component (cph/get-component libs
(:component-file instance1)
(:component-id instance1))]
(t/is (nil? component)))))
(rx/subs done #(throw %))))))

View file

@ -3,7 +3,6 @@
[app.common.colors :as clr]
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.pages.helpers :as cph]
[app.main.data.workspace.changes :as dwc]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.libraries-helpers :as dwlh]

View file

@ -7,7 +7,6 @@
[app.common.uuid :as uuid]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.main.data.workspace :as dw]
[app.main.data.workspace.libraries-helpers :as dwlh]
@ -55,26 +54,22 @@
(defn resolve-instance
[state root-inst-id]
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
shapes-inst (cph/get-object-with-children
root-inst-id
(:objects page))]
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
shapes-inst (cph/get-children-with-self (:objects page)
root-inst-id)]
;; Validate that the instance tree is well constructed
(t/is (is-instance-root (first shapes-inst)))
(is-instance-root (first shapes-inst))
(run! is-instance-child (rest shapes-inst))
shapes-inst))
(defn resolve-noninstance
[state root-inst-id]
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
shapes-inst (cph/get-object-with-children
root-inst-id
(:objects page))]
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
shapes-inst (cph/get-children-with-self (:objects page)
root-inst-id)]
;; Validate that the tree is not an instance
(run! is-noninstance shapes-inst)
@ -82,31 +77,23 @@
(defn resolve-instance-and-main
[state root-inst-id]
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
(let [page (thp/current-page state)
root-inst (cph/get-shape page root-inst-id)
file (dwlh/get-local-file state)
component (cph/get-component
(:component-id root-inst)
(:id file)
file
nil)
libs (dwlh/get-libraries state)
component (cph/get-component libs (:component-id root-inst))
shapes-inst (cph/get-object-with-children
root-inst-id
(:objects page))
shapes-main (cph/get-object-with-children
(:shape-ref root-inst)
(:objects component))
shapes-inst (cph/get-children-with-self (:objects page) root-inst-id)
shapes-main (cph/get-children-with-self (:objects component) (:shape-ref root-inst))
unique-refs (into #{} (map :shape-ref shapes-inst))
unique-refs (into #{} (map :shape-ref) shapes-inst)
main-exists? (fn [shape]
(t/is (some #(= (:id %) (:shape-ref shape))
shapes-main)))]
main-exists? (fn [shape]
(t/is (some #(= (:id %) (:shape-ref shape))
shapes-main)))]
;; Validate that the instance tree is well constructed
(t/is (is-instance-root (first shapes-inst)))
(is-instance-root (first shapes-inst))
(run! is-instance-child (rest shapes-inst))
(run! is-noninstance shapes-main)
(t/is (= (count shapes-inst)
@ -118,20 +105,11 @@
(defn resolve-component
[state component-id]
(let [page (thp/current-page state)
file (dwlh/get-local-file state)
component (cph/get-component
component-id
(:id file)
file
nil)
root-main (cph/get-component-root
component)
shapes-main (cph/get-object-with-children
(:id root-main)
(:objects component))]
(let [page (thp/current-page state)
libs (dwlh/get-libraries state)
component (cph/get-component libs component-id)
root-main (cph/get-component-root component)
shapes-main (cph/get-children-with-self (:objects component) (:id root-main))]
;; Validate that the component tree is well constructed
(run! is-noninstance shapes-main)

View file

@ -66,7 +66,7 @@
([state label type] (sample-shape state type {}))
([state label type props]
(let [page (current-page state)
frame (cph/get-top-frame (:objects page))
frame (cph/get-frame (:objects page))
shape (-> (cp/make-minimal-shape type)
(gsh/setup {:x 0 :y 0 :width 1 :height 1})
(merge props))]