Create nested frames from selection

This commit is contained in:
alonso.torres 2022-06-06 21:45:14 +02:00
parent c8ad379bf8
commit 79a46efa35
4 changed files with 46 additions and 40 deletions

View file

@ -227,17 +227,19 @@
(defn is-shape-over-shape? (defn is-shape-over-shape?
[objects base-shape-id over-shape-id] [objects base-shape-id over-shape-id]
(let [[base parent-a parent-b] (get-base objects base-shape-id over-shape-id)] (let [[base index-a index-b] (get-base objects base-shape-id over-shape-id)]
(cond (cond
(= base base-shape-id) (= base base-shape-id)
;; over-shape is a child of base-shape. Will be over if base is a root-frame
(= uuid/zero (get-in objects [base-shape-id :parent-id])) (and (frame-shape? objects over-shape-id)
(root-frame? objects over-shape-id))
(= base over-shape-id) (= base over-shape-id)
(not= uuid/zero (get-in objects [over-shape-id :parent-id])) (or (not (frame-shape? objects over-shape-id))
(not (root-frame? objects over-shape-id)))
:else :else
(< parent-a parent-b)))) (> index-a index-b))))
(defn sort-z-index (defn sort-z-index
([objects ids] ([objects ids]
@ -266,17 +268,11 @@
(defn frame-id-by-position (defn frame-id-by-position
[objects position] [objects position]
(let [frames (->> (get-frames objects) (let [top-frame
(filter #(and position (gsh/has-point? % position)))) (->> (get-frames-ids objects)
(sort-z-index objects)
top-frame (d/seek #(and position (gsh/has-point? (get objects %) position))))]
(reduce (fn [current-top frame] (or top-frame uuid/zero)))
(if (is-shape-over-shape? objects (:id current-top) (:id frame))
frame
current-top))
(first frames)
(rest frames))]
(or (:id top-frame) uuid/zero)))
(defn frame-by-position (defn frame-by-position
[objects position] [objects position]
@ -630,3 +626,8 @@
(-> (select-keys objects selected+parents) (-> (select-keys objects selected+parents)
(d/update-vals remove-children)))) (d/update-vals remove-children))))
(defn is-child?
[objects parent-id candidate-child-id]
(let [parents (get-parents-seq objects candidate-child-id)]
(some? (d/seek #(= % parent-id) parents))))

View file

@ -1673,20 +1673,22 @@
(watch [_ state _] (watch [_ state _]
(let [page-id (:current-page-id state) (let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id) objects (wsh/lookup-page-objects state page-id)
shapes (cph/get-immediate-children objects)
selected (wsh/lookup-selected state) selected (wsh/lookup-selected state)
selected-objs (map #(get objects %) selected) selected-objs (map #(get objects %) selected)]
has-frame? (some #(= (:type %) :frame) selected-objs)] (when (d/not-empty? selected)
(when (not (or (empty? selected) has-frame?))
(let [srect (gsh/selection-rect selected-objs) (let [srect (gsh/selection-rect selected-objs)
frame-id (:frame-id (first shapes)) frame-id (get-in objects [(first selected) :frame-id])
parent-id (get-in objects [(first selected) :parent-id])
shape (-> (cp/make-minimal-shape :frame) shape (-> (cp/make-minimal-shape :frame)
(merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)}) (merge {:x (:x srect) :y (:y srect) :width (:width srect) :height (:height srect)})
(assoc :frame-id frame-id) (assoc :frame-id frame-id :parent-id parent-id)
(cond-> (not= frame-id uuid/zero)
(assoc :fills [] :hide-in-viewer true))
(cp/setup-rect-selrect))] (cp/setup-rect-selrect))]
(rx/of (rx/of
(dwu/start-undo-transaction) (dwu/start-undo-transaction)
(dwc/add-shape shape) (dwc/add-shape shape)
(dwc/move-shapes-into-frame (:id shape) selected) (dwc/move-shapes-into-frame (:id shape) selected)
(dwu/commit-undo-transaction)))))))) (dwu/commit-undo-transaction))))))))

View file

@ -313,7 +313,10 @@
selected) selected)
changes (-> (pcb/empty-changes it page-id) changes (-> (pcb/empty-changes it page-id)
(pcb/add-object shape #_{:index (when (= :frame (:type shape)) 0)}))] (pcb/with-objects objects)
(pcb/add-object shape)
(cond-> (some? (:parent-id attrs))
(pcb/change-parent (:parent-id attrs) [shape])))]
(rx/concat (rx/concat
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)

View file

@ -8,6 +8,7 @@
(:require (:require
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.math :as mth] [app.common.math :as mth]
[app.common.pages.helpers :as cph]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.config :as cfg] [app.config :as cfg]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
@ -165,6 +166,7 @@
(defn on-double-click (defn on-double-click
[hover hover-ids drawing-path? objects edition] [hover hover-ids drawing-path? objects edition]
(mf/use-callback (mf/use-callback
(mf/deps @hover @hover-ids drawing-path? edition) (mf/deps @hover @hover-ids drawing-path? edition)
(fn [event] (fn [event]
@ -174,30 +176,28 @@
alt? (kbd/alt? event) alt? (kbd/alt? event)
meta? (kbd/meta? event) meta? (kbd/meta? event)
{:keys [id type] :as shape} @hover {:keys [id type] :as shape} (or @hover (get objects (first @hover-ids)))
frame? (= :frame type) editable? (contains? #{:text :rect :path :image :circle} type)]
group? (= :group type)]
(st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?)) (st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?))
;; Emit asynchronously so the double click to exit shapes won't break ;; Emit asynchronously so the double click to exit shapes won't break
(timers/schedule (timers/schedule
#(when (and (not drawing-path?) shape) (fn []
(cond (when (and (not drawing-path?) shape)
frame? (cond
(st/emit! (dw/select-shape id shift?)) (and editable? (not= id edition))
(st/emit! (dw/select-shape id)
(dw/start-editing-selected))
(and group? (> (count @hover-ids) 1)) :else
(let [selected (get objects (second @hover-ids))] (let [;; We only get inside childrens of the hovering shape
(reset! hover selected) hover-ids (->> @hover-ids (filter (partial cph/is-child? objects id)))
(reset! hover-ids (into [] (rest @hover-ids))) selected (get objects (if (> (count hover-ids) 1) (second hover-ids) (first hover-ids)))]
(when (some? selected)
(st/emit! (dw/select-shape (:id selected)))) (reset! hover selected)
(st/emit! (dw/select-shape (:id selected)))))))))))))
(not= id edition)
(st/emit! (dw/select-shape id)
(dw/start-editing-selected)))))))))
(defn on-context-menu (defn on-context-menu
[hover hover-ids] [hover hover-ids]