Move auto-layout children

This commit is contained in:
alonso.torres 2022-10-14 14:44:10 +02:00
parent 025cac0228
commit c3ed46d3ab
22 changed files with 457 additions and 329 deletions

View file

@ -21,27 +21,37 @@
[beicon.core :as rx]
[potok.core :as ptk]))
(defn truncate-zero [num default]
(if (mth/almost-zero? num) default num))
(defn adjust-ratio
[point initial]
(let [v (gpt/to-vec point initial)
dx (mth/abs (:x v))
dy (mth/abs (:y v))
sx (mth/sign (:x v))
sy (mth/sign (:y v))]
(cond-> point
(> dx dy)
(assoc :y (- (:y point) (* sy (- dx dy))))
(> dy dx)
(assoc :x (- (:x point) (* sx (- dy dx)))))))
(defn resize-shape [{:keys [x y width height] :as shape} initial point lock?]
(let [draw-rect (gsh/make-rect initial (cond-> point lock? (adjust-ratio initial)))
shape-rect (gsh/make-rect x y width height)
scalev (gpt/point (/ (:width draw-rect) (:width shape-rect))
(/ (:height draw-rect) (:height shape-rect)))
movev (gpt/to-vec (gpt/point shape-rect) (gpt/point draw-rect))]
(defn resize-shape [{:keys [x y width height] :as shape} point lock?]
(let [;; The new shape behaves like a resize on the bottom-right corner
initial (gpt/point (+ x width) (+ y height))
shapev (gpt/point width height)
deltav (gpt/to-vec initial point)
scalev (-> (gpt/divide (gpt/add shapev deltav) shapev)
(update :x truncate-zero 0.01)
(update :y truncate-zero 0.01))
scalev (if lock?
(let [v (max (:x scalev) (:y scalev))]
(gpt/point v v))
scalev)]
(-> shape
(assoc :click-draw? false)
(gsh/transform-shape (ctm/resize scalev (gpt/point x y))))))
(gsh/transform-shape (ctm/resize scalev (gpt/point x y)))
(gsh/transform-shape (ctm/move movev)))))
(defn update-drawing [state point lock?]
(update-in state [:workspace-drawing :object] resize-shape point lock?))
(defn update-drawing [state initial point lock?]
(update-in state [:workspace-drawing :object] resize-shape initial point lock?))
(defn move-drawing
[{:keys [x y]}]
@ -57,8 +67,7 @@
layout (get state :workspace-layout)
snap-pixel? (contains? layout :snap-pixel-grid)
initial (cond-> @ms/mouse-position
snap-pixel? gpt/round)
initial (cond-> @ms/mouse-position snap-pixel? gpt/round)
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
@ -96,7 +105,7 @@
(rx/map #(conj current %)))))
(rx/map
(fn [[_ shift? point]]
#(update-drawing % (cond-> point snap-pixel? gpt/round) shift?)))
#(update-drawing % initial (cond-> point snap-pixel? gpt/round) shift?)))
(rx/take-until stoper))
(rx/of (common/handle-finish-drawing)))))))

View file

@ -51,8 +51,7 @@
(and click-draw? (not text?))
(-> (assoc :width min-side :height min-side)
(gsh/transform-shape (ctm/move (- (/ min-side 2)) (- (/ min-side 2))))
#_(ctm/add-move (- (/ min-side 2)) (- (/ min-side 2))))
(gsh/transform-shape (ctm/move (- (/ min-side 2)) (- (/ min-side 2)))))
(and click-draw? text?)
(assoc :height 17 :width 4 :grow-type :auto-width)

View file

