Shortcuts for paths

This commit is contained in:
alonso.torres 2021-04-22 14:06:11 +02:00
parent 6331dff484
commit 65ad46ab38
15 changed files with 320 additions and 116 deletions

View file

@ -305,10 +305,9 @@
} }
&.is-disabled { &.is-disabled {
opacity: 0.3; cursor: initial;
svg {
&:hover svg { fill: $color-gray-20;
fill: initial;
} }
} }

View file

@ -6,15 +6,13 @@
(ns app.main.data.shortcuts (ns app.main.data.shortcuts
(:require (:require
[app.main.data.workspace.colors :as mdc] ["mousetrap" :as mousetrap]
[app.main.data.workspace.transforms :as dwt] [app.config :as cfg]
[app.main.store :as st] [app.util.logging :as log])
[app.util.dom :as dom]
[potok.core :as ptk]
[beicon.core :as rx]
[app.config :as cfg])
(:refer-clojure :exclude [meta])) (:refer-clojure :exclude [meta]))
(log/set-level! :warn)
(def mac-command "\u2318") (def mac-command "\u2318")
(def mac-option "\u2325") (def mac-option "\u2325")
(def mac-delete "\u232B") (def mac-delete "\u232B")
@ -46,20 +44,41 @@
[shortcut] [shortcut]
(c-mod (a-mod shortcut))) (c-mod (a-mod shortcut)))
(defn bind-shortcuts [shortcuts bind-fn cb-fn] (defn bind-shortcuts
(doseq [[key {:keys [command disabled fn type]}] shortcuts] ([shortcuts-config]
(when-not disabled (bind-shortcuts
(if (vector? command) shortcuts-config
(doseq [cmd (seq command)] mousetrap/bind
(bind-fn cmd (cb-fn key fn) type)) (fn [key cb]
(bind-fn command (cb-fn key fn) type))))) (fn [event]
(log/debug :msg (str "Shortcut" key))
(.preventDefault event)
(cb event)))))
([shortcuts-config bind-fn cb-fn]
(doseq [[key {:keys [command disabled fn type]}] shortcuts-config]
(when-not disabled
(if (vector? command)
(doseq [cmd (seq command)]
(bind-fn cmd (cb-fn key fn) type))
(bind-fn command (cb-fn key fn) type))))))
(defn remove-shortcuts
[]
(mousetrap/reset))
(defn meta [key] (defn meta [key]
(str ;; If the key is "+" we need to surround with quotes
(if (cfg/check-platform? :macos) ;; otherwise will not be very readable
mac-command (let [key (if (and (not (cfg/check-platform? :macos))
"Ctrl+") (= key "+"))
key)) "\"+\""
key)]
(str
(if (cfg/check-platform? :macos)
mac-command
"Ctrl+")
key)))
(defn shift [key] (defn shift [key]
(str (str

View file

@ -10,7 +10,8 @@
[app.main.data.workspace.path.drawing :as drawing] [app.main.data.workspace.path.drawing :as drawing]
[app.main.data.workspace.path.edition :as edition] [app.main.data.workspace.path.edition :as edition]
[app.main.data.workspace.path.selection :as selection] [app.main.data.workspace.path.selection :as selection]
[app.main.data.workspace.path.tools :as tools])) [app.main.data.workspace.path.tools :as tools]
[app.main.data.workspace.path.undo :as undo]))
;; Drawing ;; Drawing
(d/export drawing/handle-new-shape) (d/export drawing/handle-new-shape)
@ -42,3 +43,7 @@
(d/export tools/separate-nodes) (d/export tools/separate-nodes)
(d/export tools/toggle-snap) (d/export tools/toggle-snap)
;; Undo/redo
(d/export undo/undo-path)
(d/export undo/redo-path)
(d/export undo/merge-head)

View file

