Improved action stacking.

This commit is contained in:
Andrey Antukh 2016-03-18 18:32:42 +02:00
parent e6161a0f62
commit f5f4e0f0fe
9 changed files with 45 additions and 46 deletions

View file

@ -1,29 +1,26 @@
(ns uxbox.ui.core (ns uxbox.ui.core
(:require [beicon.core :as rx])) (:require [beicon.core :as rx]
[cuerdas.core :as str]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Actions ;; Actions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defonce actions-lock (atom :nothing)) (defonce lock (atom ""))
(defonce actions-s (rx/bus)) (defonce actions-s (rx/bus))
;; TODO: implement that as multimethod for add specific validation
;; layer for different kind of action payloads
(defn acquire-action! (defn acquire-action!
([type] ([type]
(acquire-action! type nil)) (acquire-action! type nil))
([type payload] ([type payload]
(when-let [result (compare-and-set! actions-lock :nothing type)] (when (empty? @lock)
(reset! lock type)
(rx/push! actions-s {:type type :payload payload})))) (rx/push! actions-s {:type type :payload payload}))))
(defn release-action! (defn release-action!
[type] ([type]
(when-let [result (compare-and-set! actions-lock type :nothing)] (when (str/contains? @lock type)
(rx/push! actions-s {:type :nothing}))) (rx/push! actions-s {:type ""})
(reset! lock "")))
(defn release-all-actions! ([type & more]
[] (run! release-action! (cons type more))))
(reset! actions-lock :nothing)
(rx/push! actions-s {:type :nothing}))

View file

@ -43,11 +43,12 @@
[own shape] [own shape]
(letfn [(on-mouse-down [vid event] (letfn [(on-mouse-down [vid event]
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :resize/shape {:vid vid :shape (:id shape)})) (uuc/acquire-action! "ui.shape.resize"
{:vid vid :shape (:id shape)}))
(on-mouse-up [vid event] (on-mouse-up [vid event]
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/release-action! :resize/shape))] (uuc/release-action! "ui.shape.resize"))]
(let [{:keys [x y width height]} (ush/outer-rect' shape)] (let [{:keys [x y width height]} (ush/outer-rect' shape)]
(html (html
[:g.controls [:g.controls

View file

@ -28,7 +28,7 @@
(and (not selected?) (empty? selected)) (and (not selected?) (empty? selected))
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :shape/movement) (uuc/acquire-action! "ui.shape.move")
(rs/emit! (dw/select-shape id))) (rs/emit! (dw/select-shape id)))
(and (not selected?) (not (empty? selected))) (and (not selected?) (not (empty? selected)))
@ -42,7 +42,7 @@
:else :else
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :shape/movement)))))) (uuc/acquire-action! "ui.shape.move"))))))
(defn on-mouse-up (defn on-mouse-up
[event {:keys [id group] :as shape}] [event {:keys [id group] :as shape}]
@ -53,7 +53,7 @@
:else :else
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/release-all-actions!)))) (uuc/release-action! "ui.shape"))))
(declare handlers) (declare handlers)
@ -80,11 +80,12 @@
[own shape] [own shape]
(letfn [(on-mouse-down [vid event] (letfn [(on-mouse-down [vid event]
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :resize/shape {:vid vid :shape (:id shape)})) (uuc/acquire-action! "ui.shape.resize"
{:vid vid :shape (:id shape)}))
(on-mouse-up [vid event] (on-mouse-up [vid event]
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/release-action! :resize/shape))] (uuc/release-action! "ui.shape.resize"))]
(let [{:keys [x y width height]} (ush/outer-rect' shape)] (let [{:keys [x y width height]} (ush/outer-rect' shape)]
(html (html
[:g.controls [:g.controls

View file

@ -33,7 +33,7 @@
(and (not selected?) (empty? selected)) (and (not selected?) (empty? selected))
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :shape/movement) (uuc/acquire-action! "ui.shape.move")
(rs/emit! (dw/select-shape id))) (rs/emit! (dw/select-shape id)))
(and (not selected?) (not (empty? selected))) (and (not selected?) (not (empty? selected)))
@ -47,7 +47,7 @@
:else :else
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/acquire-action! :shape/movement)))))) (uuc/acquire-action! "ui.shape.move"))))))
(defn on-mouse-up (defn on-mouse-up
[event {:keys [id group] :as shape}] [event {:keys [id group] :as shape}]
@ -58,7 +58,7 @@
:else :else
(do (do
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/release-all-actions!)))) (uuc/release-action! "ui.shape"))))
(defn- text-component-did-mount (defn- text-component-did-mount
[own] [own]
@ -66,14 +66,14 @@
(let [container (mx/get-ref-dom own "container") (let [container (mx/get-ref-dom own "container")
local (:rum/local own)] local (:rum/local own)]
(swap! local assoc :edition true) (swap! local assoc :edition true)
(uuc/acquire-action! ::edition) (uuc/acquire-action! "ui.text.edit")
(set! (.-contentEditable container) true) (set! (.-contentEditable container) true)
(.setAttribute container "contenteditable" "true") (.setAttribute container "contenteditable" "true")
(.focus container))) (.focus container)))
(on-blur [ev] (on-blur [ev]
(let [container (mx/get-ref-dom own "container") (let [container (mx/get-ref-dom own "container")
local (:rum/local own)] local (:rum/local own)]
(uuc/release-action! ::edition) (uuc/release-action! "ui.text.edit")
(swap! local assoc :edition false) (swap! local assoc :edition false)
(set! (.-contentEditable container) false) (set! (.-contentEditable container) false)
(.removeAttribute container "contenteditable"))) (.removeAttribute container "contenteditable")))

