diff --git a/CHANGES.md b/CHANGES.md index 8a3db46c3..617b40225 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ - Allow for absolute positioned elements inside layout [Taiga #4834](https://tree.taiga.io/project/penpot/us/4834) - Add z-index option for flex layout items [Taiga #2980](https://tree.taiga.io/project/penpot/us/2980) - Scale content proportionally affects strokes, shadows, blurs and corners [Taiga #1951](https://tree.taiga.io/project/penpot/us/1951) +- Use tabulators to navigate layers [Taiga #5010](https://tree.taiga.io/project/penpot/issue/5010) ### :bug: Bugs fixed diff --git a/frontend/src/app/main/data/shortcuts.cljs b/frontend/src/app/main/data/shortcuts.cljs index 383aa4e1f..ff4577f9b 100644 --- a/frontend/src/app/main/data/shortcuts.cljs +++ b/frontend/src/app/main/data/shortcuts.cljs @@ -7,7 +7,7 @@ (ns app.main.data.shortcuts (:refer-clojure :exclude [meta reset!]) (:require - ["mousetrap" :as mousetrap] + ["./shortcuts_impl.js$default" :as mousetrap] [app.common.logging :as log] [app.common.spec :as us] [app.config :as cf] @@ -32,6 +32,7 @@ (def up-arrow "\u2191") (def right-arrow "\u2192") (def down-arrow "\u2193") +(def tab "tab") (defn c-mod "Adds the control/command modifier to a shortcuts depending on the diff --git a/frontend/src/app/main/data/shortcuts_impl.js b/frontend/src/app/main/data/shortcuts_impl.js new file mode 100644 index 000000000..e0f113c89 --- /dev/null +++ b/frontend/src/app/main/data/shortcuts_impl.js @@ -0,0 +1,27 @@ +/** + * 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 + */ +"use strict"; + +import Mousetrap from 'mousetrap' + +const target = Mousetrap.prototype || Mousetrap; +target.stopCallback = function(e, element, combo) { + // if the element has the class "mousetrap" then no need to stop + if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) { + return false; + } + + // stop for input, select, textarea and button + return element.tagName == 'INPUT' || + element.tagName == 'SELECT' || + element.tagName == 'TEXTAREA' || + element.tagName == 'BUTTON' || + (element.contentEditable && element.contentEditable == 'true'); +} + +export default Mousetrap; diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 22de3463b..816ed7e7e 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -2046,6 +2046,8 @@ (dm/export dws/select-all) (dm/export dws/select-inside-group) (dm/export dws/select-shape) +(dm/export dws/select-prev-shape) +(dm/export dws/select-next-shape) (dm/export dws/shift-select-shapes) ;; Highlight diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index 3ac7ffecb..c3de20ec9 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -131,6 +131,55 @@ objects (wsh/lookup-page-objects state page-id)] (rx/of (dwc/expand-all-parents [id] objects))))))) +(defn select-prev-shape + ([] + (ptk/reify ::select-prev-shape + ptk/WatchEvent + (watch [_ state _] + (let [selected (wsh/lookup-selected state) + count-selected (count selected) + first-selected (first selected) + page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + current (get objects first-selected) + parent (get objects (:parent-id current)) + sibling-ids (:shapes parent) + current-index (d/index-of sibling-ids first-selected) + sibling (if (= (dec (count sibling-ids)) current-index) + (first sibling-ids) + (nth sibling-ids (inc current-index)))] + + (cond + (= 1 count-selected) + (rx/of (select-shape sibling)) + + (> count-selected 1) + (rx/of (select-shape first-selected)))))))) + +(defn select-next-shape + ([] + (ptk/reify ::select-next-shape + ptk/WatchEvent + (watch [_ state _] + (let [selected (wsh/lookup-selected state) + count-selected (count selected) + first-selected (first selected) + page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + current (get objects first-selected) + parent (get objects (:parent-id current)) + sibling-ids (:shapes parent) + current-index (d/index-of sibling-ids first-selected) + sibling (if (= 0 current-index) + (last sibling-ids) + (nth sibling-ids (dec current-index)))] + (cond + (= 1 count-selected) + (rx/of (select-shape sibling)) + + (> count-selected 1) + (rx/of (select-shape first-selected)))))))) + (defn deselect-shape [id] (us/verify ::us/uuid id) diff --git a/frontend/src/app/main/data/workspace/shortcuts.cljs b/frontend/src/app/main/data/workspace/shortcuts.cljs index 6db639cbe..795dfee48 100644 --- a/frontend/src/app/main/data/workspace/shortcuts.cljs +++ b/frontend/src/app/main/data/workspace/shortcuts.cljs @@ -67,8 +67,8 @@ :cut {:tooltip (ds/meta "X") :command (ds/c-mod "x") :subsections [:edit] - :fn #(emit-when-no-readonly (dw/copy-selected) - (dw/delete-selected))} + :fn #(emit-when-no-readonly (dw/copy-selected) + (dw/delete-selected))} :paste {:tooltip (ds/meta "V") :disabled true @@ -110,7 +110,7 @@ ;; MODIFY LAYERS - + :group {:tooltip (ds/meta "G") :command (ds/c-mod "g") @@ -222,7 +222,7 @@ :fn #(emit-when-no-readonly (dwsl/toggle-layout-flex))} ;; TOOLS - + :draw-frame {:tooltip "B" :command ["b" "a"] :subsections [:tools :basics] @@ -247,7 +247,7 @@ :command "t" :subsections [:tools] :fn #(emit-when-no-readonly dwtxt/start-edit-if-selected - (dwd/select-for-drawing :text))} + (dwd/select-for-drawing :text))} :draw-path {:tooltip "P" :command "p" @@ -300,7 +300,7 @@ :fn #(emit-when-no-readonly (dw/toggle-focus-mode))} ;; ITEM ALIGNMENT - + :align-left {:tooltip (ds/alt "A") :command "alt+a" :subsections [:alignment] @@ -342,7 +342,7 @@ :fn #(emit-when-no-readonly (dw/distribute-objects :vertical))} ;; MAIN MENU - + :toggle-rules {:tooltip (ds/meta-shift "R") :command (ds/c-mod "shift+r") :subsections [:main-menu] @@ -387,7 +387,7 @@ :command (ds/c-mod "shift+e") :subsections [:basics :main-menu] :fn #(st/emit! - (de/show-workspace-export-dialog))} + (de/show-workspace-export-dialog))} :toggle-snap-guide {:tooltip (ds/meta-shift "G") :command (ds/c-mod "shift+g") @@ -400,7 +400,7 @@ :fn #(st/emit! (toggle-layout-flag :shortcuts))} ;; PANELS - + :toggle-layers {:tooltip (ds/alt "L") :command (ds/a-mod "l") :subsections [:panels] @@ -420,15 +420,15 @@ :command (ds/a-mod "p") :subsections [:panels] :fn #(do (r/set-resize-type! :bottom) - (emit-when-no-readonly (dw/remove-layout-flag :textpalette) - (toggle-layout-flag :colorpalette)))} + (emit-when-no-readonly (dw/remove-layout-flag :textpalette) + (toggle-layout-flag :colorpalette)))} :toggle-textpalette {:tooltip (ds/alt "T") :command (ds/a-mod "t") :subsections [:panels] :fn #(do (r/set-resize-type! :bottom) - (emit-when-no-readonly (dw/remove-layout-flag :colorpalette) - (toggle-layout-flag :textpalette)))} + (emit-when-no-readonly (dw/remove-layout-flag :colorpalette) + (toggle-layout-flag :textpalette)))} :hide-ui {:tooltip "\\" :command "\\" @@ -436,7 +436,7 @@ :fn #(st/emit! (toggle-layout-flag :hide-ui))} ;; ZOOM-WORKSPACE - + :increase-zoom {:tooltip "+" :command ["+" "="] :subsections [:zoom-workspace] @@ -473,7 +473,7 @@ :fn identity} ;; NAVIGATION - + :open-viewer {:tooltip "G V" :command "g v" @@ -495,7 +495,18 @@ :subsections [:navigation-workspace] :fn #(st/emit! (dw/go-to-dashboard))} + :select-prev {:tooltip (ds/shift "tab") + :command "shift+tab" + :subsections [:navigation-workspace] + :fn #(st/emit! (dw/select-prev-shape))} + + :select-next {:tooltip ds/tab + :command "tab" + :subsections [:navigation-workspace] + :fn #(st/emit! (dw/select-next-shape))} + ;; SHAPE + :bool-union {:tooltip (ds/meta (ds/alt "U")) :command (ds/c-mod "alt+u") diff --git a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs index d740b528a..72017a3e3 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/shortcuts.cljs @@ -143,6 +143,8 @@ ;; shortcuts.open-color-picker ;; shortcuts.open-comments ;; shortcuts.open-dashboard + ;; shortcuts.select-prev + ;; shortcuts.select-next ;; shortcuts.open-inspect ;; shortcuts.open-interactions ;; shortcuts.open-viewer diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 6dc61154b..ea07c4359 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2458,6 +2458,12 @@ msgstr "Go to viewer comment section" msgid "shortcuts.open-dashboard" msgstr "Go to dashboard" +msgid "shortcuts.select-next" +msgstr "Select next layer" + +msgid "shortcuts.select-prev" +msgstr "Select previous layer" + msgid "shortcuts.open-inspect" msgstr "Go to viewer inspect section" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 8b50b06cf..3e9861a8d 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -2603,6 +2603,12 @@ msgstr "Comentarios" msgid "shortcuts.open-dashboard" msgstr "Ir al dashboard" +msgid "shortcuts.select-next" +msgstr "Seleccionar capa siguiente" + +msgid "shortcuts.select-prev" +msgstr "Seleccionar capa anterior" + msgid "shortcuts.open-inspect" msgstr "Ir al inspector"