diff --git a/src/uxbox/ui/workspace/canvas.cljs b/src/uxbox/ui/workspace/canvas.cljs index bea6f5192..6653576e0 100644 --- a/src/uxbox/ui/workspace/canvas.cljs +++ b/src/uxbox/ui/workspace/canvas.cljs @@ -66,7 +66,7 @@ :mixins [mx/static rum/reactive]})) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Selected shapes group +;; Selected shapes. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (def ^:private @@ -102,7 +102,7 @@ :on-mouse-down on-mouse-down :on-mouse-up on-mouse-up} (for [item shapes] - (shapes/render item)) + (shapes/-render item nil)) [:g.controls [:rect {:x x :y y :width width :height height :style {:stroke "black" :fill "transparent" @@ -122,52 +122,73 @@ :name "selected-shapes" :mixins [mx/static rum/reactive (mx/local {})]})) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Shape +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defn selected-shape-render + [own shape selected] + (let [{:keys [id x y width height] :as shape} shape] + (letfn [(on-mouse-down [event] + (when-not (:blocked shape) + (let [local (:rum/local own)] + (dom/stop-propagation event) + (swap! local assoc :init-coords [x y]) + (reset! wb/shapes-dragging? true)))) + (on-mouse-up [event] + (dom/stop-propagation event) + (reset! wb/shapes-dragging? false))] + (html + [:g.shape {:class "selected" + :on-mouse-down on-mouse-down + :on-mouse-up on-mouse-up} + (shapes/-render shape nil) + [:g.controls + [:rect {:x x :y y :width width :height height + :style {:stroke "black" :fill "transparent" + :stroke-opacity "0.5"}}] + [:circle.top-left (merge default-selection-props + {:cx x :cy y})] + [:circle.top-right (merge default-selection-props + {:cx (+ x width) :cy y})] + [:circle.bottom-left (merge default-selection-props + {:cx x :cy (+ y height)})] + [:circle.bottom-right (merge default-selection-props + {:cx (+ x width) :cy (+ y height)})]]])))) + +(def selected-shape + (mx/component + {:render selected-shape-render + :name "selected-shape" + :mixins [mx/static (mx/local {})]})) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Shape ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defn shape-render [own shape selected] - (let [{:keys [id x y width height] :as shape} shape - selected? (contains? selected id)] + ;; (println "shape" (:id shape)) + (let [{:keys [id x y width height] :as shape} shape] (letfn [(on-mouse-down [event] (when-not (:blocked shape) (let [local (:rum/local own)] (dom/stop-propagation event) (swap! local assoc :init-coords [x y]) (reset! wb/shapes-dragging? true)) - (cond - (and (not selected?) - (empty? selected)) - (rs/emit! (dw/select-shape id)) - - (and (not selected?) - (not (empty? selected))) (if (.-ctrlKey event) (rs/emit! (dw/select-shape id)) (rs/emit! (dw/deselect-all) - (dw/select-shape id)))))) + (dw/select-shape id))))) + (on-mouse-up [event] (dom/stop-propagation event) (reset! wb/shapes-dragging? false))] (html - [:g.shape {:class (when selected? "selected") - :on-mouse-down on-mouse-down + [:g.shape {:on-mouse-down on-mouse-down :on-mouse-up on-mouse-up} - (shapes/render shape) - (if selected? - [:g.controls - [:rect {:x x :y y :width width :height height - :style {:stroke "black" :fill "transparent" - :stroke-opacity "0.5"}}] - [:circle.top-left (merge default-selection-props - {:cx x :cy y})] - [:circle.top-right (merge default-selection-props - {:cx (+ x width) :cy y})] - [:circle.bottom-left (merge default-selection-props - {:cx x :cy (+ y height)})] - [:circle.bottom-right (merge default-selection-props - {:cx (+ x width) :cy (+ y height)})]])])))) + (shapes/-render shape nil)])))) (def shape (mx/component @@ -230,18 +251,19 @@ (background) (grid 1) [:svg.page-layout {} - (for [item shapes-notselected - :let [component (shape item workspace-selected)]] - (rum/with-key component (str (:id item)))) + [:g.main {} + (for [item shapes-notselected] + (-> (shape item workspace-selected) + (rum/with-key (str (:id item))))) - (cond - (= (count shapes-selected) 1) - (let [item (first shapes-selected)] - (shape item workspace-selected)) + (cond + (= (count shapes-selected) 1) + (let [item (first shapes-selected)] + (selected-shape item workspace-selected)) - (> (count shapes-selected) 1) - (selected-shapes shapes-selected)) - (selrect)]]))) + (> (count shapes-selected) 1) + (selected-shapes shapes-selected)) + (selrect)]]]))) (def canvas (mx/component diff --git a/src/uxbox/ui/workspace/toolboxes.cljs b/src/uxbox/ui/workspace/toolboxes.cljs index 8d0a117ed..0725b3172 100644 --- a/src/uxbox/ui/workspace/toolboxes.cljs +++ b/src/uxbox/ui/workspace/toolboxes.cljs @@ -134,15 +134,18 @@ [:li {:key (str (:id item)) :on-click select :class (when selected? "selected")} - [:div.element-list-body + [:div.element-list-body {:class (when selected? "selected")} [:div.element-actions [:div.toggle-element {:class (when-not (:hidden item) "selected") :on-click toggle-visibility} i/eye] [:div.block-element {:class (when (:blocked item) "selected") - :on-click toggle-blocking} + :on-click toggle-blocking} i/lock]] - [:div.element-icon (shapes/render item)] + + (if (:group item) + [:div.sublevel-element i/sublevel]) + [:div.element-icon (shapes/-render-svg item)] [:span (or (:name item) (:id item))]]]))) @@ -152,6 +155,36 @@ :name "layer-element" :mixins [mx/static]})) +(declare layer-group) + +(defn- layer-group-render + [own item selected] + (let [selected? (contains? selected (:id item)) + shapes-by-id (rum/react shapes-by-id)] + (html + [:li.group.open + [:div.element-list-body {:class (when selected? "selected")} + [:div.element-actions + [:div.toggle-element i/eye] + [:div.block-element i/lock] + [:div.chain-element i/chain]] + [:div.element-icon i/folder] + [:span "Opened group"] + [:span.toggle-content i/arrow-slide]] + [:ul + (for [shape (map #(get shapes-by-id %) (:items item)) + :let [key (str (:id shape))]] + ;; TODO: make polymorphic + (case (:type shape) + :builtin/icon (rum/with-key (layer-element shape selected) key) + :builtin/group (rum/with-key (layer-group shape selected) key)))]]))) + +(def ^:static ^:private layer-group + (mx/component + {:render layer-group-render + :name "layer-group" + :mixins [mx/static rum/reactive]})) + (defn layers-render [own] (let [workspace (rum/react wb/workspace-l) @@ -160,6 +193,7 @@ page (rum/react (focus-page (:page workspace))) close #(rs/emit! (dw/toggle-toolbox :layers)) copy #(rs/emit! (dw/copy-selected)) + group #(rs/emit! (dw/group-selected)) delete #(rs/emit! (dw/delete-selected))] (html [:div#layers.tool-window @@ -170,44 +204,17 @@ [:div.tool-window-content [:ul.element-list (for [shape (map #(get shapes-by-id %) (:shapes page)) - :let [component (layer-element shape selected)]] - (rum/with-key component (:id shape))) - - [:li.group.open - [:div.element-list-body - [:div.element-actions - [:div.toggle-element i/eye] - [:div.block-element i/lock] - [:div.chain-element i/chain]] - [:div.element-icon i/folder] - [:span "Opened group"] - [:span.toggle-content i/arrow-slide]] - - [:ul - - [:li - [:div.element-list-body - [:div.element-actions - [:div.toggle-element i/eye] - [:div.block-element i/lock]] - [:div.sublevel-element i/sublevel] - [:div.element-icon i/box] - [:span "Sub layer"]]] - - [:li - [:div.element-list-body - [:div.element-actions - [:div.toggle-element i/eye] - [:div.block-element i/lock]] - [:div.sublevel-element i/sublevel] - [:div.element-icon i/box] - [:span "Sub layer"]]]]]]] - + :let [key (str (:id shape))]] + ;; TODO: make polymorphic + (case (:type shape) + :builtin/icon (rum/with-key (layer-element shape selected) key) + :builtin/group (rum/with-key (layer-group shape selected) key)))]] [:div.layers-tools [:ul.layers-tools-content [:li.clone-layer {:on-click copy} i/copy] - [:li.group-layer i/folder] + [:li.group-layer {:on-click group} + i/folder] [:li.delete-layer {:on-click delete} i/trash] ]]]))) @@ -275,7 +282,7 @@ (defn- icon-wrapper-render [own icon] - (shapes/render icon)) + (shapes/-render-svg icon nil)) (def ^:static ^:private icon-wrapper (mx/component