0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-14 16:51:18 -05:00

🎉 Add basic left-right layout

This commit is contained in:
alonso.torres 2022-06-29 12:35:49 +02:00 committed by Andrey Antukh
parent 3c3664535e
commit aeb8fa1896
7 changed files with 145 additions and 41 deletions

View file

@ -14,6 +14,7 @@
[app.common.geom.shapes.constraints :as gct] [app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.corners :as gsc] [app.common.geom.shapes.corners :as gsc]
[app.common.geom.shapes.intersect :as gin] [app.common.geom.shapes.intersect :as gin]
[app.common.geom.shapes.layout :as gcl]
[app.common.geom.shapes.path :as gsp] [app.common.geom.shapes.path :as gsp]
[app.common.geom.shapes.rect :as gpr] [app.common.geom.shapes.rect :as gpr]
[app.common.geom.shapes.transforms :as gtr] [app.common.geom.shapes.transforms :as gtr]
@ -174,6 +175,10 @@
;; Constratins ;; Constratins
(dm/export gct/calc-child-modifiers) (dm/export gct/calc-child-modifiers)
;; Layout
(dm/export gcl/calc-layout-data)
(dm/export gcl/calc-layout-modifiers)
;; PATHS ;; PATHS
(dm/export gsp/content->selrect) (dm/export gsp/content->selrect)
(dm/export gsp/transform-content) (dm/export gsp/transform-content)

View file