@ -113,7 +113,8 @@
(let [id (st/get-path-id state) (let [id (st/get-path-id state)
handler (get-in state [:workspace-local :edit-path id :prev-handler])] handler (get-in state [:workspace-local :edit-path id :prev-handler])]
;; Update the preview because can be outdated after the dragging ;; Update the preview because can be outdated after the dragging
(rx/of (preview-next-point handler)))))) (rx/of (preview-next-point handler)
(undo/merge-head))))))
(declare close-path-drag-end) (declare close-path-drag-end)

View file

@ -0,0 +1,94 @@
;; 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) UXBOX Labs SL
(ns app.main.data.workspace.path.shortcuts
(:require
[app.main.data.shortcuts :as ds]
[app.main.data.workspace :as dw]
[app.main.data.workspace.path :as drp]
[app.main.store :as st]
[beicon.core :as rx]
[potok.core :as ptk]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shortcuts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shortcuts format https://github.com/ccampbell/mousetrap
(defn esc-pressed []
(ptk/reify :esc-pressed
ptk/WatchEvent
(watch [_ state stream]
;; Not interrupt when we're editing a path
(let [edition-id (or (get-in state [:workspace-drawing :object :id])
(get-in state [:workspace-local :edition]))
path-edit-mode (get-in state [:workspace-local :edit-path edition-id :edit-mode])]
(if-not (= :draw path-edit-mode)
(rx/of :interrupt (dw/deselect-all true))
(rx/empty))))))
(def shortcuts
{:move-nodes {:tooltip "V"
:command "v"
:fn #(st/emit! (drp/change-edit-mode :move))}
:draw-nodes {:tooltip "P"
:command "p"
:fn #(st/emit! (drp/change-edit-mode :draw))}
:add-node {:tooltip (ds/meta "+")
:command (ds/c-mod "+")
:fn #(st/emit! (drp/add-node))}
:delete-node {:tooltip (ds/supr)
:command ["del" "backspace"]
:fn #(st/emit! (drp/remove-node))}
:merge-nodes {:tooltip (ds/meta "J")
:command (ds/c-mod "j")
:fn #(st/emit! (drp/merge-nodes))}
:join-nodes {:tooltip (ds/meta-shift "J")
:command (ds/c-mod "shift+j")
:fn #(st/emit! (drp/join-nodes))}
:separate-nodes {:tooltip (ds/meta "K")
:command (ds/c-mod "k")
:fn #(st/emit! (drp/separate-nodes))}
:make-corner {:tooltip (ds/meta "B")
:command (ds/c-mod "b")
:fn #(st/emit! (drp/make-corner))}
:make-curve {:tooltip (ds/meta-shift "B")
:command (ds/c-mod "shift+b")
:fn #(st/emit! (drp/make-curve))}
:snap-nodes {:tooltip (ds/meta "'")
:command (ds/c-mod "'")
:fn #(st/emit! (drp/toggle-snap))}
:escape {:tooltip (ds/esc)
:command "escape"
:fn #(st/emit! (esc-pressed))}
:start-editing {:tooltip (ds/enter)
:command "enter"
:fn #(st/emit! (dw/start-editing-selected))}
:undo {:tooltip (ds/meta "Z")
:command (ds/c-mod "z")
:fn #(st/emit! (drp/undo-path))}
:redo {:tooltip (ds/meta "Y")
:command [(ds/c-mod "shift+z") (ds/c-mod "y")]
:fn #(st/emit! (drp/redo-path))}
})
(defn get-tooltip [shortcut]
(assert (contains? shortcuts shortcut) (str shortcut))
(get-in shortcuts [shortcut :tooltip]))

View file

@ -72,6 +72,14 @@
(->> ms/mouse-position (->> ms/mouse-position
(rx/map check-path-snap)))) (rx/map check-path-snap))))
(defn get-angle [node handler opposite]
(when (and (some? node) (some? handler) (some? opposite))
(let [v1 (gpt/to-vec node opposite)
v2 (gpt/to-vec node handler)
rot-angle (gpt/angle-with-other v1 v2)
rot-sign (gpt/angle-sign v1 v2)]
[rot-angle rot-sign])))
(defn move-handler-stream (defn move-handler-stream
[snap-toggled start-point node handler opposite points] [snap-toggled start-point node handler opposite points]
@ -79,8 +87,7 @@
ranges (snap/create-ranges points) ranges (snap/create-ranges points)
d-pos (/ snap/snap-path-accuracy zoom) d-pos (/ snap/snap-path-accuracy zoom)
initial-angle (gpt/angle-with-other (gpt/to-vec node handler) [initial-angle] (get-angle node handler opposite)
(gpt/to-vec node opposite))
check-path-snap check-path-snap
(fn [position] (fn [position]
@ -88,14 +95,11 @@
(let [delta (gpt/subtract position start-point) (let [delta (gpt/subtract position start-point)
handler (gpt/add handler delta) handler (gpt/add handler delta)
v1 (gpt/to-vec node opposite) [rot-angle rot-sign] (get-angle node handler opposite)
v2 (gpt/to-vec node handler)
rot-angle (gpt/angle-with-other v1 v2)
rot-sign (gpt/angle-sign v1 v2)
snap-opposite-angle? snap-opposite-angle?
(and (or (:alt? position) (> (- 180 initial-angle) 0.1)) (and (some? rot-angle)
(or (:alt? position) (> (- 180 initial-angle) 0.1))
(<= (- 180 rot-angle) 5))] (<= (- 180 rot-angle) 5))]
(cond (cond

View file

@ -48,8 +48,8 @@
:prev-handler prev-handler :prev-handler prev-handler
:old-content old-content)))) :old-content old-content))))
(defn undo [] (defn undo-path []
(ptk/reify ::undo (ptk/reify ::undo-path
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [id (st/get-path-id state) (let [id (st/get-path-id state)
@ -65,10 +65,10 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(rx/of (changes/save-path-content))))) (rx/of (changes/save-path-content {:preserve-move-to true})))))
(defn redo [] (defn redo-path []
(ptk/reify ::redo (ptk/reify ::redo-path
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [id (st/get-path-id state) (let [id (st/get-path-id state)
@ -85,6 +85,23 @@
(watch [_ state stream] (watch [_ state stream]
(rx/of (changes/save-path-content))))) (rx/of (changes/save-path-content)))))
(defn merge-head
"Joins the head with the previous undo in one. This is done so when the user changes a
node handlers after adding it the undo merges both in one operation only"
[]
(ptk/reify ::add-undo-entry
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
entry (make-entry state)
stack (get-in state [:workspace-local :edit-path id :undo-stack])
head (u/peek stack)
stack (-> stack (u/undo) (u/fixup head))]
(-> state
(d/assoc-in-when
[:workspace-local :edit-path id :undo-stack]
stack))))))
(defn add-undo-entry [] (defn add-undo-entry []
(ptk/reify ::add-undo-entry (ptk/reify ::add-undo-entry
ptk/UpdateEvent ptk/UpdateEvent
@ -136,20 +153,10 @@
(rx/filter stop-undo?) (rx/filter stop-undo?)
(rx/take 1))] (rx/take 1))]
(rx/concat (rx/concat
(->> (rx/merge (->> (rx/from-atom path-content-ref {:emit-current-value? true})
(->> (rx/from-atom path-content-ref {:emit-current-value? true}) (rx/take-until stop-undo-stream)
(rx/filter (comp not nil?)) (rx/filter (comp not nil?))
(rx/map #(add-undo-entry))) (rx/map #(add-undo-entry)))
(->> stream
(rx/filter undo-event?)
(rx/map #(undo)))
(->> stream
(rx/filter redo-event?)
(rx/map #(redo))))
(rx/take-until stop-undo-stream))
(rx/of (end-path-undo)))))))))) (rx/of (end-path-undo))))))))))

View file

@ -6,10 +6,9 @@
(ns app.main.data.workspace.shortcuts (ns app.main.data.workspace.shortcuts
(:require (:require
[app.config :as cfg]
[app.main.data.workspace.colors :as mdc]
[app.main.data.shortcuts :as ds] [app.main.data.shortcuts :as ds]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.colors :as mdc]
[app.main.data.workspace.common :as dwc] [app.main.data.workspace.common :as dwc]
[app.main.data.workspace.drawing :as dwd] [app.main.data.workspace.drawing :as dwd]
[app.main.data.workspace.libraries :as dwl] [app.main.data.workspace.libraries :as dwl]
@ -17,28 +16,13 @@
[app.main.data.workspace.transforms :as dwt] [app.main.data.workspace.transforms :as dwt]
[app.main.store :as st] [app.main.store :as st]
[app.util.dom :as dom] [app.util.dom :as dom]
[beicon.core :as rx]
[potok.core :as ptk])) [potok.core :as ptk]))
;; \u2318P
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shortcuts ;; Shortcuts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shortcuts impl https://github.com/ccampbell/mousetrap ;; Shortcuts format https://github.com/ccampbell/mousetrap
(defn esc-pressed []
(ptk/reify :esc-pressed
ptk/WatchEvent
(watch [_ state stream]
;; Not interrupt when we're editing a path
(let [edition-id (or (get-in state [:workspace-drawing :object :id])
(get-in state [:workspace-local :edition]))
path-edit-mode (get-in state [:workspace-local :edit-path edition-id :edit-mode])]
(if-not (= :draw path-edit-mode)
(rx/of :interrupt (dw/deselect-all true))
(rx/empty))))))
(def shortcuts (def shortcuts
{:toggle-layers {:tooltip (ds/alt "L") {:toggle-layers {:tooltip (ds/alt "L")
@ -252,7 +236,7 @@
:escape {:tooltip (ds/esc) :escape {:tooltip (ds/esc)
:command "escape" :command "escape"
:fn #(st/emit! (esc-pressed))} :fn #(st/emit! :interrupt (dw/deselect-all true))}
:start-editing {:tooltip (ds/enter) :start-editing {:tooltip (ds/enter)
:command "enter" :command "enter"

View file

@ -7,9 +7,8 @@
(ns app.main.ui.hooks (ns app.main.ui.hooks
"A collection of general purpose react hooks." "A collection of general purpose react hooks."
(:require (:require
["mousetrap" :as mousetrap]
[app.common.spec :as us] [app.common.spec :as us]
[app.main.data.shortcuts :refer [bind-shortcuts]] [app.main.data.shortcuts :as dsc]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.object :as obj] [app.util.object :as obj]
[app.util.dom.dnd :as dnd] [app.util.dom.dnd :as dnd]
@ -39,16 +38,8 @@
[shortcuts] [shortcuts]
(mf/use-effect (mf/use-effect
(fn [] (fn []
(bind-shortcuts (dsc/bind-shortcuts shortcuts)
shortcuts (fn [] (dsc/remove-shortcuts)))))
mousetrap/bind
(fn [key cb]
(fn [event]
(log/debug :msg (str "Shortcut" key))
(.preventDefault event)
(cb event))))
(fn [] (mousetrap/reset))))
nil)
(defn invisible-image (defn invisible-image
[] []

View file

@ -11,7 +11,6 @@
[app.main.data.history :as udh] [app.main.data.history :as udh]
[app.main.data.messages :as dm] [app.main.data.messages :as dm]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.shortcuts :as sc]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.streams :as ms] [app.main.streams :as ms]
@ -21,13 +20,13 @@
[app.main.ui.workspace.colorpalette :refer [colorpalette]] [app.main.ui.workspace.colorpalette :refer [colorpalette]]
[app.main.ui.workspace.colorpicker] [app.main.ui.workspace.colorpicker]
[app.main.ui.workspace.context-menu :refer [context-menu]] [app.main.ui.workspace.context-menu :refer [context-menu]]
[app.main.ui.workspace.coordinates :as coordinates]
[app.main.ui.workspace.header :refer [header]] [app.main.ui.workspace.header :refer [header]]
[app.main.ui.workspace.left-toolbar :refer [left-toolbar]] [app.main.ui.workspace.left-toolbar :refer [left-toolbar]]
[app.main.ui.workspace.libraries] [app.main.ui.workspace.libraries]
[app.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]] [app.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]]
[app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] [app.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]]
[app.main.ui.workspace.viewport :refer [viewport]] [app.main.ui.workspace.viewport :refer [viewport]]
[app.main.ui.workspace.coordinates :as coordinates]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
@ -114,30 +113,29 @@
(mf/defc workspace (mf/defc workspace
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [project-id file-id page-id layout-name] :as props}] [{:keys [project-id file-id page-id layout-name] :as props}]
(mf/use-effect
(mf/deps layout-name)
#(st/emit! (dw/initialize-layout layout-name)))
(mf/use-effect
(mf/deps project-id file-id)
(fn []
(st/emit! (dw/initialize-file project-id file-id))
(st/emitf (dw/finalize-file project-id file-id))))
(mf/use-effect
(fn []
;; Close any non-modal dialog that may be still open
(st/emitf dm/hide)))
(hooks/use-shortcuts sc/shortcuts)
(let [file (mf/deref refs/workspace-file) (let [file (mf/deref refs/workspace-file)
project (mf/deref refs/workspace-project) project (mf/deref refs/workspace-project)
layout (mf/deref refs/workspace-layout)] layout (mf/deref refs/workspace-layout)]
(mf/use-effect (mf/use-effect
(mf/deps file) (mf/deps layout-name)
#(dom/set-html-title (tr "title.workspace" (:name file)))) #(st/emit! (dw/initialize-layout layout-name)))
(mf/use-effect
(mf/deps project-id file-id)
(fn []
(st/emit! (dw/initialize-file project-id file-id))
(st/emitf (dw/finalize-file project-id file-id))))
(mf/use-effect
(fn []
;; Close any non-modal dialog that may be still open
(st/emitf dm/hide)))
(mf/use-effect
(mf/deps file)
#(dom/set-html-title (tr "title.workspace" (:name file))))
[:& (mf/provider ctx/current-file-id) {:value (:id file)} [:& (mf/provider ctx/current-file-id) {:value (:id file)}
[:& (mf/provider ctx/current-team-id) {:value (:team-id project)} [:& (mf/provider ctx/current-team-id) {:value (:team-id project)}

View file

@ -143,6 +143,7 @@
(hooks/setup-keyboard alt? ctrl?) (hooks/setup-keyboard alt? ctrl?)
(hooks/setup-hover-shapes page-id move-stream selected objects transform selected ctrl? hover hover-ids) (hooks/setup-hover-shapes page-id move-stream selected objects transform selected ctrl? hover hover-ids)
(hooks/setup-viewport-modifiers modifiers selected objects render-ref) (hooks/setup-viewport-modifiers modifiers selected objects render-ref)
(hooks/setup-shortcuts path-editing? drawing-path?)
[:div.viewport [:div.viewport
[:div.viewport-overlays [:div.viewport-overlays

View file

@ -9,7 +9,10 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.pages :as cp] [app.common.pages :as cp]
[app.main.data.shortcuts :as dsc]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.path.shortcuts :as psc]
[app.main.data.workspace.shortcuts :as wsc]
[app.main.store :as st] [app.main.store :as st]
[app.main.streams :as ms] [app.main.streams :as ms]
[app.main.ui.hooks :as hooks] [app.main.ui.hooks :as hooks]
@ -148,3 +151,15 @@
(if modifiers (if modifiers
(utils/update-transform render-node roots modifiers) (utils/update-transform render-node roots modifiers)
(utils/remove-transform render-node roots)))))) (utils/remove-transform render-node roots))))))
(defn setup-shortcuts [path-editing? drawing-path?]
(mf/use-effect
(mf/deps path-editing? drawing-path?)
(fn []
(cond
(or drawing-path? path-editing?)
(dsc/bind-shortcuts psc/shortcuts)
:else
(dsc/bind-shortcuts wsc/shortcuts))
dsc/remove-shortcuts)))

View file

@ -8,10 +8,12 @@
(:require (:require
[app.main.data.workspace.path :as drp] [app.main.data.workspace.path :as drp]
[app.main.data.workspace.path.helpers :as wph] [app.main.data.workspace.path.helpers :as wph]
[app.main.data.workspace.path.shortcuts :as sc]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.shapes.path.common :as pc] [app.main.ui.workspace.shapes.path.common :as pc]
[app.util.i18n :as i18n :refer [tr]]
[app.util.path.tools :as upt] [app.util.path.tools :as upt]
[rumext.alpha :as mf])) [rumext.alpha :as mf]))
@ -106,65 +108,75 @@
[:div.viewport-actions-group [:div.viewport-actions-group
;; Draw Mode ;; Draw Mode
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when (= edit-mode :draw) "is-toggled") {:class (when (= edit-mode :draw) "is-toggled")
:alt (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes))
:on-click on-select-draw-mode} :on-click on-select-draw-mode}
i/pen] i/pen]
;; Edit mode ;; Edit mode
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when (= edit-mode :move) "is-toggled") {:class (when (= edit-mode :move) "is-toggled")
:alt (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:on-click on-select-edit-mode} :on-click on-select-edit-mode}
i/pointer-inner]] i/pointer-inner]]
[:div.viewport-actions-group [:div.viewport-actions-group
;; Add Node ;; Add Node
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:add-node enabled-buttons) "is-disabled") {:class (when-not (:add-node enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node))
:on-click on-add-node} :on-click on-add-node}
i/nodes-add] i/nodes-add]
;; Remove node ;; Remove node
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:remove-node enabled-buttons) "is-disabled") {:class (when-not (:remove-node enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node))
:on-click on-remove-node} :on-click on-remove-node}
i/nodes-remove]] i/nodes-remove]]
[:div.viewport-actions-group [:div.viewport-actions-group
;; Merge Nodes ;; Merge Nodes
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:merge-nodes enabled-buttons) "is-disabled") {:class (when-not (:merge-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes))
:on-click on-merge-nodes} :on-click on-merge-nodes}
i/nodes-merge] i/nodes-merge]
;; Join Nodes ;; Join Nodes
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:join-nodes enabled-buttons) "is-disabled") {:class (when-not (:join-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes))
:on-click on-join-nodes} :on-click on-join-nodes}
i/nodes-join] i/nodes-join]
;; Separate Nodes ;; Separate Nodes
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:separate-nodes enabled-buttons) "is-disabled") {:class (when-not (:separate-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes))
:on-click on-separate-nodes} :on-click on-separate-nodes}
i/nodes-separate]] i/nodes-separate]]
;; Make Corner ;; Make Corner
[:div.viewport-actions-group [:div.viewport-actions-group
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:make-corner enabled-buttons) "is-disabled") {:class (when-not (:make-corner enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner))
:on-click on-make-corner} :on-click on-make-corner}
i/nodes-corner] i/nodes-corner]
;; Make Curve ;; Make Curve
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:make-curve enabled-buttons) "is-disabled") {:class (when-not (:make-curve enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:on-click on-make-curve} :on-click on-make-curve}
i/nodes-curve]] i/nodes-curve]]
;; Toggle snap ;; Toggle snap
[:div.viewport-actions-group [:div.viewport-actions-group
[:div.viewport-actions-entry [:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when snap-toggled "is-toggled") {:class (when snap-toggled "is-toggled")
:alt (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes))
:on-click on-toggle-snap} :on-click on-toggle-snap}
i/nodes-snap]]])) i/nodes-snap]]]))