@ -22,6 +22,7 @@
[app.main.data.workspace.edition :as dwe]
[app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.features :as features]
[app.main.streams :as ms]
@ -146,6 +147,10 @@
ids (cph/clean-loops objects ids)
lookup (d/getf objects)
layout-ids (->> ids
(mapcat (partial cph/get-parent-ids objects))
(filter (partial cph/layout-shape? objects)))
components-v2 (features/active-feature? state :components-v2)
groups-to-unmask
@ -266,7 +271,8 @@
(rx/of (dc/detach-comment-thread ids)
(dwsl/update-layout-positions all-parents)
(dch/commit-changes changes)))))))
(dch/commit-changes changes)
(dwsl/update-layout-positions layout-ids)))))))
(defn- viewport-center
[state]

View file

@ -11,6 +11,7 @@
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl]
[app.common.math :as mth]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.common :as cpc]
@ -137,8 +138,20 @@
snap-pixel? (and (not ignore-snap-pixel)
(contains? (:workspace-layout state) :snap-pixel-grid))
workspace-modifiers (:workspace-modifiers state)
modif-tree
(gsh/set-objects-modifiers ids objects (constantly modifiers) ignore-constraints snap-pixel?)]
(gsh/set-objects-modifiers
;; TODO LAYOUT: I don't like this
(concat (keys workspace-modifiers) ids)
objects
(fn [shape]
(let [modifiers (if (contains? ids (:id shape)) modifiers {})
old-modifiers-v3 (get-in state [:workspace-modifiers (:id shape) :modifiers :v3])]
(cond-> modifiers
(some? old-modifiers-v3)
(assoc :v3 old-modifiers-v3))))
ignore-constraints snap-pixel?)]
(update state :workspace-modifiers merge modif-tree))))))
@ -619,6 +632,40 @@
(rx/take 1)
(rx/map #(start-move from-position))))))
(defn set-change-frame-modifiers
[selected target-frame position]
(ptk/reify ::set-change-frame-modifiers
ptk/UpdateEvent
(update [_ state]
(let [objects (wsh/lookup-page-objects state)
origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
layout? (get-in objects [target-frame :layout])
drop-index
(when layout? (gsl/get-drop-index target-frame objects position))
modif-tree
(into {}
(mapcat
(fn [original-frame]
(let [shapes (->> (get origin-frame-ids original-frame)
(d/removev #(= target-frame %)))]
(cond
(not= original-frame target-frame)
[[original-frame {:modifiers {:v3 [{:type :remove-children :value shapes}]}}]
[target-frame {:modifiers {:v3 [{:type :add-children
:value shapes
:index drop-index}]}}]]
layout?
[[target-frame {:modifiers {:v3 [{:type :add-children
:value shapes
:index drop-index}]}}]]))))
(keys origin-frame-ids))]
(assoc state :workspace-modifiers modif-tree)))))
(defn- start-move
([from-position] (start-move from-position nil))
([from-position ids]
@ -664,17 +711,25 @@
(if (empty? shapes)
(rx/of (finish-transform))
(rx/concat
(->> position
;; We ask for the snap position but we continue even if the result is not available
(rx/with-latest vector snap-delta)
;; We try to use the previous snap so we don't have to wait for the result of the new
(rx/map snap/correct-snap-point)
(rx/merge
(->> position
(rx/map (fn [delta]
(let [position (gpt/add from-position delta)
target-frame (ctst/top-nested-frame objects position)]
(set-change-frame-modifiers selected target-frame position))))
(rx/take-until stopper))
#_(rx/map #(hash-map :displacement (gmt/translate-matrix %)))
(rx/map #(array-map :v2 [{:type :move :vector %}]))
(->> position
;; We ask for the snap position but we continue even if the result is not available
(rx/with-latest vector snap-delta)
(rx/map (partial set-modifiers ids))
(rx/take-until stopper))
;; We try to use the previous snap so we don't have to wait for the result of the new
(rx/map snap/correct-snap-point)
(rx/map (fn [move-vec] {:v2 [{:type :move :vector move-vec}]}))
(rx/map (partial set-modifiers ids))
(rx/take-until stopper)))
(rx/of (dwu/start-undo-transaction)
(calculate-frame-for-move ids)
@ -767,18 +822,22 @@
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame-id (ctst/top-nested-frame objects position)
layout? (get-in objects [frame-id :layout])
lookup (d/getf objects)
shapes (->> ids (cph/clean-loops objects) (keep lookup))
moving-shapes
(->> ids
(cph/clean-loops objects)
(keep lookup)
(remove #(= (:frame-id %) frame-id)))
(cond->> shapes
(not layout?)
(remove #(= (:frame-id %) frame-id)))
drop-index (when layout? (gsl/get-drop-index frame-id objects position))
changes
(-> (pcb/empty-changes it page-id)
(pcb/with-objects objects)
(pcb/change-parent frame-id moving-shapes))]
(pcb/change-parent frame-id moving-shapes drop-index))]
(when-not (empty? changes)
(rx/of (dch/commit-changes changes)

View file

@ -12,7 +12,9 @@
others are defined using a generic wrapper implemented in
common."
(:require
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid]
[app.main.ui.context :as ctx]
[app.main.ui.shapes.circle :as circle]
[app.main.ui.shapes.image :as image]
@ -55,33 +57,36 @@
(mf/deps objects)
#(cph/objects-by-frame objects))]
[:& (mf/provider ctx/active-frames) {:value active-frames}
;; 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)}])
[:g {:id (dm/str "shape-" uuid/zero)}
[:& (mf/provider ctx/active-frames) {:value active-frames}
;; 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 [shape shapes]
(cond
(not (cph/frame-shape? shape))
[:& shape-wrapper
{:shape shape
:key (:id shape)}]
[:g.frame-children
(for [shape shapes]
[:g.ws-shape-wrapper
(cond
(not (cph/frame-shape? shape))
[:& shape-wrapper
{:shape shape
:key (:id shape)}]
(cph/root-frame? shape)
[:& root-frame-wrapper
{:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape))
:thumbnail? (not (contains? active-frames (:id shape)))}]
(cph/root-frame? shape)
[:& root-frame-wrapper
{:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape))
:thumbnail? (not (contains? active-frames (:id shape)))}]
:else
[:& nested-frame-wrapper
{:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape))}]))]))
:else
[:& nested-frame-wrapper
{:shape shape
:key (:id shape)
:objects (get frame-objects (:id shape))}])])]]]))
(mf/defc shape-wrapper
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))]
@ -98,20 +103,21 @@
opts #js {:shape shape :thumbnail? thumbnail?}]
(when (and (some? shape) (not (:hidden shape)))
(case (:type shape)
:path [:> path/path-wrapper opts]
:text [:> text/text-wrapper opts]
:group [:> group-wrapper opts]
:rect [:> rect-wrapper opts]
:image [:> image-wrapper opts]
:circle [:> circle-wrapper opts]
:svg-raw [:> svg-raw-wrapper opts]
:bool [:> bool-wrapper opts]
[:g.ws-shape-wrapper
(case (:type shape)
:path [:> path/path-wrapper opts]
:text [:> text/text-wrapper opts]
:group [:> group-wrapper opts]
:rect [:> rect-wrapper opts]
:image [:> image-wrapper opts]
:circle [:> circle-wrapper opts]
:svg-raw [:> svg-raw-wrapper opts]
:bool [:> bool-wrapper opts]
;; Only used when drawing a new frame.
:frame [:> nested-frame-wrapper opts]
;; Only used when drawing a new frame.
:frame [:> nested-frame-wrapper opts]
nil))))
nil)])))
(def group-wrapper (group/group-wrapper-factory shape-wrapper))
(def svg-raw-wrapper (svg-raw/svg-raw-wrapper-factory shape-wrapper))

