From 4185849102bbd441826c35d2c8cdab0ce6b5343f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 6 Apr 2016 18:53:16 +0300 Subject: [PATCH] Refactor drawing area. --- src/uxbox/ui/workspace/canvas.cljs | 2 +- src/uxbox/ui/workspace/canvas/draw.cljs | 105 -------------------- src/uxbox/ui/workspace/drawarea.cljs | 123 ++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 106 deletions(-) delete mode 100644 src/uxbox/ui/workspace/canvas/draw.cljs create mode 100644 src/uxbox/ui/workspace/drawarea.cljs diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index ce5b16176..d5e33f297 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -23,9 +23,9 @@ [uxbox.ui.shapes :as uus] [uxbox.ui.mixins :as mx] [uxbox.ui.workspace.base :as uuwb] + [uxbox.ui.workspace.drawarea :refer (draw-area)] [uxbox.ui.workspace.canvas.movement] [uxbox.ui.workspace.canvas.resize] - [uxbox.ui.workspace.canvas.draw :refer (draw-area)] [uxbox.ui.workspace.canvas.ruler :refer (ruler)] [uxbox.ui.workspace.canvas.selection :refer (shapes-selection)] [uxbox.ui.workspace.canvas.selrect :refer (selrect)] diff --git a/src/uxbox/ui/workspace/canvas/draw.cljs b/src/uxbox/ui/workspace/canvas/draw.cljs deleted file mode 100644 index 3333b7c4d..000000000 --- a/src/uxbox/ui/workspace/canvas/draw.cljs +++ /dev/null @@ -1,105 +0,0 @@ -;; This Source Code Form is subject to the terms of the Mozilla Public -;; License, v. 2.0. If a copy of the MPL was not distributed with this -;; file, You can obtain one at http://mozilla.org/MPL/2.0/. -;; -;; Copyright (c) 2015-2016 Andrey Antukh -;; Copyright (c) 2015-2016 Juan de la Cruz - -(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] - [lentes.core :as l] - [uxbox.rstore :as rs] - [uxbox.shapes :as ush] - [uxbox.state :as st] - [uxbox.data.workspace :as udw] - [uxbox.data.shapes :as uds] - [uxbox.ui.core :as uuc] - [uxbox.ui.shapes.core :as uusc] - [uxbox.ui.workspace.base :as wb] - [uxbox.ui.mixins :as mx] - [uxbox.util.geom.point :as gpt] - [uxbox.util.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+) - position (rum/react +drawing-position+)] - (when shape - (-> (assoc shape :drawing? true) - (ush/resize position) - (uusc/render-shape identity))))) - -(def ^:static draw-area - (mx/component - {:render draw-area-render - :name "draw-area" - :mixins [mx/static rum/reactive]})) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Subscriptions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; FIXME: this works for now, but should be refactored when advanced rendering -;; is introduced such as polyline, polygon and path. - -(define-once :drawing-subscriptions - (letfn [(init-shape [shape] - (let [{:keys [x y] :as pt} (gpt/divide @wb/mouse-canvas-a @wb/zoom-l) - shape (ush/initialize shape {:x1 x :y1 y :x2 x :y2 y})] - - (reset! +drawing-shape+ shape) - (reset! +drawing-position+ (assoc pt :lock false)) - - (let [stoper (->> uuc/actions-s - (rx/map :type) - (rx/filter #(empty? %)) - (rx/take 1))] - (as-> wb/mouse-canvas-s $ - (rx/take-until stoper $) - (rx/with-latest-from vector wb/mouse-ctrl-s $) - (rx/subscribe $ on-value nil on-complete))))) - - (init-icon [shape] - (let [{:keys [x y]} (gpt/divide @wb/mouse-canvas-a @wb/zoom-l) - props {:x1 x :y1 y :x2 (+ x 100) :y2 (+ y 100)} - shape (ush/initialize shape props)] - (rs/emit! (uds/add-shape shape) - (udw/select-for-drawing nil)))) - - (on-value [[pt ctrl?]] - (let [pt (gpt/divide pt @wb/zoom-l)] - (reset! +drawing-position+ (assoc pt :lock ctrl?)))) - - (on-complete [] - (let [shape @+drawing-shape+ - shpos @+drawing-position+ - shape (ush/resize shape shpos)] - (rs/emit! (uds/add-shape shape) - (udw/select-for-drawing nil)) - (reset! +drawing-position+ nil) - (reset! +drawing-shape+ nil))) - - (init [] - (when-let [shape (:drawing @wb/workspace-l)] - (case (:type shape) - :builtin/icon (init-icon shape) - :builtin/text (init-shape shape) - :builtin/rect (init-shape shape) - :builtin/circle (init-shape shape) - :builtin/line (init-shape shape))))] - - (as-> uuc/actions-s $ - (rx/map :type $) - (rx/dedupe $) - (rx/filter #(= "ui.shape.draw" %) $) - (rx/on-value $ init)))) diff --git a/src/uxbox/ui/workspace/drawarea.cljs b/src/uxbox/ui/workspace/drawarea.cljs new file mode 100644 index 000000000..197d8ded5 --- /dev/null +++ b/src/uxbox/ui/workspace/drawarea.cljs @@ -0,0 +1,123 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) 2015-2016 Andrey Antukh +;; Copyright (c) 2015-2016 Juan de la Cruz + +(ns uxbox.ui.workspace.drawarea + (:require-macros [uxbox.util.syntax :refer [define-once]]) + (:require [sablono.core :as html :refer-macros [html]] + [rum.core :as rum] + [beicon.core :as rx] + [lentes.core :as l] + [uxbox.rstore :as rs] + [uxbox.shapes :as ush] + [uxbox.state :as st] + [uxbox.data.workspace :as udw] + [uxbox.data.shapes :as uds] + [uxbox.ui.core :as uuc] + [uxbox.ui.shapes.core :as uusc] + [uxbox.ui.workspace.base :as wb] + [uxbox.ui.mixins :as mx] + [uxbox.util.geom.point :as gpt] + [uxbox.util.dom :as dom])) + +;; --- State + +(defonce drawing-shape (atom nil)) +(defonce drawing-position (atom nil)) + +;; --- Draw Area (Component) + +(declare watch-draw-actions) + +(defn- draw-area-render + [own] + (let [shape (rum/react drawing-shape) + position (rum/react drawing-position)] + (when shape + (-> (assoc shape :drawing? true) + (ush/resize position) + (uusc/render-shape identity))))) + +(defn- draw-area-will-mount + [own] + (assoc own ::sub (watch-draw-actions))) + +(defn- draw-area-will-unmount + [own] + (.close (::sub own)) + (dissoc own ::sub)) + +(defn- draw-area-transfer-state + [oldown own] + (assoc own ::sub (::sub oldown))) + +(def draw-area + (mx/component + {:render draw-area-render + :name "draw-area" + :will-mount draw-area-will-mount + :will-unmount draw-area-will-unmount + :mixins [mx/static rum/reactive]})) + +;; --- Drawing Logic + +(declare initialize-icon-drawing) +(declare initialize-shape-drawing) + +(defn- watch-draw-actions + [] + (letfn [(initialize [shape] + (println "initialize" shape) + (if (= (:type shape) :builtin/icon) + (initialize-icon-drawing shape) + (initialize-shape-drawing shape)))] + (as-> uuc/actions-s $ + (rx/map :type $) + (rx/dedupe $) + (rx/filter #(= "ui.shape.draw" %) $) + (rx/map #(:drawing @wb/workspace-l) $) + (rx/filter identity $) + (rx/on-value $ initialize)))) + +(defn- initialize-icon-drawing + "A drawing handler for icons." + [shape] + (let [{:keys [x y]} (gpt/divide @wb/mouse-canvas-a @wb/zoom-l) + props {:x1 x :y1 y :x2 (+ x 100) :y2 (+ y 100)} + shape (ush/initialize shape props)] + (rs/emit! (uds/add-shape shape) + (udw/select-for-drawing nil)))) + +(defn- initialize-shape-drawing + "A drawing handler for generic shapes such as rect, circle, text, etc." + [shape] + (letfn [(on-value [[pt ctrl?]] + (let [pt (gpt/divide pt @wb/zoom-l)] + (reset! drawing-position (assoc pt :lock ctrl?)))) + + (on-complete [] + (let [shape @drawing-shape + shpos @drawing-position + shape (ush/resize shape shpos)] + (rs/emit! (uds/add-shape shape) + (udw/select-for-drawing nil)) + (reset! drawing-position nil) + (reset! drawing-shape nil)))] + + (let [{:keys [x y] :as pt} (gpt/divide @wb/mouse-canvas-a @wb/zoom-l) + shape (ush/initialize shape {:x1 x :y1 y :x2 x :y2 y}) + stoper (->> uuc/actions-s + (rx/map :type) + (rx/filter #(empty? %)) + (rx/take 1))] + + (reset! drawing-shape shape) + (reset! drawing-position (assoc pt :lock false)) + + (as-> wb/mouse-canvas-s $ + (rx/take-until stoper $) + (rx/with-latest-from vector wb/mouse-ctrl-s $) + (rx/subscribe $ on-value nil on-complete)))))