From bcc82bc5cf4fb0239ab3f4fa69ac3cf2bbbe6e30 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:01:25 +0300 Subject: [PATCH] Move shape related events from data.workspace to data.shapes. --- src/uxbox/data/shapes.cljs | 141 ++++++++++++++++++++++++++++++++ src/uxbox/data/workspace.cljs | 150 +--------------------------------- 2 files changed, 144 insertions(+), 147 deletions(-) diff --git a/src/uxbox/data/shapes.cljs b/src/uxbox/data/shapes.cljs index 7934dda3a..d2c3ab8c7 100644 --- a/src/uxbox/data/shapes.cljs +++ b/src/uxbox/data/shapes.cljs @@ -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))))))) + + diff --git a/src/uxbox/data/workspace.cljs b/src/uxbox/data/workspace.cljs index bf7a529b4..af6af7891 100644 --- a/src/uxbox/data/workspace.cljs +++ b/src/uxbox/data/workspace.cljs @@ -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 []