View file

@ -1,11 +1,25 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Language: en\n" "Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2021-04-22 13:43+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=iso-8859-1\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
# ~ msgid ""
# ~ msgstr ""
# ~ "Language: en\n"
# ~ "MIME-Version: 1.0\n"
# ~ "Content-Type: text/plain; charset=utf-8\n"
# ~ "Content-Transfer-Encoding: 8bit\n"
# ~ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/app/main/ui/auth/register.cljs #: src/app/main/ui/auth/register.cljs
msgid "auth.already-have-account" msgid "auth.already-have-account"
msgstr "Already have an account?" msgstr "Already have an account?"
@ -2169,6 +2183,36 @@ msgstr "Vertical align"
msgid "workspace.options.use-play-button" msgid "workspace.options.use-play-button"
msgstr "Use the play button at the header to run the prototype view." msgstr "Use the play button at the header to run the prototype view."
msgid "workspace.path.actions.add-node"
msgstr "Add node (%s)"
msgid "workspace.path.actions.delete-node"
msgstr "Delete node (%s)"
msgid "workspace.path.actions.draw-nodes"
msgstr "Draw nodes (%s)"
msgid "workspace.path.actions.join-nodes"
msgstr "Join nodes (%s)"
msgid "workspace.path.actions.make-corner"
msgstr "To corner (%s)"
msgid "workspace.path.actions.make-curve"
msgstr "To curve (%s)"
msgid "workspace.path.actions.merge-nodes"
msgstr "Merge nodes (%s)"
msgid "workspace.path.actions.move-nodes"
msgstr "Move nodes (%s)"
msgid "workspace.path.actions.separate-nodes"
msgstr "Separate nodes (%s)"
msgid "workspace.path.actions.snap-nodes"
msgstr "Snap nodes (%s)"
#: src/app/main/ui/workspace/context_menu.cljs #: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.back" msgid "workspace.shape.menu.back"
msgstr "Send to back" msgstr "Send to back"

