mirror of
https://github.com/penpot/penpot.git
synced 2025-03-16 01:31:22 -05:00
🎉 Update master component
This commit is contained in:
parent
917643489f
commit
f837bad894
10 changed files with 337 additions and 166 deletions
|
@ -182,6 +182,20 @@
|
|||
(assoc m key (apply f found args))
|
||||
m)))
|
||||
|
||||
(defn assoc-in-when
|
||||
[m key-seq v]
|
||||
(let [found (get-in m key-seq sentinel)]
|
||||
(if-not (identical? sentinel found)
|
||||
(assoc-in m key-seq v)
|
||||
m)))
|
||||
|
||||
(defn assoc-when
|
||||
[m key v]
|
||||
(let [found (get m key sentinel)]
|
||||
(if-not (identical? sentinel found)
|
||||
(assoc m key v)
|
||||
m)))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Data Parsing / Conversion
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
|
@ -362,8 +362,8 @@
|
|||
(defmethod change-spec :del-component [_]
|
||||
(s/keys :req-un [::id]))
|
||||
|
||||
(defmethod change-spec :sync-library [_]
|
||||
(s/keys :req-un [::id]))
|
||||
(defmethod change-spec :update-component [_]
|
||||
(s/keys :req-un [::id ::shapes]))
|
||||
|
||||
(s/def ::change (s/multi-spec change-spec :type))
|
||||
(s/def ::changes (s/coll-of ::change))
|
||||
|
@ -777,80 +777,50 @@
|
|||
[data {:keys [id]}]
|
||||
(d/dissoc-in data [:components id]))
|
||||
|
||||
(declare sync-page)
|
||||
(declare sync-shape-and-children)
|
||||
(declare sync-shape)
|
||||
(declare sync-component-shape)
|
||||
|
||||
(defmethod process-change :sync-library
|
||||
[data id]
|
||||
(cph/walk-pages (sync-page (:components data)) data))
|
||||
(defmethod process-change :update-component
|
||||
[data {:keys [id shapes]}]
|
||||
(let [sync-component
|
||||
(fn [component]
|
||||
(update component :objects
|
||||
#(d/mapm (partial sync-component-shape shapes) %)))]
|
||||
|
||||
(defn- sync-page
|
||||
[components]
|
||||
(fn [page-id page]
|
||||
(let [linked-shapes
|
||||
(cph/select-objects #(some? (:component-id %)) page)
|
||||
(update-in data [:components id] sync-component)))
|
||||
|
||||
updated-shapes
|
||||
(reduce
|
||||
(fn [updated-shapes linked-shape]
|
||||
(let [component-id (:component-id linked-shape)
|
||||
component (get components component-id)]
|
||||
(into updated-shapes
|
||||
(sync-shape-and-children linked-shape
|
||||
component
|
||||
(:objects page)))))
|
||||
[]
|
||||
linked-shapes)]
|
||||
|
||||
(cph/update-object-list page updated-shapes))))
|
||||
|
||||
(defn- sync-shape-and-children
|
||||
[linked-shape component objects]
|
||||
(let [children (cph/get-children-objects (:id linked-shape) objects)
|
||||
all-shapes (conj children linked-shape)]
|
||||
(if (nil? component)
|
||||
(map #(dissoc % :component-id :shape-ref) all-shapes)
|
||||
(map #(sync-shape % (:objects component)) all-shapes))))
|
||||
|
||||
(defn- sync-shape
|
||||
[shape component-objs]
|
||||
(let [component-shape (get component-objs (:shape-ref shape))]
|
||||
(if (nil? component-shape)
|
||||
(assoc shape :shape-ref nil)
|
||||
(-> shape
|
||||
(d/update-when :content :content component-shape)
|
||||
(d/update-when :fill-color :fill-color component-shape)
|
||||
(d/update-when :fill-color-ref-file :fill-color-ref-file component-shape)
|
||||
(d/update-when :fill-color-ref-id :fill-color-ref-id component-shape)
|
||||
(d/update-when :fill-opacity :fill-opacity component-shape)
|
||||
(d/update-when :font-family :font-family component-shape)
|
||||
(d/update-when :font-size :font-size component-shape)
|
||||
(d/update-when :font-style :font-style component-shape)
|
||||
(d/update-when :font-weight :font-weight component-shape)
|
||||
(d/update-when :letter-spacing :letter-spacing component-shape)
|
||||
(d/update-when :line-height :line-height component-shape)
|
||||
(d/update-when :proportion :proportion component-shape)
|
||||
(d/update-when :rx :rx component-shape)
|
||||
(d/update-when :ry :ry component-shape)
|
||||
(d/update-when :cx :cx component-shape)
|
||||
(d/update-when :cy :cy component-shape)
|
||||
(d/update-when :x :x component-shape)
|
||||
(d/update-when :y :y component-shape)
|
||||
(d/update-when :exports :exports component-shape)
|
||||
(d/update-when :stroke-color :stroke-color component-shape)
|
||||
(d/update-when :stroke-color-ref-file :stroke-color-ref-file component-shape)
|
||||
(d/update-when :stroke-color-ref-id :stroke-color-ref-id component-shape)
|
||||
(d/update-when :stroke-opacity :stroke-opacity component-shape)
|
||||
(d/update-when :stroke-style :stroke-style component-shape)
|
||||
(d/update-when :stroke-width :stroke-width component-shape)
|
||||
(d/update-when :stroke-alignment :stroke-alignment component-shape)
|
||||
(d/update-when :text-align :text-align component-shape)
|
||||
(d/update-when :width :width component-shape)
|
||||
(d/update-when :height :height component-shape)
|
||||
(d/update-when :interactions :interactions component-shape)
|
||||
(d/update-when :selrect :selrect component-shape)
|
||||
(d/update-when :points :points component-shape)))))
|
||||
(defn- sync-component-shape
|
||||
[new-shapes _ component-shape]
|
||||
(let [shape (d/seek #(= (:shape-ref %) (:id component-shape)) new-shapes)]
|
||||
(if (nil? shape)
|
||||
component-shape
|
||||
(-> component-shape
|
||||
(d/assoc-when :content (:content shape))
|
||||
(d/assoc-when :fill-color (:fill-color shape))
|
||||
(d/assoc-when :fill-color-ref-file (:fill-color-ref-file shape))
|
||||
(d/assoc-when :fill-color-ref-id (:fill-color-ref-id shape))
|
||||
(d/assoc-when :fill-opacity (:fill-opacity shape))
|
||||
(d/assoc-when :font-family (:font-family shape))
|
||||
(d/assoc-when :font-size (:font-size shape))
|
||||
(d/assoc-when :font-style (:font-style shape))
|
||||
(d/assoc-when :font-weight (:font-weight shape))
|
||||
(d/assoc-when :letter-spacing (:letter-spacing shape))
|
||||
(d/assoc-when :line-height (:line-height shape))
|
||||
(d/assoc-when :proportion (:proportion shape))
|
||||
(d/assoc-when :rx (:rx shape))
|
||||
(d/assoc-when :ry (:ry shape))
|
||||
(d/assoc-when :stroke-color (:stroke-color shape))
|
||||
(d/assoc-when :stroke-color-ref-file (:stroke-color-ref-file shape))
|
||||
(d/assoc-when :stroke-color-ref-id (:stroke-color-ref-id shape))
|
||||
(d/assoc-when :stroke-opacity (:stroke-opacity shape))
|
||||
(d/assoc-when :stroke-style (:stroke-style shape))
|
||||
(d/assoc-when :stroke-width (:stroke-width shape))
|
||||
(d/assoc-when :stroke-alignment (:stroke-alignment shape))
|
||||
(d/assoc-when :text-align (:text-align shape))
|
||||
(d/assoc-when :width (:width shape))
|
||||
(d/assoc-when :height (:height shape))
|
||||
(d/assoc-when :interactions (:interactions shape))
|
||||
(d/assoc-when :selrect (:selrect shape))
|
||||
(d/assoc-when :points (:points shape))))))
|
||||
|
||||
(defmethod process-operation :set
|
||||
[shape op]
|
||||
|
|
|
@ -30,6 +30,16 @@
|
|||
(update page :objects
|
||||
#(into % (d/index-by :id objects-list))))
|
||||
|
||||
(defn get-root-component
|
||||
"Get the root shape linked to the component for this shape, if any"
|
||||
[id objects]
|
||||
(let [obj (get objects id)]
|
||||
(if-let [component-id (:component-id obj)]
|
||||
id
|
||||
(if-let [parent-id (:parent-id obj)]
|
||||
(get-root-component parent-id obj)
|
||||
nil))))
|
||||
|
||||
(defn get-children
|
||||
"Retrieve all children ids recursively for a given object"
|
||||
[id objects]
|
||||
|
@ -43,6 +53,26 @@
|
|||
[id objects]
|
||||
(map #(get objects %) (get-children id objects)))
|
||||
|
||||
(defn get-object-with-children
|
||||
"Retrieve a list with an object and all of its children"
|
||||
[id objects]
|
||||
(map #(get objects %) (concat [id] (get-children id objects))))
|
||||
|
||||
(defn walk-children
|
||||
"Go through an object and all the children tree, and apply a
|
||||
function to each one. Return the list of changed objects."
|
||||
[id f objects]
|
||||
(let [obj (get objects id)]
|
||||
(if (nil? (:shapes obj))
|
||||
[(apply f obj)]
|
||||
(loop [children (map #(get objects %) (:shapes obj))
|
||||
updated-children []]
|
||||
(if (empty? children)
|
||||
updated-children
|
||||
(let [child (first children)]
|
||||
(recur (rest children)
|
||||
(concat [(apply f child)] updated-children))))))))
|
||||
|
||||
(defn is-shape-grouped
|
||||
"Checks if a shape is inside a group"
|
||||
[shape-id objects]
|
||||
|
@ -136,3 +166,54 @@
|
|||
(lazy-seq (loopfn (rest ids))))))]
|
||||
(loopfn (:shapes root))))
|
||||
|
||||
(defn clone-object
|
||||
"Gets a copy of the object and all its children, with new ids
|
||||
and with the parent-children links correctly set. Admits functions
|
||||
to make more transformations to the cloned objects and the
|
||||
original ones.
|
||||
|
||||
Returns the cloned object, the list of all new objects (including
|
||||
the cloned one), and possibly a list of original objects modified."
|
||||
([object parent-id objects xf-new-object]
|
||||
(clone-object object parent-id objects xf-new-object identity))
|
||||
|
||||
([object parent-id objects xf-new-object xf-original-object]
|
||||
(let [new-id (uuid/next)]
|
||||
(loop [child-ids (seq (:shapes object))
|
||||
new-direct-children []
|
||||
new-children []
|
||||
updated-children []]
|
||||
|
||||
(if (empty? child-ids)
|
||||
(let [new-object (cond-> object
|
||||
true
|
||||
(assoc :id new-id
|
||||
:parent-id parent-id)
|
||||
|
||||
(some? (:shapes object))
|
||||
(assoc :shapes (map :id new-direct-children)))
|
||||
|
||||
new-object (xf-new-object new-object object)
|
||||
|
||||
new-objects (concat [new-object] new-children)
|
||||
|
||||
updated-object (xf-original-object object new-object)
|
||||
|
||||
updated-objects (if (= object updated-object)
|
||||
updated-children
|
||||
(concat [updated-object] updated-children))]
|
||||
|
||||
[new-object new-objects updated-objects])
|
||||
|
||||
(let [child-id (first child-ids)
|
||||
child (get objects child-id)
|
||||
|
||||
[new-child new-child-objects updated-child-objects]
|
||||
(clone-object child new-id objects xf-new-object xf-original-object)]
|
||||
|
||||
(recur
|
||||
(next child-ids)
|
||||
(concat new-direct-children [new-child])
|
||||
(concat new-children new-child-objects)
|
||||
(concat updated-children updated-child-objects))))))))
|
||||
|
||||
|
|
|
@ -48,10 +48,6 @@
|
|||
(s/def ::set-of-string
|
||||
(s/every string? :kind set?))
|
||||
|
||||
;; --- Expose inner functions
|
||||
|
||||
(defn interrupt? [e] (= e :interrupt))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Workspace Initialization
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -956,7 +952,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> stream
|
||||
(rx/filter interrupt?)
|
||||
(rx/filter dwc/interrupt?)
|
||||
(rx/take 1)
|
||||
(rx/map (constantly clear-edition-mode))))))
|
||||
|
||||
|
@ -985,7 +981,7 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [cancel-event? (fn [event]
|
||||
(interrupt? event))
|
||||
(dwc/interrupt? event))
|
||||
stoper (rx/filter (ptk/type? ::clear-drawing) stream)]
|
||||
(->> (rx/filter cancel-event? stream)
|
||||
(rx/take 1)
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
([state page-id]
|
||||
(get-in state [:workspace-data :pages-index page-id :options])))
|
||||
|
||||
(defn interrupt? [e] (= e :interrupt))
|
||||
|
||||
(defn lookup-component-objects
|
||||
([state component-id]
|
||||
(get-in state [:workspace-data :components component-id :objects])))
|
||||
|
||||
|
||||
;; --- Changes Handling
|
||||
|
@ -454,3 +459,4 @@
|
|||
objects (lookup-page-objects state page-id)
|
||||
[rchanges uchanges] (impl-gen-changes objects page-id (seq ids))]
|
||||
(rx/of (commit-changes rchanges uchanges {:commit-local? true})))))))
|
||||
|
||||
|
|
|
@ -12,11 +12,15 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.pages-helpers :as cph]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.common.pages :as cp]
|
||||
[app.main.repo :as rp]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.util.color :as color]
|
||||
[app.util.i18n :refer [tr]]
|
||||
[beicon.core :as rx]
|
||||
|
@ -107,7 +111,7 @@
|
|||
:object prev}]
|
||||
(rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}))))))
|
||||
|
||||
(declare clone-shape)
|
||||
(declare make-component-shape)
|
||||
|
||||
(def add-component
|
||||
(ptk/reify ::add-component
|
||||
|
@ -127,7 +131,7 @@
|
|||
(dws/prepare-create-group page-id shapes "Component-" true))
|
||||
|
||||
[new-shape new-shapes updated-shapes]
|
||||
(clone-shape group nil objects)
|
||||
(make-component-shape group nil objects)
|
||||
|
||||
rchanges (conj rchanges
|
||||
{:type :add-component
|
||||
|
@ -168,59 +172,23 @@
|
|||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dws/select-shapes (d/ordered-set (:id group))))))))))
|
||||
|
||||
(defn- clone-shape
|
||||
(defn- make-component-shape
|
||||
"Clone the shape and all children. Generate new ids and detach
|
||||
from parent and frame. Update the original shapes to have links
|
||||
to the new ones."
|
||||
[shape parent-id objects]
|
||||
(let [new-id (uuid/next)]
|
||||
(if (nil? (:shapes shape))
|
||||
(let [xf-new-shape (fn [new-shape original-shape]
|
||||
(assoc new-shape :frame-id nil))
|
||||
|
||||
; TODO: unify this case with the empty child-ids case.
|
||||
(let [new-shape (assoc shape
|
||||
:id new-id
|
||||
:parent-id parent-id
|
||||
:frame-id nil)
|
||||
xf-original-shape (fn [original-shape new-shape]
|
||||
(cond-> original-shape
|
||||
true
|
||||
(assoc :shape-ref (:id new-shape))
|
||||
|
||||
new-shapes [new-shape]
|
||||
(nil? (:parent-id new-shape))
|
||||
(assoc :component-id (:id new-shape))))]
|
||||
|
||||
updated-shapes [(cond-> shape
|
||||
true (assoc :shape-ref (:id new-shape))
|
||||
(nil? parent-id) (assoc :component-id (:id new-shape)))]]
|
||||
|
||||
[new-shape new-shapes updated-shapes])
|
||||
|
||||
(loop [child-ids (seq (:shapes shape))
|
||||
new-children []
|
||||
updated-children []]
|
||||
|
||||
(if (empty? child-ids)
|
||||
(let [new-shape (assoc shape
|
||||
:id new-id
|
||||
:parent-id parent-id
|
||||
:frame-id nil
|
||||
:shapes (map :id new-children))
|
||||
|
||||
new-shapes (conj new-children new-shape)
|
||||
|
||||
updated-shapes
|
||||
(conj updated-children
|
||||
(cond-> shape
|
||||
true (assoc :shape-ref (:id new-shape))
|
||||
(nil? parent-id) (assoc :component-id (:id new-shape))))]
|
||||
|
||||
[new-shape new-shapes updated-shapes])
|
||||
|
||||
(let [child-id (first child-ids)
|
||||
child (get objects child-id)
|
||||
|
||||
[new-child new-child-shapes updated-child-shapes]
|
||||
(clone-shape child new-id objects)]
|
||||
|
||||
(recur
|
||||
(next child-ids)
|
||||
(into new-children new-child-shapes)
|
||||
(into updated-children updated-child-shapes))))))))
|
||||
(cph/clone-object shape parent-id objects xf-new-shape xf-original-shape)))
|
||||
|
||||
(defn delete-component
|
||||
[{:keys [id] :as params}]
|
||||
|
@ -241,3 +209,145 @@
|
|||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn instantiate-component
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::instantiate-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [component (get-in state [:workspace-data :components id])
|
||||
component-shape (get-in component [:objects (:id component)])
|
||||
|
||||
orig-pos (gpt/point (:x component-shape) (:y component-shape))
|
||||
mouse-pos @ms/mouse-position
|
||||
delta (gpt/subtract mouse-pos orig-pos)
|
||||
|
||||
_ (js/console.log "orig-pos" (clj->js orig-pos))
|
||||
_ (js/console.log "mouse-pos" (clj->js mouse-pos))
|
||||
_ (js/console.log "delta" (clj->js delta))
|
||||
|
||||
page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
unames (dwc/retrieve-used-names objects)
|
||||
|
||||
all-frames (cph/select-frames objects)
|
||||
|
||||
xf-new-shape
|
||||
(fn [new-shape original-shape]
|
||||
(let [new-name ;; TODO: ojoooooooooo
|
||||
(dwc/generate-unique-name unames (:name new-shape))]
|
||||
|
||||
(cond-> new-shape
|
||||
true
|
||||
(as-> $
|
||||
(assoc $ :name new-name)
|
||||
(geom/move $ delta)
|
||||
(assoc $ :frame-id
|
||||
(dwc/calculate-frame-overlap all-frames $))
|
||||
(assoc $ :parent-id
|
||||
(or (:parent-id $) (:frame-id $)))
|
||||
(assoc $ :shape-ref (:id original-shape)))
|
||||
|
||||
(nil? (:parent-id original-shape))
|
||||
(assoc :component-id (:id original-shape)))))
|
||||
|
||||
[new-shape new-shapes _]
|
||||
(cph/clone-object component-shape
|
||||
nil
|
||||
(get component :objects)
|
||||
xf-new-shape)
|
||||
|
||||
rchanges (map (fn [obj]
|
||||
{:type :add-obj
|
||||
:id (:id obj)
|
||||
:page-id page-id
|
||||
:frame-id (:frame-id obj)
|
||||
:parent-id (:parent-id obj)
|
||||
:obj obj})
|
||||
new-shapes)
|
||||
|
||||
uchanges (map (fn [obj]
|
||||
{:type :del-obj
|
||||
:id (:id obj)
|
||||
:page-id page-id})
|
||||
new-shapes)]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dws/select-shapes (d/ordered-set (:id new-shape))))))))
|
||||
|
||||
(defn detach-component
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::detach-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
root-id (cph/get-root-component id objects)
|
||||
|
||||
shapes (cph/get-object-with-children root-id objects)
|
||||
|
||||
rchanges (map (fn [obj]
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id obj)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val nil}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val nil}]})
|
||||
shapes)
|
||||
|
||||
uchanges (map (fn [obj]
|
||||
{:type :mod-obj
|
||||
:page-id page-id
|
||||
:id (:id obj)
|
||||
:operations [{:type :set
|
||||
:attr :component-id
|
||||
:val (:component-id obj)}
|
||||
{:type :set
|
||||
:attr :shape-ref
|
||||
:val (:shape-ref obj)}]})
|
||||
shapes)]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
(defn reset-component
|
||||
[id]
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::reset-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
)))
|
||||
|
||||
(defn update-component
|
||||
[id]
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::update-component
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (dwc/lookup-page-objects state page-id)
|
||||
root-id (cph/get-root-component id objects)
|
||||
root-shape (get objects id)
|
||||
component-id (get root-shape :component-id)
|
||||
component-objs (dwc/lookup-component-objects state component-id)
|
||||
|
||||
shapes (cph/get-object-with-children root-id objects)
|
||||
|
||||
rchanges [{:type :update-component
|
||||
:id component-id
|
||||
:shapes shapes}
|
||||
{:type :sync-library
|
||||
:id (get-in state [:workspace-file :id])}]
|
||||
|
||||
|
||||
uchanges [{:type :update-component
|
||||
:id component-id
|
||||
:shapes (vals component-objs)}]]
|
||||
|
||||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))
|
||||
|
||||
|
|
|
@ -33,33 +33,6 @@
|
|||
(s/def ::set-of-string
|
||||
(s/every string? :kind set?))
|
||||
|
||||
;; Duplicate from workspace.
|
||||
;; FIXME: Move these functions to a common place
|
||||
|
||||
(defn interrupt? [e] (= e :interrupt))
|
||||
|
||||
(defn- retrieve-used-names
|
||||
[objects]
|
||||
(into #{} (map :name) (vals objects)))
|
||||
|
||||
(defn- extract-numeric-suffix
|
||||
[basename]
|
||||
(if-let [[match p1 p2] (re-find #"(.*)-([0-9]+)$" basename)]
|
||||
[p1 (+ 1 (d/parse-integer p2))]
|
||||
[basename 1]))
|
||||
|
||||
(defn- generate-unique-name
|
||||
"A unique name generator"
|
||||
[used basename]
|
||||
(s/assert ::set-of-string used)
|
||||
(s/assert ::us/string basename)
|
||||
(let [[prefix initial] (extract-numeric-suffix basename)]
|
||||
(loop [counter initial]
|
||||
(let [candidate (str prefix "-" counter)]
|
||||
(if (contains? used candidate)
|
||||
(recur (inc counter))
|
||||
candidate)))))
|
||||
|
||||
;; --- Selection Rect
|
||||
|
||||
(declare select-shapes-by-current-selrect)
|
||||
|
@ -88,7 +61,7 @@
|
|||
(ptk/reify ::handle-selection
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [stoper (rx/filter #(or (interrupt? %)
|
||||
(let [stoper (rx/filter #(or (dwc/interrupt? %)
|
||||
(ms/mouse-up? %))
|
||||
stream)]
|
||||
(rx/concat
|
||||
|
@ -198,7 +171,9 @@
|
|||
(let [selrect (geom/selection-rect shapes)
|
||||
frame-id (-> shapes first :frame-id)
|
||||
parent-id (-> shapes first :parent-id)
|
||||
group-name (if (and keep-name (= (count shapes) 1))
|
||||
group-name (if (and keep-name
|
||||
(= (count shapes) 1)
|
||||
(= (:type (first shapes)) :group))
|
||||
(:name (first shapes))
|
||||
(name (gensym prefix)))]
|
||||
(-> (cp/make-minimal-group frame-id selrect group-name)
|
||||
|
@ -298,7 +273,7 @@
|
|||
(defn- prepare-duplicate-shape-change
|
||||
[objects page-id names obj delta frame-id parent-id]
|
||||
(let [id (uuid/next)
|
||||
name (generate-unique-name names (:name obj))
|
||||
name (dwc/generate-unique-name names (:name obj))
|
||||
renamed-obj (assoc obj :id id :name name)
|
||||
moved-obj (geom/move renamed-obj delta)
|
||||
frames (cph/select-frames objects)
|
||||
|
@ -338,7 +313,7 @@
|
|||
(defn- prepare-duplicate-frame-change
|
||||
[objects page-id names obj delta]
|
||||
(let [frame-id (uuid/next)
|
||||
frame-name (generate-unique-name names (:name obj))
|
||||
frame-name (dwc/generate-unique-name names (:name obj))
|
||||
sch (->> (map #(get objects %) (:shapes obj))
|
||||
(mapcat #(prepare-duplicate-shape-change objects page-id names % delta frame-id frame-id)))
|
||||
|
||||
|
@ -367,7 +342,7 @@
|
|||
|
||||
selected (get-in state [:workspace-local :selected])
|
||||
delta (gpt/point 0 0)
|
||||
unames (retrieve-used-names objects)
|
||||
unames (dwc/retrieve-used-names objects)
|
||||
|
||||
rchanges (prepare-duplicate-changes objects page-id unames selected delta)
|
||||
uchanges (mapv #(array-map :type :del-obj :page-id page-id :id (:id %))
|
||||
|
|
|
@ -61,7 +61,10 @@
|
|||
do-unlock-shape #(st/emit! (dw/update-shape-flags id {:blocked false}))
|
||||
do-create-group #(st/emit! dw/group-selected)
|
||||
do-remove-group #(st/emit! dw/ungroup-selected)
|
||||
do-add-component #(st/emit! dwl/add-component)]
|
||||
do-add-component #(st/emit! dwl/add-component)
|
||||
do-detach-component #(st/emit! (dwl/detach-component id))
|
||||
do-reset-component #(st/emit! (dwl/reset-component id))
|
||||
do-update-component #(st/emit! (dwl/update-component id))]
|
||||
[:*
|
||||
[:& menu-entry {:title "Copy"
|
||||
:shortcut "Ctrl + c"
|
||||
|
@ -110,9 +113,18 @@
|
|||
:on-click do-lock-shape}])
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title "Create component"
|
||||
:shortcut "Ctrl + K"
|
||||
:on-click do-add-component}]
|
||||
|
||||
(if (nil? (:shape-ref shape))
|
||||
[:& menu-entry {:title "Create component"
|
||||
:shortcut "Ctrl + K"
|
||||
:on-click do-add-component}]
|
||||
[:*
|
||||
[:& menu-entry {:title "Detach instance"
|
||||
:on-click do-detach-component}]
|
||||
[:& menu-entry {:title "Reset overrides"
|
||||
:on-click do-reset-component}]
|
||||
[:& menu-entry {:title "Update master component"
|
||||
:on-click do-update-component}]])
|
||||
|
||||
[:& menu-separator]
|
||||
[:& menu-entry {:title "Delete"
|
||||
|
|
|
@ -69,8 +69,8 @@
|
|||
|
||||
on-drag-start
|
||||
(mf/use-callback
|
||||
(fn [path event]
|
||||
(dnd/set-data! event "text/uri-list" (cfg/resolve-media-path path))
|
||||
(fn [component-id event]
|
||||
(dnd/set-data! event "app/component" component-id)
|
||||
(dnd/set-allowed-effect! event "move")))]
|
||||
|
||||
[:div.asset-group
|
||||
|
@ -82,7 +82,7 @@
|
|||
[:div.grid-cell {:key (:id component)
|
||||
:draggable true
|
||||
:on-context-menu (on-context-menu (:id component))
|
||||
:on-drag-start (partial on-drag-start (:path component))}
|
||||
:on-drag-start (partial on-drag-start (:id component))}
|
||||
[:& exports/component-svg {:group (get-in component [:objects (:id component)])
|
||||
:objects (:objects component)}]
|
||||
[:div.cell-name (:name component)]])
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.main.constants :as c]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.drawing :as dd]
|
||||
[app.main.data.colors :as dwc]
|
||||
[app.main.data.fetch :as mdf]
|
||||
|
@ -454,6 +455,7 @@
|
|||
on-drag-enter
|
||||
(fn [e]
|
||||
(when (or (dnd/has-type? e "app/shape")
|
||||
(dnd/has-type? e "app/component")
|
||||
(dnd/has-type? e "Files")
|
||||
(dnd/has-type? e "text/uri-list"))
|
||||
(dom/prevent-default e)))
|
||||
|
@ -461,6 +463,7 @@
|
|||
on-drag-over
|
||||
(fn [e]
|
||||
(when (or (dnd/has-type? e "app/shape")
|
||||
(dnd/has-type? e "app/component")
|
||||
(dnd/has-type? e "Files")
|
||||
(dnd/has-type? e "text/uri-list"))
|
||||
(dom/prevent-default e)))
|
||||
|
@ -491,6 +494,10 @@
|
|||
(assoc :x final-x)
|
||||
(assoc :y final-y)))))
|
||||
|
||||
(dnd/has-type? event "app/component")
|
||||
(let [component-id (dnd/get-data event "app/component")]
|
||||
(st/emit! (dwl/instantiate-component component-id)))
|
||||
|
||||
(dnd/has-type? event "text/uri-list")
|
||||
(let [data (dnd/get-data event "text/uri-list")
|
||||
lines (str/lines data)
|
||||
|
|
Loading…
Add table
Reference in a new issue