From 6049d97ed9aeccc4a05a1204de969144b44c79a4 Mon Sep 17 00:00:00 2001 From: Andres Gonzalez Date: Thu, 24 Jul 2025 17:46:21 +0200 Subject: [PATCH 1/3] :sparkles: Display continously the distances between layers When a user moves a layer with the keyboard. --- CHANGES.md | 2 ++ .../app/main/data/workspace/shortcuts.cljs | 16 ++++++------- .../src/app/main/ui/workspace/viewport.cljs | 24 +++++++++++++++++-- 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index efcba90dec..3aa38d215c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ ### :sparkles: New features & Enhancements +- Continuous display of distances between elements when moving a layer with the keyboard [Taiga #1780](https://tree.taiga.io/project/penpot/issue/1780) + ### :bug: Bugs fixed - Display strokes information in inspect tab [Taiga #11154](https://tree.taiga.io/project/penpot/issue/11154) diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index e1535516bf..5320652c0c 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -213,42 +213,42 @@ :fn #(emit-when-no-readonly (dw/vertical-order-selected :bottom))} :move-fast-up {:tooltip (ds/shift ds/up-arrow) - :command "shift+up" + :command ["shift+up" "shift+alt+up" "alt+shift+up"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :up true))} :move-fast-down {:tooltip (ds/shift ds/down-arrow) - :command "shift+down" + :command ["shift+down" "shift+alt+down" "alt+shift+down"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :down true))} :move-fast-right {:tooltip (ds/shift ds/right-arrow) - :command "shift+right" + :command ["shift+right" "shift+alt+right" "alt+shift+right"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :right true))} :move-fast-left {:tooltip (ds/shift ds/left-arrow) - :command "shift+left" + :command ["shift+left" "shift+alt+left" "alt+shift+left"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :left true))} :move-unit-up {:tooltip ds/up-arrow - :command "up" + :command ["up" "alt+up"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :up false))} :move-unit-down {:tooltip ds/down-arrow - :command "down" + :command ["down" "alt+down"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :down false))} :move-unit-left {:tooltip ds/right-arrow - :command "right" + :command ["right" "alt+right"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :right false))} :move-unit-right {:tooltip ds/left-arrow - :command "left" + :command ["left" "alt+left"] :subsections [:modify-layers] :fn #(emit-when-no-readonly (dwt/move-selected :left false))} diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index e496500259..f602191ac0 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -378,7 +378,7 @@ (when (dbg/enabled? :show-export-metadata) [:& use/export-page {:page page}]) - ;; We need a "real" background shape so layer transforms work properly in firefox + ;; We need a "real" background shape so layer transforms work properly in firefox [:rect {:width (:width vbox 0) :height (:height vbox 0) :x (:x vbox 0) @@ -387,7 +387,7 @@ [:& (mf/provider ctx/current-vbox) {:value vbox'} [:& (mf/provider use/include-metadata-ctx) {:value (dbg/enabled? :show-export-metadata)} - ;; Render root shape + ;; Render root shape [:& shapes/root-shape {:key page-id :objects base-objects :active-frames @active-frames}]]]] @@ -487,6 +487,26 @@ :hover-shape @measure-hover :zoom zoom}]) + ;; Show distances during movement with ALT + (when (and (= transform :move) @alt? (seq selected-shapes)) + [:& msr/measurement + {:bounds vbox + :selected-shapes selected-shapes + :frame selected-frame + :hover-shape @hover + :zoom zoom}]) + + ;; Reactive subscription to duplication relation (safe) + (let [state-var (mf/use-var (resolve 'app.main.store/state)) + duplicated-info (get-in @(deref state-var) [:workspace-local :duplicated])] + (when (and (= transform :move) @alt? duplicated-info) + [:g.duplicated-distance + [:& msr/distance-display + {:from (get duplicated-info :selrect-original) + :to (get duplicated-info :selrect-duplicated) + :zoom zoom + :bounds vbox}]])) + (when show-padding? [:& mfc/padding-control {:frame first-shape From 02cff2740fee2e8aaa994373fd7c29cd35ea14f0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 29 Jul 2025 12:48:09 +0200 Subject: [PATCH 2/3] :sparkles: Remove restriction of duplicate bindings on mousetrap --- frontend/vendor/mousetrap/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/vendor/mousetrap/index.js b/frontend/vendor/mousetrap/index.js index c1cd8af3d3..06866e6a5b 100644 --- a/frontend/vendor/mousetrap/index.js +++ b/frontend/vendor/mousetrap/index.js @@ -845,8 +845,8 @@ function Mousetrap(targetElement) { // a callback is added for this key self._callbacks[info.key] = self._callbacks[info.key] || []; - // remove an existing match if there is one - _getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level); + // // remove an existing match if there is one + // _getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level); // add this call back to the array // if it is a sequence put it at the beginning From d84ee8bb65da9d0521eedc6a062f804934cb4178 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 29 Jul 2025 12:48:56 +0200 Subject: [PATCH 3/3] :zap: Optimize mousetrap binding setup --- frontend/src/app/main/data/shortcuts.cljs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/data/shortcuts.cljs b/frontend/src/app/main/data/shortcuts.cljs index febed4486e..03d95d4eb3 100644 --- a/frontend/src/app/main/data/shortcuts.cljs +++ b/frontend/src/app/main/data/shortcuts.cljs @@ -142,23 +142,24 @@ [key cb] (fn [event] (log/debug :msg (str "Shortcut" key)) - (when (aget event "preventDefault") + (when (unchecked-get event "preventDefault") (.preventDefault event)) (cb event))) (defn- bind! [shortcuts] (let [msbind (fn [command callback type] - (if type - (mousetrap/bind command callback type) - (mousetrap/bind command callback)))] + (let [command (if (vector? command) + (into-array command) + command)] + (if type + (mousetrap/bind command callback type) + (mousetrap/bind command callback))))] (->> shortcuts (remove #(:disabled (second %))) (run! (fn [[key {:keys [command fn type]}]] (let [callback (wrap-cb key fn)] - (if (vector? command) - (run! #(msbind % callback type) command) - (msbind command callback type)))))))) + (msbind command callback type))))))) (defn- reset! ([]