mirror of
https://github.com/penpot/penpot.git
synced 2026-05-26 02:13:46 +00:00
141 lines
4.8 KiB
Clojure
141 lines
4.8 KiB
Clojure
;; 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/.
|
|
;;
|
|
;; This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
;; defined by the Mozilla Public License, v. 2.0.
|
|
;;
|
|
;; Copyright (c) 2020 UXBOX Labs SL
|
|
|
|
(ns uxbox.main.ui.workspace.context-menu
|
|
"A workspace specific context menu (mouse right click)."
|
|
(:require
|
|
[beicon.core :as rx]
|
|
[okulary.core :as l]
|
|
[potok.core :as ptk]
|
|
[rumext.alpha :as mf]
|
|
[uxbox.main.store :as st]
|
|
[uxbox.main.refs :as refs]
|
|
[uxbox.main.streams :as ms]
|
|
[uxbox.main.ui.icons :as i]
|
|
[uxbox.util.dom :as dom]
|
|
[uxbox.main.data.workspace :as dw]
|
|
[uxbox.main.ui.hooks :refer [use-rxsub]]
|
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]))
|
|
|
|
(def menu-ref
|
|
(l/derived :context-menu refs/workspace-local))
|
|
|
|
(defn- prevent-default
|
|
[event]
|
|
(dom/prevent-default event)
|
|
(dom/stop-propagation event))
|
|
|
|
(mf/defc menu-entry
|
|
[{:keys [title shortcut on-click] :as props}]
|
|
[:li {:on-click on-click}
|
|
[:span.title title]
|
|
[:span.shortcut (or shortcut "")]])
|
|
|
|
(mf/defc menu-separator
|
|
[props]
|
|
[:li.separator])
|
|
|
|
(mf/defc shape-context-menu
|
|
[{:keys [mdata] :as props}]
|
|
(let [{:keys [id] :as shape} (:shape mdata)
|
|
selected (:selected mdata)
|
|
|
|
do-duplicate #(st/emit! dw/duplicate-selected)
|
|
do-delete #(st/emit! dw/delete-selected)
|
|
do-copy #(st/emit! dw/copy-selected)
|
|
do-paste #(st/emit! dw/paste)
|
|
do-bring-forward #(st/emit! (dw/vertical-order-selected :up))
|
|
do-bring-to-front #(st/emit! (dw/vertical-order-selected :top))
|
|
do-send-backward #(st/emit! (dw/vertical-order-selected :down))
|
|
do-send-to-back #(st/emit! (dw/vertical-order-selected :bottom))
|
|
do-show-shape #(st/emit! (dw/recursive-assign id :hidden false))
|
|
do-hide-shape #(st/emit! (dw/recursive-assign id :hidden true))
|
|
do-lock-shape #(st/emit! (dw/recursive-assign id :blocked true))
|
|
do-unlock-shape #(st/emit! (dw/recursive-assign id :blocked false))
|
|
do-create-group #(st/emit! dw/create-group)
|
|
do-remove-group #(st/emit! dw/remove-group)]
|
|
[:*
|
|
[:& menu-entry {:title "Copy"
|
|
:shortcut "Ctrl + c"
|
|
:on-click do-copy}]
|
|
[:& menu-entry {:title "Paste"
|
|
:shortcut "Ctrl + v"
|
|
:on-click do-paste}]
|
|
[:& menu-entry {:title "Duplicate"
|
|
:shortcut "Ctrl + d"
|
|
:on-click do-duplicate}]
|
|
[:& menu-separator]
|
|
[:& menu-entry {:title "Bring forward"
|
|
:shortcut "Ctrl + ↑"
|
|
:on-click do-bring-forward}]
|
|
[:& menu-entry {:title "Bring to front"
|
|
:shortcut "Ctrl + Shift + ↑"
|
|
:on-click do-bring-to-front}]
|
|
[:& menu-entry {:title "Send backward"
|
|
:shortcut "Ctrl + ↓"
|
|
:on-click do-send-backward}]
|
|
[:& menu-entry {:title "Send to back"
|
|
:shortcut "Ctrl + Shift + ↓"
|
|
:on-click do-send-to-back}]
|
|
[:& menu-separator]
|
|
|
|
(when (> (count selected) 1)
|
|
[:& menu-entry {:title "Group"
|
|
:shortcut "Ctrl + g"
|
|
:on-click do-create-group}])
|
|
|
|
(when (and (= (count selected)) (= (:type shape) :group))
|
|
[:& menu-entry {:title "Ungroup"
|
|
:shortcut "Ctrl + shift + g"
|
|
:on-click do-remove-group}])
|
|
|
|
(if (:hidden shape)
|
|
[:& menu-entry {:title "Show"
|
|
:on-click do-show-shape}]
|
|
[:& menu-entry {:title "Hide"
|
|
:on-click do-hide-shape}])
|
|
|
|
|
|
|
|
(if (:blocked shape)
|
|
[:& menu-entry {:title "Unlock"
|
|
:on-click do-unlock-shape}]
|
|
[:& menu-entry {:title "Lock"
|
|
:on-click do-lock-shape}])
|
|
[:& menu-separator]
|
|
[:& menu-entry {:title "Delete"
|
|
:shortcut "Supr"
|
|
:on-click do-delete}]
|
|
]))
|
|
|
|
(mf/defc viewport-context-menu
|
|
[{:keys [mdata] :as props}]
|
|
(let [do-paste #(st/emit! dw/paste)]
|
|
[:*
|
|
[:& menu-entry {:title "Paste"
|
|
:shortcut "Ctrl + v"
|
|
:on-click do-paste}]]))
|
|
|
|
(mf/defc context-menu
|
|
[props]
|
|
(let [mdata (mf/deref menu-ref)]
|
|
[:& dropdown {:show (boolean mdata)
|
|
:on-close #(st/emit! dw/hide-context-menu)}
|
|
[:ul.workspace-context-menu
|
|
{:style {:top (- (get-in mdata [:position :y]) 20)
|
|
:left (get-in mdata [:position :x])}
|
|
:on-context-menu prevent-default}
|
|
|
|
(if (:shape mdata)
|
|
[:& shape-context-menu {:mdata mdata}]
|
|
[:& viewport-context-menu {:mdata mdata}])]]))
|
|
|
|
|
|
|