penpot/src/uxbox/ui/workspace/canvas/draw.cljs
2016-02-03 17:07:47 +02:00

90 lines
3.2 KiB
Clojure

(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.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
(-> (sh/-resize shape position)
(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+ {:x2 x :y2 y :lock false})
(as-> wb/interactions-b $
(rx/filter #(not= % :shape/movement) $)
(rx/take 1 $)
(rx/take-until $ wb/mouse-s)
(rx/with-latest-from vector wb/mouse-ctrl-s $)
(rx/subscribe $ on-value nil on-complete))))
(on-value [[[x y :as pos] ctrl?]]
(let [stop @wb/scroll-top]
(reset! +drawing-position+
{:x2 x :y2 (+ y stop) :lock ctrl?})))
(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/rect (init-shape shape)
:builtin/circle (init-shape shape)
:builtin/line (init-shape shape))))]
(as-> wb/interactions-b $
(rx/dedupe $)
(rx/filter #(= :draw/shape %) $)
(rx/on-value $ init))))