0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-18 10:41:29 -05:00

Move shape related events from data.workspace to data.shapes.

This commit is contained in:
Andrey Antukh 2016-04-10 18:01:25 +03:00
parent 551c95b8fe
commit bcc82bc5cf
No known key found for this signature in database
GPG key ID: 4DFEBCB8316A8B95
2 changed files with 144 additions and 147 deletions

View file

@ -345,3 +345,144 @@
(-apply-update [_ state]
(stsh/drop-shape state sid tid loc))))
(defn select-shape
"Mark a shape selected for drawing in the canvas."
[id]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(let [selected (get-in state [:workspace :selected])]
(if (contains? selected id)
(update-in state [:workspace :selected] disj id)
(update-in state [:workspace :selected] conj id))))))
(defn select-shapes
"Select shapes that matches the select rect."
[selrect]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(let [pageid (get-in state [:workspace :page])
xf (comp
(filter #(= (:page %) pageid))
(remove :hidden)
(remove :blocked)
(map sh/outer-rect')
(filter #(sh/contained-in? % selrect))
(map :id))]
(->> (into #{} xf (vals (:shapes-by-id state)))
(assoc-in state [:workspace :selected]))))))
;; --- Events (implicit) (for selected)
(defn deselect-all
"Mark a shape selected for drawing in the canvas."
[]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(assoc-in state [:workspace :selected] #{}))))
(defn group-selected
[]
(letfn [(update-shapes-on-page [state pid selected group]
(as-> (get-in state [:pages-by-id pid :shapes]) $
(remove selected $)
(into [group] $)
(assoc-in state [:pages-by-id pid :shapes] $)))
(update-shapes-on-index [state shapes group]
(reduce (fn [state {:keys [id] :as shape}]
(as-> shape $
(assoc $ :group group)
(assoc-in state [:shapes-by-id id] $)))
state
shapes))
(valid-selection? [shapes]
(let [groups (into #{} (map :group shapes))]
(= 1 (count groups))))]
(reify
udp/IPageUpdate
rs/UpdateEvent
(-apply-update [_ state]
(let [shapes-by-id (get state :shapes-by-id)
sid (random-uuid)
pid (get-in state [:workspace :page])
selected (get-in state [:workspace :selected])
selected' (map #(get shapes-by-id %) selected)
group {:type :builtin/group
:name (str "Group " (rand-int 1000))
:items (into [] selected)
:id sid
:page pid}]
(if (valid-selection? selected')
(as-> state $
(update-shapes-on-index $ selected' sid)
(update-shapes-on-page $ pid selected sid)
(update $ :shapes-by-id assoc sid group)
(update $ :workspace assoc :selected #{}))
state))))))
;; TODO: maybe split in two separate events
(defn duplicate-selected
[]
(reify
udp/IPageUpdate
rs/UpdateEvent
(-apply-update [_ state]
(let [selected (get-in state [:workspace :selected])]
(stsh/duplicate-shapes state selected)))))
(defn delete-selected
"Deselect all and remove all selected shapes."
[]
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(let [selected (get-in state [:workspace :selected])]
(rx/from-coll
(into [(deselect-all)] (map #(delete-shape %) selected)))))))
(defn move-selected
"Move a minimal position unit the selected shapes."
([dir] (move-selected dir 1))
([dir n]
{:pre [(contains? #{:up :down :right :left} dir)]}
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(let [selected (get-in state [:workspace :selected])
delta (case dir
:up (gpt/point 0 (- n))
:down (gpt/point 0 n)
:right (gpt/point n 0)
:left (gpt/point (- n) 0))]
(rx/from-coll
(map #(move-shape % delta) selected)))))))
(defn update-selected-shapes-fill
"Update the fill related attributed on
selected shapes."
[opts]
(sc/validate! +shape-fill-attrs-schema+ opts)
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(rx/from-coll
(->> (get-in state [:workspace :selected])
(map #(update-fill-attrs % opts)))))))
(defn update-selected-shapes-stroke
"Update the fill related attributed on
selected shapes."
[opts]
(sc/validate! +shape-stroke-attrs-schema+ opts)
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(rx/from-coll
(->> (get-in state [:workspace :selected])
(map #(update-stroke-attrs % opts)))))))

View file

@ -10,19 +10,15 @@
[beicon.core :as rx]
[uxbox.shapes :as sh]
[uxbox.rstore :as rs]
[uxbox.router :as r]
[uxbox.state :as st]
[uxbox.state.shapes :as stsh]
[uxbox.schema :as sc]
[uxbox.xforms :as xf]
[uxbox.shapes :as sh]
[uxbox.data.pages :as udp]
[uxbox.data.shapes :as uds]
;; [uxbox.data.worker :as wrk]
[uxbox.util.datetime :as dt]
[uxbox.util.geom.point :as gpt]
[uxbox.util.data :refer (index-of)]))
[uxbox.util.geom.point :as gpt]))
;; --- Events (concrete)
;; --- Workspace Initialization
(defn initialize
"Initialize the workspace state."
@ -65,146 +61,6 @@
(assoc-in state [:workspace :drawing] shape)
(update-in state [:workspace] dissoc :drawing)))))
(defn select-shape
"Mark a shape selected for drawing in the canvas."
[id]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(let [selected (get-in state [:workspace :selected])]
(if (contains? selected id)
(update-in state [:workspace :selected] disj id)
(update-in state [:workspace :selected] conj id))))))
(defn select-shapes
"Select shapes that matches the select rect."
[selrect]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(let [pageid (get-in state [:workspace :page])
xf (comp
(filter #(= (:page %) pageid))
(remove :hidden)
(remove :blocked)
(map sh/outer-rect')
(filter #(sh/contained-in? % selrect))
(map :id))]
(->> (into #{} xf (vals (:shapes-by-id state)))
(assoc-in state [:workspace :selected]))))))
;; --- Events (implicit) (for selected)
(defn deselect-all
"Mark a shape selected for drawing in the canvas."
[]
(reify
rs/UpdateEvent
(-apply-update [_ state]
(assoc-in state [:workspace :selected] #{}))))
(defn group-selected
[]
(letfn [(update-shapes-on-page [state pid selected group]
(as-> (get-in state [:pages-by-id pid :shapes]) $
(remove selected $)
(into [group] $)
(assoc-in state [:pages-by-id pid :shapes] $)))
(update-shapes-on-index [state shapes group]
(reduce (fn [state {:keys [id] :as shape}]
(as-> shape $
(assoc $ :group group)
(assoc-in state [:shapes-by-id id] $)))
state
shapes))
(valid-selection? [shapes]
(let [groups (into #{} (map :group shapes))]
(= 1 (count groups))))]
(reify
udp/IPageUpdate
rs/UpdateEvent
(-apply-update [_ state]
(let [shapes-by-id (get state :shapes-by-id)
sid (random-uuid)
pid (get-in state [:workspace :page])
selected (get-in state [:workspace :selected])
selected' (map #(get shapes-by-id %) selected)
group {:type :builtin/group
:name (str "Group " (rand-int 1000))
:items (into [] selected)
:id sid
:page pid}]
(if (valid-selection? selected')
(as-> state $
(update-shapes-on-index $ selected' sid)
(update-shapes-on-page $ pid selected sid)
(update $ :shapes-by-id assoc sid group)
(update $ :workspace assoc :selected #{}))
state))))))
;; TODO: maybe split in two separate events
(defn duplicate-selected
[]
(reify
udp/IPageUpdate
rs/UpdateEvent
(-apply-update [_ state]
(let [selected (get-in state [:workspace :selected])]
(stsh/duplicate-shapes state selected)))))
(defn delete-selected
"Deselect all and remove all selected shapes."
[]
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(let [selected (get-in state [:workspace :selected])]
(rx/from-coll
(into [(deselect-all)] (map #(uds/delete-shape %) selected)))))))
(defn move-selected
"Move a minimal position unit the selected shapes."
([dir] (move-selected dir 1))
([dir n]
{:pre [(contains? #{:up :down :right :left} dir)]}
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(let [selected (get-in state [:workspace :selected])
delta (case dir
:up (gpt/point 0 (- n))
:down (gpt/point 0 n)
:right (gpt/point n 0)
:left (gpt/point (- n) 0))]
(rx/from-coll
(map #(uds/move-shape % delta) selected)))))))
(defn update-selected-shapes-fill
"Update the fill related attributed on
selected shapes."
[opts]
(sc/validate! uds/+shape-fill-attrs-schema+ opts)
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(rx/from-coll
(->> (get-in state [:workspace :selected])
(map #(uds/update-fill-attrs % opts)))))))
(defn update-selected-shapes-stroke
"Update the fill related attributed on
selected shapes."
[opts]
(sc/validate! uds/+shape-stroke-attrs-schema+ opts)
(reify
rs/WatchEvent
(-apply-watch [_ state s]
(rx/from-coll
(->> (get-in state [:workspace :selected])
(map #(uds/update-stroke-attrs % opts)))))))
;; --- Copy to Clipboard
(defrecord CopyToClipboard []