Compare commits

...

2 Commits

Author SHA1 Message Date
Andrey Antukh
16090f28df WIP 2026-01-19 19:45:36 +01:00
Andrey Antukh
afb10172ca WIP 2026-01-19 18:32:19 +01:00
7 changed files with 137 additions and 93 deletions

View File

@@ -25,7 +25,8 @@
(defn append
[{index :index items :items :as stack} value]
(if (and (some? stack) (not= value (peek stack)))
(if (and (some? stack)
(not= value (peek stack)))
(let [items (cond-> items
(> index 0)
(subvec 0 (inc index))
@@ -35,7 +36,6 @@
:always
(conj value))
index (min (dec MAX-UNDO-SIZE) (inc index))]
{:index index
:items items})

View File

@@ -15,6 +15,8 @@
(declare clear-edition-mode)
;; FIXME: rename to `enter-edition-mode`
(defn start-edition-mode
"Mark a shape in edition mode"
[id]
@@ -42,6 +44,8 @@
;; update namespace reference in the
;; app/main/data/workspace/path/undo.cljs file.
;; FIXME: rename to `exit-edition-mode`
(defn clear-edition-mode
[]
(ptk/reify ::clear-edition-mode

View File

@@ -17,14 +17,12 @@
(defn generate-path-changes
"Generates changes to update the new content of the shape"
[it objects page-id shape old-content new-content]
[it objects page-id shape-id old-content new-content]
(assert (path/content? old-content))
(assert (path/content? new-content))
(let [shape-id (:id shape)
;; We set the old values so the update-shapes works
(let [;; We set the old values so the update-shapes works
objects
(update objects shape-id
(fn [shape]
@@ -58,32 +56,32 @@
(path/update-geometry))))
(pcb/resize-parents [shape-id])))))
(defn save-path-content
([]
(save-path-content {}))
([{:keys [preserve-move-to] :or {preserve-move-to false}}]
(ptk/reify ::save-path-content
ptk/UpdateEvent
(update [_ state]
(let [content (st/get-path state :content)
content (if (and (not preserve-move-to)
(= (-> content last :command) :move-to))
(into [] (take (dec (count content)) content))
content)]
(-> state
(st/set-content content))))
;; (defn save-path-content
;; ([]
;; (save-path-content {}))
;; ([{:keys [preserve-move-to] :or {preserve-move-to false}}]
;; (ptk/reify ::save-path-content
;; ptk/UpdateEvent
;; (update [_ state]
;; (let [content (st/get-path state :content)
;; content (if (and (not preserve-move-to)
;; (= (-> content last :command) :move-to))
;; (into [] (take (dec (count content)) content))
;; content)]
;; (-> state
;; (st/set-content content))))
ptk/WatchEvent
(watch [it state _]
(let [page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
id (dm/get-in state [:workspace-local :edition])
old-content (dm/get-in state [:workspace-local :edit-path id :old-content])
shape (st/get-path state)]
;; ptk/WatchEvent
;; (watch [it state _]
;; (let [page-id (:current-page-id state)
;; objects (dsh/lookup-page-objects state page-id)
;; id (dm/get-in state [:workspace-local :edition])
;; old-content (dm/get-in state [:workspace-local :edit-path id :old-content])
;; shape (st/get-path state)]
(if (and (some? old-content) (some? (:id shape)))
(let [changes (generate-path-changes it objects page-id shape old-content (:content shape))]
(rx/of (dch/commit-changes changes)))
(rx/empty)))))))
;; (if (and (some? old-content) (some? (:id shape)))
;; (let [changes (generate-path-changes it objects page-id id old-content (:content shape))]
;; (rx/of (dch/commit-changes changes)))
;; (rx/empty)))))))

View File

@@ -17,6 +17,7 @@
[app.common.types.shape :as cts]
[app.common.types.shape-tree :as ctst]
[app.common.types.shape.layout :as ctl]
[app.main.data.changes :as dch]
[app.main.data.helpers :as dsh]
[app.main.data.workspace.drawing.common :as dwdc]
[app.main.data.workspace.edition :as dwe]
@@ -120,13 +121,15 @@
(ptk/reify ::finish-drag
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
(let [id (st/get-path-id state)
modifiers (get-in state [:workspace-local :edit-path id :content-modifiers])
content (-> (st/get-path state :content)
(path/apply-content-modifiers modifiers))
content (-> (st/get-path state :content)
(path/apply-content-modifiers modifiers))
handler (get-in state [:workspace-local :edit-path id :drag-handler])]
handler (get-in state [:workspace-local :edit-path id :drag-handler])]
(prn "finish-drag")
(-> state
(st/set-content content)
(update-in [:workspace-local :edit-path id] dissoc :drag-handler)
@@ -225,7 +228,7 @@
(rx/of (finish-drag)))))))
(defn- start-edition
[_id]
[id]
(ptk/reify ::start-edition
ptk/UpdateEvent
(update [_ state]
@@ -351,6 +354,8 @@
(let [id (dm/get-in state [:workspace-local :edition])
objects (dsh/lookup-page-objects state)
content (dm/get-in objects [id :content])]
(prn "start-draw-mode" id)
(if content
(update-in state [:workspace-local :edit-path id] assoc :old-content content)
state)))
@@ -359,14 +364,15 @@
(watch [_ _ _]
(rx/of (start-draw-mode*)))))
(defn start-draw-mode*
[]
(defn- start-draw-mode*
[id]
(ptk/reify ::start-draw-mode*
ptk/WatchEvent
(watch [_ state stream]
(let [local (get state :workspace-local)
id (get local :edition)
mode (dm/get-in local [:edit-path id :edit-mode])]
(prn "start-draw-mode*" id)
(if (= :draw mode)
(rx/concat
@@ -376,7 +382,7 @@
(rx/filter (ptk/type? ::end-edition))
(rx/take 1)
(rx/mapcat (fn [_]
(rx/of (check-changed-content)
(rx/of (check-changed-content id)
(start-draw-mode*))))))
(rx/empty))))))
@@ -386,7 +392,7 @@
ptk/UpdateEvent
(update [_ state]
(if-let [id (dm/get-in state [:workspace-local :edition])]
(d/update-in-when state [:workspace-local :edit-path id] assoc :edit-mode mode)
(update-in state [:workspace-local :edit-path id] assoc :edit-mode mode)
state))
ptk/WatchEvent
@@ -407,21 +413,29 @@
(assoc-in state [:workspace-local :edit-path id :prev-handler] nil)))))
(defn check-changed-content
[]
[id]
(ptk/reify ::check-changed-content
ptk/WatchEvent
(watch [_ state _]
(let [id (st/get-path-id state)
content (st/get-path state :content)
old-content (get-in state [:workspace-local :edit-path id :old-content])
mode (get-in state [:workspace-local :edit-path id :edit-mode])
empty-content? (empty? content)]
(watch [it state _]
(let [
;; id (st/get-path-id state)
content (st/get-path state :content)
empty-content? (empty? content)
local (get-in state [:workspace-local :edit-path id])
old-content (get local :old-content)
edit-mode (get local :edit-mode)]
(prn "check-changed-content" old-content)
(prn "check-changed-content" content)
(cond
(and (not= content old-content) (not empty-content?))
(rx/of (changes/save-path-content))
(let [page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
changes (changes/generate-path-changes it objects page-id id old-content content)]
(rx/of (dch/commit-changes changes)))
(= mode :draw)
(= :draw edit-mode)
(rx/of :interrupt)
:else

View File

@@ -65,7 +65,7 @@
point-change (->> (map hash-map old-points new-points) (reduce merge))]
(when (and (some? new-content) (some? shape))
(let [changes (changes/generate-path-changes it objects page-id shape (:content shape) new-content)]
(let [changes (changes/generate-path-changes it objects page-id (:id shape) (:content shape) new-content)]
(if (empty? new-content)
(rx/of (dch/commit-changes changes)
(dwe/clear-edition-mode))
@@ -298,8 +298,8 @@
edit-path (dm/get-in state [:workspace-local :edit-path id])
content (st/get-path state :content)
state (cond-> state
(cfh/path-shape? objects id)
(st/set-content (path/close-subpaths content)))]
#_(cfh/path-shape? objects id)
#_(st/set-content (path/close-subpaths content)))]
(cond-> state
(or (not edit-path)
@@ -338,19 +338,25 @@
(defn split-segments
[{:keys [from-p to-p t]}]
(ptk/reify ::split-segments
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
content (st/get-path state :content)]
(-> state
(assoc-in [:workspace-local :edit-path id :old-content] content)
(st/set-content (-> content
(path.segment/split-segments #{from-p to-p} t)
(path/content))))))
ptk/WatchEvent
(watch [_ _ _]
(rx/of (changes/save-path-content {:preserve-move-to true})))))
(watch [it state _]
(let [page-id (get state :current-page-id)
objects (dsh/lookup-page-objects state page-id)
shape (st/get-path state)
shape-id (get shape :id)
old-content (get shape :content)
new-content (-> old-content
(path.segment/split-segments #{from-p to-p} t)
(path/content))
changes (changes/generate-path-changes it objects page-id shape-id old-content new-content)]
(prn "split-segments" old-content)
(prn "split-segments" new-content)
(rx/of (dch/commit-changes changes))))))
(defn create-node-at-position
[event]

View File

@@ -44,7 +44,7 @@
(path/close-subpaths))
changes
(changes/generate-path-changes it objects page-id shape (:content shape) new-content)]
(changes/generate-path-changes it objects page-id (:id shape) (:content shape) new-content)]
(rx/concat
(rx/of (dwsh/update-shapes [id] path/convert-to-path)

View File

@@ -10,7 +10,9 @@
[app.common.data.undo-stack :as u]
[app.common.uuid :as uuid]
[app.main.data.workspace.common :as dwc]
[app.main.data.changes :as dch]
[app.main.data.workspace.edition :as-alias dwe]
[app.main.data.helpers :as dsh]
[app.main.data.workspace.pages :as-alias dwpg]
[app.main.data.workspace.path.changes :as changes]
[app.main.data.workspace.path.common :as common]
@@ -57,44 +59,63 @@
(ptk/reify ::undo-path
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
undo-stack (-> (get-in state [:workspace-local :edit-path id :undo-stack])
(u/undo))
entry (u/peek undo-stack)]
(cond-> state
(some? entry)
(-> (load-entry entry)
(d/assoc-in-when
[:workspace-local :edit-path id :undo-stack]
undo-stack)))))
(let [id (st/get-path-id state)]
(update-in state [:workspace-local :edit-path id :undo-stack] u/undo)))
ptk/WatchEvent
(watch [_ state _]
(let [id (st/get-path-id state)
undo-stack (get-in state [:workspace-local :edit-path id :undo-stack])]
(if (> (:index undo-stack) 0)
(rx/of (changes/save-path-content {:preserve-move-to true}))
(rx/of (changes/save-path-content {:preserve-move-to true})
(common/finish-path)
(dwc/show-toolbar)))))))
(watch [it state _]
(let [id (st/get-path-id state)
shape (st/get-path state)
page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
edition? (= (get-in state [:workspace-local :edition]) id)
ustack (get-in state [:workspace-local :edit-path id :undo-stack])
entry (u/peek ustack)
old-content (get shape :content)
new-content (get entry :content)
changes (changes/generate-path-changes it objects page-id id old-content new-content)]
(rx/concat
(rx/of #(load-entry % entry))
(if edition?
(rx/of (dch/commit-changes changes))
(rx/empty))
(if (zero? (:index ustack))
(rx/of (common/finish-path)
(dwc/show-toolbar))
(rx/empty)))))))
(defn redo-path []
(ptk/reify ::redo-path
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
undo-stack (-> (get-in state [:workspace-local :edit-path id :undo-stack])
(u/redo))
entry (u/peek undo-stack)]
(let [id (st/get-path-id state)
ustack (-> (get-in state [:workspace-local :edit-path id :undo-stack])
(u/redo))
entry (u/peek ustack)]
(-> state
(load-entry entry)
(d/assoc-in-when
[:workspace-local :edit-path id :undo-stack]
undo-stack))))
(d/assoc-in-when [:workspace-local :edit-path id :undo-stack] ustack))))
ptk/WatchEvent
(watch [_ _ _]
(rx/of (changes/save-path-content)))))
(watch [it state _]
(let [id (st/get-path-id state)
shape (st/get-path state)
page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
ustack (get-in state [:workspace-local :edit-path id :undo-stack])
entry (u/peek ustack)
old-content (get shape :content)
new-content (get entry :content)
changes (changes/generate-path-changes it objects page-id id old-content new-content)]
(rx/of (dch/commit-changes changes))))))
(defn merge-head
"Joins the head with the previous undo in one. This is done so when the user changes a
@@ -149,6 +170,7 @@
(ptk/reify ::start-path-undo
ptk/UpdateEvent
(update [_ state]
(let [undo-lock (get-in state [:workspace-local :edit-path (st/get-path-id state) :undo-lock])]
(cond-> state
(not undo-lock)