From 23ca77fe3a73e24e867331f5fe371be3043b9d4b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 19 May 2020 13:47:52 +0200 Subject: [PATCH] :recycle: Renamed layout to grid and some refactors --- frontend/src/uxbox/main/data/workspace.cljs | 70 ---------------- .../src/uxbox/main/data/workspace/grid.cljs | 83 +++++++++++++++++++ frontend/src/uxbox/main/refs.cljs | 4 +- .../{layout_display.cljs => frame_grid.cljs} | 46 +++++----- .../ui/workspace/sidebar/options/frame.cljs | 5 +- .../{frame_layouts.cljs => frame_grid.cljs} | 70 ++++++++-------- .../src/uxbox/main/ui/workspace/viewport.cljs | 4 +- .../util/geom/{layout.cljs => grid.cljs} | 73 +++++++++------- frontend/src/uxbox/util/geom/snap_points.cljs | 2 +- frontend/src/uxbox/worker/snaps.cljs | 17 ++-- 10 files changed, 203 insertions(+), 171 deletions(-) create mode 100644 frontend/src/uxbox/main/data/workspace/grid.cljs rename frontend/src/uxbox/main/ui/workspace/{layout_display.cljs => frame_grid.cljs} (59%) rename frontend/src/uxbox/main/ui/workspace/sidebar/options/{frame_layouts.cljs => frame_grid.cljs} (75%) rename frontend/src/uxbox/util/geom/{layout.cljs => grid.cljs} (61%) diff --git a/frontend/src/uxbox/main/data/workspace.cljs b/frontend/src/uxbox/main/data/workspace.cljs index a80432eb9..11962eb43 100644 --- a/frontend/src/uxbox/main/data/workspace.cljs +++ b/frontend/src/uxbox/main/data/workspace.cljs @@ -1489,76 +1489,6 @@ (rx/of (update-shape shape-id {:interactions []})))))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Layouts -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defonce default-layout-params - {:square {:size 16 - :color {:value "#59B9E2" - :opacity 0.9}} - - :column {:size 12 - :type :stretch - :item-length nil - :gutter 8 - :margin 0 - :color {:value "#DE4762" - :opacity 0.1}} - :row {:size 12 - :type :stretch - :item-height nil - :gutter 8 - :margin 0 - :color {:value "#DE4762" - :opacity 0.1}}}) - -(defn add-frame-layout [frame-id] - (ptk/reify ::set-frame-layout - dwc/IBatchedChange - ptk/UpdateEvent - (update [_ state] - (let [pid (:current-page-id state) - default-params (or - (get-in state [:workspace-data pid :options :saved-layouts :square]) - (:square default-layout-params)) - prop-path [:workspace-data pid :objects frame-id :layouts] - layout {:type :square - :params default-params - :display true}] - (-> state - (update-in prop-path #(if (nil? %) [layout] (conj % layout)))))))) - -(defn remove-frame-layout [frame-id index] - (ptk/reify ::set-frame-layout - dwc/IBatchedChange - ptk/UpdateEvent - (update [_ state] - (let [pid (:current-page-id state)] - (-> state - (update-in [:workspace-data pid :objects frame-id :layouts] #(d/remove-at-index % index))))))) - -(defn set-frame-layout [frame-id index data] - (ptk/reify ::set-frame-layout - dwc/IBatchedChange - ptk/UpdateEvent - (update [_ state] - (let [pid (:current-page-id state)] - (-> - state - (assoc-in [:workspace-data pid :objects frame-id :layouts index] data)))))) - -(defn set-default-layout [type params] - (ptk/reify ::set-default-layout - ptk/WatchEvent - (watch [_ state stream] - (rx/of (dwc/commit-changes [{:type :set-option - :option [:saved-layouts type] - :value params}] - [] - {:commit-local? true}))))) - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Exports ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/uxbox/main/data/workspace/grid.cljs b/frontend/src/uxbox/main/data/workspace/grid.cljs new file mode 100644 index 000000000..31e666e7b --- /dev/null +++ b/frontend/src/uxbox/main/data/workspace/grid.cljs @@ -0,0 +1,83 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2020 UXBOX Labs SL + +(ns uxbox.main.data.workspace.grid + (:require + [beicon.core :as rx] + [potok.core :as ptk] + [uxbox.common.data :as d] + [uxbox.main.data.workspace.common :as dwc])) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Grid +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defonce ^:private default-square-params + {:size 16 + :color {:value "#59B9E2" + :opacity 0.9}}) + +(defonce ^:private default-layout-params + {:size 12 + :type :stretch + :item-length nil + :gutter 8 + :margin 0 + :color {:value "#DE4762" + :opacity 0.1}}) + +(defonce default-grid-params + {:square default-square-params + :column default-layout-params + :row default-layout-params}) + +(defn add-frame-grid [frame-id] + (ptk/reify ::set-frame-grid + dwc/IBatchedChange + ptk/UpdateEvent + (update [_ state] + (let [pid (:current-page-id state) + default-params (or + (get-in state [:workspace-data pid :options :saved-grids :square]) + (:square default-grid-params)) + prop-path [:workspace-data pid :objects frame-id :grids] + grid {:type :square + :params default-params + :display true}] + (-> state + (update-in prop-path #(if (nil? %) [grid] (conj % grid)))))))) + +(defn remove-frame-grid [frame-id index] + (ptk/reify ::set-frame-grid + dwc/IBatchedChange + ptk/UpdateEvent + (update [_ state] + (let [pid (:current-page-id state)] + (-> state + (update-in [:workspace-data pid :objects frame-id :grids] #(d/remove-at-index % index))))))) + +(defn set-frame-grid [frame-id index data] + (ptk/reify ::set-frame-grid + dwc/IBatchedChange + ptk/UpdateEvent + (update [_ state] + (let [pid (:current-page-id state)] + (-> + state + (assoc-in [:workspace-data pid :objects frame-id :grids index] data)))))) + +(defn set-default-grid [type params] + (ptk/reify ::set-default-grid + ptk/WatchEvent + (watch [_ state stream] + (rx/of (dwc/commit-changes [{:type :set-option + :option [:saved-grids type] + :value params}] + [] + {:commit-local? true}))))) diff --git a/frontend/src/uxbox/main/refs.cljs b/frontend/src/uxbox/main/refs.cljs index 295530487..84d72442f 100644 --- a/frontend/src/uxbox/main/refs.cljs +++ b/frontend/src/uxbox/main/refs.cljs @@ -71,8 +71,8 @@ (def workspace-page-options (l/derived :options workspace-data)) -(def workspace-saved-layouts - (l/derived :saved-layouts workspace-page-options)) +(def workspace-saved-grids + (l/derived :saved-grids workspace-page-options)) (def workspace-objects diff --git a/frontend/src/uxbox/main/ui/workspace/layout_display.cljs b/frontend/src/uxbox/main/ui/workspace/frame_grid.cljs similarity index 59% rename from frontend/src/uxbox/main/ui/workspace/layout_display.cljs rename to frontend/src/uxbox/main/ui/workspace/frame_grid.cljs index 6facef86d..1707d03a5 100644 --- a/frontend/src/uxbox/main/ui/workspace/layout_display.cljs +++ b/frontend/src/uxbox/main/ui/workspace/frame_grid.cljs @@ -7,20 +7,20 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns uxbox.main.ui.workspace.layout-display +(ns uxbox.main.ui.workspace.frame-grid (:require [rumext.alpha :as mf] [uxbox.main.refs :as refs] [uxbox.common.pages :as cp] [uxbox.util.geom.shapes :as gsh] - [uxbox.util.geom.layout :as ula])) + [uxbox.util.geom.grid :as gg])) -(mf/defc grid-layout [{:keys [frame zoom layout] :as props}] - (let [{:keys [color size] :as params} (-> layout :params) - {color-value :value color-opacity :opacity} (-> layout :params :color) +(mf/defc square-grid [{:keys [frame zoom grid] :as props}] + (let [{:keys [color size] :as params} (-> grid :params) + {color-value :value color-opacity :opacity} (-> grid :params :color) {frame-width :width frame-height :height :keys [x y]} frame] (when (> size 0) - [:g.layout + [:g.grid [:* (for [xs (range size frame-width size)] [:line {:key (str (:id frame) "-y-" xs) @@ -41,10 +41,10 @@ :stroke-opacity color-opacity :stroke-width (str (/ 1 zoom))}}])]]))) -(mf/defc flex-layout [{:keys [key frame zoom layout]}] - (let [{color-value :value color-opacity :opacity} (-> layout :params :color)] - [:g.layout - (for [{:keys [x y width height]} (ula/layout-rects frame layout)] +(mf/defc layout-grid [{:keys [key frame zoom grid]}] + (let [{color-value :value color-opacity :opacity} (-> grid :params :color)] + [:g.grid + (for [{:keys [x y width height]} (gg/grid-areas frame grid)] [:rect {:key (str key "-" x "-" y) :x x :y y @@ -53,24 +53,24 @@ :style {:fill color-value :opacity color-opacity}}])])) -(mf/defc layout-display-frame [{:keys [frame zoom]}] - (let [layouts (:layouts frame)] - (for [[index {:keys [type display] :as layout}] (map-indexed vector layouts)] - (let [props #js {:key (str (:id frame) "-layout-" index) +(mf/defc grid-display-frame [{:keys [frame zoom]}] + (let [grids (:grids frame)] + (for [[index {:keys [type display] :as grid}] (map-indexed vector grids)] + (let [props #js {:key (str (:id frame) "-grid-" index) :frame frame :zoom zoom - :layout layout}] + :grid grid}] (when display (case type - :square [:> grid-layout props] - :column [:> flex-layout props] - :row [:> flex-layout props])))))) + :square [:> square-grid props] + :column [:> layout-grid props] + :row [:> layout-grid props])))))) -(mf/defc layout-display [{:keys [zoom]}] +(mf/defc frame-grid [{:keys [zoom]}] (let [frames (mf/deref refs/workspace-frames)] - [:g.layout-display {:style {:pointer-events "none"}} + [:g.grid-display {:style {:pointer-events "none"}} (for [frame frames] - [:& layout-display-frame {:key (str "layout-" (:id frame)) - :zoom zoom - :frame (gsh/transform-shape frame)}])])) + [:& grid-display-frame {:key (str "grid-" (:id frame)) + :zoom zoom + :frame (gsh/transform-shape frame)}])])) diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs index af6051a39..13d525922 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame.cljs @@ -22,7 +22,7 @@ [uxbox.main.ui.components.dropdown :refer [dropdown]] [uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]] [uxbox.main.ui.workspace.sidebar.options.stroke :refer [stroke-menu]] - [uxbox.main.ui.workspace.sidebar.options.frame-layouts :refer [frame-layouts]])) + [uxbox.main.ui.workspace.sidebar.options.frame-grid :refer [frame-grid]])) (declare +size-presets+) @@ -204,4 +204,5 @@ [:& measures-menu {:shape shape}] [:& fill-menu {:shape shape}] [:& stroke-menu {:shape shape}] - [:& frame-layouts {:shape shape}]]) + [:& frame-grid {:shape shape}]]) + diff --git a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_layouts.cljs b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_grid.cljs similarity index 75% rename from frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_layouts.cljs rename to frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_grid.cljs index 5bf198c65..5e835f44b 100644 --- a/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_layouts.cljs +++ b/frontend/src/uxbox/main/ui/workspace/sidebar/options/frame_grid.cljs @@ -7,7 +7,7 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns uxbox.main.ui.workspace.sidebar.options.frame-layouts +(ns uxbox.main.ui.workspace.sidebar.options.frame-grid (:require [rumext.alpha :as mf] [uxbox.util.dom :as dom] @@ -16,8 +16,8 @@ [uxbox.common.data :refer [parse-integer]] [uxbox.main.store :as st] [uxbox.main.refs :as refs] - [uxbox.main.data.workspace :as dw] - [uxbox.util.geom.layout :as gla] + [uxbox.main.data.workspace.grid :as dw] + [uxbox.util.geom.grid :as gg] [uxbox.main.ui.icons :as i] [uxbox.main.ui.workspace.sidebar.options.rows.color-row :refer [color-row]] [uxbox.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]] @@ -40,29 +40,29 @@ :separator 18 12 10 8 6 4 3 2]) -(mf/defc layout-options [{:keys [frame layout default-layout-params on-change on-remove on-save-layout]}] +(mf/defc grid-options [{:keys [frame grid default-grid-params on-change on-remove on-save-grid]}] (let [state (mf/use-state {:show-advanced-options false :changes {}}) - {:keys [type display params] :as layout} (d/deep-merge layout (:changes @state)) + {:keys [type display params] :as grid} (d/deep-merge grid (:changes @state)) toggle-advanced-options #(swap! state update :show-advanced-options not) emit-changes! (fn [update-fn] (swap! state update :changes update-fn) - (when on-change (on-change (d/deep-merge layout (-> @state :changes update-fn))))) + (when on-change (on-change (d/deep-merge grid (-> @state :changes update-fn))))) handle-toggle-visibility (fn [event] (emit-changes! (fn [changes] (update changes :display #(if (nil? %) false (not %)))))) - handle-remove-layout + handle-remove-grid (fn [event] (when on-remove (on-remove))) handle-change-type (fn [type] - (let [defaults (type default-layout-params) + (let [defaults (type default-grid-params) keys (keys defaults) params (->> @state :changes params (select-keys keys) (merge defaults)) to-merge {:type type :params params}] @@ -81,11 +81,11 @@ handle-change-size (fn [size] - (let [layout (d/deep-merge layout (:changes @state)) - {:keys [margin gutter item-length]} (:params layout) - frame-length (if (= :column (:type layout)) (:width frame) (:height frame)) + (let [grid (d/deep-merge grid (:changes @state)) + {:keys [margin gutter item-length]} (:params grid) + frame-length (if (= :column (:type grid)) (:width frame) (:height frame)) item-length (if (or (nil? size) (= :auto size)) - (-> (gla/calculate-default-item-length frame-length margin gutter) + (-> (gg/calculate-default-item-length frame-length margin gutter) (mth/round)) item-length)] (emit-changes! #(-> % @@ -94,7 +94,7 @@ handle-change-item-length (fn [item-length] - (let [{:keys [margin gutter size]} (->> @state :changes :params (d/deep-merge (:params layout))) + (let [{:keys [margin gutter size]} (->> @state :changes :params (d/deep-merge (:params grid))) size (if (and (nil? item-length) (or (nil? size) (= :auto size))) 12 size)] (emit-changes! #(-> % (assoc-in [:params :size] size) @@ -102,15 +102,15 @@ handle-use-default (fn [] - (emit-changes! #(hash-map :params ((:type layout) default-layout-params)))) + (emit-changes! #(hash-map :params ((:type grid) default-grid-params)))) handle-set-as-default (fn [] - (let [current-layout (d/deep-merge layout (-> @state :changes))] - (on-save-layout current-layout))) + (let [current-grid (d/deep-merge grid (-> @state :changes))] + (on-save-grid current-grid))) - is-default (= (->> @state :changes (d/deep-merge layout) :params) - (->> layout :type default-layout-params))] + is-default (= (->> @state :changes (d/deep-merge grid) :params) + (->> grid :type default-grid-params))] [:div.grid-option [:div.grid-option-main @@ -139,7 +139,7 @@ [:div.grid-option-main-actions [:button.custom-button {:on-click handle-toggle-visibility} (if display i/eye i/eye-closed)] - [:button.custom-button {:on-click handle-remove-layout} i/trash]]] + [:button.custom-button {:on-click handle-remove-grid} i/trash]]] [:& advanced-options {:visible? (:show-advanced-options @state) :on-close toggle-advanced-options} @@ -203,26 +203,26 @@ [:button.btn-options {:disabled is-default :on-click handle-set-as-default} "Set as default"]]]])) -(mf/defc frame-layouts [{:keys [shape]}] +(mf/defc frame-grid [{:keys [shape]}] (let [id (:id shape) - default-layout-params (merge dw/default-layout-params (mf/deref refs/workspace-saved-layouts)) - handle-create-layout #(st/emit! (dw/add-frame-layout id)) - handle-remove-layout (fn [index] #(st/emit! (dw/remove-frame-layout id index))) - handle-edit-layout (fn [index] #(st/emit! (dw/set-frame-layout id index %))) - handle-save-layout (fn [layout] (st/emit! (dw/set-default-layout (:type layout) (:params layout))))] + default-grid-params (merge dw/default-grid-params (mf/deref refs/workspace-saved-grids)) + handle-create-grid #(st/emit! (dw/add-frame-grid id)) + handle-remove-grid (fn [index] #(st/emit! (dw/remove-frame-grid id index))) + handle-edit-grid (fn [index] #(st/emit! (dw/set-frame-grid id index %))) + handle-save-grid (fn [grid] (st/emit! (dw/set-default-grid (:type grid) (:params grid))))] [:div.element-set [:div.element-set-title - [:span "Grid & Layout"] - [:div.add-page {:on-click handle-create-layout} i/close]] + [:span "Grids"] + [:div.add-page {:on-click handle-create-grid} i/close]] - (when (not (empty? (:layouts shape))) + (when (not (empty? (:grids shape))) [:div.element-set-content - (for [[index layout] (map-indexed vector (:layouts shape))] - [:& layout-options {:key (str (:id shape) "-" index) - :layout layout - :default-layout-params default-layout-params + (for [[index grid] (map-indexed vector (:grids shape))] + [:& grid-options {:key (str (:id shape) "-" index) + :grid grid + :default-grid-params default-grid-params :frame shape - :on-change (handle-edit-layout index) - :on-remove (handle-remove-layout index) - :on-save-layout handle-save-layout}])])])) + :on-change (handle-edit-grid index) + :on-remove (handle-remove-grid index) + :on-save-grid handle-save-grid}])])])) diff --git a/frontend/src/uxbox/main/ui/workspace/viewport.cljs b/frontend/src/uxbox/main/ui/workspace/viewport.cljs index 0dbe00d00..8cd0e0662 100644 --- a/frontend/src/uxbox/main/ui/workspace/viewport.cljs +++ b/frontend/src/uxbox/main/ui/workspace/viewport.cljs @@ -29,7 +29,7 @@ [uxbox.main.ui.workspace.selection :refer [selection-handlers]] [uxbox.main.ui.workspace.presence :as presence] [uxbox.main.ui.workspace.snap-feedback :refer [snap-feedback]] - [uxbox.main.ui.workspace.layout-display :refer [layout-display]] + [uxbox.main.ui.workspace.frame-grid :refer [frame-grid]] [uxbox.util.math :as mth] [uxbox.util.dom :as dom] [uxbox.util.object :as obj] @@ -387,7 +387,7 @@ :modifiers (:modifiers local)}]) (when (contains? layout :display-grid) - [:& layout-display {:zoom zoom}]) + [:& frame-grid {:zoom zoom}]) [:& snap-feedback {:layout layout}] diff --git a/frontend/src/uxbox/util/geom/layout.cljs b/frontend/src/uxbox/util/geom/grid.cljs similarity index 61% rename from frontend/src/uxbox/util/geom/layout.cljs rename to frontend/src/uxbox/util/geom/grid.cljs index 7c12100bc..b3706e25a 100644 --- a/frontend/src/uxbox/util/geom/layout.cljs +++ b/frontend/src/uxbox/util/geom/grid.cljs @@ -7,24 +7,27 @@ ;; ;; Copyright (c) 2020 UXBOX Labs SL -(ns uxbox.util.geom.layout +(ns uxbox.util.geom.grid (:require [uxbox.util.math :as mth] [uxbox.util.geom.point :as gpt])) (def ^:private default-items 12) -(defn calculate-default-item-length [frame-length margin gutter] +(defn calculate-default-item-length + "Calculates the item-length so the default number of items fits inside the frame-length" + [frame-length margin gutter] (/ (- frame-length (+ margin (- margin gutter)) (* gutter default-items)) default-items)) (defn calculate-size - "Calculates the number of rows/columns given the other layout parameters" + "Calculates the number of rows/columns given the other grid parameters" [frame-length item-length margin gutter] (let [item-length (or item-length (calculate-default-item-length frame-length margin gutter)) frame-length-no-margins (- frame-length (+ margin (- margin gutter)))] (mth/floor (/ frame-length-no-margins (+ item-length gutter))))) -(defn calculate-column-layout [{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}] +(defn- calculate-column-grid + [{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}] (let [size (if (number? size) size (calculate-size width item-length margin gutter)) parts (/ width size) item-width (or item-length (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size)))) @@ -38,7 +41,8 @@ next-y (fn [cur-val] y)] [size item-width item-height next-x next-y])) -(defn calculate-row-layout [{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}] +(defn- calculate-row-grid + [{:keys [width height x y] :as frame} {:keys [size gutter margin item-length type] :as params}] (let [size (if (number? size) size (calculate-size height item-length margin gutter)) parts (/ height size) item-width width @@ -52,7 +56,8 @@ next-y (fn [cur-val] (+ initial-offset y (* (+ item-height gutter) cur-val)))] [size item-width item-height next-x next-y])) -(defn calculate-grid-layout [{:keys [width height x y] :as frame} {:keys [size] :as params}] +(defn- calculate-square-grid + [{:keys [width height x y] :as frame} {:keys [size] :as params}] (let [col-size (quot width size) row-size (quot height size) as-row-col (fn [value] [(quot value col-size) (rem value col-size)]) @@ -62,12 +67,14 @@ (let [[row _] (as-row-col cur-val)] (+ y (* row size))))] [(* col-size row-size) size size next-x next-y])) -(defn layout-rects [frame layout] - (let [layout-fn (case (-> layout :type) - :column calculate-column-layout - :row calculate-row-layout - :square calculate-grid-layout) - [num-items item-width item-height next-x next-y] (layout-fn frame (-> layout :params))] +(defn grid-areas + "Given a frame and the grid parameters returns the areas defined on the grid" + [frame grid] + (let [grid-fn (case (-> grid :type) + :column calculate-column-grid + :row calculate-row-grid + :square calculate-square-grid) + [num-items item-width item-height next-x next-y] (grid-fn frame (-> grid :params))] (->> (range 0 num-items) (map #(hash-map :x (next-x %) @@ -75,27 +82,35 @@ :width item-width :height item-height))))) -(defn- layout-rect-points [{:keys [x y width height]}] +(defn grid-area-points + [{:keys [x y width height]}] [(gpt/point x y) (gpt/point (+ x width) y) (gpt/point (+ x width) (+ y height)) (gpt/point x (+ y height))]) -(defn- layout-snap-points - ([shape coord] (mapcat #(layout-snap-points shape % coord) (:layouts shape))) - ([shape {:keys [type display params] :as layout} coord] +(defn grid-snap-points + "Returns the snap points for a given grid" + ([shape coord] (mapcat #(grid-snap-points shape % coord) (:grids shape))) + ([shape {:keys [type display params] :as grid} coord] + (when (:display grid) + (case type + :square + (let [{:keys [x y width height]} shape + size (-> params :size)] + (when (> size 0) + (if (= coord :x) + (mapcat #(vector (gpt/point (+ x %) y) + (gpt/point (+ x %) (+ y height))) (range size width size)) + (mapcat #(vector (gpt/point x (+ y %)) + (gpt/point (+ x width) (+ y %))) (range size height size))))) - (case type - :square (let [{:keys [x y width height]} shape - size (-> params :size)] - (when (> size 0) - (if (= coord :x) - (mapcat #(vector (gpt/point (+ x %) y) - (gpt/point (+ x %) (+ y height))) (range size width size)) - (mapcat #(vector (gpt/point x (+ y %)) - (gpt/point (+ x width) (+ y %))) (range size height size))))) - :column (when (= coord :x) (->> (layout-rects shape layout) - (mapcat layout-rect-points))) + :column + (when (= coord :x) + (->> (grid-areas shape grid) + (mapcat grid-area-points))) - :row (when (= coord :y) (->> (layout-rects shape layout) - (mapcat layout-rect-points)))))) + :row + (when (= coord :y) + (->> (grid-areas shape grid) + (mapcat grid-area-points))))))) diff --git a/frontend/src/uxbox/util/geom/snap_points.cljs b/frontend/src/uxbox/util/geom/snap_points.cljs index 6adbf3dfc..ebdfbc54d 100644 --- a/frontend/src/uxbox/util/geom/snap_points.cljs +++ b/frontend/src/uxbox/util/geom/snap_points.cljs @@ -14,7 +14,7 @@ [uxbox.util.geom.shapes :as gsh] [uxbox.util.geom.point :as gpt])) -(defn- frame-snap-points [{:keys [x y width height layouts] :as frame}] +(defn- frame-snap-points [{:keys [x y width height] :as frame}] (into #{(gpt/point x y) (gpt/point (+ x (/ width 2)) y) (gpt/point (+ x width) y) diff --git a/frontend/src/uxbox/worker/snaps.cljs b/frontend/src/uxbox/worker/snaps.cljs index e14883860..e314acda0 100644 --- a/frontend/src/uxbox/worker/snaps.cljs +++ b/frontend/src/uxbox/worker/snaps.cljs @@ -15,20 +15,23 @@ [uxbox.worker.impl :as impl] [uxbox.util.range-tree :as rt] [uxbox.util.geom.snap-points :as snap] - [uxbox.util.geom.layout :as gla])) + [uxbox.util.geom.grid :as gg])) (defonce state (l/atom {})) (defn- create-coord-data "Initializes the range tree given the shapes" - [shapes coord] + [frame-id shapes coord] (let [process-shape (fn [coord] (fn [shape] (concat (let [points (snap/shape-snap-points shape)] (map #(vector % (:id shape)) points)) - (let [points (gla/layout-snap-points shape coord)] - (map #(vector % :layout) points))))) + + ;; The grid points are only added by the "root" of the coord-dat + (if (= (:id shape) frame-id) + (let [points (gg/grid-snap-points shape coord)] + (map #(vector % :layout) points)))))) into-tree (fn [tree [point _ :as data]] (rt/insert tree (coord point) data))] (->> shapes @@ -38,7 +41,7 @@ (defn- mapm "Map over the values of a map" [mfn coll] - (into {} (map (fn [[key val]] [key (mfn val)]) coll))) + (into {} (map (fn [[key val]] [key (mfn key val)]) coll))) (defn- initialize-snap-data "Initialize the snap information with the current workspace information" @@ -48,8 +51,8 @@ (group-by :frame-id)) frame-shapes (->> (cp/select-frames objects) (reduce #(update %1 (:id %2) conj %2) frame-shapes))] - (mapm (fn [shapes] {:x (create-coord-data shapes :x) - :y (create-coord-data shapes :y)}) + (mapm (fn [frame-id shapes] {:x (create-coord-data frame-id shapes :x) + :y (create-coord-data frame-id shapes :y)}) frame-shapes))) (defn- log-state