View file

@ -24,87 +24,7 @@
[app.main.ui.workspace.shapes.frame.node-store :as fns]
[app.main.ui.workspace.shapes.frame.thumbnail-render :as ftr]
[beicon.core :as rx]
[rumext.v2 :as mf]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.store :as st]))
(mf/defc debug-layout
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
children (-> (wsh/lookup-page-objects @st/state)
(cph/get-immediate-children (:id shape)))
layout-data (gsl/calc-layout-data shape children)
drop-areas
(gsl/drop-areas shape layout-data children)
]
[:g.debug-layout {:pointer-events "none"}
(for [[idx drop-area] (d/enumerate drop-areas)]
[:rect {:x (:x drop-area)
:y (:y drop-area)
:width (:width drop-area)
:height (:height drop-area)
:style {:fill "blue"
:fill-opacity 0.3
:stroke "red"
:stroke-width 1
:stroke-dasharray "3 6"}}])
#_(for [[idx layout-line] (d/enumerate (:layout-lines layout-data))]
(let [col? (gsl/col? shape)
row? (gsl/row? shape)
h-center? (and row? (gsl/h-center? shape))
h-end? (and row? (gsl/h-end? shape))
v-center? (and col? (gsl/v-center? shape))
v-end? (and row? (gsl/v-end? shape))
line-width
(+ (-> layout-line :line-width)
(:margin-x shape)
(if col?
(* (:layout-gap layout-line) (dec (-> layout-line :num-children)))
0))
line-height
(+ (-> layout-line :line-height)
(:margin-y shape)
(if row?
(* (:layout-gap layout-line) (dec (-> layout-line :num-children)))
0))
]
[:g {:key (dm/str "line-" idx)}
[:rect {:x (- (-> layout-line :start-p :x)
(cond
h-center? (/ line-width 2)
h-end? line-width
:else 0))
:y (- (-> layout-line :start-p :y)
(cond
v-center? (/ line-height 2)
v-end? line-height
:else 0))
:width line-width
:height line-height
:style {:fill "blue"
:fill-opacity 0.3}
}]
#_[:line {:x1 (-> layout-line :start-p :x)
:y1 (-> layout-line :start-p :y)
:x2 (+ (-> layout-line :start-p :x) (if col? line-width 0))
:y2 (+ (-> layout-line :start-p :y) (if row? line-height 0))
:transform (gsh/transform-str shape)
:style {:fill "none"
:stroke "red"
:stroke-width 2}}]]))]))
[rumext.v2 :as mf]))
(defn frame-shape-factory
[shape-wrapper]
@ -119,12 +39,9 @@
childs-ref (mf/use-memo (mf/deps (:id shape)) #(refs/children-objects (:id shape)))
childs (mf/deref childs-ref)]
[:*
[:& (mf/provider embed/context) {:value true}
[:& shape-container {:shape shape :ref ref :disable-shadows? (cph/root-frame? shape)}
[:& frame-shape {:shape shape :childs childs} ]]]
#_[:& debug-layout {:shape shape}]]))))
[:& (mf/provider embed/context) {:value true}
[:& shape-container {:shape shape :ref ref :disable-shadows? (cph/root-frame? shape)}
[:& frame-shape {:shape shape :childs childs} ]]]))))
(defn check-props
[new-props old-props]

View file

@ -13,8 +13,10 @@
[app.common.geom.shapes :as gsh]
[app.common.types.modifiers :as ctm]
[app.main.store :as st]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.viewport.utils :as vwu]
[app.util.dom :as dom]
[app.util.globals :as globals]
[rumext.v2 :as mf]))
(defn- transform-no-resize
@ -78,13 +80,20 @@
[result width height]))
(defn get-shape-node
([id]
(get-shape-node js/document id))
([base-node id]
(if (= (.-id base-node) (dm/str "shape-" id))
base-node
(dom/query base-node (dm/str "#shape-" id)))))
(defn get-nodes
"Retrieve the DOM nodes to apply the matrix transformation"
[base-node {:keys [id type masked-group?] :as shape}]
(when (some? base-node)
(let [shape-node (if (= (.-id base-node) (dm/str "shape-" id))
base-node
(dom/query base-node (dm/str "#shape-" id)))
(let [shape-node (get-shape-node base-node id)
frame? (= :frame type)
group? (= :group type)
@ -164,7 +173,7 @@
(defn set-transform-att!
[node att value]
(let [old-att (dom/get-attribute node (dm/str "data-old-" att))
new-value (if (some? old-att)
(dm/str value " " old-att)
@ -269,6 +278,33 @@
(ctm/modifiers->transform center modifiers)))
modifiers))))
structure-changes
(mf/use-memo
(mf/deps modifiers)
(fn []
(into {}
(comp (filter (fn [[_ val]] (-> val :modifiers :v3 some?)))
(map (fn [[key val]]
[key (-> val :modifiers :v3)])))
modifiers)))
structure-changes (hooks/use-equal-memo structure-changes)
add-children
(mf/use-memo
(mf/deps structure-changes)
(fn []
(into []
(mapcat (fn [[frame-id changes]]
(->> changes
(filter (fn [{:keys [type]}] (= type :add-children)))
(mapcat (fn [{:keys [value]}]
(->> value (map (fn [id] {:frame frame-id :shape id}))))))))
structure-changes)))
add-children-prev (hooks/use-previous add-children)
shapes
(mf/use-memo
(mf/deps transforms)
@ -280,6 +316,31 @@
prev-modifiers (mf/use-var nil)
prev-transforms (mf/use-var nil)]
(mf/use-effect
(mf/deps add-children)
(fn []
(doseq [{:keys [frame shape]} add-children-prev]
(let [frame-node (get-shape-node node frame)
shape-node (get-shape-node shape)
mirror-node (dom/query frame-node (dm/fmt ".mirror-shape[href='#shape-%'" shape))]
(when mirror-node (.remove mirror-node))
(dom/remove-attribute! (dom/get-parent shape-node) "display")))
(doseq [{:keys [frame shape]} add-children]
(let [frame-node (get-shape-node node frame)
shape-node (get-shape-node shape)
use-node
(.createElementNS globals/document "http://www.w3.org/2000/svg" "use")
contents-node
(or (dom/query frame-node ".frame-children") frame-node)]
(dom/set-attribute! use-node "href" (dm/fmt "#shape-%" shape))
(dom/add-class! use-node "mirror-shape")
(dom/append-child! contents-node use-node)
(dom/set-attribute! (dom/get-parent shape-node) "display" "none")))))
(mf/use-layout-effect
(mf/deps transforms)
(fn []

View file

@ -23,6 +23,7 @@
[app.main.ui.workspace.shapes.text.viewport-texts-html :as stvh]
[app.main.ui.workspace.viewport.actions :as actions]
[app.main.ui.workspace.viewport.comments :as comments]
[app.main.ui.workspace.viewport.debug :as wvd]
[app.main.ui.workspace.viewport.drawarea :as drawarea]
[app.main.ui.workspace.viewport.frame-grid :as frame-grid]
[app.main.ui.workspace.viewport.gradients :as gradients]
@ -41,85 +42,7 @@
[app.main.ui.workspace.viewport.widgets :as widgets]
[beicon.core :as rx]
[debug :refer [debug?]]
[rumext.v2 :as mf]
[app.common.uuid :as uuid]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.store :as st]
))
(mf/defc debug-layout
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
objects (unchecked-get props "objects")
children (cph/get-immediate-children objects (:id shape))
layout-data (gsl/calc-layout-data shape children)
drop-areas (gsl/drop-areas shape layout-data children)]
[:g.debug-layout {:pointer-events "none"}
(for [[idx drop-area] (d/enumerate drop-areas)]
[:rect {:x (:x drop-area)
:y (:y drop-area)
:width (:width drop-area)
:height (:height drop-area)
:style {:fill "blue"
:fill-opacity 0.3
:stroke "red"
:stroke-width 1
:stroke-dasharray "3 6"}}])
#_(for [[idx layout-line] (d/enumerate (:layout-lines layout-data))]
(let [col? (gsl/col? shape)
row? (gsl/row? shape)
h-center? (and row? (gsl/h-center? shape))
h-end? (and row? (gsl/h-end? shape))
v-center? (and col? (gsl/v-center? shape))
v-end? (and row? (gsl/v-end? shape))
line-width
(+ (-> layout-line :line-width)
(:margin-x shape)
(if col?
(* (:layout-gap layout-line) (dec (-> layout-line :num-children)))
0))
line-height
(+ (-> layout-line :line-height)
(:margin-y shape)
(if row?
(* (:layout-gap layout-line) (dec (-> layout-line :num-children)))
0))
]
[:g {:key (dm/str "line-" idx)}
[:rect {:x (- (-> layout-line :start-p :x)
(cond
h-center? (/ line-width 2)
h-end? line-width
:else 0))
:y (- (-> layout-line :start-p :y)
(cond
v-center? (/ line-height 2)
v-end? line-height
:else 0))
:width line-width
:height line-height
:style {:fill "blue"
:fill-opacity 0.3}
}]
#_[:line {:x1 (-> layout-line :start-p :x)
:y1 (-> layout-line :start-p :y)
:x2 (+ (-> layout-line :start-p :x) (if col? line-width 0))
:y2 (+ (-> layout-line :start-p :y) (if row? line-height 0))
:transform (gsh/transform-str shape)
:style {:fill "none"
:stroke "red"
:stroke-width 2}}]]))]))
[rumext.v2 :as mf]))
;; --- Viewport
@ -493,15 +416,12 @@
:hover-frame frame-parent
:disabled-guides? disabled-guides?}])
(let [selected-frame (when (= 1 (count selected-shapes))
(let [selected-shape (get objects-modified (first selected))]
(when (= :frame (:type selected-shape))
selected-shape)))
;; DEBUG LAYOUT DROP-ZONES
(when (debug? :layout-drop-zones)
[:& wvd/debug-layout {:selected-shapes selected-shapes
:objects objects-modified
:hover-top-frame-id @hover-top-frame-id}])
top-frame (or selected-frame (get objects-modified @hover-top-frame-id))]
(when (and top-frame (not= uuid/zero top-frame) (:layout top-frame))
[:& debug-layout {:shape top-frame
:objects objects-modified}]))
(when show-selection-handlers?
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}

