mirror of
https://github.com/penpot/penpot.git
synced 2025-05-18 14:46:10 +02:00
✨ Control key to hide group interactions
This commit is contained in:
parent
fcda3b557e
commit
6c2b5ff0c7
5 changed files with 86 additions and 55 deletions
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
;; --- User Events
|
;; --- User Events
|
||||||
|
|
||||||
(defrecord KeyboardEvent [type key shift ctrl alt])
|
(defrecord KeyboardEvent [type key shift ctrl alt meta])
|
||||||
|
|
||||||
(defn keyboard-event?
|
(defn keyboard-event?
|
||||||
[v]
|
[v]
|
||||||
|
@ -122,6 +122,21 @@
|
||||||
(rx/subscribe-with ob sub)
|
(rx/subscribe-with ob sub)
|
||||||
sub))
|
sub))
|
||||||
|
|
||||||
|
(defonce keyboard-ctrl
|
||||||
|
(let [sub (rx/behavior-subject nil)
|
||||||
|
ob (->> (rx/merge
|
||||||
|
(->> st/stream
|
||||||
|
(rx/filter keyboard-event?)
|
||||||
|
(rx/map :ctrl))
|
||||||
|
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||||
|
;; that makes keyboard-alt stream registring the key pressed but
|
||||||
|
;; on bluring the window (unfocus) the key down is never arrived.
|
||||||
|
(->> window-blur
|
||||||
|
(rx/map (constantly false))))
|
||||||
|
(rx/dedupe))]
|
||||||
|
(rx/subscribe-with ob sub)
|
||||||
|
sub))
|
||||||
|
|
||||||
(defn mouse-position-deltas
|
(defn mouse-position-deltas
|
||||||
[current]
|
[current]
|
||||||
(->> (rx/concat (rx/of current)
|
(->> (rx/concat (rx/of current)
|
||||||
|
|
|
@ -52,11 +52,9 @@
|
||||||
drawing? @refs/selected-drawing-tool
|
drawing? @refs/selected-drawing-tool
|
||||||
button (.-which (.-nativeEvent event))
|
button (.-which (.-nativeEvent event))
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
ctrl? (or (kbd/ctrl? event) (kbd/meta? event))
|
|
||||||
|
|
||||||
allow-click? (and (not blocked)
|
allow-click? (and (not blocked)
|
||||||
(not drawing?)
|
(not drawing?)
|
||||||
(not ctrl?)
|
|
||||||
(not edition))]
|
(not edition))]
|
||||||
|
|
||||||
(when (and (= button 1) allow-click?)
|
(when (and (= button 1) allow-click?)
|
||||||
|
|
|
@ -10,29 +10,30 @@
|
||||||
(ns app.main.ui.workspace.selection
|
(ns app.main.ui.workspace.selection
|
||||||
"Selection handlers component."
|
"Selection handlers component."
|
||||||
(:require
|
(:require
|
||||||
[beicon.core :as rx]
|
[app.common.geom.matrix :as gmt]
|
||||||
[cuerdas.core :as str]
|
[app.common.geom.point :as gpt]
|
||||||
[potok.core :as ptk]
|
[app.common.geom.shapes :as geom]
|
||||||
[rumext.alpha :as mf]
|
[app.common.math :as mth]
|
||||||
[rumext.util :refer [map->obj]]
|
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.data :as d]
|
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[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]
|
||||||
[app.main.ui.cursors :as cur]
|
[app.main.ui.cursors :as cur]
|
||||||
[app.common.math :as mth]
|
[app.main.ui.hooks :as hooks]
|
||||||
|
[app.main.ui.measurements :as msr]
|
||||||
|
[app.main.ui.workspace.shapes.outline :refer [outline]]
|
||||||
|
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]
|
||||||
|
[app.util.data :as d]
|
||||||
|
[app.util.debug :refer [debug?]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.common.geom.shapes :as geom]
|
[beicon.core :as rx]
|
||||||
[app.common.geom.point :as gpt]
|
[cuerdas.core :as str]
|
||||||
[app.common.geom.matrix :as gmt]
|
[potok.core :as ptk]
|
||||||
[app.util.debug :refer [debug?]]
|
[rumext.alpha :as mf]
|
||||||
[app.main.ui.workspace.shapes.outline :refer [outline]]
|
[rumext.util :refer [map->obj]]))
|
||||||
[app.main.ui.measurements :as msr]
|
|
||||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]))
|
|
||||||
|
|
||||||
(def rotation-handler-size 20)
|
(def rotation-handler-size 20)
|
||||||
(def resize-point-radius 4)
|
(def resize-point-radius 4)
|
||||||
|
@ -235,19 +236,22 @@
|
||||||
(mf/defc controls
|
(mf/defc controls
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [{:keys [overflow-text] :as shape} (obj/get props "shape")
|
(let [{:keys [overflow-text type] :as shape} (obj/get props "shape")
|
||||||
zoom (obj/get props "zoom")
|
zoom (obj/get props "zoom")
|
||||||
color (obj/get props "color")
|
color (obj/get props "color")
|
||||||
on-resize (obj/get props "on-resize")
|
on-resize (obj/get props "on-resize")
|
||||||
on-rotate (obj/get props "on-rotate")
|
on-rotate (obj/get props "on-rotate")
|
||||||
current-transform (mf/deref refs/current-transform)
|
current-transform (mf/deref refs/current-transform)
|
||||||
|
|
||||||
|
hide? (mf/use-state false)
|
||||||
selrect (-> (:selrect shape)
|
selrect (-> (:selrect shape)
|
||||||
minimum-selrect)
|
minimum-selrect)
|
||||||
transform (geom/transform-matrix shape {:no-flip true})]
|
transform (geom/transform-matrix shape {:no-flip true})]
|
||||||
|
|
||||||
|
(hooks/use-stream ms/keyboard-ctrl #(when (= type :group) (reset! hide? %)))
|
||||||
|
|
||||||
(when (not (#{:move :rotate} current-transform))
|
(when (not (#{:move :rotate} current-transform))
|
||||||
[:g.controls
|
[:g.controls {:style {:display (when @hide? "none")}}
|
||||||
|
|
||||||
;; Selection rect
|
;; Selection rect
|
||||||
[:& selection-rect {:rect selrect
|
[:& selection-rect {:rect selrect
|
||||||
|
|
|
@ -9,17 +9,18 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.shapes.group
|
(ns app.main.ui.workspace.shapes.group
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[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]
|
||||||
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.main.ui.shapes.group :as group]
|
[app.main.ui.shapes.group :as group]
|
||||||
[app.main.ui.shapes.shape :refer [shape-container]]
|
[app.main.ui.shapes.shape :refer [shape-container]]
|
||||||
[app.main.ui.workspace.effects :as we]
|
[app.main.ui.workspace.effects :as we]
|
||||||
|
[app.util.debug :refer [debug?]]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]))
|
||||||
[app.common.geom.shapes :as gsh]
|
|
||||||
[app.util.debug :refer [debug?]]))
|
|
||||||
|
|
||||||
(defn use-double-click [{:keys [id]}]
|
(defn use-double-click [{:keys [id]}]
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -40,8 +41,10 @@
|
||||||
frame (unchecked-get props "frame")
|
frame (unchecked-get props "frame")
|
||||||
|
|
||||||
{:keys [id x y width height]} shape
|
{:keys [id x y width height]} shape
|
||||||
|
|
||||||
transform (gsh/transform-matrix shape)
|
transform (gsh/transform-matrix shape)
|
||||||
|
|
||||||
|
ctrl? (mf/use-state false)
|
||||||
childs-ref (mf/use-memo (mf/deps shape) #(refs/objects-by-id (:shapes shape)))
|
childs-ref (mf/use-memo (mf/deps shape) #(refs/objects-by-id (:shapes shape)))
|
||||||
childs (mf/deref childs-ref)
|
childs (mf/deref childs-ref)
|
||||||
|
|
||||||
|
@ -59,33 +62,38 @@
|
||||||
is-mask-selected?
|
is-mask-selected?
|
||||||
(mf/deref is-mask-selected-ref)
|
(mf/deref is-mask-selected-ref)
|
||||||
|
|
||||||
|
expand-mask? is-child-selected?
|
||||||
|
group-interactions? (not (or @ctrl? is-child-selected?))
|
||||||
|
|
||||||
handle-mouse-down (we/use-mouse-down shape)
|
handle-mouse-down (we/use-mouse-down shape)
|
||||||
handle-context-menu (we/use-context-menu shape)
|
handle-context-menu (we/use-context-menu shape)
|
||||||
handle-pointer-enter (we/use-pointer-enter shape)
|
handle-pointer-enter (we/use-pointer-enter shape)
|
||||||
handle-pointer-leave (we/use-pointer-leave shape)
|
handle-pointer-leave (we/use-pointer-leave shape)
|
||||||
handle-double-click (use-double-click shape)]
|
handle-double-click (use-double-click shape)]
|
||||||
|
|
||||||
|
(hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %))
|
||||||
|
|
||||||
[:> shape-container {:shape shape}
|
[:> shape-container {:shape shape}
|
||||||
[:g.group-shape
|
[:g.group-shape
|
||||||
[:& group-shape
|
[:& group-shape
|
||||||
{:frame frame
|
{:frame frame
|
||||||
:shape shape
|
:shape shape
|
||||||
:childs childs
|
:childs childs
|
||||||
:expand-mask is-mask-selected?
|
:expand-mask expand-mask?
|
||||||
:pointer-events (when (not is-child-selected?) "none")}]
|
:pointer-events (when group-interactions? "none")}]
|
||||||
|
|
||||||
(when-not is-child-selected?
|
|
||||||
[:rect.group-actions
|
[:rect.group-actions
|
||||||
{:x x
|
{:x x
|
||||||
:y y
|
:y y
|
||||||
:fill (if (debug? :group) "red" "transparent")
|
|
||||||
:opacity 0.5
|
|
||||||
:transform transform
|
|
||||||
:width width
|
:width width
|
||||||
:height height
|
:height height
|
||||||
|
:transform transform
|
||||||
|
:style {:pointer-events (when-not group-interactions? "none")
|
||||||
|
:fill (if (debug? :group) "red" "transparent")
|
||||||
|
:opacity 0.5}
|
||||||
:on-mouse-down handle-mouse-down
|
:on-mouse-down handle-mouse-down
|
||||||
:on-context-menu handle-context-menu
|
:on-context-menu handle-context-menu
|
||||||
:on-pointer-over handle-pointer-enter
|
:on-pointer-over handle-pointer-enter
|
||||||
:on-pointer-out handle-pointer-leave
|
:on-pointer-out handle-pointer-leave
|
||||||
:on-double-click handle-double-click}])]]))))
|
:on-double-click handle-double-click}]]]))))
|
||||||
|
|
||||||
|
|
|
@ -219,11 +219,17 @@
|
||||||
(not (:blocked shape))
|
(not (:blocked shape))
|
||||||
(not= edition (:id shape))
|
(not= edition (:id shape))
|
||||||
(outline? (:id shape))))
|
(outline? (:id shape))))
|
||||||
shapes (->> (vals objects) (filter show-outline?))
|
|
||||||
|
remove-groups? (mf/use-state false)
|
||||||
|
|
||||||
|
shapes (cond->> (vals objects)
|
||||||
|
show-outline? (filter show-outline?)
|
||||||
|
@remove-groups? (remove #(= :group (:type %))))
|
||||||
transform (mf/deref refs/current-transform)
|
transform (mf/deref refs/current-transform)
|
||||||
color (if (or (> (count shapes) 1) (nil? (:shape-ref (first shapes))))
|
color (if (or (> (count shapes) 1) (nil? (:shape-ref (first shapes))))
|
||||||
"#31EFB8"
|
"#31EFB8"
|
||||||
"#00E0FF")]
|
"#00E0FF")]
|
||||||
|
(hooks/use-stream ms/keyboard-ctrl #(reset! remove-groups? %))
|
||||||
(when (nil? transform)
|
(when (nil? transform)
|
||||||
[:g.outlines
|
[:g.outlines
|
||||||
(for [shape shapes]
|
(for [shape shapes]
|
||||||
|
@ -442,9 +448,7 @@
|
||||||
(let [ctrl? (kbd/ctrl? event)
|
(let [ctrl? (kbd/ctrl? event)
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)]
|
alt? (kbd/alt? event)]
|
||||||
(if ctrl?
|
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?)))))
|
||||||
(st/emit! (dw/select-last-layer @ms/mouse-position))
|
|
||||||
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?))))))
|
|
||||||
|
|
||||||
on-double-click
|
on-double-click
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -464,10 +468,11 @@
|
||||||
ctrl? (kbd/ctrl? event)
|
ctrl? (kbd/ctrl? event)
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)
|
alt? (kbd/alt? event)
|
||||||
|
meta? (kbd/meta? event)
|
||||||
target (dom/get-target event)]
|
target (dom/get-target event)]
|
||||||
|
|
||||||
(when-not (.-repeat bevent)
|
(when-not (.-repeat bevent)
|
||||||
(st/emit! (ms/->KeyboardEvent :down key ctrl? shift? alt?))
|
(st/emit! (ms/->KeyboardEvent :down key shift? ctrl? alt? meta?))
|
||||||
(when (and (kbd/space? event)
|
(when (and (kbd/space? event)
|
||||||
(not= "rich-text" (obj/get target "className"))
|
(not= "rich-text" (obj/get target "className"))
|
||||||
(not= "INPUT" (obj/get target "tagName"))
|
(not= "INPUT" (obj/get target "tagName"))
|
||||||
|
@ -480,10 +485,11 @@
|
||||||
(let [key (.-keyCode event)
|
(let [key (.-keyCode event)
|
||||||
ctrl? (kbd/ctrl? event)
|
ctrl? (kbd/ctrl? event)
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)]
|
alt? (kbd/alt? event)
|
||||||
|
meta? (kbd/meta? event)]
|
||||||
(when (kbd/space? event)
|
(when (kbd/space? event)
|
||||||
(st/emit! dw/finish-pan ::finish-positioning))
|
(st/emit! dw/finish-pan ::finish-positioning))
|
||||||
(st/emit! (ms/->KeyboardEvent :up key ctrl? shift? alt?)))))
|
(st/emit! (ms/->KeyboardEvent :up key shift? ctrl? alt? meta?)))))
|
||||||
|
|
||||||
translate-point-to-viewport
|
translate-point-to-viewport
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue