From 7b23a2a2b475121bc1c5dfe5b4bf40fa3128968e Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 23 Mar 2020 15:28:53 +0100 Subject: [PATCH] :recycle: Reorganize and improve the shortcuts machinary. --- frontend/src/uxbox/main/data/workspace.cljs | 69 +++++++++++++++- frontend/src/uxbox/main/ui/shapes/frame.cljs | 1 - frontend/src/uxbox/main/ui/workspace.cljs | 8 +- .../uxbox/main/ui/workspace/shortcuts.cljs | 81 ------------------- 4 files changed, 71 insertions(+), 88 deletions(-) delete mode 100644 frontend/src/uxbox/main/ui/workspace/shortcuts.cljs diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 310d615f9..11a90d44e 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -11,6 +11,8 @@ (:require [clojure.set :as set] [beicon.core :as rx] + [goog.object :as gobj] + [goog.events :as events] [cljs.spec.alpha :as s] [potok.core :as ptk] [uxbox.common.data :as d] @@ -36,7 +38,11 @@ [uxbox.util.time :as dt] [uxbox.util.transit :as t] [uxbox.util.uuid :as uuid] - [vendor.randomcolor])) + [uxbox.util.webapi :as wapi] + [vendor.randomcolor]) + (:import goog.events.EventType + goog.events.KeyCodes + goog.ui.KeyboardShortcutHandler)) ;; TODO: temporal workaround (def clear-ruler nil) @@ -1097,7 +1103,6 @@ (rx/empty)))))) - ;; --- Toggle shape's selection status (selected or deselected) (defn select-shape @@ -1999,3 +2004,63 @@ pages (vec (concat before [id] after))] (assoc-in state [:projects (:project-id page) :pages] pages))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Shortcuts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(def shortcuts + {"ctrl+shift+m" #(rx/of (toggle-layout-flag :sitemap)) + "ctrl+shift+f" #(rx/of (toggle-layout-flag :drawtools)) + "ctrl+shift+i" #(rx/of (toggle-layout-flag :icons)) + "ctrl+shift+l" #(rx/of (toggle-layout-flag :layers)) + "ctrl+0" #(rx/of (reset-zoom)) + "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) + "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 + (letfn [(initialize [sink] + (let [handler (KeyboardShortcutHandler. js/document)] + + ;; Register shortcuts. + (run! #(.registerShortcut handler % %) (keys shortcuts)) + + ;; Initialize shortcut listener. + (let [event KeyboardShortcutHandler.EventType.SHORTCUT_TRIGGERED + callback #(sink (gobj/get % "identifier")) + key (events/listen handler event callback)] + (fn [] + (events/unlistenByKey key) + (.clearKeyListener handler)))))] + (ptk/reify ::initialize-shortcuts + ptk/WatchEvent + (watch [_ state stream] + (let [stoper (rx/filter #(= ::finalize-shortcuts %) stream)] + (->> (rx/create initialize) + (rx/pr-log "[debug]: shortcut:") + (rx/map #(get shortcuts %)) + (rx/filter fn?) + (rx/merge-map (fn [f] (f))) + (rx/take-until stoper))))))) diff --git a/frontend/src/uxbox/main/ui/shapes/frame.cljs b/frontend/src/uxbox/main/ui/shapes/frame.cljs index a1dfad528..fc235b747 100644 --- a/frontend/src/uxbox/main/ui/shapes/frame.cljs +++ b/frontend/src/uxbox/main/ui/shapes/frame.cljs @@ -133,7 +133,6 @@ translate #(translate-to-frame % ds-modifier (gpt/point (- x) (- y))) ] - [:svg {:x x :y y :width width :height height} [:& "rect" props] (for [item (reverse childs)] diff --git a/frontend/src/uxbox/main/ui/workspace.cljs b/frontend/src/uxbox/main/ui/workspace.cljs index 2278d05c3..e29cfa126 100644 --- a/frontend/src/uxbox/main/ui/workspace.cljs +++ b/frontend/src/uxbox/main/ui/workspace.cljs @@ -26,7 +26,6 @@ [uxbox.main.ui.workspace.header :refer [header]] [uxbox.main.ui.workspace.rules :refer [horizontal-rule vertical-rule]] [uxbox.main.ui.workspace.scroll :as scroll] - [uxbox.main.ui.workspace.shortcuts :as shortcuts] [uxbox.main.ui.workspace.sidebar :refer [left-sidebar right-sidebar]] [uxbox.main.ui.workspace.sidebar.history :refer [history-dialog]] [uxbox.main.ui.workspace.left-toolbar :refer [left-toolbar]] @@ -119,10 +118,11 @@ {:fn #(st/emit! dw/initialize-layout)}) (mf/use-effect - {:deps (mf/deps file-id page-id) + {:deps (mf/deps file-id) :fn (fn [] - (let [sub (shortcuts/init)] - #(rx/cancel! sub)))}) + (st/emit! dw/initialize-shortcuts) + #(st/emit! ::dw/finalize-shortcuts))}) + (let [file (mf/deref refs/workspace-file) page (mf/deref refs/workspace-page) layout (mf/deref refs/workspace-layout)] diff --git a/frontend/src/uxbox/main/ui/workspace/shortcuts.cljs b/frontend/src/uxbox/main/ui/workspace/shortcuts.cljs deleted file mode 100644 index 120887265..000000000 --- a/frontend/src/uxbox/main/ui/workspace/shortcuts.cljs +++ /dev/null @@ -1,81 +0,0 @@ -;; 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) 2015-2016 Andrey Antukh -;; Copyright (c) 2015-2016 Juan de la Cruz - -(ns uxbox.main.ui.workspace.shortcuts - (:require [goog.events :as events] - [beicon.core :as rx] - [potok.core :as ptk] - [uxbox.main.store :as st] - [uxbox.main.data.lightbox :as dl] - [uxbox.main.data.workspace :as dw]) - (:import goog.events.EventType - goog.events.KeyCodes - goog.ui.KeyboardShortcutHandler)) - -(declare move-selected) - -;; --- Shortcuts - -(defonce +shortcuts+ - { - ;; :shift+g #(st/emit! (dw/toggle-flag :grid)) - :ctrl+shift+m #(st/emit! (dw/toggle-layout-flag :sitemap)) - :ctrl+shift+f #(st/emit! (dw/toggle-layout-flag :drawtools)) - :ctrl+shift+i #(st/emit! (dw/toggle-layout-flag :icons)) - :ctrl+shift+l #(st/emit! (dw/toggle-layout-flag :layers)) - :ctrl+0 #(st/emit! (dw/reset-zoom)) - ;; :ctrl+r #(st/emit! (dw/toggle-flag :ruler)) - :ctrl+d #(st/emit! dw/duplicate-selected) - :ctrl+z #(st/emit! dw/undo) - :ctrl+shift+z #(st/emit! dw/redo) - :ctrl+y #(st/emit! dw/redo) - :ctrl+q #(st/emit! dw/reinitialize-undo) - :ctrl+b #(st/emit! (dw/select-for-drawing :rect)) - :ctrl+e #(st/emit! (dw/select-for-drawing :circle)) - :ctrl+t #(st/emit! (dw/select-for-drawing :text)) - :esc #(st/emit! :interrupt dw/deselect-all) - :delete #(st/emit! dw/delete-selected) - :ctrl+up #(st/emit! (dw/vertical-order-selected :up)) - :ctrl+down #(st/emit! (dw/vertical-order-selected :down)) - :ctrl+shift+up #(st/emit! (dw/vertical-order-selected :top)) - :ctrl+shift+down #(st/emit! (dw/vertical-order-selected :bottom)) - :shift+up #(st/emit! (dw/move-selected :up true)) - :shift+down #(st/emit! (dw/move-selected :down true)) - :shift+right #(st/emit! (dw/move-selected :right true)) - :shift+left #(st/emit! (dw/move-selected :left true)) - :up #(st/emit! (dw/move-selected :up false)) - :down #(st/emit! (dw/move-selected :down false)) - :right #(st/emit! (dw/move-selected :right false)) - :left #(st/emit! (dw/move-selected :left false)) - }) - -;; --- Shortcuts Setup Functions - -(defn- watch-shortcuts - [sink] - (let [handler (KeyboardShortcutHandler. js/document)] - - ;; Register shortcuts. - (doseq [item (keys +shortcuts+)] - (let [identifier (name item)] - (.registerShortcut handler identifier identifier))) - - ;; Initialize shortcut listener. - (let [event KeyboardShortcutHandler.EventType.SHORTCUT_TRIGGERED - callback #(sink (keyword (.-identifier %))) - key (events/listen handler event callback)] - (fn [] - (events/unlistenByKey key) - (.clearKeyListener handler))))) - -(defn init - [] - (let [stream (->> (rx/create watch-shortcuts) - (rx/pr-log "[debug]: shortcut:"))] - (rx/on-value stream (fn [event] - (when-let [handler (get +shortcuts+ event)] - (handler))))))