View file

@ -0,0 +1,54 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.viewport.debug
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.geom.shapes.layout :as gsl]
[app.common.pages.helpers :as cph]
[rumext.v2 :as mf]))
(mf/defc debug-layout
"Debug component to show the auto-layout drop areas"
{::mf/wrap-props false}
[props]
(let [objects (unchecked-get props "objects")
selected-shapes (unchecked-get props "selected-shapes")
hover-top-frame-id (unchecked-get props "hover-top-frame-id")
selected-frame
(when (and (= (count selected-shapes) 1) (= :frame (-> selected-shapes first :type)))
(first selected-shapes))
shape (or selected-frame (get objects hover-top-frame-id))]
(when (and shape (:layout shape))
(let [children (cph/get-immediate-children objects (:id shape))
layout-data (gsl/calc-layout-data shape children)
drop-areas (gsl/drop-areas shape layout-data children)]
[:g.debug-layout {:pointer-events "none"
:transform (gsh/transform-str shape)}
(for [[idx drop-area] (d/enumerate drop-areas)]
[:g.drop-area {:key (dm/str "drop-area-" idx)}
[:rect {:x (:x drop-area)
:y (:y drop-area)
:width (:width drop-area)
:height (:height drop-area)
:style {:fill "blue"
:fill-opacity 0.3
:stroke "red"
:stroke-width 1
:stroke-dasharray "3 6"}}]
[:text {:x (:x drop-area)
:y (:y drop-area)
:width (:width drop-area)
:height (:height drop-area)
:alignment-baseline "hanging"
:fill "black"}
(:index drop-area)]])]))))

