From 650bbabe945897c79af3f6286ff2722621450f78 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:13:25 +0300 Subject: [PATCH 01/19] Update externs file with more interop calls. --- resources/externs/main.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/externs/main.js b/resources/externs/main.js index be5aed904..1e3d5eb8c 100644 --- a/resources/externs/main.js +++ b/resources/externs/main.js @@ -25,5 +25,8 @@ var TopLevel = { "value": function() {}, "identifier": function() {}, "getBoundingClientRect": function() {}, - "getBBox": function() {} + "getBBox": function() {}, + "addEventListener": function() {}, + "postMessage": function() {}, + "data": function() {} }; From d976afda30c571dd2ecd7e0eb6581d29dfeac64b Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:13:54 +0300 Subject: [PATCH 02/19] Fix wrong filename on watch-tests script. --- scripts/watch-tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/watch-tests b/scripts/watch-tests index 6958be417..76b57dda5 100755 --- a/scripts/watch-tests +++ b/scripts/watch-tests @@ -1,2 +1,2 @@ #!/bin/sh -lein trampoline run -m clojure.main scripts/watch.clj +lein trampoline run -m clojure.main scripts/watch-tests.clj From 89a21d7abb6948df5f14822bb54551af2ac49cde Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:14:21 +0300 Subject: [PATCH 03/19] Add update-shape event just for shape inplace update. --- src/uxbox/data/shapes.cljs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/uxbox/data/shapes.cljs b/src/uxbox/data/shapes.cljs index b552a6883..474a078b7 100644 --- a/src/uxbox/data/shapes.cljs +++ b/src/uxbox/data/shapes.cljs @@ -94,6 +94,14 @@ (let [shape (get-in state [:shapes-by-id id])] (stsh/dissoc-shape state shape))))) +(defn update-shape + "Just updates in place the shape." + [{:keys [id] :as shape}] + (reify + rs/UpdateEvent + (-apply-update [_ state] + (update-in state [:shapes-by-id id] merge shape)))) + (defn move-shape "Mark a shape selected for drawing in the canvas." [sid delta] From 3dd741129c4b19cf540e0598f6c86a8c259f4575 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:14:38 +0300 Subject: [PATCH 04/19] Improve move-shape event constructor docstring. --- src/uxbox/data/shapes.cljs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/uxbox/data/shapes.cljs b/src/uxbox/data/shapes.cljs index 474a078b7..7934dda3a 100644 --- a/src/uxbox/data/shapes.cljs +++ b/src/uxbox/data/shapes.cljs @@ -103,9 +103,8 @@ (update-in state [:shapes-by-id id] merge shape)))) (defn move-shape - "Mark a shape selected for drawing in the canvas." + "Move shape using relative position (delta)." [sid delta] - {:pre [(gpt/point? delta)]} (reify udp/IPageUpdate rs/UpdateEvent From 6c64279c9437928ba2da3a82d0062878a252708f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:15:44 +0300 Subject: [PATCH 05/19] Move transit ns under uxbox.util. --- src/uxbox/repo/core.cljs | 2 +- src/uxbox/{ => util}/transit.cljs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename src/uxbox/{ => util}/transit.cljs (96%) diff --git a/src/uxbox/repo/core.cljs b/src/uxbox/repo/core.cljs index 3f152186a..18105b4e7 100644 --- a/src/uxbox/repo/core.cljs +++ b/src/uxbox/repo/core.cljs @@ -13,7 +13,7 @@ [hodgepodge.core :refer (local-storage)] [promesa.core :as p :include-macros true] [beicon.core :as rx] - [uxbox.transit :as t] + [uxbox.util.transit :as t] [uxbox.state :as ust]) (:import [goog.Uri QueryData])) diff --git a/src/uxbox/transit.cljs b/src/uxbox/util/transit.cljs similarity index 96% rename from src/uxbox/transit.cljs rename to src/uxbox/util/transit.cljs index 4718c6922..e5b8e403e 100644 --- a/src/uxbox/transit.cljs +++ b/src/uxbox/util/transit.cljs @@ -4,9 +4,8 @@ ;; ;; Copyright (c) 2016 Andrey Antukh -(ns uxbox.transit +(ns uxbox.util.transit "A lightweight abstraction for transit serialization." - (:refer-clojure :exclude [do]) (:require [cognitect.transit :as t] [uxbox.util.data :refer (parse-int)] [uxbox.util.datetime :as dt])) From b66be25a8e38064433b0ed3d2ca7f7af94aace36 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:17:31 +0300 Subject: [PATCH 06/19] Minor comments change. --- src/uxbox/shapes.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uxbox/shapes.cljs b/src/uxbox/shapes.cljs index 374d74136..1e49d63c8 100644 --- a/src/uxbox/shapes.cljs +++ b/src/uxbox/shapes.cljs @@ -211,7 +211,7 @@ [shape _] (throw (ex-info "Not implemented (size)" (select-keys shape [:type])))) -;; Move +;; Move (with deltas) (defmethod move ::rect [shape {dx :x dy :y}] From bfc0fc0f987ab3217f8c3443b0e93fc52ae75197 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:17:43 +0300 Subject: [PATCH 07/19] Temporary comment duplicated code. --- src/uxbox/ui/shapes/circle.cljs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/uxbox/ui/shapes/circle.cljs b/src/uxbox/ui/shapes/circle.cljs index ba34d7e1d..715362baa 100644 --- a/src/uxbox/ui/shapes/circle.cljs +++ b/src/uxbox/ui/shapes/circle.cljs @@ -20,20 +20,20 @@ (declare handlers) -(defmethod uusc/render-component :default ;; :builtin/icon - [own shape] - (let [{:keys [id x y width height group]} shape - selected (rum/react uusc/selected-shapes-l) - selected? (contains? selected id) - on-mouse-down #(uusi/on-mouse-down % shape selected) - on-mouse-up #(uusi/on-mouse-up % shape)] - (html - [:g.shape {:class (when selected? "selected") - :on-mouse-down on-mouse-down - :on-mouse-up on-mouse-up} - (uusc/render-shape shape #(uusc/shape %)) - (when (and selected? (= (count selected) 1)) - (handlers shape))]))) +;; (defmethod uusc/render-component :default ;; :builtin/icon +;; [own shape] +;; (let [{:keys [id x y width height group]} shape +;; selected (rum/react uusc/selected-shapes-l) +;; selected? (contains? selected id) +;; on-mouse-down #(uusi/on-mouse-down % shape selected) +;; on-mouse-up #(uusi/on-mouse-up % shape)] +;; (html +;; [:g.shape {:class (when selected? "selected") +;; :on-mouse-down on-mouse-down +;; :on-mouse-up on-mouse-up} +;; (uusc/render-shape shape #(uusc/shape %)) +;; (when (and selected? (= (count selected) 1)) +;; (handlers shape))]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Circle Handlers From 50e8de4552fa5d2ae939ceda1d2cbe7364b78583 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:18:04 +0300 Subject: [PATCH 08/19] Send the select-shape event before acquire move action. --- src/uxbox/ui/shapes/icon.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uxbox/ui/shapes/icon.cljs b/src/uxbox/ui/shapes/icon.cljs index 48d97aadc..44e16f3de 100644 --- a/src/uxbox/ui/shapes/icon.cljs +++ b/src/uxbox/ui/shapes/icon.cljs @@ -28,8 +28,8 @@ (and (not selected?) (empty? selected)) (do (dom/stop-propagation event) - (uuc/acquire-action! "ui.shape.move") - (rs/emit! (dw/select-shape id))) + (rs/emit! (dw/select-shape id)) + (uuc/acquire-action! "ui.shape.move")) (and (not selected?) (not (empty? selected))) (do From 69329f7f6452f3e8e80d45ba363af93a3c29df9d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:19:11 +0300 Subject: [PATCH 09/19] Make grid fill all the workspace instead only canvas. --- src/uxbox/ui/workspace/canvas.cljs | 13 +++++++------ src/uxbox/ui/workspace/grid.cljs | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index 2fa038d92..1f3fb3363 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -69,9 +69,7 @@ (for [item (reverse (:shapes page))] (-> (uus/shape item) (rum/with-key (str item)))) - (draw-area)]] - (when (contains? flags :grid) - (grid))]))) + (draw-area)]]]))) (def canvas (mx/component @@ -87,6 +85,7 @@ [own] (let [workspace (rum/react uuwb/workspace-l) page (rum/react uuwb/page-l) + flags (:flags workspace) drawing? (:drawing workspace) zoom (or (:zoom workspace) 1)] (letfn [(on-mouse-down [event] @@ -109,9 +108,11 @@ :on-mouse-up on-mouse-up} [:g.zoom {:transform (str "scale(" zoom ", " zoom ")")} (if page - (canvas page))] - (ruler) - (selrect)])))) + (canvas page)) + (if (contains? flags :grid) + (grid))] + (ruler) + (selrect)])))) (defn- viewport-did-mount [own] diff --git a/src/uxbox/ui/workspace/grid.cljs b/src/uxbox/ui/workspace/grid.cljs index af2813ba1..5e7b8a255 100644 --- a/src/uxbox/ui/workspace/grid.cljs +++ b/src/uxbox/ui/workspace/grid.cljs @@ -20,8 +20,10 @@ (defn- grid-render [own] - (let [{:keys [width height options]} (deref wb/page-l) + (let [options (:options @wb/page-l) color (:grid/color options "#cccccc") + width wb/viewport-width + height wb/viewport-height x-ticks (ticks-range width (:grid/x-axis options 10)) y-ticks (ticks-range height (:grid/y-axis options 10)) path (as-> [] $ From 551c95b8fe72578d9dfb5fa1c0ed68c736daa200 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 9 Apr 2016 23:20:00 +0300 Subject: [PATCH 10/19] Change the shapes moviment tracking approach. Will facilitate grid alignment. --- src/uxbox/ui/workspace/movement.cljs | 32 +++++++++++++++++++--------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/uxbox/ui/workspace/movement.cljs b/src/uxbox/ui/workspace/movement.cljs index 08541eef4..b80d30485 100644 --- a/src/uxbox/ui/workspace/movement.cljs +++ b/src/uxbox/ui/workspace/movement.cljs @@ -8,16 +8,31 @@ (ns uxbox.ui.workspace.movement "Shape movement in workspace logic." (:require [beicon.core :as rx] + [lentes.core :as l] [uxbox.rstore :as rs] [uxbox.state :as st] + [uxbox.shapes :as sh] [uxbox.ui.core :as uuc] [uxbox.ui.workspace.base :as wb] + [uxbox.ui.workspace.align :as align] [uxbox.data.shapes :as uds] [uxbox.util.geom.point :as gpt])) (declare initialize) (declare handle-movement) +;; --- Lenses + +(defn- resolve-selected + [state] + (let [selected (get-in state [:workspace :selected]) + xf (map #(get-in state [:shapes-by-id %]))] + (into #{} xf selected))) + +(def ^:const ^:private selected-shapes-l + (-> (l/getter resolve-selected) + (l/focus-atom st/state))) + ;; --- Public Api (defn watch-move-actions @@ -30,22 +45,19 @@ (defn- initialize [] - (let [stoper (->> uuc/actions-s + (let [shapes @selected-shapes-l + stoper (->> uuc/actions-s (rx/map :type) (rx/filter empty?) (rx/take 1))] (as-> wb/mouse-delta-s $ (rx/take-until stoper $) - (rx/on-value $ handle-movement)))) + (rx/scan (fn [acc delta] + (mapv #(sh/move % delta) acc)) shapes $) + (rx/subscribe $ handle-movement)))) (defn- handle-movement [delta] - (let [pageid (get-in @st/state [:workspace :page]) - selected (get-in @st/state [:workspace :selected]) - shapes (->> (vals @wb/shapes-by-id-l) - (filter #(= (:page %) pageid)) - (filter (comp selected :id))) - delta (gpt/divide delta @wb/zoom-l)] - (doseq [{:keys [id group]} shapes] - (rs/emit! (uds/move-shape id delta))))) + (doseq [shape delta] + (rs/emit! (uds/update-shape shape)))) From bcc82bc5cf4fb0239ab3f4fa69ac3cf2bbbe6e30 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:01:25 +0300 Subject: [PATCH 11/19] 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 [] From aa06d824ee8612a357806a859b24eac0efe29016 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:03:28 +0300 Subject: [PATCH 12/19] Adapt imports to previos data api change. --- src/uxbox/ui/shapes/icon.cljs | 9 +++++---- src/uxbox/ui/shapes/text.cljs | 12 ++++++------ src/uxbox/ui/workspace/base.cljs | 16 ++++------------ src/uxbox/ui/workspace/canvas.cljs | 3 ++- src/uxbox/ui/workspace/colorpalette.cljs | 5 +++-- src/uxbox/ui/workspace/selrect.cljs | 3 ++- src/uxbox/ui/workspace/shortcuts.cljs | 13 +++++++------ src/uxbox/ui/workspace/sidebar/layers.cljs | 20 ++++++++++---------- 8 files changed, 39 insertions(+), 42 deletions(-) diff --git a/src/uxbox/ui/shapes/icon.cljs b/src/uxbox/ui/shapes/icon.cljs index 44e16f3de..654a9a90b 100644 --- a/src/uxbox/ui/shapes/icon.cljs +++ b/src/uxbox/ui/shapes/icon.cljs @@ -7,6 +7,7 @@ [uxbox.state :as st] [uxbox.shapes :as ush] [uxbox.data.workspace :as dw] + [uxbox.data.shapes :as uds] [uxbox.ui.core :as uuc] [uxbox.ui.mixins :as mx] [uxbox.ui.keyboard :as kbd] @@ -28,16 +29,16 @@ (and (not selected?) (empty? selected)) (do (dom/stop-propagation event) - (rs/emit! (dw/select-shape id)) + (rs/emit! (uds/select-shape id)) (uuc/acquire-action! "ui.shape.move")) (and (not selected?) (not (empty? selected))) (do (dom/stop-propagation event) (if (kbd/shift? event) - (rs/emit! (dw/select-shape id)) - (rs/emit! (dw/deselect-all) - (dw/select-shape id)))) + (rs/emit! (uds/select-shape id)) + (rs/emit! (uds/deselect-all) + (uds/select-shape id)))) :else (do diff --git a/src/uxbox/ui/shapes/text.cljs b/src/uxbox/ui/shapes/text.cljs index 5e882bd1b..0f58f8091 100644 --- a/src/uxbox/ui/shapes/text.cljs +++ b/src/uxbox/ui/shapes/text.cljs @@ -7,7 +7,7 @@ [uxbox.rstore :as rs] [uxbox.state :as st] [uxbox.shapes :as ush] - [uxbox.data.shapes :as ds] + [uxbox.data.shapes :as uds] [uxbox.data.workspace :as dw] [uxbox.ui.core :as uuc] [uxbox.ui.mixins :as mx] @@ -34,15 +34,15 @@ (do (dom/stop-propagation event) (uuc/acquire-action! "ui.shape.move") - (rs/emit! (dw/select-shape id))) + (rs/emit! (uds/select-shape id))) (and (not selected?) (not (empty? selected))) (do (dom/stop-propagation event) (if (kbd/shift? event) - (rs/emit! (dw/select-shape id)) - (rs/emit! (dw/deselect-all) - (dw/select-shape id)))) + (rs/emit! (uds/select-shape id)) + (rs/emit! (uds/deselect-all) + (uds/select-shape id)))) :else (do @@ -80,7 +80,7 @@ (on-input [ev] (let [content (dom/event->inner-text ev) sid (:id (first (:rum/props own)))] - (rs/emit! (ds/update-text sid {:content content}))))] + (rs/emit! (uds/update-text sid {:content content}))))] (let [dom (mx/get-ref-dom own "main") dom2 (mx/get-ref-dom own "container") key1 (events/listen dom EventType.DBLCLICK on-double-click) diff --git a/src/uxbox/ui/workspace/base.cljs b/src/uxbox/ui/workspace/base.cljs index 0ed1381b0..ffca0c1e6 100644 --- a/src/uxbox/ui/workspace/base.cljs +++ b/src/uxbox/ui/workspace/base.cljs @@ -18,9 +18,7 @@ [goog.events :as events]) (:import goog.events.EventType)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Lenses -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Lenses (def ^:const workspace-l (as-> (l/in [:workspace]) $ @@ -60,9 +58,7 @@ (-> (l/in [:workspace :zoom]) (l/focus-atom st/state))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Scroll Stream -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Scroll Stream (defonce scroll-b (rx/bus)) @@ -75,9 +71,7 @@ (defonce scroll-a (rx/to-atom scroll-s)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Mouse Position Stream -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Mouse Position Stream (defonce mouse-b (rx/bus)) (defonce mouse-s @@ -120,9 +114,7 @@ (rx/map coords-delta) (rx/share))) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Constants -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Constants (def ^:const viewport-width 4000) (def ^:const viewport-height 4000) diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index 1f3fb3363..e5e382901 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -15,6 +15,7 @@ [uxbox.shapes :as sh] [uxbox.data.projects :as dp] [uxbox.data.workspace :as dw] + [uxbox.data.shapes :as uds] [uxbox.util.geom.point :as gpt] [uxbox.util.dom :as dom] [uxbox.util.data :refer (parse-int)] @@ -91,7 +92,7 @@ (letfn [(on-mouse-down [event] (dom/stop-propagation event) (when-not (empty? (:selected workspace)) - (rs/emit! (dw/deselect-all))) + (rs/emit! (uds/deselect-all))) (if-let [shape (:drawing workspace)] (uuc/acquire-action! "ui.shape.draw") (uuc/acquire-action! "ui.selrect"))) diff --git a/src/uxbox/ui/workspace/colorpalette.cljs b/src/uxbox/ui/workspace/colorpalette.cljs index ff7bab258..e9e1f2ed2 100644 --- a/src/uxbox/ui/workspace/colorpalette.cljs +++ b/src/uxbox/ui/workspace/colorpalette.cljs @@ -14,6 +14,7 @@ [uxbox.state :as st] [uxbox.library :as library] [uxbox.data.workspace :as dw] + [uxbox.data.shapes :as uds] [uxbox.util.lens :as ul] [uxbox.util.data :refer (read-string)] [uxbox.util.color :refer (hex->rgb)] @@ -48,8 +49,8 @@ [color event] (dom/prevent-default event) (if (kbd/shift? event) - (rs/emit! (dw/update-selected-shapes-stroke {:color color})) - (rs/emit! (dw/update-selected-shapes-fill {:color color})))) + (rs/emit! (uds/update-selected-shapes-stroke {:color color})) + (rs/emit! (uds/update-selected-shapes-fill {:color color})))) (defn- colorpalette-render [own] diff --git a/src/uxbox/ui/workspace/selrect.cljs b/src/uxbox/ui/workspace/selrect.cljs index 15c7b2135..00b2574c3 100644 --- a/src/uxbox/ui/workspace/selrect.cljs +++ b/src/uxbox/ui/workspace/selrect.cljs @@ -13,6 +13,7 @@ [uxbox.rstore :as rs] [uxbox.shapes :as sh] [uxbox.data.workspace :as dw] + [uxbox.data.shapes :as uds] [uxbox.ui.core :as uuc] [uxbox.ui.mixins :as mx] [uxbox.ui.workspace.base :as wb])) @@ -94,7 +95,7 @@ (on-complete [] (rs/emit! (-> (selrect->rect @position) (translate-to-canvas) - (dw/select-shapes))) + (uds/select-shapes))) (reset! position nil)) (init [] diff --git a/src/uxbox/ui/workspace/shortcuts.cljs b/src/uxbox/ui/workspace/shortcuts.cljs index 4e543be7f..9d14ac147 100644 --- a/src/uxbox/ui/workspace/shortcuts.cljs +++ b/src/uxbox/ui/workspace/shortcuts.cljs @@ -11,6 +11,7 @@ [uxbox.rstore :as rs] [uxbox.ui.lightbox :as lightbox] [uxbox.data.workspace :as dw] + [uxbox.data.shapes :as uds] [uxbox.data.history :as udh]) (:import goog.events.EventType goog.events.KeyCodes @@ -28,15 +29,15 @@ :ctrl+shift+l #(rs/emit! (dw/toggle-flag :layers)) :ctrl+0 #(rs/emit! (dw/reset-zoom)) :ctrl+r #(rs/emit! (dw/toggle-flag :ruler)) - :ctrl+d #(rs/emit! (dw/duplicate-selected)) + :ctrl+d #(rs/emit! (uds/duplicate-selected)) :ctrl+c #(rs/emit! (dw/copy-to-clipboard)) :ctrl+v #(rs/emit! (dw/paste-from-clipboard)) :ctrl+z #(rs/emit! (udh/backwards-to-previous-version)) :ctrl+shift+z #(rs/emit! (udh/forward-to-next-version)) :ctrl+shift+v #(lightbox/open! :clipboard) - :esc #(rs/emit! (dw/deselect-all)) - :backspace #(rs/emit! (dw/delete-selected)) - :delete #(rs/emit! (dw/delete-selected)) + :esc #(rs/emit! (uds/deselect-all)) + :backspace #(rs/emit! (uds/delete-selected)) + :delete #(rs/emit! (uds/delete-selected)) :shift+up #(move-selected :up :fast) :shift+down #(move-selected :down :fast) :shift+right #(move-selected :right :fast) @@ -78,8 +79,8 @@ (defn- move-selected [dir speed] (case speed - :std (rs/emit! (dw/move-selected dir 1)) - :fast (rs/emit! (dw/move-selected dir 20)))) + :std (rs/emit! (uds/move-selected dir 1)) + :fast (rs/emit! (uds/move-selected dir 20)))) ;; --- Mixin diff --git a/src/uxbox/ui/workspace/sidebar/layers.cljs b/src/uxbox/ui/workspace/sidebar/layers.cljs index a18bd65cf..f33e41617 100644 --- a/src/uxbox/ui/workspace/sidebar/layers.cljs +++ b/src/uxbox/ui/workspace/sidebar/layers.cljs @@ -49,18 +49,18 @@ nil (.-ctrlKey event) - (rs/emit! (udw/select-shape id)) + (rs/emit! (uds/select-shape id)) (> (count selected) 1) - (rs/emit! (udw/deselect-all) - (udw/select-shape id)) + (rs/emit! (uds/deselect-all) + (uds/select-shape id)) (contains? selected id) - (rs/emit! (udw/select-shape id)) + (rs/emit! (uds/select-shape id)) :else - (rs/emit! (udw/deselect-all) - (udw/select-shape id))))) + (rs/emit! (uds/deselect-all) + (uds/select-shape id))))) (defn- toggle-visibility [selected item event] @@ -71,7 +71,7 @@ (rs/emit! (uds/show-shape id)) (rs/emit! (uds/hide-shape id))) (when (contains? selected id) - (rs/emit! (udw/select-shape id))))) + (rs/emit! (uds/select-shape id))))) (defn- toggle-blocking [item event] @@ -289,9 +289,9 @@ shapes-by-id (rum/react wb/shapes-by-id-l) page (rum/react (focus-page (:page workspace))) close #(rs/emit! (udw/toggle-flag :layers)) - duplicate #(rs/emit! (udw/duplicate-selected)) - group #(rs/emit! (udw/group-selected)) - delete #(rs/emit! (udw/delete-selected)) + duplicate #(rs/emit! (uds/duplicate-selected)) + group #(rs/emit! (uds/group-selected)) + delete #(rs/emit! (uds/delete-selected)) dragel (volatile! nil)] (html [:div#layers.tool-window From e9d3e7578e3c2ccd394d0dea29f33d44e169ee74 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:04:37 +0300 Subject: [PATCH 13/19] Minor improvements on grid render code. --- src/uxbox/ui/workspace/grid.cljs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/uxbox/ui/workspace/grid.cljs b/src/uxbox/ui/workspace/grid.cljs index 5e7b8a255..a76c11c1b 100644 --- a/src/uxbox/ui/workspace/grid.cljs +++ b/src/uxbox/ui/workspace/grid.cljs @@ -14,7 +14,6 @@ ;; --- Grid (Component) -(declare ticks-range) (declare vertical-line) (declare horizontal-line) @@ -24,8 +23,14 @@ color (:grid/color options "#cccccc") width wb/viewport-width height wb/viewport-height - x-ticks (ticks-range width (:grid/x-axis options 10)) - y-ticks (ticks-range height (:grid/y-axis options 10)) + x-ticks (range (- 0 wb/canvas-start-x) + (- width wb/canvas-start-x) + (:grid/x-axis options 10)) + + y-ticks (range (- 0 wb/canvas-start-x) + (- height wb/canvas-start-x) + (:grid/y-axis options 10)) + path (as-> [] $ (reduce (partial vertical-line height) $ x-ticks) (reduce (partial horizontal-line width) $ y-ticks))] @@ -50,9 +55,3 @@ [height acc value] (let [pos (+ value wb/canvas-start-y)] (conj acc (str/format "M %s %s L %s %s" pos 0 pos height)))) - -(defn- ticks-range - [size step] - (range (- 0 wb/canvas-start-y) - (- size wb/canvas-start-y) - step)) From 9bd358a1195d1a7491769ac23660c51dcd383f44 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:05:04 +0300 Subject: [PATCH 14/19] Properly persist as int the grid axis on workspace settings lightbox. --- src/uxbox/ui/workspace/settings.cljs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/uxbox/ui/workspace/settings.cljs b/src/uxbox/ui/workspace/settings.cljs index 87a725954..489d314cb 100644 --- a/src/uxbox/ui/workspace/settings.cljs +++ b/src/uxbox/ui/workspace/settings.cljs @@ -16,7 +16,8 @@ [uxbox.ui.lightbox :as lightbox] [uxbox.ui.colorpicker :as uucp] [uxbox.ui.workspace.base :as wb] - [uxbox.util.dom :as dom])) + [uxbox.util.dom :as dom] + [uxbox.util.data :refer (parse-int)])) ;; --- Lentes @@ -33,7 +34,8 @@ opts (merge (:options page) (deref local))] (letfn [(on-field-change [field event] - (let [value (dom/event->value event)] + (let [value (dom/event->value event) + value (parse-int value)] (swap! local assoc field value))) (on-color-change [color] (swap! local assoc :grid/color color)) @@ -42,6 +44,7 @@ (dom/checked?))] (swap! local assoc :grid/align checked?))) (on-submit [event] + (dom/prevent-default event) (let [page (assoc page :options opts)] (rs/emit! (udp/update-page-metadata page)) (lightbox/close!)))] @@ -52,14 +55,15 @@ [:input#grid-x.input-text {:placeholder "X px" :type "number" - :value (:grid/x-axis opts "2") + ;; TODO: put here the default from constants + :value (:grid/x-axis opts "10") :on-change (partial on-field-change :grid/x-axis) :min 1 ;;TODO check this value :max 100}] [:input#grid-y.input-text {:placeholder "Y px" :type "number" - :value (:grid/y-axis opts "2") + :value (:grid/y-axis opts "10") :on-change (partial on-field-change :grid/y-axis) :min 1 :max 100}]] From e791f49921c2eeb5d481472f36c9423273a7bcd4 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:05:32 +0300 Subject: [PATCH 15/19] Add point read/write handler to transit. --- src/uxbox/util/transit.cljs | 44 +++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/src/uxbox/util/transit.cljs b/src/uxbox/util/transit.cljs index e5b8e403e..4493f616a 100644 --- a/src/uxbox/util/transit.cljs +++ b/src/uxbox/util/transit.cljs @@ -7,34 +7,44 @@ (ns uxbox.util.transit "A lightweight abstraction for transit serialization." (:require [cognitect.transit :as t] + [com.cognitect.transit :as tr] [uxbox.util.data :refer (parse-int)] + [uxbox.util.geom.point :as gpt] [uxbox.util.datetime :as dt])) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Read/Write Transit handlers -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Transit Handlers -(def ^:private datetime-write-handler - (reify - Object - (tag [_ v] "m") - (rep [_ v] (dt/format v :offset)) - (stringRep [this v] (str (dt/format v :offset))))) +(def datetime-write-handler + (t/write-handler (constantly "m") + #(str (dt/format % :offset)))) -(defn- datetime-read-handler - [v] - (dt/datetime (parse-int v))) +(def datetime-read-handler + (t/read-handler + #(dt/datetime (parse-int %)))) + +(def point-write-handler + (t/write-handler + (constantly "point") + (fn [v] + (let [ret #js []] + (.push ret (:x v)) + (.push ret (:y v)) + ret)))) + +(def point-read-handler + (t/read-handler + #(gpt/point (js->clj %)))) (def ^:privare +read-handlers+ {"u" uuid - "m" datetime-read-handler}) + "m" datetime-read-handler + "point" point-read-handler}) (def ^:privare +write-handlers+ - {dt/DateTime datetime-write-handler}) + {dt/DateTime datetime-write-handler + gpt/Point point-write-handler}) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Public Api -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; --- Public Api (defn decode [data] From d69be9a3785d5022163c745887333980dac78702 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:19:24 +0300 Subject: [PATCH 16/19] Split constants to specific namespace. --- src/uxbox/constants.cljs | 22 ++++++++++++++++++++ src/uxbox/ui/workspace.cljs | 16 +++++++++++---- src/uxbox/ui/workspace/base.cljs | 11 ---------- src/uxbox/ui/workspace/canvas.cljs | 9 +++++---- src/uxbox/ui/workspace/grid.cljs | 17 ++++++++-------- src/uxbox/ui/workspace/ruler.cljs | 5 +++-- src/uxbox/ui/workspace/rules.cljs | 31 +++++++++++++++-------------- src/uxbox/ui/workspace/scroll.cljs | 1 + src/uxbox/ui/workspace/selrect.cljs | 5 +++-- 9 files changed, 71 insertions(+), 46 deletions(-) create mode 100644 src/uxbox/constants.cljs diff --git a/src/uxbox/constants.cljs b/src/uxbox/constants.cljs new file mode 100644 index 000000000..64151d602 --- /dev/null +++ b/src/uxbox/constants.cljs @@ -0,0 +1,22 @@ +;; 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.constants) + +(def ^:const grid-x-axis 10) +(def ^:const grid-y-axis 10) + +(def ^:const viewport-width 4000) +(def ^:const viewport-height 4000) + +(def ^:const canvas-start-x 1200) +(def ^:const canvas-start-y 1200) +(def ^:const canvas-scroll-padding 50) +(def ^:const canvas-start-scroll-x (- canvas-start-x canvas-scroll-padding)) +(def ^:const canvas-start-scroll-y (- canvas-start-y canvas-scroll-padding)) + + diff --git a/src/uxbox/ui/workspace.cljs b/src/uxbox/ui/workspace.cljs index 95c1232d8..b600313d0 100644 --- a/src/uxbox/ui/workspace.cljs +++ b/src/uxbox/ui/workspace.cljs @@ -1,7 +1,15 @@ +;; 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 (:require [sablono.core :as html :refer-macros [html]] [rum.core :as rum] [beicon.core :as rx] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.data.workspace :as dw] [uxbox.data.pages :as udp] @@ -42,8 +50,8 @@ dom (mx/get-ref-dom own "workspace-canvas")] ;; Set initial scroll position - (set! (.-scrollLeft dom) (* wb/canvas-start-scroll-x @wb/zoom-l)) - (set! (.-scrollTop dom) (* wb/canvas-start-scroll-y @wb/zoom-l)) + (set! (.-scrollLeft dom) (* c/canvas-start-scroll-x @wb/zoom-l)) + (set! (.-scrollTop dom) (* c/canvas-start-scroll-y @wb/zoom-l)) (assoc own ::sub1 sub1 ::sub2 sub2))) @@ -89,8 +97,8 @@ (rs/emit! (dw/decrease-zoom))) (let [dom (mx/get-ref-dom own "workspace-canvas")] - (set! (.-scrollLeft dom) (* wb/canvas-start-scroll-x @wb/zoom-l)) - (set! (.-scrollTop dom) (* wb/canvas-start-scroll-y @wb/zoom-l))))) + (set! (.-scrollLeft dom) (* c/canvas-start-scroll-x @wb/zoom-l)) + (set! (.-scrollTop dom) (* c/canvas-start-scroll-y @wb/zoom-l))))) (defn- workspace-render [own projectid] diff --git a/src/uxbox/ui/workspace/base.cljs b/src/uxbox/ui/workspace/base.cljs index ffca0c1e6..b1c1c49c1 100644 --- a/src/uxbox/ui/workspace/base.cljs +++ b/src/uxbox/ui/workspace/base.cljs @@ -113,14 +113,3 @@ (rx/buffer 2 1) (rx/map coords-delta) (rx/share))) - -;; --- Constants - -(def ^:const viewport-width 4000) -(def ^:const viewport-height 4000) - -(def ^:const canvas-start-x 1200) -(def ^:const canvas-start-y 1200) -(def ^:const canvas-scroll-padding 50) -(def ^:const canvas-start-scroll-x (- canvas-start-x canvas-scroll-padding)) -(def ^:const canvas-start-scroll-y (- canvas-start-y canvas-scroll-padding)) diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index e5e382901..794e35453 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -11,6 +11,7 @@ [beicon.core :as rx] [lentes.core :as l] [goog.events :as events] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.shapes :as sh] [uxbox.data.projects :as dp] @@ -58,8 +59,8 @@ (let [workspace (rum/react uuwb/workspace-l) flags (:flags workspace)] (html - [:svg.page-canvas {:x uuwb/canvas-start-x - :y uuwb/canvas-start-y + [:svg.page-canvas {:x c/canvas-start-x + :y c/canvas-start-y :ref (str "canvas" id) :width width :height height} @@ -101,8 +102,8 @@ (uuc/release-action! "ui.shape" "ui.selrect"))] (html - [:svg.viewport {:width (* uuwb/viewport-width zoom) - :height (* uuwb/viewport-height zoom) + [:svg.viewport {:width (* c/viewport-width zoom) + :height (* c/viewport-height zoom) :ref "viewport" :class (when drawing? "drawing") :on-mouse-down on-mouse-down diff --git a/src/uxbox/ui/workspace/grid.cljs b/src/uxbox/ui/workspace/grid.cljs index a76c11c1b..e58557058 100644 --- a/src/uxbox/ui/workspace/grid.cljs +++ b/src/uxbox/ui/workspace/grid.cljs @@ -9,6 +9,7 @@ (:require [sablono.core :as html :refer-macros [html]] [rum.core :as rum] [cuerdas.core :as str] + [uxbox.constants :as c] [uxbox.ui.mixins :as mx] [uxbox.ui.workspace.base :as wb])) @@ -21,14 +22,14 @@ [own] (let [options (:options @wb/page-l) color (:grid/color options "#cccccc") - width wb/viewport-width - height wb/viewport-height - x-ticks (range (- 0 wb/canvas-start-x) - (- width wb/canvas-start-x) + width c/viewport-width + height c/viewport-height + x-ticks (range (- 0 c/canvas-start-x) + (- width c/canvas-start-x) (:grid/x-axis options 10)) - y-ticks (range (- 0 wb/canvas-start-x) - (- height wb/canvas-start-x) + y-ticks (range (- 0 c/canvas-start-x) + (- height c/canvas-start-x) (:grid/y-axis options 10)) path (as-> [] $ @@ -48,10 +49,10 @@ (defn- horizontal-line [width acc value] - (let [pos (+ value wb/canvas-start-y)] + (let [pos (+ value c/canvas-start-y)] (conj acc (str/format "M %s %s L %s %s" 0 pos width pos)))) (defn- vertical-line [height acc value] - (let [pos (+ value wb/canvas-start-y)] + (let [pos (+ value c/canvas-start-y)] (conj acc (str/format "M %s %s L %s %s" pos 0 pos height)))) diff --git a/src/uxbox/ui/workspace/ruler.cljs b/src/uxbox/ui/workspace/ruler.cljs index 7868e2206..0afe957e9 100644 --- a/src/uxbox/ui/workspace/ruler.cljs +++ b/src/uxbox/ui/workspace/ruler.cljs @@ -9,6 +9,7 @@ (:require [sablono.core :as html :refer-macros [html]] [rum.core :as rum] [beicon.core :as rx] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.util.math :as mth] [uxbox.ui.workspace.base :as wb] @@ -104,8 +105,8 @@ [:rect {:style {:fill "transparent" :stroke "transparent" :cursor "cell"} - :width wb/viewport-width - :height wb/viewport-height}] + :width c/viewport-width + :height c/viewport-height}] (if (and p1 p2) (overlay-line-render own p1 p2))]))) diff --git a/src/uxbox/ui/workspace/rules.cljs b/src/uxbox/ui/workspace/rules.cljs index f3c5e83f7..71062b1ae 100644 --- a/src/uxbox/ui/workspace/rules.cljs +++ b/src/uxbox/ui/workspace/rules.cljs @@ -10,6 +10,7 @@ [rum.core :as rum] [cuerdas.core :as str] [beicon.core :as rx] + [uxbox.constants :as c] [uxbox.state :as s] [uxbox.util.dom :as dom] [uxbox.ui.workspace.base :as wb] @@ -24,8 +25,8 @@ (defn mid-ticks-mod [zoom] (/ 50 zoom)) (def ^:const +ticks+ - (concat (range (- (/ wb/viewport-width 1)) 0 step-size) - (range 0 (/ wb/viewport-width 1) step-size))) + (concat (range (- (/ c/viewport-width 1)) 0 step-size) + (range 0 (/ c/viewport-width 1) step-size))) (def ^:const rule-padding 20) @@ -35,8 +36,8 @@ mid-ticks-mod (mid-ticks-mod zoom) pos (+ (* value zoom) rule-padding - (* wb/canvas-start-x zoom) - wb/canvas-scroll-padding)] + (* c/canvas-start-x zoom) + c/canvas-scroll-padding)] (cond (< (mod value big-ticks-mod) step-size) (conj acc (str/format "M %s %s L %s %s" pos 5 pos step-padding)) @@ -52,8 +53,8 @@ (let [big-ticks-mod (big-ticks-mod zoom) mid-ticks-mod (mid-ticks-mod zoom) pos (+ (* value zoom) - (* wb/canvas-start-x zoom) - wb/canvas-scroll-padding)] + (* c/canvas-start-x zoom) + c/canvas-scroll-padding)] (cond (< (mod value big-ticks-mod) step-size) (conj acc (str/format "M %s %s L %s %s" 5 pos step-padding pos)) @@ -71,8 +72,8 @@ (let [big-ticks-mod (big-ticks-mod zoom) pos (+ (* value zoom) rule-padding - (* wb/canvas-start-x zoom) - wb/canvas-scroll-padding)] + (* c/canvas-start-x zoom) + c/canvas-scroll-padding)] (when (< (mod value big-ticks-mod) step-size) (html [:text {:x (+ pos 2) @@ -88,9 +89,9 @@ [zoom value] (let [big-ticks-mod (big-ticks-mod zoom) pos (+ (* value zoom) - (* wb/canvas-start-x zoom) - ;; wb/canvas-start-x - wb/canvas-scroll-padding)] + (* c/canvas-start-x zoom) + ;; c/canvas-start-x + c/canvas-scroll-padding)] (when (< (mod value big-ticks-mod) step-size) (html [:text {:y (- pos 3) @@ -145,10 +146,10 @@ [own zoom] (let [scroll (rum/react wb/scroll-a) scroll-x (:x scroll) - translate-x (- (- wb/canvas-scroll-padding) (:x scroll))] + translate-x (- (- c/canvas-scroll-padding) (:x scroll))] (html [:svg.horizontal-rule - {:width wb/viewport-width + {:width c/viewport-width :height 20} [:g {:transform (str "translate(" translate-x ", 0)")} (horizontal-rule-ticks zoom)]]))) @@ -165,11 +166,11 @@ [own zoom] (let [scroll (rum/react wb/scroll-a) scroll-y (:y scroll) - translate-y (- (- wb/canvas-scroll-padding) (:y scroll))] + translate-y (- (- c/canvas-scroll-padding) (:y scroll))] (html [:svg.vertical-rule {:width 20 - :height wb/viewport-height} + :height c/viewport-height} [:g {:transform (str "translate(0, " translate-y ")")} (vertical-rule-ticks zoom)] diff --git a/src/uxbox/ui/workspace/scroll.cljs b/src/uxbox/ui/workspace/scroll.cljs index 121e79afa..fcc3a1698 100644 --- a/src/uxbox/ui/workspace/scroll.cljs +++ b/src/uxbox/ui/workspace/scroll.cljs @@ -9,6 +9,7 @@ (:require-macros [uxbox.util.syntax :refer [define-once]]) (:require [beicon.core :as rx] [lentes.core :as l] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.state :as ust] [uxbox.data.shapes :as uds] diff --git a/src/uxbox/ui/workspace/selrect.cljs b/src/uxbox/ui/workspace/selrect.cljs index 00b2574c3..a1a168440 100644 --- a/src/uxbox/ui/workspace/selrect.cljs +++ b/src/uxbox/ui/workspace/selrect.cljs @@ -10,6 +10,7 @@ (:require [sablono.core :as html :refer-macros [html]] [rum.core :as rum] [beicon.core :as rx] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.shapes :as sh] [uxbox.data.workspace :as dw] @@ -79,8 +80,8 @@ "Translate the given rect to the canvas coordinates system." [rect] (let [zoom @wb/zoom-l - startx (* wb/canvas-start-x zoom) - starty (* wb/canvas-start-y zoom)] + startx (* c/canvas-start-x zoom) + starty (* c/canvas-start-y zoom)] (assoc rect :x (- (:x rect) startx) :y (- (:y rect) starty) From b92034218817925c1d90e12aa9077666a9c7dde0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:22:40 +0300 Subject: [PATCH 17/19] Use constants on workspace settings lightbox. --- src/uxbox/ui/workspace/settings.cljs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uxbox/ui/workspace/settings.cljs b/src/uxbox/ui/workspace/settings.cljs index 489d314cb..fecf67e00 100644 --- a/src/uxbox/ui/workspace/settings.cljs +++ b/src/uxbox/ui/workspace/settings.cljs @@ -9,6 +9,7 @@ (:require [sablono.core :as html :refer-macros [html]] [lentes.core :as l] [rum.core :as rum] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.data.pages :as udp] [uxbox.ui.icons :as i] @@ -55,15 +56,14 @@ [:input#grid-x.input-text {:placeholder "X px" :type "number" - ;; TODO: put here the default from constants - :value (:grid/x-axis opts "10") + :value (:grid/x-axis opts c/grid-x-axis) :on-change (partial on-field-change :grid/x-axis) - :min 1 ;;TODO check this value + :min 1 :max 100}] [:input#grid-y.input-text {:placeholder "Y px" :type "number" - :value (:grid/y-axis opts "10") + :value (:grid/y-axis opts c/grid-y-axis) :on-change (partial on-field-change :grid/y-axis) :min 1 :max 100}]] From 051163c3ae1e50d6534487d017d452164b26264c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:44:12 +0300 Subject: [PATCH 18/19] Add webworkers architecture (rcp). --- scripts/figwheel.clj | 20 +++++++++++++++++--- src/uxbox/worker.cljs | 21 +++++++++++++++++++++ src/uxbox/worker/core.cljs | 31 +++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 src/uxbox/worker.cljs create mode 100644 src/uxbox/worker/core.cljs diff --git a/scripts/figwheel.clj b/scripts/figwheel.clj index 599c6fa73..2ed5f7fd7 100644 --- a/scripts/figwheel.clj +++ b/scripts/figwheel.clj @@ -7,7 +7,7 @@ (ra/start-figwheel! {:figwheel-options {:css-dirs ["resources/public/css"]} - :build-ids ["dev"] + :build-ids ["dev" "worker"] :all-builds [{:id "dev" :figwheel {:on-jsload "uxbox.ui/init"} @@ -20,10 +20,24 @@ "https://test.uxbox.io/api"} :warnings {:ns-var-clash false} :pretty-print true - :language-in :ecmascript5 + :language-in :ecmascript6 :language-out :ecmascript5 :output-to "resources/public/js/main.js" :output-dir "resources/public/js" + :verbose true}} + + {:id "worker" + :source-paths ["src" "vendor"] + :compiler {:main 'uxbox.worker + :asset-path "js" + :parallel-build false + :optimizations :simple + :warnings {:ns-var-clash false} + :pretty-print true + :static-fns true + :language-in :ecmascript6 + :language-out :ecmascript5 + :output-to "resources/public/js/worker.js" :verbose true}}]}) -(ra/cljs-repl) +(ra/cljs-repl "dev") diff --git a/src/uxbox/worker.cljs b/src/uxbox/worker.cljs new file mode 100644 index 000000000..4db0d390f --- /dev/null +++ b/src/uxbox/worker.cljs @@ -0,0 +1,21 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.worker + (:require [beicon.core :as rx] + [uxbox.util.transit :as t] + [uxbox.worker.core :as wrk] + [uxbox.worker.align])) + +(enable-console-print!) + +(defn- on-message + [event] + (let [message (t/decode (.-data event))] + (wrk/handler message))) + +(defonce _ + (.addEventListener js/self "message" on-message)) diff --git a/src/uxbox/worker/core.cljs b/src/uxbox/worker/core.cljs new file mode 100644 index 000000000..43988fb93 --- /dev/null +++ b/src/uxbox/worker/core.cljs @@ -0,0 +1,31 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.worker.core + (:require [uxbox.util.transit :as t])) + +(enable-console-print!) + +;; --- Handler + +(defmulti handler :cmd) + +(defmethod handler :default + [message] + (println "Unexpected message:" message)) + +;; --- Helpers + +(defn worker? + "Check if the code is executed in webworker context." + [] + (undefined? (.-document js/self))) + +(defn reply! + [sender message] + (let [message (assoc message :reply-to sender)] + (println "replying " message) + (.postMessage js/self (t/encode message)))) From 935bafd512024b6fdca3a0f77cb6d23a6f7480a0 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sun, 10 Apr 2016 18:45:20 +0300 Subject: [PATCH 19/19] Add initial approach for grid alignment. A little bit buggy because the main algorithm does not works well. --- src/uxbox/data/worker.cljs | 32 ++++++++++++++ src/uxbox/data/workspace.cljs | 44 ++++++++++++-------- src/uxbox/ui/workspace/align.cljs | 37 +++++++++++++++++ src/uxbox/ui/workspace/movement.cljs | 55 +++++++++++++++++++++++- src/uxbox/util/workers.cljs | 62 ++++++++++++++++++++++++++++ src/uxbox/worker/align.cljs | 34 +++++++++++++++ 6 files changed, 245 insertions(+), 19 deletions(-) create mode 100644 src/uxbox/data/worker.cljs create mode 100644 src/uxbox/ui/workspace/align.cljs create mode 100644 src/uxbox/util/workers.cljs create mode 100644 src/uxbox/worker/align.cljs diff --git a/src/uxbox/data/worker.cljs b/src/uxbox/data/worker.cljs new file mode 100644 index 000000000..6a549362c --- /dev/null +++ b/src/uxbox/data/worker.cljs @@ -0,0 +1,32 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.data.worker + "Worker related api and initialization events." + (:require [beicon.core :as rx] + [uxbox.rstore :as rs] + [uxbox.constants :as c] + [uxbox.util.workers :as uw])) + +(defonce worker (uw/init "/js/worker.js")) + +;; --- Worker Initialization + +(defrecord InitializeWorker [id] + rs/EffectEvent + (-apply-effect [_ state] + (let [page (get-in state [:pages-by-id id]) + opts (:options page) + message {:cmd :grid/init + :width c/viewport-width + :height c/viewport-height + :x-axis (:grid/x-axis opts c/grid-x-axis) + :y-axis (:grid/y-axis opts c/grid-y-axis)}] + (uw/send! worker message)))) + +(defn initialize + [id] + (InitializeWorker. id)) diff --git a/src/uxbox/data/workspace.cljs b/src/uxbox/data/workspace.cljs index af6af7891..445013b05 100644 --- a/src/uxbox/data/workspace.cljs +++ b/src/uxbox/data/workspace.cljs @@ -14,31 +14,41 @@ [uxbox.schema :as sc] [uxbox.data.pages :as udp] [uxbox.data.shapes :as uds] - ;; [uxbox.data.worker :as wrk] + [uxbox.data.worker :as wrk] [uxbox.util.datetime :as dt] [uxbox.util.geom.point :as gpt])) ;; --- Workspace Initialization +(defrecord InitializeWorkspace [project page] + rs/UpdateEvent + (-apply-update [_ state] + (if (:workspace state) + (update state :workspace merge + {:project project + :page page + :selected #{} + :drawing nil}) + (assoc state :workspace + {:project project + :zoom 1 + :page page + :flags #{:layers :element-options} + :selected #{} + :drawing nil}))) + + rs/WatchEvent + (-apply-watch [_ state s] + (if (get-in state [:pages-by-id page]) + (rx/of (wrk/initialize page)) + (->> (rx/filter udp/pages-fetched? s) + (rx/take 1) + (rx/map #(wrk/initialize page)))))) + (defn initialize "Initialize the workspace state." [project page] - (reify - rs/UpdateEvent - (-apply-update [_ state] - (if (:workspace state) - (update state :workspace merge - {:project project - :page page - :selected #{} - :drawing nil}) - (assoc state :workspace - {:project project - :zoom 1 - :page page - :flags #{:layers :element-options} - :selected #{} - :drawing nil}))))) + (InitializeWorkspace. project page)) (defn toggle-flag "Toggle the enabled flag of the specified tool." diff --git a/src/uxbox/ui/workspace/align.cljs b/src/uxbox/ui/workspace/align.cljs new file mode 100644 index 000000000..d57eca2ce --- /dev/null +++ b/src/uxbox/ui/workspace/align.cljs @@ -0,0 +1,37 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.ui.workspace.align + "Shape alignmen impl." + (:require [beicon.core :as rx] + [lentes.core :as l] + [uxbox.state :as st] + [uxbox.shapes :as sh] + [uxbox.data.worker :refer (worker)] + [uxbox.ui.workspace.base :as wb] + [uxbox.util.geom.point :as gpt] + [uxbox.util.workers :as uw])) + +(defn- move + [shape p1] + (let [dx (- (:x2 shape) (:x1 shape)) + dy (- (:y2 shape) (:y1 shape)) + p2 (gpt/add p1 [dx dy])] + (assoc shape + :x1 (:x p1) + :y1 (:y p1) + :x2 (:x p2) + :y2 (:y p2)))) + +(defn translate + [{:keys [x1 y1] :as shape}] + (let [message {:cmd :grid/align + :point (gpt/point x1 y1)}] + (->> (uw/ask! worker message) + (rx/map (fn [{:keys [point]}] + (if point + (move shape point) + shape)))))) diff --git a/src/uxbox/ui/workspace/movement.cljs b/src/uxbox/ui/workspace/movement.cljs index b80d30485..364994cad 100644 --- a/src/uxbox/ui/workspace/movement.cljs +++ b/src/uxbox/ui/workspace/movement.cljs @@ -9,6 +9,7 @@ "Shape movement in workspace logic." (:require [beicon.core :as rx] [lentes.core :as l] + [uxbox.constants :as c] [uxbox.rstore :as rs] [uxbox.state :as st] [uxbox.shapes :as sh] @@ -23,16 +24,24 @@ ;; --- Lenses +(declare translate-to-viewport) + (defn- resolve-selected [state] (let [selected (get-in state [:workspace :selected]) - xf (map #(get-in state [:shapes-by-id %]))] + xf (comp + (map #(get-in state [:shapes-by-id %])) + (map translate-to-viewport))] (into #{} xf selected))) (def ^:const ^:private selected-shapes-l (-> (l/getter resolve-selected) (l/focus-atom st/state))) +(def ^:const ^:privae page-options-l + (-> (l/key :options) + (l/focus-atom wb/page-l))) + ;; --- Public Api (defn watch-move-actions @@ -43,9 +52,40 @@ ;; --- Implementation +(def coords + (gpt/point c/canvas-start-x + c/canvas-start-y)) + +(defn- translate-to-viewport + [shape] + (let [dx (- (:x2 shape) (:x1 shape)) + dy (- (:y2 shape) (:y1 shape)) + p1 (gpt/point (:x1 shape) (:y1 shape)) + p2 (gpt/add p1 coords) + p3 (gpt/add p2 [dx dy])] + (assoc shape + :x1 (:x p2) + :y1 (:y p2) + :x2 (:x p3) + :y2 (:y p3)))) + +(defn- translate-to-canvas + [shape] + (let [dx (- (:x2 shape) (:x1 shape)) + dy (- (:y2 shape) (:y1 shape)) + p1 (gpt/point (:x1 shape) (:y1 shape)) + p2 (gpt/subtract p1 coords) + p3 (gpt/add p2 [dx dy])] + (assoc shape + :x1 (:x p2) + :y1 (:y p2) + :x2 (:x p3) + :y2 (:y p3)))) + (defn- initialize [] (let [shapes @selected-shapes-l + options @page-options-l stoper (->> uuc/actions-s (rx/map :type) (rx/filter empty?) @@ -53,7 +93,17 @@ (as-> wb/mouse-delta-s $ (rx/take-until stoper $) (rx/scan (fn [acc delta] - (mapv #(sh/move % delta) acc)) shapes $) + (let [xf (map #(sh/move % delta))] + (into [] xf acc))) shapes $) + (rx/mapcat (fn [items] + (if (:grid/align options) + (->> (apply rx/of items) + (rx/mapcat align/translate) + (rx/reduce conj [])) + (rx/of items))) $) + (rx/map (fn [items] + (mapv translate-to-canvas items)) $) + (rx/subscribe $ handle-movement)))) (defn- handle-movement @@ -61,3 +111,4 @@ (doseq [shape delta] (rs/emit! (uds/update-shape shape)))) + diff --git a/src/uxbox/util/workers.cljs b/src/uxbox/util/workers.cljs new file mode 100644 index 000000000..e96b9a1dd --- /dev/null +++ b/src/uxbox/util/workers.cljs @@ -0,0 +1,62 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.util.workers + "A lightweight layer on top of webworkers api." + (:require [beicon.core :as rx] + [uxbox.util.transit :as t])) + +;; --- Implementation + +(defprotocol IWorker + (-ask [_ msg] "Send and receive message as rx stream.") + (-send [_ msg] "Send message and forget.")) + +(deftype WebWorker [stream wrk] + IWorker + (-ask [this message] + (let [sender (random-uuid) + data (assoc message :sender sender) + data (t/encode data)] + (.postMessage wrk data) + (->> stream + (rx/filter #(= (:reply-to %) sender)) + (rx/take 1)))) + + (-send [this message] + (let [sender (random-uuid) + data (assoc message :sender sender) + data (t/encode data)] + (.postMessage wrk data) + (->> stream + (rx/filter #(= (:reply-to %) sender)))))) + +;; --- Public Api + +(defn init + "Return a initialized webworker instance." + [path] + (let [wrk (js/Worker. path) + bus (rx/bus)] + (.addEventListener wrk "message" + (fn [event] + (let [data (.-data event) + data (t/decode data)] + (rx/push! bus data)))) + (.addEventListener wrk "error" + (fn [event] + (rx/error! bus event))) + + (WebWorker. (rx/map identity bus) wrk))) + +(defn ask! + [wrk message] + (-ask wrk message)) + +(defn send! + [wrk message] + (-send wrk message)) + diff --git a/src/uxbox/worker/align.cljs b/src/uxbox/worker/align.cljs new file mode 100644 index 000000000..704fb908c --- /dev/null +++ b/src/uxbox/worker/align.cljs @@ -0,0 +1,34 @@ +;; 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) 2016 Andrey Antukh + +(ns uxbox.worker.align + "Workspace aligment indexes worker." + (:require [beicon.core :as rx] + [kdtree :as kd] + [uxbox.worker.core :as wrk] + [uxbox.util.geom.point :as gpt])) + +(defonce state (volatile! nil)) + +(defmethod wrk/handler :grid/init + [{:keys [width height x-axis y-axis] :as opts}] + (println ":grid/init" opts) + (let [points (into-array + (for [x (range 0 width (or x-axis 10)) + y (range 0 height (or y-axis 10))] + #js [x y])) + tree (kd/create2d points)] + (vreset! state tree))) + +(defmethod wrk/handler :grid/align + [{:keys [sender point] :as message}] + (println "request" point) + (let [point #js [(:x point) (:y point)] + results (js->clj (.nearest @state point 1)) + [[x y] d] (first results) + result (gpt/point x y)] + (println "result:" result) + (wrk/reply! sender {:point (gpt/point x y)})))