mirror of
https://github.com/penpot/penpot.git
synced 2025-05-15 09:46:43 +02:00
✨ Improved hover behavior
This commit is contained in:
parent
688ec2589a
commit
8c5cc446b0
18 changed files with 117 additions and 217 deletions
|
@ -8,7 +8,6 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.pages.indices :as cpi]
|
|
||||||
[app.common.uuid :as uuid]))
|
[app.common.uuid :as uuid]))
|
||||||
|
|
||||||
(defn focus-objects
|
(defn focus-objects
|
||||||
|
|
|
@ -18,14 +18,24 @@
|
||||||
;; GENERIC SHAPE SELECTORS AND PREDICATES
|
;; GENERIC SHAPE SELECTORS AND PREDICATES
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn root-frame?
|
(defn root?
|
||||||
[{:keys [id type]}]
|
[{:keys [id type]}]
|
||||||
|
(and (= type :frame) (= id uuid/zero)))
|
||||||
|
|
||||||
|
(defn root-frame?
|
||||||
|
([objects id]
|
||||||
|
(root-frame? (get objects id)))
|
||||||
|
|
||||||
|
([{:keys [frame-id type]}]
|
||||||
(and (= type :frame)
|
(and (= type :frame)
|
||||||
(= id uuid/zero)))
|
(= frame-id uuid/zero))))
|
||||||
|
|
||||||
(defn frame-shape?
|
(defn frame-shape?
|
||||||
[{:keys [type]}]
|
([objects id]
|
||||||
(= type :frame))
|
(frame-shape? (get objects id)))
|
||||||
|
|
||||||
|
([{:keys [type]}]
|
||||||
|
(= type :frame)))
|
||||||
|
|
||||||
(defn group-shape?
|
(defn group-shape?
|
||||||
[{:keys [type]}]
|
[{:keys [type]}]
|
||||||
|
@ -230,13 +240,29 @@
|
||||||
(< parent-a parent-b))))
|
(< parent-a parent-b))))
|
||||||
|
|
||||||
(defn sort-z-index
|
(defn sort-z-index
|
||||||
[objects ids]
|
([objects ids]
|
||||||
|
(sort-z-index objects ids nil))
|
||||||
|
|
||||||
|
([objects ids {:keys [bottom-frames?]}]
|
||||||
(letfn [(comp [id-a id-b]
|
(letfn [(comp [id-a id-b]
|
||||||
|
(let [type-a (dm/get-in objects [id-a :type])
|
||||||
|
type-b (dm/get-in objects [id-b :type])]
|
||||||
(cond
|
(cond
|
||||||
(= id-a id-b) 0
|
(and bottom-frames? (= :frame type-a) (not= :frame type-b))
|
||||||
(is-shape-over-shape? objects id-a id-b) 1
|
1
|
||||||
:else -1))]
|
|
||||||
(sort comp ids)))
|
(and bottom-frames? (not= :frame type-a) (= :frame type-b))
|
||||||
|
-1
|
||||||
|
|
||||||
|
(= id-a id-b)
|
||||||
|
0
|
||||||
|
|
||||||
|
(is-shape-over-shape? objects id-a id-b)
|
||||||
|
1
|
||||||
|
|
||||||
|
:else
|
||||||
|
-1)))]
|
||||||
|
(sort comp ids))))
|
||||||
|
|
||||||
(defn frame-id-by-position
|
(defn frame-id-by-position
|
||||||
[objects position]
|
[objects position]
|
||||||
|
|
|
@ -8,78 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]))
|
||||||
[clojure.set :as set]))
|
|
||||||
|
|
||||||
#_(defn calculate-frame-z-index
|
|
||||||
[z-index frame-id base-idx objects]
|
|
||||||
|
|
||||||
(let [is-root-frame? (fn [id]
|
|
||||||
(and (= :frame (get-in objects [id :type]))
|
|
||||||
(= uuid/zero (get-in objects [id :parent-id]))))
|
|
||||||
children (or (get-in objects [frame-id :shapes]) [])]
|
|
||||||
|
|
||||||
(if (empty? children)
|
|
||||||
z-index
|
|
||||||
(loop [current (peek children)
|
|
||||||
pending (pop children)
|
|
||||||
current-idx base-idx
|
|
||||||
z-index z-index]
|
|
||||||
|
|
||||||
(let [children (get-in objects [current :shapes])
|
|
||||||
is-root-frame? (is-root-frame? current)
|
|
||||||
pending (if (not is-root-frame?)
|
|
||||||
(d/concat-vec pending children)
|
|
||||||
pending)]
|
|
||||||
|
|
||||||
(if (empty? pending)
|
|
||||||
(assoc z-index current current-idx)
|
|
||||||
(recur (peek pending)
|
|
||||||
(pop pending)
|
|
||||||
(dec current-idx)
|
|
||||||
(assoc z-index current current-idx))))))))
|
|
||||||
|
|
||||||
;; The z-index is really calculated per-frame. Every frame will have its own
|
|
||||||
;; internal z-index. To calculate the "final" z-index we add the shape z-index with
|
|
||||||
;; the z-index of its frame. This way we can update the z-index per frame without
|
|
||||||
;; the need of recalculate all the frames
|
|
||||||
#_(defn calculate-z-index
|
|
||||||
"Given a collection of shapes calculates their z-index. Greater index
|
|
||||||
means is displayed over other shapes with less index."
|
|
||||||
[objects]
|
|
||||||
|
|
||||||
(let [frames (cph/get-root-frames objects)
|
|
||||||
|
|
||||||
by-frame (cph/objects-by-frame objects)
|
|
||||||
frame-base-idx (d/update-vals by-frame count)
|
|
||||||
|
|
||||||
z-index (calculate-frame-z-index {} uuid/zero (get frame-base-idx uuid/zero) objects)]
|
|
||||||
(->> frames
|
|
||||||
(reduce
|
|
||||||
(fn [z-index {:keys [id]}]
|
|
||||||
(calculate-frame-z-index z-index id (get frame-base-idx id) objects)) z-index))))
|
|
||||||
|
|
||||||
#_(defn update-z-index
|
|
||||||
"Updates the z-index given a set of ids to change and the old and new objects
|
|
||||||
representations"
|
|
||||||
[z-index changed-ids old-objects new-objects]
|
|
||||||
|
|
||||||
(let [old-frames (into #{} (map #(get-in old-objects [% :frame-id])) changed-ids)
|
|
||||||
new-frames (into #{} (map #(get-in new-objects [% :frame-id])) changed-ids)
|
|
||||||
|
|
||||||
changed-frames (set/union old-frames new-frames)
|
|
||||||
|
|
||||||
frames (->> (cph/get-frames new-objects)
|
|
||||||
(map :id)
|
|
||||||
(filter #(contains? changed-frames %)))
|
|
||||||
|
|
||||||
by-frame (cph/objects-by-frame new-objects)
|
|
||||||
frame-base-idx (d/update-vals by-frame count)
|
|
||||||
z-index (calculate-frame-z-index z-index uuid/zero (get frame-base-idx uuid/zero) new-objects)]
|
|
||||||
|
|
||||||
(->> frames
|
|
||||||
(reduce (fn [z-index id]
|
|
||||||
(calculate-frame-z-index z-index id (get frame-base-idx id) new-objects)) z-index))))
|
|
||||||
|
|
||||||
(defn generate-child-parent-index
|
(defn generate-child-parent-index
|
||||||
[objects]
|
[objects]
|
||||||
|
@ -104,11 +33,16 @@
|
||||||
"Retrieves the mask information for an object"
|
"Retrieves the mask information for an object"
|
||||||
[objects parents-index]
|
[objects parents-index]
|
||||||
(let [retrieve-clips
|
(let [retrieve-clips
|
||||||
(fn [_ parents]
|
(fn [parents]
|
||||||
(let [lookup-object (fn [id] (get objects id))
|
(let [lookup-object (fn [id] (get objects id))
|
||||||
get-clip-parents
|
get-clip-parents
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
(cond-> []
|
(cond-> []
|
||||||
|
(and (= :frame (:type shape))
|
||||||
|
(not (:show-content shape))
|
||||||
|
(not= uuid/zero (:id shape)))
|
||||||
|
(conj shape)
|
||||||
|
|
||||||
(:masked-group? shape)
|
(:masked-group? shape)
|
||||||
(conj (get objects (->> shape :shapes first)))
|
(conj (get objects (->> shape :shapes first)))
|
||||||
|
|
||||||
|
@ -119,5 +53,5 @@
|
||||||
(comp (map lookup-object)
|
(comp (map lookup-object)
|
||||||
(mapcat get-clip-parents))
|
(mapcat get-clip-parents))
|
||||||
parents)))]
|
parents)))]
|
||||||
(->> parents-index
|
(-> parents-index
|
||||||
(d/mapm retrieve-clips))))
|
(d/update-vals retrieve-clips))))
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
|
|
||||||
(ns app.main.data.workspace
|
(ns app.main.data.workspace
|
||||||
(:require
|
(:require
|
||||||
[app.main.data.workspace.indices :as dwidx]
|
|
||||||
|
|
||||||
[app.common.attrs :as attrs]
|
[app.common.attrs :as attrs]
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
|
@ -34,6 +32,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.indices :as dwidx]
|
||||||
[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]
|
||||||
|
@ -130,7 +129,7 @@
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (dwn/initialize team-id file-id)
|
(rx/of (dwn/initialize team-id file-id)
|
||||||
(dwp/initialize-file-persistence file-id)
|
(dwp/initialize-file-persistence file-id)
|
||||||
(dwidx/start-indexing file-id))
|
(dwidx/start-indexing))
|
||||||
|
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter #(= ::dwc/index-initialized %))
|
(rx/filter #(= ::dwc/index-initialized %))
|
||||||
|
@ -197,7 +196,7 @@
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(rx/of (dwn/finalize file-id))
|
(rx/of (dwn/finalize file-id))
|
||||||
(rx/of (dwidx/stop-indexing file-id))
|
(rx/of (dwidx/stop-indexing))
|
||||||
(->> (rx/of ::dwp/finalize)
|
(->> (rx/of ::dwp/finalize)
|
||||||
(rx/observe-on :async))))))
|
(rx/observe-on :async))))))
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
:height 0.01})
|
:height 0.01})
|
||||||
(cond-> (and (cph/frame-shape? shape)
|
(cond-> (and (cph/frame-shape? shape)
|
||||||
(not= fid uuid/zero))
|
(not= fid uuid/zero))
|
||||||
(assoc :fills [] :show-content true :hide-in-viewer true))
|
(assoc :fills [] :hide-in-viewer true))
|
||||||
|
|
||||||
(assoc :frame-id fid)
|
(assoc :frame-id fid)
|
||||||
(assoc :initialized? true)
|
(assoc :initialized? true)
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
|
|
||||||
(ns app.main.data.workspace.indices
|
(ns app.main.data.workspace.indices
|
||||||
(:require
|
(:require
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.main.data.workspace.indices.object-tree :as dwi-object-tree]
|
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.main.data.workspace.changes :as dwc]
|
[app.main.data.workspace.changes :as dwc]
|
||||||
|
[app.main.data.workspace.indices.object-tree :as dwi-object-tree]
|
||||||
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
|
[app.main.refs :as refs]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[app.common.data :as d]
|
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
(def stop-indexing? (ptk/type? ::stop-indexing))
|
(def stop-indexing? (ptk/type? ::stop-indexing))
|
||||||
|
@ -19,7 +18,7 @@
|
||||||
(def objects-changes #{:add-obj :mod-obj :del-obj :mov-objects})
|
(def objects-changes #{:add-obj :mod-obj :del-obj :mov-objects})
|
||||||
|
|
||||||
(defn stop-indexing
|
(defn stop-indexing
|
||||||
[file-id]
|
[]
|
||||||
(ptk/reify ::stop-indexing
|
(ptk/reify ::stop-indexing
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -41,13 +40,11 @@
|
||||||
(ptk/reify ::update-indexing
|
(ptk/reify ::update-indexing
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
|
||||||
(-> state
|
(-> state
|
||||||
(update :index-object-tree dwi-object-tree/update-index shape-id change-type old-objects new-objects))))))
|
(update :index-object-tree dwi-object-tree/update-index shape-id change-type old-objects new-objects)))))
|
||||||
|
|
||||||
(defn start-indexing
|
(defn start-indexing
|
||||||
[file-id]
|
[]
|
||||||
|
|
||||||
(ptk/reify ::start-indexing
|
(ptk/reify ::start-indexing
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
@ -56,7 +53,7 @@
|
||||||
(assoc :index-object-tree (dwi-object-tree/init-index objects)))))
|
(assoc :index-object-tree (dwi-object-tree/init-index objects)))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state stream]
|
(watch [_ _ stream]
|
||||||
(let [stopper (->> stream (rx/filter stop-indexing?) (rx/take 1))
|
(let [stopper (->> stream (rx/filter stop-indexing?) (rx/take 1))
|
||||||
objects-delta (->> (rx/from-atom refs/workspace-page-objects {:emit-current-value? true}) (rx/buffer 2 1))]
|
objects-delta (->> (rx/from-atom refs/workspace-page-objects {:emit-current-value? true}) (rx/buffer 2 1))]
|
||||||
(->> stream
|
(->> stream
|
||||||
|
|
|
@ -4,25 +4,13 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) UXBOX Labs SL
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
(ns app.main.data.workspace.indices.object-tree
|
(ns app.main.data.workspace.indices.object-tree)
|
||||||
(:require
|
|
||||||
[app.common.pages.helpers :as cph]
|
|
||||||
))
|
|
||||||
|
|
||||||
(defn objects-tree
|
(defn objects-tree
|
||||||
[objects]
|
[_objects])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
(defn init-index
|
(defn init-index
|
||||||
[objects]
|
[_objects])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
(defn update-index
|
(defn update-index
|
||||||
[index shape-id change-type old-objects new-objects]
|
[_index _shape-id _change-type _old-objects _new-objects])
|
||||||
)
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
(ns app.main.errors
|
(ns app.main.errors
|
||||||
"Generic error handling"
|
"Generic error handling"
|
||||||
(:require
|
(:require
|
||||||
[cuerdas.core :as str]
|
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
|
@ -21,6 +20,7 @@
|
||||||
[app.util.i18n :refer [tr]]
|
[app.util.i18n :refer [tr]]
|
||||||
[app.util.router :as rt]
|
[app.util.router :as rt]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
|
[cuerdas.core :as str]
|
||||||
[potok.core :as ptk]))
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
(defn on-error
|
(defn on-error
|
||||||
|
|
|
@ -169,7 +169,7 @@
|
||||||
[objects object-id]
|
[objects object-id]
|
||||||
(let [object (get objects object-id)
|
(let [object (get objects object-id)
|
||||||
object (cond->> object
|
object (cond->> object
|
||||||
(cph/root-frame? object)
|
(cph/root? object)
|
||||||
(adapt-root-frame objects))
|
(adapt-root-frame objects))
|
||||||
|
|
||||||
;; Replace the previous object with the new one
|
;; Replace the previous object with the new one
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
(ns app.main.ui.hooks.resize
|
(ns app.main.ui.hooks.resize
|
||||||
(:require
|
(:require
|
||||||
[app.main.ui.hooks :as hooks]
|
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.logging :as log]
|
[app.common.logging :as log]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.storage :refer [storage]]
|
[app.util.storage :refer [storage]]
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.shapes.frame
|
(ns app.main.ui.workspace.shapes.frame
|
||||||
(:require
|
(:require
|
||||||
[app.main.store :as st]
|
|
||||||
[app.main.data.workspace.state-helpers :as wsh]
|
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[app.main.data.workspace.state-helpers :as wsh]
|
||||||
[app.main.data.workspace.thumbnails :as dwt]
|
[app.main.data.workspace.thumbnails :as dwt]
|
||||||
[app.main.fonts :as fonts]
|
[app.main.fonts :as fonts]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
[app.main.store :as st]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.hooks :as hooks]
|
[app.main.ui.hooks :as hooks]
|
||||||
[app.main.ui.shapes.embed :as embed]
|
[app.main.ui.shapes.embed :as embed]
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.sidebar.options.menus.measures
|
(ns app.main.ui.workspace.sidebar.options.menus.measures
|
||||||
(:require
|
(:require
|
||||||
[app.main.constants :refer [size-presets]]
|
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.spec.radius :as ctr]
|
[app.common.spec.radius :as ctr]
|
||||||
|
[app.main.constants :refer [size-presets]]
|
||||||
[app.main.data.workspace :as udw]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.data.workspace.changes :as dch]
|
[app.main.data.workspace.changes :as dch]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
@ -204,13 +204,6 @@
|
||||||
on-radius-r3-change #(on-radius-4-change % :r3)
|
on-radius-r3-change #(on-radius-4-change % :r3)
|
||||||
on-radius-r4-change #(on-radius-4-change % :r4)
|
on-radius-r4-change #(on-radius-4-change % :r4)
|
||||||
|
|
||||||
on-change-clip-content
|
|
||||||
(mf/use-callback
|
|
||||||
(mf/deps ids)
|
|
||||||
(fn [event]
|
|
||||||
(let [value (-> event dom/get-target dom/checked?)]
|
|
||||||
(dch/update-shapes ids (fn [shape]) (assoc shape :show-content (not value))))))
|
|
||||||
|
|
||||||
on-change-clip-content
|
on-change-clip-content
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps ids)
|
(mf/deps ids)
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.context :as ctx]
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.hooks :as ui-hooks]
|
[app.main.ui.hooks :as ui-hooks]
|
||||||
|
@ -156,6 +157,7 @@
|
||||||
show-gradient-handlers? (= (count selected) 1)
|
show-gradient-handlers? (= (count selected) 1)
|
||||||
show-grids? (contains? layout :display-grid)
|
show-grids? (contains? layout :display-grid)
|
||||||
|
|
||||||
|
show-frame-outline? (= transform :move)
|
||||||
show-outlines? (and (nil? transform)
|
show-outlines? (and (nil? transform)
|
||||||
(not edition)
|
(not edition)
|
||||||
(not drawing-obj)
|
(not drawing-obj)
|
||||||
|
@ -280,6 +282,14 @@
|
||||||
(when show-text-editor?
|
(when show-text-editor?
|
||||||
[:& editor/text-editor-svg {:shape editing-shape}])
|
[:& editor/text-editor-svg {:shape editing-shape}])
|
||||||
|
|
||||||
|
(when show-frame-outline?
|
||||||
|
[:& outline/shape-outlines
|
||||||
|
{:objects base-objects
|
||||||
|
:hover #{(->> @hover-ids
|
||||||
|
(filter #(cph/frame-shape? base-objects %))
|
||||||
|
(first))}
|
||||||
|
:zoom zoom}])
|
||||||
|
|
||||||
(when show-outlines?
|
(when show-outlines?
|
||||||
[:& outline/shape-outlines
|
[:& outline/shape-outlines
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
|
@ -314,7 +324,6 @@
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
:selected selected
|
:selected selected
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:modifiers modifiers
|
|
||||||
:show-artboard-names? show-artboard-names?
|
:show-artboard-names? show-artboard-names?
|
||||||
:on-frame-enter on-frame-enter
|
:on-frame-enter on-frame-enter
|
||||||
:on-frame-leave on-frame-leave
|
:on-frame-leave on-frame-leave
|
||||||
|
|
|
@ -50,9 +50,7 @@
|
||||||
mod? (kbd/mod? event)
|
mod? (kbd/mod? event)
|
||||||
|
|
||||||
left-click? (and (not panning) (= 1 (.-which event)))
|
left-click? (and (not panning) (= 1 (.-which event)))
|
||||||
middle-click? (and (not panning) (= 2 (.-which event)))
|
middle-click? (and (not panning) (= 2 (.-which event)))]
|
||||||
|
|
||||||
selected? (contains? selected id)]
|
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
middle-click?
|
middle-click?
|
||||||
|
@ -155,7 +153,6 @@
|
||||||
shift? (kbd/shift? event)
|
shift? (kbd/shift? event)
|
||||||
alt? (kbd/alt? event)
|
alt? (kbd/alt? event)
|
||||||
meta? (kbd/meta? event)
|
meta? (kbd/meta? event)
|
||||||
mod? (kbd/mod? event)
|
|
||||||
hovering? (some? @hover)]
|
hovering? (some? @hover)]
|
||||||
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt? meta?))
|
(st/emit! (ms/->MouseEvent :click ctrl? shift? alt? meta?))
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.viewport.hooks
|
(ns app.main.ui.workspace.viewport.hooks
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.common.data :as d]
|
|
||||||
[app.main.data.shortcuts :as dsc]
|
[app.main.data.shortcuts :as dsc]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.path.shortcuts :as psc]
|
[app.main.data.workspace.path.shortcuts :as psc]
|
||||||
|
@ -130,8 +130,7 @@
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:rect rect
|
:rect rect
|
||||||
:include-frames? true
|
:include-frames? true
|
||||||
:clip-children? (not mod?)
|
:clip-children? (not mod?)})))))
|
||||||
:reverse? true}))))) ;; we want the topmost shape to be selected first
|
|
||||||
|
|
||||||
over-shapes-stream
|
over-shapes-stream
|
||||||
(mf/use-memo
|
(mf/use-memo
|
||||||
|
@ -145,14 +144,7 @@
|
||||||
|
|
||||||
(->> move-stream
|
(->> move-stream
|
||||||
;; When transforming shapes we stop querying the worker
|
;; When transforming shapes we stop querying the worker
|
||||||
(rx/filter #(not (some? (mf/ref-val transform-ref))))
|
|
||||||
(rx/merge-map query-point)
|
(rx/merge-map query-point)
|
||||||
(rx/tap #(reset! last-point-ref %)))
|
|
||||||
|
|
||||||
(->> move-stream
|
|
||||||
;; When transforming shapes we stop querying the worker
|
|
||||||
(rx/filter #(some? (mf/ref-val transform-ref)))
|
|
||||||
(rx/map (constantly nil))
|
|
||||||
(rx/tap #(reset! last-point-ref %))))))]
|
(rx/tap #(reset! last-point-ref %))))))]
|
||||||
|
|
||||||
;; Refresh the refs on a value change
|
;; Refresh the refs on a value change
|
||||||
|
@ -186,21 +178,25 @@
|
||||||
over-shapes-stream
|
over-shapes-stream
|
||||||
(mf/deps page-id objects)
|
(mf/deps page-id objects)
|
||||||
(fn [ids]
|
(fn [ids]
|
||||||
(let [ids (into
|
(let [selected (mf/ref-val selected-ref)
|
||||||
|
focus (mf/ref-val focus-ref)
|
||||||
|
mod? (mf/ref-val mod-ref)
|
||||||
|
|
||||||
|
ids (into
|
||||||
(d/ordered-set)
|
(d/ordered-set)
|
||||||
(cph/sort-z-index objects ids))
|
(cph/sort-z-index objects ids {:bottom-frames? mod?}))
|
||||||
|
|
||||||
grouped? (fn [id] (contains? #{:group :bool} (get-in objects [id :type])))
|
grouped? (fn [id] (contains? #{:group :bool} (get-in objects [id :type])))
|
||||||
|
|
||||||
selected (mf/ref-val selected-ref)
|
|
||||||
focus (mf/ref-val focus-ref)
|
|
||||||
|
|
||||||
mod? (mf/ref-val mod-ref)
|
|
||||||
|
|
||||||
remove-xfm (mapcat #(cph/get-parent-ids objects %))
|
remove-xfm (mapcat #(cph/get-parent-ids objects %))
|
||||||
remove-id? (cond-> (into #{} remove-xfm selected)
|
remove-id? (cond-> (into #{} remove-xfm selected)
|
||||||
(not mod?)
|
(not mod?)
|
||||||
(into (filter #(group-empty-space? % objects ids)) ids)
|
(into
|
||||||
|
(filter #(or (and (cph/root-frame? objects %) (d/not-empty? (get-in objects [% :shapes])))
|
||||||
|
(group-empty-space? % objects ids)))
|
||||||
|
ids)
|
||||||
|
|
||||||
mod?
|
mod?
|
||||||
(into (filter grouped?) ids))
|
(into (filter grouped?) ids))
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages.helpers :as cph]
|
|
||||||
[app.main.refs :as refs]
|
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.path.format :as upf]
|
[app.util.path.format :as upf]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
|
@ -41,7 +39,7 @@
|
||||||
|
|
||||||
common {:fill "none"
|
common {:fill "none"
|
||||||
:stroke color
|
:stroke color
|
||||||
:strokeWidth (/ 1 zoom)
|
:strokeWidth (/ 2 zoom)
|
||||||
:pointerEvents "none"
|
:pointerEvents "none"
|
||||||
:transform transform}
|
:transform transform}
|
||||||
|
|
||||||
|
@ -82,15 +80,12 @@
|
||||||
[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") #{})
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
transform (mf/deref refs/current-transform)
|
outlines-ids (set/union selected hover)
|
||||||
|
|
||||||
outlines-ids (->> (set/union selected hover)
|
|
||||||
(cph/clean-loops objects))
|
|
||||||
|
|
||||||
show-outline? (fn [shape] (and (not (:hidden shape))
|
show-outline? (fn [shape] (and (not (:hidden shape))
|
||||||
(not (:blocked shape))))
|
(not (:blocked shape))))
|
||||||
|
|
||||||
|
@ -100,6 +95,6 @@
|
||||||
(filterv show-outline?)
|
(filterv show-outline?)
|
||||||
(filter some?))]
|
(filter some?))]
|
||||||
|
|
||||||
[:g.outlines {:display (when (some? transform) "none")}
|
[:g.outlines
|
||||||
[:& shape-outlines-render {:shapes shapes
|
[:& shape-outlines-render {:shapes shapes
|
||||||
:zoom zoom}]]))
|
:zoom zoom}]]))
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.viewport.widgets
|
(ns app.main.ui.workspace.viewport.widgets
|
||||||
(:require
|
(:require
|
||||||
[app.common.uuid :as uuid]
|
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
[app.main.data.workspace.interactions :as dwi]
|
[app.main.data.workspace.interactions :as dwi]
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
(mf/defc frame-title
|
(mf/defc frame-title
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
[{:keys [frame modifiers selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}]
|
[{:keys [frame selected? zoom show-artboard-names? on-frame-enter on-frame-leave on-frame-select]}]
|
||||||
(let [{:keys [width x y]} frame
|
(let [{:keys [width x y]} frame
|
||||||
label-pos (gpt/point x (- y (/ 10 zoom)))
|
label-pos (gpt/point x (- y (/ 10 zoom)))
|
||||||
|
|
||||||
|
|
|
@ -84,19 +84,12 @@
|
||||||
index-shape (make-index-shape objects parents-index clip-parents-index)
|
index-shape (make-index-shape objects parents-index clip-parents-index)
|
||||||
initial-quadtree (qdt/create (clj->js bounds))
|
initial-quadtree (qdt/create (clj->js bounds))
|
||||||
|
|
||||||
index (reduce index-shape initial-quadtree shapes)
|
index (reduce index-shape initial-quadtree shapes)]
|
||||||
|
|
||||||
;;z-index (cp/calculate-z-index objects)
|
{:index index :bounds bounds}))
|
||||||
]
|
|
||||||
|
|
||||||
{:index index
|
|
||||||
;;:z-index z-index
|
|
||||||
:bounds bounds}))
|
|
||||||
|
|
||||||
(defn- update-index
|
(defn- update-index
|
||||||
[{index :index
|
[{index :index :as data} old-objects new-objects]
|
||||||
;; z-index :z-index
|
|
||||||
:as data} old-objects new-objects]
|
|
||||||
(let [changes? (fn [id]
|
(let [changes? (fn [id]
|
||||||
(not= (get old-objects id)
|
(not= (get old-objects id)
|
||||||
(get new-objects id)))
|
(get new-objects id)))
|
||||||
|
@ -115,18 +108,12 @@
|
||||||
new-index (qdt/remove-all index changed-ids)
|
new-index (qdt/remove-all index changed-ids)
|
||||||
|
|
||||||
index-shape (make-index-shape new-objects parents-index clip-parents-index)
|
index-shape (make-index-shape new-objects parents-index clip-parents-index)
|
||||||
index (reduce index-shape new-index shapes)
|
index (reduce index-shape new-index shapes)]
|
||||||
|
|
||||||
;;z-index (cp/update-z-index z-index changed-ids old-objects new-objects)
|
(assoc data :index index)))
|
||||||
]
|
|
||||||
|
|
||||||
(assoc data :index index ;;:z-index z-index
|
|
||||||
)))
|
|
||||||
|
|
||||||
(defn- query-index
|
(defn- query-index
|
||||||
[{index :index
|
[{index :index} rect frame-id full-frame? include-frames? ignore-groups? clip-children?]
|
||||||
;;z-index :z-index
|
|
||||||
} rect frame-id full-frame? include-frames? ignore-groups? clip-children? reverse?]
|
|
||||||
(let [result (-> (qdt/search index (clj->js rect))
|
(let [result (-> (qdt/search index (clj->js rect))
|
||||||
(es6-iterator-seq))
|
(es6-iterator-seq))
|
||||||
|
|
||||||
|
@ -152,33 +139,18 @@
|
||||||
|
|
||||||
overlaps-parent?
|
overlaps-parent?
|
||||||
(fn [clip-parents]
|
(fn [clip-parents]
|
||||||
(->> clip-parents (some (comp not overlaps?)) not))
|
(->> clip-parents (some (comp not overlaps?)) not))]
|
||||||
|
|
||||||
;;add-z-index
|
|
||||||
;;(fn [{:keys [id frame-id] :as shape}]
|
|
||||||
;; (assoc shape :z (+ (get z-index id)
|
|
||||||
;; (get z-index frame-id 0))))
|
|
||||||
|
|
||||||
;; Shapes after filters of overlapping and criteria
|
;; Shapes after filters of overlapping and criteria
|
||||||
matching-shapes
|
(into (d/ordered-set)
|
||||||
(into []
|
|
||||||
(comp (map #(unchecked-get % "data"))
|
(comp (map #(unchecked-get % "data"))
|
||||||
(filter match-criteria?)
|
(filter match-criteria?)
|
||||||
(filter overlaps?)
|
(filter overlaps?)
|
||||||
(filter (comp overlaps? :frame))
|
|
||||||
(filter (if clip-children?
|
(filter (if clip-children?
|
||||||
(comp overlaps-parent? :clip-parents)
|
(comp overlaps-parent? :clip-parents)
|
||||||
(constantly true)))
|
(constantly true)))
|
||||||
#_(map add-z-index))
|
(map :id))
|
||||||
result)
|
result)))
|
||||||
|
|
||||||
;;keyfn (if reverse? (comp - :z) :z)
|
|
||||||
]
|
|
||||||
|
|
||||||
(into (d/ordered-set)
|
|
||||||
(->> matching-shapes
|
|
||||||
#_(sort-by keyfn)
|
|
||||||
(map :id)))))
|
|
||||||
|
|
||||||
|
|
||||||
(defmethod impl/handler :selection/initialize-index
|
(defmethod impl/handler :selection/initialize-index
|
||||||
|
@ -213,13 +185,8 @@
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defmethod impl/handler :selection/query
|
(defmethod impl/handler :selection/query
|
||||||
[{:keys [page-id rect frame-id reverse? full-frame? include-frames? ignore-groups? clip-children?]
|
[{:keys [page-id rect frame-id full-frame? include-frames? ignore-groups? clip-children?]
|
||||||
:or {reverse? false full-frame? false include-frames? false clip-children? true} :as message}]
|
:or {full-frame? false include-frames? false clip-children? true} :as message}]
|
||||||
(when-let [index (get @state page-id)]
|
(when-let [index (get @state page-id)]
|
||||||
(query-index index rect frame-id full-frame? include-frames? ignore-groups? clip-children? reverse?)))
|
(query-index index rect frame-id full-frame? include-frames? ignore-groups? clip-children?)))
|
||||||
|
|
||||||
#_(defmethod impl/handler :selection/query-z-index
|
|
||||||
[{:keys [page-id objects ids]}]
|
|
||||||
(when-let [{z-index :z-index} (get @state page-id)]
|
|
||||||
(->> ids (map #(+ (get z-index %)
|
|
||||||
(get z-index (get-in objects [% :frame-id])))))))
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue