0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-10 08:50:57 -05:00

Merge pull request #238 from uxbox/393/hover_feedback

Hover feedback on shapes
This commit is contained in:
Hirunatan 2020-06-03 15:59:25 +02:00 committed by GitHub
commit 8989591b04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 14 deletions

View file

@ -297,3 +297,11 @@
(rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})
(select-shapes selected))))))
(defn change-hover-state [id value]
(ptk/reify ::change-hover-state
ptk/UpdateEvent
(update [_ state]
(-> state
(update-in [:workspace-local :hover] #(if (nil? %) #{} %))
(update-in [:workspace-local :hover] (comp (if value conj disj)) id)))))

View file

@ -147,6 +147,9 @@
(def vbox
(l/derived :vbox workspace-local))
(def current-hover
(l/derived :hover workspace-local))
;; ---- Viewer refs
(def viewer-data

View file

@ -22,7 +22,7 @@
(mf/fnc frame-shape
{::mf/wrap-props false}
[props]
(let [childs (unchecked-get props "childs")
(let [children (unchecked-get props "children")
shape (unchecked-get props "shape")
{:keys [id x y width height]} shape
@ -36,7 +36,7 @@
:height height}))]
[:svg {:x x :y y :width width :height height}
[:> "rect" props]
(for [[i item] (d/enumerate childs)]
(for [[i item] (d/enumerate children)]
[:& shape-wrapper {:frame shape
:shape item
:key (:id item)}])])))

View file

@ -19,6 +19,8 @@
[uxbox.main.ui.shapes.circle :as circle]
[uxbox.main.ui.shapes.icon :as icon]
[uxbox.main.ui.shapes.image :as image]
[uxbox.main.data.workspace.selection :as dws]
[uxbox.main.store :as st]
;; Shapes that has some peculiarities are defined in its own
;; namespace under uxbox.ui.workspace.shapes.* prefix, all the
@ -52,20 +54,39 @@
(and (identical? n-shape o-shape)
(identical? n-frame o-frame)))))
(defn use-mouse-over
[{:keys [id] :as shape}]
(mf/use-callback
(mf/deps shape)
(fn []
(st/emit! (dws/change-hover-state id true)))))
(defn use-mouse-out
[{:keys [id] :as shape}]
(mf/use-callback
(mf/deps shape)
(fn []
(st/emit! (dws/change-hover-state id false)))))
(mf/defc shape-wrapper
{::mf/wrap [#(mf/memo' % shape-wrapper-memo-equals?)]
::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
frame (unchecked-get props "frame")
opts #js {:shape (->> shape (geom/transform-shape frame))
shape (geom/transform-shape frame shape)
opts #js {:shape shape
:frame frame}
alt? (mf/use-state false)]
alt? (mf/use-state false)
on-mouse-over (use-mouse-over shape)
on-mouse-out (use-mouse-out shape)]
(hooks/use-stream ms/keyboard-alt #(reset! alt? %))
(when (and shape (not (:hidden shape)))
[:g.shape {:style {:cursor (if @alt? cur/duplicate nil)}}
[:g.shape-wrapper {:on-mouse-over on-mouse-over
:on-mouse-out on-mouse-out
:style {:cursor (if @alt? cur/duplicate nil)}}
(case (:type shape)
:curve [:> path/path-wrapper opts]
:path [:> path/path-wrapper opts]
@ -79,7 +100,7 @@
;; Only used when drawing a new frame.
:frame [:> frame-wrapper {:shape shape}]
nil)
[:& bounding-box {:shape (->> shape (geom/transform-shape frame)) :frame frame}]])))
[:& bounding-box {:shape shape :frame frame}]])))
(def group-wrapper (group/group-wrapper-factory shape-wrapper))
(def frame-wrapper (frame/frame-wrapper-factory shape-wrapper))

View file

@ -9,6 +9,7 @@
(ns uxbox.main.ui.workspace.shapes.frame
(:require
[clojure.set :as set]
[rumext.alpha :as mf]
[uxbox.common.data :as d]
[uxbox.main.constants :as c]
@ -16,6 +17,7 @@
[uxbox.main.refs :as refs]
[uxbox.main.store :as st]
[uxbox.main.ui.workspace.shapes.common :as common]
[uxbox.main.ui.workspace.shapes.outline :refer [outline]]
[uxbox.main.ui.shapes.frame :as frame]
[uxbox.common.geom.matrix :as gmt]
[uxbox.common.geom.point :as gpt]
@ -58,6 +60,9 @@
selected? (mf/deref selected-iref)
zoom (mf/deref refs/selected-zoom)
selected-shape? (or (mf/deref refs/selected-shapes) #{})
hover? (or (mf/deref refs/current-hover) #{})
outline? (set/union selected-shape? hover?)
on-mouse-down (mf/use-callback (mf/deps shape)
#(common/on-mouse-down % shape))
@ -68,7 +73,7 @@
{:keys [x y width height]} shape
inv-zoom (/ 1 zoom)
childs (mapv #(get objects %) (:shapes shape))
children (mapv #(get objects %) (:shapes shape))
ds-modifier (get-in shape [:modifiers :displacement])
label-pos (gpt/point x (- y (/ 10 zoom)))
@ -102,7 +107,12 @@
;; User may also select the frame with single click in the label
:on-click on-double-click}
(:name shape)]
[:& frame-shape
{:shape shape
:childs childs}]])))))
[:*
[:& frame-shape
{:shape shape
:children children}]
[:g.outlines
(for [child (filter (comp outline? :id) children)]
[:& outline {:shape (geom/transform-shape child)}])]]])))))

View file

@ -0,0 +1,52 @@
;; 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.shapes.outline
(:require
[rumext.alpha :as mf]
[uxbox.common.geom.shapes :as gsh]
[uxbox.util.object :as obj]
[rumext.util :refer [map->obj]]
[uxbox.main.ui.shapes.path :as path]))
(mf/defc outline
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
transform (gsh/transform-matrix shape)
{:keys [id x y width height]} shape
outline-type (case (:type shape)
:circle "ellipse"
(:curve :path) "path"
"rect")
common {:fill "transparent"
:stroke "#31EFB8"
:stroke-width "1px"
:pointer-events "none"
:transform transform}
props (case (:type shape)
:circle
{:cx (+ x (/ width 2))
:cy (+ y (/ height 2))
:rx (/ width 2)
:ry (/ height 2)}
(:curve :path)
{:d (path/render-path shape)}
{:x x
:y y
:width width
:height height})]
[:> outline-type (map->obj (merge common props))]))

View file

@ -27,8 +27,7 @@
{::mf/wrap-props false}
[props]
(let [shape (unchecked-get props "shape")
selected (mf/deref refs/selected-shapes)
selected? (contains? selected (:id shape))
hover? (or (mf/deref refs/current-hover) #{})
on-mouse-down (mf/use-callback
(mf/deps shape)
#(common/on-mouse-down % shape))
@ -38,8 +37,11 @@
on-double-click (mf/use-callback
(mf/deps shape)
(fn [event]
(when selected?
(st/emit! (dw/start-edition-mode (:id shape))))))]
(when (hover? (:id shape))
(do
(dom/stop-propagation event)
(dom/prevent-default event)
(st/emit! (dw/start-edition-mode (:id shape)))))))]
[:g.shape {:on-double-click on-double-click
:on-mouse-down on-mouse-down