mirror of
https://github.com/penpot/penpot.git
synced 2025-02-13 02:28:18 -05:00
Merge pull request #2114 from penpot/andrewzhurov-2645-hovering-layers-bounding-box
Layer outlines hightlight on hovering
This commit is contained in:
commit
aa95114860
8 changed files with 201 additions and 109 deletions
|
@ -5,12 +5,15 @@
|
||||||
### :boom: Breaking changes & Deprecations
|
### :boom: Breaking changes & Deprecations
|
||||||
### :sparkles: New features
|
### :sparkles: New features
|
||||||
|
|
||||||
- Add some cosmetic changes in viewer mode [Taiga #3688](https://tree.taiga.io/project/penpot/us/3688)
|
- Add cosmetic changes in viewer mode [Taiga #3688](https://tree.taiga.io/project/penpot/us/3688)
|
||||||
|
- Outline highlights on layer hovering [Taiga #2645](https://tree.taiga.io/project/penpot/us/2645) by @andrewzhurov
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
### :heart: Community contributions by (Thank you!)
|
### :heart: Community contributions by (Thank you!)
|
||||||
|
|
||||||
|
- To @andrewzhurov for many code contributions on this release.
|
||||||
|
|
||||||
|
|
||||||
## 1.15.0-beta
|
## 1.15.0-beta
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
[app.main.data.workspace.fix-bool-contents :as fbc]
|
[app.main.data.workspace.fix-bool-contents :as fbc]
|
||||||
[app.main.data.workspace.groups :as dwg]
|
[app.main.data.workspace.groups :as dwg]
|
||||||
[app.main.data.workspace.guides :as dwgu]
|
[app.main.data.workspace.guides :as dwgu]
|
||||||
|
[app.main.data.workspace.highlight :as dwh]
|
||||||
[app.main.data.workspace.interactions :as dwi]
|
[app.main.data.workspace.interactions :as dwi]
|
||||||
[app.main.data.workspace.layers :as dwly]
|
[app.main.data.workspace.layers :as dwly]
|
||||||
[app.main.data.workspace.layout :as layout]
|
[app.main.data.workspace.layout :as layout]
|
||||||
|
@ -1732,6 +1733,10 @@
|
||||||
(dm/export dws/select-shape)
|
(dm/export dws/select-shape)
|
||||||
(dm/export dws/shift-select-shapes)
|
(dm/export dws/shift-select-shapes)
|
||||||
|
|
||||||
|
;; Highlight
|
||||||
|
(dm/export dwh/highlight-shape)
|
||||||
|
(dm/export dwh/dehighlight-shape)
|
||||||
|
|
||||||
;; Groups
|
;; Groups
|
||||||
(dm/export dwg/mask-group)
|
(dm/export dwg/mask-group)
|
||||||
(dm/export dwg/unmask-group)
|
(dm/export dwg/unmask-group)
|
||||||
|
|
29
frontend/src/app/main/data/workspace/highlight.cljs
Normal file
29
frontend/src/app/main/data/workspace/highlight.cljs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
;; 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) UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns app.main.data.workspace.highlight
|
||||||
|
(:require
|
||||||
|
[app.common.spec :as us]
|
||||||
|
[clojure.set :as set]
|
||||||
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
|
;; --- Manage shape's highlight status
|
||||||
|
|
||||||
|
(defn highlight-shape
|
||||||
|
[id]
|
||||||
|
(us/verify ::us/uuid id)
|
||||||
|
(ptk/reify ::highlight-shape
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in state [:workspace-local :highlighted] set/union #{id}))))
|
||||||
|
|
||||||
|
(defn dehighlight-shape
|
||||||
|
[id]
|
||||||
|
(us/verify ::us/uuid id)
|
||||||
|
(ptk/reify ::dehighlight-shape
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in state [:workspace-local :highlighted] disj id))))
|
|
@ -251,6 +251,8 @@
|
||||||
[page-id]
|
[page-id]
|
||||||
(l/derived #(wsh/lookup-page-objects % page-id) st/state =))
|
(l/derived #(wsh/lookup-page-objects % page-id) st/state =))
|
||||||
|
|
||||||
|
;; TODO: Looks like using the `=` comparator can be pretty expensive
|
||||||
|
;; on large pages, we are using this for some reason?
|
||||||
(def workspace-page-objects
|
(def workspace-page-objects
|
||||||
(l/derived wsh/lookup-page-objects st/state =))
|
(l/derived wsh/lookup-page-objects st/state =))
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"A workspace specific context menu (mouse right click)."
|
"A workspace specific context menu (mouse right click)."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.page :as ctp]
|
[app.common.types.page :as ctp]
|
||||||
[app.main.data.events :as ev]
|
[app.main.data.events :as ev]
|
||||||
|
@ -38,7 +39,7 @@
|
||||||
(dom/stop-propagation event))
|
(dom/stop-propagation event))
|
||||||
|
|
||||||
(mf/defc menu-entry
|
(mf/defc menu-entry
|
||||||
[{:keys [title shortcut on-click children selected? icon] :as props}]
|
[{:keys [title shortcut on-click on-pointer-enter on-pointer-leave on-unmount children selected? icon] :as props}]
|
||||||
(let [submenu-ref (mf/use-ref nil)
|
(let [submenu-ref (mf/use-ref nil)
|
||||||
hovering? (mf/use-ref false)
|
hovering? (mf/use-ref false)
|
||||||
|
|
||||||
|
@ -48,7 +49,8 @@
|
||||||
(mf/set-ref-val! hovering? true)
|
(mf/set-ref-val! hovering? true)
|
||||||
(let [submenu-node (mf/ref-val submenu-ref)]
|
(let [submenu-node (mf/ref-val submenu-ref)]
|
||||||
(when (some? submenu-node)
|
(when (some? submenu-node)
|
||||||
(dom/set-css-property! submenu-node "display" "block")))))
|
(dom/set-css-property! submenu-node "display" "block")))
|
||||||
|
(when on-pointer-enter (on-pointer-enter))))
|
||||||
|
|
||||||
on-pointer-leave
|
on-pointer-leave
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -59,7 +61,8 @@
|
||||||
(timers/schedule
|
(timers/schedule
|
||||||
200
|
200
|
||||||
#(when-not (mf/ref-val hovering?)
|
#(when-not (mf/ref-val hovering?)
|
||||||
(dom/set-css-property! submenu-node "display" "none")))))))
|
(dom/set-css-property! submenu-node "display" "none")))))
|
||||||
|
(when on-pointer-leave (on-pointer-leave))))
|
||||||
|
|
||||||
set-dom-node
|
set-dom-node
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
@ -68,6 +71,11 @@
|
||||||
(when (and (some? dom) (some? submenu-node))
|
(when (and (some? dom) (some? submenu-node))
|
||||||
(dom/set-css-property! submenu-node "top" (str (.-offsetTop dom) "px"))))))]
|
(dom/set-css-property! submenu-node "top" (str (.-offsetTop dom) "px"))))))]
|
||||||
|
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(mf/deps on-unmount)
|
||||||
|
(constantly on-unmount))
|
||||||
|
|
||||||
(if icon
|
(if icon
|
||||||
[:li.icon-menu-item {:ref set-dom-node
|
[:li.icon-menu-item {:ref set-dom-node
|
||||||
:on-click on-click
|
:on-click on-click
|
||||||
|
@ -123,19 +131,34 @@
|
||||||
[:& menu-separator]]))
|
[:& menu-separator]]))
|
||||||
|
|
||||||
(mf/defc context-menu-layer-position
|
(mf/defc context-menu-layer-position
|
||||||
[{:keys [hover-objs shapes]}]
|
[{:keys [shapes]}]
|
||||||
(let [do-bring-forward #(st/emit! (dw/vertical-order-selected :up))
|
(let [do-bring-forward (mf/use-fn #(st/emit! (dw/vertical-order-selected :up)))
|
||||||
do-bring-to-front #(st/emit! (dw/vertical-order-selected :top))
|
do-bring-to-front (mf/use-fn #(st/emit! (dw/vertical-order-selected :top)))
|
||||||
do-send-backward #(st/emit! (dw/vertical-order-selected :down))
|
do-send-backward (mf/use-fn #(st/emit! (dw/vertical-order-selected :down)))
|
||||||
do-send-to-back #(st/emit! (dw/vertical-order-selected :bottom))
|
do-send-to-back (mf/use-fn #(st/emit! (dw/vertical-order-selected :bottom)))
|
||||||
select-shapes (fn [id] #(st/emit! (dws/select-shape id)))]
|
|
||||||
|
select-shapes (fn [id] #(st/emit! (dws/select-shape id)))
|
||||||
|
on-pointer-enter (fn [id] #(st/emit! (dw/highlight-shape id)))
|
||||||
|
on-pointer-leave (fn [id] #(st/emit! (dw/dehighlight-shape id)))
|
||||||
|
on-unmount (fn [id] #(st/emit! (dw/dehighlight-shape id)))
|
||||||
|
|
||||||
|
;; NOTE: we use deref instead of mf/deref on objects because
|
||||||
|
;; we really don't want rerender on object changes
|
||||||
|
hover-ids (deref refs/current-hover-ids)
|
||||||
|
objects (deref refs/workspace-page-objects)
|
||||||
|
hover-objs (into [] (keep (d/getf objects)) hover-ids)]
|
||||||
|
|
||||||
[:*
|
[:*
|
||||||
(when (> (count hover-objs) 1)
|
(when (> (count hover-objs) 1)
|
||||||
[:& menu-entry {:title (tr "workspace.shape.menu.select-layer")}
|
[:& menu-entry {:title (tr "workspace.shape.menu.select-layer")}
|
||||||
(for [object hover-objs]
|
(for [object hover-objs]
|
||||||
[:& menu-entry {:title (:name object)
|
[:& menu-entry {:title (:name object)
|
||||||
|
:key (dm/str (:id object))
|
||||||
:selected? (some #(= object %) shapes)
|
:selected? (some #(= object %) shapes)
|
||||||
:on-click (select-shapes (:id object))
|
:on-click (select-shapes (:id object))
|
||||||
|
:on-pointer-enter (on-pointer-enter (:id object))
|
||||||
|
:on-pointer-leave (on-pointer-leave (:id object))
|
||||||
|
:on-unmount (on-unmount (:id object))
|
||||||
:icon (si/element-icon {:shape object})}])])
|
:icon (si/element-icon {:shape object})}])])
|
||||||
[:& menu-entry {:title (tr "workspace.shape.menu.forward")
|
[:& menu-entry {:title (tr "workspace.shape.menu.forward")
|
||||||
:shortcut (sc/get-tooltip :bring-forward)
|
:shortcut (sc/get-tooltip :bring-forward)
|
||||||
|
@ -435,14 +458,11 @@
|
||||||
:on-click do-delete}]))
|
:on-click do-delete}]))
|
||||||
|
|
||||||
(mf/defc shape-context-menu
|
(mf/defc shape-context-menu
|
||||||
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [mdata] :as props}]
|
[{:keys [mdata] :as props}]
|
||||||
(let [{:keys [disable-booleans? disable-flatten?]} mdata
|
(let [{:keys [disable-booleans? disable-flatten?]} mdata
|
||||||
shapes (mf/deref refs/selected-objects)
|
shapes (mf/deref refs/selected-objects)
|
||||||
hover-ids (mf/deref refs/current-hover-ids)
|
|
||||||
hover-objs (mf/deref (refs/objects-by-id hover-ids))
|
|
||||||
|
|
||||||
props #js {:shapes shapes
|
props #js {:shapes shapes
|
||||||
:hover-objs hover-objs
|
|
||||||
:disable-booleans? disable-booleans?
|
:disable-booleans? disable-booleans?
|
||||||
:disable-flatten? disable-flatten?}]
|
:disable-flatten? disable-flatten?}]
|
||||||
(when-not (empty? shapes)
|
(when-not (empty? shapes)
|
||||||
|
|
|
@ -84,91 +84,114 @@
|
||||||
(:name shape "")
|
(:name shape "")
|
||||||
(when (seq (:touched shape)) " *")])))
|
(when (seq (:touched shape)) " *")])))
|
||||||
|
|
||||||
(defn- make-collapsed-iref
|
|
||||||
[id]
|
|
||||||
#(-> (l/in [:expanded id])
|
|
||||||
(l/derived refs/workspace-local)))
|
|
||||||
|
|
||||||
(mf/defc layer-item
|
(mf/defc layer-item
|
||||||
[{:keys [index item selected objects] :as props}]
|
[{:keys [index item selected objects] :as props}]
|
||||||
(let [id (:id item)
|
(let [id (:id item)
|
||||||
selected? (contains? selected id)
|
blocked? (:blocked item)
|
||||||
container? (or (cph/frame-shape? item)
|
hidden? (:hidden item)
|
||||||
(cph/group-shape? item))
|
|
||||||
|
|
||||||
disable-drag (mf/use-state false)
|
disable-drag (mf/use-state false)
|
||||||
scroll-to-middle? (mf/use-var true)
|
scroll-to-middle? (mf/use-var true)
|
||||||
|
expanded-iref (mf/with-memo [id]
|
||||||
|
(-> (l/in [:expanded id])
|
||||||
|
(l/derived refs/workspace-local)))
|
||||||
|
|
||||||
expanded-iref (mf/use-memo
|
expanded? (mf/deref expanded-iref)
|
||||||
(mf/deps id)
|
selected? (contains? selected id)
|
||||||
(make-collapsed-iref id))
|
container? (or (cph/frame-shape? item)
|
||||||
|
(cph/group-shape? item))
|
||||||
expanded? (mf/deref expanded-iref)
|
|
||||||
|
|
||||||
toggle-collapse
|
toggle-collapse
|
||||||
(fn [event]
|
(mf/use-fn
|
||||||
(dom/stop-propagation event)
|
(mf/deps expanded?)
|
||||||
(if (and expanded? (kbd/shift? event))
|
(fn [event]
|
||||||
(st/emit! (dwc/collapse-all))
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dwc/toggle-collapse id))))
|
(if (and expanded? (kbd/shift? event))
|
||||||
|
(st/emit! (dwc/collapse-all))
|
||||||
|
(st/emit! (dwc/toggle-collapse id)))))
|
||||||
|
|
||||||
toggle-blocking
|
toggle-blocking
|
||||||
(fn [event]
|
(mf/use-fn
|
||||||
(dom/stop-propagation event)
|
(mf/deps id blocked?)
|
||||||
(if (:blocked item)
|
(fn [event]
|
||||||
(st/emit! (dw/update-shape-flags [id] {:blocked false}))
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dw/update-shape-flags [id] {:blocked true})
|
(if blocked?
|
||||||
(dw/deselect-shape id))))
|
(st/emit! (dw/update-shape-flags [id] {:blocked false}))
|
||||||
|
(st/emit! (dw/update-shape-flags [id] {:blocked true})
|
||||||
|
(dw/deselect-shape id)))))
|
||||||
|
|
||||||
toggle-visibility
|
toggle-visibility
|
||||||
(fn [event]
|
(mf/use-fn
|
||||||
(dom/stop-propagation event)
|
(mf/deps hidden?)
|
||||||
(if (:hidden item)
|
(fn [event]
|
||||||
(st/emit! (dw/update-shape-flags [id] {:hidden false}))
|
(dom/stop-propagation event)
|
||||||
(st/emit! (dw/update-shape-flags [id] {:hidden true}))))
|
(if hidden?
|
||||||
|
(st/emit! (dw/update-shape-flags [id] {:hidden false}))
|
||||||
|
(st/emit! (dw/update-shape-flags [id] {:hidden true})))))
|
||||||
|
|
||||||
select-shape
|
select-shape
|
||||||
(fn [event]
|
(mf/use-fn
|
||||||
(dom/prevent-default event)
|
(mf/deps id)
|
||||||
(reset! scroll-to-middle? false)
|
(fn [event]
|
||||||
(let [id (:id item)]
|
(dom/prevent-default event)
|
||||||
(cond
|
(reset! scroll-to-middle? false)
|
||||||
(kbd/shift? event)
|
(cond
|
||||||
(st/emit! (dw/shift-select-shapes id))
|
(kbd/shift? event)
|
||||||
|
(st/emit! (dw/shift-select-shapes id))
|
||||||
|
|
||||||
(kbd/mod? event)
|
(kbd/mod? event)
|
||||||
(st/emit! (dw/select-shape id true))
|
(st/emit! (dw/select-shape id true))
|
||||||
|
|
||||||
(> (count selected) 1)
|
(> (count selected) 1)
|
||||||
(st/emit! (dw/select-shape id))
|
(st/emit! (dw/select-shape id))
|
||||||
:else
|
|
||||||
(st/emit! (dw/select-shape id)))))
|
:else
|
||||||
|
(st/emit! (dw/select-shape id)))))
|
||||||
|
|
||||||
|
on-pointer-enter
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps id)
|
||||||
|
(fn [_event]
|
||||||
|
(st/emit! (dw/highlight-shape id))))
|
||||||
|
|
||||||
|
on-pointer-leave
|
||||||
|
(mf/use-fn
|
||||||
|
(mf/deps id)
|
||||||
|
(fn [_event]
|
||||||
|
(st/emit! (dw/dehighlight-shape id))))
|
||||||
|
|
||||||
on-context-menu
|
on-context-menu
|
||||||
(fn [event]
|
(mf/use-fn
|
||||||
(dom/prevent-default event)
|
(mf/deps item)
|
||||||
(dom/stop-propagation event)
|
(fn [event]
|
||||||
(let [pos (dom/get-client-position event)]
|
(dom/prevent-default event)
|
||||||
(st/emit! (dw/show-shape-context-menu {:position pos
|
(dom/stop-propagation event)
|
||||||
:shape item}))))
|
(let [pos (dom/get-client-position event)]
|
||||||
|
(st/emit! (dw/show-shape-context-menu {:position pos :shape item})))))
|
||||||
|
|
||||||
on-drag
|
on-drag
|
||||||
(fn [{:keys [id]}]
|
(mf/use-fn
|
||||||
(when (not (contains? selected id))
|
(mf/deps id selected)
|
||||||
(st/emit! (dw/select-shape id))))
|
(fn [{:keys [id]}]
|
||||||
|
(when (not (contains? selected id))
|
||||||
|
(st/emit! (dw/select-shape id)))))
|
||||||
|
|
||||||
on-drop
|
on-drop
|
||||||
(fn [side _data]
|
(mf/use-fn
|
||||||
(if (= side :center)
|
(mf/deps id)
|
||||||
(st/emit! (dw/relocate-selected-shapes (:id item) 0))
|
(fn [side _data]
|
||||||
(let [to-index (if (= side :top) (inc index) index)
|
(if (= side :center)
|
||||||
parent-id (cph/get-parent-id objects (:id item))]
|
(st/emit! (dw/relocate-selected-shapes id 0))
|
||||||
(st/emit! (dw/relocate-selected-shapes parent-id to-index)))))
|
(let [to-index (if (= side :top) (inc index) index)
|
||||||
|
parent-id (cph/get-parent-id objects id)]
|
||||||
|
(st/emit! (dw/relocate-selected-shapes parent-id to-index))))))
|
||||||
|
|
||||||
on-hold
|
on-hold
|
||||||
(fn []
|
(mf/use-fn
|
||||||
(when-not expanded?
|
(mf/deps id expanded?)
|
||||||
(st/emit! (dwc/toggle-collapse (:id item)))))
|
(fn []
|
||||||
|
(when-not expanded?
|
||||||
|
(st/emit! (dwc/toggle-collapse id)))))
|
||||||
|
|
||||||
[dprops dref] (hooks/use-sortable
|
[dprops dref] (hooks/use-sortable
|
||||||
:data-type "penpot/layer"
|
:data-type "penpot/layer"
|
||||||
|
@ -183,25 +206,23 @@
|
||||||
|
|
||||||
ref (mf/use-ref)]
|
ref (mf/use-ref)]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/with-effect [selected? selected]
|
||||||
(mf/deps selected? selected)
|
(let [single? (= (count selected) 1)
|
||||||
(fn []
|
node (mf/ref-val ref)
|
||||||
(let [single? (= (count selected) 1)
|
|
||||||
node (mf/ref-val ref)
|
|
||||||
|
|
||||||
subid
|
subid
|
||||||
(when (and single? selected?)
|
(when (and single? selected?)
|
||||||
(let [scroll-to @scroll-to-middle?]
|
(let [scroll-to @scroll-to-middle?]
|
||||||
(ts/schedule
|
(ts/schedule
|
||||||
100
|
100
|
||||||
#(if scroll-to
|
#(if scroll-to
|
||||||
(dom/scroll-into-view! node #js {:block "center", :behavior "smooth"})
|
(dom/scroll-into-view! node #js {:block "center", :behavior "smooth"})
|
||||||
(do
|
(do
|
||||||
(dom/scroll-into-view-if-needed! node #js {:block "center", :behavior "smooth"})
|
(dom/scroll-into-view-if-needed! node #js {:block "center", :behavior "smooth"})
|
||||||
(reset! scroll-to-middle? true))))))]
|
(reset! scroll-to-middle? true))))))]
|
||||||
|
|
||||||
#(when (some? subid)
|
#(when (some? subid)
|
||||||
(rx/dispose! subid)))))
|
(rx/dispose! subid))))
|
||||||
|
|
||||||
[:li {:on-context-menu on-context-menu
|
[:li {:on-context-menu on-context-menu
|
||||||
:ref dref
|
:ref dref
|
||||||
|
@ -217,6 +238,8 @@
|
||||||
[:div.element-list-body {:class (dom/classnames :selected selected?
|
[:div.element-list-body {:class (dom/classnames :selected selected?
|
||||||
:icon-layer (= (:type item) :icon))
|
:icon-layer (= (:type item) :icon))
|
||||||
:on-click select-shape
|
:on-click select-shape
|
||||||
|
:on-pointer-enter on-pointer-enter
|
||||||
|
:on-pointer-leave on-pointer-leave
|
||||||
:on-double-click #(dom/stop-propagation %)}
|
:on-double-click #(dom/stop-propagation %)}
|
||||||
[:& si/element-icon {:shape item}]
|
[:& si/element-icon {:shape item}]
|
||||||
[:& layer-name {:shape item
|
[:& layer-name {:shape item
|
||||||
|
@ -373,7 +396,7 @@
|
||||||
(and
|
(and
|
||||||
(:show-search-box @filter-state)
|
(:show-search-box @filter-state)
|
||||||
(or (d/not-empty? (:search-text @filter-state))
|
(or (d/not-empty? (:search-text @filter-state))
|
||||||
(d/not-empty? (:active-filters @filter-state))))
|
(d/not-empty? (:active-filters @filter-state))))
|
||||||
|
|
||||||
search-and-filters
|
search-and-filters
|
||||||
(fn [[id shape]]
|
(fn [[id shape]]
|
||||||
|
@ -426,7 +449,7 @@
|
||||||
|
|
||||||
[filtered-objects
|
[filtered-objects
|
||||||
handle-show-more
|
handle-show-more
|
||||||
|
|
||||||
(mf/html
|
(mf/html
|
||||||
(if (:show-search-box @filter-state)
|
(if (:show-search-box @filter-state)
|
||||||
[:*
|
[:*
|
||||||
|
@ -487,7 +510,7 @@
|
||||||
(fn [entries]
|
(fn [entries]
|
||||||
(when (and (.-isIntersecting (first entries)) (some? show-more))
|
(when (and (.-isIntersecting (first entries)) (some? show-more))
|
||||||
(show-more)))
|
(show-more)))
|
||||||
|
|
||||||
on-render-container
|
on-render-container
|
||||||
(fn [element]
|
(fn [element]
|
||||||
(let [options #js {:root element}
|
(let [options #js {:root element}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
panning
|
panning
|
||||||
selrect
|
selrect
|
||||||
transform
|
transform
|
||||||
|
highlighted
|
||||||
vbox
|
vbox
|
||||||
vport
|
vport
|
||||||
zoom
|
zoom
|
||||||
|
@ -286,6 +287,7 @@
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
:selected selected
|
:selected selected
|
||||||
:hover #{(:id @hover) @frame-hover}
|
:hover #{(:id @hover) @frame-hover}
|
||||||
|
:highlighted highlighted
|
||||||
:edition edition
|
:edition edition
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.viewport.outline
|
(ns app.main.ui.workspace.viewport.outline
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
|
@ -75,26 +76,33 @@
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:color color}])))
|
:color color}])))
|
||||||
|
|
||||||
|
(defn- show-outline?
|
||||||
|
[shape]
|
||||||
|
(and (not (:hidden shape))
|
||||||
|
(not (:blocked shape))))
|
||||||
|
|
||||||
(mf/defc shape-outlines
|
(mf/defc shape-outlines
|
||||||
{::mf/wrap-props false}
|
{::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [selected (or (obj/get props "selected") #{})
|
(let [selected (or (obj/get props "selected") #{})
|
||||||
hover (or (obj/get props "hover") #{})
|
hover (or (obj/get props "hover") #{})
|
||||||
|
highlighted (or (obj/get props "highlighted") #{})
|
||||||
|
|
||||||
objects (obj/get props "objects")
|
objects (obj/get props "objects")
|
||||||
edition (obj/get props "edition")
|
edition (obj/get props "edition")
|
||||||
zoom (obj/get props "zoom")
|
zoom (obj/get props "zoom")
|
||||||
|
|
||||||
outlines-ids (set/union selected hover)
|
lookup (d/getf objects)
|
||||||
show-outline? (fn [shape] (and (not (:hidden shape))
|
edition? (fn [o] (= edition o))
|
||||||
(not (:blocked shape))))
|
|
||||||
|
|
||||||
shapes (->> outlines-ids
|
shapes (-> #{}
|
||||||
(filter #(not= edition %))
|
(into (comp (remove edition?)
|
||||||
(map #(get objects %))
|
(keep lookup)
|
||||||
(filterv show-outline?)
|
(filter show-outline?))
|
||||||
(filter some?))]
|
(set/union selected hover))
|
||||||
|
(into (comp (remove edition?)
|
||||||
|
(keep lookup))
|
||||||
|
highlighted))]
|
||||||
|
|
||||||
[:g.outlines
|
[:g.outlines
|
||||||
[:& shape-outlines-render {:shapes shapes
|
[:& shape-outlines-render {:shapes shapes :zoom zoom}]]))
|
||||||
:zoom zoom}]]))
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue