From 4a74862bf5cfb18564cfd0f3c11b48c5d774b9f3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 23 Apr 2024 14:52:57 +0200 Subject: [PATCH] :sparkles: Add viewport information to the plugin --- .../src/app/main/data/workspace/zoom.cljs | 50 ++++++++++-- frontend/src/app/plugins/api.cljs | 40 +++++++--- frontend/src/app/plugins/shape.cljs | 3 +- frontend/src/app/plugins/viewport.cljs | 79 +++++++++++++++++++ 4 files changed, 150 insertions(+), 22 deletions(-) create mode 100644 frontend/src/app/plugins/viewport.cljs diff --git a/frontend/src/app/main/data/workspace/zoom.cljs b/frontend/src/app/main/data/workspace/zoom.cljs index 379776ede..8672544fd 100644 --- a/frontend/src/app/main/data/workspace/zoom.cljs +++ b/frontend/src/app/main/data/workspace/zoom.cljs @@ -6,6 +6,8 @@ (ns app.main.data.workspace.zoom (:require + [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.files.helpers :as cfh] [app.common.geom.align :as gal] [app.common.geom.matrix :as gmt] @@ -54,14 +56,20 @@ #(impl-update-zoom % center (fn [z] (max (/ z 1.3) 0.01))))))))) (defn set-zoom - [center scale] - (ptk/reify ::set-zoom - ptk/UpdateEvent - (update [_ state] - (update state :workspace-local - #(impl-update-zoom % center (fn [z] (-> (* z scale) - (max 0.01) - (min 200)))))))) + ([scale] + (set-zoom nil scale)) + ([center scale] + (ptk/reify ::set-zoom + ptk/UpdateEvent + (update [_ state] + (let [vp (dm/get-in state [:workspace-local :vbox]) + x (+ (:x vp) (/ (:width vp) 2)) + y (+ (:y vp) (/ (:height vp) 2)) + center (d/nilv center (gpt/point x y))] + (update state :workspace-local + #(impl-update-zoom % center (fn [z] (-> (* z scale) + (max 0.01) + (min 200)))))))))) (def reset-zoom (ptk/reify ::reset-zoom @@ -110,6 +118,32 @@ (assoc :zoom-inverse (/ 1 zoom)) (update :vbox merge srect))))))))))) +(defn fit-to-shapes + [ids] + (ptk/reify ::fit-to-shapes + ptk/UpdateEvent + (update [_ state] + (if (empty? ids) + state + (let [page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + _ (prn "??" (->> ids (map #(get objects %)) (map :name))) + srect (->> ids + (map #(get objects %)) + (gsh/shapes->rect))] + + (update state :workspace-local + (fn [{:keys [vport] :as local}] + (let [srect (gal/adjust-to-viewport + vport srect + {:padding 40}) + zoom (/ (:width vport) + (:width srect))] + (-> local + (assoc :zoom zoom) + (assoc :zoom-inverse (/ 1 zoom)) + (update :vbox merge srect)))))))))) + (defn start-zooming [pt] (ptk/reify ::start-zooming ptk/WatchEvent diff --git a/frontend/src/app/plugins/api.cljs b/frontend/src/app/plugins/api.cljs index 51ed5155c..683d5677d 100644 --- a/frontend/src/app/plugins/api.cljs +++ b/frontend/src/app/plugins/api.cljs @@ -17,7 +17,8 @@ [app.plugins.events :as events] [app.plugins.file :as file] [app.plugins.page :as page] - [app.plugins.shape :as shape])) + [app.plugins.shape :as shape] + [app.plugins.viewport :as viewport])) ;; ;; PLUGINS PUBLIC API - The plugins will able to access this functions @@ -28,12 +29,30 @@ (map val) (map shape/data->shape-proxy))) +(defn create-shape + [type] + (let [page-id (:current-page-id @st/state) + page (dm/get-in @st/state [:workspace-data :pages-index page-id]) + shape (cts/setup-shape {:type :type + :x 0 :y 0 :width 100 :height 100}) + changes + (-> (cb/empty-changes) + (cb/with-page page) + (cb/with-objects (:objects page)) + (cb/add-object shape))] + (st/emit! (ch/commit-changes changes)) + (shape/data->shape-proxy shape))) + (deftype PenpotContext [] Object (addListener [_ type callback] (events/add-listener type callback)) + (getViewport + [_] + (viewport/create-proxy)) + (getFile [_] (file/data->file-proxy (:workspace-file @st/state) (:workspace-data @st/state))) @@ -70,19 +89,13 @@ "dark" (get-in @st/state [:profile :theme])))) + (createFrame + [_] + (create-shape :frame)) + (createRectangle [_] - (let [page-id (:current-page-id @st/state) - page (dm/get-in @st/state [:workspace-data :pages-index page-id]) - shape (cts/setup-shape {:type :rect - :x 0 :y 0 :width 100 :height 100}) - changes - (-> (cb/empty-changes) - (cb/with-page page) - (cb/with-objects (:objects page)) - (cb/add-object shape))] - (st/emit! (ch/commit-changes changes)) - (shape/data->shape-proxy shape)))) + (create-shape :rect))) (defn create-context [] @@ -90,4 +103,5 @@ (PenpotContext.) {:name "root" :get #(.getRoot ^js %)} {:name "currentPage" :get #(.getPage ^js %)} - {:name "selection" :get #(.getSelectedShapes ^js %)})) + {:name "selection" :get #(.getSelectedShapes ^js %)} + {:name "viewport" :get #(.getViewport ^js %)})) diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs index 8a7aea836..1bcbea5dc 100644 --- a/frontend/src/app/plugins/shape.cljs +++ b/frontend/src/app/plugins/shape.cljs @@ -69,7 +69,8 @@ (clone [_] (.log js/console (clj->js _data))) (delete [_] (.log js/console (clj->js _data))) - (appendChild [_] (.log js/console (clj->js _data)))) + (appendChild [_ child] (.log js/console (clj->js _data))) + (insertChild [_ index child] (.log js/console (clj->js _data)))) (crc/define-properties! ShapeProxy diff --git a/frontend/src/app/plugins/viewport.cljs b/frontend/src/app/plugins/viewport.cljs new file mode 100644 index 000000000..c243d327a --- /dev/null +++ b/frontend/src/app/plugins/viewport.cljs @@ -0,0 +1,79 @@ +;; 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.viewport + "RPC for plugins runtime." + (:require + [app.common.data.macros :as dm] + [app.common.geom.point :as gpt] + [app.common.record :as crc] + [app.common.record :as crc] + [app.common.uuid :as uuid] + [app.main.data.workspace.viewport :as dwv] + [app.main.data.workspace.zoom :as dwz] + [app.main.store :as st] + [app.plugins.page :as page] + [app.plugins.utils :refer [get-data-fn]] + [app.util.object :as obj])) + +(deftype ViewportProxy [] + Object + (zoomIntoView [_ shapes] + (let [ids + (->> shapes + (map (fn [v] + (if (string? v) + (uuid/uuid v) + (uuid/uuid (obj/get v "x"))))))] + (st/emit! (dwz/fit-to-shapes ids))))) + +(crc/define-properties! + ViewportProxy + {:name js/Symbol.toStringTag + :get (fn [] (str "ViewportProxy"))}) + +(defn create-proxy + [] + (crc/add-properties! + (ViewportProxy.) + {:name "center" + :get + (fn [_] + (let [vp (dm/get-in @st/state [:workspace-local :vbox]) + x (+ (:x vp) (/ (:width vp) 2)) + y (+ (:y vp) (/ (:height vp) 2))] + (.freeze js/Object #js {:x x :y y}))) + + :set + (fn [_ value] + (let [new-x (obj/get value "x") + new-y (obj/get value "y") + vb (dm/get-in @st/state [:workspace-local :vbox]) + old-x (+ (:x vb) (/ (:width vb) 2)) + old-y (+ (:y vb) (/ (:height vb) 2)) + delta-x (- new-x old-x) + delta-y (- new-y old-y) + to-position + {:x #(+ % delta-x) + :y #(+ % delta-y)}] + (st/emit! (dwv/update-viewport-position to-position))))} + + {:name "zoom" + :get + (fn [_] + (dm/get-in @st/state [:workspace-local :zoom])) + :set + (fn [_ value] + (let [z (dm/get-in @st/state [:workspace-local :zoom])] + (st/emit! (dwz/set-zoom (/ value z)))))} + + {:name "bounds" + :get + (fn [_] + (let [vport (dm/get-in @st/state [:workspace-local :vport])] + (.freeze js/Object (clj->js vport))))})) + +