mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
♻️ Renamed layout to grid and some refactors
This commit is contained in:
parent
235e196094
commit
23ca77fe3a
10 changed files with 203 additions and 171 deletions
|
@ -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
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
83
frontend/src/uxbox/main/data/workspace/grid.cljs
Normal file
83
frontend/src/uxbox/main/data/workspace/grid.cljs
Normal file
|
@ -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})))))
|
|
@ -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
|
||||
|
|
|
@ -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)}])]))
|
|
@ -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}]])
|
||||
|
||||
|
|
|
@ -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}])])]))
|
||||
|
|
@ -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}]
|
||||
|
||||
|
|
|
@ -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)))))))
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue