Merge pull request #2996 from penpot/alotor-grid-layout
Partial merge of the grid layout infrastructure
|
@ -288,7 +288,7 @@
|
||||||
|
|
||||||
constraints-h
|
constraints-h
|
||||||
(cond
|
(cond
|
||||||
(and (ctl/layout? parent) (not (ctl/layout-absolute? child)))
|
(and (ctl/any-layout? parent) (not (ctl/layout-absolute? child)))
|
||||||
:left
|
:left
|
||||||
|
|
||||||
(not ignore-constraints)
|
(not ignore-constraints)
|
||||||
|
@ -299,7 +299,7 @@
|
||||||
|
|
||||||
constraints-v
|
constraints-v
|
||||||
(cond
|
(cond
|
||||||
(and (ctl/layout? parent) (not (ctl/layout-absolute? child)))
|
(and (ctl/any-layout? parent) (not (ctl/layout-absolute? child)))
|
||||||
:top
|
:top
|
||||||
|
|
||||||
(not ignore-constraints)
|
(not ignore-constraints)
|
||||||
|
|
19
common/src/app/common/geom/shapes/grid_layout.cljc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.geom.shapes.grid-layout
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.shapes.grid-layout.layout-data :as glld]
|
||||||
|
[app.common.geom.shapes.grid-layout.positions :as glp]))
|
||||||
|
|
||||||
|
(dm/export glld/calc-layout-data)
|
||||||
|
(dm/export glld/get-cell-data)
|
||||||
|
(dm/export glp/child-modifiers)
|
||||||
|
|
||||||
|
(defn get-drop-index
|
||||||
|
[frame objects _position]
|
||||||
|
(dec (count (get-in objects [frame :shapes]))))
|
140
common/src/app/common/geom/shapes/grid_layout/layout_data.cljc
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.geom.shapes.grid-layout.layout-data
|
||||||
|
(:require
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes.points :as gpo]))
|
||||||
|
|
||||||
|
#_(defn set-sample-data
|
||||||
|
[parent children]
|
||||||
|
|
||||||
|
(let [parent (assoc parent
|
||||||
|
:layout-grid-columns
|
||||||
|
[{:type :percent :value 25}
|
||||||
|
{:type :percent :value 25}
|
||||||
|
{:type :fixed :value 100}
|
||||||
|
;;{:type :auto}
|
||||||
|
;;{:type :flex :value 1}
|
||||||
|
]
|
||||||
|
|
||||||
|
:layout-grid-rows
|
||||||
|
[{:type :percent :value 50}
|
||||||
|
{:type :percent :value 50}
|
||||||
|
;;{:type :fixed :value 100}
|
||||||
|
;;{:type :auto}
|
||||||
|
;;{:type :flex :value 1}
|
||||||
|
])
|
||||||
|
|
||||||
|
num-rows (count (:layout-grid-rows parent))
|
||||||
|
num-columns (count (:layout-grid-columns parent))
|
||||||
|
|
||||||
|
layout-grid-cells
|
||||||
|
(into
|
||||||
|
{}
|
||||||
|
(for [[row-idx _row] (d/enumerate (:layout-grid-rows parent))
|
||||||
|
[col-idx _col] (d/enumerate (:layout-grid-columns parent))]
|
||||||
|
(let [[_bounds shape] (nth children (+ (* row-idx num-columns) col-idx) nil)
|
||||||
|
cell-data {:id (uuid/next)
|
||||||
|
:row (inc row-idx)
|
||||||
|
:column (inc col-idx)
|
||||||
|
:row-span 1
|
||||||
|
:col-span 1
|
||||||
|
:shapes (when shape [(:id shape)])}]
|
||||||
|
[(:id cell-data) cell-data])))
|
||||||
|
|
||||||
|
parent (assoc parent :layout-grid-cells layout-grid-cells)]
|
||||||
|
|
||||||
|
[parent children]))
|
||||||
|
|
||||||
|
(defn calculate-initial-track-values
|
||||||
|
[{:keys [type value]} total-value]
|
||||||
|
|
||||||
|
(case type
|
||||||
|
:percent
|
||||||
|
(let [value (/ (* total-value value) 100) ]
|
||||||
|
value)
|
||||||
|
|
||||||
|
:fixed
|
||||||
|
value
|
||||||
|
|
||||||
|
:auto
|
||||||
|
0
|
||||||
|
))
|
||||||
|
|
||||||
|
(defn calc-layout-data
|
||||||
|
[parent _children transformed-parent-bounds]
|
||||||
|
|
||||||
|
(let [height (gpo/height-points transformed-parent-bounds)
|
||||||
|
width (gpo/width-points transformed-parent-bounds)
|
||||||
|
|
||||||
|
;; Initialize tracks
|
||||||
|
column-tracks
|
||||||
|
(->> (:layout-grid-columns parent)
|
||||||
|
(map (fn [track]
|
||||||
|
(let [initial (calculate-initial-track-values track width)]
|
||||||
|
(assoc track :value initial)))))
|
||||||
|
|
||||||
|
row-tracks
|
||||||
|
(->> (:layout-grid-rows parent)
|
||||||
|
(map (fn [track]
|
||||||
|
(let [initial (calculate-initial-track-values track height)]
|
||||||
|
(assoc track :value initial)))))
|
||||||
|
|
||||||
|
;; Go through cells to adjust auto sizes
|
||||||
|
|
||||||
|
|
||||||
|
;; Once auto sizes have been calculated we get calculate the `fr` with the remainining size and adjust the size
|
||||||
|
|
||||||
|
|
||||||
|
;; Adjust final distances
|
||||||
|
|
||||||
|
acc-track-distance
|
||||||
|
(fn [[result next-distance] data]
|
||||||
|
(let [result (conj result (assoc data :distance next-distance))
|
||||||
|
next-distance (+ next-distance (:value data))]
|
||||||
|
[result next-distance]))
|
||||||
|
|
||||||
|
column-tracks
|
||||||
|
(->> column-tracks
|
||||||
|
(reduce acc-track-distance [[] 0])
|
||||||
|
first)
|
||||||
|
|
||||||
|
row-tracks
|
||||||
|
(->> row-tracks
|
||||||
|
(reduce acc-track-distance [[] 0])
|
||||||
|
first)
|
||||||
|
|
||||||
|
shape-cells
|
||||||
|
(into {}
|
||||||
|
(mapcat (fn [[_ cell]]
|
||||||
|
(->> (:shapes cell)
|
||||||
|
(map #(vector % cell)))))
|
||||||
|
(:layout-grid-cells parent))
|
||||||
|
]
|
||||||
|
|
||||||
|
{:row-tracks row-tracks
|
||||||
|
:column-tracks column-tracks
|
||||||
|
:shape-cells shape-cells}))
|
||||||
|
|
||||||
|
(defn get-cell-data
|
||||||
|
[{:keys [row-tracks column-tracks shape-cells]} transformed-parent-bounds [_child-bounds child]]
|
||||||
|
|
||||||
|
(let [origin (gpo/origin transformed-parent-bounds)
|
||||||
|
hv #(gpo/start-hv transformed-parent-bounds %)
|
||||||
|
vv #(gpo/start-vv transformed-parent-bounds %)
|
||||||
|
|
||||||
|
grid-cell (get shape-cells (:id child))]
|
||||||
|
|
||||||
|
(when (some? grid-cell)
|
||||||
|
(let [column (nth column-tracks (dec (:column grid-cell)) nil)
|
||||||
|
row (nth row-tracks (dec (:row grid-cell)) nil)
|
||||||
|
|
||||||
|
start-p (-> origin
|
||||||
|
(gpt/add (hv (:distance column)))
|
||||||
|
(gpt/add (vv (:distance row))))]
|
||||||
|
|
||||||
|
(assoc grid-cell :start-p start-p)))))
|
16
common/src/app/common/geom/shapes/grid_layout/positions.cljc
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.common.geom.shapes.grid-layout.positions
|
||||||
|
(:require
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes.points :as gpo]
|
||||||
|
[app.common.types.modifiers :as ctm]))
|
||||||
|
|
||||||
|
(defn child-modifiers
|
||||||
|
[_parent _transformed-parent-bounds _child child-bounds cell-data]
|
||||||
|
(ctm/move-modifiers
|
||||||
|
(gpt/subtract (:start-p cell-data) (gpo/origin child-bounds))))
|
|
@ -10,7 +10,8 @@
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes.constraints :as gct]
|
[app.common.geom.shapes.constraints :as gct]
|
||||||
[app.common.geom.shapes.flex-layout :as gcl]
|
[app.common.geom.shapes.flex-layout :as gcfl]
|
||||||
|
[app.common.geom.shapes.grid-layout :as gcgl]
|
||||||
[app.common.geom.shapes.pixel-precision :as gpp]
|
[app.common.geom.shapes.pixel-precision :as gpp]
|
||||||
[app.common.geom.shapes.points :as gpo]
|
[app.common.geom.shapes.points :as gpo]
|
||||||
[app.common.geom.shapes.transforms :as gtr]
|
[app.common.geom.shapes.transforms :as gtr]
|
||||||
|
@ -46,51 +47,56 @@
|
||||||
:expr (or (nil? ids) (set? ids))
|
:expr (or (nil? ids) (set? ids))
|
||||||
:hint (dm/str "tree sequence from not set: " ids))
|
:hint (dm/str "tree sequence from not set: " ids))
|
||||||
|
|
||||||
(letfn [(get-tree-root ;; Finds the tree root for the current id
|
(let [get-tree-root
|
||||||
[id]
|
(fn ;; Finds the tree root for the current id
|
||||||
|
[id]
|
||||||
|
|
||||||
(loop [current id
|
(loop [current id
|
||||||
result id]
|
result id]
|
||||||
(let [shape (get objects current)
|
(let [shape (get objects current)
|
||||||
parent (get objects (:parent-id shape))]
|
parent (get objects (:parent-id shape))]
|
||||||
(cond
|
(cond
|
||||||
(or (not shape) (= uuid/zero current))
|
(or (not shape) (= uuid/zero current))
|
||||||
|
result
|
||||||
|
|
||||||
|
;; Frame found, but not layout we return the last layout found (or the id)
|
||||||
|
(and (= :frame (:type parent))
|
||||||
|
(not (ctl/any-layout? parent)))
|
||||||
|
result
|
||||||
|
|
||||||
|
;; Layout found. We continue upward but we mark this layout
|
||||||
|
(ctl/any-layout? parent)
|
||||||
|
(recur (:id parent) (:id parent))
|
||||||
|
|
||||||
|
;; If group or boolean or other type of group we continue with the last result
|
||||||
|
:else
|
||||||
|
(recur (:id parent) result)))))
|
||||||
|
|
||||||
|
is-child? #(cph/is-child? objects %1 %2)
|
||||||
|
|
||||||
|
calculate-common-roots
|
||||||
|
(fn ;; Given some roots retrieves the minimum number of tree roots
|
||||||
|
[result id]
|
||||||
|
(if (= id uuid/zero)
|
||||||
|
result
|
||||||
|
(let [root (get-tree-root id)
|
||||||
|
|
||||||
|
;; Remove the children from the current root
|
||||||
result
|
result
|
||||||
|
(if (cph/has-children? objects root)
|
||||||
|
(into #{} (remove #(is-child? root %)) result)
|
||||||
|
result)
|
||||||
|
|
||||||
;; Frame found, but not layout we return the last layout found (or the id)
|
root-parents (cph/get-parent-ids objects root)
|
||||||
(and (= :frame (:type parent))
|
contains-parent? (some #(contains? result %) root-parents)]
|
||||||
(not (ctl/layout? parent)))
|
(cond-> result
|
||||||
result
|
(not contains-parent?)
|
||||||
|
(conj root)))))
|
||||||
|
|
||||||
;; Layout found. We continue upward but we mark this layout
|
roots (->> ids (reduce calculate-common-roots #{}))]
|
||||||
(ctl/layout? parent)
|
(concat
|
||||||
(recur (:id parent) (:id parent))
|
(when (contains? ids uuid/zero) [(get objects uuid/zero)])
|
||||||
|
(mapcat #(children-sequence % objects) roots))))
|
||||||
;; If group or boolean or other type of group we continue with the last result
|
|
||||||
:else
|
|
||||||
(recur (:id parent) result)))))
|
|
||||||
|
|
||||||
(calculate-common-roots ;; Given some roots retrieves the minimum number of tree roots
|
|
||||||
[result id]
|
|
||||||
(if (= id uuid/zero)
|
|
||||||
result
|
|
||||||
(let [root (get-tree-root id)
|
|
||||||
|
|
||||||
;; Remove the children from the current root
|
|
||||||
result
|
|
||||||
(into #{} (remove #(cph/is-child? objects root %)) result)
|
|
||||||
|
|
||||||
contains-parent?
|
|
||||||
(some #(cph/is-child? objects % root) result)]
|
|
||||||
|
|
||||||
(cond-> result
|
|
||||||
(not contains-parent?)
|
|
||||||
(conj root)))))]
|
|
||||||
|
|
||||||
(let [roots (->> ids (reduce calculate-common-roots #{}))]
|
|
||||||
(concat
|
|
||||||
(when (contains? ids uuid/zero) [(get objects uuid/zero)])
|
|
||||||
(mapcat #(children-sequence % objects) roots)))))
|
|
||||||
|
|
||||||
(defn- set-children-modifiers
|
(defn- set-children-modifiers
|
||||||
"Propagates the modifiers from a parent too its children applying constraints if necesary"
|
"Propagates the modifiers from a parent too its children applying constraints if necesary"
|
||||||
|
@ -152,7 +158,7 @@
|
||||||
(not (ctm/empty? modifiers))
|
(not (ctm/empty? modifiers))
|
||||||
(gtr/transform-bounds modifiers)))))
|
(gtr/transform-bounds modifiers)))))
|
||||||
|
|
||||||
(defn- set-layout-modifiers
|
(defn- set-flex-layout-modifiers
|
||||||
[modif-tree children objects bounds parent transformed-parent-bounds]
|
[modif-tree children objects bounds parent transformed-parent-bounds]
|
||||||
|
|
||||||
(letfn [(apply-modifiers [child]
|
(letfn [(apply-modifiers [child]
|
||||||
|
@ -162,7 +168,7 @@
|
||||||
|
|
||||||
(set-child-modifiers [[layout-line modif-tree] [child-bounds child]]
|
(set-child-modifiers [[layout-line modif-tree] [child-bounds child]]
|
||||||
(let [[modifiers layout-line]
|
(let [[modifiers layout-line]
|
||||||
(gcl/layout-child-modifiers parent transformed-parent-bounds child child-bounds layout-line)
|
(gcfl/layout-child-modifiers parent transformed-parent-bounds child child-bounds layout-line)
|
||||||
|
|
||||||
modif-tree
|
modif-tree
|
||||||
(cond-> modif-tree
|
(cond-> modif-tree
|
||||||
|
@ -175,7 +181,7 @@
|
||||||
(map (d/getf objects))
|
(map (d/getf objects))
|
||||||
(remove :hidden)
|
(remove :hidden)
|
||||||
(map apply-modifiers))
|
(map apply-modifiers))
|
||||||
layout-data (gcl/calc-layout-data parent children @transformed-parent-bounds)
|
layout-data (gcfl/calc-layout-data parent children @transformed-parent-bounds)
|
||||||
children (into [] (cond-> children (not (:reverse? layout-data)) reverse))
|
children (into [] (cond-> children (not (:reverse? layout-data)) reverse))
|
||||||
max-idx (dec (count children))
|
max-idx (dec (count children))
|
||||||
layout-lines (:layout-lines layout-data)]
|
layout-lines (:layout-lines layout-data)]
|
||||||
|
@ -193,6 +199,35 @@
|
||||||
|
|
||||||
modif-tree)))))
|
modif-tree)))))
|
||||||
|
|
||||||
|
(defn- set-grid-layout-modifiers
|
||||||
|
[modif-tree objects bounds parent transformed-parent-bounds]
|
||||||
|
|
||||||
|
(letfn [(apply-modifiers [child]
|
||||||
|
[(-> (get-group-bounds objects bounds modif-tree child)
|
||||||
|
(gpo/parent-coords-bounds @transformed-parent-bounds))
|
||||||
|
child])
|
||||||
|
(set-child-modifiers [modif-tree cell-data [child-bounds child]]
|
||||||
|
(let [modifiers (gcgl/child-modifiers parent transformed-parent-bounds child child-bounds cell-data)
|
||||||
|
modif-tree
|
||||||
|
(cond-> modif-tree
|
||||||
|
(d/not-empty? modifiers)
|
||||||
|
(update-in [(:id child) :modifiers] ctm/add-modifiers modifiers))]
|
||||||
|
modif-tree))]
|
||||||
|
(let [children (->> (cph/get-immediate-children objects (:id parent))
|
||||||
|
(remove :hidden)
|
||||||
|
(map apply-modifiers))
|
||||||
|
grid-data (gcgl/calc-layout-data parent children @transformed-parent-bounds)]
|
||||||
|
(loop [modif-tree modif-tree
|
||||||
|
child (first children)
|
||||||
|
pending (rest children)]
|
||||||
|
(if (some? child)
|
||||||
|
(let [cell-data (gcgl/get-cell-data grid-data @transformed-parent-bounds child)
|
||||||
|
modif-tree (cond-> modif-tree
|
||||||
|
(some? cell-data)
|
||||||
|
(set-child-modifiers cell-data child))]
|
||||||
|
(recur modif-tree (first pending) (rest pending)))
|
||||||
|
modif-tree)))))
|
||||||
|
|
||||||
(defn- calc-auto-modifiers
|
(defn- calc-auto-modifiers
|
||||||
"Calculates the modifiers to adjust the bounds for auto-width/auto-height shapes"
|
"Calculates the modifiers to adjust the bounds for auto-width/auto-height shapes"
|
||||||
[objects bounds parent]
|
[objects bounds parent]
|
||||||
|
@ -218,7 +253,7 @@
|
||||||
|
|
||||||
content-bounds
|
content-bounds
|
||||||
(when (and (d/not-empty? children) (or (ctl/auto-height? parent) (ctl/auto-width? parent)))
|
(when (and (d/not-empty? children) (or (ctl/auto-height? parent) (ctl/auto-width? parent)))
|
||||||
(gcl/layout-content-bounds bounds parent children))
|
(gcfl/layout-content-bounds bounds parent children))
|
||||||
|
|
||||||
auto-width (when content-bounds (gpo/width-points content-bounds))
|
auto-width (when content-bounds (gpo/width-points content-bounds))
|
||||||
auto-height (when content-bounds (gpo/height-points content-bounds))]
|
auto-height (when content-bounds (gpo/height-points content-bounds))]
|
||||||
|
@ -254,20 +289,21 @@
|
||||||
modifiers (-> (dm/get-in modif-tree [parent-id :modifiers])
|
modifiers (-> (dm/get-in modif-tree [parent-id :modifiers])
|
||||||
(ctm/select-geometry))
|
(ctm/select-geometry))
|
||||||
has-modifiers? (ctm/child-modifiers? modifiers)
|
has-modifiers? (ctm/child-modifiers? modifiers)
|
||||||
layout? (ctl/layout? parent)
|
flex-layout? (ctl/flex-layout? parent)
|
||||||
|
grid-layout? (ctl/grid-layout? parent)
|
||||||
auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent))
|
auto? (or (ctl/auto-height? parent) (ctl/auto-width? parent))
|
||||||
parent? (or (cph/group-like-shape? parent) (cph/frame-shape? parent))
|
parent? (or (cph/group-like-shape? parent) (cph/frame-shape? parent))
|
||||||
|
|
||||||
transformed-parent-bounds (delay (gtr/transform-bounds @(get bounds parent-id) modifiers))
|
transformed-parent-bounds (delay (gtr/transform-bounds @(get bounds parent-id) modifiers))
|
||||||
|
|
||||||
children-modifiers
|
children-modifiers
|
||||||
(if layout?
|
(if flex-layout?
|
||||||
(->> (:shapes parent)
|
(->> (:shapes parent)
|
||||||
(filter #(ctl/layout-absolute? objects %)))
|
(filter #(ctl/layout-absolute? objects %)))
|
||||||
(:shapes parent))
|
(:shapes parent))
|
||||||
|
|
||||||
children-layout
|
children-layout
|
||||||
(when layout?
|
(when flex-layout?
|
||||||
(->> (:shapes parent)
|
(->> (:shapes parent)
|
||||||
(remove #(ctl/layout-absolute? objects %))))]
|
(remove #(ctl/layout-absolute? objects %))))]
|
||||||
|
|
||||||
|
@ -275,8 +311,11 @@
|
||||||
(and has-modifiers? parent? (not root?))
|
(and has-modifiers? parent? (not root?))
|
||||||
(set-children-modifiers children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints)
|
(set-children-modifiers children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints)
|
||||||
|
|
||||||
layout?
|
flex-layout?
|
||||||
(set-layout-modifiers children-layout objects bounds parent transformed-parent-bounds))
|
(set-flex-layout-modifiers children-layout objects bounds parent transformed-parent-bounds)
|
||||||
|
|
||||||
|
grid-layout?
|
||||||
|
(set-grid-layout-modifiers objects bounds parent transformed-parent-bounds))
|
||||||
|
|
||||||
;; Auto-width/height can change the positions in the parent so we need to recalculate
|
;; Auto-width/height can change the positions in the parent so we need to recalculate
|
||||||
(cond-> autolayouts auto? (conj (:id parent)))]))
|
(cond-> autolayouts auto? (conj (:id parent)))]))
|
||||||
|
@ -372,7 +411,7 @@
|
||||||
|
|
||||||
to-reflow
|
to-reflow
|
||||||
(cond-> to-reflow
|
(cond-> to-reflow
|
||||||
(and (ctl/layout-descent? objects parent-base)
|
(and (ctl/flex-layout-descent? objects parent-base)
|
||||||
(not= uuid/zero (:frame-id parent-base)))
|
(not= uuid/zero (:frame-id parent-base)))
|
||||||
(conj (:frame-id parent-base)))]
|
(conj (:frame-id parent-base)))]
|
||||||
(recur modif-tree
|
(recur modif-tree
|
||||||
|
@ -404,6 +443,7 @@
|
||||||
([old-modif-tree modif-tree objects
|
([old-modif-tree modif-tree objects
|
||||||
{:keys [ignore-constraints snap-pixel? snap-precision snap-ignore-axis]
|
{:keys [ignore-constraints snap-pixel? snap-precision snap-ignore-axis]
|
||||||
:or {ignore-constraints false snap-pixel? false snap-precision 1 snap-ignore-axis nil}}]
|
:or {ignore-constraints false snap-pixel? false snap-precision 1 snap-ignore-axis nil}}]
|
||||||
|
|
||||||
(let [objects (-> objects
|
(let [objects (-> objects
|
||||||
(cond-> (some? old-modif-tree)
|
(cond-> (some? old-modif-tree)
|
||||||
(apply-structure-modifiers old-modif-tree))
|
(apply-structure-modifiers old-modif-tree))
|
||||||
|
|
|
@ -80,7 +80,7 @@
|
||||||
(fn [modif-tree shape]
|
(fn [modif-tree shape]
|
||||||
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
|
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
|
||||||
(cond-> modif-tree
|
(cond-> modif-tree
|
||||||
(ctm/has-geometry? modifiers)
|
(and (some? modifiers) (ctm/has-geometry? modifiers))
|
||||||
(update-in [(:id shape) :modifiers] set-pixel-precision shape precision ignore-axis))))]
|
(update-in [(:id shape) :modifiers] set-pixel-precision shape precision ignore-axis))))]
|
||||||
|
|
||||||
(->> (keys modif-tree)
|
(->> (keys modif-tree)
|
||||||
|
|
|
@ -76,6 +76,12 @@
|
||||||
(and (not (frame-shape? shape))
|
(and (not (frame-shape? shape))
|
||||||
(= (:frame-id shape) uuid/zero)))
|
(= (:frame-id shape) uuid/zero)))
|
||||||
|
|
||||||
|
(defn has-children?
|
||||||
|
([objects id]
|
||||||
|
(has-children? (get objects id)))
|
||||||
|
([shape]
|
||||||
|
(d/not-empty? (:shapes shape))))
|
||||||
|
|
||||||
(defn get-children-ids
|
(defn get-children-ids
|
||||||
[objects id]
|
[objects id]
|
||||||
(letfn [(get-children-ids-rec
|
(letfn [(get-children-ids-rec
|
||||||
|
@ -487,8 +493,17 @@
|
||||||
|
|
||||||
(defn is-child?
|
(defn is-child?
|
||||||
[objects parent-id candidate-child-id]
|
[objects parent-id candidate-child-id]
|
||||||
(let [parents (get-parent-ids objects candidate-child-id)]
|
(loop [cur-id candidate-child-id]
|
||||||
(some? (d/seek #(= % parent-id) parents))))
|
(let [cur-parent-id (dm/get-in objects [cur-id :parent-id])]
|
||||||
|
(cond
|
||||||
|
(= parent-id cur-parent-id)
|
||||||
|
true
|
||||||
|
|
||||||
|
(or (= cur-parent-id uuid/zero) (nil? cur-parent-id))
|
||||||
|
false
|
||||||
|
|
||||||
|
:else
|
||||||
|
(recur cur-parent-id)))))
|
||||||
|
|
||||||
(defn reduce-objects
|
(defn reduce-objects
|
||||||
([objects reducer-fn init-val]
|
([objects reducer-fn init-val]
|
||||||
|
|
|
@ -6,14 +6,17 @@
|
||||||
|
|
||||||
(ns app.common.types.shape.layout
|
(ns app.common.types.shape.layout
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
[clojure.spec.alpha :as s]))
|
[clojure.spec.alpha :as s]))
|
||||||
|
|
||||||
;; :layout ;; :flex, :grid in the future
|
;; :layout ;; :flex, :grid in the future
|
||||||
;; :layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
|
;; :layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
|
||||||
;; :layout-gap-type ;; :simple, :multiple
|
;; :layout-gap-type ;; :simple, :multiple
|
||||||
;; :layout-gap ;; {:row-gap number , :column-gap number}
|
;; :layout-gap ;; {:row-gap number , :column-gap number}
|
||||||
|
|
||||||
;; :layout-align-items ;; :start :end :center :stretch
|
;; :layout-align-items ;; :start :end :center :stretch
|
||||||
;; :layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly
|
;; :layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly
|
||||||
;; :layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default)
|
;; :layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default)
|
||||||
|
@ -21,6 +24,10 @@
|
||||||
;; :layout-padding-type ;; :simple, :multiple
|
;; :layout-padding-type ;; :simple, :multiple
|
||||||
;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
|
;; :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
|
||||||
|
|
||||||
|
;; layout-grid-rows
|
||||||
|
;; layout-grid-columns
|
||||||
|
;; layout-justify-items
|
||||||
|
|
||||||
;; ITEMS
|
;; ITEMS
|
||||||
;; :layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
|
;; :layout-item-margin ;; {:m1 0 :m2 0 :m3 0 :m4 0}
|
||||||
;; :layout-item-margin-type ;; :simple :multiple
|
;; :layout-item-margin-type ;; :simple :multiple
|
||||||
|
@ -34,15 +41,49 @@
|
||||||
;; :layout-item-z-index
|
;; :layout-item-z-index
|
||||||
|
|
||||||
(s/def ::layout #{:flex :grid})
|
(s/def ::layout #{:flex :grid})
|
||||||
|
|
||||||
(s/def ::layout-flex-dir #{:row :reverse-row :row-reverse :column :reverse-column :column-reverse}) ;;TODO remove reverse-column and reverse-row after script
|
(s/def ::layout-flex-dir #{:row :reverse-row :row-reverse :column :reverse-column :column-reverse}) ;;TODO remove reverse-column and reverse-row after script
|
||||||
|
(s/def ::layout-grid-dir #{:row :column})
|
||||||
(s/def ::layout-gap-type #{:simple :multiple})
|
(s/def ::layout-gap-type #{:simple :multiple})
|
||||||
(s/def ::layout-gap ::us/safe-number)
|
(s/def ::layout-gap ::us/safe-number)
|
||||||
|
|
||||||
(s/def ::layout-align-items #{:start :end :center :stretch})
|
(s/def ::layout-align-items #{:start :end :center :stretch})
|
||||||
|
(s/def ::layout-justify-items #{:start :end :center :stretch})
|
||||||
(s/def ::layout-align-content #{:start :end :center :space-between :space-around :space-evenly :stretch})
|
(s/def ::layout-align-content #{:start :end :center :space-between :space-around :space-evenly :stretch})
|
||||||
(s/def ::layout-justify-content #{:start :center :end :space-between :space-around :space-evenly})
|
(s/def ::layout-justify-content #{:start :center :end :space-between :space-around :space-evenly})
|
||||||
(s/def ::layout-wrap-type #{:wrap :nowrap :no-wrap}) ;;TODO remove no-wrap after script
|
(s/def ::layout-wrap-type #{:wrap :nowrap :no-wrap}) ;;TODO remove no-wrap after script
|
||||||
(s/def ::layout-padding-type #{:simple :multiple})
|
(s/def ::layout-padding-type #{:simple :multiple})
|
||||||
|
|
||||||
|
(s/def :grid/type #{:percent :flex :auto :fixed})
|
||||||
|
(s/def :grid/value (s/nilable ::us/safe-number))
|
||||||
|
(s/def ::grid-definition (s/keys :req-un [:grid/type]
|
||||||
|
:opt-un [:grid/value]))
|
||||||
|
(s/def ::layout-grid-rows (s/coll-of ::grid-definition :kind vector?))
|
||||||
|
(s/def ::layout-grid-columns (s/coll-of ::grid-definition :kind vector?))
|
||||||
|
|
||||||
|
(s/def :grid-cell/id uuid?)
|
||||||
|
(s/def :grid-cell/area-name ::us/string)
|
||||||
|
(s/def :grid-cell/row-start ::us/safe-integer)
|
||||||
|
(s/def :grid-cell/row-span ::us/safe-integer)
|
||||||
|
(s/def :grid-cell/column-start ::us/safe-integer)
|
||||||
|
(s/def :grid-cell/column-span ::us/safe-integer)
|
||||||
|
(s/def :grid-cell/position #{:auto :manual :area})
|
||||||
|
(s/def :grid-cell/align-self #{:auto :start :end :center :stretch})
|
||||||
|
(s/def :grid-cell/justify-self #{:auto :start :end :center :stretch})
|
||||||
|
(s/def :grid-cell/shapes (s/coll-of uuid?))
|
||||||
|
|
||||||
|
(s/def ::grid-cell (s/keys :opt-un [:grid-cell/id
|
||||||
|
:grid-cell/area-name
|
||||||
|
:grid-cell/row-start
|
||||||
|
:grid-cell/row-span
|
||||||
|
:grid-cell/column-start
|
||||||
|
:grid-cell/column-span
|
||||||
|
:grid-cell/position ;; auto, manual, area
|
||||||
|
:grid-cell/align-self
|
||||||
|
:grid-cell/justify-self
|
||||||
|
:grid-cell/shapes]))
|
||||||
|
(s/def ::layout-grid-cells (s/map-of uuid? ::grid-cell))
|
||||||
|
|
||||||
(s/def ::p1 ::us/safe-number)
|
(s/def ::p1 ::us/safe-number)
|
||||||
(s/def ::p2 ::us/safe-number)
|
(s/def ::p2 ::us/safe-number)
|
||||||
(s/def ::p3 ::us/safe-number)
|
(s/def ::p3 ::us/safe-number)
|
||||||
|
@ -67,7 +108,15 @@
|
||||||
::layout-padding
|
::layout-padding
|
||||||
::layout-justify-content
|
::layout-justify-content
|
||||||
::layout-align-items
|
::layout-align-items
|
||||||
::layout-align-content]))
|
::layout-align-content
|
||||||
|
|
||||||
|
;; grid
|
||||||
|
::layout-grid-dir
|
||||||
|
::layout-justify-items
|
||||||
|
::layout-grid-rows
|
||||||
|
::layout-grid-columns
|
||||||
|
::layout-grid-cells
|
||||||
|
]))
|
||||||
|
|
||||||
(s/def ::m1 ::us/safe-number)
|
(s/def ::m1 ::us/safe-number)
|
||||||
(s/def ::m2 ::us/safe-number)
|
(s/def ::m2 ::us/safe-number)
|
||||||
|
@ -100,26 +149,61 @@
|
||||||
::layout-item-absolute
|
::layout-item-absolute
|
||||||
::layout-item-z-index]))
|
::layout-item-z-index]))
|
||||||
|
|
||||||
(defn layout?
|
(defn flex-layout?
|
||||||
([objects id]
|
([objects id]
|
||||||
(layout? (get objects id)))
|
(flex-layout? (get objects id)))
|
||||||
([shape]
|
([shape]
|
||||||
(and (= :frame (:type shape)) (= :flex (:layout shape)))))
|
(and (= :frame (:type shape))
|
||||||
|
(= :flex (:layout shape)))))
|
||||||
|
|
||||||
(defn layout-immediate-child? [objects shape]
|
(defn grid-layout?
|
||||||
|
([objects id]
|
||||||
|
(grid-layout? (get objects id)))
|
||||||
|
([shape]
|
||||||
|
(and (= :frame (:type shape))
|
||||||
|
(= :grid (:layout shape)))))
|
||||||
|
|
||||||
|
(defn any-layout?
|
||||||
|
([objects id]
|
||||||
|
(any-layout? (get objects id)))
|
||||||
|
|
||||||
|
([shape]
|
||||||
|
(or (flex-layout? shape) (grid-layout? shape))))
|
||||||
|
|
||||||
|
(defn flex-layout-immediate-child? [objects shape]
|
||||||
(let [parent-id (:parent-id shape)
|
(let [parent-id (:parent-id shape)
|
||||||
parent (get objects parent-id)]
|
parent (get objects parent-id)]
|
||||||
(layout? parent)))
|
(flex-layout? parent)))
|
||||||
|
|
||||||
(defn layout-immediate-child-id? [objects id]
|
(defn any-layout-immediate-child? [objects shape]
|
||||||
|
(let [parent-id (:parent-id shape)
|
||||||
|
parent (get objects parent-id)]
|
||||||
|
(any-layout? parent)))
|
||||||
|
|
||||||
|
(defn flex-layout-immediate-child-id? [objects id]
|
||||||
(let [parent-id (dm/get-in objects [id :parent-id])
|
(let [parent-id (dm/get-in objects [id :parent-id])
|
||||||
parent (get objects parent-id)]
|
parent (get objects parent-id)]
|
||||||
(layout? parent)))
|
(flex-layout? parent)))
|
||||||
|
|
||||||
(defn layout-descent? [objects shape]
|
(defn any-layout-immediate-child-id? [objects id]
|
||||||
|
(let [parent-id (dm/get-in objects [id :parent-id])
|
||||||
|
parent (get objects parent-id)]
|
||||||
|
(any-layout? parent)))
|
||||||
|
|
||||||
|
(defn flex-layout-descent? [objects shape]
|
||||||
(let [frame-id (:frame-id shape)
|
(let [frame-id (:frame-id shape)
|
||||||
frame (get objects frame-id)]
|
frame (get objects frame-id)]
|
||||||
(layout? frame)))
|
(flex-layout? frame)))
|
||||||
|
|
||||||
|
(defn grid-layout-descent? [objects shape]
|
||||||
|
(let [frame-id (:frame-id shape)
|
||||||
|
frame (get objects frame-id)]
|
||||||
|
(grid-layout? frame)))
|
||||||
|
|
||||||
|
(defn any-layout-descent? [objects shape]
|
||||||
|
(let [frame-id (:frame-id shape)
|
||||||
|
frame (get objects frame-id)]
|
||||||
|
(any-layout? frame)))
|
||||||
|
|
||||||
(defn inside-layout?
|
(defn inside-layout?
|
||||||
"Check if the shape is inside a layout"
|
"Check if the shape is inside a layout"
|
||||||
|
@ -360,7 +444,7 @@
|
||||||
|
|
||||||
(defn change-h-sizing?
|
(defn change-h-sizing?
|
||||||
[frame-id objects children-ids]
|
[frame-id objects children-ids]
|
||||||
(and (layout? objects frame-id)
|
(and (flex-layout? objects frame-id)
|
||||||
(auto-width? objects frame-id)
|
(auto-width? objects frame-id)
|
||||||
(or (and (col? objects frame-id)
|
(or (and (col? objects frame-id)
|
||||||
(->> children-ids
|
(->> children-ids
|
||||||
|
@ -373,7 +457,7 @@
|
||||||
|
|
||||||
(defn change-v-sizing?
|
(defn change-v-sizing?
|
||||||
[frame-id objects children-ids]
|
[frame-id objects children-ids]
|
||||||
(and (layout? objects frame-id)
|
(and (flex-layout? objects frame-id)
|
||||||
(auto-height? objects frame-id)
|
(auto-height? objects frame-id)
|
||||||
(or (and (col? objects frame-id)
|
(or (and (col? objects frame-id)
|
||||||
(some (partial fill-height? objects) children-ids))
|
(some (partial fill-height? objects) children-ids))
|
||||||
|
@ -392,7 +476,12 @@
|
||||||
:layout-padding
|
:layout-padding
|
||||||
:layout-justify-content
|
:layout-justify-content
|
||||||
:layout-align-items
|
:layout-align-items
|
||||||
:layout-align-content))
|
:layout-align-content
|
||||||
|
:layout-grid-dir
|
||||||
|
:layout-justify-items
|
||||||
|
:layout-grid-columns
|
||||||
|
:layout-grid-rows
|
||||||
|
))
|
||||||
|
|
||||||
(defn remove-layout-item-data
|
(defn remove-layout-item-data
|
||||||
[shape]
|
[shape]
|
||||||
|
@ -408,3 +497,91 @@
|
||||||
:layout-item-align-self
|
:layout-item-align-self
|
||||||
:layout-item-absolute
|
:layout-item-absolute
|
||||||
:layout-item-z-index))
|
:layout-item-z-index))
|
||||||
|
(declare assign-cells)
|
||||||
|
|
||||||
|
(def grid-cell-defaults
|
||||||
|
{:row-span 1
|
||||||
|
:column-span 1
|
||||||
|
:position :auto
|
||||||
|
:align-self :auto
|
||||||
|
:justify-self :auto
|
||||||
|
:shapes []})
|
||||||
|
|
||||||
|
;; TODO: GRID ASSIGNMENTS
|
||||||
|
|
||||||
|
;; Adding a track creates the cells. We should check the shapes that are not tracked (with default values) and assign to the correct tracked values
|
||||||
|
(defn add-grid-column
|
||||||
|
[parent value]
|
||||||
|
(us/assert ::grid-definition value)
|
||||||
|
(let [rows (:layout-grid-rows parent)
|
||||||
|
new-col-num (count (:layout-grid-columns parent))
|
||||||
|
|
||||||
|
layout-grid-cells
|
||||||
|
(->> (d/enumerate rows)
|
||||||
|
(reduce (fn [result [row-idx _row]]
|
||||||
|
(let [id (uuid/next)]
|
||||||
|
(assoc result id
|
||||||
|
(merge {:id id
|
||||||
|
:row (inc row-idx)
|
||||||
|
:column new-col-num
|
||||||
|
:track? true}
|
||||||
|
grid-cell-defaults))))
|
||||||
|
(:layout-grid-cells parent)))]
|
||||||
|
(-> parent
|
||||||
|
(update :layout-grid-columns (fnil conj []) value)
|
||||||
|
(assoc :layout-grid-cells layout-grid-cells))))
|
||||||
|
|
||||||
|
(defn add-grid-row
|
||||||
|
[parent value]
|
||||||
|
(us/assert ::grid-definition value)
|
||||||
|
(let [cols (:layout-grid-columns parent)
|
||||||
|
new-row-num (inc (count (:layout-grid-rows parent)))
|
||||||
|
|
||||||
|
layout-grid-cells
|
||||||
|
(->> (d/enumerate cols)
|
||||||
|
(reduce (fn [result [col-idx _col]]
|
||||||
|
(let [id (uuid/next)]
|
||||||
|
(assoc result id
|
||||||
|
(merge {:id id
|
||||||
|
:column (inc col-idx)
|
||||||
|
:row new-row-num
|
||||||
|
:track? true}
|
||||||
|
grid-cell-defaults))))
|
||||||
|
(:layout-grid-cells parent)))]
|
||||||
|
(-> parent
|
||||||
|
(update :layout-grid-rows (fnil conj []) value)
|
||||||
|
(assoc :layout-grid-cells layout-grid-cells))))
|
||||||
|
|
||||||
|
;; TODO: Remove a track and its corresponding cells. We need to reassign the orphaned shapes into not-tracked cells
|
||||||
|
(defn remove-grid-column
|
||||||
|
[parent _index]
|
||||||
|
parent)
|
||||||
|
|
||||||
|
(defn remove-grid-row
|
||||||
|
[parent _index]
|
||||||
|
parent)
|
||||||
|
|
||||||
|
;; TODO: Mix the cells given as arguments leaving only one. It should move all the shapes in those cells in the direction for the grid
|
||||||
|
;; and lastly use assign-cells to reassing the orphaned shapes
|
||||||
|
(defn merge-cells
|
||||||
|
[parent _cells]
|
||||||
|
parent)
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO
|
||||||
|
;; Assign cells takes the children and move them into the allotted cells. If there are not enough cells it creates
|
||||||
|
;; not-tracked rows/columns and put the shapes there
|
||||||
|
;; Should be caled each time a child can be added like:
|
||||||
|
;; - On shape creation
|
||||||
|
;; - When moving a child from layers
|
||||||
|
;; - Moving from the transform into a cell and there are shapes without cell
|
||||||
|
;; - Shape duplication
|
||||||
|
;; - (maybe) create group/frames. This case will assigna a cell that had one of its children
|
||||||
|
(defn assign-cells
|
||||||
|
[parent]
|
||||||
|
#_(let [allocated-shapes
|
||||||
|
(into #{} (mapcat :shapes) (:layout-grid-cells parent))
|
||||||
|
|
||||||
|
no-cell-shapes
|
||||||
|
(->> (:shapes parent) (remove allocated-shapes))])
|
||||||
|
parent)
|
||||||
|
|
|
@ -164,7 +164,7 @@
|
||||||
:else
|
:else
|
||||||
;; If the base is a layout we should check if the z-index property is set
|
;; If the base is a layout we should check if the z-index property is set
|
||||||
(let [[z-index-a z-index-b]
|
(let [[z-index-a z-index-b]
|
||||||
(if (ctl/layout? objects base)
|
(if (ctl/any-layout? objects base)
|
||||||
[(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-a]))
|
[(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-a]))
|
||||||
(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-b]))]
|
(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-b]))]
|
||||||
[0 0])]
|
[0 0])]
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-column-around.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 0 0 L 0 11.207096 L 132.292 11.207096 L 132.292 0 L 0 0 z M 29.530055 30.909819 L 29.530055 60.636245 L 60.606789 60.636245 L 60.606789 30.909819 L 29.530055 30.909819 z M 71.685211 30.909819 L 71.685211 60.636245 L 102.76401 60.636245 L 102.76401 30.909819 L 71.685211 30.909819 z M 29.62824 71.655755 L 29.62824 101.38218 L 60.606789 101.38218 L 60.606789 71.655755 L 29.62824 71.655755 z M 71.685211 71.655755 L 71.685211 101.38218 L 102.76401 101.38218 L 102.76401 71.655755 L 71.685211 71.655755 z M 132.292 121.0849 L 0 121.08594 L 0 132.292 L 132.292 132.292 L 132.292 121.0849 z " />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-column-between.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 0 0 L 0 11.207096 L 132.292 11.207096 L 132.292 0 L 0 0 z M 29.530055 21.913963 L 29.530055 51.639872 L 60.34944 51.639872 L 60.34944 21.913963 L 29.530055 21.913963 z M 71.94256 21.913963 L 71.94256 51.639872 L 102.76401 51.639872 L 102.76401 21.913963 L 71.94256 21.913963 z M 29.62824 80.652128 L 29.62824 110.37804 L 60.34944 110.37804 L 60.34944 80.652128 L 29.62824 80.652128 z M 71.94256 80.652128 L 71.94256 110.37804 L 102.76401 110.37804 L 102.76401 80.652128 L 71.94256 80.652128 z M 0 121.0849 L 0 132.292 L 132.292 132.292 L 132.292 121.0849 L 0 121.0849 z " />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-column-center.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 29.530055 19.533224 L 29.530055 49.259133 L 60.34944 49.259133 L 60.34944 19.533224 L 29.530055 19.533224 z M 71.94256 19.533224 L 71.94256 49.259133 L 102.76401 49.259133 L 102.76401 19.533224 L 71.94256 19.533224 z M 0 60.325152 L 0 71.532248 L 132.292 71.532248 L 132.292 60.325152 L 0 60.325152 z M 29.62824 83.032867 L 29.62824 112.75878 L 60.34944 112.75878 L 60.34944 83.032867 L 29.62824 83.032867 z M 71.94256 83.032867 L 71.94256 112.75878 L 102.76401 112.75878 L 102.76401 83.032867 L 71.94256 83.032867 z " />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-column-end.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 0,132.292 V 121.0849 H 132.292 V 132.292 Z M 29.530055,109.58377 V 79.857859 H 60.54271 v 29.725911 z m 42.219235,0 V 79.857859 h 31.01472 V 109.58377 Z M 29.62824,65.134173 V 35.407747 h 30.91447 v 29.726426 z m 42.12105,0 V 35.407747 h 31.01472 v 29.726426 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-column-start.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 0 0 L 0 11.207096 L 132.292 11.207096 L 132.292 0 L 0 0 z M 29.530055 22.708232 L 29.530055 52.434141 L 60.54271 52.434141 L 60.54271 22.708232 L 29.530055 22.708232 z M 71.74929 22.708232 L 71.74929 52.434141 L 102.76401 52.434141 L 102.76401 22.708232 L 71.74929 22.708232 z M 29.62824 67.157827 L 29.62824 96.884253 L 60.54271 96.884253 L 60.54271 67.157827 L 29.62824 67.157827 z M 71.74929 67.157827 L 71.74929 96.884253 L 102.76401 96.884253 L 102.76401 67.157827 L 71.74929 67.157827 z " />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-row-around.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250.48685"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 132.292,0 H 121.0849 V 132.292 H 132.292 Z M 101.38218,29.530055 H 71.655755 v 31.076734 h 29.726425 z m 0,42.155156 H 71.655755 V 102.76401 H 101.38218 Z M 60.636245,29.62824 H 30.90982 v 30.978549 h 29.726425 z m 0,42.056971 H 30.90982 V 102.76401 H 60.636245 Z M 11.2071,132.292 11.20606,0 H 0 v 132.292 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-row-between.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250.48685"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 132.292,0 H 121.0849 V 132.292 H 132.292 Z M 110.37804,29.530055 H 80.652128 V 60.34944 h 29.725912 z m 0,42.412505 H 80.652128 v 30.82145 H 110.37804 Z M 51.639872,29.62824 H 21.91396 v 30.7212 h 29.725912 z m 0,42.31432 H 21.91396 v 30.82145 H 51.639872 Z M 11.2071,0 H 0 v 132.292 h 11.2071 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-row-center.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250.48685"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 112.75878,29.530057 H 83.032868 v 30.819385 h 29.725912 z m 0,42.412505 H 83.032868 V 102.76401 H 112.75878 Z M 71.966849,2e-6 H 60.759753 V 132.292 H 71.966849 Z M 49.259134,29.628242 H 19.533221 v 30.7212 h 29.725913 z m 0,42.31432 H 19.533221 v 30.821448 h 29.725913 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-row-end.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 132.292,1.5e-6 H 121.0849 V 132.292 H 132.292 Z M 109.58377,29.530058 H 79.857859 v 31.012654 h 29.725911 z m 0,42.219234 H 79.857859 V 102.76401 H 109.58377 Z M 65.134173,29.628242 h -29.72643 v 30.91447 h 29.72643 z m 0,42.12105 h -29.72643 v 31.014718 h 29.72643 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
viewBox="0 0 132.292 132.292"
|
||||||
|
version="1.1"
|
||||||
|
id="svg4"
|
||||||
|
sodipodi:docname="grid-justify-content-row-start.svg"
|
||||||
|
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs8" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview6"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.054"
|
||||||
|
inkscape:cx="250"
|
||||||
|
inkscape:cy="249.75657"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2066"
|
||||||
|
inkscape:window-x="2869"
|
||||||
|
inkscape:window-y="-11"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg4" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
d="M 0,1.5e-6 H 11.2071 V 132.292 H 0 Z M 22.70823,29.530058 H 52.434141 V 60.542712 H 22.70823 Z m 0,42.219234 H 52.434141 V 102.76401 H 22.70823 Z m 44.449597,-42.12105 h 29.72643 v 30.91447 h -29.72643 z m 0,42.12105 h 29.72643 v 31.014718 h -29.72643 z" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
3
frontend/resources/images/icons/grid-layout-mode.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
||||||
|
<path d="M0 0h500v500H0Zm50 50v400h400V50Zm241.416 73.877c-5.652 0-10.234 4.582-10.234 10.234v71.637c0 5.652 4.582 10.234 10.234 10.234h71.638c5.652 0 10.234-4.582 10.234-10.234v-71.637c0-5.652-4.582-10.234-10.234-10.234zm-157.894 0c-5.652 0-10.234 4.582-10.234 10.234v71.637c0 5.652 4.582 10.234 10.234 10.234h71.637c5.652 0 10.234-4.582 10.234-10.234v-71.637c0-5.652-4.582-10.234-10.234-10.234zM291.416 281.77c-5.652 0-10.234 4.582-10.234 10.234v71.638c0 5.652 4.582 10.234 10.234 10.234h71.638c5.652 0 10.234-4.582 10.234-10.234v-71.638c0-5.652-4.582-10.234-10.234-10.234zm-157.894 0c-5.652 0-10.234 4.582-10.234 10.234v71.638c0 5.652 4.582 10.234 10.234 10.234h71.637c5.652 0 10.234-4.582 10.234-10.234v-71.638c0-5.652-4.582-10.234-10.234-10.234z"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 826 B |
|
@ -1,3 +1,3 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewBox="0 0 132.292 132.292">
|
||||||
<path d="M0 0h500v500H0Zm50 50v400h400V50Zm241.416 73.877c-5.652 0-10.234 4.582-10.234 10.234v71.637c0 5.652 4.582 10.234 10.234 10.234h71.638c5.652 0 10.234-4.582 10.234-10.234v-71.637c0-5.652-4.582-10.234-10.234-10.234zm-157.894 0c-5.652 0-10.234 4.582-10.234 10.234v71.637c0 5.652 4.582 10.234 10.234 10.234h71.637c5.652 0 10.234-4.582 10.234-10.234v-71.637c0-5.652-4.582-10.234-10.234-10.234zM291.416 281.77c-5.652 0-10.234 4.582-10.234 10.234v71.638c0 5.652 4.582 10.234 10.234 10.234h71.638c5.652 0 10.234-4.582 10.234-10.234v-71.638c0-5.652-4.582-10.234-10.234-10.234zm-157.894 0c-5.652 0-10.234 4.582-10.234 10.234v71.638c0 5.652 4.582 10.234 10.234 10.234h71.637c5.652 0 10.234-4.582 10.234-10.234v-71.638c0-5.652-4.582-10.234-10.234-10.234z"/>
|
<path d="M0 0v35.454L35.454 0Zm44 0v11.232h77.06v77.642h11.232V0ZM0 43.418v88.874h88.292V121.06h-77.06V43.418Zm132.292 53.42-35.454 35.454h35.454Zm-86.73-57.15a5.877 5.877 0 0 0-5.874 5.873v41.17a5.877 5.877 0 0 0 5.873 5.873h41.17a5.877 5.877 0 0 0 5.873-5.873V45.56a5.877 5.877 0 0 0-5.873-5.873z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 407 B |
|
@ -1624,7 +1624,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-menu,
|
.layout-menu,
|
||||||
.layout-item-menu {
|
.layout-item-menu,
|
||||||
|
.layout-grid-item-menu {
|
||||||
font-family: "worksans", sans-serif;
|
font-family: "worksans", sans-serif;
|
||||||
svg {
|
svg {
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
@ -1649,11 +1650,18 @@
|
||||||
align-items: start;
|
align-items: start;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.align-items-grid,
|
||||||
|
&.jusfiy-content-grid {
|
||||||
|
align-items: start;
|
||||||
|
margin-top: 11px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.btn-wrapper {
|
.btn-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 185px;
|
max-width: 185px;
|
||||||
|
|
||||||
&.wrap {
|
&.wrap {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
@ -1697,7 +1705,9 @@
|
||||||
color: $color-gray-20;
|
color: $color-gray-20;
|
||||||
&.active,
|
&.active,
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-primary;
|
&.dir {
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
svg {
|
svg {
|
||||||
fill: $color-primary;
|
fill: $color-primary;
|
||||||
}
|
}
|
||||||
|
@ -1748,6 +1758,60 @@
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit-mode {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 5px;
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
&.active,
|
||||||
|
&:hover {
|
||||||
|
svg {
|
||||||
|
fill: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.align-grid {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 7px;
|
||||||
|
margin: 7px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.position-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr 1fr;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 185px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid $color-gray-60;
|
||||||
|
.position-btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $color-gray-20;
|
||||||
|
border-right: 1px solid $color-gray-60;
|
||||||
|
&:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
&.active,
|
||||||
|
&:hover {
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.no-wrap {
|
.no-wrap {
|
||||||
|
@ -2076,6 +2140,147 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid-columns {
|
||||||
|
border: 1px solid $color-gray-60;
|
||||||
|
padding: 5px;
|
||||||
|
min-height: 38px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.grid-columns-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
min-height: 36px;
|
||||||
|
.columns-info {
|
||||||
|
flex-grow: 1;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.expand-icon,
|
||||||
|
.add-column {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.active,
|
||||||
|
&:hover {
|
||||||
|
svg {
|
||||||
|
fill: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-column svg {
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
fill: $color-gray-20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.columns-info-wrapper {
|
||||||
|
.column-info {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 35px 1fr 1fr auto;
|
||||||
|
background-color: $color-gray-60;
|
||||||
|
padding: 3px;
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
.direction-grid-icon {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
background-color: $color-gray-60;
|
||||||
|
}
|
||||||
|
.grid-column-value,
|
||||||
|
.grid-column-unit {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 30px;
|
||||||
|
&.active,
|
||||||
|
&:focus,
|
||||||
|
&:focus-within {
|
||||||
|
border-bottom: 1px solid $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.grid-column-unit-selector {
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid $color-gray-30;
|
||||||
|
margin: 0.25rem 0;
|
||||||
|
height: 23px;
|
||||||
|
width: 100%;
|
||||||
|
&:hover {
|
||||||
|
border-bottom: 1px solid $color-gray-20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.remove-grid-column {
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 40px;
|
||||||
|
svg {
|
||||||
|
height: 12px;
|
||||||
|
width: 12px;
|
||||||
|
fill: $color-gray-20;
|
||||||
|
}
|
||||||
|
&.active,
|
||||||
|
&:hover {
|
||||||
|
svg {
|
||||||
|
fill: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.manage-grid-columns {
|
||||||
|
margin-left: 60px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
.grid-auto,
|
||||||
|
.grid-manual {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
.grid-columns-auto,
|
||||||
|
.grid-rows-auto {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20px 1fr;
|
||||||
|
.icon {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.grid-manual {
|
||||||
|
.input-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.advanced-ops {
|
.advanced-ops {
|
||||||
|
|
|
@ -660,7 +660,7 @@
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
|
|
||||||
;; Remove layout-item properties when moving a shape outside a layout
|
;; Remove layout-item properties when moving a shape outside a layout
|
||||||
(cond-> (not (ctl/layout? objects parent-id))
|
(cond-> (not (ctl/any-layout? objects parent-id))
|
||||||
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
||||||
|
|
||||||
;; Move the shapes
|
;; Move the shapes
|
||||||
|
@ -714,7 +714,7 @@
|
||||||
;; Fix the sizing when moving a shape
|
;; Fix the sizing when moving a shape
|
||||||
(pcb/update-shapes parents
|
(pcb/update-shapes parents
|
||||||
(fn [parent]
|
(fn [parent]
|
||||||
(if (ctl/layout? parent)
|
(if (ctl/flex-layout? parent)
|
||||||
(cond-> parent
|
(cond-> parent
|
||||||
(ctl/change-h-sizing? (:id parent) objects (:shapes parent))
|
(ctl/change-h-sizing? (:id parent) objects (:shapes parent))
|
||||||
(assoc :layout-item-h-sizing :fix)
|
(assoc :layout-item-h-sizing :fix)
|
||||||
|
|
|
@ -82,8 +82,9 @@
|
||||||
focus (:workspace-focus-selected state)
|
focus (:workspace-focus-selected state)
|
||||||
|
|
||||||
fid (ctst/top-nested-frame objects initial)
|
fid (ctst/top-nested-frame objects initial)
|
||||||
layout? (ctl/layout? objects fid)
|
|
||||||
drop-index (when layout? (gsl/get-drop-index fid objects initial))
|
flex-layout? (ctl/flex-layout? objects fid)
|
||||||
|
drop-index (when flex-layout? (gsl/get-drop-index fid objects initial))
|
||||||
|
|
||||||
shape (get-in state [:workspace-drawing :object])
|
shape (get-in state [:workspace-drawing :object])
|
||||||
shape (-> shape
|
shape (-> shape
|
||||||
|
|
|
@ -47,12 +47,12 @@
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
|
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
content (get-in state [:workspace-drawing :object :content] [])
|
content (get-in state [:workspace-drawing :object :content] [])
|
||||||
position (gpt/point (get-in content [0 :params] nil))
|
position (gpt/point (get-in content [0 :params] nil))
|
||||||
frame-id (ctst/top-nested-frame objects position)
|
frame-id (ctst/top-nested-frame objects position)
|
||||||
layout? (ctl/layout? objects frame-id)
|
flex-layout? (ctl/flex-layout? objects frame-id)
|
||||||
drop-index (when layout? (gsl/get-drop-index frame-id objects position))]
|
drop-index (when flex-layout? (gsl/get-drop-index frame-id objects position))]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:workspace-drawing :object :frame-id] frame-id)
|
(assoc-in [:workspace-drawing :object :frame-id] frame-id)
|
||||||
(cond-> (some? drop-index)
|
(cond-> (some? drop-index)
|
||||||
|
|
44
frontend/src/app/main/data/workspace/grid_layout/editor.cljs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.data.workspace.grid-layout.editor
|
||||||
|
(:require
|
||||||
|
[potok.core :as ptk]))
|
||||||
|
|
||||||
|
(defn hover-grid-cell
|
||||||
|
[grid-id row column add-to-set]
|
||||||
|
(ptk/reify ::hover-grid-cell
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in
|
||||||
|
state
|
||||||
|
[:workspace-grid-edition grid-id :hover]
|
||||||
|
(fn [hover-set]
|
||||||
|
(let [hover-set (or hover-set #{})]
|
||||||
|
(if add-to-set
|
||||||
|
(conj hover-set [row column])
|
||||||
|
(disj hover-set [row column]))))))))
|
||||||
|
|
||||||
|
(defn select-grid-cell
|
||||||
|
[grid-id row column]
|
||||||
|
(ptk/reify ::hover-grid-cell
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(assoc-in state [:workspace-grid-edition grid-id :selected] [row column]))))
|
||||||
|
|
||||||
|
(defn remove-selection
|
||||||
|
[grid-id]
|
||||||
|
(ptk/reify ::hover-grid-cell
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update-in state [:workspace-grid-edition grid-id] dissoc :selected))))
|
||||||
|
|
||||||
|
(defn stop-grid-layout-editing
|
||||||
|
[grid-id]
|
||||||
|
(ptk/reify ::stop-grid-layout-editing
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :workspace-grid-edition dissoc grid-id))))
|
|
@ -144,7 +144,7 @@
|
||||||
|
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
(cond-> (ctl/layout? frame)
|
(cond-> (ctl/any-layout? frame)
|
||||||
(pcb/update-shapes (:shapes frame) ctl/remove-layout-item-data))
|
(pcb/update-shapes (:shapes frame) ctl/remove-layout-item-data))
|
||||||
(pcb/change-parent parent-id children idx-in-parent)
|
(pcb/change-parent parent-id children idx-in-parent)
|
||||||
(pcb/remove-objects [(:id frame)]))))
|
(pcb/remove-objects [(:id frame)]))))
|
||||||
|
|
|
@ -179,8 +179,8 @@
|
||||||
(let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
|
(let [origin-frame-ids (->> selected (group-by #(get-in objects [% :frame-id])))
|
||||||
child-set (set (get-in objects [target-frame-id :shapes]))
|
child-set (set (get-in objects [target-frame-id :shapes]))
|
||||||
|
|
||||||
target-frame (get objects target-frame-id)
|
target-frame (get objects target-frame-id)
|
||||||
target-layout? (ctl/layout? target-frame)
|
target-flex-layout? (ctl/flex-layout? target-frame)
|
||||||
|
|
||||||
children-ids (concat (:shapes target-frame) selected)
|
children-ids (concat (:shapes target-frame) selected)
|
||||||
|
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
(fn [modif-tree [original-frame shapes]]
|
(fn [modif-tree [original-frame shapes]]
|
||||||
(let [shapes (->> shapes (d/removev #(= target-frame-id %)))
|
(let [shapes (->> shapes (d/removev #(= target-frame-id %)))
|
||||||
shapes (cond->> shapes
|
shapes (cond->> shapes
|
||||||
(and target-layout? (= original-frame target-frame-id))
|
(and target-flex-layout? (= original-frame target-frame-id))
|
||||||
;; When movining inside a layout frame remove the shapes that are not immediate children
|
;; When movining inside a layout frame remove the shapes that are not immediate children
|
||||||
(filterv #(contains? child-set %)))
|
(filterv #(contains? child-set %)))
|
||||||
children-ids (->> (dm/get-in objects [original-frame :shapes])
|
children-ids (->> (dm/get-in objects [original-frame :shapes])
|
||||||
|
@ -219,7 +219,7 @@
|
||||||
(cond-> v-sizing?
|
(cond-> v-sizing?
|
||||||
(update-in [original-frame :modifiers] ctm/change-property :layout-item-v-sizing :fix)))
|
(update-in [original-frame :modifiers] ctm/change-property :layout-item-v-sizing :fix)))
|
||||||
|
|
||||||
(and target-layout? (= original-frame target-frame-id))
|
(and target-flex-layout? (= original-frame target-frame-id))
|
||||||
(update-in [target-frame-id :modifiers] ctm/add-children shapes drop-index))))]
|
(update-in [target-frame-id :modifiers] ctm/add-children shapes drop-index))))]
|
||||||
|
|
||||||
(as-> modif-tree $
|
(as-> modif-tree $
|
||||||
|
|
|
@ -240,12 +240,12 @@
|
||||||
(ptk/reify ::setup-frame-path
|
(ptk/reify ::setup-frame-path
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
content (get-in state [:workspace-drawing :object :content] [])
|
content (get-in state [:workspace-drawing :object :content] [])
|
||||||
position (gpt/point (get-in content [0 :params] nil))
|
position (gpt/point (get-in content [0 :params] nil))
|
||||||
frame-id (ctst/top-nested-frame objects position)
|
frame-id (ctst/top-nested-frame objects position)
|
||||||
layout? (ctl/layout? objects frame-id)
|
flex-layout? (ctl/flex-layout? objects frame-id)
|
||||||
drop-index (when layout? (gsl/get-drop-index frame-id objects position))]
|
drop-index (when flex-layout? (gsl/get-drop-index frame-id objects position))]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc-in [:workspace-drawing :object :frame-id] frame-id)
|
(assoc-in [:workspace-drawing :object :frame-id] frame-id)
|
||||||
(cond-> (some? drop-index)
|
(cond-> (some? drop-index)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
; 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
|
;; 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/.
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
;;
|
;;
|
||||||
|
@ -53,14 +53,29 @@
|
||||||
:layout-padding {:p1 0 :p2 0 :p3 0 :p4 0}})
|
:layout-padding {:p1 0 :p2 0 :p3 0 :p4 0}})
|
||||||
|
|
||||||
(def initial-grid-layout ;; TODO
|
(def initial-grid-layout ;; TODO
|
||||||
{:layout :grid})
|
{:layout :grid
|
||||||
|
:layout-grid-dir :row
|
||||||
|
:layout-gap-type :multiple
|
||||||
|
:layout-gap {:row-gap 0 :column-gap 0}
|
||||||
|
:layout-align-items :start
|
||||||
|
:layout-align-content :stretch
|
||||||
|
:layout-justify-items :start
|
||||||
|
:layout-justify-content :start
|
||||||
|
:layout-padding-type :simple
|
||||||
|
:layout-padding {:p1 0 :p2 0 :p3 0 :p4 0}
|
||||||
|
:layout-grid-rows []
|
||||||
|
:layout-grid-columns []})
|
||||||
|
|
||||||
(defn get-layout-initializer
|
(defn get-layout-initializer
|
||||||
[type from-frame?]
|
[type from-frame?]
|
||||||
(let [initial-layout-data (if (= type :flex) initial-flex-layout initial-grid-layout)]
|
(let [initial-layout-data
|
||||||
|
(case type
|
||||||
|
:flex initial-flex-layout
|
||||||
|
:grid initial-grid-layout)]
|
||||||
(fn [shape]
|
(fn [shape]
|
||||||
(-> shape
|
(-> shape
|
||||||
(merge initial-layout-data)
|
(merge initial-layout-data)
|
||||||
|
(cond-> (= type :grid) ctl/assign-cells)
|
||||||
;; If the original shape is not a frame we set clip content and show-viewer to false
|
;; If the original shape is not a frame we set clip content and show-viewer to false
|
||||||
(cond-> (not from-frame?)
|
(cond-> (not from-frame?)
|
||||||
(assoc :show-content true :hide-in-viewer true))))))
|
(assoc :show-content true :hide-in-viewer true))))))
|
||||||
|
@ -140,6 +155,13 @@
|
||||||
:layout-align-items :center
|
:layout-align-items :center
|
||||||
:layout-gap layout-gap)))))
|
:layout-gap layout-gap)))))
|
||||||
|
|
||||||
|
(defn shapes->grid-params
|
||||||
|
"Given the shapes calculate its flex parameters (horizontal vs vertical, gaps, etc)"
|
||||||
|
([objects shapes]
|
||||||
|
(shapes->flex-params objects shapes nil))
|
||||||
|
([_objects _shapes _parent]
|
||||||
|
{}))
|
||||||
|
|
||||||
(defn create-layout-from-id
|
(defn create-layout-from-id
|
||||||
[ids type from-frame?]
|
[ids type from-frame?]
|
||||||
(ptk/reify ::create-layout-from-id
|
(ptk/reify ::create-layout-from-id
|
||||||
|
@ -149,8 +171,10 @@
|
||||||
children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids)
|
children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids)
|
||||||
children-shapes (map (d/getf objects) children-ids)
|
children-shapes (map (d/getf objects) children-ids)
|
||||||
parent (get objects (first ids))
|
parent (get objects (first ids))
|
||||||
flex-params (when (d/not-empty? children-shapes)
|
layout-params (when (d/not-empty? children-shapes)
|
||||||
(shapes->flex-params objects children-shapes parent))
|
(case type
|
||||||
|
:flex (shapes->flex-params objects children-shapes parent)
|
||||||
|
:grid (shapes->grid-params objects children-shapes parent)))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
(rx/of (dwu/start-undo-transaction undo-id)
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
(dwc/update-shapes ids (get-layout-initializer type from-frame?))
|
(dwc/update-shapes ids (get-layout-initializer type from-frame?))
|
||||||
|
@ -161,7 +185,7 @@
|
||||||
(not from-frame?)
|
(not from-frame?)
|
||||||
(-> (assoc :layout-item-h-sizing :auto
|
(-> (assoc :layout-item-h-sizing :auto
|
||||||
:layout-item-v-sizing :auto)
|
:layout-item-v-sizing :auto)
|
||||||
(merge flex-params)))))
|
(merge layout-params)))))
|
||||||
(ptk/data-event :layout/update ids)
|
(ptk/data-event :layout/update ids)
|
||||||
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
|
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
@ -288,7 +312,7 @@
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
(defn create-layout
|
(defn create-layout
|
||||||
[]
|
[type]
|
||||||
(ptk/reify ::create-layout
|
(ptk/reify ::create-layout
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
|
@ -300,15 +324,12 @@
|
||||||
is-frame? (= :frame (:type (first selected-shapes)))
|
is-frame? (= :frame (:type (first selected-shapes)))
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
(if (and single? is-frame?)
|
(rx/of
|
||||||
(rx/of
|
(dwu/start-undo-transaction undo-id)
|
||||||
(dwu/start-undo-transaction undo-id)
|
(if (and single? is-frame?)
|
||||||
(create-layout-from-id [(first selected)] :flex true)
|
(create-layout-from-id [(first selected)] type true)
|
||||||
(dwu/commit-undo-transaction undo-id))
|
(create-layout-from-selection type))
|
||||||
(rx/of
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
(dwu/start-undo-transaction undo-id)
|
|
||||||
(create-layout-from-selection :flex)
|
|
||||||
(dwu/commit-undo-transaction undo-id)))))))
|
|
||||||
|
|
||||||
(defn toggle-layout-flex
|
(defn toggle-layout-flex
|
||||||
[]
|
[]
|
||||||
|
@ -320,12 +341,12 @@
|
||||||
selected (wsh/lookup-selected state)
|
selected (wsh/lookup-selected state)
|
||||||
selected-shapes (map (d/getf objects) selected)
|
selected-shapes (map (d/getf objects) selected)
|
||||||
single? (= (count selected-shapes) 1)
|
single? (= (count selected-shapes) 1)
|
||||||
has-flex-layout? (and single? (ctl/layout? objects (:id (first selected-shapes))))]
|
has-flex-layout? (and single? (ctl/flex-layout? objects (:id (first selected-shapes))))]
|
||||||
|
|
||||||
(when (not= 0 (count selected))
|
(when (not= 0 (count selected))
|
||||||
(if has-flex-layout?
|
(if has-flex-layout?
|
||||||
(rx/of (remove-layout selected))
|
(rx/of (remove-layout selected))
|
||||||
(rx/of (create-layout))))))))
|
(rx/of (create-layout :flex))))))))
|
||||||
|
|
||||||
(defn update-layout
|
(defn update-layout
|
||||||
[ids changes]
|
[ids changes]
|
||||||
|
@ -338,6 +359,101 @@
|
||||||
(ptk/data-event :layout/update ids)
|
(ptk/data-event :layout/update ids)
|
||||||
(dwu/commit-undo-transaction undo-id))))))
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
|
#_(defn update-grid-cells
|
||||||
|
[parent objects]
|
||||||
|
(let [children (cph/get-immediate-children objects (:id parent))
|
||||||
|
layout-grid-rows (:layout-grid-rows parent)
|
||||||
|
layout-grid-columns (:layout-grid-columns parent)
|
||||||
|
num-rows (count layout-grid-columns)
|
||||||
|
num-columns (count layout-grid-columns)
|
||||||
|
layout-grid-cells (:layout-grid-cells parent)
|
||||||
|
|
||||||
|
allocated-shapes
|
||||||
|
(into #{} (mapcat :shapes) (:layout-grid-cells parent))
|
||||||
|
|
||||||
|
no-cell-shapes
|
||||||
|
(->> children (:shapes parent) (remove allocated-shapes))
|
||||||
|
|
||||||
|
layout-grid-cells
|
||||||
|
(for [[row-idx row] (d/enumerate layout-grid-rows)
|
||||||
|
[col-idx col] (d/enumerate layout-grid-columns)]
|
||||||
|
|
||||||
|
(let [shape (nth children (+ (* row-idx num-columns) col-idx) nil)
|
||||||
|
cell-data {:id (uuid/next)
|
||||||
|
:row (inc row-idx)
|
||||||
|
:column (inc col-idx)
|
||||||
|
:row-span 1
|
||||||
|
:col-span 1
|
||||||
|
:shapes (when shape [(:id shape)])}]
|
||||||
|
[(:id cell-data) cell-data]))]
|
||||||
|
(assoc parent :layout-grid-cells (into {} layout-grid-cells))))
|
||||||
|
|
||||||
|
#_(defn check-grid-cells-update
|
||||||
|
[ids]
|
||||||
|
(ptk/reify ::check-grid-cells-update
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ state _]
|
||||||
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
|
undo-id (js/Symbol)]
|
||||||
|
(rx/of (dwc/update-shapes
|
||||||
|
ids
|
||||||
|
(fn [shape]
|
||||||
|
(-> shape
|
||||||
|
(update-grid-cells objects)))))))))
|
||||||
|
|
||||||
|
(defn add-layout-track
|
||||||
|
[ids type value]
|
||||||
|
(assert (#{:row :column} type))
|
||||||
|
(ptk/reify ::add-layout-column
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(let [undo-id (js/Symbol)]
|
||||||
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
|
(dwc/update-shapes
|
||||||
|
ids
|
||||||
|
(fn [shape]
|
||||||
|
(case type
|
||||||
|
:row (ctl/add-grid-row shape value)
|
||||||
|
:column (ctl/add-grid-column shape value))))
|
||||||
|
(ptk/data-event :layout/update ids)
|
||||||
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
|
(defn remove-layout-track
|
||||||
|
[ids type index]
|
||||||
|
(assert (#{:row :column} type))
|
||||||
|
|
||||||
|
(ptk/reify ::remove-layout-column
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(let [undo-id (js/Symbol)]
|
||||||
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
|
(dwc/update-shapes
|
||||||
|
ids
|
||||||
|
(fn [shape]
|
||||||
|
(case type
|
||||||
|
:row (ctl/remove-grid-row shape index)
|
||||||
|
:column (ctl/remove-grid-column shape index))))
|
||||||
|
(ptk/data-event :layout/update ids)
|
||||||
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
|
(defn change-layout-track
|
||||||
|
[ids type index props]
|
||||||
|
(assert (#{:row :column} type))
|
||||||
|
(ptk/reify ::change-layout-column
|
||||||
|
ptk/WatchEvent
|
||||||
|
(watch [_ _ _]
|
||||||
|
(let [undo-id (js/Symbol)
|
||||||
|
property (case :row :layout-grid-rows
|
||||||
|
:column :layout-grid-columns)]
|
||||||
|
(rx/of (dwu/start-undo-transaction undo-id)
|
||||||
|
(dwc/update-shapes
|
||||||
|
ids
|
||||||
|
(fn [shape]
|
||||||
|
(-> shape
|
||||||
|
(update-in [property index] merge props))))
|
||||||
|
(ptk/data-event :layout/update ids)
|
||||||
|
(dwu/commit-undo-transaction undo-id))))))
|
||||||
|
|
||||||
(defn fix-child-sizing
|
(defn fix-child-sizing
|
||||||
[objects parent-changes shape]
|
[objects parent-changes shape]
|
||||||
|
|
||||||
|
|
|
@ -95,6 +95,7 @@
|
||||||
selected)
|
selected)
|
||||||
|
|
||||||
index (:index (meta attrs))
|
index (:index (meta attrs))
|
||||||
|
|
||||||
changes (-> (pcb/empty-changes it page-id)
|
changes (-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
(cond-> (some? index)
|
(cond-> (some? index)
|
||||||
|
@ -102,7 +103,10 @@
|
||||||
(cond-> (nil? index)
|
(cond-> (nil? index)
|
||||||
(pcb/add-object shape))
|
(pcb/add-object shape))
|
||||||
(cond-> (some? (:parent-id attrs))
|
(cond-> (some? (:parent-id attrs))
|
||||||
(pcb/change-parent (:parent-id attrs) [shape])))
|
(pcb/change-parent (:parent-id attrs) [shape]))
|
||||||
|
(cond-> (ctl/grid-layout? objects (:parent-id shape))
|
||||||
|
(pcb/update-shapes [(:parent-id shape)] ctl/assign-cells))
|
||||||
|
)
|
||||||
undo-id (js/Symbol)]
|
undo-id (js/Symbol)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
|
@ -131,9 +135,11 @@
|
||||||
(when (d/not-empty? to-move-shapes)
|
(when (d/not-empty? to-move-shapes)
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
(cond-> (not (ctl/layout? objects frame-id))
|
(cond-> (not (ctl/any-layout? objects frame-id))
|
||||||
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
|
||||||
(pcb/change-parent frame-id to-move-shapes 0)))]
|
(pcb/change-parent frame-id to-move-shapes 0)
|
||||||
|
(cond-> (ctl/grid-layout? objects frame-id)
|
||||||
|
(pcb/update-shapes [frame-id] ctl/assign-cells))))]
|
||||||
|
|
||||||
(if (some? changes)
|
(if (some? changes)
|
||||||
(rx/of (dch/commit-changes changes))
|
(rx/of (dch/commit-changes changes))
|
||||||
|
@ -194,10 +200,6 @@
|
||||||
[file page objects ids it components-v2]
|
[file page objects ids it components-v2]
|
||||||
(let [lookup (d/getf objects)
|
(let [lookup (d/getf objects)
|
||||||
|
|
||||||
layout-ids (->> ids
|
|
||||||
(mapcat (partial cph/get-parent-ids objects))
|
|
||||||
(filter (partial ctl/layout? objects)))
|
|
||||||
|
|
||||||
groups-to-unmask
|
groups-to-unmask
|
||||||
(reduce (fn [group-ids id]
|
(reduce (fn [group-ids id]
|
||||||
;; When the shape to delete is the mask of a masked group,
|
;; When the shape to delete is the mask of a masked group,
|
||||||
|
@ -319,7 +321,6 @@
|
||||||
(dc/detach-comment-thread ids)
|
(dc/detach-comment-thread ids)
|
||||||
(ptk/data-event :layout/update all-parents)
|
(ptk/data-event :layout/update all-parents)
|
||||||
(dch/commit-changes changes)
|
(dch/commit-changes changes)
|
||||||
(ptk/data-event :layout/update layout-ids)
|
|
||||||
(dwu/commit-undo-transaction undo-id))))
|
(dwu/commit-undo-transaction undo-id))))
|
||||||
|
|
||||||
(defn create-and-add-shape
|
(defn create-and-add-shape
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
[app.common.geom.matrix :as gmt]
|
[app.common.geom.matrix :as gmt]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.geom.shapes.flex-layout :as gsl]
|
[app.common.geom.shapes.flex-layout :as gslf]
|
||||||
|
[app.common.geom.shapes.grid-layout :as gslg]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.pages.changes-builder :as pcb]
|
[app.common.pages.changes-builder :as pcb]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
|
@ -440,7 +441,7 @@
|
||||||
exclude-frames-siblings
|
exclude-frames-siblings
|
||||||
(into exclude-frames
|
(into exclude-frames
|
||||||
(comp (mapcat (partial cph/get-siblings-ids objects))
|
(comp (mapcat (partial cph/get-siblings-ids objects))
|
||||||
(filter (partial ctl/layout-immediate-child-id? objects)))
|
(filter (partial ctl/any-layout-immediate-child-id? objects)))
|
||||||
selected)
|
selected)
|
||||||
|
|
||||||
position (->> ms/mouse-position
|
position (->> ms/mouse-position
|
||||||
|
@ -469,11 +470,14 @@
|
||||||
|
|
||||||
(rx/map
|
(rx/map
|
||||||
(fn [[move-vector mod?]]
|
(fn [[move-vector mod?]]
|
||||||
(let [position (gpt/add from-position move-vector)
|
(let [position (gpt/add from-position move-vector)
|
||||||
exclude-frames (if mod? exclude-frames exclude-frames-siblings)
|
exclude-frames (if mod? exclude-frames exclude-frames-siblings)
|
||||||
target-frame (ctst/top-nested-frame objects position exclude-frames)
|
target-frame (ctst/top-nested-frame objects position exclude-frames)
|
||||||
layout? (ctl/layout? objects target-frame)
|
flex-layout? (ctl/flex-layout? objects target-frame)
|
||||||
drop-index (when layout? (gsl/get-drop-index target-frame objects position))]
|
grid-layout? (ctl/grid-layout? objects target-frame)
|
||||||
|
drop-index (cond
|
||||||
|
flex-layout? (gslf/get-drop-index target-frame objects position)
|
||||||
|
grid-layout? (gslg/get-drop-index target-frame objects position))]
|
||||||
[move-vector target-frame drop-index])))
|
[move-vector target-frame drop-index])))
|
||||||
|
|
||||||
(rx/take-until stopper))]
|
(rx/take-until stopper))]
|
||||||
|
@ -529,7 +533,8 @@
|
||||||
get-new-position
|
get-new-position
|
||||||
(fn [parent-id position]
|
(fn [parent-id position]
|
||||||
(let [parent (get objects parent-id)]
|
(let [parent (get objects parent-id)]
|
||||||
(when (ctl/layout? parent)
|
(cond
|
||||||
|
(ctl/flex-layout? parent)
|
||||||
(if (or
|
(if (or
|
||||||
(and (ctl/reverse? parent)
|
(and (ctl/reverse? parent)
|
||||||
(or (= direction :left)
|
(or (= direction :left)
|
||||||
|
@ -538,7 +543,12 @@
|
||||||
(or (= direction :right)
|
(or (= direction :right)
|
||||||
(= direction :down))))
|
(= direction :down))))
|
||||||
(dec position)
|
(dec position)
|
||||||
(+ position 2)))))
|
(+ position 2))
|
||||||
|
|
||||||
|
;; TODO: GRID
|
||||||
|
(ctl/grid-layout? parent)
|
||||||
|
nil
|
||||||
|
)))
|
||||||
|
|
||||||
add-children-position
|
add-children-position
|
||||||
(fn [[parent-id children]]
|
(fn [[parent-id children]]
|
||||||
|
@ -643,7 +653,7 @@
|
||||||
(let [objects (wsh/lookup-page-objects state)
|
(let [objects (wsh/lookup-page-objects state)
|
||||||
selected (wsh/lookup-selected state {:omit-blocked? true})
|
selected (wsh/lookup-selected state {:omit-blocked? true})
|
||||||
selected-shapes (->> selected (map (d/getf objects)))]
|
selected-shapes (->> selected (map (d/getf objects)))]
|
||||||
(if (every? #(and (ctl/layout-immediate-child? objects %)
|
(if (every? #(and (ctl/any-layout-immediate-child? objects %)
|
||||||
(not (ctl/layout-absolute? %)))
|
(not (ctl/layout-absolute? %)))
|
||||||
selected-shapes)
|
selected-shapes)
|
||||||
(rx/of (reorder-selected-layout-child direction))
|
(rx/of (reorder-selected-layout-child direction))
|
||||||
|
@ -732,7 +742,7 @@
|
||||||
(-> (pcb/empty-changes it page-id)
|
(-> (pcb/empty-changes it page-id)
|
||||||
(pcb/with-objects objects)
|
(pcb/with-objects objects)
|
||||||
;; Remove layout-item properties when moving a shape outside a layout
|
;; Remove layout-item properties when moving a shape outside a layout
|
||||||
(cond-> (not (ctl/layout? objects frame-id))
|
(cond-> (not (ctl/any-layout? objects frame-id))
|
||||||
(pcb/update-shapes (map :id moving-shapes) ctl/remove-layout-item-data))
|
(pcb/update-shapes (map :id moving-shapes) ctl/remove-layout-item-data))
|
||||||
(pcb/change-parent frame-id moving-shapes drop-index)
|
(pcb/change-parent frame-id moving-shapes drop-index)
|
||||||
(pcb/remove-objects empty-parents))]
|
(pcb/remove-objects empty-parents))]
|
||||||
|
|
|
@ -405,7 +405,7 @@
|
||||||
(let [objects (wsh/lookup-page-objects state)]
|
(let [objects (wsh/lookup-page-objects state)]
|
||||||
(into []
|
(into []
|
||||||
(comp (map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
(filter (partial ctl/layout-immediate-child? objects)))
|
(filter (partial ctl/flex-layout-immediate-child? objects)))
|
||||||
ids)))
|
ids)))
|
||||||
st/state =))
|
st/state =))
|
||||||
|
|
||||||
|
@ -478,22 +478,22 @@
|
||||||
(defn workspace-text-modifier-by-id [id]
|
(defn workspace-text-modifier-by-id [id]
|
||||||
(l/derived #(get % id) workspace-text-modifier =))
|
(l/derived #(get % id) workspace-text-modifier =))
|
||||||
|
|
||||||
(defn is-layout-child?
|
(defn is-flex-layout-child?
|
||||||
[ids]
|
[ids]
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [objects]
|
(fn [objects]
|
||||||
(->> ids
|
(->> ids
|
||||||
(map (d/getf objects))
|
(map (d/getf objects))
|
||||||
(some (partial ctl/layout-immediate-child? objects))))
|
(some (partial ctl/flex-layout-immediate-child? objects))))
|
||||||
workspace-page-objects))
|
workspace-page-objects))
|
||||||
|
|
||||||
(defn all-layout-child?
|
(defn all-flex-layout-child?
|
||||||
[ids]
|
[ids]
|
||||||
(l/derived
|
(l/derived
|
||||||
(fn [objects]
|
(fn [objects]
|
||||||
(->> ids
|
(->> ids
|
||||||
(map (d/getf objects))
|
(map (d/getf objects))
|
||||||
(every? (partial ctl/layout-immediate-child? objects))))
|
(every? (partial ctl/flex-layout-immediate-child? objects))))
|
||||||
workspace-page-objects))
|
workspace-page-objects))
|
||||||
|
|
||||||
(defn get-flex-child-viewer
|
(defn get-flex-child-viewer
|
||||||
|
@ -503,7 +503,7 @@
|
||||||
(let [objects (wsh/lookup-viewer-objects state page-id)]
|
(let [objects (wsh/lookup-viewer-objects state page-id)]
|
||||||
(into []
|
(into []
|
||||||
(comp (map (d/getf objects))
|
(comp (map (d/getf objects))
|
||||||
(filter (partial ctl/layout-immediate-child? objects)))
|
(filter (partial ctl/flex-layout-immediate-child? objects)))
|
||||||
ids)))
|
ids)))
|
||||||
st/state =))
|
st/state =))
|
||||||
|
|
||||||
|
@ -522,3 +522,12 @@
|
||||||
|
|
||||||
(def colorpicker
|
(def colorpicker
|
||||||
(l/derived :colorpicker st/state))
|
(l/derived :colorpicker st/state))
|
||||||
|
|
||||||
|
|
||||||
|
(def workspace-grid-edition
|
||||||
|
(l/derived :workspace-grid-edition st/state))
|
||||||
|
|
||||||
|
(defn workspace-grid-edition-id
|
||||||
|
[id]
|
||||||
|
(l/derived #(get % id) workspace-grid-edition))
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,14 @@
|
||||||
i/component-copy)
|
i/component-copy)
|
||||||
(case (:type shape)
|
(case (:type shape)
|
||||||
:frame (cond
|
:frame (cond
|
||||||
(and (ctl/layout? shape) (ctl/col? shape))
|
(and (ctl/flex-layout? shape) (ctl/col? shape))
|
||||||
i/layout-columns
|
i/layout-columns
|
||||||
|
|
||||||
(and (ctl/layout? shape) (ctl/row? shape))
|
(and (ctl/flex-layout? shape) (ctl/row? shape))
|
||||||
i/layout-rows
|
i/layout-rows
|
||||||
|
|
||||||
|
;; TODO: GRID ICON
|
||||||
|
|
||||||
:else
|
:else
|
||||||
i/artboard)
|
i/artboard)
|
||||||
:image i/image
|
:image i/image
|
||||||
|
|
|
@ -113,6 +113,17 @@
|
||||||
(def full-screen (icon-xref :full-screen))
|
(def full-screen (icon-xref :full-screen))
|
||||||
(def full-screen-off (icon-xref :full-screen-off))
|
(def full-screen-off (icon-xref :full-screen-off))
|
||||||
(def grid (icon-xref :grid))
|
(def grid (icon-xref :grid))
|
||||||
|
(def grid-justify-content-column-around (icon-xref :grid-justify-content-column-around))
|
||||||
|
(def grid-justify-content-column-between (icon-xref :grid-justify-content-column-between))
|
||||||
|
(def grid-justify-content-column-center (icon-xref :grid-justify-content-column-center))
|
||||||
|
(def grid-justify-content-column-end (icon-xref :grid-justify-content-column-end))
|
||||||
|
(def grid-justify-content-column-start (icon-xref :grid-justify-content-column-start))
|
||||||
|
(def grid-justify-content-row-around (icon-xref :grid-justify-content-row-around))
|
||||||
|
(def grid-justify-content-row-between (icon-xref :grid-justify-content-row-between))
|
||||||
|
(def grid-justify-content-row-center (icon-xref :grid-justify-content-row-center))
|
||||||
|
(def grid-justify-content-row-end (icon-xref :grid-justify-content-row-end))
|
||||||
|
(def grid-justify-content-row-start (icon-xref :grid-justify-content-row-start))
|
||||||
|
(def grid-layout-mode (icon-xref :grid-layout-mode))
|
||||||
(def grid-snap (icon-xref :grid-snap))
|
(def grid-snap (icon-xref :grid-snap))
|
||||||
(def go-next (icon-xref :go-next))
|
(def go-next (icon-xref :go-next))
|
||||||
(def go-prev (icon-xref :go-prev))
|
(def go-prev (icon-xref :go-prev))
|
||||||
|
|
|
@ -129,7 +129,7 @@
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [shape (unchecked-get props "shape")
|
||||||
childs (unchecked-get props "childs")
|
childs (unchecked-get props "childs")
|
||||||
childs (cond-> childs
|
childs (cond-> childs
|
||||||
(ctl/layout? shape)
|
(ctl/any-layout? shape)
|
||||||
(cph/sort-layout-children-z-index))]
|
(cph/sort-layout-children-z-index))]
|
||||||
[:> frame-container props
|
[:> frame-container props
|
||||||
[:g.frame-children {:opacity (:opacity shape)}
|
[:g.frame-children {:opacity (:opacity shape)}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.bool :as bool]
|
[app.main.ui.workspace.sidebar.options.shapes.bool :as bool]
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.circle :as circle]
|
[app.main.ui.workspace.sidebar.options.shapes.circle :as circle]
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.frame :as frame]
|
[app.main.ui.workspace.sidebar.options.shapes.frame :as frame]
|
||||||
|
[app.main.ui.workspace.sidebar.options.shapes.grid-cell :as grid-cell]
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.group :as group]
|
[app.main.ui.workspace.sidebar.options.shapes.group :as group]
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.image :as image]
|
[app.main.ui.workspace.sidebar.options.shapes.image :as image]
|
||||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple]
|
[app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple]
|
||||||
|
@ -67,9 +68,16 @@
|
||||||
(let [drawing (mf/deref refs/workspace-drawing)
|
(let [drawing (mf/deref refs/workspace-drawing)
|
||||||
objects (mf/deref refs/workspace-page-objects)
|
objects (mf/deref refs/workspace-page-objects)
|
||||||
shared-libs (mf/deref refs/workspace-libraries)
|
shared-libs (mf/deref refs/workspace-libraries)
|
||||||
|
grid-edition (mf/deref refs/workspace-grid-edition)
|
||||||
selected-shapes (into [] (keep (d/getf objects)) selected)
|
selected-shapes (into [] (keep (d/getf objects)) selected)
|
||||||
first-selected-shape (first selected-shapes)
|
first-selected-shape (first selected-shapes)
|
||||||
shape-parent-frame (cph/get-frame objects (:frame-id first-selected-shape))
|
shape-parent-frame (cph/get-frame objects (:frame-id first-selected-shape))
|
||||||
|
|
||||||
|
[grid-id {[row-selected col-selected] :selected}]
|
||||||
|
(d/seek (fn [[_ {:keys [selected]}]] (some? selected)) grid-edition)
|
||||||
|
|
||||||
|
grid-cell-selected? (and (some? grid-id) (some? row-selected) (some? col-selected))
|
||||||
|
|
||||||
on-change-tab
|
on-change-tab
|
||||||
(fn [options-mode]
|
(fn [options-mode]
|
||||||
(st/emit! (udw/set-options-mode options-mode)
|
(st/emit! (udw/set-options-mode options-mode)
|
||||||
|
@ -87,6 +95,10 @@
|
||||||
[:& align-options]
|
[:& align-options]
|
||||||
[:& bool-options]
|
[:& bool-options]
|
||||||
(cond
|
(cond
|
||||||
|
grid-cell-selected? [:& grid-cell/options {:shape (get objects grid-id)
|
||||||
|
:row row-selected
|
||||||
|
:column col-selected}]
|
||||||
|
|
||||||
(d/not-empty? drawing) [:& shape-options {:shape (:object drawing)
|
(d/not-empty? drawing) [:& shape-options {:shape (:object drawing)
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
|
@ -138,4 +150,3 @@
|
||||||
:file-id file-id
|
:file-id file-id
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:section section}]))
|
:section section}]))
|
||||||
|
|
||||||
|
|
|
@ -5,97 +5,138 @@
|
||||||
;; Copyright (c) KALEIDOS INC
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
(ns app.main.ui.workspace.sidebar.options.menus.layout-container
|
(ns app.main.ui.workspace.sidebar.options.menus.layout-container
|
||||||
(:require [app.common.data :as d]
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data :as d]
|
||||||
[app.main.data.workspace :as udw]
|
[app.common.data.macros :as dm]
|
||||||
[app.main.data.workspace.shape-layout :as dwsl]
|
[app.main.data.workspace :as udw]
|
||||||
[app.main.store :as st]
|
[app.main.data.workspace.shape-layout :as dwsl]
|
||||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
[app.main.refs :as refs]
|
||||||
[app.main.ui.icons :as i]
|
[app.main.store :as st]
|
||||||
[app.util.dom :as dom]
|
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||||
[cuerdas.core :as str]
|
[app.main.ui.components.select :refer [select]]
|
||||||
[rumext.v2 :as mf]))
|
[app.main.ui.icons :as i]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(def layout-container-flex-attrs
|
(def layout-container-flex-attrs
|
||||||
[:layout ;; :flex, :grid in the future
|
[:layout ;; :flex, :grid in the future
|
||||||
:layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
|
:layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
|
||||||
:layout-gap-type ;; :simple, :multiple
|
:layout-gap-type ;; :simple, :multiple
|
||||||
:layout-gap ;; {:row-gap number , :column-gap number}
|
:layout-gap ;; {:row-gap number , :column-gap number}
|
||||||
|
|
||||||
:layout-align-items ;; :start :end :center :stretch
|
:layout-align-items ;; :start :end :center :stretch
|
||||||
:layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly
|
:layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly
|
||||||
:layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default)
|
:layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default)
|
||||||
:layout-wrap-type ;; :wrap, :nowrap
|
:layout-wrap-type ;; :wrap, :nowrap
|
||||||
:layout-padding-type ;; :simple, :multiple
|
:layout-padding-type ;; :simple, :multiple
|
||||||
:layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
|
:layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
|
||||||
])
|
|
||||||
|
:layout-grid-dir ;; :row :column
|
||||||
|
:layout-justify-items
|
||||||
|
:layout-grid-columns
|
||||||
|
:layout-grid-rows])
|
||||||
|
|
||||||
(defn get-layout-flex-icon
|
(defn get-layout-flex-icon
|
||||||
[type val is-col?]
|
[type val is-col?]
|
||||||
(case type
|
(case type
|
||||||
:align-items (if is-col?
|
:align-items
|
||||||
(case val
|
(if is-col?
|
||||||
:start i/align-items-column-start
|
(case val
|
||||||
:end i/align-items-column-end
|
:start i/align-items-column-start
|
||||||
:center i/align-items-column-center
|
:end i/align-items-column-end
|
||||||
:stretch i/align-items-column-strech
|
:center i/align-items-column-center
|
||||||
:baseline i/align-items-column-baseline)
|
:stretch i/align-items-column-strech
|
||||||
(case val
|
:baseline i/align-items-column-baseline)
|
||||||
:start i/align-items-row-start
|
(case val
|
||||||
:end i/align-items-row-end
|
:start i/align-items-row-start
|
||||||
:center i/align-items-row-center
|
:end i/align-items-row-end
|
||||||
:stretch i/align-items-row-strech
|
:center i/align-items-row-center
|
||||||
:baseline i/align-items-row-baseline))
|
:stretch i/align-items-row-strech
|
||||||
:justify-content (if is-col?
|
:baseline i/align-items-row-baseline))
|
||||||
(case val
|
|
||||||
:start i/justify-content-column-start
|
|
||||||
:end i/justify-content-column-end
|
|
||||||
:center i/justify-content-column-center
|
|
||||||
:space-around i/justify-content-column-around
|
|
||||||
:space-evenly i/justify-content-column-evenly
|
|
||||||
:space-between i/justify-content-column-between)
|
|
||||||
(case val
|
|
||||||
:start i/justify-content-row-start
|
|
||||||
:end i/justify-content-row-end
|
|
||||||
:center i/justify-content-row-center
|
|
||||||
:space-around i/justify-content-row-around
|
|
||||||
:space-evenly i/justify-content-row-evenly
|
|
||||||
:space-between i/justify-content-row-between))
|
|
||||||
|
|
||||||
:align-content (if is-col?
|
:justify-content
|
||||||
(case val
|
(if is-col?
|
||||||
:start i/align-content-column-start
|
(case val
|
||||||
:end i/align-content-column-end
|
:start i/justify-content-column-start
|
||||||
:center i/align-content-column-center
|
:end i/justify-content-column-end
|
||||||
:space-around i/align-content-column-around
|
:center i/justify-content-column-center
|
||||||
:space-evenly i/align-content-column-evenly
|
:space-around i/justify-content-column-around
|
||||||
:space-between i/align-content-column-between
|
:space-evenly i/justify-content-column-evenly
|
||||||
:stretch nil)
|
:space-between i/justify-content-column-between)
|
||||||
|
(case val
|
||||||
|
:start i/justify-content-row-start
|
||||||
|
:end i/justify-content-row-end
|
||||||
|
:center i/justify-content-row-center
|
||||||
|
:space-around i/justify-content-row-around
|
||||||
|
:space-evenly i/justify-content-row-evenly
|
||||||
|
:space-between i/justify-content-row-between))
|
||||||
|
|
||||||
(case val
|
:align-content
|
||||||
:start i/align-content-row-start
|
(if is-col?
|
||||||
:end i/align-content-row-end
|
(case val
|
||||||
:center i/align-content-row-center
|
:start i/align-content-column-start
|
||||||
:space-around i/align-content-row-around
|
:end i/align-content-column-end
|
||||||
:space-evenly i/align-content-row-evenly
|
:center i/align-content-column-center
|
||||||
:space-between i/align-content-row-between
|
:space-around i/align-content-column-around
|
||||||
:stretch nil))
|
:space-evenly i/align-content-column-evenly
|
||||||
|
:space-between i/align-content-column-between
|
||||||
|
:stretch nil)
|
||||||
|
|
||||||
:align-self (if is-col?
|
(case val
|
||||||
(case val
|
:start i/align-content-row-start
|
||||||
:start i/align-self-row-left
|
:end i/align-content-row-end
|
||||||
:end i/align-self-row-right
|
:center i/align-content-row-center
|
||||||
:center i/align-self-row-center
|
:space-around i/align-content-row-around
|
||||||
:stretch i/align-self-row-strech
|
:space-evenly i/align-content-row-evenly
|
||||||
:baseline i/align-self-row-baseline)
|
:space-between i/align-content-row-between
|
||||||
(case val
|
:stretch nil))
|
||||||
:start i/align-self-column-top
|
|
||||||
:end i/align-self-column-bottom
|
(case val
|
||||||
:center i/align-self-column-center
|
:start i/align-content-row-start
|
||||||
:stretch i/align-self-column-strech
|
:end i/align-content-row-end
|
||||||
:baseline i/align-self-column-baseline))))
|
:center i/align-content-row-center
|
||||||
|
:space-around i/align-content-row-around
|
||||||
|
:space-between i/align-content-row-between
|
||||||
|
:stretch nil)
|
||||||
|
|
||||||
|
:align-self
|
||||||
|
(if is-col?
|
||||||
|
(case val
|
||||||
|
:auto i/minus
|
||||||
|
:start i/align-self-row-left
|
||||||
|
:end i/align-self-row-right
|
||||||
|
:center i/align-self-row-center
|
||||||
|
:stretch i/align-self-row-strech
|
||||||
|
:baseline i/align-self-row-baseline)
|
||||||
|
(case val
|
||||||
|
:auto i/minus
|
||||||
|
:start i/align-self-column-top
|
||||||
|
:end i/align-self-column-bottom
|
||||||
|
:center i/align-self-column-center
|
||||||
|
:stretch i/align-self-column-strech
|
||||||
|
:baseline i/align-self-column-baseline))))
|
||||||
|
|
||||||
|
(defn get-layout-grid-icon
|
||||||
|
[type val is-col?]
|
||||||
|
(case type
|
||||||
|
:justify-items
|
||||||
|
(if is-col?
|
||||||
|
(case val
|
||||||
|
:start i/grid-justify-content-column-start
|
||||||
|
:end i/grid-justify-content-column-end
|
||||||
|
:center i/grid-justify-content-column-center
|
||||||
|
:space-around i/grid-justify-content-column-around
|
||||||
|
:space-between i/grid-justify-content-column-between)
|
||||||
|
(case val
|
||||||
|
:start i/grid-justify-content-row-start
|
||||||
|
:end i/grid-justify-content-row-end
|
||||||
|
:center i/grid-justify-content-row-center
|
||||||
|
:space-around i/grid-justify-content-row-around
|
||||||
|
:space-between i/grid-justify-content-row-between))))
|
||||||
|
|
||||||
(mf/defc direction-btn
|
(mf/defc direction-btn
|
||||||
[{:keys [dir saved-dir set-direction] :as props}]
|
[{:keys [dir saved-dir set-direction icon?] :as props}]
|
||||||
(let [handle-on-click
|
(let [handle-on-click
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps set-direction dir)
|
(mf/deps set-direction dir)
|
||||||
|
@ -112,7 +153,9 @@
|
||||||
:key (dm/str "direction-" dir)
|
:key (dm/str "direction-" dir)
|
||||||
:alt (str/replace (str/capital (d/name dir)) "-" " ")
|
:alt (str/replace (str/capital (d/name dir)) "-" " ")
|
||||||
:on-click handle-on-click}
|
:on-click handle-on-click}
|
||||||
i/auto-direction]))
|
(if icon?
|
||||||
|
i/auto-direction
|
||||||
|
(str/replace (str/capital (d/name dir)) "-" " "))]))
|
||||||
|
|
||||||
(mf/defc wrap-row
|
(mf/defc wrap-row
|
||||||
[{:keys [wrap-type set-wrap] :as props}]
|
[{:keys [wrap-type set-wrap] :as props}]
|
||||||
|
@ -299,6 +342,111 @@
|
||||||
:value (:row-gap gap-value)
|
:value (:row-gap gap-value)
|
||||||
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]]])
|
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]]])
|
||||||
|
|
||||||
|
(mf/defc grid-edit-mode
|
||||||
|
[{:keys [id] :as props}]
|
||||||
|
(let [edition (mf/deref refs/selected-edition)
|
||||||
|
active? (= id edition)
|
||||||
|
|
||||||
|
toggle-edit-mode
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps id edition)
|
||||||
|
(fn []
|
||||||
|
(if-not active?
|
||||||
|
(st/emit! (udw/start-edition-mode id))
|
||||||
|
(st/emit! :interrupt))))]
|
||||||
|
|
||||||
|
[:button.tooltip.tooltip-bottom-left
|
||||||
|
{:class (dom/classnames :active active?)
|
||||||
|
:alt "Grid edit mode"
|
||||||
|
:on-click #(toggle-edit-mode)
|
||||||
|
:style {:padding 0}}
|
||||||
|
i/grid-layout-mode]))
|
||||||
|
|
||||||
|
(mf/defc align-grid-row
|
||||||
|
[{:keys [is-col? align-items set-align] :as props}]
|
||||||
|
(let [type (if is-col? :column :row)]
|
||||||
|
[:div.align-items-style
|
||||||
|
(for [align [:start :center :end :stretch :baseline]]
|
||||||
|
[:button.align-start.tooltip
|
||||||
|
{:class (dom/classnames :active (= align-items align)
|
||||||
|
:tooltip-bottom-left (not= align :start)
|
||||||
|
:tooltip-bottom (= align :start))
|
||||||
|
:alt (dm/str "Align items " (d/name align))
|
||||||
|
:on-click #(set-align align type)
|
||||||
|
:key (dm/str "align-items" (d/name align))}
|
||||||
|
(get-layout-flex-icon :align-items align is-col?)])]))
|
||||||
|
|
||||||
|
(mf/defc justify-grid-row
|
||||||
|
[{:keys [is-col? justify-items set-justify] :as props}]
|
||||||
|
(let [type (if is-col? :column :row)]
|
||||||
|
[:div.justify-content-style
|
||||||
|
(for [align [:start :center :end :space-around :space-between]]
|
||||||
|
[:button.align-start.tooltip
|
||||||
|
{:class (dom/classnames :active (= justify-items align)
|
||||||
|
:tooltip-bottom-left (not= align :start)
|
||||||
|
:tooltip-bottom (= align :start))
|
||||||
|
:alt (dm/str "Justify content " (d/name align))
|
||||||
|
:on-click #(set-justify align type)
|
||||||
|
:key (dm/str "justify-content" (d/name align))}
|
||||||
|
(get-layout-grid-icon :justify-items align is-col?)])]))
|
||||||
|
|
||||||
|
(defn manage-values [{:keys [value type]}]
|
||||||
|
(case type
|
||||||
|
:auto "auto"
|
||||||
|
:percent (dm/str value "%")
|
||||||
|
:flex (dm/str value "fr")
|
||||||
|
:fixed (dm/str value "px")
|
||||||
|
value))
|
||||||
|
|
||||||
|
(mf/defc grid-columns-row
|
||||||
|
[{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element] :as props}]
|
||||||
|
(let [column-num (count column-values)
|
||||||
|
direction (if (> column-num 1)
|
||||||
|
(if is-col? "Columns " "Rows ")
|
||||||
|
(if is-col? "Column " "Row "))
|
||||||
|
|
||||||
|
column-vals (str/join ", " (map manage-values column-values))
|
||||||
|
generated-name (dm/str direction (if (= column-num 0) " - empty" (dm/str column-num " (" column-vals ")")))
|
||||||
|
type (if is-col? :column :row)]
|
||||||
|
|
||||||
|
[:div.grid-columns
|
||||||
|
[:div.grid-columns-header
|
||||||
|
[:button.expand-icon
|
||||||
|
{:on-click toggle} i/actions]
|
||||||
|
|
||||||
|
[:div.columns-info {:title generated-name
|
||||||
|
:on-click toggle} generated-name]
|
||||||
|
[:button.add-column {:on-click #(do
|
||||||
|
(when-not expanded? (toggle))
|
||||||
|
(add-new-element type {:type :fixed :value 100}))} i/plus]]
|
||||||
|
|
||||||
|
(when expanded?
|
||||||
|
[:div.columns-info-wrapper
|
||||||
|
(for [[index column] (d/enumerate column-values)]
|
||||||
|
[:div.column-info
|
||||||
|
[:div.direction-grid-icon
|
||||||
|
(if is-col?
|
||||||
|
i/layout-rows
|
||||||
|
i/layout-columns)]
|
||||||
|
|
||||||
|
[:div.grid-column-value
|
||||||
|
[:> numeric-input {:no-validate true
|
||||||
|
:value (:value column)
|
||||||
|
:on-change #(set-column-value type index %)
|
||||||
|
:placeholder "--"}]]
|
||||||
|
[:div.grid-column-unit
|
||||||
|
[:& select
|
||||||
|
{:class "grid-column-unit-selector"
|
||||||
|
:default-value (:type column)
|
||||||
|
:options [{:value :flex :label "fr"}
|
||||||
|
{:value :auto :label "auto"}
|
||||||
|
{:value :fixed :label "px"}
|
||||||
|
{:value :percent :label "%"}]
|
||||||
|
:on-change #(set-column-type type index %)}]]
|
||||||
|
[:button.remove-grid-column
|
||||||
|
{:on-click #(remove-element type index)}
|
||||||
|
i/minus]])])]))
|
||||||
|
|
||||||
(mf/defc layout-container-menu
|
(mf/defc layout-container-menu
|
||||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "multiple"]))]}
|
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type" "multiple"]))]}
|
||||||
[{:keys [ids _type values multiple] :as props}]
|
[{:keys [ids _type values multiple] :as props}]
|
||||||
|
@ -308,8 +456,8 @@
|
||||||
layout-type (:layout values)
|
layout-type (:layout values)
|
||||||
|
|
||||||
on-add-layout
|
on-add-layout
|
||||||
(fn [_]
|
(fn [type]
|
||||||
(st/emit! (dwsl/create-layout))
|
(st/emit! (dwsl/create-layout type))
|
||||||
(reset! open? true))
|
(reset! open? true))
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,22 +466,20 @@
|
||||||
(st/emit! (dwsl/remove-layout ids))
|
(st/emit! (dwsl/remove-layout ids))
|
||||||
(reset! open? false))
|
(reset! open? false))
|
||||||
|
|
||||||
;; Uncomment when activating the grid options
|
_set-flex
|
||||||
;; set-flex (fn []
|
(fn []
|
||||||
;; (st/emit! (dwsl/remove-layout ids))
|
(st/emit! (dwsl/remove-layout ids))
|
||||||
;; (on-add-layout :flex))
|
(on-add-layout :flex))
|
||||||
;;
|
|
||||||
;; set-grid (fn []
|
_set-grid
|
||||||
;; (st/emit! (dwsl/remove-layout ids))
|
(fn []
|
||||||
;; (on-add-layout :grid))
|
(st/emit! (dwsl/remove-layout ids))
|
||||||
|
(on-add-layout :grid))
|
||||||
|
|
||||||
;; Flex-direction
|
;; Flex-direction
|
||||||
|
|
||||||
saved-dir (:layout-flex-dir values)
|
saved-dir (:layout-flex-dir values)
|
||||||
is-col? (or (= :column saved-dir) (= :column-reverse saved-dir))
|
is-col? (or (= :column saved-dir) (= :column-reverse saved-dir))
|
||||||
set-direction
|
|
||||||
(fn [dir]
|
|
||||||
(st/emit! (dwsl/update-layout ids {:layout-flex-dir dir})))
|
|
||||||
|
|
||||||
;; Wrap type
|
;; Wrap type
|
||||||
|
|
||||||
|
@ -386,7 +532,79 @@
|
||||||
(st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
|
(st/emit! (dwsl/update-layout ids {:layout-padding {:p2 val :p4 val}}))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))]
|
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))
|
||||||
|
|
||||||
|
;; Grid-direction
|
||||||
|
|
||||||
|
saved-grid-dir (:layout-grid-dir values)
|
||||||
|
|
||||||
|
set-direction
|
||||||
|
(fn [dir type]
|
||||||
|
(if (= :flex type)
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-flex-dir dir}))
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))
|
||||||
|
|
||||||
|
;; Align grid
|
||||||
|
align-items-row (:layout-align-items values)
|
||||||
|
align-items-column (:layout-justify-items values)
|
||||||
|
|
||||||
|
set-align-grid
|
||||||
|
(fn [value type]
|
||||||
|
(if (= type :row)
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-align-items value}))
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
|
||||||
|
|
||||||
|
;; Justify grid
|
||||||
|
grid-justify-content-row (:layout-align-content values)
|
||||||
|
grid-justify-content-column (:layout-justify-content values)
|
||||||
|
|
||||||
|
set-justify-grid
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [value type]
|
||||||
|
(if (= type :row)
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-align-content value}))
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-justify-content value})))))
|
||||||
|
|
||||||
|
|
||||||
|
;;Grid columns
|
||||||
|
column-grid-values (:layout-grid-columns values)
|
||||||
|
grid-columns-open? (mf/use-state false)
|
||||||
|
toggle-columns-info (mf/use-callback
|
||||||
|
(fn [_]
|
||||||
|
(swap! grid-columns-open? not)))
|
||||||
|
|
||||||
|
; Grid rows / columns
|
||||||
|
rows-grid-values (:layout-grid-rows values)
|
||||||
|
grid-rows-open? (mf/use-state false)
|
||||||
|
toggle-rows-info
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [_]
|
||||||
|
(swap! grid-rows-open? not)))
|
||||||
|
|
||||||
|
add-new-element
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [type value]
|
||||||
|
(st/emit! (dwsl/add-layout-track ids type value))))
|
||||||
|
|
||||||
|
remove-element
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [type index]
|
||||||
|
(st/emit! (dwsl/remove-layout-track ids type index))))
|
||||||
|
|
||||||
|
set-column-value
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [type index value]
|
||||||
|
(st/emit! (dwsl/change-layout-track ids type index {:value value}))))
|
||||||
|
|
||||||
|
set-column-type
|
||||||
|
(mf/use-callback
|
||||||
|
(mf/deps ids)
|
||||||
|
(fn [type index track-type]
|
||||||
|
(st/emit! (dwsl/change-layout-track ids type index {:type track-type}))))]
|
||||||
|
|
||||||
[:div.element-set
|
[:div.element-set
|
||||||
[:div.element-set-title
|
[:div.element-set-title
|
||||||
|
@ -395,19 +613,21 @@
|
||||||
(if (and (not multiple) (:layout values))
|
(if (and (not multiple) (:layout values))
|
||||||
[:div.title-actions
|
[:div.title-actions
|
||||||
#_[:div.layout-btns
|
#_[:div.layout-btns
|
||||||
[:button {:on-click set-flex
|
[:button {:on-click set-flex
|
||||||
:class (dom/classnames
|
:class (dom/classnames
|
||||||
:active (= :flex layout-type))} "Flex"]
|
:active (= :flex layout-type))} "Flex"]
|
||||||
[:button {:on-click set-grid
|
[:button {:on-click set-grid
|
||||||
:class (dom/classnames
|
:class (dom/classnames
|
||||||
:active (= :grid layout-type))} "Grid"]]
|
:active (= :grid layout-type))} "Grid"]]
|
||||||
[:button.remove-layout {:on-click on-remove-layout} i/minus]]
|
[:button.remove-layout {:on-click on-remove-layout} i/minus]]
|
||||||
|
|
||||||
[:button.add-page {:on-click on-add-layout} i/close])]]
|
[:button.add-page {:on-click #(on-add-layout :flex)} i/close])]]
|
||||||
|
|
||||||
(when (:layout values)
|
(when (:layout values)
|
||||||
(when (not= :multiple layout-type)
|
(when (not= :multiple layout-type)
|
||||||
(if (= :flex layout-type)
|
(case layout-type
|
||||||
|
:flex
|
||||||
|
|
||||||
[:div.element-set-content.layout-menu
|
[:div.element-set-content.layout-menu
|
||||||
[:div.layout-row
|
[:div.layout-row
|
||||||
[:div.direction-wrap.row-title "Direction"]
|
[:div.direction-wrap.row-title "Direction"]
|
||||||
|
@ -418,7 +638,8 @@
|
||||||
[:& direction-btn {:key (d/name dir)
|
[:& direction-btn {:key (d/name dir)
|
||||||
:dir dir
|
:dir dir
|
||||||
:saved-dir saved-dir
|
:saved-dir saved-dir
|
||||||
:set-direction set-direction}])]]
|
:set-direction #(set-direction dir :flex)
|
||||||
|
:icon? true}])]]
|
||||||
|
|
||||||
[:div.wrap-type
|
[:div.wrap-type
|
||||||
[:& wrap-row {:wrap-type wrap-type
|
[:& wrap-row {:wrap-type wrap-type
|
||||||
|
@ -456,4 +677,74 @@
|
||||||
:on-change-style change-padding-type
|
:on-change-style change-padding-type
|
||||||
:on-change on-padding-change}]]
|
:on-change on-padding-change}]]
|
||||||
|
|
||||||
[:div "GRID TO COME"])))]))
|
:grid
|
||||||
|
|
||||||
|
[:div.element-set-content.layout-menu
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.direction-wrap.row-title "Direction"]
|
||||||
|
[:div.btn-wrapper
|
||||||
|
[:div.direction
|
||||||
|
[:*
|
||||||
|
(for [dir [:row :column]]
|
||||||
|
[:& direction-btn {:key (d/name dir)
|
||||||
|
:dir dir
|
||||||
|
:saved-dir saved-grid-dir
|
||||||
|
:set-direction #(set-direction dir :grid)
|
||||||
|
:icon? false}])]]
|
||||||
|
|
||||||
|
(when (= 1 (count ids))
|
||||||
|
[:div.edit-mode
|
||||||
|
[:& grid-edit-mode {:id (first ids)}]])]]
|
||||||
|
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.align-items-grid.row-title "Align"]
|
||||||
|
[:div.btn-wrapper.align-grid
|
||||||
|
[:& align-grid-row {:is-col? false
|
||||||
|
:align-items align-items-row
|
||||||
|
:set-align set-align-grid}]
|
||||||
|
|
||||||
|
[:& align-grid-row {:is-col? true
|
||||||
|
:align-items align-items-column
|
||||||
|
:set-align set-align-grid}]]]
|
||||||
|
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.jusfiy-content-grid.row-title "Justify"]
|
||||||
|
[:div.btn-wrapper.align-grid
|
||||||
|
[:& justify-grid-row {:is-col? true
|
||||||
|
:justify-items grid-justify-content-column
|
||||||
|
:set-justify set-justify-grid}]
|
||||||
|
[:& justify-grid-row {:is-col? false
|
||||||
|
:justify-items grid-justify-content-row
|
||||||
|
:set-justify set-justify-grid}]]]
|
||||||
|
|
||||||
|
[:& grid-columns-row {:is-col? true
|
||||||
|
:expanded? @grid-columns-open?
|
||||||
|
:toggle toggle-columns-info
|
||||||
|
:column-values column-grid-values
|
||||||
|
:add-new-element add-new-element
|
||||||
|
:set-column-value set-column-value
|
||||||
|
:set-column-type set-column-type
|
||||||
|
:remove-element remove-element}]
|
||||||
|
|
||||||
|
[:& grid-columns-row {:is-col? false
|
||||||
|
:expanded? @grid-rows-open?
|
||||||
|
:toggle toggle-rows-info
|
||||||
|
:column-values rows-grid-values
|
||||||
|
:add-new-element add-new-element
|
||||||
|
:set-column-value set-column-value
|
||||||
|
:set-column-type set-column-type
|
||||||
|
:remove-element remove-element}]
|
||||||
|
|
||||||
|
[:& gap-section {:is-col? is-col?
|
||||||
|
:wrap-type wrap-type
|
||||||
|
:gap-selected? gap-selected?
|
||||||
|
:set-gap set-gap
|
||||||
|
:gap-value (:layout-gap values)}]
|
||||||
|
|
||||||
|
[:& padding-section {:values values
|
||||||
|
:on-change-style change-padding-type
|
||||||
|
:on-change on-padding-change}]]
|
||||||
|
|
||||||
|
|
||||||
|
;; Default if not grid or flex
|
||||||
|
nil)))]))
|
||||||
|
|
|
@ -83,9 +83,9 @@
|
||||||
selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
|
selection-parents-ref (mf/use-memo (mf/deps ids) #(refs/parents-by-ids ids))
|
||||||
selection-parents (mf/deref selection-parents-ref)
|
selection-parents (mf/deref selection-parents-ref)
|
||||||
|
|
||||||
flex-child? (->> selection-parents (some ctl/layout?))
|
flex-child? (->> selection-parents (some ctl/flex-layout?))
|
||||||
absolute? (ctl/layout-absolute? shape)
|
absolute? (ctl/layout-absolute? shape)
|
||||||
flex-container? (ctl/layout? shape)
|
flex-container? (ctl/flex-layout? shape)
|
||||||
flex-auto-width? (ctl/auto-width? shape)
|
flex-auto-width? (ctl/auto-width? shape)
|
||||||
flex-fill-width? (ctl/fill-width? shape)
|
flex-fill-width? (ctl/fill-width? shape)
|
||||||
flex-auto-height? (ctl/auto-height? shape)
|
flex-auto-height? (ctl/auto-height? shape)
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
|
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
[:& layer-menu {:ids ids
|
[:& layer-menu {:ids ids
|
||||||
|
|
|
@ -32,9 +32,8 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
|
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
[:& measures-menu {:ids ids
|
[:& measures-menu {:ids ids
|
||||||
|
@ -43,14 +42,14 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu {:ids ids
|
[:& layout-item-menu {:ids ids
|
||||||
:type type
|
:type type
|
||||||
:values layout-item-values
|
:values layout-item-values
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:is-layout-container? false
|
:is-layout-container? false
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
[:& layer-menu {:ids ids
|
[:& layer-menu {:ids ids
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
[comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)]
|
[comp-ids comp-values] [[(:id shape)] (select-keys shape component-attrs)]
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-container? (ctl/layout? shape)
|
is-flex-layout-container? (ctl/flex-layout? shape)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
[:& measures-menu {:ids [(:id shape)]
|
[:& measures-menu {:ids [(:id shape)]
|
||||||
|
@ -48,18 +48,18 @@
|
||||||
[:& component-menu {:ids comp-ids
|
[:& component-menu {:ids comp-ids
|
||||||
:values comp-values
|
:values comp-values
|
||||||
:shape-name (:name shape)}]
|
:shape-name (:name shape)}]
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when (or is-layout-child? is-layout-container?)
|
(when (or is-flex-layout-child? is-flex-layout-container?)
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
:values layout-item-values
|
:values layout-item-values
|
||||||
:is-layout-child? is-layout-child?
|
:is-layout-child? is-flex-layout-child?
|
||||||
:is-layout-container? is-layout-container?
|
:is-layout-container? is-flex-layout-container?
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
[:& layer-menu {:ids ids
|
[:& layer-menu {:ids ids
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.ui.workspace.sidebar.options.shapes.grid-cell
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||||
|
[app.main.ui.icons :as i]
|
||||||
|
[app.main.ui.workspace.sidebar.options.menus.layout-container :as lyc]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(mf/defc set-self-alignment
|
||||||
|
[{:keys [is-col? alignment set-alignment] :as props}]
|
||||||
|
(let [dir-v [:auto :start :center :end :stretch #_:baseline]]
|
||||||
|
[:div.align-self-style
|
||||||
|
(for [align dir-v]
|
||||||
|
[:button.align-self.tooltip.tooltip-bottom
|
||||||
|
{:class (dom/classnames :active (= alignment align)
|
||||||
|
:tooltip-bottom-left (not= align :start)
|
||||||
|
:tooltip-bottom (= align :start))
|
||||||
|
:alt (dm/str "Align self " (d/name align)) ;; TODO fix this tooltip
|
||||||
|
:on-click #(set-alignment align)
|
||||||
|
:key (str "align-self" align)}
|
||||||
|
(lyc/get-layout-flex-icon :align-self align is-col?)])]))
|
||||||
|
|
||||||
|
|
||||||
|
(mf/defc options
|
||||||
|
{::mf/wrap [mf/memo]}
|
||||||
|
[{:keys [_shape row column] :as props}]
|
||||||
|
|
||||||
|
(let [position-mode (mf/use-state :auto) ;; TODO this should come from shape
|
||||||
|
|
||||||
|
set-position-mode (fn [mode]
|
||||||
|
(reset! position-mode mode))
|
||||||
|
|
||||||
|
|
||||||
|
align-self (mf/use-state :auto) ;; TODO this should come from shape
|
||||||
|
justify-alignment (mf/use-state :auto) ;; TODO this should come from shape
|
||||||
|
set-alignment (fn [value]
|
||||||
|
(reset! align-self value)
|
||||||
|
#_(if (= align-self value)
|
||||||
|
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil}))
|
||||||
|
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))
|
||||||
|
set-justify-self (fn [value]
|
||||||
|
(reset! justify-alignment value)
|
||||||
|
#_(if (= align-self value)
|
||||||
|
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil}))
|
||||||
|
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))
|
||||||
|
column-start column
|
||||||
|
column-end (inc column)
|
||||||
|
row-start row
|
||||||
|
row-end (inc row)
|
||||||
|
|
||||||
|
on-change
|
||||||
|
(fn [_side _orientation _value]
|
||||||
|
;; TODO
|
||||||
|
#_(if (= orientation :column)
|
||||||
|
(case side
|
||||||
|
:all ((reset! column-start value)
|
||||||
|
(reset! column-end value))
|
||||||
|
:start (reset! column-start value)
|
||||||
|
:end (reset! column-end value))
|
||||||
|
(case side
|
||||||
|
:all ((reset! row-start value)
|
||||||
|
(reset! row-end value))
|
||||||
|
:start (reset! row-start value)
|
||||||
|
:end (reset! row-end value))))
|
||||||
|
|
||||||
|
area-name (mf/use-state "header") ;; TODO this should come from shape
|
||||||
|
|
||||||
|
on-area-name-change (fn [value]
|
||||||
|
(reset! area-name value))
|
||||||
|
on-key-press (fn [_event])]
|
||||||
|
|
||||||
|
[:div.element-set
|
||||||
|
[:div.element-set-title
|
||||||
|
[:span "Grid Cell"]]
|
||||||
|
|
||||||
|
[:div.element-set-content.layout-grid-item-menu
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.row-title.sizing "Position"]
|
||||||
|
[:div.position-wrapper
|
||||||
|
[:button.position-btn
|
||||||
|
{:on-click #(set-position-mode :auto)
|
||||||
|
:class (dom/classnames :active (= :auto @position-mode))} "Auto"]
|
||||||
|
[:button.position-btn
|
||||||
|
{:on-click #(set-position-mode :manual)
|
||||||
|
:class (dom/classnames :active (= :manual @position-mode))} "Manual"]
|
||||||
|
[:button.position-btn
|
||||||
|
{:on-click #(set-position-mode :area)
|
||||||
|
:class (dom/classnames :active (= :area @position-mode))} "Area"]]]
|
||||||
|
[:div.manage-grid-columns
|
||||||
|
(when (= :auto @position-mode)
|
||||||
|
[:div.grid-auto
|
||||||
|
[:div.grid-columns-auto
|
||||||
|
[:spam.icon i/layout-rows]
|
||||||
|
[:div.input-wrapper
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :all :column) ;; TODO cambiar este on-change y el value
|
||||||
|
:value column-start}]]]
|
||||||
|
[:div.grid-rows-auto
|
||||||
|
[:spam.icon i/layout-columns]
|
||||||
|
[:div.input-wrapper
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :all :row) ;; TODO cambiar este on-change y el value
|
||||||
|
:value row-start}]]]])
|
||||||
|
(when (= :area @position-mode)
|
||||||
|
[:div.input-wrapper
|
||||||
|
[:input.input-text
|
||||||
|
{:key "grid-area-name"
|
||||||
|
:id "grid-area-name"
|
||||||
|
:type "text"
|
||||||
|
:aria-label "grid-area-name"
|
||||||
|
:placeholder "--"
|
||||||
|
:default-value @area-name
|
||||||
|
:auto-complete "off"
|
||||||
|
:on-change on-area-name-change
|
||||||
|
:on-key-press on-key-press}]])
|
||||||
|
|
||||||
|
(when (or (= :manual @position-mode) (= :area @position-mode))
|
||||||
|
[:div.grid-manual
|
||||||
|
[:div.grid-columns-auto
|
||||||
|
[:spam.icon i/layout-rows]
|
||||||
|
[:div.input-wrapper
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :start :column)
|
||||||
|
:value column-start}]
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :end :column)
|
||||||
|
:value column-end}]]]
|
||||||
|
[:div.grid-rows-auto
|
||||||
|
[:spam.icon i/layout-columns]
|
||||||
|
[:div.input-wrapper
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :start :row)
|
||||||
|
:value row-start}]
|
||||||
|
[:> numeric-input
|
||||||
|
{:placeholder "--"
|
||||||
|
:on-click #(dom/select-target %)
|
||||||
|
:on-change (partial on-change :end :row)
|
||||||
|
:value row-end}]]]])]
|
||||||
|
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.row-title "Align"]
|
||||||
|
[:div.btn-wrapper
|
||||||
|
[:& set-self-alignment {:is-col? false
|
||||||
|
:alignment @align-self
|
||||||
|
:set-alignment set-alignment}]]]
|
||||||
|
|
||||||
|
|
||||||
|
[:div.layout-row
|
||||||
|
[:div.row-title "Justify"]
|
||||||
|
[:div.btn-wrapper
|
||||||
|
[:& set-self-alignment {:is-col? true
|
||||||
|
:alignment @justify-alignment
|
||||||
|
:set-alignment set-justify-self}]]]]]))
|
|
@ -29,15 +29,15 @@
|
||||||
{::mf/wrap [mf/memo]
|
{::mf/wrap [mf/memo]
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [shape (unchecked-get props "shape")
|
||||||
shape-with-children (unchecked-get props "shape-with-children")
|
shape-with-children (unchecked-get props "shape-with-children")
|
||||||
shared-libs (unchecked-get props "shared-libs")
|
shared-libs (unchecked-get props "shared-libs")
|
||||||
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
objects (->> shape-with-children (group-by :id) (d/mapm (fn [_ v] (first v))))
|
||||||
file-id (unchecked-get props "file-id")
|
file-id (unchecked-get props "file-id")
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
ids [(:id shape)]
|
ids [(:id shape)]
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
||||||
|
|
||||||
type :group
|
type :group
|
||||||
|
@ -58,7 +58,7 @@
|
||||||
[:& component-menu {:ids comp-ids :values comp-values :shape-name (:name shape)}]
|
[:& component-menu {:ids comp-ids :values comp-values :shape-name (:name shape)}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:type type
|
{:type type
|
||||||
:ids layout-item-ids
|
:ids layout-item-ids
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
:is-layout-container? false
|
:is-layout-container? false
|
||||||
:values layout-item-values}])
|
:values layout-item-values}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids constraint-ids :values constraint-values}])
|
[:& constraints-menu {:ids constraint-ids :values constraint-values}])
|
||||||
|
|
||||||
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
|
[:& layer-menu {:type type :ids layer-ids :values layer-values}]
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
[:& measures-menu {:ids ids
|
[:& measures-menu {:ids ids
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
|
|
||||||
|
|
|
@ -294,17 +294,17 @@
|
||||||
all-types (into #{} (map :type shapes))
|
all-types (into #{} (map :type shapes))
|
||||||
|
|
||||||
ids (->> shapes (map :id))
|
ids (->> shapes (map :id))
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
|
|
||||||
has-text? (contains? all-types :text)
|
has-text? (contains? all-types :text)
|
||||||
|
|
||||||
has-layout-container? (->> shapes (some ctl/layout?))
|
has-flex-layout-container? (->> shapes (some ctl/flex-layout?))
|
||||||
|
|
||||||
all-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/all-layout-child? ids))
|
all-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/all-flex-layout-child? ids))
|
||||||
all-layout-child? (mf/deref all-layout-child-ref)
|
all-flex-layout-child? (mf/deref all-flex-layout-child-ref)
|
||||||
|
|
||||||
all-layout-container? (->> shapes (every? ctl/layout?))
|
all-flex-layout-container? (->> shapes (every? ctl/flex-layout?))
|
||||||
|
|
||||||
[measure-ids measure-values] (get-attrs shapes objects :measure)
|
[measure-ids measure-values] (get-attrs shapes objects :measure)
|
||||||
|
|
||||||
|
@ -342,15 +342,15 @@
|
||||||
|
|
||||||
[:& layout-container-menu {:type type :ids layout-container-ids :values layout-container-values :multiple true}]
|
[:& layout-container-menu {:type type :ids layout-container-ids :values layout-container-values :multiple true}]
|
||||||
|
|
||||||
(when (or is-layout-child? has-layout-container?)
|
(when (or is-flex-layout-child? has-flex-layout-container?)
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:type type
|
{:type type
|
||||||
:ids layout-item-ids
|
:ids layout-item-ids
|
||||||
:is-layout-child? all-layout-child?
|
:is-layout-child? all-flex-layout-child?
|
||||||
:is-layout-container? all-layout-container?
|
:is-layout-container? all-flex-layout-container?
|
||||||
:values layout-item-values}])
|
:values layout-item-values}])
|
||||||
|
|
||||||
(when-not (or (empty? constraint-ids) is-layout-child?)
|
(when-not (or (empty? constraint-ids) is-flex-layout-child?)
|
||||||
[:& constraints-menu {:ids constraint-ids :values constraint-values}])
|
[:& constraints-menu {:ids constraint-ids :values constraint-values}])
|
||||||
|
|
||||||
(when-not (empty? layer-ids)
|
(when-not (empty? layer-ids)
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
[:& measures-menu {:ids ids
|
[:& measures-menu {:ids ids
|
||||||
|
@ -42,14 +42,14 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu {:ids ids
|
[:& layout-item-menu {:ids ids
|
||||||
:type type
|
:type type
|
||||||
:values layout-item-values
|
:values layout-item-values
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:is-layout-container? false
|
:is-layout-container? false
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
[:& layer-menu {:ids ids
|
[:& layer-menu {:ids ids
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
stroke-values (select-keys shape stroke-attrs)
|
stroke-values (select-keys shape stroke-attrs)
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
[:*
|
[:*
|
||||||
[:& measures-menu {:ids ids
|
[:& measures-menu {:ids ids
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
:values measure-values
|
:values measure-values
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,8 @@
|
||||||
layout-item-values (select-keys shape layout-item-attrs)
|
layout-item-values (select-keys shape layout-item-attrs)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
is-layout-child-absolute? (ctl/layout-absolute? shape)]
|
||||||
|
|
||||||
(when (contains? svg-elements tag)
|
(when (contains? svg-elements tag)
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu {:ids ids
|
[:& constraints-menu {:ids ids
|
||||||
:values constraint-values}])
|
:values constraint-values}])
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
(let [ids [(:id shape)]
|
(let [ids [(:id shape)]
|
||||||
type (:type shape)
|
type (:type shape)
|
||||||
|
|
||||||
is-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-layout-child? ids))
|
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
|
||||||
is-layout-child? (mf/deref is-layout-child-ref)
|
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
|
||||||
layout-container-values (select-keys shape layout-container-flex-attrs)
|
layout-container-values (select-keys shape layout-container-flex-attrs)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
||||||
state-map (mf/deref refs/workspace-editor-state)
|
state-map (mf/deref refs/workspace-editor-state)
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
:shape shape}]
|
:shape shape}]
|
||||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||||
|
|
||||||
(when is-layout-child?
|
(when is-flex-layout-child?
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -84,7 +84,7 @@
|
||||||
:is-layout-child? true
|
:is-layout-child? true
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
(when (or (not is-layout-child?) is-layout-child-absolute?)
|
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||||
[:& constraints-menu
|
[:& constraints-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:values (select-keys shape constraint-attrs)}])
|
:values (select-keys shape constraint-attrs)}])
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
[app.main.ui.workspace.viewport.drawarea :as drawarea]
|
[app.main.ui.workspace.viewport.drawarea :as drawarea]
|
||||||
[app.main.ui.workspace.viewport.frame-grid :as frame-grid]
|
[app.main.ui.workspace.viewport.frame-grid :as frame-grid]
|
||||||
[app.main.ui.workspace.viewport.gradients :as gradients]
|
[app.main.ui.workspace.viewport.gradients :as gradients]
|
||||||
|
[app.main.ui.workspace.viewport.grid-layout-editor :as grid-layout]
|
||||||
[app.main.ui.workspace.viewport.guides :as guides]
|
[app.main.ui.workspace.viewport.guides :as guides]
|
||||||
[app.main.ui.workspace.viewport.hooks :as hooks]
|
[app.main.ui.workspace.viewport.hooks :as hooks]
|
||||||
[app.main.ui.workspace.viewport.interactions :as interactions]
|
[app.main.ui.workspace.viewport.interactions :as interactions]
|
||||||
|
@ -51,17 +52,20 @@
|
||||||
|
|
||||||
(defn apply-modifiers-to-selected
|
(defn apply-modifiers-to-selected
|
||||||
[selected objects text-modifiers modifiers]
|
[selected objects text-modifiers modifiers]
|
||||||
(into []
|
(reduce
|
||||||
(comp
|
(fn [objects id]
|
||||||
(keep (d/getf objects))
|
(update
|
||||||
(map (fn [{:keys [id] :as shape}]
|
objects id
|
||||||
(cond-> shape
|
(fn [shape]
|
||||||
(and (cph/text-shape? shape) (contains? text-modifiers id))
|
(cond-> shape
|
||||||
(dwm/apply-text-modifier (get text-modifiers id))
|
(and (cph/text-shape? shape) (contains? text-modifiers id))
|
||||||
|
(dwm/apply-text-modifier (get text-modifiers id))
|
||||||
|
|
||||||
(contains? modifiers id)
|
(contains? modifiers id)
|
||||||
(gsh/transform-shape (dm/get-in modifiers [id :modifiers]))))))
|
(gsh/transform-shape (dm/get-in modifiers [id :modifiers]))))))
|
||||||
selected))
|
|
||||||
|
objects
|
||||||
|
selected))
|
||||||
|
|
||||||
(mf/defc viewport
|
(mf/defc viewport
|
||||||
[{:keys [wlocal wglobal selected layout file] :as props}]
|
[{:keys [wlocal wglobal selected layout file] :as props}]
|
||||||
|
@ -97,8 +101,11 @@
|
||||||
modifiers (mf/deref refs/workspace-modifiers)
|
modifiers (mf/deref refs/workspace-modifiers)
|
||||||
text-modifiers (mf/deref refs/workspace-text-modifier)
|
text-modifiers (mf/deref refs/workspace-text-modifier)
|
||||||
|
|
||||||
objects-modified (mf/with-memo [base-objects modifiers]
|
objects-modified (mf/with-memo
|
||||||
(gsh/apply-objects-modifiers base-objects modifiers selected))
|
[base-objects text-modifiers modifiers]
|
||||||
|
(apply-modifiers-to-selected selected base-objects text-modifiers modifiers))
|
||||||
|
|
||||||
|
selected-shapes (->> selected (keep (d/getf objects-modified)))
|
||||||
|
|
||||||
background (get options :background clr/canvas)
|
background (get options :background clr/canvas)
|
||||||
|
|
||||||
|
@ -138,7 +145,6 @@
|
||||||
drawing-tool (:tool drawing)
|
drawing-tool (:tool drawing)
|
||||||
drawing-obj (:object drawing)
|
drawing-obj (:object drawing)
|
||||||
|
|
||||||
selected-shapes (apply-modifiers-to-selected selected base-objects text-modifiers modifiers)
|
|
||||||
|
|
||||||
selected-frames (into #{} (map :frame-id) selected-shapes)
|
selected-frames (into #{} (map :frame-id) selected-shapes)
|
||||||
|
|
||||||
|
@ -152,6 +158,7 @@
|
||||||
(and (some? drawing-obj) (= :path (:type drawing-obj))))
|
(and (some? drawing-obj) (= :path (:type drawing-obj))))
|
||||||
node-editing? (and edition (not= :text (get-in base-objects [edition :type])))
|
node-editing? (and edition (not= :text (get-in base-objects [edition :type])))
|
||||||
text-editing? (and edition (= :text (get-in base-objects [edition :type])))
|
text-editing? (and edition (= :text (get-in base-objects [edition :type])))
|
||||||
|
grid-editing? (and edition (ctl/grid-layout? base-objects edition))
|
||||||
|
|
||||||
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
mode-inspect? (= options-mode :inspect)
|
mode-inspect? (= options-mode :inspect)
|
||||||
|
@ -162,7 +169,7 @@
|
||||||
on-drag-enter (actions/on-drag-enter)
|
on-drag-enter (actions/on-drag-enter)
|
||||||
on-drag-over (actions/on-drag-over)
|
on-drag-over (actions/on-drag-over)
|
||||||
on-drop (actions/on-drop file)
|
on-drop (actions/on-drop file)
|
||||||
on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing?
|
on-mouse-down (actions/on-mouse-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing?
|
||||||
drawing-path? create-comment? space? panning z? workspace-read-only?)
|
drawing-path? create-comment? space? panning z? workspace-read-only?)
|
||||||
on-mouse-up (actions/on-mouse-up disable-paste)
|
on-mouse-up (actions/on-mouse-up disable-paste)
|
||||||
on-pointer-down (actions/on-pointer-down)
|
on-pointer-down (actions/on-pointer-down)
|
||||||
|
@ -193,6 +200,7 @@
|
||||||
show-pixel-grid? (and (contains? layout :show-pixel-grid)
|
show-pixel-grid? (and (contains? layout :show-pixel-grid)
|
||||||
(>= zoom 8))
|
(>= zoom 8))
|
||||||
show-text-editor? (and editing-shape (= :text (:type editing-shape)))
|
show-text-editor? (and editing-shape (= :text (:type editing-shape)))
|
||||||
|
show-grid-editor? (and editing-shape (ctl/grid-layout? editing-shape))
|
||||||
show-presence? page-id
|
show-presence? page-id
|
||||||
show-prototypes? (= options-mode :prototype)
|
show-prototypes? (= options-mode :prototype)
|
||||||
show-selection-handlers? (and (seq selected) (not show-text-editor?))
|
show-selection-handlers? (and (seq selected) (not show-text-editor?))
|
||||||
|
@ -333,7 +341,7 @@
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:modifiers modifiers}]
|
:modifiers modifiers}]
|
||||||
|
|
||||||
(when (ctl/layout? outlined-frame)
|
(when (ctl/any-layout? outlined-frame)
|
||||||
[:g.ghost-outline
|
[:g.ghost-outline
|
||||||
[:& outline/shape-outlines
|
[:& outline/shape-outlines
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
|
@ -496,6 +504,12 @@
|
||||||
:hover-top-frame-id @hover-top-frame-id
|
:hover-top-frame-id @hover-top-frame-id
|
||||||
:zoom zoom}])
|
:zoom zoom}])
|
||||||
|
|
||||||
|
(when (debug? :grid-layout)
|
||||||
|
[:& wvd/debug-grid-layout {:selected-shapes selected-shapes
|
||||||
|
:objects base-objects
|
||||||
|
:hover-top-frame-id @hover-top-frame-id
|
||||||
|
:zoom zoom}])
|
||||||
|
|
||||||
(when show-selection-handlers?
|
(when show-selection-handlers?
|
||||||
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
[:g.selection-handlers {:clipPath "url(#clip-handlers)"}
|
||||||
[:defs
|
[:defs
|
||||||
|
@ -526,4 +540,11 @@
|
||||||
(when show-gradient-handlers?
|
(when show-gradient-handlers?
|
||||||
[:& gradients/gradient-handlers
|
[:& gradients/gradient-handlers
|
||||||
{:id (first selected)
|
{:id (first selected)
|
||||||
:zoom zoom}])]]]))
|
:zoom zoom}])
|
||||||
|
|
||||||
|
(when show-grid-editor?
|
||||||
|
[:& grid-layout/editor
|
||||||
|
{:zoom zoom
|
||||||
|
:objects base-objects
|
||||||
|
:shape (get base-objects edition)}])
|
||||||
|
]]]))
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
|
|
||||||
(defn on-mouse-down
|
(defn on-mouse-down
|
||||||
[{:keys [id blocked hidden type]} selected edition drawing-tool text-editing?
|
[{:keys [id blocked hidden type]} selected edition drawing-tool text-editing?
|
||||||
node-editing? drawing-path? create-comment? space? panning z? workspace-read-only?]
|
node-editing? grid-editing? drawing-path? create-comment? space? panning z? workspace-read-only?]
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps id blocked hidden type selected edition drawing-tool text-editing?
|
(mf/deps id blocked hidden type selected edition drawing-tool text-editing?
|
||||||
node-editing? drawing-path? create-comment? @z? @space?
|
node-editing? grid-editing? drawing-path? create-comment? @z? @space?
|
||||||
panning workspace-read-only?)
|
panning workspace-read-only?)
|
||||||
(fn [bevent]
|
(fn [bevent]
|
||||||
(when (or (dom/class? (dom/get-target bevent) "viewport-controls")
|
(when (or (dom/class? (dom/get-target bevent) "viewport-controls")
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
(do
|
(do
|
||||||
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?))
|
(st/emit! (ms/->MouseEvent :down ctrl? shift? alt? meta?))
|
||||||
|
|
||||||
(when (and (not= edition id) text-editing?)
|
(when (and (not= edition id) (or text-editing? grid-editing?))
|
||||||
(st/emit! dw/clear-edition-mode))
|
(st/emit! dw/clear-edition-mode))
|
||||||
|
|
||||||
(when (and (not text-editing?)
|
(when (and (not text-editing?)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.geom.shapes.flex-layout :as gsl]
|
[app.common.geom.shapes.flex-layout :as gsl]
|
||||||
|
[app.common.geom.shapes.grid-layout :as gsg]
|
||||||
[app.common.geom.shapes.points :as gpo]
|
[app.common.geom.shapes.points :as gpo]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
|
@ -68,7 +69,7 @@
|
||||||
|
|
||||||
shape (or selected-frame (get objects hover-top-frame-id))]
|
shape (or selected-frame (get objects hover-top-frame-id))]
|
||||||
|
|
||||||
(when (and shape (ctl/layout? shape))
|
(when (and shape (ctl/flex-layout? shape))
|
||||||
(let [row? (ctl/row? shape)
|
(let [row? (ctl/row? shape)
|
||||||
col? (ctl/col? shape)
|
col? (ctl/col? shape)
|
||||||
|
|
||||||
|
@ -195,3 +196,55 @@
|
||||||
:cy (:y point)
|
:cy (:y point)
|
||||||
:r (/ 2 zoom)
|
:r (/ 2 zoom)
|
||||||
:style {:fill "red"}}]))])]))))
|
:style {:fill "red"}}]))])]))))
|
||||||
|
|
||||||
|
(mf/defc debug-grid-layout
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [objects (unchecked-get props "objects")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
selected-shapes (unchecked-get props "selected-shapes")
|
||||||
|
hover-top-frame-id (unchecked-get props "hover-top-frame-id")
|
||||||
|
|
||||||
|
selected-frame
|
||||||
|
(when (and (= (count selected-shapes) 1) (= :frame (-> selected-shapes first :type)))
|
||||||
|
(first selected-shapes))
|
||||||
|
|
||||||
|
parent (or selected-frame (get objects hover-top-frame-id))
|
||||||
|
parent-bounds (:points parent)]
|
||||||
|
|
||||||
|
(when (and (some? parent) (not= uuid/zero (:id parent)))
|
||||||
|
(let [children (->> (cph/get-immediate-children objects (:id parent))
|
||||||
|
(remove :hidden)
|
||||||
|
(map #(vector (gpo/parent-coords-bounds (:points %) (:points parent)) %)))
|
||||||
|
|
||||||
|
hv #(gpo/start-hv parent-bounds %)
|
||||||
|
vv #(gpo/start-vv parent-bounds %)
|
||||||
|
|
||||||
|
width (gpo/width-points parent-bounds)
|
||||||
|
height (gpo/height-points parent-bounds)
|
||||||
|
origin (gpo/origin parent-bounds)
|
||||||
|
|
||||||
|
{:keys [row-tracks column-tracks]}
|
||||||
|
(gsg/calc-layout-data parent children parent-bounds)]
|
||||||
|
|
||||||
|
[:*
|
||||||
|
(for [row-data row-tracks]
|
||||||
|
(let [start-p (gpt/add origin (vv (:distance row-data)))
|
||||||
|
end-p (gpt/add start-p (hv width))]
|
||||||
|
[:line {:x1 (:x start-p)
|
||||||
|
:y1 (:y start-p)
|
||||||
|
:x2 (:x end-p)
|
||||||
|
:y2 (:y end-p)
|
||||||
|
:style {:stroke "red"
|
||||||
|
:stroke-width (/ 1 zoom)}}]))
|
||||||
|
|
||||||
|
(for [column-data column-tracks]
|
||||||
|
(let [start-p (gpt/add origin (hv (:distance column-data)))
|
||||||
|
end-p (gpt/add start-p (vv height))]
|
||||||
|
[:line {:x1 (:x start-p)
|
||||||
|
:y1 (:y start-p)
|
||||||
|
:x2 (:x end-p)
|
||||||
|
:y2 (:y end-p)
|
||||||
|
:style {:stroke "red"
|
||||||
|
:stroke-width (/ 1 zoom)}}]))]))))
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
;; 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/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.main.ui.workspace.viewport.grid-layout-editor
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.geom.shapes.grid-layout :as gsg]
|
||||||
|
[app.common.geom.shapes.points :as gpo]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
|
[app.main.data.workspace.grid-layout.editor :as dwge]
|
||||||
|
[app.main.refs :as refs]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.main.ui.cursors :as cur]
|
||||||
|
[app.util.dom :as dom]
|
||||||
|
[cuerdas.core :as str]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(defn apply-to-point [result next-fn]
|
||||||
|
(conj result (next-fn (last result))))
|
||||||
|
|
||||||
|
(mf/defc track-marker
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [center (unchecked-get props "center")
|
||||||
|
value (unchecked-get props "value")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
|
||||||
|
marker-points
|
||||||
|
(reduce
|
||||||
|
apply-to-point
|
||||||
|
[(gpt/subtract center
|
||||||
|
(gpt/point (/ 13 zoom) (/ 16 zoom)))]
|
||||||
|
[#(gpt/add % (gpt/point (/ 26 zoom) 0))
|
||||||
|
#(gpt/add % (gpt/point 0 (/ 24 zoom)))
|
||||||
|
#(gpt/add % (gpt/point (- (/ 13 zoom)) (/ 8 zoom)))
|
||||||
|
#(gpt/subtract % (gpt/point (/ 13 zoom) (/ 8 zoom)))])
|
||||||
|
|
||||||
|
text-x (:x center)
|
||||||
|
text-y (:y center)]
|
||||||
|
|
||||||
|
[:g.grid-track-marker
|
||||||
|
[:polygon {:points (->> marker-points
|
||||||
|
(map #(dm/fmt "%,%" (:x %) (:y %)))
|
||||||
|
(str/join " "))
|
||||||
|
|
||||||
|
:style {:fill "var(--color-distance)"
|
||||||
|
:fill-opacity 0.3}}]
|
||||||
|
[:text {:x text-x
|
||||||
|
:y text-y
|
||||||
|
:width (/ 26.26 zoom)
|
||||||
|
:height (/ 32 zoom)
|
||||||
|
:font-size (/ 16 zoom)
|
||||||
|
:text-anchor "middle"
|
||||||
|
:dominant-baseline "middle"
|
||||||
|
:style {:fill "var(--color-distance)"}}
|
||||||
|
(dm/str value)]]))
|
||||||
|
|
||||||
|
(mf/defc grid-editor-frame
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [bounds (unchecked-get props "bounds")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
hv #(gpo/start-hv bounds %)
|
||||||
|
vv #(gpo/start-vv bounds %)
|
||||||
|
width (gpo/width-points bounds)
|
||||||
|
height (gpo/height-points bounds)
|
||||||
|
origin (gpo/origin bounds)
|
||||||
|
|
||||||
|
frame-points
|
||||||
|
(reduce
|
||||||
|
apply-to-point
|
||||||
|
[origin]
|
||||||
|
[#(gpt/add % (hv width))
|
||||||
|
#(gpt/subtract % (vv (/ 40 zoom)))
|
||||||
|
#(gpt/subtract % (hv (+ width (/ 40 zoom))))
|
||||||
|
#(gpt/add % (vv (+ height (/ 40 zoom))))
|
||||||
|
#(gpt/add % (hv (/ 40 zoom)))])]
|
||||||
|
|
||||||
|
[:polygon {:points (->> frame-points
|
||||||
|
(map #(dm/fmt "%,%" (:x %) (:y %)))
|
||||||
|
(str/join " "))
|
||||||
|
:style {:stroke "var(--color-distance)"
|
||||||
|
:stroke-width (/ 1 zoom)}}]))
|
||||||
|
|
||||||
|
(mf/defc plus-btn
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [start-p (unchecked-get props "start-p")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
type (unchecked-get props "type")
|
||||||
|
|
||||||
|
[rect-x rect-y icon-x icon-y]
|
||||||
|
(if (= type :column)
|
||||||
|
[(:x start-p)
|
||||||
|
(- (:y start-p) (/ 40 zoom))
|
||||||
|
(+ (:x start-p) (/ 12 zoom))
|
||||||
|
(- (:y start-p) (/ 28 zoom))]
|
||||||
|
|
||||||
|
[(- (:x start-p) (/ 40 zoom))
|
||||||
|
(:y start-p)
|
||||||
|
(- (:x start-p) (/ 28 zoom))
|
||||||
|
(+ (:y start-p) (/ 12 zoom))])]
|
||||||
|
|
||||||
|
[:g.plus-button
|
||||||
|
[:rect {:x rect-x
|
||||||
|
:y rect-y
|
||||||
|
:width (/ 40 zoom)
|
||||||
|
:height (/ 40 zoom)
|
||||||
|
:style {:fill "var(--color-distance)"
|
||||||
|
:stroke "var(--color-distance)"
|
||||||
|
:stroke-width (/ 1 zoom)}}]
|
||||||
|
|
||||||
|
[:use {:x icon-x
|
||||||
|
:y icon-y
|
||||||
|
:width (/ 16 zoom)
|
||||||
|
:height (/ 16 zoom)
|
||||||
|
:href (dm/str "#icon-plus")
|
||||||
|
:fill "white"}]]))
|
||||||
|
|
||||||
|
(mf/defc grid-cell
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
(let [shape (unchecked-get props "shape")
|
||||||
|
{:keys [row-tracks column-tracks]} (unchecked-get props "layout-data")
|
||||||
|
bounds (unchecked-get props "bounds")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
|
||||||
|
hover? (unchecked-get props "hover?")
|
||||||
|
selected? (unchecked-get props "selected?")
|
||||||
|
|
||||||
|
row (unchecked-get props "row")
|
||||||
|
column (unchecked-get props "column")
|
||||||
|
|
||||||
|
column-track (nth column-tracks (dec column) nil)
|
||||||
|
row-track (nth row-tracks (dec row) nil)
|
||||||
|
|
||||||
|
|
||||||
|
origin (gpo/origin bounds)
|
||||||
|
hv #(gpo/start-hv bounds %)
|
||||||
|
vv #(gpo/start-vv bounds %)
|
||||||
|
|
||||||
|
start-p (-> origin
|
||||||
|
(gpt/add (hv (:distance column-track)))
|
||||||
|
(gpt/add (vv (:distance row-track))))
|
||||||
|
|
||||||
|
end-p (-> start-p
|
||||||
|
(gpt/add (hv (:value column-track)))
|
||||||
|
(gpt/add (vv (:value row-track))))]
|
||||||
|
|
||||||
|
[:rect.cell-editor
|
||||||
|
{:x (:x start-p)
|
||||||
|
:y (:y start-p)
|
||||||
|
:width (- (:x end-p) (:x start-p))
|
||||||
|
:height (- (:y end-p) (:y start-p))
|
||||||
|
|
||||||
|
:on-pointer-enter #(st/emit! (dwge/hover-grid-cell (:id shape) row column true))
|
||||||
|
:on-pointer-leave #(st/emit! (dwge/hover-grid-cell (:id shape) row column false))
|
||||||
|
|
||||||
|
:on-click #(st/emit! (dwge/select-grid-cell (:id shape) row column))
|
||||||
|
|
||||||
|
:style {:fill "transparent"
|
||||||
|
:stroke "var(--color-distance)"
|
||||||
|
:stroke-dasharray (when-not (or hover? selected?)
|
||||||
|
(str/join " " (map #(/ % zoom) [0 8]) ))
|
||||||
|
:stroke-linecap "round"
|
||||||
|
:stroke-width (/ 2 zoom)}}]))
|
||||||
|
|
||||||
|
(mf/defc resize-handler
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [start-p (unchecked-get props "start-p")
|
||||||
|
type (unchecked-get props "type")
|
||||||
|
bounds (unchecked-get props "bounds")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
|
||||||
|
width (gpo/width-points bounds)
|
||||||
|
height (gpo/height-points bounds)
|
||||||
|
|
||||||
|
dragging-ref (mf/use-ref false)
|
||||||
|
start-ref (mf/use-ref nil)
|
||||||
|
|
||||||
|
on-pointer-down
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [event]
|
||||||
|
(dom/capture-pointer event)
|
||||||
|
(mf/set-ref-val! dragging-ref true)
|
||||||
|
(mf/set-ref-val! start-ref (dom/get-client-position event))))
|
||||||
|
|
||||||
|
on-lost-pointer-capture
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [event]
|
||||||
|
(dom/release-pointer event)
|
||||||
|
(mf/set-ref-val! dragging-ref false)
|
||||||
|
(mf/set-ref-val! start-ref nil)))
|
||||||
|
|
||||||
|
on-mouse-move
|
||||||
|
(mf/use-callback
|
||||||
|
(fn [event]
|
||||||
|
(when (mf/ref-val dragging-ref)
|
||||||
|
(let [start (mf/ref-val start-ref)
|
||||||
|
pos (dom/get-client-position event)
|
||||||
|
_delta (-> (gpt/to-vec start pos)
|
||||||
|
(get (if (= type :column) :x :y)))]
|
||||||
|
|
||||||
|
;; TODO Implement resize
|
||||||
|
#_(prn ">Delta" delta)))))
|
||||||
|
|
||||||
|
|
||||||
|
[x y width height]
|
||||||
|
(if (= type :column)
|
||||||
|
[(- (:x start-p) (/ 8 zoom))
|
||||||
|
(- (:y start-p) (/ 40 zoom))
|
||||||
|
(/ 16 zoom)
|
||||||
|
(+ height (/ 40 zoom))]
|
||||||
|
|
||||||
|
[(- (:x start-p) (/ 40 zoom))
|
||||||
|
(- (:y start-p) (/ 8 zoom))
|
||||||
|
(+ width (/ 40 zoom))
|
||||||
|
(/ 16 zoom)])]
|
||||||
|
|
||||||
|
[:rect.resize-handler
|
||||||
|
{:x x
|
||||||
|
:y y
|
||||||
|
:height height
|
||||||
|
:width width
|
||||||
|
:on-pointer-down on-pointer-down
|
||||||
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
|
:on-mouse-move on-mouse-move
|
||||||
|
:style {:fill "transparent"
|
||||||
|
:cursor (if (= type :column)
|
||||||
|
(cur/resize-ew 0)
|
||||||
|
(cur/resize-ns 0))}}]))
|
||||||
|
|
||||||
|
(mf/defc editor
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[props]
|
||||||
|
|
||||||
|
(let [shape (unchecked-get props "shape")
|
||||||
|
objects (unchecked-get props "objects")
|
||||||
|
zoom (unchecked-get props "zoom")
|
||||||
|
bounds (:points shape)
|
||||||
|
|
||||||
|
grid-edition-id-ref (mf/use-memo #(refs/workspace-grid-edition-id (:id shape)))
|
||||||
|
grid-edition (mf/deref grid-edition-id-ref)
|
||||||
|
|
||||||
|
hover-cells (:hover grid-edition)
|
||||||
|
selected-cells (:selected grid-edition)
|
||||||
|
|
||||||
|
children (->> (cph/get-immediate-children objects (:id shape))
|
||||||
|
(remove :hidden)
|
||||||
|
(map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %)))
|
||||||
|
|
||||||
|
hv #(gpo/start-hv bounds %)
|
||||||
|
vv #(gpo/start-vv bounds %)
|
||||||
|
width (gpo/width-points bounds)
|
||||||
|
height (gpo/height-points bounds)
|
||||||
|
origin (gpo/origin bounds)
|
||||||
|
|
||||||
|
{:keys [row-tracks column-tracks] :as layout-data}
|
||||||
|
(gsg/calc-layout-data shape children bounds)]
|
||||||
|
|
||||||
|
(mf/use-effect
|
||||||
|
(fn []
|
||||||
|
#(st/emit! (dwge/stop-grid-layout-editing (:id shape)))))
|
||||||
|
|
||||||
|
[:g.grid-editor
|
||||||
|
[:& grid-editor-frame {:zoom zoom
|
||||||
|
:bounds bounds}]
|
||||||
|
(let [start-p (-> origin (gpt/add (hv width)))]
|
||||||
|
[:& plus-btn {:start-p start-p
|
||||||
|
:zoom zoom
|
||||||
|
:type :column}])
|
||||||
|
|
||||||
|
(let [start-p (-> origin (gpt/add (vv height)))]
|
||||||
|
[:& plus-btn {:start-p start-p
|
||||||
|
:zoom zoom
|
||||||
|
:type :row}])
|
||||||
|
|
||||||
|
(for [[_ {:keys [column row]}] (:layout-grid-cells shape)]
|
||||||
|
[:& grid-cell {:shape shape
|
||||||
|
:layout-data layout-data
|
||||||
|
:row row
|
||||||
|
:column column
|
||||||
|
:bounds bounds
|
||||||
|
:zoom zoom
|
||||||
|
:hover? (contains? hover-cells [row column])
|
||||||
|
:selected? (= selected-cells [row column])
|
||||||
|
}])
|
||||||
|
|
||||||
|
(for [[idx column-data] (d/enumerate column-tracks)]
|
||||||
|
(let [start-p (-> origin (gpt/add (hv (:distance column-data))))
|
||||||
|
marker-p (-> start-p (gpt/subtract (vv (/ 20 zoom))))]
|
||||||
|
[:*
|
||||||
|
[:& track-marker {:center marker-p
|
||||||
|
:value (dm/str (inc idx))
|
||||||
|
:zoom zoom}]
|
||||||
|
|
||||||
|
[:& resize-handler {:type :column
|
||||||
|
:start-p start-p
|
||||||
|
:zoom zoom
|
||||||
|
:bounds bounds}]]))
|
||||||
|
|
||||||
|
(for [[idx row-data] (d/enumerate row-tracks)]
|
||||||
|
(let [start-p (-> origin (gpt/add (vv (:distance row-data))))
|
||||||
|
marker-p (-> start-p (gpt/subtract (hv (/ 20 zoom))))]
|
||||||
|
[:*
|
||||||
|
[:g {:transform (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p))}
|
||||||
|
[:& track-marker {:center marker-p
|
||||||
|
:value (dm/str (inc idx))
|
||||||
|
:zoom zoom}]]
|
||||||
|
|
||||||
|
[:& resize-handler {:type :row
|
||||||
|
:start-p start-p
|
||||||
|
:zoom zoom
|
||||||
|
:bounds bounds}]]))]))
|
|
@ -268,7 +268,7 @@
|
||||||
frame (mf/deref (refs/object-by-id frame-id))
|
frame (mf/deref (refs/object-by-id frame-id))
|
||||||
selrect (gsh/selection-rect selected-shapes)]
|
selrect (gsh/selection-rect selected-shapes)]
|
||||||
|
|
||||||
(when-not (ctl/layout? frame)
|
(when-not (ctl/any-layout? frame)
|
||||||
[:g.distance
|
[:g.distance
|
||||||
[:& shape-distance
|
[:& shape-distance
|
||||||
{:selrect selrect
|
{:selrect selrect
|
||||||
|
|
|
@ -175,7 +175,7 @@
|
||||||
|
|
||||||
shapes (if drawing [drawing] shapes)
|
shapes (if drawing [drawing] shapes)
|
||||||
frame-id (snap/snap-frame-id shapes)]
|
frame-id (snap/snap-frame-id shapes)]
|
||||||
(when-not (ctl/layout? objects frame-id)
|
(when-not (ctl/any-layout? objects frame-id)
|
||||||
[:& snap-feedback {:shapes shapes
|
[:& snap-feedback {:shapes shapes
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:remove-snap? remove-snap?
|
:remove-snap? remove-snap?
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
|
[app.common.pages.helpers :as cph]
|
||||||
[app.common.types.shape-tree :as ctt]
|
[app.common.types.shape-tree :as ctt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.main.data.workspace :as dw]
|
[app.main.data.workspace :as dw]
|
||||||
|
@ -55,8 +56,11 @@
|
||||||
drawing (mf/deref refs/workspace-drawing)
|
drawing (mf/deref refs/workspace-drawing)
|
||||||
drawing-obj (:object drawing)
|
drawing-obj (:object drawing)
|
||||||
shape (or drawing-obj (-> selected first))]
|
shape (or drawing-obj (-> selected first))]
|
||||||
(when (or (and (= (count selected) 1) (= (:id shape) edition) (not= :text (:type shape)))
|
(when (or (and (= (count selected) 1)
|
||||||
(and (some? drawing-obj) (= :path (:type drawing-obj))
|
(= (:id shape) edition)
|
||||||
|
(cph/path-shape? shape))
|
||||||
|
(and (some? drawing-obj)
|
||||||
|
(cph/path-shape? drawing-obj)
|
||||||
(not= :curve (:tool drawing))))
|
(not= :curve (:tool drawing))))
|
||||||
[:div.viewport-actions
|
[:div.viewport-actions
|
||||||
[:& path-actions {:shape shape}]])))
|
[:& path-actions {:shape shape}]])))
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
grid-y-data (get-grids-snap-points frame :y)]
|
grid-y-data (get-grids-snap-points frame :y)]
|
||||||
|
|
||||||
(cond-> page-data
|
(cond-> page-data
|
||||||
(not (ctl/layout-descent? objects frame))
|
(not (ctl/any-layout-descent? objects frame))
|
||||||
|
|
||||||
(-> ;; Update root frame information
|
(-> ;; Update root frame information
|
||||||
(assoc-in [uuid/zero :objects-data frame-id] frame-data)
|
(assoc-in [uuid/zero :objects-data frame-id] frame-data)
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
:id (:id shape)
|
:id (:id shape)
|
||||||
:pt %)))]
|
:pt %)))]
|
||||||
(cond-> page-data
|
(cond-> page-data
|
||||||
(not (ctl/layout-descent? objects shape))
|
(not (ctl/any-layout-descent? objects shape))
|
||||||
(-> (assoc-in [frame-id :objects-data (:id shape)] shape-data)
|
(-> (assoc-in [frame-id :objects-data (:id shape)] shape-data)
|
||||||
(update-in [frame-id :x] (make-insert-tree-data shape-data :x))
|
(update-in [frame-id :x] (make-insert-tree-data shape-data :x))
|
||||||
(update-in [frame-id :y] (make-insert-tree-data shape-data :y))))))
|
(update-in [frame-id :y] (make-insert-tree-data shape-data :y))))))
|
||||||
|
|
|
@ -95,6 +95,9 @@
|
||||||
|
|
||||||
;; Show shape name and id
|
;; Show shape name and id
|
||||||
:shape-titles
|
:shape-titles
|
||||||
|
|
||||||
|
;;
|
||||||
|
:grid-layout
|
||||||
})
|
})
|
||||||
|
|
||||||
;; These events are excluded when we activate the :events flag
|
;; These events are excluded when we activate the :events flag
|
||||||
|
|