mirror of
https://github.com/penpot/penpot.git
synced 2025-01-24 07:29:08 -05: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
|
||||
|
||||
(defrecord KeyboardEvent [type key shift ctrl alt])
|
||||
(defrecord KeyboardEvent [type key shift ctrl alt meta])
|
||||
|
||||
(defn keyboard-event?
|
||||
[v]
|
||||
|
@ -120,6 +120,21 @@
|
|||
(rx/map (constantly false))))
|
||||
(rx/dedupe))]
|
||||
(rx/subscribe-with ob 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
|
||||
|
|
|
@ -52,11 +52,9 @@
|
|||
drawing? @refs/selected-drawing-tool
|
||||
button (.-which (.-nativeEvent event))
|
||||
shift? (kbd/shift? event)
|
||||
ctrl? (or (kbd/ctrl? event) (kbd/meta? event))
|
||||
|
||||
allow-click? (and (not blocked)
|
||||
(not drawing?)
|
||||
(not ctrl?)
|
||||
(not edition))]
|
||||
|
||||
(when (and (= button 1) allow-click?)
|
||||
|
|
|
@ -10,29 +10,30 @@
|
|||
(ns app.main.ui.workspace.selection
|
||||
"Selection handlers component."
|
||||
(:require
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[rumext.alpha :as mf]
|
||||
[rumext.util :refer [map->obj]]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.common.math :as mth]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.util.data :as d]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.common :as dwc]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[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.object :as obj]
|
||||
[app.common.geom.shapes :as geom]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.util.debug :refer [debug?]]
|
||||
[app.main.ui.workspace.shapes.outline :refer [outline]]
|
||||
[app.main.ui.measurements :as msr]
|
||||
[app.main.ui.workspace.shapes.path.editor :refer [path-editor]]))
|
||||
[beicon.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[rumext.alpha :as mf]
|
||||
[rumext.util :refer [map->obj]]))
|
||||
|
||||
(def rotation-handler-size 20)
|
||||
(def resize-point-radius 4)
|
||||
|
@ -235,19 +236,22 @@
|
|||
(mf/defc controls
|
||||
{::mf/wrap-props false}
|
||||
[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")
|
||||
color (obj/get props "color")
|
||||
on-resize (obj/get props "on-resize")
|
||||
on-rotate (obj/get props "on-rotate")
|
||||
current-transform (mf/deref refs/current-transform)
|
||||
|
||||
hide? (mf/use-state false)
|
||||
selrect (-> (:selrect shape)
|
||||
minimum-selrect)
|
||||
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))
|
||||
[:g.controls
|
||||
[:g.controls {:style {:display (when @hide? "none")}}
|
||||
|
||||
;; Selection rect
|
||||
[:& selection-rect {:rect selrect
|
||||
|
|
|
@ -9,17 +9,18 @@
|
|||
|
||||
(ns app.main.ui.workspace.shapes.group
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.streams :as ms]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.shapes.group :as group]
|
||||
[app.main.ui.shapes.shape :refer [shape-container]]
|
||||
[app.main.ui.workspace.effects :as we]
|
||||
[app.util.debug :refer [debug?]]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.alpha :as mf]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.util.debug :refer [debug?]]))
|
||||
[rumext.alpha :as mf]))
|
||||
|
||||
(defn use-double-click [{:keys [id]}]
|
||||
(mf/use-callback
|
||||
|
@ -40,8 +41,10 @@
|
|||
frame (unchecked-get props "frame")
|
||||
|
||||
{: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 (mf/deref childs-ref)
|
||||
|
||||
|
@ -59,33 +62,38 @@
|
|||
is-mask-selected?
|
||||
(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-context-menu (we/use-context-menu shape)
|
||||
handle-pointer-enter (we/use-pointer-enter shape)
|
||||
handle-pointer-leave (we/use-pointer-leave shape)
|
||||
handle-double-click (use-double-click shape)]
|
||||
|
||||
(hooks/use-stream ms/keyboard-ctrl #(reset! ctrl? %))
|
||||
|
||||
[:> shape-container {:shape shape}
|
||||
[:g.group-shape
|
||||
[:& group-shape
|
||||
{:frame frame
|
||||
:shape shape
|
||||
:childs childs
|
||||
:expand-mask is-mask-selected?
|
||||
:pointer-events (when (not is-child-selected?) "none")}]
|
||||
:expand-mask expand-mask?
|
||||
:pointer-events (when group-interactions? "none")}]
|
||||
|
||||
(when-not is-child-selected?
|
||||
[:rect.group-actions
|
||||
{:x x
|
||||
:y y
|
||||
:fill (if (debug? :group) "red" "transparent")
|
||||
:opacity 0.5
|
||||
:transform transform
|
||||
:width width
|
||||
:height height
|
||||
:on-mouse-down handle-mouse-down
|
||||
:on-context-menu handle-context-menu
|
||||
:on-pointer-over handle-pointer-enter
|
||||
:on-pointer-out handle-pointer-leave
|
||||
:on-double-click handle-double-click}])]]))))
|
||||
[:rect.group-actions
|
||||
{:x x
|
||||
:y y
|
||||
:width width
|
||||
: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-context-menu handle-context-menu
|
||||
:on-pointer-over handle-pointer-enter
|
||||
:on-pointer-out handle-pointer-leave
|
||||
:on-double-click handle-double-click}]]]))))
|
||||
|
||||
|
|
|
@ -219,11 +219,17 @@
|
|||
(not (:blocked shape))
|
||||
(not= edition (: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)
|
||||
color (if (or (> (count shapes) 1) (nil? (:shape-ref (first shapes))))
|
||||
"#31EFB8"
|
||||
"#00E0FF")]
|
||||
(hooks/use-stream ms/keyboard-ctrl #(reset! remove-groups? %))
|
||||
(when (nil? transform)
|
||||
[:g.outlines
|
||||
(for [shape shapes]
|
||||
|
@ -424,16 +430,16 @@
|
|||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [target (dom/get-target event)]
|
||||
; Capture mouse pointer to detect the movements even if cursor
|
||||
; leaves the viewport or the browser itself
|
||||
; https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture
|
||||
; Capture mouse pointer to detect the movements even if cursor
|
||||
; leaves the viewport or the browser itself
|
||||
; https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture
|
||||
(.setPointerCapture target (.-pointerId event)))))
|
||||
|
||||
on-pointer-up
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [target (dom/get-target event)]
|
||||
; Release pointer on mouse up
|
||||
; Release pointer on mouse up
|
||||
(.releasePointerCapture target (.-pointerId event)))))
|
||||
|
||||
on-click
|
||||
|
@ -442,9 +448,7 @@
|
|||
(let [ctrl? (kbd/ctrl? event)
|
||||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)]
|
||||
(if ctrl?
|
||||
(st/emit! (dw/select-last-layer @ms/mouse-position))
|
||||
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?))))))
|
||||
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt?)))))
|
||||
|
||||
on-double-click
|
||||
(mf/use-callback
|
||||
|
@ -460,14 +464,15 @@
|
|||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [bevent (.getBrowserEvent ^js event)
|
||||
key (.-keyCode ^js event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
key (.-keyCode ^js event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)
|
||||
alt? (kbd/alt? event)
|
||||
meta? (kbd/meta? event)
|
||||
target (dom/get-target event)]
|
||||
|
||||
(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)
|
||||
(not= "rich-text" (obj/get target "className"))
|
||||
(not= "INPUT" (obj/get target "tagName"))
|
||||
|
@ -477,13 +482,14 @@
|
|||
on-key-up
|
||||
(mf/use-callback
|
||||
(fn [event]
|
||||
(let [key (.-keyCode event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
(let [key (.-keyCode event)
|
||||
ctrl? (kbd/ctrl? event)
|
||||
shift? (kbd/shift? event)
|
||||
alt? (kbd/alt? event)]
|
||||
alt? (kbd/alt? event)
|
||||
meta? (kbd/meta? event)]
|
||||
(when (kbd/space? event)
|
||||
(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
|
||||
(mf/use-callback
|
||||
|
|
Loading…
Add table
Reference in a new issue