diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index 90492d4ad..12533631a 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -827,6 +827,52 @@ ;; (->> (uwrk/initialize-alignment params) ;; (rx/map #(activate-flag :grid-indexed)))))))) +;; --- Selection Rect + +(declare select-shapes-by-current-selrect) +(declare deselect-all) + +(defn update-selrect + [selrect] + (ptk/reify ::update-selrect + ptk/UpdateEvent + (update [_ state] + (assoc-in state [:workspace-local :selrect] selrect)))) + +(def handle-selection + (letfn [(data->selrect [data] + (let [start (:start data) + stop (:stop data) + start-x (min (:x start) (:x stop)) + start-y (min (:y start) (:y stop)) + end-x (max (:x start) (:x stop)) + end-y (max (:y start) (:y stop))] + {:type :rect + :x start-x + :y start-y + :width (- end-x start-x) + :height (- end-y start-y)}))] + (ptk/reify ::handle-selection + ptk/WatchEvent + (watch [_ state stream] + (let [stoper (rx/filter #(or (interrupt? %) + (ms/mouse-up? %)) + stream)] + (rx/concat + (rx/of deselect-all) + (->> ms/mouse-position + (rx/scan (fn [data pos] + (if data + (assoc data :stop pos) + {:start pos :stop pos})) + nil) + (rx/map data->selrect) + (rx/map update-selrect) + (rx/take-until stoper)) + (rx/of select-shapes-by-current-selrect + (update-selrect nil)))))))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Shapes events ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/uxbox/main/ui/workspace/viewport.cljs b/frontend/src/uxbox/main/ui/workspace/viewport.cljs index 3c308b8ac..2e86bd980 100644 --- a/frontend/src/uxbox/main/ui/workspace/viewport.cljs +++ b/frontend/src/uxbox/main/ui/workspace/viewport.cljs @@ -10,8 +10,8 @@ [beicon.core :as rx] [goog.events :as events] [goog.object :as gobj] - [potok.core :as ptk] [lentes.core :as l] + [potok.core :as ptk] [rumext.alpha :as mf] [uxbox.builtins.icons :as i] [uxbox.main.constants :as c] @@ -21,17 +21,17 @@ [uxbox.main.store :as st] [uxbox.main.streams :as ms] [uxbox.main.ui.keyboard :as kbd] - [uxbox.main.ui.workspace.grid :refer [grid]] - [uxbox.main.ui.workspace.ruler :refer [ruler]] - [uxbox.main.ui.workspace.drawarea :refer [start-drawing]] + [uxbox.main.ui.react-hooks :refer [use-rxsub]] [uxbox.main.ui.shapes :refer [shape-wrapper frame-wrapper]] [uxbox.main.ui.workspace.drawarea :refer [draw-area]] + [uxbox.main.ui.workspace.drawarea :refer [start-drawing]] + [uxbox.main.ui.workspace.grid :refer [grid]] + [uxbox.main.ui.workspace.ruler :refer [ruler]] [uxbox.main.ui.workspace.selection :refer [selection-handlers]] - [uxbox.main.ui.react-hooks :refer [use-rxsub]] - [uxbox.util.perf :as perf] - [uxbox.util.uuid :as uuid] [uxbox.util.dom :as dom] - [uxbox.util.geom.point :as gpt]) + [uxbox.util.geom.point :as gpt] + [uxbox.util.perf :as perf] + [uxbox.util.uuid :as uuid]) (:import goog.events.EventType)) ;; --- Coordinates Widget @@ -73,45 +73,7 @@ ;; --- Selection Rect -(defn- selection->rect - [data] - (let [start (:start data) - stop (:stop data) - start-x (min (:x start) (:x stop)) - start-y (min (:y start) (:y stop)) - end-x (max (:x start) (:x stop)) - end-y (max (:y start) (:y stop))] - (assoc data - :type :rect - :x start-x - :y start-y - :width (- end-x start-x) - :height (- end-y start-y)))) - -(def ^:private handle-selrect - (letfn [(update-state [state position] - (let [selrect (get-in state [:workspace-local :selrect])] - (if selrect - (assoc-in state [:workspace-local :selrect] - (selection->rect (assoc selrect :stop position))) - (assoc-in state [:workspace-local :selrect] - (selection->rect {:start position :stop position}))))) - - (clear-state [state] - (update state :workspace-local dissoc :selrect))] - (ptk/reify ::handle-selrect - ptk/WatchEvent - (watch [_ state stream] - (let [stoper (rx/filter #(or (dw/interrupt? %) (ms/mouse-up? %)) stream)] - (rx/concat - (rx/of dw/deselect-all) - (->> ms/mouse-position - (rx/map (fn [pos] #(update-state % pos))) - (rx/take-until stoper)) - (rx/of dw/select-shapes-by-current-selrect - clear-state))))))) - -(mf/defc selrect +(mf/defc selection-rect {:wrap [mf/wrap-memo]} [{:keys [data] :as props}] (when data @@ -144,13 +106,7 @@ (declare remote-user-cursors) (declare frames) -(defn- build-workspace-data-iref - [page-id] - (-> (l/in [:workspace-data page-id]) - (l/derive st/state))) - (mf/defrc frames-wrapper - ;; {:wrap [mf/wrap-memo]} [props] (let [page (gobj/get props "page") page-id (:id page) @@ -187,6 +143,8 @@ selected] :as local} (mf/deref refs/workspace-local) viewport-ref (mf/use-ref nil) + last-position (mf/use-var nil) + zoom (or zoom 1) on-mouse-down @@ -196,11 +154,12 @@ shift? (kbd/shift? event) opts {:shift? shift? :ctrl? ctrl?}] - (st/emit! (ms/->MouseEvent :down ctrl? shift?))) - (when (not edition) - (if drawing-tool - (st/emit! (start-drawing drawing-tool)) - (st/emit! handle-selrect)))) + (st/emit! (ms/->MouseEvent :down ctrl? shift?)) + (when (and (not edition) + (= 1 (.-which (.-nativeEvent event)))) + (if drawing-tool + (st/emit! (start-drawing drawing-tool)) + (st/emit! dw/handle-selection))))) on-context-menu (fn [event] @@ -337,7 +296,7 @@ [:& ruler {:zoom zoom :ruler (:ruler local)}]) [:& remote-user-cursors {:page page}] - [:& selrect {:data (:selrect local)}]]])) + [:& selection-rect {:data (:selrect local)}]]])) (mf/defc remote-user-cursor