mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 00:01:51 -05:00
🎉 Add basic left-right layout
This commit is contained in:
parent
3c3664535e
commit
aeb8fa1896
7 changed files with 145 additions and 41 deletions
|
@ -14,6 +14,7 @@
|
|||
[app.common.geom.shapes.constraints :as gct]
|
||||
[app.common.geom.shapes.corners :as gsc]
|
||||
[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.rect :as gpr]
|
||||
[app.common.geom.shapes.transforms :as gtr]
|
||||
|
@ -174,6 +175,10 @@
|
|||
;; Constratins
|
||||
(dm/export gct/calc-child-modifiers)
|
||||
|
||||
;; Layout
|
||||
(dm/export gcl/calc-layout-data)
|
||||
(dm/export gcl/calc-layout-modifiers)
|
||||
|
||||
;; PATHS
|
||||
(dm/export gsp/content->selrect)
|
||||
(dm/export gsp/transform-content)
|
||||
|
|
41
common/src/app/common/geom/shapes/layout.cljc
Normal file
41
common/src/app/common/geom/shapes/layout.cljc
Normal 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 )]))
|
|
@ -491,6 +491,7 @@
|
|||
|
||||
([center modifiers]
|
||||
(let [displacement (:displacement modifiers)
|
||||
displacement-after (:displacement-after modifiers)
|
||||
resize-v1 (:resize-vector modifiers)
|
||||
resize-v2 (:resize-vector-2 modifiers)
|
||||
origin-1 (:resize-origin modifiers (gpt/point))
|
||||
|
@ -512,6 +513,9 @@
|
|||
rt-modif (:rotation modifiers)]
|
||||
|
||||
(cond-> (gmt/matrix)
|
||||
(some? displacement-after)
|
||||
(gmt/multiply displacement-after)
|
||||
|
||||
(some? resize-1)
|
||||
(-> (gmt/translate origin-1)
|
||||
(cond-> (some? resize-transform)
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
[app.main.data.workspace.path.shapes-to-path :as dwps]
|
||||
[app.main.data.workspace.persistence :as dwp]
|
||||
[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.state-helpers :as wsh]
|
||||
[app.main.data.workspace.thumbnails :as dwth]
|
||||
|
@ -799,7 +800,8 @@
|
|||
ids)]
|
||||
|
||||
(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
|
||||
[parent-id to-index]
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
(:require
|
||||
[app.common.data :as d]
|
||||
[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]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
|
@ -35,8 +37,17 @@
|
|||
|
||||
(defn update-layout-positions
|
||||
[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
|
||||
[ids]
|
||||
(ptk/reify ::create-layout
|
||||
|
|
|
@ -113,7 +113,7 @@
|
|||
(declare set-objects-modifiers)
|
||||
(declare get-ignore-tree)
|
||||
|
||||
(defn- set-modifiers
|
||||
(defn set-modifiers
|
||||
([ids]
|
||||
(set-modifiers ids nil false))
|
||||
|
||||
|
@ -150,21 +150,19 @@
|
|||
|
||||
([angle shapes center]
|
||||
(ptk/reify ::set-rotation-modifiers
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
shapes (->> shapes
|
||||
(remove #(get % :blocked false))
|
||||
(mapcat #(cph/get-children objects (:id %)))
|
||||
(concat shapes)
|
||||
(filter #((cpc/editable-attrs (:type %)) :rotation)))
|
||||
|
||||
update-shape
|
||||
(fn [modifiers shape]
|
||||
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
|
||||
(assoc-in modifiers [(:id shape) :modifiers] rotate-modifiers)))]
|
||||
|
||||
(update state :workspace-modifiers #(reduce update-shape % shapes)))))))
|
||||
shapes
|
||||
(->> shapes
|
||||
(remove #(get % :blocked false))
|
||||
(mapcat #(cph/get-children objects (:id %)))
|
||||
(concat shapes)
|
||||
(filter #((cpc/editable-attrs (:type %)) :rotation)))]
|
||||
(->> (rx/from shapes)
|
||||
(rx/map (fn [shape]
|
||||
(let [rotate-modifiers (gsh/rotation-modifiers shape center angle)]
|
||||
(set-modifiers [(:id shape)] rotate-modifiers))))))))))
|
||||
|
||||
(defn- update-grow-type
|
||||
[shape old-shape]
|
||||
|
@ -180,18 +178,20 @@
|
|||
change-to-fixed?
|
||||
(assoc :grow-type :fixed))))
|
||||
|
||||
(defn- apply-modifiers
|
||||
([ids]
|
||||
(apply-modifiers ids nil))
|
||||
(defn apply-modifiers
|
||||
([]
|
||||
(apply-modifiers nil))
|
||||
|
||||
([ids {:keys [undo-transation?] :or {undo-transation? true}}]
|
||||
(us/verify (s/coll-of uuid?) ids)
|
||||
([{:keys [undo-transation?] :or {undo-transation? true}}]
|
||||
(ptk/reify ::apply-modifiers
|
||||
ptk/WatchEvent
|
||||
(watch [_ 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)
|
||||
|
||||
ids (keys object-modifiers)
|
||||
ids-with-children (into (vec ids) (mapcat #(cph/get-children-ids objects %)) ids)
|
||||
|
||||
shapes (map (d/getf objects) ids)
|
||||
ignore-tree (->> (map #(get-ignore-tree object-modifiers objects %) shapes)
|
||||
(reduce merge {}))]
|
||||
|
@ -202,7 +202,7 @@
|
|||
(rx/empty))
|
||||
(rx/of (dwg/move-frame-guides ids-with-children)
|
||||
(dch/update-shapes
|
||||
ids-with-children
|
||||
ids
|
||||
(fn [shape]
|
||||
(let [modif (get object-modifiers (:id shape))
|
||||
text-shape? (cph/text-shape? shape)]
|
||||
|
@ -374,6 +374,26 @@
|
|||
(let [children (map (d/getf objects) (:shapes shape))
|
||||
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
|
||||
(fn [snap-pixel? modif-tree child]
|
||||
(let [child-modifiers (gsh/calc-child-modifiers shape child modifiers ignore-constraints transformed-rect)
|
||||
|
@ -387,12 +407,35 @@
|
|||
(assoc-in [(:id shape) :modifiers] modifiers))
|
||||
|
||||
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))]
|
||||
(set-modifiers-rec modif-tree shape modifiers))))
|
||||
modif-tree
|
||||
(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
|
||||
"Retrieves a map with the flag `ignore-geometry?` given a tree of modifiers"
|
||||
|
@ -534,7 +577,7 @@
|
|||
(rx/map #(conj current %)))))
|
||||
(rx/mapcat (partial resize shape initial-position layout))
|
||||
(rx/take-until stoper))
|
||||
(rx/of (apply-modifiers ids)
|
||||
(rx/of (apply-modifiers)
|
||||
(finish-transform))))))))
|
||||
|
||||
(defn update-dimensions
|
||||
|
@ -562,7 +605,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (apply-modifiers ids)))))
|
||||
(rx/of (apply-modifiers)))))
|
||||
|
||||
(defn change-orientation
|
||||
"Change orientation of shapes, from the sidebar options form.
|
||||
|
@ -588,7 +631,7 @@
|
|||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (apply-modifiers ids)))))
|
||||
(rx/of (apply-modifiers)))))
|
||||
|
||||
;; -- Rotate --------------------------------------------------------
|
||||
|
||||
|
@ -631,7 +674,7 @@
|
|||
(let [delta-angle (calculate-angle pos mod? shift?)]
|
||||
(set-rotation-modifiers delta-angle shapes group-center))))
|
||||
(rx/take-until stoper))
|
||||
(rx/of (apply-modifiers (map :id shapes))
|
||||
(rx/of (apply-modifiers)
|
||||
(finish-transform)))))))
|
||||
|
||||
(defn increase-rotation
|
||||
|
@ -648,7 +691,7 @@
|
|||
(set-rotation-modifiers delta [shape])))]
|
||||
(rx/concat
|
||||
(rx/from (->> ids (map #(get objects %)) (map rotate-shape)))
|
||||
(rx/of (apply-modifiers ids)))))))
|
||||
(rx/of (apply-modifiers)))))))
|
||||
|
||||
|
||||
;; -- Move ----------------------------------------------------------
|
||||
|
@ -772,7 +815,7 @@
|
|||
|
||||
(rx/of (dwu/start-undo-transaction)
|
||||
(calculate-frame-for-move ids)
|
||||
(apply-modifiers ids {:undo-transation? false})
|
||||
(apply-modifiers {:undo-transation? false})
|
||||
(finish-transform)
|
||||
(dwu/commit-undo-transaction)))))))))
|
||||
|
||||
|
@ -820,7 +863,7 @@
|
|||
(rx/take-until stopper))
|
||||
(rx/of (move-selected direction shift?)))
|
||||
|
||||
(rx/of (apply-modifiers selected)
|
||||
(rx/of (apply-modifiers)
|
||||
(finish-transform))))
|
||||
(rx/empty))))))
|
||||
|
||||
|
@ -850,7 +893,7 @@
|
|||
displ (gmt/translate-matrix delta)]
|
||||
|
||||
(rx/of (set-modifiers [id] {:displacement displ} false true)
|
||||
(apply-modifiers [id]))))))
|
||||
(apply-modifiers))))))
|
||||
|
||||
(defn check-frame-move?
|
||||
[target-frame-id objects position shape]
|
||||
|
@ -911,7 +954,7 @@
|
|||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point (- (:width selrect)) 0))}
|
||||
true)
|
||||
(apply-modifiers selected))))))
|
||||
(apply-modifiers))))))
|
||||
|
||||
(defn flip-vertical-selected []
|
||||
(ptk/reify ::flip-vertical-selected
|
||||
|
@ -928,4 +971,4 @@
|
|||
:resize-origin origin
|
||||
:displacement (gmt/translate-matrix (gpt/point 0 (- (:height selrect))))}
|
||||
true)
|
||||
(apply-modifiers selected))))))
|
||||
(apply-modifiers))))))
|
||||
|
|
|
@ -200,7 +200,7 @@
|
|||
|
||||
(mf/defc layout-container-menu
|
||||
{::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)
|
||||
gap-selected? (mf/use-state false)
|
||||
toggle-open (fn [] (swap! open? not))
|
||||
|
@ -226,8 +226,6 @@
|
|||
(fn [type]
|
||||
(st/emit! (dwsl/update-layout ids {:layout-padding-type type})))
|
||||
|
||||
select-all #(dom/select-target %)
|
||||
|
||||
select-all-gap
|
||||
(fn [event]
|
||||
(reset! gap-selected? true)
|
||||
|
|
Loading…
Add table
Reference in a new issue