From 9d0b71a36c50057470698ff3488e2a9ba91ef028 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 6 Apr 2020 15:19:14 +0200 Subject: [PATCH] :sparkles: Allow selection of elements inside group --- frontend/src/uxbox/main/data/workspace.cljs | 31 ++++++++++++++++++-- frontend/src/uxbox/main/refs.cljs | 25 ++++++++++++---- frontend/src/uxbox/main/ui/shapes/group.cljs | 28 ++++++++++-------- 3 files changed, 65 insertions(+), 19 deletions(-) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 843d2191d..afef7e2c1 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -1485,6 +1485,27 @@ (when-not (empty? rch) (rx/of (commit-changes rch uch {:commit-local? true})))))))) +(defn- adjust-group-shapes [state ids] + (let [page-id (::page-id state) + objects (get-in state [:workspace-data page-id :objects]) + groups-to-adjust (->> ids + (map #(helpers/get-parent % objects)) + (map #(get objects %)) + (filter #(= (:type %) :group)) + (map #(:id %)) + distinct) + + update-group + (fn [group] + (let [group-objects (map #(get objects %) (:shapes group)) + selrect (geom/selection-rect group-objects)] + (merge group (select-keys selrect [:x :y :width :height])))) + + reduce-fn + #(update-in %1 [:workspace-data page-id :objects %2] update-group)] + + (reduce reduce-fn state groups-to-adjust))) + (defn assoc-resize-modifier-in-bulk [ids xfmt] (us/verify ::set-of-uuid ids) @@ -1530,7 +1551,10 @@ (-> state (materialize-shape id mtx) (materialize-children id mtx)))))] - (reduce update-shapes state ids))) + + (as-> state $ + (reduce update-shapes $ ids) + (adjust-group-shapes $ ids)))) ptk/WatchEvent (watch [_ state stream] @@ -1558,6 +1582,7 @@ (assoc-in state [:workspace-data page-id :objects id]))))] (reduce rfn state ids))))) + (defn materialize-displacement-in-bulk [ids] (ptk/reify ::materialize-displacement-in-bulk @@ -1590,7 +1615,9 @@ (materialize-shape id mtx) (materialize-children id mtx))))] - (reduce update-shapes state ids))) + (as-> state $ + (reduce update-shapes $ ids) + (adjust-group-shapes $ ids)))) ptk/WatchEvent (watch [_ state stream] diff --git a/frontend/src/uxbox/main/refs.cljs b/frontend/src/uxbox/main/refs.cljs index 2a8fab50c..981cb315c 100644 --- a/frontend/src/uxbox/main/refs.cljs +++ b/frontend/src/uxbox/main/refs.cljs @@ -12,7 +12,8 @@ (:require [lentes.core :as l] [beicon.core :as rx] [uxbox.main.constants :as c] - [uxbox.main.store :as st])) + [uxbox.main.store :as st] + [uxbox.main.data.helpers :as helpers])) (def profile (-> (l/key :profile) @@ -62,10 +63,24 @@ (defn objects-by-id [ids] (let [set-ids (set ids)] - (-> (l/lens #(let [page-id (get-in % [:workspace-page :id]) - objects (get-in % [:workspace-data page-id :objects])] - (filter (fn [it] (set-ids (:id it))) (vals objects)))) - (l/derive st/state)))) + (-> (l/lens (fn [state] + (let [page-id (get-in state [:workspace-page :id]) + objects (get-in state [:workspace-data page-id :objects])] + (mapv #(get objects %) set-ids)))) + (l/derive st/state)))) + +(defn is-child-selected? [id] + (let [is-child-selector + (fn [state] + (let [page-id (get-in state [:workspace-page :id]) + objects (get-in state [:workspace-data page-id :objects]) + selected (get-in state [:workspace-local :selected]) + shape (get objects id) + children (helpers/get-children id objects)] + (some selected children)))] + + (-> (l/lens is-child-selector) + (l/derive st/state)))) (def selected-shapes (-> (l/key :selected) diff --git a/frontend/src/uxbox/main/ui/shapes/group.cljs b/frontend/src/uxbox/main/ui/shapes/group.cljs index d5bb51cab..eaea47d1a 100644 --- a/frontend/src/uxbox/main/ui/shapes/group.cljs +++ b/frontend/src/uxbox/main/ui/shapes/group.cljs @@ -15,7 +15,7 @@ [uxbox.main.ui.shapes.common :as common] [uxbox.main.ui.shapes.attrs :as attrs])) -(defonce ^:dynamic *debug* (atom false)) +(defonce ^:dynamic *debug* (atom true)) (declare translate-to-frame) (declare group-shape) @@ -29,6 +29,7 @@ on-mouse-down #(common/on-mouse-down % shape) on-context-menu #(common/on-context-menu % shape) children (-> (refs/objects-by-id (:shapes shape)) mf/deref) + is-child-selected? (-> (refs/is-child-selected? (:id shape)) mf/deref) on-double-click (fn [event] (dom/stop-propagation event) @@ -40,7 +41,8 @@ :on-double-click on-double-click} [:& (group-shape shape-wrapper) {:frame frame :shape (geom/transform-shape frame shape) - :children children}]]))) + :children children + :is-child-selected? is-child-selected?}]]))) (defn group-shape [shape-wrapper] (mf/fnc group-shape @@ -49,6 +51,7 @@ (let [frame (unchecked-get props "frame") shape (unchecked-get props "shape") children (unchecked-get props "children") + is-child-selected? (unchecked-get props "is-child-selected?") {:keys [id x y width height rotation displacement-modifier resize-modifier]} shape @@ -61,17 +64,18 @@ [:g {:transform transform} (for [item children] [:& shape-wrapper {:frame frame - :shape (-> item - (assoc :displacement-modifier displacement-modifier) - (assoc :resize-modifier resize-modifier)) + :shape (cond-> item + displacement-modifier (assoc :displacement-modifier displacement-modifier) + resize-modifier (assoc :resize-modifier resize-modifier)) :key (:id item)}]) - [:rect {:x x - :y y - :fill (if (deref *debug*) "red" "transparent") - :opacity 0.8 - :id (str "group-" id) - :width width - :height height}]]))) + (when (not is-child-selected?) + [:rect {:x x + :y y + :fill (if (deref *debug*) "red" "transparent") + :opacity 0.8 + :id (str "group-" id) + :width width + :height height}])])))