View file

@ -11,6 +11,7 @@
[app.common.pages :as cp]
[app.common.pages.helpers :as cph]
[app.common.types.shape-tree :as ctt]
[app.common.uuid :as uuid]
[app.main.data.shortcuts :as dsc]
[app.main.data.workspace :as dw]
[app.main.data.workspace.path.shortcuts :as psc]
@ -28,8 +29,7 @@
[beicon.core :as rx]
[debug :refer [debug?]]
[goog.events :as events]
[rumext.v2 :as mf]
[app.common.types.shape-tree :as ctst])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(defn setup-dom-events [viewport-ref zoom disable-paste in-viewport?]
@ -217,7 +217,7 @@
(get objects))]
(reset! hover hover-shape)
(reset! hover-ids ids)
(reset! hover-top-frame-id (ctst/top-nested-frame objects (deref last-point-ref))))))))
(reset! hover-top-frame-id (ctt/top-nested-frame objects (deref last-point-ref))))))))
(defn setup-viewport-modifiers
[modifiers objects]
@ -225,7 +225,7 @@
(mf/use-memo
(mf/deps objects)
#(ctt/get-root-shapes-ids objects))
modifiers (select-keys modifiers root-frame-ids)]
modifiers (select-keys modifiers (conj root-frame-ids uuid/zero))]
(sfd/use-dynamic-modifiers objects globals/document modifiers)))
(defn inside-vbox [vbox objects frame-id]

View file

@ -67,6 +67,9 @@
;; Disable frame thumbnails
:disable-frame-thumbnails
;; Enable a widget to show the auto-layout drop-zones
:layout-drop-zones
})
;; These events are excluded when we activate the :events flag
@ -294,9 +297,16 @@
num-nodes (->> (dom/seq-nodes root-node) count)]
#js {:number num-nodes}))
#_(defn modif->js
(defn modif->js
[modif-tree objects]
(clj->js (into {}
(map (fn [[k v]]
[(get-in objects [k :name]) v]))
modif-tree)))
(defn ^:export dump-modifiers
[]
(let [page-id (get @st/state :current-page-id)
objects (get-in @st/state [:workspace-data :pages-index page-id :objects])]
(.log js/console (modif->js (:workspace-modifiers @st/state) objects)))
nil)