View file

@ -2153,6 +2153,36 @@ msgstr "Alineación vertical"
msgid "workspace.options.use-play-button" msgid "workspace.options.use-play-button"
msgstr "Usa el botón de play de la cabecera para arrancar la vista de prototipo." msgstr "Usa el botón de play de la cabecera para arrancar la vista de prototipo."
msgid "workspace.path.actions.add-node"
msgstr "Añadir nodo (%s)"
msgid "workspace.path.actions.delete-node"
msgstr "Borrar nodos (%s)"
msgid "workspace.path.actions.draw-nodes"
msgstr "Dibujar nodos (%s)"
msgid "workspace.path.actions.join-nodes"
msgstr "Unir nodos (%s)"
msgid "workspace.path.actions.make-corner"
msgstr "Convertir en esquina (%s)"
msgid "workspace.path.actions.make-curve"
msgstr "Convertir en curva (%s)"
msgid "workspace.path.actions.merge-nodes"
msgstr "Fusionar nodos (%s)"
msgid "workspace.path.actions.move-nodes"
msgstr "Mover nodes (%s)"
msgid "workspace.path.actions.separate-nodes"
msgstr "Separar nodos (%s)"
msgid "workspace.path.actions.snap-nodes"
msgstr "Alinear nodos (%s)"
#: src/app/main/ui/workspace/context_menu.cljs #: src/app/main/ui/workspace/context_menu.cljs
msgid "workspace.shape.menu.back" msgid "workspace.shape.menu.back"
msgstr "Enviar al fondo" msgstr "Enviar al fondo"