Delete a timeline row with everything in it
Delete or Backspace, or the × on the selected row, takes the node out of its symbol along with every node hanging off it. One edit, so undo brings it back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
7246534505
commit
4b8123d5e2
5 changed files with 34 additions and 7 deletions
|
|
@ -144,6 +144,11 @@
|
||||||
[nodes id]
|
[nodes id]
|
||||||
(into #{} (filter #(some #{id} (symbol/lineage nodes %))) (keys nodes)))
|
(into #{} (filter #(some #{id} (symbol/lineage nodes %))) (keys nodes)))
|
||||||
|
|
||||||
|
(defn delete-node
|
||||||
|
"Take node `id` out of symbol `sid`, with everything hanging off it."
|
||||||
|
[clip sid id]
|
||||||
|
(clip/update-symbol clip sid update :nodes #(apply dissoc % (subtree % id))))
|
||||||
|
|
||||||
(defn- transplant
|
(defn- transplant
|
||||||
"Move node `id` from symbol `host`, where frame `frame` is showing, into symbol
|
"Move node `id` from symbol `host`, where frame `frame` is showing, into symbol
|
||||||
`target`, keeping where it is on screen and when. `carry` is the matrix from
|
`target`, keeping where it is on screen and when. `carry` is the matrix from
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
[arthur.domain.leaf :as leaf]
|
[arthur.domain.leaf :as leaf]
|
||||||
[arthur.events.edit :as edit]
|
[arthur.events.edit :as edit]
|
||||||
[arthur.events.playback :as pb]
|
[arthur.events.playback :as pb]
|
||||||
|
[arthur.events.ui :as ui]
|
||||||
[arthur.footage.store :as store]
|
[arthur.footage.store :as store]
|
||||||
[re-frame.core :as rf]))
|
[re-frame.core :as rf]))
|
||||||
|
|
||||||
|
|
@ -66,16 +67,19 @@
|
||||||
(or (#{"INPUT" "TEXTAREA" "SELECT"} (.-tagName target)) (.-isContentEditable target)))
|
(or (#{"INPUT" "TEXTAREA" "SELECT"} (.-tagName target)) (.-isContentEditable target)))
|
||||||
|
|
||||||
(defn install-keys!
|
(defn install-keys!
|
||||||
"⌘Z / Ctrl+Z undoes, with Shift redoes, and Ctrl+Y redoes. Not while typing
|
"⌘Z / Ctrl+Z undoes, with Shift redoes, and Ctrl+Y redoes; Delete or
|
||||||
in a field, where the browser's own undo is the one wanted."
|
Backspace deletes the selected node, which undo brings back. Not while typing
|
||||||
|
in a field, where the browser's own keys are the ones wanted."
|
||||||
[]
|
[]
|
||||||
(.addEventListener
|
(.addEventListener
|
||||||
js/window "keydown"
|
js/window "keydown"
|
||||||
(fn [^js e]
|
(fn [^js e]
|
||||||
(when (and (or (.-metaKey e) (.-ctrlKey e)) (not (typing? (.-target e))))
|
(when-not (typing? (.-target e))
|
||||||
(let [k (.toLowerCase (.-key e))]
|
(let [k (.toLowerCase (.-key e))]
|
||||||
(when-let [ev (cond (and (= k "z") (.-shiftKey e)) ::redo
|
(when-let [ev (if (or (.-metaKey e) (.-ctrlKey e))
|
||||||
(= k "z") ::undo
|
(cond (and (= k "z") (.-shiftKey e)) ::redo
|
||||||
(= k "y") ::redo)]
|
(= k "z") ::undo
|
||||||
|
(= k "y") ::redo)
|
||||||
|
(when (#{"delete" "backspace"} k) ::ui/delete-selected))]
|
||||||
(.preventDefault e)
|
(.preventDefault e)
|
||||||
(rf/dispatch [ev])))))))
|
(rf/dispatch [ev])))))))
|
||||||
|
|
|
||||||
|
|
@ -195,6 +195,16 @@
|
||||||
(:refused r) (refused db (:refused r))
|
(:refused r) (refused db (:refused r))
|
||||||
:else (edit/edit db (constantly (:clip r)))))))
|
:else (edit/edit db (constantly (:clip r)))))))
|
||||||
|
|
||||||
|
(rf/reg-event-db
|
||||||
|
::delete-selected
|
||||||
|
(fn [db _]
|
||||||
|
(let [[kind sid id] (get-in db [:ui :selection])]
|
||||||
|
(if (= :node kind)
|
||||||
|
(-> db
|
||||||
|
(edit/edit #(nest/delete-node % sid id))
|
||||||
|
(assoc-in [:ui :selection] nil))
|
||||||
|
db))))
|
||||||
|
|
||||||
(rf/reg-event-db
|
(rf/reg-event-db
|
||||||
::restack
|
::restack
|
||||||
;; Onto the edge of a row in another symbol, it goes into that symbol first:
|
;; Onto the edge of a row in another symbol, it goes into that symbol first:
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,13 @@
|
||||||
(rf/dispatch [::ui/toggle-row path]))}
|
(rf/dispatch [::ui/toggle-row path]))}
|
||||||
(when expandable? (if expanded? "▾" "▸"))]
|
(when expandable? (if expanded? "▾" "▸"))]
|
||||||
[:span.name label]
|
[:span.name label]
|
||||||
(when node? [:span.kind (str "·" (name node-kind))])]))
|
(when node? [:span.kind (str "·" (name node-kind))])
|
||||||
|
(when (and node? (= select selection))
|
||||||
|
[:button.tl-delete {:title "delete, with everything in it (⌫)"
|
||||||
|
:on-click (fn [^js e]
|
||||||
|
(.stopPropagation e)
|
||||||
|
(rf/dispatch [::ui/delete-selected]))}
|
||||||
|
"×"])]))
|
||||||
|
|
||||||
(defn- track-cell
|
(defn- track-cell
|
||||||
"`sliding` is the pointer's side of a bar being dragged, `{:path :x :width
|
"`sliding` is the pointer's side of a bar being dragged, `{:path :x :width
|
||||||
|
|
|
||||||
|
|
@ -618,6 +618,8 @@ button.share-button:hover, button.share-button.on { filter: brightness(1.1); }
|
||||||
|
|
||||||
.tl-twist:hover:not(:disabled) { background: none; color: var(--fg); }
|
.tl-twist:hover:not(:disabled) { background: none; color: var(--fg); }
|
||||||
.tl-twist:disabled { opacity: 0; cursor: default; }
|
.tl-twist:disabled { opacity: 0; cursor: default; }
|
||||||
|
.tl-delete { margin-left: auto; padding: 0 4px; border: 0; background: none; color: var(--dim); }
|
||||||
|
.tl-delete:hover { color: var(--fg); }
|
||||||
|
|
||||||
.tl-ruler {
|
.tl-ruler {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue