Align stage multi-selection modifiers with the timeline
This commit is contained in:
parent
9bc406f413
commit
6de71c4c66
3 changed files with 38 additions and 6 deletions
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
WHICH LEVEL a click selects is Figma's and Illustrator's rule, and Flash's
|
WHICH LEVEL a click selects is Figma's and Illustrator's rule, and Flash's
|
||||||
without its edit mode: a click selects the thing in the open symbol, a
|
without its edit mode: a click selects the thing in the open symbol, a
|
||||||
double-click goes one level into what is selected, ⌘-click goes straight to the
|
double-click goes one level into what is selected, ⌥-click goes straight to the
|
||||||
shape itself. A click inside what is selected keeps it, so a deep selection can
|
shape itself. A click inside what is selected keeps it, so a deep selection can
|
||||||
be dragged; one elsewhere selects at the same depth, beside it."
|
be dragged; one elsewhere selects at the same depth, beside it."
|
||||||
(:require [arthur.domain.channel :as ch]
|
(:require [arthur.domain.channel :as ch]
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
[arthur.ui.player :as player]
|
[arthur.ui.player :as player]
|
||||||
[arthur.ui.tracing :as tracing]
|
[arthur.ui.tracing :as tracing]
|
||||||
[arthur.ui.tools :as tools]
|
[arthur.ui.tools :as tools]
|
||||||
|
[arthur.ui.timeline :as timeline]
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[reagent.core :as r]))
|
[reagent.core :as r]))
|
||||||
|
|
||||||
|
|
@ -55,6 +56,7 @@
|
||||||
;; produces go straight out as `::set-vertex`, which is where the document
|
;; produces go straight out as `::set-vertex`, which is where the document
|
||||||
;; changes and where re-frame belongs.
|
;; changes and where re-frame belongs.
|
||||||
(defonce ^:private dragging (atom nil))
|
(defonce ^:private dragging (atom nil))
|
||||||
|
(defonce ^:private selection-anchor (atom nil))
|
||||||
|
|
||||||
(defn- editing
|
(defn- editing
|
||||||
"The selected node when it is a polygon on screen, however deep it is nested,
|
"The selected node when it is a polygon on screen, however deep it is nested,
|
||||||
|
|
@ -550,20 +552,35 @@
|
||||||
(do (.setPointerCapture svg (.-pointerId event))
|
(do (.setPointerCapture svg (.-pointerId event))
|
||||||
(stroke-begin! ctx tool p size tone event))
|
(stroke-begin! ctx tool p size tone event))
|
||||||
|
|
||||||
(let [path (pick/choose selected (player/at p)
|
(let [path (pick/choose selected (player/at p) (.-altKey event))]
|
||||||
(or (.-metaKey event) (.-ctrlKey event)))]
|
(when (and path (not (.-shiftKey event)))
|
||||||
|
(reset! selection-anchor {:clip-id clip-id :open (:open ctx) :path path}))
|
||||||
(cond
|
(cond
|
||||||
(and (.-shiftKey event) path)
|
(and (or (.-metaKey event) (.-ctrlKey event)) path)
|
||||||
(when-let [address (address-for ctx path)]
|
(when-let [address (address-for ctx path)]
|
||||||
(rf/dispatch [::ui/toggle-selection address]))
|
(rf/dispatch [::ui/toggle-selection address]))
|
||||||
|
|
||||||
|
(and (.-shiftKey event) path)
|
||||||
|
(when-let [address (address-for ctx path)]
|
||||||
|
(let [document (:clip (loaded ctx))
|
||||||
|
expanded @(rf/subscribe [::sub/expanded])
|
||||||
|
xs (vec (keep :select (timeline/rows document (:open ctx) expanded selected)))
|
||||||
|
origin (if (and (= clip-id (:clip-id @selection-anchor))
|
||||||
|
(= (:open ctx) (:open @selection-anchor)))
|
||||||
|
(:path @selection-anchor) selected)
|
||||||
|
anchor (when origin (address-for ctx origin))
|
||||||
|
a (.indexOf xs anchor) b (.indexOf xs address)]
|
||||||
|
(rf/dispatch (if (and (<= 0 a) (<= 0 b))
|
||||||
|
[::ui/select-many (subvec xs (min a b) (inc (max a b)))]
|
||||||
|
[::ui/select address]))))
|
||||||
|
|
||||||
path
|
path
|
||||||
(when-not (contains? selected-paths path) (select! ctx path))
|
(when-not (contains? selected-paths path) (select! ctx path))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(do (.setPointerCapture svg (.-pointerId event))
|
(do (.setPointerCapture svg (.-pointerId event))
|
||||||
(reset! marquee {:p0 p :p p :more? (.-shiftKey event)})))
|
(reset! marquee {:p0 p :p p :more? (or (.-metaKey event) (.-ctrlKey event) (.-shiftKey event))})))
|
||||||
(when (and path (not (.-shiftKey event)))
|
(when (and path (not (or (.-shiftKey event) (.-metaKey event) (.-ctrlKey event))))
|
||||||
(.setPointerCapture svg (.-pointerId event))
|
(.setPointerCapture svg (.-pointerId event))
|
||||||
(if (and (> (count placements) 1) (contains? selected-paths path))
|
(if (and (> (count placements) 1) (contains? selected-paths path))
|
||||||
(begin-many! ctx :move placements p)
|
(begin-many! ctx :move placements p)
|
||||||
|
|
|
||||||
|
|
@ -484,3 +484,18 @@
|
||||||
(is (= [:girl clip-id] path))
|
(is (= [:girl clip-id] path))
|
||||||
(is (some? (get-in saved [:symbols :main :nodes clip-id]))
|
(is (some? (get-in saved [:symbols :main :nodes clip-id]))
|
||||||
"and that is where the node actually is")))
|
"and that is where the node actually is")))
|
||||||
|
|
||||||
|
(deftest restacking-a-selection-keeps-all-members-selected
|
||||||
|
(let [doc (update-in (fixture/document) [:symbols :main] dissoc :display)
|
||||||
|
id (store/install! {:clip doc :store {}} "restack-many-test")
|
||||||
|
selections [[:node :main :a [:a]] [:node :main :b [:b]]]]
|
||||||
|
(reset! rf-db/app-db {:clip/current id :paint/revision 0
|
||||||
|
:ui {:open :main :selection (peek selections) :selections selections}
|
||||||
|
:playback {:frame 6}})
|
||||||
|
(rf/dispatch-sync [::ui/restack-nodes selections [:insert] true])
|
||||||
|
(let [after (:clip (store/entry (:clip/current @rf-db/app-db)))
|
||||||
|
z #(get-in after [:symbols :main :nodes % :z])]
|
||||||
|
(is (pos? (compare (z :a) (z :insert))))
|
||||||
|
(is (pos? (compare (z :b) (z :a))))
|
||||||
|
(is (= selections (get-in @rf-db/app-db [:ui :selections])))
|
||||||
|
(is (= [0 4] (mapv #(get-in after [:symbols :main :nodes % :time :at]) [:a :b]))))))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue