mirror of
https://github.com/penpot/penpot.git
synced 2025-03-16 01:31:22 -05:00
✨ Edition mode for grid
This commit is contained in:
parent
b497de0dae
commit
23104b28b6
15 changed files with 298 additions and 148 deletions
|
@ -13,3 +13,7 @@
|
|||
(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]))))
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
|
||||
(ns app.common.geom.shapes.grid-layout.layout-data
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.points :as gpo]))
|
||||
|
||||
(defn set-sample-data
|
||||
#_(defn set-sample-data
|
||||
[parent children]
|
||||
|
||||
(let [parent (assoc parent
|
||||
|
@ -38,8 +35,8 @@
|
|||
layout-grid-cells
|
||||
(into
|
||||
{}
|
||||
(for [[row-idx row] (d/enumerate (:layout-grid-rows parent))
|
||||
[col-idx col] (d/enumerate (:layout-grid-columns parent))]
|
||||
(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)
|
||||
|
@ -69,7 +66,7 @@
|
|||
))
|
||||
|
||||
(defn calc-layout-data
|
||||
[parent children transformed-parent-bounds]
|
||||
[parent _children transformed-parent-bounds]
|
||||
|
||||
(let [height (gpo/height-points transformed-parent-bounds)
|
||||
width (gpo/width-points transformed-parent-bounds)
|
||||
|
@ -124,7 +121,7 @@
|
|||
:shape-cells shape-cells}))
|
||||
|
||||
(defn get-cell-data
|
||||
[{:keys [row-tracks column-tracks shape-cells]} transformed-parent-bounds [child-bounds child]]
|
||||
[{: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 %)
|
||||
|
@ -138,7 +135,6 @@
|
|||
|
||||
start-p (-> origin
|
||||
(gpt/add (hv (:distance column)))
|
||||
(gpt/add (vv (:distance row))))
|
||||
]
|
||||
(gpt/add (vv (:distance row))))]
|
||||
|
||||
(assoc grid-cell :start-p start-p)))))
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
(fn [modif-tree shape]
|
||||
(let [modifiers (dm/get-in modif-tree [(:id shape) :modifiers])]
|
||||
(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))))]
|
||||
|
||||
(->> (keys modif-tree)
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
|
||||
(ns app.common.types.shape.layout
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[clojure.spec.alpha :as s]))
|
||||
|
||||
;; :layout ;; :flex, :grid in the future
|
||||
|
@ -41,6 +43,7 @@
|
|||
(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-grid-dir #{:row :column})
|
||||
(s/def ::layout-gap-type #{:simple :multiple})
|
||||
(s/def ::layout-gap ::us/safe-number)
|
||||
|
||||
|
@ -53,11 +56,34 @@
|
|||
|
||||
(s/def :grid/type #{:percent :flex :auto :fixed})
|
||||
(s/def :grid/value (s/nilable ::us/safe-number))
|
||||
(s/def ::grid-definition (s/keys :opt-un [:grid/type
|
||||
:grid/value]))
|
||||
(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 ::p2 ::us/safe-number)
|
||||
(s/def ::p3 ::us/safe-number)
|
||||
|
@ -85,9 +111,11 @@
|
|||
::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)
|
||||
|
@ -448,7 +476,12 @@
|
|||
:layout-padding
|
||||
:layout-justify-content
|
||||
: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
|
||||
[shape]
|
||||
|
@ -464,3 +497,91 @@
|
|||
:layout-item-align-self
|
||||
:layout-item-absolute
|
||||
: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 aloted 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)
|
||||
|
|
|
@ -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
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
|
@ -54,6 +54,7 @@
|
|||
|
||||
(def initial-grid-layout ;; TODO
|
||||
{:layout :grid
|
||||
:layout-grid-dir :row
|
||||
:layout-gap-type :multiple
|
||||
:layout-gap {:row-gap 0 :column-gap 0}
|
||||
:layout-align-items :start
|
||||
|
@ -62,7 +63,6 @@
|
|||
:layout-justify-content :start
|
||||
:layout-padding-type :simple
|
||||
:layout-padding {:p1 0 :p2 0 :p3 0 :p4 0}
|
||||
|
||||
:layout-grid-rows []
|
||||
:layout-grid-columns []})
|
||||
|
||||
|
@ -75,6 +75,7 @@
|
|||
(fn [shape]
|
||||
(-> shape
|
||||
(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
|
||||
(cond-> (not from-frame?)
|
||||
(assoc :show-content true :hide-in-viewer true))))))
|
||||
|
@ -154,6 +155,13 @@
|
|||
:layout-align-items :center
|
||||
: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
|
||||
[ids type from-frame?]
|
||||
(ptk/reify ::create-layout-from-id
|
||||
|
@ -163,8 +171,10 @@
|
|||
children-ids (into [] (mapcat #(get-in objects [% :shapes])) ids)
|
||||
children-shapes (map (d/getf objects) children-ids)
|
||||
parent (get objects (first ids))
|
||||
flex-params (when (d/not-empty? children-shapes)
|
||||
(shapes->flex-params objects children-shapes parent))
|
||||
layout-params (when (d/not-empty? children-shapes)
|
||||
(case type
|
||||
:flex (shapes->flex-params objects children-shapes parent)
|
||||
:grid (shapes->grid-params objects children-shapes parent)))
|
||||
undo-id (js/Symbol)]
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dwc/update-shapes ids (get-layout-initializer type from-frame?))
|
||||
|
@ -175,7 +185,7 @@
|
|||
(not from-frame?)
|
||||
(-> (assoc :layout-item-h-sizing :auto
|
||||
:layout-item-v-sizing :auto)
|
||||
(merge flex-params)))))
|
||||
(merge layout-params)))))
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwc/update-shapes children-ids #(dissoc % :constraints-h :constraints-v))
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
@ -183,7 +193,6 @@
|
|||
|
||||
;; Never call this directly but through the data-event `:layout/update`
|
||||
;; Otherwise a lot of cycle dependencies could be generated
|
||||
(declare check-grid-cells-update)
|
||||
(defn- update-layout-positions
|
||||
[ids]
|
||||
(ptk/reify ::update-layout-positions
|
||||
|
@ -191,16 +200,10 @@
|
|||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
ids (->> ids (filter #(contains? objects %)))]
|
||||
|
||||
(rx/concat
|
||||
;; Update grids if necesary
|
||||
(rx/of (check-grid-cells-update
|
||||
(->> (concat ids (map #(cph/get-parent-id objects %) ids))
|
||||
(filter #(ctl/grid-layout? objects %)))))
|
||||
(if (d/not-empty? ids)
|
||||
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modif-tree})))
|
||||
(rx/empty)))))))
|
||||
(if (d/not-empty? ids)
|
||||
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
|
||||
(rx/of (dwm/apply-modifiers {:modifiers modif-tree})))
|
||||
(rx/empty))))))
|
||||
|
||||
(defn initialize
|
||||
[]
|
||||
|
@ -321,15 +324,12 @@
|
|||
is-frame? (= :frame (:type (first selected-shapes)))
|
||||
undo-id (js/Symbol)]
|
||||
|
||||
(if (and single? is-frame?)
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(if (and single? is-frame?)
|
||||
(create-layout-from-id [(first selected)] type true)
|
||||
(dwu/commit-undo-transaction undo-id))
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
(create-layout-from-selection type)
|
||||
(dwu/commit-undo-transaction undo-id)))))))
|
||||
(create-layout-from-selection type))
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn toggle-layout-flex
|
||||
[]
|
||||
|
@ -359,14 +359,20 @@
|
|||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn update-grid-cells
|
||||
#_(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)
|
||||
|
@ -380,9 +386,9 @@
|
|||
:col-span 1
|
||||
:shapes (when shape [(:id shape)])}]
|
||||
[(:id cell-data) cell-data]))]
|
||||
(assoc parent :layout-grid-cells layout-grid-cells)))
|
||||
(assoc parent :layout-grid-cells (into {} layout-grid-cells))))
|
||||
|
||||
(defn check-grid-cells-update
|
||||
#_(defn check-grid-cells-update
|
||||
[ids]
|
||||
(ptk/reify ::check-grid-cells-update
|
||||
ptk/WatchEvent
|
||||
|
@ -395,54 +401,56 @@
|
|||
(-> shape
|
||||
(update-grid-cells objects)))))))))
|
||||
|
||||
(defn add-layout-column
|
||||
[ids property value]
|
||||
(defn add-layout-track
|
||||
[ids type value]
|
||||
(assert (#{:row :column} type))
|
||||
(ptk/reify ::add-layout-column
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
undo-id (js/Symbol)]
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dwc/update-shapes
|
||||
ids
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(update property (fnil conj []) value)
|
||||
(update-grid-cells objects))))
|
||||
(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-column
|
||||
[ids property index]
|
||||
(defn remove-layout-track
|
||||
[ids type index]
|
||||
(assert (#{:row :column} type))
|
||||
|
||||
(ptk/reify ::remove-layout-column
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
undo-id (js/Symbol)]
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/of (dwu/start-undo-transaction undo-id)
|
||||
(dwc/update-shapes
|
||||
ids
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(update property d/remove-at-index index)
|
||||
(update-grid-cells objects))))
|
||||
(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-column
|
||||
[ids property index props]
|
||||
(defn change-layout-track
|
||||
[ids type index props]
|
||||
(assert (#{:row :column} type))
|
||||
(ptk/reify ::change-layout-column
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
undo-id (js/Symbol)]
|
||||
(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)
|
||||
(update-grid-cells objects))))
|
||||
(update-in [property index] merge props))))
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
(ptk/reify ::add-shape
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
(.log js/console (clj->js attrs))
|
||||
(let [page-id (:current-page-id state)
|
||||
objects (wsh/lookup-page-objects state page-id)
|
||||
selected (wsh/lookup-selected state)
|
||||
|
@ -95,6 +96,7 @@
|
|||
selected)
|
||||
|
||||
index (:index (meta attrs))
|
||||
|
||||
changes (-> (pcb/empty-changes it page-id)
|
||||
(pcb/with-objects objects)
|
||||
(cond-> (some? index)
|
||||
|
@ -102,7 +104,10 @@
|
|||
(cond-> (nil? index)
|
||||
(pcb/add-object shape))
|
||||
(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)]
|
||||
|
||||
(rx/concat
|
||||
|
@ -133,7 +138,9 @@
|
|||
(pcb/with-objects objects)
|
||||
(cond-> (not (ctl/any-layout? objects frame-id))
|
||||
(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)
|
||||
(rx/of (dch/commit-changes changes))
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
[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.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
|
@ -474,7 +475,10 @@
|
|||
exclude-frames (if mod? exclude-frames exclude-frames-siblings)
|
||||
target-frame (ctst/top-nested-frame objects position exclude-frames)
|
||||
flex-layout? (ctl/flex-layout? objects target-frame)
|
||||
drop-index (when flex-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])))
|
||||
|
||||
(rx/take-until stopper))]
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.main.ui.workspace.sidebar.options
|
||||
(:require
|
||||
[app.main.ui.workspace.sidebar.options.shapes.grid-cell :as grid-cell]
|
||||
[app.common.data :as d]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.pages.helpers :as cph]
|
||||
|
@ -24,6 +23,7 @@
|
|||
[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.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.image :as image]
|
||||
[app.main.ui.workspace.sidebar.options.shapes.multiple :as multiple]
|
||||
|
@ -74,9 +74,7 @@
|
|||
shape-parent-frame (cph/get-frame objects (:frame-id first-selected-shape))
|
||||
|
||||
[grid-id {[row-selected col-selected] :selected}]
|
||||
(d/seek (fn [[grid-id {:keys [selected]}]]
|
||||
(some? selected))
|
||||
grid-edition)
|
||||
(d/seek (fn [[_ {:keys [selected]}]] (some? selected)) grid-edition)
|
||||
|
||||
grid-cell-selected? (and (some? grid-id) (some? row-selected) (some? col-selected))
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.main.data.workspace :as udw]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input]]
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
|
@ -34,8 +35,7 @@
|
|||
:layout-grid-dir ;; :row :column
|
||||
:layout-justify-items
|
||||
:layout-grid-columns
|
||||
:layout-grid-rows
|
||||
])
|
||||
:layout-grid-rows])
|
||||
|
||||
(defn get-layout-flex-icon
|
||||
[type val is-col?]
|
||||
|
@ -343,14 +343,24 @@
|
|||
:disabled (and (= :nowrap wrap-type) (not is-col?))}]]]])
|
||||
|
||||
(mf/defc grid-edit-mode
|
||||
[{:keys [active toggle-edit-mode] :as props}]
|
||||
[:*
|
||||
[:button.tooltip.tooltip-bottom-left
|
||||
{:class (dom/classnames :active (= active true))
|
||||
:alt "Grid edit mode"
|
||||
:on-click #(toggle-edit-mode)
|
||||
:style {:padding 0}}
|
||||
i/grid-layout-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}]
|
||||
|
@ -456,14 +466,15 @@
|
|||
(st/emit! (dwsl/remove-layout ids))
|
||||
(reset! open? false))
|
||||
|
||||
;; Uncomment when activating the grid options
|
||||
set-flex (fn []
|
||||
(st/emit! (dwsl/remove-layout ids))
|
||||
(on-add-layout :flex))
|
||||
_set-flex
|
||||
(fn []
|
||||
(st/emit! (dwsl/remove-layout ids))
|
||||
(on-add-layout :flex))
|
||||
|
||||
set-grid (fn []
|
||||
(st/emit! (dwsl/remove-layout ids))
|
||||
(on-add-layout :grid))
|
||||
_set-grid
|
||||
(fn []
|
||||
(st/emit! (dwsl/remove-layout ids))
|
||||
(on-add-layout :grid))
|
||||
|
||||
;; Flex-direction
|
||||
|
||||
|
@ -575,33 +586,25 @@
|
|||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [type value]
|
||||
(if (= type :row)
|
||||
(st/emit! (dwsl/add-layout-column ids :layout-grid-rows value))
|
||||
(st/emit! (dwsl/add-layout-column ids :layout-grid-columns value)))))
|
||||
(st/emit! (dwsl/add-layout-track ids type value))))
|
||||
|
||||
remove-element
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [type index]
|
||||
(if (= type :row)
|
||||
(st/emit! (dwsl/remove-layout-column ids :layout-grid-rows index))
|
||||
(st/emit! (dwsl/remove-layout-column ids :layout-grid-columns index)))))
|
||||
(st/emit! (dwsl/remove-layout-track ids type index))))
|
||||
|
||||
set-column-value
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [type index value]
|
||||
(if (= type :row)
|
||||
(st/emit! (dwsl/change-layout-column ids :layout-grid-rows index {:value value}))
|
||||
(st/emit! (dwsl/change-layout-column ids :layout-grid-columns index {:value value})))))
|
||||
(st/emit! (dwsl/change-layout-track ids type index {:value value}))))
|
||||
|
||||
set-column-type
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [type index col-type]
|
||||
(if (= type :row)
|
||||
(st/emit! (dwsl/change-layout-column ids :layout-grid-rows index {:type col-type}))
|
||||
(st/emit! (dwsl/change-layout-column ids :layout-grid-columns index {:type col-type})))))]
|
||||
(fn [type index track-type]
|
||||
(st/emit! (dwsl/change-layout-track ids type index {:type track-type}))))]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
|
@ -609,7 +612,7 @@
|
|||
[:span "Layout"]
|
||||
(if (and (not multiple) (:layout values))
|
||||
[:div.title-actions
|
||||
[:div.layout-btns
|
||||
#_[:div.layout-btns
|
||||
[:button {:on-click set-flex
|
||||
:class (dom/classnames
|
||||
:active (= :flex layout-type))} "Flex"]
|
||||
|
@ -622,8 +625,9 @@
|
|||
|
||||
(when (:layout values)
|
||||
(when (not= :multiple layout-type)
|
||||
(if (= :flex layout-type)
|
||||
;; FLEX
|
||||
(case layout-type
|
||||
:flex
|
||||
|
||||
[:div.element-set-content.layout-menu
|
||||
[:div.layout-row
|
||||
[:div.direction-wrap.row-title "Direction"]
|
||||
|
@ -673,7 +677,8 @@
|
|||
:on-change-style change-padding-type
|
||||
:on-change on-padding-change}]]
|
||||
|
||||
;; GRID
|
||||
:grid
|
||||
|
||||
[:div.element-set-content.layout-menu
|
||||
[:div.layout-row
|
||||
[:div.direction-wrap.row-title "Direction"]
|
||||
|
@ -687,10 +692,9 @@
|
|||
:set-direction #(set-direction dir :grid)
|
||||
:icon? false}])]]
|
||||
|
||||
[:div.edit-mode
|
||||
[:& grid-edit-mode
|
||||
{:active false
|
||||
:toggle-edit-mode ()}]]]]
|
||||
(when (= 1 (count ids))
|
||||
[:div.edit-mode
|
||||
[:& grid-edit-mode {:id (first ids)}]])]]
|
||||
|
||||
[:div.layout-row
|
||||
[:div.align-items-grid.row-title "Align"]
|
||||
|
@ -739,4 +743,8 @@
|
|||
|
||||
[:& padding-section {:values values
|
||||
:on-change-style change-padding-type
|
||||
:on-change on-padding-change}]])))]))
|
||||
:on-change on-padding-change}]]
|
||||
|
||||
|
||||
;; Default if not grid or flex
|
||||
nil)))]))
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [shape row column] :as props}]
|
||||
[{:keys [_shape row column] :as props}]
|
||||
|
||||
(let [position-mode (mf/use-state :auto) ;; TODO this should come from shape
|
||||
|
||||
|
@ -57,8 +57,9 @@
|
|||
row-end (inc row)
|
||||
|
||||
on-change
|
||||
(fn [side orientation value]
|
||||
(if (= orientation :column)
|
||||
(fn [_side _orientation _value]
|
||||
;; TODO
|
||||
#_(if (= orientation :column)
|
||||
(case side
|
||||
:all ((reset! column-start value)
|
||||
(reset! column-end value))
|
||||
|
@ -74,7 +75,7 @@
|
|||
|
||||
on-area-name-change (fn [value]
|
||||
(reset! area-name value))
|
||||
on-key-press (fn [event])]
|
||||
on-key-press (fn [_event])]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
(ns app.main.ui.workspace.viewport
|
||||
(:require
|
||||
[app.main.ui.workspace.viewport.grid-layout-editor :as grid-layout]
|
||||
[app.common.colors :as clr]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
|
@ -30,6 +29,7 @@
|
|||
[app.main.ui.workspace.viewport.drawarea :as drawarea]
|
||||
[app.main.ui.workspace.viewport.frame-grid :as frame-grid]
|
||||
[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.hooks :as hooks]
|
||||
[app.main.ui.workspace.viewport.interactions :as interactions]
|
||||
|
@ -158,6 +158,7 @@
|
|||
(and (some? drawing-obj) (= :path (:type drawing-obj))))
|
||||
node-editing? (and edition (not= :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?)
|
||||
mode-inspect? (= options-mode :inspect)
|
||||
|
@ -168,7 +169,7 @@
|
|||
on-drag-enter (actions/on-drag-enter)
|
||||
on-drag-over (actions/on-drag-over)
|
||||
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?)
|
||||
on-mouse-up (actions/on-mouse-up disable-paste)
|
||||
on-pointer-down (actions/on-pointer-down)
|
||||
|
@ -199,6 +200,7 @@
|
|||
show-pixel-grid? (and (contains? layout :show-pixel-grid)
|
||||
(>= zoom 8))
|
||||
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-prototypes? (= options-mode :prototype)
|
||||
show-selection-handlers? (and (seq selected) (not show-text-editor?))
|
||||
|
@ -540,10 +542,9 @@
|
|||
{:id (first selected)
|
||||
:zoom zoom}])
|
||||
|
||||
(when-let [selected (first selected-shapes)]
|
||||
(when (ctl/grid-layout? selected)
|
||||
[:& grid-layout/editor
|
||||
{:zoom zoom
|
||||
:objects base-objects
|
||||
:shape selected}]))
|
||||
(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
|
||||
[{: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/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?)
|
||||
(fn [bevent]
|
||||
(when (or (dom/class? (dom/get-target bevent) "viewport-controls")
|
||||
|
@ -70,7 +70,7 @@
|
|||
(do
|
||||
(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))
|
||||
|
||||
(when (and (not text-editing?)
|
||||
|
|
|
@ -225,7 +225,7 @@
|
|||
height (gpo/height-points parent-bounds)
|
||||
origin (gpo/origin parent-bounds)
|
||||
|
||||
{:keys [row-tracks column-tracks shape-cells]}
|
||||
{:keys [row-tracks column-tracks]}
|
||||
(gsg/calc-layout-data parent children parent-bounds)]
|
||||
|
||||
[:*
|
||||
|
@ -236,7 +236,8 @@
|
|||
:y1 (:y start-p)
|
||||
:x2 (:x end-p)
|
||||
:y2 (:y end-p)
|
||||
:style {:stroke "red"}}]))
|
||||
:style {:stroke "red"
|
||||
:stroke-width (/ 1 zoom)}}]))
|
||||
|
||||
(for [column-data column-tracks]
|
||||
(let [start-p (gpt/add origin (hv (:distance column-data)))
|
||||
|
@ -245,4 +246,5 @@
|
|||
:y1 (:y start-p)
|
||||
:x2 (:x end-p)
|
||||
:y2 (:y end-p)
|
||||
:style {:stroke "red"}}]))]))))
|
||||
:style {:stroke "red"
|
||||
:stroke-width (/ 1 zoom)}}]))]))))
|
||||
|
|
|
@ -10,15 +10,12 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes.grid-layout :as gsg]
|
||||
[app.common.geom.shapes.grid-layout.layout-data :refer [set-sample-data] ]
|
||||
[app.common.geom.shapes.points :as gpo]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[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.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
@ -211,7 +208,7 @@
|
|||
(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)
|
||||
_delta (-> (gpt/to-vec start pos)
|
||||
(get (if (= type :column) :x :y)))]
|
||||
|
||||
;; TODO Implement resize
|
||||
|
@ -268,7 +265,7 @@
|
|||
height (gpo/height-points bounds)
|
||||
origin (gpo/origin bounds)
|
||||
|
||||
{:keys [row-tracks column-tracks shape-cells] :as layout-data}
|
||||
{:keys [row-tracks column-tracks] :as layout-data}
|
||||
(gsg/calc-layout-data shape children bounds)]
|
||||
|
||||
(mf/use-effect
|
||||
|
@ -289,16 +286,15 @@
|
|||
:type :row}])
|
||||
|
||||
(for [[_ {:keys [column row]}] (:layout-grid-cells shape)]
|
||||
(let []
|
||||
[:& 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])
|
||||
}]))
|
||||
[:& 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))))
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.shape-tree :as ctt]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace :as dw]
|
||||
|
@ -55,8 +56,11 @@
|
|||
drawing (mf/deref refs/workspace-drawing)
|
||||
drawing-obj (:object drawing)
|
||||
shape (or drawing-obj (-> selected first))]
|
||||
(when (or (and (= (count selected) 1) (= (:id shape) edition) (not= :text (:type shape)))
|
||||
(and (some? drawing-obj) (= :path (:type drawing-obj))
|
||||
(when (or (and (= (count selected) 1)
|
||||
(= (:id shape) edition)
|
||||
(cph/path-shape? shape))
|
||||
(and (some? drawing-obj)
|
||||
(cph/path-shape? drawing-obj)
|
||||
(not= :curve (:tool drawing))))
|
||||
[:div.viewport-actions
|
||||
[:& path-actions {:shape shape}]])))
|
||||
|
|
Loading…
Add table
Reference in a new issue