diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 74e243af8..1177b4f90 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -438,28 +438,28 @@ ;; - It consideres the center for everyshape instead of the center of the total selrect ;; - The angle param is the desired final value, not a delta (defn set-delta-rotation-modifiers - ([angle shapes] - (ptk/reify ::set-delta-rotation-modifiers - ptk/UpdateEvent - (update [_ state] - (let [objects (wsh/lookup-page-objects state) - ids - (->> shapes - (remove #(get % :blocked false)) - (filter #(contains? (get editable-attrs (:type %)) :rotation)) - (map :id)) + [angle shapes {:keys [center delta?] :or {center nil delta? false}}] + (ptk/reify ::set-delta-rotation-modifiers + ptk/UpdateEvent + (update [_ state] + (let [objects (wsh/lookup-page-objects state) + ids + (->> shapes + (remove #(get % :blocked false)) + (filter #(contains? (get editable-attrs (:type %)) :rotation)) + (map :id)) - get-modifier - (fn [shape] - (let [delta (- angle (:rotation shape)) - center (gsh/shape->center shape)] - (ctm/rotation-modifiers shape center delta))) + get-modifier + (fn [shape] + (let [delta (if delta? angle (- angle (:rotation shape))) + center (or center (gsh/shape->center shape))] + (ctm/rotation-modifiers shape center delta))) - modif-tree - (-> (build-modif-tree ids objects get-modifier) - (gm/set-objects-modifiers objects))] + modif-tree + (-> (build-modif-tree ids objects get-modifier) + (gm/set-objects-modifiers objects))] - (assoc state :workspace-modifiers modif-tree)))))) + (assoc state :workspace-modifiers modif-tree))))) (defn apply-modifiers ([] diff --git a/frontend/src/app/main/data/workspace/transforms.cljs b/frontend/src/app/main/data/workspace/transforms.cljs index 3107f9ace..c4e2a8064 100644 --- a/frontend/src/app/main/data/workspace/transforms.cljs +++ b/frontend/src/app/main/data/workspace/transforms.cljs @@ -400,17 +400,18 @@ (defn increase-rotation "Rotate shapes a fixed angle, from a keyboard action." - [ids rotation] - (ptk/reify ::increase-rotation - ptk/WatchEvent - (watch [_ state _] - - (let [page-id (:current-page-id state) - objects (wsh/lookup-page-objects state page-id) - shapes (->> ids (map #(get objects %)))] - (rx/concat - (rx/of (dwm/set-delta-rotation-modifiers rotation shapes)) - (rx/of (dwm/apply-modifiers))))))) + ([ids rotation] + (increase-rotation ids rotation nil)) + ([ids rotation params] + (ptk/reify ::increase-rotation + ptk/WatchEvent + (watch [_ state _] + (let [page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + shapes (->> ids (map #(get objects %)))] + (rx/concat + (rx/of (dwm/set-delta-rotation-modifiers rotation shapes params)) + (rx/of (dwm/apply-modifiers)))))))) ;; -- Move ---------------------------------------------------------- @@ -889,26 +890,32 @@ ;; -- Flip ---------------------------------------------------------- -(defn flip-horizontal-selected [] - (ptk/reify ::flip-horizontal-selected - ptk/WatchEvent - (watch [_ state _] - (let [objects (wsh/lookup-page-objects state) - selected (wsh/lookup-selected state {:omit-blocked? true}) - shapes (map #(get objects %) selected) - selrect (gsh/shapes->rect shapes) - center (grc/rect->center selrect) - modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))) +(defn flip-horizontal-selected + ([] + (flip-horizontal-selected nil)) + ([ids] + (ptk/reify ::flip-horizontal-selected + ptk/WatchEvent + (watch [_ state _] + (let [objects (wsh/lookup-page-objects state) + selected (or ids (wsh/lookup-selected state {:omit-blocked? true})) + shapes (map #(get objects %) selected) + selrect (gsh/shapes->rect shapes) + center (grc/rect->center selrect) + modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point -1.0 1.0) center))] + (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))) -(defn flip-vertical-selected [] - (ptk/reify ::flip-vertical-selected - ptk/WatchEvent - (watch [_ state _] - (let [objects (wsh/lookup-page-objects state) - selected (wsh/lookup-selected state {:omit-blocked? true}) - shapes (map #(get objects %) selected) - selrect (gsh/shapes->rect shapes) - center (grc/rect->center selrect) - modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))] - (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true})))))) +(defn flip-vertical-selected + ([] + (flip-vertical-selected nil)) + ([ids] + (ptk/reify ::flip-vertical-selected + ptk/WatchEvent + (watch [_ state _] + (let [objects (wsh/lookup-page-objects state) + selected (or ids (wsh/lookup-selected state {:omit-blocked? true})) + shapes (map #(get objects %) selected) + selrect (gsh/shapes->rect shapes) + center (grc/rect->center selrect) + modifiers (dwm/create-modif-tree selected (ctm/resize-modifiers (gpt/point 1.0 -1.0) center))] + (rx/of (dwm/apply-modifiers {:modifiers modifiers :ignore-snap-pixel true}))))))) diff --git a/frontend/src/app/plugins.cljs b/frontend/src/app/plugins.cljs index ac48f5c08..551591b4a 100644 --- a/frontend/src/app/plugins.cljs +++ b/frontend/src/app/plugins.cljs @@ -10,6 +10,7 @@ [app.main.features :as features] [app.main.store :as st] [app.plugins.api :as api] + [app.plugins.public-utils] [app.util.globals :refer [global]] [app.util.object :as obj] [beicon.v2.core :as rx] diff --git a/frontend/src/app/plugins/public_utils.cljs b/frontend/src/app/plugins/public_utils.cljs new file mode 100644 index 000000000..6ebe31151 --- /dev/null +++ b/frontend/src/app/plugins/public_utils.cljs @@ -0,0 +1,19 @@ +;; 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.plugins.public-utils + "Utilities that will be exposed to plugins developers" + (:require + [app.common.geom.rect :as grc] + [app.common.geom.shapes :as gsh] + [app.plugins.utils :as u])) + +(defn ^:export centerShapes + [shapes] + (let [shapes (->> shapes (map u/proxy->shape))] + (-> (gsh/shapes->rect shapes) + (grc/rect->center) + (u/to-js)))) diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index 0d239dbe2..2048e8afe 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -202,6 +202,20 @@ (st/emit! (dw/update-dimensions [$id] :width width) (dw/update-dimensions [$id] :height height))) + (rotate + [self angle center] + (let [center (when center {:x (obj/get center "x") :y (obj/get center "y")})] + (cond + (not (number? angle)) + (u/display-not-valid :rotate-angle angle) + + (and (some? center) (or (not (number? (:x center))) (not (number? (:y center))))) + (u/display-not-valid :rotate-center center) + + :else + (let [id (obj/get self "$id")] + (st/emit! (dw/increase-rotation [id] angle {:center center :delta? true})))))) + (clone [_] (let [ret-v (atom nil)] @@ -624,11 +638,32 @@ {:name "height" :get #(-> % u/proxy->shape :height)} + {:name "rotation" + :get #(-> % u/proxy->shape :rotation) + :set + (fn [self value] + (if (number? value) + (let [shape (u/proxy->shape self)] + (st/emit! (dw/increase-rotation #{(:id shape)} value))) + (u/display-not-valid :rotation value)))} + {:name "flipX" - :get #(-> % u/proxy->shape :flip-x)} + :get #(-> % u/proxy->shape :flip-x boolean) + :set + (fn [self value] + (if (boolean? value) + (let [id (obj/get self "$id")] + (st/emit! (dw/flip-horizontal-selected #{id}))) + (u/display-not-valid :flipX value)))} {:name "flipY" - :get #(-> % u/proxy->shape :flip-y)} + :get #(-> % u/proxy->shape :flip-y boolean) + :set + (fn [self value] + (if (boolean? value) + (let [id (obj/get self "$id")] + (st/emit! (dw/flip-vertical-selected #{id}))) + (u/display-not-valid :flipY value)))} ;; Strokes and fills ;; TODO: Validate fills input