mirror of
https://github.com/penpot/penpot.git
synced 2025-02-10 00:58:26 -05:00
Merge pull request #254 from uxbox/other/coll-of-issues
Issues related to groups & layers
This commit is contained in:
commit
51acd2b529
17 changed files with 132 additions and 129 deletions
|
@ -17,21 +17,33 @@
|
|||
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
|
||||
[ring.middleware.params :refer [wrap-params]]
|
||||
[uxbox.common.spec :as us]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.http.session :refer [wrap-auth]]
|
||||
[uxbox.services.notifications :as nf]))
|
||||
|
||||
(s/def ::file-id ::us/uuid)
|
||||
(s/def ::session-id ::us/uuid)
|
||||
|
||||
(s/def ::websocket-params
|
||||
(s/keys :req-un [::file-id ::session-id]))
|
||||
|
||||
(defn websocket
|
||||
[{:keys [profile-id] :as req}]
|
||||
(let [params (us/conform ::websocket-params (:params req))
|
||||
params (assoc params :profile-id profile-id)]
|
||||
(if profile-id
|
||||
(nf/websocket params)
|
||||
{:error {:code 403 :message "Authentication required"}})))
|
||||
file (db/get-by-id db/pool :file (:file-id params))
|
||||
params (assoc params
|
||||
:profile-id profile-id
|
||||
:file file)]
|
||||
|
||||
(cond
|
||||
(not profile-id)
|
||||
{:error {:code 403 :message "Authentication required"}}
|
||||
|
||||
(not file)
|
||||
{:error {:code 404 :message "File does not exists"}}
|
||||
|
||||
:else
|
||||
(nf/websocket params))))
|
||||
|
||||
(def handler
|
||||
(-> websocket
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
;; 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/.
|
||||
;;
|
||||
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
;; defined by the Mozilla Public License, v. 2.0.
|
||||
;;
|
||||
;; Copyright (c) 2020 UXBOX Labs SL
|
||||
|
||||
(ns uxbox.services.notifications
|
||||
|
|
|
@ -32,9 +32,7 @@
|
|||
(fn [v] (into {} v))))
|
||||
|
||||
(def point-read-handler
|
||||
(t/read-handler
|
||||
(fn [value]
|
||||
(gpt/map->Point value))))
|
||||
(t/read-handler gpt/map->Point))
|
||||
|
||||
(def matrix-write-handler
|
||||
(t/write-handler
|
||||
|
@ -42,9 +40,7 @@
|
|||
(fn [v] (into {} v))))
|
||||
|
||||
(def matrix-read-handler
|
||||
(t/read-handler
|
||||
(fn [value]
|
||||
(gmt/map->Matrix value))))
|
||||
(t/read-handler gmt/map->Matrix))
|
||||
|
||||
(def +read-handlers+
|
||||
(assoc dt/+read-handlers+
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
[uxbox.services.mutations.colors :as colors]
|
||||
[uxbox.fixtures :as fixtures]
|
||||
[uxbox.migrations]
|
||||
[uxbox.images]
|
||||
[uxbox.media]
|
||||
[uxbox.db :as db]
|
||||
[uxbox.util.blob :as blob]
|
||||
|
@ -44,6 +45,7 @@
|
|||
#'uxbox.db/pool
|
||||
#'uxbox.redis/client
|
||||
#'uxbox.redis/conn
|
||||
#'uxbox.images/semaphore
|
||||
#'uxbox.services.init/query-services
|
||||
#'uxbox.services.init/mutation-services
|
||||
#'uxbox.migrations/migrations
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
(t/is (= [id3 id1 id2] (get-in res [:objects uuid/zero :shapes])))))
|
||||
))
|
||||
|
||||
(t/deftest process-changes-move-objects
|
||||
(t/deftest process-change-move-objects
|
||||
(let [frame-a-id (uuid/custom 1)
|
||||
frame-b-id (uuid/custom 2)
|
||||
group-a-id (uuid/custom 3)
|
||||
|
@ -391,10 +391,10 @@
|
|||
(t/is (= data res))))))
|
||||
|
||||
|
||||
(t/deftest process-changes-move-objects-3
|
||||
(t/deftest process-change-move-objects-regression
|
||||
(let [shape-2-id (uuid/custom 1 2)
|
||||
shape-3-id (uuid/custom 1 3)
|
||||
frame-id (uuid/custom 1 1)
|
||||
frame-id (uuid/custom 1 1)
|
||||
changes [{:type :add-obj
|
||||
:id frame-id
|
||||
:frame-id uuid/zero
|
||||
|
@ -426,7 +426,7 @@
|
|||
(get-in data [:objects shape-3-id :frame-id])))))))
|
||||
|
||||
|
||||
(t/deftest process-changes-move-objects-2
|
||||
(t/deftest process-change-move-objects-2
|
||||
(let [shape-1-id (uuid/custom 1 1)
|
||||
shape-2-id (uuid/custom 1 2)
|
||||
shape-3-id (uuid/custom 1 3)
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
(t/is (= image-id (:id result)))
|
||||
(t/is (= "testfile" (:name result)))
|
||||
(t/is (= "image/jpeg" (:mtype result)))
|
||||
(t/is (= "image/webp" (:thumb-mtype result))))
|
||||
(t/is (= "image/jpeg" (:thumb-mtype result))))
|
||||
|
||||
(let [data2 {::sm/type :import-image-to-file
|
||||
:image-id image-id
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
(t/is (= image-id (get-in out [:result :id])))
|
||||
(t/is (= "testfile" (get-in out [:result :name])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result :mtype])))
|
||||
(t/is (= "image/webp" (get-in out [:result :thumb-mtype])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result :thumb-mtype])))
|
||||
(t/is (= 800 (get-in out [:result :width])))
|
||||
(t/is (= 800 (get-in out [:result :height])))
|
||||
|
||||
|
@ -148,7 +148,7 @@
|
|||
(t/is (= image-id (get-in out [:result 0 :id])))
|
||||
(t/is (= "testfile" (get-in out [:result 0 :name])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result 0 :mtype])))
|
||||
(t/is (= "image/webp" (get-in out [:result 0 :thumb-mtype])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result 0 :thumb-mtype])))
|
||||
(t/is (= 800 (get-in out [:result 0 :width])))
|
||||
(t/is (= 800 (get-in out [:result 0 :height])))
|
||||
|
||||
|
@ -167,7 +167,7 @@
|
|||
(t/is (= image-id (get-in out [:result :id])))
|
||||
(t/is (= "testfile" (get-in out [:result :name])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result :mtype])))
|
||||
(t/is (= "image/webp" (get-in out [:result :thumb-mtype])))
|
||||
(t/is (= "image/jpeg" (get-in out [:result :thumb-mtype])))
|
||||
(t/is (= 800 (get-in out [:result :width])))
|
||||
(t/is (= 800 (get-in out [:result :height])))
|
||||
|
||||
|
|
|
@ -48,11 +48,7 @@
|
|||
(update :y inc-y))))]
|
||||
(-> shape
|
||||
(update :x inc-x)
|
||||
(update :x1 inc-x)
|
||||
(update :x2 inc-x)
|
||||
(update :y inc-y)
|
||||
(update :y1 inc-y)
|
||||
(update :y2 inc-y)
|
||||
(update-in [:selrect :x] inc-x)
|
||||
(update-in [:selrect :x1] inc-x)
|
||||
(update-in [:selrect :x2] inc-x)
|
||||
|
@ -197,11 +193,10 @@
|
|||
(us/assert number? width)
|
||||
(us/assert number? height)
|
||||
(-> shape
|
||||
(assoc :width width
|
||||
:height height
|
||||
:x2 (+ (:x1 shape) width)
|
||||
:y2 (+ (:y1 shape) height))
|
||||
(update :selrect (nilf #(resize % width height)))))
|
||||
(assoc :width width :height height)
|
||||
(update :selrect (fn [shape]
|
||||
(assoc :x2 (+ (:x1 shape) width)
|
||||
:y2 (+ (:y1 shape) height))))))
|
||||
|
||||
;; --- Setup (Initialize)
|
||||
|
||||
|
@ -232,14 +227,11 @@
|
|||
|
||||
(defn- setup-image
|
||||
[{:keys [metadata] :as shape} {:keys [x y width height] :as props}]
|
||||
(assoc shape
|
||||
:x x
|
||||
:y y
|
||||
:width width
|
||||
:height height
|
||||
:proportion (/ (:width metadata)
|
||||
(:height metadata))
|
||||
:proportion-lock true))
|
||||
(-> (setup-rect shape props)
|
||||
(assoc
|
||||
:proportion (/ (:width metadata)
|
||||
(:height metadata))
|
||||
:proportion-lock true)))
|
||||
|
||||
;; --- Coerce to Rect-like shape.
|
||||
|
||||
|
@ -247,30 +239,16 @@
|
|||
(declare group->rect-shape)
|
||||
(declare rect->rect-shape)
|
||||
|
||||
;; TODO: completly remove
|
||||
|
||||
(defn shape->rect-shape
|
||||
"Coerce shape to rect like shape."
|
||||
|
||||
[{:keys [type] :as shape}]
|
||||
(case type
|
||||
(:curve :path) (path->rect-shape shape)
|
||||
(rect->rect-shape shape)))
|
||||
|
||||
(defn shapes->rect-shape
|
||||
[shapes]
|
||||
(let [shapes (mapv shape->rect-shape shapes)
|
||||
minx (transduce (map :x1) min ##Inf shapes)
|
||||
miny (transduce (map :y1) min ##Inf shapes)
|
||||
maxx (transduce (map :x2) max ##-Inf shapes)
|
||||
maxy (transduce (map :y2) max ##-Inf shapes)]
|
||||
{:x1 minx
|
||||
:y1 miny
|
||||
:x2 maxx
|
||||
:y2 maxy
|
||||
:x minx
|
||||
:y miny
|
||||
:width (- maxx minx)
|
||||
:height (- maxy miny)
|
||||
:type :rect}))
|
||||
|
||||
;; -- Points
|
||||
|
||||
(declare transform-shape-point)
|
||||
|
@ -603,10 +581,10 @@
|
|||
|
||||
(defn pad-selrec
|
||||
([selrect] (pad-selrec selrect 1))
|
||||
([selrec size]
|
||||
([selrect size]
|
||||
(let [inc #(+ % size)
|
||||
dec #(- % size)]
|
||||
(-> selrec
|
||||
(-> selrect
|
||||
(update :x dec)
|
||||
(update :y dec)
|
||||
(update :x1 dec)
|
||||
|
@ -728,10 +706,6 @@
|
|||
(-> rect-shape
|
||||
(update :x check)
|
||||
(update :y check)
|
||||
(update :x1 check)
|
||||
(update :y1 check)
|
||||
(update :x2 check)
|
||||
(update :y2 check)
|
||||
(update :width (comp to-positive check))
|
||||
(update :height (comp to-positive check)))))
|
||||
|
||||
|
|
|
@ -440,9 +440,16 @@
|
|||
(defmethod process-change :del-obj
|
||||
[data {:keys [id] :as change}]
|
||||
(when-let [{:keys [frame-id shapes] :as obj} (get-in data [:objects id])]
|
||||
(let [data (update data :objects dissoc id)]
|
||||
(let [objects (:objects data)
|
||||
parent-id (get-parent id objects)
|
||||
parent (get objects parent-id)
|
||||
data (update data :objects dissoc id)]
|
||||
(cond-> data
|
||||
(contains? (:objects data) frame-id)
|
||||
(and (not= parent-id frame-id)
|
||||
(= :group (:type parent)))
|
||||
(update-in [:objects parent-id :shapes] (fn [s] (filterv #(not= % id) s)))
|
||||
|
||||
(contains? objects frame-id)
|
||||
(update-in [:objects frame-id :shapes] (fn [s] (filterv #(not= % id) s)))
|
||||
|
||||
(seq shapes) ; Recursive delete all dependend objects
|
||||
|
|
|
@ -659,18 +659,27 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
session-id (:session-id state)
|
||||
objects (get-in state [:workspace-data page-id :objects])
|
||||
cpindex (cp/calculate-child-parent-map objects)
|
||||
|
||||
del-change #(array-map :type :del-obj :id %)
|
||||
|
||||
get-empty-parents
|
||||
(fn get-empty-parents [id]
|
||||
(let [parent (get objects (get cpindex id))]
|
||||
(if (and (= :group (:type parent))
|
||||
(= 1 (count (:shapes parent))))
|
||||
(lazy-seq (cons (:id parent)
|
||||
(get-empty-parents (:id parent))))
|
||||
nil)))
|
||||
|
||||
rchanges
|
||||
(reduce (fn [res id]
|
||||
(let [chd (cp/get-children id objects)]
|
||||
(into res (d/concat
|
||||
(mapv del-change (reverse chd))
|
||||
[(del-change id)]))))
|
||||
[(del-change id)]
|
||||
(map del-change (get-empty-parents id))))))
|
||||
[]
|
||||
ids)
|
||||
|
||||
|
@ -1200,8 +1209,8 @@
|
|||
:width (:width selection-rect)
|
||||
:height (:height selection-rect)})
|
||||
|
||||
(def create-group
|
||||
(ptk/reify ::create-group
|
||||
(def group-selected
|
||||
(ptk/reify ::group-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [id (uuid/next)
|
||||
|
@ -1209,21 +1218,23 @@
|
|||
(when (not-empty selected)
|
||||
(let [page-id (get-in state [:workspace-page :id])
|
||||
objects (get-in state [:workspace-data page-id :objects])
|
||||
|
||||
selected-objects (map (partial get objects) selected)
|
||||
selection-rect (geom/selection-rect selected-objects)
|
||||
selrect (geom/selection-rect selected-objects)
|
||||
frame-id (-> selected-objects first :frame-id)
|
||||
group-shape (group-shape id frame-id selected selection-rect)
|
||||
frame-children (get-in objects [frame-id :shapes])
|
||||
index-frame (->> frame-children
|
||||
(map-indexed vector)
|
||||
(filter #(selected (second %)))
|
||||
(ffirst))
|
||||
group (-> (group-shape id frame-id selected selrect)
|
||||
(geom/setup selrect))
|
||||
|
||||
index (->> (get-in objects [frame-id :shapes])
|
||||
(map-indexed vector)
|
||||
(filter #(selected (second %)))
|
||||
(ffirst))
|
||||
|
||||
rchanges [{:type :add-obj
|
||||
:id id
|
||||
:frame-id frame-id
|
||||
:obj group-shape
|
||||
:index index-frame}
|
||||
:obj group
|
||||
:index index}
|
||||
{:type :mov-objects
|
||||
:parent-id id
|
||||
:shapes (vec selected)}]
|
||||
|
@ -1235,8 +1246,8 @@
|
|||
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
|
||||
(dws/select-shapes #{id}))))))))
|
||||
|
||||
(def remove-group
|
||||
(ptk/reify ::remove-group
|
||||
(def ungroup-selected
|
||||
(ptk/reify ::ungroup-selected
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [page-id (:current-page-id state)
|
||||
|
@ -1405,8 +1416,8 @@
|
|||
"ctrl+shift+'" #(st/emit! (toggle-layout-flag :snap-grid))
|
||||
"+" #(st/emit! (increase-zoom nil))
|
||||
"-" #(st/emit! (decrease-zoom nil))
|
||||
"g" #(st/emit! create-group)
|
||||
"shift+g" #(st/emit! remove-group)
|
||||
"g" #(st/emit! group-selected)
|
||||
"shift+g" #(st/emit! ungroup-selected)
|
||||
"shift+0" #(st/emit! reset-zoom)
|
||||
"shift+1" #(st/emit! zoom-to-fit-all)
|
||||
"shift+2" #(st/emit! zoom-to-selected-shape)
|
||||
|
|
|
@ -67,14 +67,13 @@
|
|||
(letfn [(resize-shape [{:keys [x y width height] :as shape} point lock? point-snap]
|
||||
(let [;; The new shape behaves like a resize on the bottom-right corner
|
||||
initial (gpt/point (+ x width) (+ y height))
|
||||
shape' (geom/shape->rect-shape shape)
|
||||
shapev (gpt/point (:width shape') (:height shape'))
|
||||
deltav (gpt/to-vec initial point-snap)
|
||||
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
||||
scalev (if lock?
|
||||
(let [v (max (:x scalev) (:y scalev))]
|
||||
(gpt/point v v))
|
||||
scalev)]
|
||||
shapev (gpt/point width height)
|
||||
deltav (gpt/to-vec initial point-snap)
|
||||
scalev (gpt/divide (gpt/add shapev deltav) shapev)
|
||||
scalev (if lock?
|
||||
(let [v (max (:x scalev) (:y scalev))]
|
||||
(gpt/point v v))
|
||||
scalev)]
|
||||
(-> shape
|
||||
(assoc-in [:modifiers :resize-vector] scalev)
|
||||
(assoc-in [:modifiers :resize-origin] (gpt/point x y))
|
||||
|
@ -87,45 +86,46 @@
|
|||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [{:keys [flags]} (:workspace-local state)
|
||||
|
||||
stoper? #(or (ms/mouse-up? %) (= % :interrupt))
|
||||
stoper (rx/filter stoper? stream)
|
||||
stoper (rx/filter stoper? stream)
|
||||
initial @ms/mouse-position
|
||||
|
||||
page-id (get state :current-page-id)
|
||||
objects (get-in state [:workspace-data page-id :objects])
|
||||
layout (get state :workspace-layout)
|
||||
layout (get state :workspace-layout)
|
||||
|
||||
frames (->> objects
|
||||
vals
|
||||
(filter (comp #{:frame} :type))
|
||||
(remove #(= (:id %) uuid/zero) ))
|
||||
|
||||
frame-id (or (->> frames
|
||||
(filter #(geom/has-point? % initial))
|
||||
first
|
||||
:id)
|
||||
uuid/zero)
|
||||
frames (cp/select-frames objects)
|
||||
fid (or (->> frames
|
||||
(filter #(geom/has-point? % initial))
|
||||
first
|
||||
:id)
|
||||
uuid/zero)
|
||||
|
||||
shape (-> state
|
||||
(get-in [:workspace-local :drawing])
|
||||
(geom/setup {:x (:x initial) :y (:y initial) :width 1 :height 1})
|
||||
(assoc :frame-id frame-id)
|
||||
(assoc :frame-id fid)
|
||||
(assoc ::initialized? true))]
|
||||
(rx/concat
|
||||
;; Add shape to drawing state
|
||||
(rx/of #(assoc-in state [:workspace-local :drawing] shape))
|
||||
|
||||
;; Initial SNAP
|
||||
(->> (snap/closest-snap-point page-id [shape] layout initial)
|
||||
(rx/map (fn [{:keys [x y]}]
|
||||
#(-> %
|
||||
(assoc-in [:workspace-local :drawing :x] x)
|
||||
(assoc-in [:workspace-local :drawing :y] y)))))
|
||||
#(update-in % [:workspace-local :drawing] assoc :x x :y y))))
|
||||
|
||||
(->> ms/mouse-position
|
||||
(rx/with-latest vector ms/mouse-position-ctrl)
|
||||
(rx/switch-map (fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map (fn [[pt ctrl? point-snap]] #(update-drawing % pt ctrl? point-snap)))
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] layout point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map
|
||||
(fn [[pt ctrl? point-snap]]
|
||||
#(update-drawing % pt ctrl? point-snap)))
|
||||
|
||||
(rx/take-until stoper))
|
||||
(rx/of handle-finish-drawing)))))))
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
(defn- calculate-dimensions
|
||||
[{:keys [objects] :as data} vport]
|
||||
(let [shapes (cp/select-toplevel-shapes objects {:include-frames? true})]
|
||||
(->> (geom/shapes->rect-shape shapes)
|
||||
(->> (geom/selection-rect shapes)
|
||||
(geom/adjust-to-viewport vport)
|
||||
(geom/fix-invalid-rect-values))))
|
||||
|
||||
|
|
|
@ -58,8 +58,8 @@
|
|||
do-hide-shape #(st/emit! (dw/recursive-assign id :hidden true))
|
||||
do-lock-shape #(st/emit! (dw/recursive-assign id :blocked true))
|
||||
do-unlock-shape #(st/emit! (dw/recursive-assign id :blocked false))
|
||||
do-create-group #(st/emit! dw/create-group)
|
||||
do-remove-group #(st/emit! dw/remove-group)]
|
||||
do-create-group #(st/emit! dw/group-selected)
|
||||
do-remove-group #(st/emit! dw/ungroup-selected)]
|
||||
[:*
|
||||
[:& menu-entry {:title "Copy"
|
||||
:shortcut "Ctrl + c"
|
||||
|
|
|
@ -43,20 +43,6 @@
|
|||
(recur (first ids) (rest ids))
|
||||
false))))))
|
||||
|
||||
(defn use-mouse-over
|
||||
[{:keys [id] :as shape}]
|
||||
(mf/use-callback
|
||||
(mf/deps shape)
|
||||
(fn []
|
||||
(st/emit! (dws/change-hover-state id true)))))
|
||||
|
||||
(defn use-mouse-out
|
||||
[{:keys [id] :as shape}]
|
||||
(mf/use-callback
|
||||
(mf/deps shape)
|
||||
(fn []
|
||||
(st/emit! (dws/change-hover-state id false)))))
|
||||
|
||||
(defn frame-wrapper-factory
|
||||
[shape-wrapper]
|
||||
(let [frame-shape (frame/frame-shape shape-wrapper)]
|
||||
|
@ -93,7 +79,19 @@
|
|||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(st/emit! dw/deselect-all
|
||||
(dw/select-shape (:id shape)))))]
|
||||
(dw/select-shape (:id shape)))))
|
||||
|
||||
on-mouse-over
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape))
|
||||
(fn []
|
||||
(st/emit! (dws/change-hover-state (:id shape) true))))
|
||||
|
||||
on-mouse-out
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape))
|
||||
(fn []
|
||||
(st/emit! (dws/change-hover-state (:id shape) false))))]
|
||||
|
||||
(when-not (:hidden shape)
|
||||
[:g {:class (when selected? "selected")
|
||||
|
@ -115,8 +113,8 @@
|
|||
")")
|
||||
;; User may also select the frame with single click in the label
|
||||
:on-click on-double-click
|
||||
:on-mouse-over (use-mouse-over shape)
|
||||
:on-mouse-out (use-mouse-out shape)}
|
||||
:on-mouse-over on-mouse-over
|
||||
:on-mouse-out on-mouse-out}
|
||||
(:name shape)]
|
||||
[:*
|
||||
[:& frame-shape
|
||||
|
|
|
@ -153,9 +153,9 @@
|
|||
(fn [side {:keys [id] :as data}]
|
||||
(if (= side :center)
|
||||
(st/emit! (dw/relocate-shape id (:id item) 0))
|
||||
(let [to-index (if (= side :top) (inc index) index)
|
||||
(let [to-index (if (= side :top) (inc index) index)
|
||||
parent-id (cp/get-parent (:id item) objects)]
|
||||
(st/emit! (dw/relocate-shape id parent-id to-index)))))
|
||||
(st/emit! (dw/relocate-shape id parent-id to-index)))))
|
||||
|
||||
on-hold
|
||||
(fn []
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns uxbox.util.debug
|
||||
"Debugging utils")
|
||||
|
||||
(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center #_:simple-selection })
|
||||
(def debug-options #{:bounding-boxes :group :events :rotation-handler :resize-handler :selection-center #_:simple-selection})
|
||||
|
||||
(defonce ^:dynamic *debug* (atom #{}))
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
[objects]
|
||||
(let [shapes (->> (cp/select-toplevel-shapes objects {:include-frames? true})
|
||||
(map #(merge % (select-keys % [:x :y :width :height]))))
|
||||
bounds (geom/shapes->rect-shape shapes)
|
||||
bounds (geom/selection-rect shapes)
|
||||
bounds #js {:x (:x bounds)
|
||||
:y (:y bounds)
|
||||
:width (:width bounds)
|
||||
|
|
Loading…
Add table
Reference in a new issue