diff --git a/src/uxbox/data/shapes.cljs b/src/uxbox/data/shapes.cljs index d2c3ab8c7c..d59429aa03 100644 --- a/src/uxbox/data/shapes.cljs +++ b/src/uxbox/data/shapes.cljs @@ -486,3 +486,11 @@ (map #(update-stroke-attrs % opts))))))) +(defn move-selected-layer + [loc] + (reify + udp/IPageUpdate + rs/UpdateEvent + (-apply-update [_ state] + (let [selected (get-in state [:workspace :selected])] + (stsh/move-layer state selected loc))))) diff --git a/src/uxbox/state/shapes.cljs b/src/uxbox/state/shapes.cljs index fc8401371d..8ccb38bfa8 100644 --- a/src/uxbox/state/shapes.cljs +++ b/src/uxbox/state/shapes.cljs @@ -132,6 +132,43 @@ (let [[fst snd] (split-at index coll)] (into [] (concat fst [v] snd)))) +(defn drop-relative + [state loc sid] + {:pre [(not (nil? sid))]} + (let [shape (get-in state [:shapes-by-id (first sid)]) + {:keys [page group]} shape + sid (:id shape) + + shapes (if group + (get-in state [:shapes-by-id group :items]) + (get-in state [:pages-by-id page :shapes])) + + index (case loc + :first 0 + :after (min (- (count shapes) 1) (inc (index-of shapes sid))) + :before (max 0 (- (index-of shapes sid) 1)) + :last (- (count shapes) 1)) + + state (-> state + (dissoc-from-page shape) + (dissoc-from-group shape)) + + shapes (if group + (get-in state [:shapes-by-id group :items]) + (get-in state [:pages-by-id page :shapes])) + + shapes (drop-at-index index shapes sid)] + + (if group + (as-> state $ + (assoc-in $ [:shapes-by-id group :items] shapes) + (update-in $ [:shapes-by-id sid] assoc :group group) + (clear-empty-groups $ shape)) + (as-> state $ + (assoc-in $ [:pages-by-id page :shapes] shapes) + (update-in $ [:shapes-by-id sid] dissoc :group) + (clear-empty-groups $ shape))))) + (defn drop-aside [state loc tid sid] {:pre [(not= tid sid) @@ -190,6 +227,15 @@ :after (drop-after state tid sid) (throw (ex-info "Invalid data" {}))))) +(defn move-layer + [state shape loc] + (case loc + :up (drop-relative state :before shape) + :down (drop-relative state :after shape) + :top (drop-relative state :first shape) + :bottom (drop-relative state :last shape) + (throw (ex-info "Invalid data" {})))) + ;; --- Shape Packing ;; (defn- deep-scan-shape-ids @@ -211,4 +257,3 @@ ;; {:type :builtin/packed-shape ;; :index index ;; :id id})) - diff --git a/src/uxbox/ui/workspace/shortcuts.cljs b/src/uxbox/ui/workspace/shortcuts.cljs index 9d14ac1473..2038f40412 100644 --- a/src/uxbox/ui/workspace/shortcuts.cljs +++ b/src/uxbox/ui/workspace/shortcuts.cljs @@ -38,6 +38,10 @@ :esc #(rs/emit! (uds/deselect-all)) :backspace #(rs/emit! (uds/delete-selected)) :delete #(rs/emit! (uds/delete-selected)) + :ctrl+up #(rs/emit! (uds/move-selected-layer :up)) + :ctrl+down #(rs/emit! (uds/move-selected-layer :down)) + :ctrl+shift+up #(rs/emit! (uds/move-selected-layer :top)) + :ctrl+shift+down #(rs/emit! (uds/move-selected-layer :bottom)) :shift+up #(move-selected :up :fast) :shift+down #(move-selected :down :fast) :shift+right #(move-selected :right :fast) diff --git a/src/uxbox/ui/workspace/sidebar/layers.cljs b/src/uxbox/ui/workspace/sidebar/layers.cljs index f33e41617b..f8642d4543 100644 --- a/src/uxbox/ui/workspace/sidebar/layers.cljs +++ b/src/uxbox/ui/workspace/sidebar/layers.cljs @@ -290,6 +290,10 @@ page (rum/react (focus-page (:page workspace))) close #(rs/emit! (udw/toggle-flag :layers)) duplicate #(rs/emit! (uds/duplicate-selected)) + move-up #(rs/emit! (uds/move-selected-layer :up)) + move-down #(rs/emit! (uds/move-selected-layer :down)) + move-top #(rs/emit! (uds/move-selected-layer :top)) + move-bottom #(rs/emit! (uds/move-selected-layer :bottom)) group #(rs/emit! (uds/group-selected)) delete #(rs/emit! (uds/delete-selected)) dragel (volatile! nil)] @@ -310,10 +314,10 @@ (rum/with-key key))))]] [:div.layers-tools [:ul.layers-tools-content - [:li.layer-up {:on-click duplicate} i/arrow-slide] - [:li.layer-top {:on-click duplicate} i/arrow-end] - [:li.layer-down {:on-click duplicate} i/arrow-slide] - [:li.layer-end {:on-click duplicate} i/arrow-end] + [:li.layer-up {:on-click move-up} i/arrow-slide] + [:li.layer-top {:on-click move-top} i/arrow-end] + [:li.layer-down {:on-click move-down} i/arrow-slide] + [:li.layer-end {:on-click move-bottom} i/arrow-end] [:li.clone-layer {:on-click duplicate} i/copy] [:li.group-layer {:on-click group} i/folder] [:li.delete-layer {:on-click delete} i/trash]]]])))