Add the final layouts drag and drop impl.

This commit is contained in:
Andrey Antukh 2016-02-01 23:25:37 +02:00
parent 2b74c34c00
commit d238166405
2 changed files with 105 additions and 60 deletions

View file

@ -377,11 +377,18 @@
(rx/from-coll (rx/from-coll
(map unlock-shape (:items shape)))))))) (map unlock-shape (:items shape))))))))
;; FIXME: the impl can be maybe simplified.
(defn transfer-shape (defn transfer-shape
"Event used in drag and drop for transfer shape "Event used in drag and drop for transfer shape
from one position to an other." from one position to an other."
[sid tid type] [sid tid type]
(letfn [(transfer-to-group [state target]) (letfn [(transfer-to-group [state {:keys [id] :as target}]
(let [shapes (get-in state [:shapes-by-id id :items])
shapes (conj shapes sid)]
(as-> state $
(assoc-in $ [:shapes-by-id id :items] shapes)
(update-in $ [:shapes-by-id sid] assoc :group id))))
(transfer-at [index shapes sid] (transfer-at [index shapes sid]
(let [[fst snd] (split-at index shapes)] (let [[fst snd] (split-at index shapes)]
@ -426,18 +433,24 @@
(reify (reify
rs/UpdateEvent rs/UpdateEvent
(-apply-update [_ state] (-apply-update [_ state]
(if (= tid sid)
state
(let [target (get-in state [:shapes-by-id tid]) (let [target (get-in state [:shapes-by-id tid])
source (get-in state [:shapes-by-id sid]) source (get-in state [:shapes-by-id sid])
state (remove-source state source)] state (remove-source state source)]
(cond (cond
(and (= type :inside) (:group target)) (and (= type :inside)
(= (:type target) :builtin/group))
(transfer-to-group state target) (transfer-to-group state target)
(= type :before) (= type :before)
(transfer-before state target) (transfer-before state target)
(= type :after) (= type :after)
(transfer-after state target))))))) (transfer-after state target)
:else
(throw (ex-info "Invalid data" {})))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Events (for selected) ;; Events (for selected)

View file

@ -14,6 +14,7 @@
[uxbox.ui.workspace.base :as wb] [uxbox.ui.workspace.base :as wb]
[uxbox.ui.icons :as i] [uxbox.ui.icons :as i]
[uxbox.ui.mixins :as mx] [uxbox.ui.mixins :as mx]
[uxbox.util.dom.dnd :as dnd]
[uxbox.util.dom :as dom]) [uxbox.util.dom :as dom])
(:import goog.events.EventType)) (:import goog.events.EventType))
@ -115,36 +116,30 @@
toggle-visibility #(toggle-visibility selected item %) toggle-visibility #(toggle-visibility selected item %)
toggle-blocking #(toggle-blocking item %) toggle-blocking #(toggle-blocking item %)
local (:rum/local own) local (:rum/local own)
classes (classnames classes (classnames
:selected selected? :selected selected?
:drag-top (= :top (:over @local)) :drag-top (= :top (:over @local))
:drag-bottom (= :bottom (:over @local)) :drag-bottom (= :bottom (:over @local))
:drag-inside (= :middle (:over @local)))] :drag-inside (= :middle (:over @local)))]
(letfn [(on-drag-start [event] (letfn [(on-drag-start [event]
(let [target (.-target event) (let [target (dom/event->target event)]
style (.-style target) (dnd/set-allowed-effect! event "move")
dt (.-dataTransfer event)] (dnd/set-data! event (:id item))
(set! (.-effectAllowed dt) "move")
(.setData dt "item/uuid" (pr-str (:id item)))
(swap! local assoc :dragging true))) (swap! local assoc :dragging true)))
(on-drag-end [event] (on-drag-end [event]
(swap! local assoc :dragging false :over nil)) (swap! local assoc :dragging false :over nil))
(on-drop [event] (on-drop [event]
(let [dt (.-dataTransfer event) (dom/stop-propagation event)
id (read-string (.getData dt "item/uuid")) (let [id (dnd/get-data event)
over (:over @local)] over (:over @local)]
(case (:over @local) (case (:over @local)
:top (rs/emit! (dw/transfer-shape id (:id item) :before)) :top (rs/emit! (dw/transfer-shape id (:id item) :before))
:bottom (rs/emit! (dw/transfer-shape id (:id item) :after)) :bottom (rs/emit! (dw/transfer-shape id (:id item) :after)))
;; :middle (rs/emit! (dw/transfer-inside id (:id item)))
)
(swap! local assoc :dragging false :over nil))) (swap! local assoc :dragging false :over nil)))
(on-drag-over [event] (on-drag-over [event]
(dom/prevent-default event) (dom/prevent-default event)
(let [dt (.-dataTransfer event) (dnd/set-drop-effect! event "move")
over (get-hover-position event false)] (let [over (get-hover-position event false)]
(set! (.-dropEffect dt) "move")
(swap! local assoc :over over))) (swap! local assoc :over over)))
(on-drag-enter [event] (on-drag-enter [event]
(swap! local assoc :over true)) (swap! local assoc :over true))
@ -159,7 +154,6 @@
:on-drag-over on-drag-over :on-drag-over on-drag-over
:on-drag-end on-drag-end :on-drag-end on-drag-end
:on-drop on-drop :on-drop on-drop
:data-over (str (:over @local))
:draggable true :draggable true
:class (when selected? "selected")} :class (when selected? "selected")}
[:div.element-list-body [:div.element-list-body
@ -198,11 +192,49 @@
toggle-open (fn [event] toggle-open (fn [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(swap! local assoc :open (not open?))) (swap! local assoc :open (not open?)))
shapes-by-id (rum/react wb/shapes-by-id-l)] shapes-by-id (rum/react wb/shapes-by-id-l)
classes (classnames
:selected selected?
:drag-top (= :top (:over @local))
:drag-bottom (= :bottom (:over @local))
:drag-inside (= :middle (:over @local)))]
(letfn [(on-drag-start [event]
(let [target (dom/event->target event)]
(dnd/set-allowed-effect! event "move")
(dnd/set-data! event (:id item))
(swap! local assoc :dragging true)))
(on-drag-end [event]
(swap! local assoc :dragging false :over nil))
(on-drop [event]
(dom/stop-propagation event)
(let [id (dnd/get-data event)
over (:over @local)]
(case (:over @local)
:top (rs/emit! (dw/transfer-shape id (:id item) :before))
:bottom (rs/emit! (dw/transfer-shape id (:id item) :after))
:middle (rs/emit! (dw/transfer-shape id (:id item) :inside)))
(swap! local assoc :dragging false :over nil)))
(on-drag-over [event]
(dom/prevent-default event)
(dnd/set-drop-effect! event "move")
(let [over (get-hover-position event true)]
(swap! local assoc :over over)))
(on-drag-enter [event]
(swap! local assoc :over true))
(on-drag-leave [event]
(swap! local assoc :over false))]
(html (html
[:li.group {:class (when open? "open") :draggable true} [:li.group {:class (when open? "open")
:key (str (:id item))
:draggable true}
[:div.element-list-body [:div.element-list-body
{:class (when selected? "selected") {:class classes
:on-drag-start on-drag-start
:on-drag-enter on-drag-enter
:on-drag-leave on-drag-leave
:on-drag-over on-drag-over
:on-drag-end on-drag-end
:on-drop on-drop
:on-click select} :on-click select}
[:div.element-actions [:div.element-actions
[:div.toggle-element [:div.toggle-element
@ -231,7 +263,7 @@
(-> (layer-group shape selected) (-> (layer-group shape selected)
(rum/with-key key)) (rum/with-key key))
(-> (layer-element shape selected) (-> (layer-element shape selected)
(rum/with-key key))))])]))) (rum/with-key key))))])]))))
(def ^:static ^:private layer-group (def ^:static ^:private layer-group
(mx/component (mx/component