From 24ae745da0b403bb5133135f8a5d8e9b820f6c7c Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Sat, 30 Jan 2016 19:05:33 +0200 Subject: [PATCH] Add quick & dirty impl of ruler. --- src/uxbox/ui/workspace/canvas.cljs | 4 +- src/uxbox/ui/workspace/canvas/ruler.cljs | 97 ++++++++++++++++++++++++ src/uxbox/ui/workspace/header.cljs | 4 +- src/uxbox/ui/workspace/shortcuts.cljs | 3 +- 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 src/uxbox/ui/workspace/canvas/ruler.cljs diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index 3375a8481..5b8a42a74 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -18,6 +18,7 @@ [uxbox.ui.workspace.base :as wb] [uxbox.ui.workspace.canvas.movement] [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)] [uxbox.ui.workspace.grid :refer (grid)] @@ -202,7 +203,8 @@ :on-mouse-up on-mouse-up} [:g.zoom {:transform (str "scale(" zoom ", " zoom ")")} (if page - (canvas page))]])))) + (canvas page)) + (ruler)]])))) (def viewport (mx/component diff --git a/src/uxbox/ui/workspace/canvas/ruler.cljs b/src/uxbox/ui/workspace/canvas/ruler.cljs new file mode 100644 index 000000000..fe126eb7d --- /dev/null +++ b/src/uxbox/ui/workspace/canvas/ruler.cljs @@ -0,0 +1,97 @@ +(ns uxbox.ui.workspace.canvas.ruler + (: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.util.math :as mth] + [uxbox.ui.workspace.base :as wb] + [uxbox.ui.mixins :as mx] + [uxbox.ui.dom :as dom])) + +;; FIXME: clear & refactor (this is a first quick & dirty impl) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Component +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn- distance + [[x1 y1] [x2 y2]] + (let [dx (- x1 x2) + dy (- y1 y2)] + (-> (mth/sqrt (+ (mth/pow dx 2) (mth/pow dy 2))) + (mth/precision 2)))) + +(defn- get-position + [own event] + (let [x (.-clientX event) + y (.-clientY event) + overlay (mx/get-ref-dom own "overlay") + brect (.getBoundingClientRect overlay)] + [(- x (.-left brect)) + (- y (.-top brect))])) + +(defn- on-mouse-down + [own local event] + (dom/stop-propagation event) + (let [pos (get-position own event)] + (swap! local assoc + :active true + :pos1 pos + :pos2 pos))) + +(defn- on-mouse-up + [own local event] + (dom/stop-propagation event) + (swap! local assoc + :active false + :pos1 nil + :pos2 nil)) + +(defn- on-mouse-move + [own local event] + (when (:active @local) + (let [pos (get-position own event)] + (swap! local assoc :pos2 pos)))) + +(defn overlay-render + [own] + (let [local (:rum/local own) + [x1 y1 :as p1] (:pos1 @local) + [x2 y2 :as p2] (:pos2 @local) + distance (distance p1 p2)] + (html + [:svg {:on-mouse-down #(on-mouse-down own local %) + :on-mouse-up #(on-mouse-up own local %) + :on-mouse-move #(on-mouse-move own local %) + :ref "overlay"} + [:rect {:style {:fill "transparent" :stroke "transparent" :cursor "cell"} + :width wb/viewport-width + :height wb/viewport-height}] + (if (and (:active @local) x1 x2) + [:g + [:line {:x1 x1 + :y1 y1 + :x2 x2 + :y2 y2 + :style {:cursor "cell"} + :stroke-width "2" + :stroke "red"}] + [:text {:x (+ x2 15) :y y2} + [:tspan (str distance)]]])]))) + +(defn- ruler-render + [own] + (let [flags (rum/react wb/flags-l)] + (when (contains? flags :workspace/ruler) + (overlay-render own)))) + +(def ^:static ruler + (mx/component + {:render ruler-render + :name "ruler" + :mixins [mx/static rum/reactive (mx/local)]})) diff --git a/src/uxbox/ui/workspace/header.cljs b/src/uxbox/ui/workspace/header.cljs index 289147892..32f3bbe26 100644 --- a/src/uxbox/ui/workspace/header.cljs +++ b/src/uxbox/ui/workspace/header.cljs @@ -53,7 +53,9 @@ i/image]] [:ul.options-btn [:li.tooltip.tooltip-bottom - {:alt "Ruler (Ctrl + R)"} + {:alt "Ruler (Ctrl + R)" + :class (when (contains? flags :workspace/ruler) "selected") + :on-click (partial toggle :workspace/ruler)} i/ruler] [:li.tooltip.tooltip-bottom {:alt "Grid (Ctrl + G)" diff --git a/src/uxbox/ui/workspace/shortcuts.cljs b/src/uxbox/ui/workspace/shortcuts.cljs index 981bb489d..2c4e9da98 100644 --- a/src/uxbox/ui/workspace/shortcuts.cljs +++ b/src/uxbox/ui/workspace/shortcuts.cljs @@ -14,10 +14,11 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defonce ^:static +shortcuts+ - {:ctrl+g #(rs/emit! (dw/toggle-tool :grid)) + {:ctrl+g #(rs/emit! (dw/toggle-tool :workspace/grid)) :ctrl+shift+f #(rs/emit! (dw/toggle-toolbox :draw)) :ctrl+shift+i #(rs/emit! (dw/toggle-toolbox :icons)) :ctrl+shift+l #(rs/emit! (dw/toggle-toolbox :layers)) + :ctrl+r #(rs/emit! (dw/toggle-tool :workspace/ruler)) :esc #(rs/emit! (dw/deselect-all)) :backspace #(rs/emit! (dw/delete-selected)) :delete #(rs/emit! (dw/delete-selected))