mirror of
https://github.com/penpot/penpot.git
synced 2025-08-07 14:38:33 +02:00
Improved action stacking.
This commit is contained in:
parent
e6161a0f62
commit
f5f4e0f0fe
9 changed files with 45 additions and 46 deletions
|
@ -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}))
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue