🎉 Update master component

This commit is contained in:
Andrés Moya 2020-09-09 11:19:29 +02:00
parent 917643489f
commit f837bad894
10 changed files with 337 additions and 166 deletions

View file

@ -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)

View file

@ -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})))))))

View file

@ -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}))))))

View file

@ -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 %))

View file

@ -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"

View file

@ -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)]])

View file

@ -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)