mirror of
https://github.com/penpot/penpot.git
synced 2025-03-14 08:41:48 -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
|
(rx/of (update-shape shape-id
|
||||||
{:interactions []}))))))))
|
{: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
|
;; 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
|
(def workspace-page-options
|
||||||
(l/derived :options workspace-data))
|
(l/derived :options workspace-data))
|
||||||
|
|
||||||
(def workspace-saved-layouts
|
(def workspace-saved-grids
|
||||||
(l/derived :saved-layouts workspace-page-options))
|
(l/derived :saved-grids workspace-page-options))
|
||||||
|
|
||||||
|
|
||||||
(def workspace-objects
|
(def workspace-objects
|
||||||
|
|
|
@ -7,20 +7,20 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2020 UXBOX Labs SL
|
;; Copyright (c) 2020 UXBOX Labs SL
|
||||||
|
|
||||||
(ns uxbox.main.ui.workspace.layout-display
|
(ns uxbox.main.ui.workspace.frame-grid
|
||||||
(:require
|
(:require
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.common.pages :as cp]
|
[uxbox.common.pages :as cp]
|
||||||
[uxbox.util.geom.shapes :as gsh]
|
[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}]
|
(mf/defc square-grid [{:keys [frame zoom grid] :as props}]
|
||||||
(let [{:keys [color size] :as params} (-> layout :params)
|
(let [{:keys [color size] :as params} (-> grid :params)
|
||||||
{color-value :value color-opacity :opacity} (-> layout :params :color)
|
{color-value :value color-opacity :opacity} (-> grid :params :color)
|
||||||
{frame-width :width frame-height :height :keys [x y]} frame]
|
{frame-width :width frame-height :height :keys [x y]} frame]
|
||||||
(when (> size 0)
|
(when (> size 0)
|
||||||
[:g.layout
|
[:g.grid
|
||||||
[:*
|
[:*
|
||||||
(for [xs (range size frame-width size)]
|
(for [xs (range size frame-width size)]
|
||||||
[:line {:key (str (:id frame) "-y-" xs)
|
[:line {:key (str (:id frame) "-y-" xs)
|
||||||
|
@ -41,10 +41,10 @@
|
||||||
:stroke-opacity color-opacity
|
:stroke-opacity color-opacity
|
||||||
:stroke-width (str (/ 1 zoom))}}])]])))
|
:stroke-width (str (/ 1 zoom))}}])]])))
|
||||||
|
|
||||||
(mf/defc flex-layout [{:keys [key frame zoom layout]}]
|
(mf/defc layout-grid [{:keys [key frame zoom grid]}]
|
||||||
(let [{color-value :value color-opacity :opacity} (-> layout :params :color)]
|
(let [{color-value :value color-opacity :opacity} (-> grid :params :color)]
|
||||||
[:g.layout
|
[:g.grid
|
||||||
(for [{:keys [x y width height]} (ula/layout-rects frame layout)]
|
(for [{:keys [x y width height]} (gg/grid-areas frame grid)]
|
||||||
[:rect {:key (str key "-" x "-" y)
|
[:rect {:key (str key "-" x "-" y)
|
||||||
:x x
|
:x x
|
||||||
:y y
|
:y y
|
||||||
|
@ -53,24 +53,24 @@
|
||||||
:style {:fill color-value
|
:style {:fill color-value
|
||||||
:opacity color-opacity}}])]))
|
:opacity color-opacity}}])]))
|
||||||
|
|
||||||
(mf/defc layout-display-frame [{:keys [frame zoom]}]
|
(mf/defc grid-display-frame [{:keys [frame zoom]}]
|
||||||
(let [layouts (:layouts frame)]
|
(let [grids (:grids frame)]
|
||||||
(for [[index {:keys [type display] :as layout}] (map-indexed vector layouts)]
|
(for [[index {:keys [type display] :as grid}] (map-indexed vector grids)]
|
||||||
(let [props #js {:key (str (:id frame) "-layout-" index)
|
(let [props #js {:key (str (:id frame) "-grid-" index)
|
||||||
:frame frame
|
:frame frame
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:layout layout}]
|
:grid grid}]
|
||||||
(when display
|
(when display
|
||||||
(case type
|
(case type
|
||||||
:square [:> grid-layout props]
|
:square [:> square-grid props]
|
||||||
:column [:> flex-layout props]
|
:column [:> layout-grid props]
|
||||||
:row [:> flex-layout props]))))))
|
:row [:> layout-grid props]))))))
|
||||||
|
|
||||||
|
|
||||||
(mf/defc layout-display [{:keys [zoom]}]
|
(mf/defc frame-grid [{:keys [zoom]}]
|
||||||
(let [frames (mf/deref refs/workspace-frames)]
|
(let [frames (mf/deref refs/workspace-frames)]
|
||||||
[:g.layout-display {:style {:pointer-events "none"}}
|
[:g.grid-display {:style {:pointer-events "none"}}
|
||||||
(for [frame frames]
|
(for [frame frames]
|
||||||
[:& layout-display-frame {:key (str "layout-" (:id frame))
|
[:& grid-display-frame {:key (str "grid-" (:id frame))
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:frame (gsh/transform-shape frame)}])]))
|
:frame (gsh/transform-shape frame)}])]))
|
|
@ -22,7 +22,7 @@
|
||||||
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
[uxbox.main.ui.components.dropdown :refer [dropdown]]
|
||||||
[uxbox.main.ui.workspace.sidebar.options.fill :refer [fill-menu]]
|
[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.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+)
|
(declare +size-presets+)
|
||||||
|
|
||||||
|
@ -204,4 +204,5 @@
|
||||||
[:& measures-menu {:shape shape}]
|
[:& measures-menu {:shape shape}]
|
||||||
[:& fill-menu {:shape shape}]
|
[:& fill-menu {:shape shape}]
|
||||||
[:& stroke-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
|
;; 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
|
(:require
|
||||||
[rumext.alpha :as mf]
|
[rumext.alpha :as mf]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
|
@ -16,8 +16,8 @@
|
||||||
[uxbox.common.data :refer [parse-integer]]
|
[uxbox.common.data :refer [parse-integer]]
|
||||||
[uxbox.main.store :as st]
|
[uxbox.main.store :as st]
|
||||||
[uxbox.main.refs :as refs]
|
[uxbox.main.refs :as refs]
|
||||||
[uxbox.main.data.workspace :as dw]
|
[uxbox.main.data.workspace.grid :as dw]
|
||||||
[uxbox.util.geom.layout :as gla]
|
[uxbox.util.geom.grid :as gg]
|
||||||
[uxbox.main.ui.icons :as i]
|
[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.color-row :refer [color-row]]
|
||||||
[uxbox.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
|
[uxbox.main.ui.workspace.sidebar.options.rows.input-row :refer [input-row]]
|
||||||
|
@ -40,29 +40,29 @@
|
||||||
:separator
|
:separator
|
||||||
18 12 10 8 6 4 3 2])
|
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
|
(let [state (mf/use-state {:show-advanced-options false
|
||||||
:changes {}})
|
: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)
|
toggle-advanced-options #(swap! state update :show-advanced-options not)
|
||||||
|
|
||||||
emit-changes!
|
emit-changes!
|
||||||
(fn [update-fn]
|
(fn [update-fn]
|
||||||
(swap! state update :changes 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
|
handle-toggle-visibility
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(emit-changes! (fn [changes] (update changes :display #(if (nil? %) false (not %))))))
|
(emit-changes! (fn [changes] (update changes :display #(if (nil? %) false (not %))))))
|
||||||
|
|
||||||
handle-remove-layout
|
handle-remove-grid
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(when on-remove (on-remove)))
|
(when on-remove (on-remove)))
|
||||||
|
|
||||||
handle-change-type
|
handle-change-type
|
||||||
(fn [type]
|
(fn [type]
|
||||||
(let [defaults (type default-layout-params)
|
(let [defaults (type default-grid-params)
|
||||||
keys (keys defaults)
|
keys (keys defaults)
|
||||||
params (->> @state :changes params (select-keys keys) (merge defaults))
|
params (->> @state :changes params (select-keys keys) (merge defaults))
|
||||||
to-merge {:type type :params params}]
|
to-merge {:type type :params params}]
|
||||||
|
@ -81,11 +81,11 @@
|
||||||
|
|
||||||
handle-change-size
|
handle-change-size
|
||||||
(fn [size]
|
(fn [size]
|
||||||
(let [layout (d/deep-merge layout (:changes @state))
|
(let [grid (d/deep-merge grid (:changes @state))
|
||||||
{:keys [margin gutter item-length]} (:params layout)
|
{:keys [margin gutter item-length]} (:params grid)
|
||||||
frame-length (if (= :column (:type layout)) (:width frame) (:height frame))
|
frame-length (if (= :column (:type grid)) (:width frame) (:height frame))
|
||||||
item-length (if (or (nil? size) (= :auto size))
|
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))
|
(mth/round))
|
||||||
item-length)]
|
item-length)]
|
||||||
(emit-changes! #(-> %
|
(emit-changes! #(-> %
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
handle-change-item-length
|
handle-change-item-length
|
||||||
(fn [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)]
|
size (if (and (nil? item-length) (or (nil? size) (= :auto size))) 12 size)]
|
||||||
(emit-changes! #(-> %
|
(emit-changes! #(-> %
|
||||||
(assoc-in [:params :size] size)
|
(assoc-in [:params :size] size)
|
||||||
|
@ -102,15 +102,15 @@
|
||||||
|
|
||||||
handle-use-default
|
handle-use-default
|
||||||
(fn []
|
(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
|
handle-set-as-default
|
||||||
(fn []
|
(fn []
|
||||||
(let [current-layout (d/deep-merge layout (-> @state :changes))]
|
(let [current-grid (d/deep-merge grid (-> @state :changes))]
|
||||||
(on-save-layout current-layout)))
|
(on-save-grid current-grid)))
|
||||||
|
|
||||||
is-default (= (->> @state :changes (d/deep-merge layout) :params)
|
is-default (= (->> @state :changes (d/deep-merge grid) :params)
|
||||||
(->> layout :type default-layout-params))]
|
(->> grid :type default-grid-params))]
|
||||||
|
|
||||||
[:div.grid-option
|
[:div.grid-option
|
||||||
[:div.grid-option-main
|
[:div.grid-option-main
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
|
|
||||||
[:div.grid-option-main-actions
|
[: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-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)
|
[:& advanced-options {:visible? (:show-advanced-options @state)
|
||||||
:on-close toggle-advanced-options}
|
:on-close toggle-advanced-options}
|
||||||
|
@ -203,26 +203,26 @@
|
||||||
[:button.btn-options {:disabled is-default
|
[:button.btn-options {:disabled is-default
|
||||||
:on-click handle-set-as-default} "Set as 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)
|
(let [id (:id shape)
|
||||||
default-layout-params (merge dw/default-layout-params (mf/deref refs/workspace-saved-layouts))
|
default-grid-params (merge dw/default-grid-params (mf/deref refs/workspace-saved-grids))
|
||||||
handle-create-layout #(st/emit! (dw/add-frame-layout id))
|
handle-create-grid #(st/emit! (dw/add-frame-grid id))
|
||||||
handle-remove-layout (fn [index] #(st/emit! (dw/remove-frame-layout id index)))
|
handle-remove-grid (fn [index] #(st/emit! (dw/remove-frame-grid id index)))
|
||||||
handle-edit-layout (fn [index] #(st/emit! (dw/set-frame-layout id index %)))
|
handle-edit-grid (fn [index] #(st/emit! (dw/set-frame-grid id index %)))
|
||||||
handle-save-layout (fn [layout] (st/emit! (dw/set-default-layout (:type layout) (:params layout))))]
|
handle-save-grid (fn [grid] (st/emit! (dw/set-default-grid (:type grid) (:params grid))))]
|
||||||
[:div.element-set
|
[:div.element-set
|
||||||
[:div.element-set-title
|
[:div.element-set-title
|
||||||
[:span "Grid & Layout"]
|
[:span "Grids"]
|
||||||
[:div.add-page {:on-click handle-create-layout} i/close]]
|
[:div.add-page {:on-click handle-create-grid} i/close]]
|
||||||
|
|
||||||
(when (not (empty? (:layouts shape)))
|
(when (not (empty? (:grids shape)))
|
||||||
[:div.element-set-content
|
[:div.element-set-content
|
||||||
(for [[index layout] (map-indexed vector (:layouts shape))]
|
(for [[index grid] (map-indexed vector (:grids shape))]
|
||||||
[:& layout-options {:key (str (:id shape) "-" index)
|
[:& grid-options {:key (str (:id shape) "-" index)
|
||||||
:layout layout
|
:grid grid
|
||||||
:default-layout-params default-layout-params
|
:default-grid-params default-grid-params
|
||||||
:frame shape
|
:frame shape
|
||||||
:on-change (handle-edit-layout index)
|
:on-change (handle-edit-grid index)
|
||||||
:on-remove (handle-remove-layout index)
|
:on-remove (handle-remove-grid index)
|
||||||
:on-save-layout handle-save-layout}])])]))
|
:on-save-grid handle-save-grid}])])]))
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
[uxbox.main.ui.workspace.selection :refer [selection-handlers]]
|
[uxbox.main.ui.workspace.selection :refer [selection-handlers]]
|
||||||
[uxbox.main.ui.workspace.presence :as presence]
|
[uxbox.main.ui.workspace.presence :as presence]
|
||||||
[uxbox.main.ui.workspace.snap-feedback :refer [snap-feedback]]
|
[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.math :as mth]
|
||||||
[uxbox.util.dom :as dom]
|
[uxbox.util.dom :as dom]
|
||||||
[uxbox.util.object :as obj]
|
[uxbox.util.object :as obj]
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
:modifiers (:modifiers local)}])
|
:modifiers (:modifiers local)}])
|
||||||
|
|
||||||
(when (contains? layout :display-grid)
|
(when (contains? layout :display-grid)
|
||||||
[:& layout-display {:zoom zoom}])
|
[:& frame-grid {:zoom zoom}])
|
||||||
|
|
||||||
[:& snap-feedback {:layout layout}]
|
[:& snap-feedback {:layout layout}]
|
||||||
|
|
||||||
|
|
|
@ -7,24 +7,27 @@
|
||||||
;;
|
;;
|
||||||
;; Copyright (c) 2020 UXBOX Labs SL
|
;; Copyright (c) 2020 UXBOX Labs SL
|
||||||
|
|
||||||
(ns uxbox.util.geom.layout
|
(ns uxbox.util.geom.grid
|
||||||
(:require
|
(:require
|
||||||
[uxbox.util.math :as mth]
|
[uxbox.util.math :as mth]
|
||||||
[uxbox.util.geom.point :as gpt]))
|
[uxbox.util.geom.point :as gpt]))
|
||||||
|
|
||||||
(def ^:private default-items 12)
|
(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))
|
(/ (- frame-length (+ margin (- margin gutter)) (* gutter default-items)) default-items))
|
||||||
|
|
||||||
(defn calculate-size
|
(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]
|
[frame-length item-length margin gutter]
|
||||||
(let [item-length (or item-length (calculate-default-item-length frame-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)))]
|
frame-length-no-margins (- frame-length (+ margin (- margin gutter)))]
|
||||||
(mth/floor (/ frame-length-no-margins (+ item-length 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))
|
(let [size (if (number? size) size (calculate-size width item-length margin gutter))
|
||||||
parts (/ width size)
|
parts (/ width size)
|
||||||
item-width (or item-length (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
item-width (or item-length (+ parts (- gutter) (/ gutter size) (- (/ (* margin 2) size))))
|
||||||
|
@ -38,7 +41,8 @@
|
||||||
next-y (fn [cur-val] y)]
|
next-y (fn [cur-val] y)]
|
||||||
[size item-width item-height next-x next-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))
|
(let [size (if (number? size) size (calculate-size height item-length margin gutter))
|
||||||
parts (/ height size)
|
parts (/ height size)
|
||||||
item-width width
|
item-width width
|
||||||
|
@ -52,7 +56,8 @@
|
||||||
next-y (fn [cur-val] (+ initial-offset y (* (+ item-height gutter) cur-val)))]
|
next-y (fn [cur-val] (+ initial-offset y (* (+ item-height gutter) cur-val)))]
|
||||||
[size item-width item-height next-x next-y]))
|
[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)
|
(let [col-size (quot width size)
|
||||||
row-size (quot height size)
|
row-size (quot height size)
|
||||||
as-row-col (fn [value] [(quot value col-size) (rem value col-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))))]
|
(let [[row _] (as-row-col cur-val)] (+ y (* row size))))]
|
||||||
[(* col-size row-size) size size next-x next-y]))
|
[(* col-size row-size) size size next-x next-y]))
|
||||||
|
|
||||||
(defn layout-rects [frame layout]
|
(defn grid-areas
|
||||||
(let [layout-fn (case (-> layout :type)
|
"Given a frame and the grid parameters returns the areas defined on the grid"
|
||||||
:column calculate-column-layout
|
[frame grid]
|
||||||
:row calculate-row-layout
|
(let [grid-fn (case (-> grid :type)
|
||||||
:square calculate-grid-layout)
|
:column calculate-column-grid
|
||||||
[num-items item-width item-height next-x next-y] (layout-fn frame (-> layout :params))]
|
: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)
|
(range 0 num-items)
|
||||||
(map #(hash-map :x (next-x %)
|
(map #(hash-map :x (next-x %)
|
||||||
|
@ -75,27 +82,35 @@
|
||||||
:width item-width
|
:width item-width
|
||||||
:height item-height)))))
|
: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 y)
|
||||||
(gpt/point (+ x width) y)
|
(gpt/point (+ x width) y)
|
||||||
(gpt/point (+ x width) (+ y height))
|
(gpt/point (+ x width) (+ y height))
|
||||||
(gpt/point x (+ y height))])
|
(gpt/point x (+ y height))])
|
||||||
|
|
||||||
(defn- layout-snap-points
|
(defn grid-snap-points
|
||||||
([shape coord] (mapcat #(layout-snap-points shape % coord) (:layouts shape)))
|
"Returns the snap points for a given grid"
|
||||||
([shape {:keys [type display params] :as layout} coord]
|
([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
|
:column
|
||||||
:square (let [{:keys [x y width height]} shape
|
(when (= coord :x)
|
||||||
size (-> params :size)]
|
(->> (grid-areas shape grid)
|
||||||
(when (> size 0)
|
(mapcat grid-area-points)))
|
||||||
(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)))
|
|
||||||
|
|
||||||
:row (when (= coord :y) (->> (layout-rects shape layout)
|
:row
|
||||||
(mapcat layout-rect-points))))))
|
(when (= coord :y)
|
||||||
|
(->> (grid-areas shape grid)
|
||||||
|
(mapcat grid-area-points)))))))
|
|
@ -14,7 +14,7 @@
|
||||||
[uxbox.util.geom.shapes :as gsh]
|
[uxbox.util.geom.shapes :as gsh]
|
||||||
[uxbox.util.geom.point :as gpt]))
|
[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)
|
(into #{(gpt/point x y)
|
||||||
(gpt/point (+ x (/ width 2)) y)
|
(gpt/point (+ x (/ width 2)) y)
|
||||||
(gpt/point (+ x width) y)
|
(gpt/point (+ x width) y)
|
||||||
|
|
|
@ -15,20 +15,23 @@
|
||||||
[uxbox.worker.impl :as impl]
|
[uxbox.worker.impl :as impl]
|
||||||
[uxbox.util.range-tree :as rt]
|
[uxbox.util.range-tree :as rt]
|
||||||
[uxbox.util.geom.snap-points :as snap]
|
[uxbox.util.geom.snap-points :as snap]
|
||||||
[uxbox.util.geom.layout :as gla]))
|
[uxbox.util.geom.grid :as gg]))
|
||||||
|
|
||||||
(defonce state (l/atom {}))
|
(defonce state (l/atom {}))
|
||||||
|
|
||||||
(defn- create-coord-data
|
(defn- create-coord-data
|
||||||
"Initializes the range tree given the shapes"
|
"Initializes the range tree given the shapes"
|
||||||
[shapes coord]
|
[frame-id shapes coord]
|
||||||
(let [process-shape (fn [coord]
|
(let [process-shape (fn [coord]
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
(concat
|
(concat
|
||||||
(let [points (snap/shape-snap-points shape)]
|
(let [points (snap/shape-snap-points shape)]
|
||||||
(map #(vector % (:id shape)) points))
|
(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]]
|
into-tree (fn [tree [point _ :as data]]
|
||||||
(rt/insert tree (coord point) data))]
|
(rt/insert tree (coord point) data))]
|
||||||
(->> shapes
|
(->> shapes
|
||||||
|
@ -38,7 +41,7 @@
|
||||||
(defn- mapm
|
(defn- mapm
|
||||||
"Map over the values of a map"
|
"Map over the values of a map"
|
||||||
[mfn coll]
|
[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
|
(defn- initialize-snap-data
|
||||||
"Initialize the snap information with the current workspace information"
|
"Initialize the snap information with the current workspace information"
|
||||||
|
@ -48,8 +51,8 @@
|
||||||
(group-by :frame-id))
|
(group-by :frame-id))
|
||||||
frame-shapes (->> (cp/select-frames objects)
|
frame-shapes (->> (cp/select-frames objects)
|
||||||
(reduce #(update %1 (:id %2) conj %2) frame-shapes))]
|
(reduce #(update %1 (:id %2) conj %2) frame-shapes))]
|
||||||
(mapm (fn [shapes] {:x (create-coord-data shapes :x)
|
(mapm (fn [frame-id shapes] {:x (create-coord-data frame-id shapes :x)
|
||||||
:y (create-coord-data shapes :y)})
|
:y (create-coord-data frame-id shapes :y)})
|
||||||
frame-shapes)))
|
frame-shapes)))
|
||||||
|
|
||||||
(defn- log-state
|
(defn- log-state
|
||||||
|
|
Loading…
Add table
Reference in a new issue