View file

@ -92,11 +92,12 @@
(when-not (empty? (:selected workspace)) (when-not (empty? (:selected workspace))
(rs/emit! (dw/deselect-all))) (rs/emit! (dw/deselect-all)))
(if-let [shape (:drawing workspace)] (if-let [shape (:drawing workspace)]
(uuc/acquire-action! :draw/shape) (uuc/acquire-action! "ui.shape.draw")
(uuc/acquire-action! :draw/selrect))) (uuc/acquire-action! "ui.selrect")))
(on-mouse-up [event] (on-mouse-up [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(uuc/release-all-actions!))] (uuc/release-action! "ui.shape"
"ui.selrect"))]
(html (html
[:svg.viewport {:width uuwb/viewport-width [:svg.viewport {:width uuwb/viewport-width
:height uuwb/viewport-height :height uuwb/viewport-height
@ -132,11 +133,11 @@
(on-key-down [event] (on-key-down [event]
(when (kbd/space? event) (when (kbd/space? event)
(uuc/acquire-action! :scroll/viewport))) (uuc/acquire-action! "ui.workspace.scroll")))
(on-key-up [event] (on-key-up [event]
(when (kbd/space? event) (when (kbd/space? event)
(uuc/release-action! :scroll/viewport))) (uuc/release-action! "ui.workspace.scroll")))
(on-mousemove [event] (on-mousemove [event]
(let [wpt (gpt/point (.-clientX event) (let [wpt (gpt/point (.-clientX event)

View file

@ -60,7 +60,7 @@
(let [stoper (->> uuc/actions-s (let [stoper (->> uuc/actions-s
(rx/map :type) (rx/map :type)
(rx/filter #(not= % :shape/movement)) (rx/filter #(empty? %))
(rx/take 1))] (rx/take 1))]
(as-> wb/mouse-canvas-s $ (as-> wb/mouse-canvas-s $
(rx/take-until stoper $) (rx/take-until stoper $)
@ -97,5 +97,5 @@
(as-> uuc/actions-s $ (as-> uuc/actions-s $
(rx/map :type $) (rx/map :type $)
(rx/dedupe $) (rx/dedupe $)
(rx/filter #(= :draw/shape %) $) (rx/filter #(= "ui.shape.draw" %) $)
(rx/on-value $ init)))) (rx/on-value $ init))))

View file

@ -26,15 +26,14 @@
(rs/emit! (uds/move-shape id delta))))) (rs/emit! (uds/move-shape id delta)))))
(init [] (init []
(as-> uuc/actions-s $ (let [stoper (->> uuc/actions-s
(rx/map :type $) (rx/map :type)
(rx/filter #(not= % :shape/movement) $) (rx/filter empty?)
(rx/take 1 $) (rx/take 1))]
(rx/take-until $ uuwb/mouse-delta-s) (as-> uuwb/mouse-delta-s $
(rx/on-value $ on-value)))] (rx/take-until stoper $)
(rx/on-value $ on-value))))]
(as-> uuc/actions-s $ (as-> uuc/actions-s $
(rx/map :type $) (rx/filter #(= "ui.shape.move" (:type %)) $)
(rx/dedupe $)
(rx/filter #(= :shape/movement %) $)
(rx/on-value $ init)))) (rx/on-value $ init))))

View file

@ -27,7 +27,7 @@
(let [payload (:payload event) (let [payload (:payload event)
stoper (->> uuc/actions-s stoper (->> uuc/actions-s
(rx/map :type) (rx/map :type)
(rx/filter #(= :nothing %)) (rx/filter #(empty? %))
(rx/take 1))] (rx/take 1))]
(as-> uuwb/mouse-delta-s $ (as-> uuwb/mouse-delta-s $
(rx/take-until stoper $) (rx/take-until stoper $)
@ -40,5 +40,5 @@
(as-> uuc/actions-s $ (as-> uuc/actions-s $
(rx/dedupe $) (rx/dedupe $)
(rx/filter #(= (:type %) :resize/shape) $) (rx/filter #(= (:type %) "ui.shape.resize") $)
(rx/on-value $ init)))) (rx/on-value $ init))))

View file

@ -84,7 +84,7 @@
(init [] (init []
(let [stoper (->> uuc/actions-s (let [stoper (->> uuc/actions-s
(rx/map :type) (rx/map :type)
(rx/filter #(not= % :draw/selrect)) (rx/filter #(empty? %))
(rx/take 1)) (rx/take 1))
pos @wb/mouse-viewport-a] pos @wb/mouse-viewport-a]
(reset! selrect-pos {:start pos :current pos}) (reset! selrect-pos {:start pos :current pos})
@ -96,6 +96,6 @@
(as-> uuc/actions-s $ (as-> uuc/actions-s $
(rx/map :type $) (rx/map :type $)
(rx/dedupe $) (rx/dedupe $)
(rx/filter #(= :draw/selrect %) $) (rx/filter #(= "ui.selrect" %) $)
(rx/on-value $ init)))) (rx/on-value $ init))))