🎉 Add new shortcuts handling implementation.

This commit is contained in:
Andrey Antukh 2020-04-02 20:01:49 +02:00
parent 1a3a48e4de
commit 8597b87cad
5 changed files with 67 additions and 64 deletions

View file

@ -3945,6 +3945,11 @@
} }
} }
}, },
"mousetrap": {
"version": "1.6.5",
"resolved": "https://registry.npmjs.org/mousetrap/-/mousetrap-1.6.5.tgz",
"integrity": "sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA=="
},
"ms": { "ms": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

View file

@ -29,6 +29,7 @@
}, },
"dependencies": { "dependencies": {
"date-fns": "^2.11.1", "date-fns": "^2.11.1",
"mousetrap": "^1.6.5",
"randomcolor": "^0.5.4", "randomcolor": "^0.5.4",
"react": "^16.13.1", "react": "^16.13.1",
"react-color": "^2.18.0", "react-color": "^2.18.0",

View file

@ -2263,63 +2263,41 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(def shortcuts (def shortcuts
{"ctrl+shift+m" #(rx/of (toggle-layout-flag :sitemap)) {"ctrl+shift+m" #(st/emit! (toggle-layout-flag :sitemap))
"ctrl+shift+f" #(rx/of (toggle-layout-flag :drawtools)) "ctrl+shift+i" #(st/emit! (toggle-layout-flag :libraries))
"ctrl+shift+i" #(rx/of (toggle-layout-flag :icons)) "ctrl+shift+l" #(st/emit! (toggle-layout-flag :layers))
"ctrl+shift+l" #(rx/of (toggle-layout-flag :layers)) "+" #(st/emit! increase-zoom)
"equals" #(rx/of increase-zoom) ; keyName for the key with = and + in US keyboards (see https://unixpapa.com/js/key.html) "-" #(st/emit! decrease-zoom)
"dash" #(rx/of decrease-zoom) ; keyName for the key with - and _ in US keyboards
"shift+0" #(rx/of zoom-to-50)
"shift+1" #(rx/of reset-zoom)
"shift+2" #(rx/of zoom-to-200)
"ctrl+d" #(rx/of duplicate-selected)
"ctrl+z" #(rx/of undo)
"ctrl+shift+z" #(rx/of redo)
"ctrl+y" #(rx/of redo)
"ctrl+q" #(rx/of reinitialize-undo)
"ctrl+b" #(rx/of (select-for-drawing :rect))
"ctrl+e" #(rx/of (select-for-drawing :circle))
"ctrl+t" #(rx/of (select-for-drawing :text))
"ctrl+c" #(rx/of copy-selected)
"ctrl+v" #(rx/of paste)
"ctrl+g" #(rx/of (create-group))
"ctrl+shift+g" #(rx/of (remove-group))
"esc" #(rx/of :interrupt deselect-all)
"delete" #(rx/of delete-selected)
"ctrl+up" #(rx/of (vertical-order-selected :up))
"ctrl+down" #(rx/of (vertical-order-selected :down))
"ctrl+shift+up" #(rx/of (vertical-order-selected :top))
"ctrl+shift+down" #(rx/of (vertical-order-selected :bottom))
"shift+up" #(rx/of (move-selected :up true))
"shift+down" #(rx/of (move-selected :down true))
"shift+right" #(rx/of (move-selected :right true))
"shift+left" #(rx/of (move-selected :left true))
"up" #(rx/of (move-selected :up false))
"down" #(rx/of (move-selected :down false))
"right" #(rx/of (move-selected :right false))
"left" #(rx/of (move-selected :left false))})
(def initialize-shortcuts "ctrl+g" #(st/emit! (create-group))
(letfn [(initialize [sink] "ctrl+shift+g" #(st/emit! (remove-group))
(let [handler (KeyboardShortcutHandler. js/document)]
;; Register shortcuts. "shift+0" #(st/emit! zoom-to-50)
(run! #(.registerShortcut handler % %) (keys shortcuts)) "shift+1" #(st/emit! reset-zoom)
"shift+2" #(st/emit! zoom-to-200)
;; Initialize shortcut listener. "ctrl+d" #(st/emit! duplicate-selected)
(let [event KeyboardShortcutHandler.EventType.SHORTCUT_TRIGGERED "ctrl+z" #(st/emit! undo)
callback #(sink (gobj/get % "identifier")) "ctrl+shift+z" #(st/emit! redo)
key (events/listen handler event callback)] "ctrl+y" #(st/emit! redo)
(fn [] "ctrl+q" #(st/emit! reinitialize-undo)
(events/unlistenByKey key) "ctrl+b" #(st/emit! (select-for-drawing :rect))
(.clearKeyListener handler)))))] "ctrl+e" #(st/emit! (select-for-drawing :circle))
(ptk/reify ::initialize-shortcuts "ctrl+t" #(st/emit! (select-for-drawing :text))
ptk/WatchEvent "ctrl+c" #(st/emit! copy-selected)
(watch [_ state stream] "ctrl+v" #(st/emit! paste)
(let [stoper (rx/filter #(= ::finalize-shortcuts %) stream)] "ctrl+g" #(st/emit! (create-group))
(->> (rx/create initialize) ;; "ctrl+shift+g" #(st/emit! remove-group)
(rx/pr-log "[debug]: shortcut:") "esc" #(st/emit! :interrupt deselect-all)
(rx/map #(get shortcuts %)) "delete" #(st/emit! delete-selected)
(rx/filter fn?) "ctrl+up" #(st/emit! (vertical-order-selected :up))
(rx/merge-map (fn [f] (f))) "ctrl+down" #(st/emit! (vertical-order-selected :down))
(rx/take-until stoper))))))) "ctrl+shift+up" #(st/emit! (vertical-order-selected :top))
"ctrl+shift+down" #(st/emit! (vertical-order-selected :bottom))
"shift+up" #(st/emit! (move-selected :up true))
"shift+down" #(st/emit! (move-selected :down true))
"shift+right" #(st/emit! (move-selected :right true))
"shift+left" #(st/emit! (move-selected :left true))
"up" #(st/emit! (move-selected :up false))
"down" #(st/emit! (move-selected :down false))
"right" #(st/emit! (move-selected :right false))
"left" #(st/emit! (move-selected :left false))})

View file

@ -10,9 +10,12 @@
(ns uxbox.main.ui.react-hooks (ns uxbox.main.ui.react-hooks
"A collection of general purpose react hooks." "A collection of general purpose react hooks."
(:require (:require
[cljs.spec.alpha :as s]
[uxbox.common.spec :as us]
[beicon.core :as rx] [beicon.core :as rx]
[goog.events :as events] [goog.events :as events]
[rumext.alpha :as mf]) [rumext.alpha :as mf]
["mousetrap" :as mousetrap])
(:import goog.events.EventType)) (:import goog.events.EventType))
(defn use-rxsub (defn use-rxsub
@ -24,3 +27,22 @@
#(rx/cancel! sub))) #(rx/cancel! sub)))
#js [ob]) #js [ob])
state)) state))
(s/def ::shortcuts
(s/map-of ::us/string fn?))
(defn use-shortcuts
[shortcuts]
(us/assert ::shortcuts shortcuts)
(mf/use-effect
(fn []
(->> (seq shortcuts)
(run! (fn [[key f]]
(mousetrap/bind key (fn [event]
(js/console.log "[debug]: shortcut:" key)
(.preventDefault event)
(f event))))))
(fn [] (mousetrap/reset))))
nil)

View file

@ -19,6 +19,7 @@
[uxbox.main.streams :as ms] [uxbox.main.streams :as ms]
[uxbox.main.ui.confirm] [uxbox.main.ui.confirm]
[uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.react-hooks :as hooks]
[uxbox.main.ui.messages :refer [messages-widget]] [uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.main.ui.workspace.viewport :refer [viewport]] [uxbox.main.ui.workspace.viewport :refer [viewport]]
[uxbox.main.ui.workspace.colorpalette :refer [colorpalette]] [uxbox.main.ui.workspace.colorpalette :refer [colorpalette]]
@ -111,11 +112,7 @@
(st/emit! (dw/initialize-ws file-id)) (st/emit! (dw/initialize-ws file-id))
#(st/emit! (dw/finalize-ws file-id))))) #(st/emit! (dw/finalize-ws file-id)))))
(-> (mf/deps file-id) (hooks/use-shortcuts dw/shortcuts)
(mf/use-effect
(fn []
(st/emit! dw/initialize-shortcuts)
#(st/emit! ::dw/finalize-shortcuts))))
(mf/use-effect #(st/emit! dw/initialize-layout)) (mf/use-effect #(st/emit! dw/initialize-layout))