mirror of
https://github.com/penpot/penpot.git
synced 2025-06-25 17:26:59 +02:00
✨ More improvements to layout grid UI
This commit is contained in:
parent
b13db69cf9
commit
06ab577e41
8 changed files with 105 additions and 31 deletions
|
@ -424,7 +424,7 @@
|
||||||
|
|
||||||
to-reflow
|
to-reflow
|
||||||
(cond-> to-reflow
|
(cond-> to-reflow
|
||||||
(and (ctl/flex-layout-descent? objects parent-base)
|
(and (ctl/any-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
|
||||||
|
|
|
@ -45,8 +45,10 @@
|
||||||
(= type :group)))
|
(= type :group)))
|
||||||
|
|
||||||
(defn mask-shape?
|
(defn mask-shape?
|
||||||
[{:keys [type masked-group?]}]
|
([objects id]
|
||||||
(and (= type :group) masked-group?))
|
(mask-shape? (get objects id)))
|
||||||
|
([{:keys [type masked-group?]}]
|
||||||
|
(and (= type :group) masked-group?)))
|
||||||
|
|
||||||
(defn bool-shape?
|
(defn bool-shape?
|
||||||
[{:keys [type]}]
|
[{:keys [type]}]
|
||||||
|
|
|
@ -715,6 +715,11 @@
|
||||||
[{:keys [ids values] :as props}]
|
[{:keys [ids values] :as props}]
|
||||||
(let [;; Gap
|
(let [;; Gap
|
||||||
gap-selected? (mf/use-state :none)
|
gap-selected? (mf/use-state :none)
|
||||||
|
saved-grid-dir (:layout-grid-dir values)
|
||||||
|
|
||||||
|
set-direction
|
||||||
|
(fn [dir]
|
||||||
|
(st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))
|
||||||
|
|
||||||
set-gap
|
set-gap
|
||||||
(fn [gap-multiple? type val]
|
(fn [gap-multiple? type val]
|
||||||
|
@ -739,6 +744,28 @@
|
||||||
:else
|
:else
|
||||||
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))
|
(st/emit! (dwsl/update-layout ids {:layout-padding {prop val}}))))
|
||||||
|
|
||||||
|
;; 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
|
;;Grid columns
|
||||||
column-grid-values (:layout-grid-columns values)
|
column-grid-values (:layout-grid-columns values)
|
||||||
grid-columns-open? (mf/use-state false)
|
grid-columns-open? (mf/use-state false)
|
||||||
|
@ -746,7 +773,7 @@
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(swap! grid-columns-open? not)))
|
(swap! grid-columns-open? not)))
|
||||||
|
|
||||||
; Grid rows / columns
|
;; Grid rows / columns
|
||||||
rows-grid-values (:layout-grid-rows values)
|
rows-grid-values (:layout-grid-rows values)
|
||||||
grid-rows-open? (mf/use-state false)
|
grid-rows-open? (mf/use-state false)
|
||||||
toggle-rows-info
|
toggle-rows-info
|
||||||
|
@ -789,6 +816,42 @@
|
||||||
[:span "Grid Layout"]]
|
[:span "Grid Layout"]]
|
||||||
|
|
||||||
[:div.element-set-content.layout-menu
|
[: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)
|
||||||
|
: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
|
[:& grid-columns-row {:is-col? true
|
||||||
:expanded? @grid-columns-open?
|
:expanded? @grid-columns-open?
|
||||||
:toggle toggle-columns-info
|
:toggle toggle-columns-info
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
|
is-grid-parent-ref (mf/use-memo (mf/deps ids) #(refs/grid-layout-child? ids))
|
||||||
is-grid-parent? (mf/deref is-grid-parent-ref)
|
is-grid-parent? (mf/deref is-grid-parent-ref)
|
||||||
|
|
||||||
is-flex-layout-container? (ctl/flex-layout? shape)
|
is-layout-container? (ctl/any-layout? shape)
|
||||||
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
is-layout-child-absolute? (ctl/layout-absolute? shape)
|
||||||
|
|
||||||
ids (hooks/use-equal-memo ids)
|
ids (hooks/use-equal-memo ids)
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
{:shape (first parents)
|
{:shape (first parents)
|
||||||
:cell (ctl/get-cell-by-shape-id (first parents) (first ids))}])
|
:cell (ctl/get-cell-by-shape-id (first parents) (first ids))}])
|
||||||
|
|
||||||
(when (or is-layout-child? is-flex-layout-container?)
|
(when (or is-layout-child? is-layout-container?)
|
||||||
[:& layout-item-menu
|
[:& layout-item-menu
|
||||||
{:ids ids
|
{:ids ids
|
||||||
:type type
|
:type type
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
:is-flex-parent? is-flex-parent?
|
:is-flex-parent? is-flex-parent?
|
||||||
:is-grid-parent? is-grid-parent?
|
:is-grid-parent? is-grid-parent?
|
||||||
:is-layout-child? is-layout-child?
|
:is-layout-child? is-layout-child?
|
||||||
:is-layout-container? is-flex-layout-container?
|
:is-layout-container? is-layout-container?
|
||||||
:shape shape}])
|
:shape shape}])
|
||||||
|
|
||||||
[:& layer-menu {:ids ids
|
[:& layer-menu {:ids ids
|
||||||
|
|
|
@ -595,9 +595,8 @@
|
||||||
[:g.grid-layout-editor {:clipPath "url(#clip-handlers)"}
|
[:g.grid-layout-editor {:clipPath "url(#clip-handlers)"}
|
||||||
[:& grid-layout/editor
|
[:& grid-layout/editor
|
||||||
{:zoom zoom
|
{:zoom zoom
|
||||||
:objects objects-modified
|
:objects base-objects
|
||||||
|
:modifiers modifiers
|
||||||
:shape (or (get objects-modified edition)
|
:shape (or (get objects-modified edition)
|
||||||
(gsh/transform-shape
|
(get base-objects @hover-top-frame-id))
|
||||||
(get base-objects @hover-top-frame-id)
|
|
||||||
(dm/get-in modifiers [@hover-top-frame-id :modifiers])))
|
|
||||||
:view-only (not show-grid-editor?)}]])]]]))
|
:view-only (not show-grid-editor?)}]])]]]))
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.main.ui.workspace.viewport.actions
|
(ns app.main.ui.workspace.viewport.actions
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.math :as mth]
|
[app.common.math :as mth]
|
||||||
[app.common.pages.helpers :as cph]
|
[app.common.pages.helpers :as cph]
|
||||||
|
@ -202,7 +203,12 @@
|
||||||
|
|
||||||
{:keys [id type] :as shape} (or @hover (get objects (first @hover-ids)))
|
{:keys [id type] :as shape} (or @hover (get objects (first @hover-ids)))
|
||||||
|
|
||||||
editable? (contains? #{:text :rect :path :image :circle} type)]
|
editable? (contains? #{:text :rect :path :image :circle} type)
|
||||||
|
|
||||||
|
hover-shape (->> @hover-ids (filter (partial cph/is-child? objects id)) first)
|
||||||
|
selected-shape (get objects hover-shape)
|
||||||
|
|
||||||
|
grid-layout-id (->> @hover-ids reverse (d/seek (partial ctl/grid-layout? objects)))]
|
||||||
|
|
||||||
(st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?))
|
(st/emit! (ms/->MouseEvent :double-click ctrl? shift? alt? meta?))
|
||||||
|
|
||||||
|
@ -215,16 +221,12 @@
|
||||||
(st/emit! (dw/select-shape id)
|
(st/emit! (dw/select-shape id)
|
||||||
(dw/start-editing-selected))
|
(dw/start-editing-selected))
|
||||||
|
|
||||||
(ctl/grid-layout? objects @hover-top-frame-id)
|
(some? selected-shape)
|
||||||
(st/emit! (dw/start-edition-mode @hover-top-frame-id))
|
(do (reset! hover selected-shape)
|
||||||
|
(st/emit! (dw/select-shape (:id selected-shape))))
|
||||||
|
|
||||||
:else
|
(and (not selected-shape) (some? grid-layout-id))
|
||||||
(let [;; We only get inside childrens of the hovering shape
|
(st/emit! (dw/start-edition-mode grid-layout-id)))))))))))
|
||||||
hover-ids (->> @hover-ids (filter (partial cph/is-child? objects id)))
|
|
||||||
selected (get objects (first hover-ids))]
|
|
||||||
(when (some? selected)
|
|
||||||
(reset! hover selected)
|
|
||||||
(st/emit! (dw/select-shape (:id selected))))))))))))))
|
|
||||||
|
|
||||||
(defn on-context-menu
|
(defn on-context-menu
|
||||||
[hover hover-ids workspace-read-only?]
|
[hover hover-ids workspace-read-only?]
|
||||||
|
|
|
@ -299,9 +299,11 @@
|
||||||
|
|
||||||
handle-pointer-down
|
handle-pointer-down
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps (:id shape) (:id cell))
|
(mf/deps (:id shape) (:id cell) selected?)
|
||||||
(fn []
|
(fn []
|
||||||
(st/emit! (dwge/select-grid-cell (:id shape) (:id cell)))))]
|
(if selected?
|
||||||
|
(st/emit! (dwge/remove-selection (:id shape)))
|
||||||
|
(st/emit! (dwge/select-grid-cell (:id shape) (:id cell))))))]
|
||||||
|
|
||||||
[:g.cell-editor
|
[:g.cell-editor
|
||||||
[:rect
|
[:rect
|
||||||
|
@ -657,14 +659,17 @@
|
||||||
::mf/wrap-props false}
|
::mf/wrap-props false}
|
||||||
[props]
|
[props]
|
||||||
|
|
||||||
(let [shape (unchecked-get props "shape")
|
(let [base-shape (unchecked-get props "shape")
|
||||||
objects (unchecked-get props "objects")
|
objects (unchecked-get props "objects")
|
||||||
zoom (unchecked-get props "zoom")
|
modifiers (unchecked-get props "modifiers")
|
||||||
view-only (unchecked-get props "view-only")
|
zoom (unchecked-get props "zoom")
|
||||||
|
view-only (unchecked-get props "view-only")
|
||||||
|
|
||||||
;; We need to know the state unmodified so we can create the modifiers
|
shape (mf/use-memo
|
||||||
shape-ref (mf/use-memo (mf/deps (:id shape)) #(refs/object-by-id (:id shape)))
|
(mf/deps modifiers base-shape)
|
||||||
base-shape (mf/deref shape-ref)
|
#(gsh/transform-shape
|
||||||
|
base-shape
|
||||||
|
(dm/get-in modifiers [(:id base-shape) :modifiers])))
|
||||||
|
|
||||||
snap-pixel? (mf/deref refs/snap-pixel?)
|
snap-pixel? (mf/deref refs/snap-pixel?)
|
||||||
|
|
||||||
|
@ -680,6 +685,7 @@
|
||||||
|
|
||||||
children (->> (:shapes shape)
|
children (->> (:shapes shape)
|
||||||
(map (d/getf objects))
|
(map (d/getf objects))
|
||||||
|
(map #(gsh/transform-shape % (dm/get-in modifiers [(:id %) :modifiers])))
|
||||||
(remove :hidden)
|
(remove :hidden)
|
||||||
(map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %)))
|
(map #(vector (gpo/parent-coords-bounds (:points %) (:points shape)) %)))
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,9 @@
|
||||||
(remove #(dm/get-in objects [% :blocked]))
|
(remove #(dm/get-in objects [% :blocked]))
|
||||||
(ctt/sort-z-index objects ids {:bottom-frames? mod?}))
|
(ctt/sort-z-index objects ids {:bottom-frames? mod?}))
|
||||||
|
|
||||||
grouped? (fn [id] (contains? #{:group :bool} (get-in objects [id :type])))
|
grouped? (fn [id]
|
||||||
|
(and (cph/group-shape? objects id)
|
||||||
|
(not (cph/mask-shape? objects id))))
|
||||||
|
|
||||||
selected-with-parents
|
selected-with-parents
|
||||||
(into #{} (mapcat #(cph/get-parent-ids objects %)) selected)
|
(into #{} (mapcat #(cph/get-parent-ids objects %)) selected)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue