diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 9a20a8ec4..7fb531b32 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -153,6 +153,7 @@ (declare initialize-page-persistence) +(declare initialize-group-check) (defn initialize-page [page-id] @@ -169,7 +170,8 @@ ptk/WatchEvent (watch [_ state stream] - (rx/of (initialize-page-persistence page-id))))) + (rx/of (initialize-page-persistence page-id) + (initialize-group-check))))) (defn finalize-page [page-id] @@ -199,7 +201,7 @@ ptk/UpdateEvent (update [_ state] - (let [page-id (:page-id state) + (let [page-id (:current-page-id state) objects (get-in state [:workspace-data page-id :objects]) groups-to-adjust (->> ids (mapcat #(reverse (helpers/get-all-parents % objects))) @@ -207,13 +209,25 @@ (filter #(= (:type %) :group)) (map #(:id %)) distinct) - update-group (fn [state group] (let [objects (get-in state [:workspace-data page-id :objects]) - group-objects (map #(get objects %) (:shapes group)) + group-center (geom/center group) + group-objects (->> (:shapes group) + (map #(get objects %)) + (map #(-> % + (assoc :modifiers + (transforms/rotation-modifiers group-center % (- (:rotation group 0)))) + (geom/transform-shape)))) selrect (geom/selection-rect group-objects)] - (merge group (select-keys selrect [:x :y :width :height])))) + + ;; Rotate the group shape change the data and rotate back again + (-> group + (assoc-in [:modifiers :rotation] (- (:rotation group))) + (geom/transform-shape) + (merge (select-keys selrect [:x :y :width :height])) + (assoc-in [:modifiers :rotation] (:rotation group)) + (geom/transform-shape)))) reduce-fn #(update-in %1 [:workspace-data page-id :objects %2] (partial update-group %1))] diff --git a/frontend/src/uxbox/main/data/workspace/transforms.cljs b/frontend/src/uxbox/main/data/workspace/transforms.cljs index 761c0d93d..9a1c6ea49 100644 --- a/frontend/src/uxbox/main/data/workspace/transforms.cljs +++ b/frontend/src/uxbox/main/data/workspace/transforms.cljs @@ -250,27 +250,31 @@ #(merge % modifiers)))] (reduce update-shape state ids-with-children)))))) +(defn rotation-modifiers [center shape angle] + (let [displacement (let [shape-center (gsh/center shape)] + (-> (gmt/matrix) + (gmt/rotate angle center) + (gmt/rotate (- angle) shape-center)))] + {:rotation angle + :displacement displacement})) + + ;; Set-rotation is custom because applies different modifiers to each shape adjusting their position (defn set-rotation [delta-rotation shapes] (ptk/reify ::set-rotation + IUpdateGroup + (get-ids [_] (map :id shapes)) + ptk/UpdateEvent (update [_ state] (let [page-id (:current-page-id state)] - (letfn [(calculate-displacement [shape angle center] - (let [shape-center (gsh/center shape)] - (-> (gmt/matrix) - (gmt/rotate angle center) - (gmt/rotate (- angle) shape-center)))) - - (rotate-shape [state angle shape center] + (letfn [(rotate-shape [state angle shape center] (let [objects (get-in state [:workspace-data page-id :objects]) path [:workspace-data page-id :objects (:id shape) :modifiers] - ds (calculate-displacement shape angle center)] + modifiers (rotation-modifiers center shape angle)] (-> state - (assoc-in (conj path :rotation) angle) - (assoc-in (conj path :displacement) ds)))) - + (update-in path merge modifiers)))) (rotate-around-center [state angle center shapes] (reduce #(rotate-shape %1 angle %2 center) state shapes))] diff --git a/frontend/src/uxbox/main/ui/shapes/group.cljs b/frontend/src/uxbox/main/ui/shapes/group.cljs index 3059aa93f..3f6e0f421 100644 --- a/frontend/src/uxbox/main/ui/shapes/group.cljs +++ b/frontend/src/uxbox/main/ui/shapes/group.cljs @@ -76,7 +76,8 @@ :shape (geom/transform-shape frame shape) :children children :is-child-selected? is-child-selected?}] - [:& bounding-box {:shape shape :frame frame}]])))) + (when (not is-child-selected?) + [:& bounding-box {:shape shape :frame frame}])])))) (defn group-shape [shape-wrapper] diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs index fe5df7677..a0aae202f 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/circle.cljs @@ -18,6 +18,6 @@ [{:keys [shape] :as props}] [:div [:& measures-menu {:shape shape - :options #{:circle-size :position :rotation}}] + :options #{:size :position :rotation}}] [:& fill-menu {:shape shape}] [:& stroke-menu {:shape shape}]]) diff --git a/frontend/src/uxbox/util/debug.cljs b/frontend/src/uxbox/util/debug.cljs index 18f0a48f7..5aeef407d 100644 --- a/frontend/src/uxbox/util/debug.cljs +++ b/frontend/src/uxbox/util/debug.cljs @@ -3,7 +3,7 @@ (def debug-options #{:bounding-boxes :group :events #_:simple-selection}) -(defonce ^:dynamic *debug* (atom #{:bounding-boxes})) +(defonce ^:dynamic *debug* (atom #{})) (defn debug-all! [] (reset! *debug* debug-options)) (defn debug-none! [] (reset! *debug* #{})) diff --git a/frontend/src/uxbox/util/geom/shapes.cljs b/frontend/src/uxbox/util/geom/shapes.cljs index f403566fc..8fdf6c3a2 100644 --- a/frontend/src/uxbox/util/geom/shapes.cljs +++ b/frontend/src/uxbox/util/geom/shapes.cljs @@ -464,14 +464,16 @@ (declare transform-apply-modifiers) +(defn selection-rect-shape [shape] + (-> shape + (transform-apply-modifiers) + (shape->rect-shape))) + (defn selection-rect "Returns a rect that contains all the shapes and is aware of the rotation of each shape. Mainly used for multiple selection." [shapes] - (let [xf-resolve-shape (comp (map shape->rect-shape) - (map transform-apply-modifiers) - (map shape->rect-shape)) - + (let [xf-resolve-shape (map selection-rect-shape) shapes (into [] xf-resolve-shape shapes) minx (transduce (map :x1) min shapes) miny (transduce (map :y1) min shapes) diff --git a/frontend/src/uxbox/worker/selection.cljs b/frontend/src/uxbox/worker/selection.cljs index c2106a2ca..f39bc508a 100644 --- a/frontend/src/uxbox/worker/selection.cljs +++ b/frontend/src/uxbox/worker/selection.cljs @@ -92,10 +92,8 @@ (defn- resolve-object [state {:keys [id] :as item}] - (let [item (-> item - (geom/shape->rect-shape) - (geom/transform-apply-modifiers) - (geom/shape->rect-shape)) + (let [selection-rect (geom/selection-rect-shape item) + item (merge item (select-keys selection-rect [:x :y :width :height])) width (+ (:x item 0) (:width item 0)) height (+ (:y item 0) (:height item 0)) max (fnil max 0)]