From 32b7bfe383b05ecb9f7c08d7d1ca68ff668e53dd Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 28 Jan 2016 20:26:08 +0200 Subject: [PATCH] Reimplemented the draw shapes/icons. --- src/uxbox/ui/workspace/base.cljs | 6 +- src/uxbox/ui/workspace/canvas.cljs | 24 ++---- src/uxbox/ui/workspace/canvas/draw.cljs | 86 +++++++++++++++++++++ src/uxbox/ui/workspace/canvas/movement.cljs | 32 +++++--- src/uxbox/ui/workspace/canvas/selrect.cljs | 57 ++++++-------- 5 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 src/uxbox/ui/workspace/canvas/draw.cljs diff --git a/src/uxbox/ui/workspace/base.cljs b/src/uxbox/ui/workspace/base.cljs index a9555c640..7d3ec2883 100644 --- a/src/uxbox/ui/workspace/base.cljs +++ b/src/uxbox/ui/workspace/base.cljs @@ -80,10 +80,8 @@ (defonce interactions-b (rx/bus)) (defn emit-interaction! - ([type] - (rx/push! interactions-b {:type type})) - ([type payload] - (rx/push! interactions-b {:type type :payload payload}))) + [type] + (rx/push! interactions-b type)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Mouse Position Stream diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index dab3cc2de..27fd46e80 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -17,6 +17,7 @@ [uxbox.ui.dom :as dom] [uxbox.ui.workspace.base :as wb] [uxbox.ui.workspace.canvas.movement] + [uxbox.ui.workspace.canvas.draw :refer (draw-area)] [uxbox.ui.workspace.canvas.selection :refer (shapes-selection)] [uxbox.ui.workspace.canvas.selrect :refer (selrect)] [uxbox.ui.workspace.grid :refer (grid)] @@ -67,7 +68,6 @@ (do (dom/stop-propagation event) (swap! local assoc :init-coords [x y]) - #_(reset! wb/shapes-dragging? true) (if (.-ctrlKey event) (rs/emit! (dw/select-shape id)) (rs/emit! (dw/deselect-all) @@ -162,7 +162,8 @@ (for [item (sequence xf (:shapes page))] (-> (shape item workspace-selected) (rum/with-key (str (:id item))))) - (selrect)]]]))) + (selrect) + (draw-area)]]]))) (def canvas (mx/component @@ -187,27 +188,16 @@ (dom/stop-propagation event) (when-not (empty? (:selected workspace)) (rs/emit! (dw/deselect-all))) - (wb/emit-interaction! :selrect/draw)) + (if-let [shape (:drawing workspace)] + (wb/emit-interaction! :draw/shape) + (wb/emit-interaction! :draw/selrect))) (on-mouse-up [event] (dom/stop-propagation event) - (wb/emit-interaction! :nothing)) - (on-click [event wstate] - (let [mousepos @wb/mouse-position - scroll-top @wb/scroll-top - shape (:drawing wstate)] - (when shape - (let [props {:x (first mousepos) - :y (+ (second mousepos) scroll-top) - :width 100 - :height 100}] - (rs/emit! - (dw/add-shape shape props) - (dw/select-for-drawing nil))))))] + (wb/emit-interaction! :nothing))] (html [:svg.viewport {:width wb/viewport-height :height wb/viewport-width :class (when drawing? "drawing") - :on-click #(on-click % workspace) :on-mouse-down on-mouse-down :on-mouse-up on-mouse-up} [:g.zoom {:transform (str "scale(" zoom ", " zoom ")")} diff --git a/src/uxbox/ui/workspace/canvas/draw.cljs b/src/uxbox/ui/workspace/canvas/draw.cljs new file mode 100644 index 000000000..5cfc2d998 --- /dev/null +++ b/src/uxbox/ui/workspace/canvas/draw.cljs @@ -0,0 +1,86 @@ +(ns uxbox.ui.workspace.canvas.draw + (:require-macros [uxbox.util.syntax :refer [define-once]]) + (:require [sablono.core :as html :refer-macros [html]] + [rum.core :as rum] + [beicon.core :as rx] + [cats.labs.lens :as l] + [uxbox.rstore :as rs] + [uxbox.state :as st] + [uxbox.shapes :as sh] + [uxbox.data.workspace :as dw] + [uxbox.ui.workspace.base :as wb] + [uxbox.ui.mixins :as mx] + [uxbox.ui.dom :as dom])) + +(defonce +drawing-shape+ (atom nil)) +(defonce +drawing-position+ (atom nil)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Component +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn- draw-area-render + [own] + (let [shape (rum/react +drawing-shape+) + [x y] (rum/react +drawing-position+)] + (when shape + (-> (sh/-resize shape [x y]) + (sh/-render identity))))) + +(def ^:static draw-area + (mx/component + {:render draw-area-render + :name "draw-area" + :mixins [mx/static rum/reactive]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Subscriptions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define-once :drawing-subscriptions + (letfn [(init-shape [shape] + (let [[x y :as mpos] @wb/mouse-position + stop @wb/scroll-top + y (+ stop y) + shape (sh/-initialize shape {:x1 x :y1 y :x2 x :y2 y})] + (reset! +drawing-shape+ shape) + (reset! +drawing-position+ [x y]) + + (as-> wb/interactions-b $ + (rx/filter #(not= % :shape/movement) $) + (rx/take 1 $) + (rx/take-until $ wb/mouse-s) + (rx/subscribe $ on-value nil on-complete)))) + + (on-value [[x y :as pos]] + (let [stop @wb/scroll-top] + (reset! +drawing-position+ + [x (+ y stop)]))) + + (on-complete [] + (let [shape @+drawing-shape+ + shpos @+drawing-position+ + shape (sh/-resize shape shpos)] + (rs/emit! (dw/add-shape shape) + (dw/select-for-drawing nil)) + (reset! +drawing-position+ nil) + (reset! +drawing-shape+ nil))) + + (init-icon [shape] + (let [[x y] @wb/mouse-position + stop @wb/scroll-top + y (+ stop y) + props {:x1 x :y1 y :x2 (+ x 100) :y2 (+ y 100)} + shape (sh/-initialize shape props)] + (rs/emit! (dw/add-shape shape) + (dw/select-for-drawing nil)))) + (init [] + (when-let [shape (:drawing @wb/workspace-l)] + (case (:type shape) + :builtin/icon (init-icon shape) + :builtin/line (init-shape shape))))] + + (as-> wb/interactions-b $ + (rx/dedupe $) + (rx/filter #(= :draw/shape %) $) + (rx/on-value $ init)))) diff --git a/src/uxbox/ui/workspace/canvas/movement.cljs b/src/uxbox/ui/workspace/canvas/movement.cljs index 1c46461ce..d2bbeed78 100644 --- a/src/uxbox/ui/workspace/canvas/movement.cljs +++ b/src/uxbox/ui/workspace/canvas/movement.cljs @@ -7,16 +7,24 @@ [uxbox.ui.workspace.base :as wb] [uxbox.data.workspace :as dw])) -(define-once :mouse-subscriptions - (as-> (rx/with-latest-from vector wb/interactions-b wb/mouse-delta-s) $ - (rx/filter #(= (:type (second %)) :shape/movement) $) - (rx/map first $) - (rx/on-value $ (fn [delta] - (let [pageid (get-in @st/state [:workspace :page]) - selected (get-in @st/state [:workspace :selected]) - shapes (->> (vals @wb/shapes-by-id) - (filter #(= (:page %) pageid)) - (filter (comp selected :id)))] - (doseq [{:keys [id group]} shapes] - (rs/emit! (dw/move-shape id delta)))))))) +(define-once :movement-subscription + (letfn [(on-value [delta] + (let [pageid (get-in @st/state [:workspace :page]) + selected (get-in @st/state [:workspace :selected]) + shapes (->> (vals @wb/shapes-by-id) + (filter #(= (:page %) pageid)) + (filter (comp selected :id)))] + (doseq [{:keys [id group]} shapes] + (rs/emit! (dw/move-shape id delta))))) + (init [] + (as-> wb/interactions-b $ + (rx/filter #(not= % :shape/movement) $) + (rx/take 1 $) + (rx/take-until $ wb/mouse-delta-s) + (rx/on-value $ on-value)))] + + (as-> wb/interactions-b $ + (rx/dedupe $) + (rx/filter #(= :shape/movement %) $) + (rx/on-value $ init)))) diff --git a/src/uxbox/ui/workspace/canvas/selrect.cljs b/src/uxbox/ui/workspace/canvas/selrect.cljs index e9c0cb6df..f96c7dcfa 100644 --- a/src/uxbox/ui/workspace/canvas/selrect.cljs +++ b/src/uxbox/ui/workspace/canvas/selrect.cljs @@ -58,36 +58,27 @@ :height (- current-y start-y)})) (define-once :selrect-subscriptions - (let [events #{:selrect/draw :nothing} - ss (as-> wb/interactions-b $ - (rx/filter #(contains? events (:type %)) $) - (rx/dedupe $) - (rx/merge (rx/of {:type :nothing}) $) - (rx/map (fn [event] - (case (:type event) - :selrect/draw true - :nothing false)) $) - (rx/buffer 2 1 $) - (rx/share $))] - (as-> ss $ - (rx/filter #(= (vec %) [false true]) $) - (rx/with-latest-from vector wb/mouse-s $) - (rx/on-value $ (fn [[_ [x y :as pos]]] - (let [scroll (or @wb/scroll-top 0) - pos [x (+ y scroll)]] - (swap! selrect-pos assoc - :start pos - :current pos))))) - (as-> ss $ - (rx/filter #(= (vec %) [true false]) $) - (rx/on-value $ (fn [] - (let [selrect (selrect->rect @selrect-pos)] - (rs/emit! (dw/select-shapes selrect)) - (reset! selrect-pos nil))))) - (as-> (rx/with-latest-from vector wb/interactions-b wb/mouse-s) $ - (rx/filter #(= (:type (second %)) :selrect/draw) $) - (rx/map first $) - (rx/on-value $ (fn [[x y :as pos]] - (let [scroll (or @wb/scroll-top 0) - pos [x (+ y scroll)]] - (swap! selrect-pos assoc :current pos))))))) + (letfn [(on-value [[x y :as pos]] + (let [scroll (or @wb/scroll-top 0) + pos [x (+ y scroll)]] + (if (nil? @selrect-pos) + (reset! selrect-pos {:start pos :current pos}) + (swap! selrect-pos assoc :current pos)))) + + (on-complete [] + (let [selrect (selrect->rect @selrect-pos)] + (rs/emit! (dw/select-shapes selrect)) + (reset! selrect-pos nil))) + + (init [] + (as-> wb/interactions-b $ + (rx/filter #(not= % :draw/selrect) $) + (rx/take 1 $) + (rx/take-until $ wb/mouse-s) + (rx/subscribe $ on-value nil on-complete)))] + + (as-> wb/interactions-b $ + (rx/dedupe $) + (rx/filter #(= :draw/selrect %) $) + (rx/on-value $ init)))) +