@ -0,0 +1,41 @@
;; 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) UXBOX Labs SL
(ns app.common.geom.shapes.layout
(:require
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.rect :as gre]
[app.common.geom.shapes.transforms :as gtr]))
(defn calc-layout-data
"Digest the layout data to pass it to the constrains"
[_parent children transformed-rect]
(let [[children-width children-height]
(->> children (reduce (fn [[acc-width acc-height] shape]
[(+ acc-width (-> shape :points gre/points->rect :width))
(+ acc-height (-> shape :points gre/points->rect :height))]) [0 0]))]
{:start-x (:x transformed-rect)
:start-y (:y transformed-rect)
:children-width children-width
:children-height children-height})
)
(defn calc-layout-modifiers
[_parent child current-modifier _modifiers _transformed-rect {:keys [start-x start-y] :as layout-data}]
(let [current-modifier (dissoc current-modifier :displacement-after)
child' (-> child (assoc :modifiers current-modifier) gtr/transform-shape)
bounds' (-> child' :points gre/points->selrect)
corner-p (gpt/point start-x start-y)
displacement (gmt/translate-matrix (gpt/subtract corner-p (gpt/point bounds')))
modifiers (-> current-modifier
(assoc :displacement-after displacement))
next-x (+ start-x (:width bounds'))]
[modifiers (assoc layout-data :start-x next-x )]))

View file

@ -491,6 +491,7 @@
([center modifiers] ([center modifiers]
(let [displacement (:displacement modifiers) (let [displacement (:displacement modifiers)
displacement-after (:displacement-after modifiers)
resize-v1 (:resize-vector modifiers) resize-v1 (:resize-vector modifiers)
resize-v2 (:resize-vector-2 modifiers) resize-v2 (:resize-vector-2 modifiers)
origin-1 (:resize-origin modifiers (gpt/point)) origin-1 (:resize-origin modifiers (gpt/point))
@ -512,6 +513,9 @@
rt-modif (:rotation modifiers)] rt-modif (:rotation modifiers)]
(cond-> (gmt/matrix) (cond-> (gmt/matrix)
(some? displacement-after)
(gmt/multiply displacement-after)
(some? resize-1) (some? resize-1)
(-> (gmt/translate origin-1) (-> (gmt/translate origin-1)
(cond-> (some? resize-transform) (cond-> (some? resize-transform)

View file

@ -45,6 +45,7 @@
[app.main.data.workspace.path.shapes-to-path :as dwps] [app.main.data.workspace.path.shapes-to-path :as dwps]
[app.main.data.workspace.persistence :as dwp] [app.main.data.workspace.persistence :as dwp]
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.data.workspace.shapes :as dwsh] [app.main.data.workspace.shapes :as dwsh]
[app.main.data.workspace.state-helpers :as wsh] [app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.thumbnails :as dwth] [app.main.data.workspace.thumbnails :as dwth]
@ -799,7 +800,8 @@
ids)] ids)]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwco/expand-collapse parent-id)))))) (dwco/expand-collapse parent-id)
(dwsl/update-layout-positions [parent-id]))))))
(defn relocate-selected-shapes (defn relocate-selected-shapes
[parent-id to-index] [parent-id to-index]

View file

@ -8,6 +8,8 @@
(:require (:require
[app.common.data :as d] [app.common.data :as d]
[app.main.data.workspace.changes :as dwc] [app.main.data.workspace.changes :as dwc]
[app.main.data.workspace.state-helpers :as wsh]
[app.main.data.workspace.transforms :as dwt]
[beicon.core :as rx] [beicon.core :as rx]
[potok.core :as ptk])) [potok.core :as ptk]))
@ -35,8 +37,17 @@
(defn update-layout-positions (defn update-layout-positions
[ids] [ids]
(ptk/reify ::update-layout-positions)) (ptk/reify ::update-layout-positions
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
ids (->> ids (filter #(get-in objects [% :layout])))]
(if (d/not-empty? ids)
(rx/of (dwt/set-modifiers ids)
(dwt/apply-modifiers))
(rx/empty))))))
;; TODO: Remove constraints from children
(defn create-layout (defn create-layout
[ids] [ids]
(ptk/reify ::create-layout (ptk/reify ::create-layout

View file

@ -113,7 +113,7 @@
(declare set-objects-modifiers) (declare set-objects-modifiers)
(declare get-ignore-tree) (declare get-ignore-tree)
(defn- set-modifiers (defn set-modifiers
([ids] ([ids]
(set-modifiers ids nil false)) (set-modifiers ids nil false))
@ -150,21 +150,19 @@
([angle shapes center] ([angle shapes center]
(ptk/reify ::set-rotation-modifiers (ptk/reify ::set-rotation-modifiers
ptk/UpdateEvent ptk/WatchEvent
(update [_ state] (watch [_ state _]
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
shapes (->> shapes shapes
(remove #(get % :blocked false)) (->> shapes
(mapcat #(cph/get-children objects (:id %))) (remove #(get % :blocked false))
(concat shapes) (mapcat #(cph/get-children objects (:id %)))
(filter #((cpc/editable-attrs (:type %)) :rotation))) (concat shapes)
(filter #((cpc/editable-attrs (:type %)) :rotation)))]
update-shape (->> (rx/from shapes)
(fn [modifiers shape] (rx/map (fn [shape]
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)] (let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
(assoc-in modifiers [(:id shape) :modifiers] rotate-modifiers)))] (set-modifiers [(:id shape)] rotate-modifiers))))))))))
(update state :workspace-modifiers #(reduce update-shape % shapes)))))))
(defn- update-grow-type (defn- update-grow-type
[shape old-shape] [shape old-shape]
@ -180,18 +178,20 @@
change-to-fixed? change-to-fixed?
(assoc :grow-type :fixed)))) (assoc :grow-type :fixed))))
(defn- apply-modifiers (defn apply-modifiers
([ids] ([]
(apply-modifiers ids nil)) (apply-modifiers nil))
([ids {:keys [undo-transation?] :or {undo-transation? true}}] ([{:keys [undo-transation?] :or {undo-transation? true}}]
(us/verify (s/coll-of uuid?) ids)
(ptk/reify ::apply-modifiers (ptk/reify ::apply-modifiers
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids)
object-modifiers (get state :workspace-modifiers) object-modifiers (get state :workspace-modifiers)
ids (keys object-modifiers)
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids)
shapes (map (d/getf objects) ids) shapes (map (d/getf objects) ids)
ignore-tree (->> (map #(get-ignore-tree object-modifiers objects %) shapes) ignore-tree (->> (map #(get-ignore-tree object-modifiers objects %) shapes)
(reduce merge {}))] (reduce merge {}))]
@ -202,7 +202,7 @@
(rx/empty)) (rx/empty))
(rx/of (dwg/move-frame-guides ids-with-children) (rx/of (dwg/move-frame-guides ids-with-children)
(dch/update-shapes (dch/update-shapes
ids-with-children ids
(fn [shape] (fn [shape]
(let [modif (get object-modifiers (:id shape)) (let [modif (get object-modifiers (:id shape))
text-shape? (cph/text-shape? shape)] text-shape? (cph/text-shape? shape)]
@ -374,6 +374,26 @@
(let [children (map (d/getf objects) (:shapes shape)) (let [children (map (d/getf objects) (:shapes shape))
transformed-rect (gsh/transform-selrect (:selrect shape) modifiers) transformed-rect (gsh/transform-selrect (:selrect shape) modifiers)
set-layout-child
(fn [snap-pixel? {:keys [modif-tree] :as layout-data} child]
(let [current-modifier (get-in modif-tree [(:id child) :modifiers])
;; child (-> (merge child old-modif) gsh/transform-shape)
[child-modifiers next-layout-data] (gsh/calc-layout-modifiers shape child current-modifier modifiers transformed-rect layout-data)
child-modifiers (cond-> child-modifiers snap-pixel? (set-pixel-precision child))
;;child-modifiers (if (some? old-modif)
;; (d/deep-merge (:modifiers old-modif) child-modifiers)
;; child-modifiers)
modif-tree
(cond-> modif-tree
(not (gsh/empty-modifiers? child-modifiers))
(set-modifiers-rec child child-modifiers))]
(assoc next-layout-data :modif-tree modif-tree)))
set-child set-child
(fn [snap-pixel? modif-tree child] (fn [snap-pixel? modif-tree child]
(let [child-modifiers (gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect) (let [child-modifiers (gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)
@ -387,12 +407,35 @@
(assoc-in [(:id shape) :modifiers] modifiers)) (assoc-in [(:id shape) :modifiers] modifiers))
resize-modif? resize-modif?
(or (:resize-vector modifiers) (:resize-vector-2 modifiers))] (or (:resize-vector modifiers) (:resize-vector-2 modifiers))
(reduce (partial set-child (and snap-pixel? resize-modif?)) modif-tree children)))]
(let [modifiers (cond-> modifiers snap-pixel? (set-pixel-precision shape))] modif-tree
(set-modifiers-rec modif-tree shape modifiers)))) (reduce (partial set-child (and snap-pixel? resize-modif?)) modif-tree children)]
(cond
(:layout shape)
(let [result
(->> children
(reduce (partial set-layout-child (and snap-pixel? resize-modif?))
(merge {:modif-tree modif-tree}
(gsh/calc-layout-data shape children transformed-rect))))]
(:modif-tree result))
:else
modif-tree)))]
(let [modifiers (cond-> modifiers snap-pixel? (set-pixel-precision shape))
modif-tree (set-modifiers-rec modif-tree shape modifiers)
parent (get objects (:parent-id shape))
modif-tree
(cond-> modif-tree
(:layout parent)
(set-modifiers-rec parent nil))]
modif-tree)))
(defn- get-ignore-tree (defn- get-ignore-tree
"Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers" "Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers"
@ -534,7 +577,7 @@
(rx/map #(conj current %))))) (rx/map #(conj current %)))))
(rx/mapcat (partial resize shape initial-position layout)) (rx/mapcat (partial resize shape initial-position layout))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (apply-modifiers ids) (rx/of (apply-modifiers)
(finish-transform)))))))) (finish-transform))))))))
(defn update-dimensions (defn update-dimensions
@ -562,7 +605,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(rx/of (apply-modifiers ids))))) (rx/of (apply-modifiers)))))
(defn change-orientation (defn change-orientation
"Change orientation of shapes, from the sidebar options form. "Change orientation of shapes, from the sidebar options form.
@ -588,7 +631,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(rx/of (apply-modifiers ids))))) (rx/of (apply-modifiers)))))
;; -- Rotate -------------------------------------------------------- ;; -- Rotate --------------------------------------------------------
@ -631,7 +674,7 @@
(let [delta-angle (calculate-angle pos mod? shift?)] (let [delta-angle (calculate-angle pos mod? shift?)]
(set-rotation-modifiers delta-angle shapes group-center)))) (set-rotation-modifiers delta-angle shapes group-center))))
(rx/take-until stoper)) (rx/take-until stoper))
(rx/of (apply-modifiers (map :id shapes)) (rx/of (apply-modifiers)
(finish-transform))))))) (finish-transform)))))))
(defn increase-rotation (defn increase-rotation
@ -648,7 +691,7 @@
(set-rotation-modifiers delta [shape])))] (set-rotation-modifiers delta [shape])))]
(rx/concat (rx/concat
(rx/from (->> ids (map #(get objects %)) (map rotate-shape))) (rx/from (->> ids (map #(get objects %)) (map rotate-shape)))
(rx/of (apply-modifiers ids))))))) (rx/of (apply-modifiers)))))))
;; -- Move ---------------------------------------------------------- ;; -- Move ----------------------------------------------------------
@ -772,7 +815,7 @@
(rx/of (dwu/start-undo-transaction) (rx/of (dwu/start-undo-transaction)
(calculate-frame-for-move ids) (calculate-frame-for-move ids)
(apply-modifiers ids {:undo-transation? false}) (apply-modifiers {:undo-transation? false})
(finish-transform) (finish-transform)
(dwu/commit-undo-transaction))))))))) (dwu/commit-undo-transaction)))))))))
@ -820,7 +863,7 @@
(rx/take-until stopper)) (rx/take-until stopper))
(rx/of (move-selected direction shift?))) (rx/of (move-selected direction shift?)))
(rx/of (apply-modifiers selected) (rx/of (apply-modifiers)
(finish-transform)))) (finish-transform))))
(rx/empty)))))) (rx/empty))))))
@ -850,7 +893,7 @@
displ (gmt/translate-matrix delta)] displ (gmt/translate-matrix delta)]
(rx/of (set-modifiers [id] {:displacement displ} false true) (rx/of (set-modifiers [id] {:displacement displ} false true)
(apply-modifiers [id])))))) (apply-modifiers))))))
(defn check-frame-move? (defn check-frame-move?
[target-frame-id objects position shape] [target-frame-id objects position shape]
@ -911,7 +954,7 @@
:resize-origin origin :resize-origin origin
:displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))} :displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))}
true) true)
(apply-modifiers selected)))))) (apply-modifiers))))))
(defn flip-vertical-selected [] (defn flip-vertical-selected []
(ptk/reify ::flip-vertical-selected (ptk/reify ::flip-vertical-selected
@ -928,4 +971,4 @@
:resize-origin origin :resize-origin origin
:displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))} :displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))}
true) true)
(apply-modifiers selected)))))) (apply-modifiers))))))

View file

@ -200,7 +200,7 @@
(mf/defc layout-container-menu (mf/defc layout-container-menu
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type"]))]} {::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values" "type"]))]}
[{:keys [ids type values] :as props}] [{:keys [ids _type values] :as props}]
(let [open? (mf/use-state false) (let [open? (mf/use-state false)
gap-selected? (mf/use-state false) gap-selected? (mf/use-state false)
toggle-open (fn [] (swap! open? not)) toggle-open (fn [] (swap! open? not))
@ -226,8 +226,6 @@
(fn [type] (fn [type]
(st/emit! (dwsl/update-layout ids {:layout-padding-type type}))) (st/emit! (dwsl/update-layout ids {:layout-padding-type type})))
select-all #(dom/select-target %)
select-all-gap select-all-gap
(fn [event] (fn [event]
(reset! gap-selected? true) (reset! gap-selected? true)