mirror of
https://github.com/penpot/penpot.git
synced 2026-03-06 02:01:09 +00:00
Merge pull request #3635 from penpot/alotor-grid-polishing
Grid polishing
This commit is contained in:
@@ -62,15 +62,17 @@
|
||||
|
||||
(defn child-min-width
|
||||
[child bounds]
|
||||
(if (ctl/fill-width? child)
|
||||
(ctl/child-min-width child)
|
||||
(gpo/width-points bounds)))
|
||||
(+ (if (ctl/fill-width? child)
|
||||
(ctl/child-min-width child)
|
||||
(gpo/width-points bounds))
|
||||
(ctl/child-width-margin child)))
|
||||
|
||||
(defn child-min-height
|
||||
[child bounds]
|
||||
(if (ctl/fill-height? child)
|
||||
(ctl/child-min-height child)
|
||||
(gpo/height-points bounds)))
|
||||
(+ (if (ctl/fill-height? child)
|
||||
(ctl/child-min-height child)
|
||||
(gpo/height-points bounds))
|
||||
(ctl/child-height-margin child)))
|
||||
|
||||
(defn calculate-initial-track-size
|
||||
[total-value {:keys [type value] :as track}]
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
[app.common.types.shape.layout :as ctl]))
|
||||
|
||||
(defn cell-bounds
|
||||
"Retrieves the points that define the bounds for given cell"
|
||||
[{:keys [origin row-tracks column-tracks layout-bounds column-gap row-gap] :as layout-data} {:keys [row column row-span column-span] :as cell}]
|
||||
|
||||
(let [hv #(gpo/start-hv layout-bounds %)
|
||||
@@ -55,11 +56,13 @@
|
||||
[_parent
|
||||
transform
|
||||
transform-inverse
|
||||
_child
|
||||
child
|
||||
child-origin child-width
|
||||
cell-bounds]
|
||||
|
||||
(let [target-width (max (gpo/width-points cell-bounds) 0.01)
|
||||
(let [target-width (max (- (gpo/width-points cell-bounds) (ctl/child-width-margin child)) 0.01)
|
||||
max-width (max (ctl/child-max-width child) 0.01)
|
||||
target-width (mth/clamp target-width (ctl/child-min-width child) max-width)
|
||||
fill-scale (/ target-width child-width)]
|
||||
{:width target-width
|
||||
:modifiers (ctm/resize-modifiers (gpt/point fill-scale 1) child-origin transform transform-inverse)}))
|
||||
@@ -68,10 +71,12 @@
|
||||
"Calculates the size and modifiers for the height of an auto-fill child"
|
||||
[_parent
|
||||
transform transform-inverse
|
||||
_child
|
||||
child
|
||||
child-origin child-height
|
||||
cell-bounds]
|
||||
(let [target-height (max (gpo/height-points cell-bounds) 0.01)
|
||||
(let [target-height (max (- (gpo/height-points cell-bounds) (ctl/child-height-margin child)) 0.01)
|
||||
max-height (max (ctl/child-max-height child) 0.01)
|
||||
target-height (mth/clamp target-height (ctl/child-min-height child) max-height)
|
||||
fill-scale (/ target-height child-height)]
|
||||
{:height target-height
|
||||
:modifiers (ctm/resize-modifiers (gpt/point 1 fill-scale) child-origin transform transform-inverse)}))
|
||||
@@ -106,7 +111,7 @@
|
||||
(cond-> fill-height (ctm/add-modifiers (:modifiers fill-height))))]))
|
||||
|
||||
(defn child-position-delta
|
||||
[parent child-bounds child-width child-height layout-data cell-data]
|
||||
[parent child child-bounds child-width child-height layout-data cell-data]
|
||||
(let [cell-bounds (cell-bounds layout-data cell-data)
|
||||
child-origin (gpo/origin child-bounds)
|
||||
|
||||
@@ -126,30 +131,35 @@
|
||||
hv (partial gpo/start-hv cell-bounds)
|
||||
vv (partial gpo/start-vv cell-bounds)
|
||||
|
||||
[top-m right-m bottom-m left-m] (ctl/child-margins child)
|
||||
|
||||
;; Adjust alignment/justify
|
||||
[from-h to-h]
|
||||
(case justify
|
||||
:end
|
||||
[(gpt/add origin-h (hv child-width))
|
||||
(nth cell-bounds 1)]
|
||||
(gpt/subtract (nth cell-bounds 1) (hv right-m))]
|
||||
|
||||
:center
|
||||
[(gpt/add origin-h (hv (/ child-width 2)))
|
||||
(gpo/project-point cell-bounds :h (gpo/center cell-bounds))]
|
||||
|
||||
[origin-h (first cell-bounds)])
|
||||
[origin-h
|
||||
(gpt/add (first cell-bounds) (hv left-m))])
|
||||
|
||||
[from-v to-v]
|
||||
(case align
|
||||
:end
|
||||
[(gpt/add origin-v (vv child-height))
|
||||
(nth cell-bounds 3)]
|
||||
(gpt/subtract (nth cell-bounds 3) (vv bottom-m))]
|
||||
|
||||
:center
|
||||
[(gpt/add origin-v (vv (/ child-height 2)))
|
||||
(gpo/project-point cell-bounds :v (gpo/center cell-bounds))]
|
||||
|
||||
[origin-v (first cell-bounds)])]
|
||||
[origin-v
|
||||
(gpt/add (first cell-bounds) (vv top-m))])]
|
||||
|
||||
(-> (gpt/point)
|
||||
(gpt/add (gpt/to-vec from-h to-h))
|
||||
(gpt/add (gpt/to-vec from-v to-v)))))
|
||||
@@ -160,7 +170,7 @@
|
||||
(let [[child-width child-height fill-modifiers]
|
||||
(fill-modifiers parent parent-bounds child child-bounds layout-data cell-data)
|
||||
|
||||
position-delta (child-position-delta parent child-bounds child-width child-height layout-data cell-data)]
|
||||
position-delta (child-position-delta parent child child-bounds child-width child-height layout-data cell-data)]
|
||||
|
||||
(cond-> (ctm/empty)
|
||||
(not (ctl/layout-absolute? child))
|
||||
|
||||
@@ -104,14 +104,15 @@
|
||||
(defn absolute-move
|
||||
"Move the shape to the exactly specified position."
|
||||
[shape pos]
|
||||
(let [x (dm/get-prop pos :x)
|
||||
y (dm/get-prop pos :y)
|
||||
sr (dm/get-prop shape :selrect)
|
||||
px (dm/get-prop sr :x)
|
||||
py (dm/get-prop sr :y)
|
||||
dx (- (d/check-num x) px)
|
||||
dy (- (d/check-num y) py)]
|
||||
(move shape (gpt/point dx dy))))
|
||||
(when shape
|
||||
(let [x (dm/get-prop pos :x)
|
||||
y (dm/get-prop pos :y)
|
||||
sr (dm/get-prop shape :selrect)
|
||||
px (dm/get-prop sr :x)
|
||||
py (dm/get-prop sr :y)
|
||||
dx (- (d/check-num x) px)
|
||||
dy (- (d/check-num y) py)]
|
||||
(move shape (gpt/point dx dy)))))
|
||||
|
||||
;; --- Transformation matrix operations
|
||||
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
[app.common.schema :as sm]
|
||||
[app.common.uuid :as uuid]))
|
||||
|
||||
;; FIXME: need proper schemas
|
||||
|
||||
;; :layout ;; :flex, :grid in the future
|
||||
;; :layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
|
||||
;; :layout-gap-type ;; :simple, :multiple
|
||||
@@ -695,6 +693,29 @@
|
||||
(update :layout-grid-cells update-cells)
|
||||
(assign-cells))))
|
||||
|
||||
(defn- reorder-grid-track
|
||||
[prop parent from-index to-index]
|
||||
(-> parent
|
||||
(update
|
||||
prop
|
||||
(fn [tracks]
|
||||
(let [tr (nth tracks from-index)]
|
||||
(mapv
|
||||
second
|
||||
(-> tracks
|
||||
(d/enumerate) ;; make unique so the insert-at-index won't remove the value
|
||||
(assoc from-index nil)
|
||||
(d/insert-at-index (inc to-index) [[nil tr]])
|
||||
(d/vec-without-nils))))))))
|
||||
|
||||
(defn reorder-grid-column
|
||||
[parent from-index to-index]
|
||||
(reorder-grid-track :layout-grid-columns parent from-index to-index))
|
||||
|
||||
(defn reorder-grid-row
|
||||
[parent from-index to-index]
|
||||
(reorder-grid-track :layout-grid-rows parent from-index to-index))
|
||||
|
||||
(defn get-cells
|
||||
([parent]
|
||||
(get-cells parent nil))
|
||||
@@ -827,7 +848,9 @@
|
||||
cells
|
||||
(let [next-free (first free-cells)
|
||||
current (first pending)
|
||||
cells (update-in cells [next-free :shapes] conj current)]
|
||||
cells (-> cells
|
||||
(update-in [next-free :shapes] conj current)
|
||||
(assoc-in [next-free :position] :auto))]
|
||||
(recur cells (rest free-cells) (rest pending)))))]
|
||||
|
||||
;; TODO: Remove after testing
|
||||
@@ -851,7 +874,7 @@
|
||||
|
||||
(let [cell-from (get cells idx)
|
||||
cell-to (get cells (inc idx))
|
||||
cell (assoc cell-to :shapes (:shapes cell-from))
|
||||
cell (assoc cell-to :shapes (:shapes cell-from) :position (:position cell-from))
|
||||
parent (assoc-in parent [:layout-grid-cells (:id cell)] cell)
|
||||
result-cells (assoc result-cells (inc idx) cell)]
|
||||
|
||||
@@ -863,7 +886,7 @@
|
||||
(recur parent result-cells (inc idx))))))]
|
||||
|
||||
[(assoc-in parent [:layout-grid-cells (get-in cells [index :id]) :shapes] [])
|
||||
(assoc-in result-cells [index :shapes] [])]))))
|
||||
(update result-cells index assoc :shapes [] :position :auto)]))))
|
||||
|
||||
|
||||
(defn in-cell?
|
||||
@@ -893,7 +916,7 @@
|
||||
[start-index start-cell] (seek-indexed-cell cells row column)]
|
||||
|
||||
(if (some? start-cell)
|
||||
(let [ ;; start-index => to-index is the range where the shapes inserted will be added
|
||||
(let [;; start-index => to-index is the range where the shapes inserted will be added
|
||||
to-index (min (+ start-index (count shape-ids)) (dec (count cells)))]
|
||||
|
||||
;; Move shift the `shapes` attribute between cells
|
||||
@@ -901,7 +924,8 @@
|
||||
(map vector shape-ids)
|
||||
(reduce (fn [[parent cells] [shape-id idx]]
|
||||
(let [[parent cells] (free-cell-push parent cells idx)]
|
||||
[(assoc-in parent [:layout-grid-cells (get-in cells [idx :id]) :shapes] [shape-id])
|
||||
[(update-in parent [:layout-grid-cells (get-in cells [idx :id])]
|
||||
assoc :position :manual :shapes [shape-id])
|
||||
cells]))
|
||||
[parent cells])
|
||||
(first)))
|
||||
@@ -1025,9 +1049,17 @@
|
||||
(defn swap-shapes
|
||||
[parent id-from id-to]
|
||||
|
||||
(-> parent
|
||||
(assoc-in [:layout-grid-cells id-from :shapes] (dm/get-in parent [:layout-grid-cells id-to :shapes]))
|
||||
(assoc-in [:layout-grid-cells id-to :shapes] (dm/get-in parent [:layout-grid-cells id-from :shapes]))))
|
||||
(let [cell-to (dm/get-in parent [:layout-grid-cells id-to])
|
||||
cell-from (dm/get-in parent [:layout-grid-cells id-from])]
|
||||
(-> parent
|
||||
(update-in [:layout-grid-cells id-from]
|
||||
assoc
|
||||
:shapes (:shapes cell-to)
|
||||
:podition (:position cell-to))
|
||||
(update-in [:layout-grid-cells id-to]
|
||||
assoc
|
||||
:shapes (:shapes cell-from)
|
||||
:position (:position cell-from)))))
|
||||
|
||||
(defn add-children-to-cell
|
||||
[frame children objects [row column :as cell]]
|
||||
@@ -1069,3 +1101,80 @@
|
||||
new-shapes (into new-shapes (:shapes parent))]
|
||||
|
||||
(assoc parent :shapes (into [] (reverse new-shapes)))))
|
||||
|
||||
(defn shapes-by-row
|
||||
[parent index]
|
||||
(->> (:layout-grid-cells parent)
|
||||
(filter (fn [[_ {:keys [row row-span]}]]
|
||||
(and (>= (inc index) row)
|
||||
(< (inc index) (+ row row-span)))))
|
||||
(map second)
|
||||
(mapcat :shapes)))
|
||||
|
||||
(defn shapes-by-column
|
||||
[parent index]
|
||||
(->> (:layout-grid-cells parent)
|
||||
(filter (fn [[_ {:keys [column column-span]}]]
|
||||
(and (>= (inc index) column)
|
||||
(< (inc index) (+ column column-span)))))
|
||||
(map second)
|
||||
(mapcat :shapes)))
|
||||
|
||||
(defn cells-coordinates
|
||||
"Given a group of cells returns the coordinates that define"
|
||||
[cells]
|
||||
(loop [cells (seq cells)
|
||||
result
|
||||
{:first-row ##Inf
|
||||
:first-column ##Inf
|
||||
:last-row ##-Inf
|
||||
:last-column ##-Inf
|
||||
:cell-coords #{}}]
|
||||
|
||||
(if (empty? cells)
|
||||
result
|
||||
(let [{:keys [first-row last-row first-column last-column cell-coords]} result
|
||||
current (first cells)
|
||||
|
||||
first-row
|
||||
(if (< (:row current) first-row)
|
||||
(:row current)
|
||||
first-row)
|
||||
|
||||
last-row
|
||||
(if (> (+ (:row current) (:row-span current) -1) last-row)
|
||||
(+ (:row current) (:row-span current) -1)
|
||||
last-row)
|
||||
|
||||
first-column
|
||||
(if (< (:column current) first-column)
|
||||
(:column current)
|
||||
first-column)
|
||||
|
||||
last-column
|
||||
(if (> (+ (:column current) (:column-span current) -1) last-column)
|
||||
(+ (:column current) (:column-span current) -1)
|
||||
last-column)
|
||||
|
||||
cell-coords
|
||||
(into cell-coords
|
||||
(for [r (range (:row current) (+ (:row current) (:row-span current)))
|
||||
c (range (:column current) (+ (:column current) (:column-span current)))]
|
||||
[r c]))]
|
||||
(recur (rest cells)
|
||||
(assoc result
|
||||
:first-row first-row
|
||||
:last-row last-row
|
||||
:first-column first-column
|
||||
:last-column last-column
|
||||
:cell-coords cell-coords))))))
|
||||
|
||||
(defn valid-area-cells?
|
||||
[cells]
|
||||
|
||||
(let [{:keys [first-row last-row first-column last-column cell-coords]} (cells-coordinates cells)]
|
||||
(every?
|
||||
#(contains? cell-coords %)
|
||||
(for [r (range first-row (inc last-row))
|
||||
c (range first-column (inc last-column))]
|
||||
[r c]))))
|
||||
|
||||
@@ -1855,13 +1855,13 @@
|
||||
}
|
||||
}
|
||||
.position-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 185px;
|
||||
height: 26px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid $color-gray-60;
|
||||
|
||||
.position-btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -1871,6 +1871,8 @@
|
||||
cursor: pointer;
|
||||
color: $color-gray-20;
|
||||
border-right: 1px solid $color-gray-60;
|
||||
flex: 1;
|
||||
|
||||
&:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
@@ -1878,6 +1880,23 @@
|
||||
&:hover {
|
||||
color: $color-primary;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
opacity: 0.5;
|
||||
&:hover {
|
||||
color: $color-gray-20;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.single-button {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
height: 1.5rem;
|
||||
|
||||
.btn-wrapper {
|
||||
width: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2262,6 +2281,13 @@
|
||||
grid-template-columns: 35px 1fr 1fr auto;
|
||||
background-color: $color-gray-60;
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
border: 1px solid transparent;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid $color-primary;
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&.hover {
|
||||
background-color: $color-primary;
|
||||
|
||||
svg {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
(> dy dx)
|
||||
(assoc :x (- (:x point) (* sx (- dy dx)))))))
|
||||
|
||||
(defn resize-shape [{:keys [x y width height] :as shape} initial point lock?]
|
||||
(defn resize-shape [{:keys [x y width height] :as shape} initial point lock? mod?]
|
||||
(if (and (some? x) (some? y) (some? width) (some? height))
|
||||
(let [draw-rect (grc/make-rect initial (cond-> point lock? (adjust-ratio initial)))
|
||||
shape-rect (grc/make-rect x y width height)
|
||||
@@ -56,13 +56,14 @@
|
||||
|
||||
(-> shape
|
||||
(assoc :click-draw? false)
|
||||
(vary-meta merge {:mod? mod?})
|
||||
(gsh/transform-shape (-> (ctm/empty)
|
||||
(ctm/resize scalev (gpt/point x y))
|
||||
(ctm/move movev)))))
|
||||
shape))
|
||||
|
||||
(defn update-drawing [state initial point lock?]
|
||||
(update-in state [:workspace-drawing :object] resize-shape initial point lock?))
|
||||
(defn update-drawing [state initial point lock? mod?]
|
||||
(update-in state [:workspace-drawing :object] resize-shape initial point lock? mod?))
|
||||
|
||||
(defn move-drawing
|
||||
[{:keys [x y]}]
|
||||
@@ -105,9 +106,7 @@
|
||||
(cond-> (some? drop-index)
|
||||
(with-meta {:index drop-index}))
|
||||
(cond-> (some? drop-cell)
|
||||
(with-meta {:cell drop-cell})))
|
||||
|
||||
]
|
||||
(with-meta {:cell drop-cell})))]
|
||||
|
||||
(rx/concat
|
||||
;; Add shape to drawing state
|
||||
@@ -120,14 +119,14 @@
|
||||
(->> ms/mouse-position
|
||||
(rx/filter #(> (gpt/distance % initial) (/ 2 zoom)))
|
||||
(rx/with-latest vector ms/mouse-position-shift)
|
||||
(rx/with-latest conj ms/mouse-position-mod)
|
||||
(rx/switch-map
|
||||
(fn [[point :as current]]
|
||||
(->> (snap/closest-snap-point page-id [shape] objects layout zoom focus point)
|
||||
(rx/map #(conj current %)))))
|
||||
(rx/map
|
||||
(fn [[_ shift? point]]
|
||||
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift?)))))
|
||||
|
||||
(fn [[_ shift? mod? point]]
|
||||
#(update-drawing % initial (cond-> point snap-pixel? (gpt/round-step snap-prec)) shift? mod?)))))
|
||||
(rx/take-until stoper))
|
||||
|
||||
(->> (rx/of (common/handle-finish-drawing))
|
||||
|
||||
@@ -25,19 +25,41 @@
|
||||
(disj hover-set cell-id))))))))
|
||||
|
||||
(defn select-grid-cell
|
||||
[grid-id cell-id]
|
||||
[grid-id cell-id add?]
|
||||
(ptk/reify ::select-grid-cell
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-grid-edition grid-id :selected] cell-id))))
|
||||
(if add?
|
||||
(update-in state [:workspace-grid-edition grid-id :selected] (fnil conj #{}) cell-id)
|
||||
(assoc-in state [:workspace-grid-edition grid-id :selected] #{cell-id})))))
|
||||
|
||||
(defn remove-selection
|
||||
[grid-id]
|
||||
[grid-id cell-id]
|
||||
(ptk/reify ::remove-selection
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update-in state [:workspace-grid-edition grid-id :selected] disj cell-id))))
|
||||
|
||||
(defn clear-selection
|
||||
[grid-id]
|
||||
(ptk/reify ::clear-selection
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update-in state [:workspace-grid-edition grid-id] dissoc :selected))))
|
||||
|
||||
(defn clean-selection
|
||||
[grid-id]
|
||||
(ptk/reify ::clean-selection
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
shape (get objects grid-id)]
|
||||
(update-in state [:workspace-grid-edition grid-id :selected]
|
||||
(fn [selected]
|
||||
(into #{}
|
||||
(filter #(contains? (:layout-grid-cells shape) %))
|
||||
selected)))))))
|
||||
|
||||
(defn stop-grid-layout-editing
|
||||
[grid-id]
|
||||
(ptk/reify ::stop-grid-layout-editing
|
||||
|
||||
@@ -490,11 +490,13 @@
|
||||
(let [page (wsh/lookup-page state)
|
||||
libraries (wsh/get-libraries state)
|
||||
|
||||
objects (:objects page)
|
||||
changes (-> (pcb/empty-changes it (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(pcb/with-objects objects))
|
||||
|
||||
[new-shape changes]
|
||||
(dwlh/generate-instantiate-component changes
|
||||
objects
|
||||
file-id
|
||||
component-id
|
||||
position
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.geom.point :as gpt]
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.common.geom.shapes.grid-layout :as gslg]
|
||||
[app.common.logging :as log]
|
||||
[app.common.pages.changes-builder :as pcb]
|
||||
[app.common.pages.helpers :as cph]
|
||||
@@ -21,6 +22,7 @@
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.shape-tree :as ctst]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.common.types.typography :as cty]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.state-helpers :as wsh]
|
||||
@@ -158,10 +160,10 @@
|
||||
|
||||
(defn generate-instantiate-component
|
||||
"Generate changes to create a new instance from a component."
|
||||
([changes file-id component-id position page libraries]
|
||||
(generate-instantiate-component changes file-id component-id position page libraries nil nil))
|
||||
([changes objects file-id component-id position page libraries]
|
||||
(generate-instantiate-component changes objects file-id component-id position page libraries nil nil))
|
||||
|
||||
([changes file-id component-id position page libraries old-id parent-id]
|
||||
([changes objects file-id component-id position page libraries old-id parent-id]
|
||||
(let [component (ctf/get-component libraries file-id component-id)
|
||||
library (get libraries file-id)
|
||||
|
||||
@@ -182,6 +184,19 @@
|
||||
changes (cond-> (pcb/add-object changes first-shape {:ignore-touched true})
|
||||
(some? old-id) (pcb/amend-last-change #(assoc % :old-id old-id)))
|
||||
|
||||
changes
|
||||
(if (ctl/grid-layout? objects (:parent-id first-shape))
|
||||
(let [[row column] (gslg/get-drop-cell (:parent-id first-shape) objects position)]
|
||||
(-> changes
|
||||
(pcb/update-shapes
|
||||
[(:parent-id first-shape)]
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(ctl/push-into-cell [(:id first-shape)] row column)
|
||||
(ctl/assign-cells))))
|
||||
(pcb/reorder-grid-children [(:parent-id first-shape)])))
|
||||
changes)
|
||||
|
||||
changes (reduce #(pcb/add-object %1 %2 {:ignore-touched true})
|
||||
changes
|
||||
(rest new-shapes))]
|
||||
|
||||
@@ -384,7 +384,7 @@
|
||||
(prepare-duplicate-guides shapes page ids-map delta)))))
|
||||
|
||||
(defn- prepare-duplicate-component-change
|
||||
[changes page component-root parent-id delta libraries library-data it]
|
||||
[changes objects page component-root parent-id delta libraries library-data it]
|
||||
(let [component-id (:component-id component-root)
|
||||
file-id (:component-file component-root)
|
||||
main-component (ctf/get-component libraries file-id component-id)
|
||||
@@ -393,6 +393,7 @@
|
||||
|
||||
instantiate-component
|
||||
#(dwlh/generate-instantiate-component changes
|
||||
objects
|
||||
file-id
|
||||
(:component-id component-root)
|
||||
pos
|
||||
@@ -421,7 +422,7 @@
|
||||
changes
|
||||
|
||||
(ctf/is-known-component? obj libraries)
|
||||
(prepare-duplicate-component-change changes page obj parent-id delta libraries library-data it)
|
||||
(prepare-duplicate-component-change changes objects page obj parent-id delta libraries library-data it)
|
||||
|
||||
:else
|
||||
(let [frame? (cph/frame-shape? obj)
|
||||
@@ -469,7 +470,10 @@
|
||||
|
||||
; We want the first added object to touch it's parent, but not subsequent children
|
||||
changes (-> (pcb/add-object changes new-obj {:ignore-touched (and duplicating-component? child?)})
|
||||
(pcb/amend-last-change #(assoc % :old-id (:id obj))))
|
||||
(pcb/amend-last-change #(assoc % :old-id (:id obj)))
|
||||
(cond-> (ctl/grid-layout? objects (:parent-id obj))
|
||||
(-> (pcb/update-shapes [(:parent-id obj)] ctl/assign-cells)
|
||||
(pcb/reorder-grid-children [(:parent-id obj)]))))
|
||||
|
||||
changes (cond-> changes
|
||||
(and is-component-root? is-component-main?)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.workspace.changes :as dwc]
|
||||
[app.main.data.workspace.colors :as cl]
|
||||
[app.main.data.workspace.grid-layout.editor :as dwge]
|
||||
[app.main.data.workspace.modifiers :as dwm]
|
||||
[app.main.data.workspace.selection :as dwse]
|
||||
[app.main.data.workspace.shapes :as dws]
|
||||
@@ -407,6 +408,48 @@
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn reorder-layout-track
|
||||
[ids type from-index to-index]
|
||||
(assert (#{:row :column} type))
|
||||
|
||||
(ptk/reify ::reorder-layout-track
|
||||
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/reorder-grid-row shape from-index to-index)
|
||||
:column (ctl/reorder-grid-column shape from-index to-index))))
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn hover-layout-track
|
||||
[ids type index hover?]
|
||||
(assert (#{:row :column} type))
|
||||
|
||||
(ptk/reify ::hover-layout-track
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [objects (wsh/lookup-page-objects state)
|
||||
shape (get objects (first ids))
|
||||
highlighted (when hover?
|
||||
(->> (if (= type :row)
|
||||
(ctl/shapes-by-row shape index)
|
||||
(ctl/shapes-by-column shape index))
|
||||
(set)))]
|
||||
(cond-> state
|
||||
hover?
|
||||
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil conj #{}) [type index])
|
||||
|
||||
(not hover?)
|
||||
(update-in [:workspace-grid-edition (first ids) :hover-track] (fnil disj #{}) [type index])
|
||||
|
||||
:always
|
||||
(assoc-in [:workspace-local :highlighted] highlighted))))))
|
||||
|
||||
(defn change-layout-track
|
||||
[ids type index props]
|
||||
(assert (#{:row :column} type))
|
||||
@@ -521,20 +564,73 @@
|
||||
(ptk/data-event :layout/update ids)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn update-grid-cell
|
||||
[layout-id cell-id props]
|
||||
(ptk/reify ::update-grid-cell
|
||||
(defn update-grid-cells
|
||||
[layout-id ids props]
|
||||
(ptk/reify ::update-grid-cells
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
||||
(dwc/update-shapes
|
||||
[layout-id]
|
||||
(fn [shape]
|
||||
(-> shape
|
||||
(d/update-in-when [:layout-grid-cells cell-id]
|
||||
#(d/without-nils (merge % props))))))
|
||||
(->> ids
|
||||
(reduce (fn [shape cell-id]
|
||||
(-> shape
|
||||
(d/update-in-when [:layout-grid-cells cell-id]
|
||||
#(d/without-nils (merge % props)))))
|
||||
shape))))
|
||||
(ptk/data-event :layout/update [layout-id])
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
(defn change-cells-mode
|
||||
[layout-id ids mode]
|
||||
|
||||
(ptk/reify ::change-cells-mode
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(rx/of
|
||||
(dwu/start-undo-transaction undo-id)
|
||||
|
||||
(dwc/update-shapes
|
||||
[layout-id]
|
||||
(fn [shape]
|
||||
(cond
|
||||
(= mode :area)
|
||||
;; Create area with the selected cells
|
||||
(let [{:keys [first-row first-column last-row last-column]}
|
||||
(ctl/cells-coordinates (->> ids (map #(get-in shape [:layout-grid-cells %]))))
|
||||
|
||||
target-cell
|
||||
(ctl/get-cell-by-position shape first-row first-column)
|
||||
|
||||
shape
|
||||
(-> shape
|
||||
(ctl/resize-cell-area
|
||||
(:row target-cell) (:column target-cell)
|
||||
first-row
|
||||
first-column
|
||||
(inc (- last-row first-row))
|
||||
(inc (- last-column first-column)))
|
||||
(ctl/assign-cells))]
|
||||
|
||||
(-> shape
|
||||
(d/update-in-when [:layout-grid-cells (:id target-cell)] assoc :position :area)))
|
||||
|
||||
(= mode :auto)
|
||||
;; change the manual cells and move to auto
|
||||
(->> ids
|
||||
(reduce
|
||||
(fn [shape cell-id]
|
||||
(cond-> shape
|
||||
(contains? #{:area :manual} (get-in shape [:layout-grid-cells cell-id :position]))
|
||||
(-> (d/update-in-when [:layout-grid-cells cell-id] assoc :shapes [] :position :auto)
|
||||
(ctl/assign-cells))))
|
||||
shape)))))
|
||||
(dwge/clean-selection layout-id)
|
||||
(ptk/data-event :layout/update [layout-id])
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
(defn prepare-add-shape
|
||||
[changes shape objects _selected]
|
||||
(let [index (:index (meta shape))
|
||||
;; FIXME: revisit
|
||||
id (:id shape)
|
||||
|
||||
[row column :as cell] (:cell (meta shape))
|
||||
mod? (:mod? (meta shape))
|
||||
[row column :as cell] (when-not mod? (:cell (meta shape)))
|
||||
|
||||
changes (-> changes
|
||||
(pcb/with-objects objects)
|
||||
|
||||
@@ -490,7 +490,7 @@
|
||||
flex-layout? (ctl/flex-layout? objects target-frame)
|
||||
grid-layout? (ctl/grid-layout? objects target-frame)
|
||||
drop-index (when flex-layout? (gslf/get-drop-index target-frame objects position))
|
||||
cell-data (when grid-layout? (gslg/get-drop-cell target-frame objects position))]
|
||||
cell-data (when (and grid-layout? (not mod?)) (gslg/get-drop-cell target-frame objects position))]
|
||||
[move-vector target-frame drop-index cell-data])))
|
||||
|
||||
(rx/take-until stopper))]
|
||||
|
||||
@@ -126,6 +126,9 @@
|
||||
[id]
|
||||
(l/derived #(contains? % id) selected-shapes))
|
||||
|
||||
(def highlighted-shapes
|
||||
(l/derived :highlighted workspace-local))
|
||||
|
||||
(def export-in-progress?
|
||||
(l/derived :export-in-progress? export))
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
(mf/defc layer-item
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [index item selected objects sortable? filtered? depth parent-size component-child?]}]
|
||||
[{:keys [index item selected objects sortable? filtered? depth parent-size component-child? highlighted]}]
|
||||
(let [id (:id item)
|
||||
name (:name item)
|
||||
blocked? (:blocked item)
|
||||
@@ -50,6 +50,7 @@
|
||||
expanded? (mf/deref expanded-iref)
|
||||
|
||||
selected? (contains? selected id)
|
||||
highlighted? (contains? highlighted id)
|
||||
container? (or (cph/frame-shape? item)
|
||||
(cph/group-shape? item))
|
||||
absolute? (ctl/layout-absolute? item)
|
||||
@@ -341,6 +342,7 @@
|
||||
|
||||
[:div.element-list-body {:class (stl/css-case*
|
||||
:selected selected?
|
||||
:hover highlighted?
|
||||
:icon-layer (= (:type item) :icon))
|
||||
:on-click select-shape
|
||||
:on-pointer-enter on-pointer-enter
|
||||
@@ -395,6 +397,7 @@
|
||||
[:& layer-item
|
||||
{:item item
|
||||
:selected selected
|
||||
:highlighted highlighted
|
||||
:index index
|
||||
:objects objects
|
||||
:key (dm/str id)
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
[{:keys [objects filtered? parent-size] :as props}]
|
||||
(let [selected (mf/deref refs/selected-shapes)
|
||||
selected (hooks/use-equal-memo selected)
|
||||
highlighted (mf/deref refs/highlighted-shapes)
|
||||
highlighted (hooks/use-equal-memo highlighted)
|
||||
root (get objects uuid/zero)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
[:ul
|
||||
@@ -54,6 +56,7 @@
|
||||
[:& frame-wrapper
|
||||
{:item obj
|
||||
:selected selected
|
||||
:highlighted highlighted
|
||||
:index index
|
||||
:objects objects
|
||||
:key id
|
||||
@@ -64,6 +67,7 @@
|
||||
[:& layer-item
|
||||
{:item obj
|
||||
:selected selected
|
||||
:highlighted highlighted
|
||||
:index index
|
||||
:objects objects
|
||||
:key id
|
||||
|
||||
@@ -82,7 +82,8 @@
|
||||
shape-parent-frame (cph/get-frame objects (:frame-id first-selected-shape))
|
||||
|
||||
edit-grid? (ctl/grid-layout? objects edition)
|
||||
selected-cell (dm/get-in grid-edition [edition :selected])
|
||||
selected-cells (->> (dm/get-in grid-edition [edition :selected])
|
||||
(map #(dm/get-in objects [edition :layout-grid-cells %])))
|
||||
|
||||
on-change-tab
|
||||
(fn [options-mode]
|
||||
@@ -105,10 +106,10 @@
|
||||
[:& bool-options]
|
||||
|
||||
(cond
|
||||
(some? selected-cell)
|
||||
(d/not-empty? selected-cells)
|
||||
[:& grid-cell/options
|
||||
{:shape (get objects edition)
|
||||
:cell (dm/get-in objects [edition :layout-grid-cells selected-cell])}]
|
||||
:cells selected-cells}]
|
||||
|
||||
edit-grid?
|
||||
[:& layout-container/grid-layout-edition
|
||||
@@ -166,10 +167,10 @@
|
||||
[:& align-options]
|
||||
[:& bool-options]
|
||||
(cond
|
||||
(some? selected-cell)
|
||||
(d/not-empty? selected-cells)
|
||||
[:& grid-cell/options
|
||||
{:shape (get objects edition)
|
||||
:cell (dm/get-in objects [edition :layout-grid-cells selected-cell])}]
|
||||
:cells selected-cells}]
|
||||
|
||||
edit-grid?
|
||||
[:& layout-container/grid-layout-edition
|
||||
|
||||
@@ -6,16 +6,31 @@
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.options.menus.grid-cell
|
||||
(:require
|
||||
[app.common.attrs :as attrs]
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.shape.layout :as ctl]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.grid-layout.editor :as dwge]
|
||||
[app.main.data.workspace.shape-layout :as dwsl]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.numeric-input :refer [numeric-input*]]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[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]))
|
||||
|
||||
(def cell-props [:id
|
||||
:position
|
||||
:row
|
||||
:row-span
|
||||
:column
|
||||
:column-span
|
||||
:align-self
|
||||
:justify-self
|
||||
:area-name])
|
||||
|
||||
(mf/defc set-self-alignment
|
||||
[{:keys [is-col? alignment set-alignment] :as props}]
|
||||
(let [dir-v [:auto :start :center :end :stretch #_:baseline]
|
||||
@@ -34,72 +49,91 @@
|
||||
|
||||
(mf/defc options
|
||||
{::mf/wrap [mf/memo]}
|
||||
[{:keys [shape cell] :as props}]
|
||||
[{:keys [shape cell cells] :as props}]
|
||||
|
||||
(let [{:keys [mode area-name align-self justify-self column column-span row row-span]} cell
|
||||
column-end (+ column column-span)
|
||||
row-end (+ row row-span)
|
||||
(let [cells (hooks/use-equal-memo cells)
|
||||
cell (or cell (attrs/get-attrs-multi cells cell-props))
|
||||
|
||||
cell-mode (or mode :auto)
|
||||
multiple? (= :multiple (:id cell))
|
||||
cell-ids (if (some? cell) [(:id cell)] (->> cells (map :id)))
|
||||
cell-ids (hooks/use-equal-memo cell-ids)
|
||||
|
||||
{:keys [position area-name align-self justify-self column column-span row row-span]} cell
|
||||
|
||||
column-end (when (and (d/num? column) (d/num? column-span))
|
||||
(+ column column-span))
|
||||
row-end (when (and (d/num? row) (d/num? row-span))
|
||||
(+ row row-span))
|
||||
|
||||
cell-mode (or position :auto)
|
||||
cell-mode (if (and (= :auto cell-mode)
|
||||
(or (> (:column-span cell) 1)
|
||||
(> (:row-span cell) 1)))
|
||||
:manual
|
||||
cell-mode)
|
||||
|
||||
valid-area-cells? (mf/use-memo
|
||||
(mf/deps cells)
|
||||
#(ctl/valid-area-cells? cells))
|
||||
|
||||
set-alignment
|
||||
(mf/use-callback
|
||||
(mf/deps align-self (:id shape) (:id cell))
|
||||
(mf/deps align-self (:id shape) cell-ids)
|
||||
(fn [value]
|
||||
(if (= align-self value)
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:align-self nil}))
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:align-self value})))))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:align-self nil}))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:align-self value})))))
|
||||
|
||||
set-justify-self
|
||||
(mf/use-callback
|
||||
(mf/deps justify-self (:id shape) (:id cell))
|
||||
(mf/deps justify-self (:id shape) cell-ids)
|
||||
(fn [value]
|
||||
(if (= justify-self value)
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:justify-self nil}))
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:justify-self value})))))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:justify-self nil}))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:justify-self value})))))
|
||||
|
||||
on-change
|
||||
on-grid-coordinates
|
||||
(mf/use-callback
|
||||
(mf/deps column row (:id shape) (:id cell))
|
||||
(fn [field type value]
|
||||
(let [[property value]
|
||||
(cond
|
||||
(and (= type :column) (or (= field :all) (= field :start)))
|
||||
[:column value]
|
||||
(when-not multiple?
|
||||
(let [[property value]
|
||||
(cond
|
||||
(and (= type :column) (or (= field :all) (= field :start)))
|
||||
[:column value]
|
||||
|
||||
(and (= type :column) (= field :end))
|
||||
[:column-span (max 1 (- value column))]
|
||||
(and (= type :column) (= field :end))
|
||||
[:column-span (max 1 (- value column))]
|
||||
|
||||
(and (= type :row) (or (= field :all) (= field :start)))
|
||||
[:row value]
|
||||
(and (= type :row) (or (= field :all) (= field :start)))
|
||||
[:row value]
|
||||
|
||||
(and (= type :row) (= field :end))
|
||||
[:row-span (max 1 (- value row))])]
|
||||
(and (= type :row) (= field :end))
|
||||
[:row-span (max 1 (- value row))])]
|
||||
|
||||
(st/emit! (dwsl/update-grid-cell-position (:id shape) (:id cell) {property value})))))
|
||||
(st/emit! (dwsl/update-grid-cell-position (:id shape) (:id cell) {property value}))))))
|
||||
|
||||
on-area-name-change
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) (:id cell))
|
||||
(mf/deps (:id shape) cell-ids)
|
||||
(fn [event]
|
||||
(let [value (dom/get-value (dom/get-target event))]
|
||||
(if (= value "")
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:area-name nil}))
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) {:area-name value}))))))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:area-name nil}))
|
||||
(st/emit! (dwsl/update-grid-cells (:id shape) cell-ids {:area-name value}))))))
|
||||
|
||||
set-cell-mode
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) (:id cell))
|
||||
(mf/deps (:id shape) cell-ids)
|
||||
(fn [mode]
|
||||
(let [props (cond-> {:mode mode}
|
||||
(not= mode :area)
|
||||
(assoc :area-name nil))]
|
||||
(st/emit! (dwsl/update-grid-cell (:id shape) (:id cell) props)))))]
|
||||
(st/emit! (dwsl/change-cells-mode (:id shape) cell-ids mode))))
|
||||
|
||||
toggle-edit-mode
|
||||
(mf/use-fn
|
||||
(mf/deps (:id shape))
|
||||
(fn []
|
||||
(st/emit! (dw/start-edition-mode (:id shape))
|
||||
(dwge/clear-selection (:id shape)))))]
|
||||
|
||||
[:div.element-set
|
||||
[:div.element-set-title
|
||||
@@ -112,15 +146,17 @@
|
||||
[:button.position-btn
|
||||
{:on-click #(set-cell-mode :auto)
|
||||
:class (dom/classnames :active (= :auto cell-mode))} "Auto"]
|
||||
[:button.position-btn
|
||||
{:on-click #(set-cell-mode :manual)
|
||||
:class (dom/classnames :active (= :manual cell-mode))} "Manual"]
|
||||
(when-not multiple?
|
||||
[:button.position-btn
|
||||
{:on-click #(set-cell-mode :manual)
|
||||
:class (dom/classnames :active (= :manual cell-mode))} "Manual"])
|
||||
[:button.position-btn
|
||||
{:on-click #(set-cell-mode :area)
|
||||
:disabled (not valid-area-cells?)
|
||||
:class (dom/classnames :active (= :area cell-mode))} "Area"]]]
|
||||
|
||||
[:div.manage-grid-columns
|
||||
(when (= :auto cell-mode)
|
||||
(when (and (not multiple?) (= :auto cell-mode))
|
||||
[:div.grid-auto
|
||||
[:div.grid-columns-auto
|
||||
[:span.icon i/layout-rows]
|
||||
@@ -128,7 +164,7 @@
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-click #(dom/select-target %)
|
||||
:on-change (partial on-change :all :column)
|
||||
:on-change (partial on-grid-coordinates :all :column)
|
||||
:value column}]]]
|
||||
[:div.grid-rows-auto
|
||||
[:span.icon i/layout-columns]
|
||||
@@ -136,7 +172,7 @@
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-click #(dom/select-target %)
|
||||
:on-change (partial on-change :all :row)
|
||||
:on-change (partial on-grid-coordinates :all :row)
|
||||
:value row}]]]])
|
||||
|
||||
(when (= :area cell-mode)
|
||||
@@ -151,7 +187,7 @@
|
||||
:auto-complete "off"
|
||||
:on-change on-area-name-change}]])
|
||||
|
||||
(when (or (= :manual cell-mode) (= :area cell-mode))
|
||||
(when (and (not multiple?) (or (= :manual cell-mode) (= :area cell-mode)))
|
||||
[:div.grid-manual
|
||||
[:div.grid-columns-auto
|
||||
[:span.icon i/layout-rows]
|
||||
@@ -159,12 +195,12 @@
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-pointer-down #(dom/select-target %)
|
||||
:on-change (partial on-change :start :column)
|
||||
:on-change (partial on-grid-coordinates :start :column)
|
||||
:value column}]
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-pointer-down #(dom/select-target %)
|
||||
:on-change (partial on-change :end :column)
|
||||
:on-change (partial on-grid-coordinates :end :column)
|
||||
:value column-end}]]]
|
||||
[:div.grid-rows-auto
|
||||
[:span.icon i/layout-columns]
|
||||
@@ -172,12 +208,12 @@
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-pointer-down #(dom/select-target %)
|
||||
:on-change (partial on-change :start :row)
|
||||
:on-change (partial on-grid-coordinates :start :row)
|
||||
:value row}]
|
||||
[:> numeric-input*
|
||||
{:placeholder "--"
|
||||
:on-pointer-down #(dom/select-target %)
|
||||
:on-change (partial on-change :end :row)
|
||||
:on-change (partial on-grid-coordinates :end :row)
|
||||
:value row-end}]]]])]
|
||||
|
||||
[:div.layout-row
|
||||
@@ -191,4 +227,14 @@
|
||||
[:div.btn-wrapper
|
||||
[:& set-self-alignment {:is-col? true
|
||||
:alignment justify-self
|
||||
:set-alignment set-justify-self}]]]]]))
|
||||
:set-alignment set-justify-self}]]]
|
||||
|
||||
[:div.layout-row.single-button
|
||||
[:div.btn-wrapper
|
||||
[:div.edit-mode
|
||||
[:button.tooltip.tooltip-bottom-left
|
||||
{:alt "Grid edit mode"
|
||||
:on-click toggle-edit-mode
|
||||
:style {:padding 0}}
|
||||
"Edit grid"
|
||||
i/grid-layout-mode]]]]]]))
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
[app.main.ui.components.select :refer [select]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[cuerdas.core :as str]
|
||||
@@ -871,8 +872,68 @@
|
||||
:fixed (dm/str value "px")
|
||||
value))
|
||||
|
||||
(mf/defc grid-track-info
|
||||
[{:keys [is-col? type index column set-column-value set-column-type remove-element reorder-track hover-track]}]
|
||||
(let [drop-track
|
||||
(mf/use-callback
|
||||
(mf/deps type reorder-track index)
|
||||
(fn [drop-position data]
|
||||
(reorder-track type (:index data) (if (= :top drop-position) (dec index) index))))
|
||||
|
||||
pointer-enter
|
||||
(mf/use-callback
|
||||
(mf/deps type hover-track index)
|
||||
(fn []
|
||||
(hover-track type index true)))
|
||||
|
||||
pointer-leave
|
||||
(mf/use-callback
|
||||
(mf/deps type hover-track index)
|
||||
(fn []
|
||||
(hover-track type index false)))
|
||||
|
||||
[dprops dref]
|
||||
(h/use-sortable
|
||||
:data-type "penpot/grid-track"
|
||||
:on-drop drop-track
|
||||
:data {:is-col? is-col?
|
||||
:index index
|
||||
:column column}
|
||||
:draggable? true)]
|
||||
[:div.column-info
|
||||
{:ref dref
|
||||
:class (dom/classnames
|
||||
:dnd-over-top (or (= (:over dprops) :top)
|
||||
(= (:over dprops) :center))
|
||||
:dnd-over-bot (= (:over dprops) :bot))
|
||||
:on-pointer-enter pointer-enter
|
||||
:on-pointer-leave pointer-leave}
|
||||
[: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 "--"
|
||||
:disabled (= :auto (:type column))}]]
|
||||
[: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 grid-columns-row
|
||||
[{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element] :as props}]
|
||||
[{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element reorder-track hover-track] :as props}]
|
||||
(let [column-num (count column-values)
|
||||
direction (if (> column-num 1)
|
||||
(if is-col? "Columns " "Rows ")
|
||||
@@ -894,32 +955,19 @@
|
||||
(add-new-element type ctl/default-track-value))} i/plus]]
|
||||
|
||||
(when expanded?
|
||||
[:div.columns-info-wrapper
|
||||
(for [[index column] (d/enumerate column-values)]
|
||||
[:div.column-info {:key (dm/str index "-" (name type) "-" column)}
|
||||
[: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 "--"
|
||||
:disabled (= :auto (:type column))}]]
|
||||
[: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]])])]))
|
||||
[:& h/sortable-container {}
|
||||
[:div.columns-info-wrapper
|
||||
(for [[index column] (d/enumerate column-values)]
|
||||
[:& grid-track-info {:key (dm/str index "-" (name type) "-" column)
|
||||
:type type
|
||||
:is-col? is-col?
|
||||
:index index
|
||||
:column column
|
||||
:set-column-value set-column-value
|
||||
:set-column-type set-column-type
|
||||
:remove-element remove-element
|
||||
:reorder-track reorder-track
|
||||
:hover-track hover-track}])]])]))
|
||||
|
||||
;; LAYOUT COMPONENT
|
||||
|
||||
@@ -1352,7 +1400,7 @@
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["ids" "values"]))]}
|
||||
[{:keys [ids values] :as props}]
|
||||
(let [;; Gap
|
||||
gap-selected? (mf/use-state :none)
|
||||
gap-selected? (mf/use-state :none)
|
||||
saved-grid-dir (:layout-grid-dir values)
|
||||
|
||||
set-direction
|
||||
@@ -1401,8 +1449,8 @@
|
||||
(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})))))
|
||||
(st/emit! (dwsl/update-layout ids {:layout-justify-content value}))
|
||||
(st/emit! (dwsl/update-layout ids {:layout-align-content value})))))
|
||||
|
||||
;;Grid columns
|
||||
column-grid-values (:layout-grid-columns values)
|
||||
@@ -1431,6 +1479,18 @@
|
||||
(fn [type index]
|
||||
(st/emit! (dwsl/remove-layout-track ids type index))))
|
||||
|
||||
reorder-track
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [type from-index to-index]
|
||||
(st/emit! (dwsl/reorder-layout-track ids type from-index to-index))))
|
||||
|
||||
hover-track
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
(fn [type index hover?]
|
||||
(st/emit! (dwsl/hover-layout-track ids type index hover?))))
|
||||
|
||||
set-column-value
|
||||
(mf/use-fn
|
||||
(mf/deps ids)
|
||||
@@ -1482,12 +1542,12 @@
|
||||
|
||||
[:div.layout-row
|
||||
[:div.jusfiy-content-grid.row-title "Content"]
|
||||
[:div.btn-wrapper.align-grid
|
||||
[:div.btn-wrapper.align-grid-content
|
||||
[:& justify-grid-row {:is-col? true
|
||||
:justify-items grid-justify-content-column
|
||||
:justify-items grid-justify-content-row
|
||||
:set-justify set-content-grid}]
|
||||
[:& justify-grid-row {:is-col? false
|
||||
:justify-items grid-justify-content-row
|
||||
:justify-items grid-justify-content-column
|
||||
:set-justify set-content-grid}]]]
|
||||
[:& grid-columns-row {:is-col? true
|
||||
:expanded? @grid-columns-open?
|
||||
@@ -1496,7 +1556,9 @@
|
||||
:add-new-element add-new-element
|
||||
:set-column-value set-column-value
|
||||
:set-column-type set-column-type
|
||||
:remove-element remove-element}]
|
||||
:remove-element remove-element
|
||||
:reorder-track reorder-track
|
||||
:hover-track hover-track}]
|
||||
|
||||
[:& grid-columns-row {:is-col? false
|
||||
:expanded? @grid-rows-open?
|
||||
@@ -1505,7 +1567,9 @@
|
||||
:add-new-element add-new-element
|
||||
:set-column-value set-column-value
|
||||
:set-column-type set-column-type
|
||||
:remove-element remove-element}]
|
||||
:remove-element remove-element
|
||||
:reorder-track reorder-track
|
||||
:hover-track hover-track}]
|
||||
|
||||
[:& gap-section {:gap-selected? gap-selected?
|
||||
:on-change set-gap
|
||||
|
||||
@@ -533,7 +533,7 @@
|
||||
:nillable true
|
||||
:value (:layout-item-z-index values)}]])]
|
||||
|
||||
(when is-layout-child?
|
||||
(when (and is-layout-child? is-flex-parent?)
|
||||
[:div {:class (stl/css :second-row)}
|
||||
[:& align-self-row {:is-col? is-col?
|
||||
:align-self align-self
|
||||
@@ -667,7 +667,7 @@
|
||||
:on-change-behaviour-v-refactor on-change-behaviour-v
|
||||
:on-change on-change-behaviour}]]
|
||||
|
||||
(when is-layout-child?
|
||||
(when (and is-layout-child? is-flex-parent?)
|
||||
[:div.layout-row
|
||||
[:div.row-title "Align"]
|
||||
[:div.btn-wrapper
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
;; --- Page Item
|
||||
|
||||
(mf/defc page-item [{:keys [page index deletable? selected? editing?] :as props}]
|
||||
(mf/defc page-item
|
||||
[{:keys [page index deletable? selected? editing? hovering?] :as props}]
|
||||
(let [input-ref (mf/use-ref)
|
||||
id (:id page)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
@@ -135,6 +136,7 @@
|
||||
(css :selected) selected?)
|
||||
(dom/classnames
|
||||
:element-list-body true
|
||||
:hover hovering?
|
||||
:selected selected?))
|
||||
:data-test (dm/str "page-" id)
|
||||
:tab-index "0"
|
||||
|
||||
@@ -176,7 +176,8 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
&:hover,
|
||||
&.hover {
|
||||
.element-list-body {
|
||||
color: var(--layer-row-foreground-color-hover);
|
||||
background-color: var(--layer-row-background-color-hover);
|
||||
|
||||
@@ -173,7 +173,7 @@
|
||||
on-context-menu (actions/on-context-menu hover hover-ids workspace-read-only?)
|
||||
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? workspace-read-only?)
|
||||
on-drag-enter (actions/on-drag-enter)
|
||||
on-drag-over (actions/on-drag-over)
|
||||
on-drag-over (actions/on-drag-over move-stream)
|
||||
on-drop (actions/on-drop file)
|
||||
on-pointer-down (actions/on-pointer-down @hover selected edition drawing-tool text-editing? node-editing? grid-editing?
|
||||
drawing-path? create-comment? space? panning z? workspace-read-only?)
|
||||
|
||||
@@ -404,15 +404,17 @@
|
||||
(dnd/has-type? e "text/asset-id"))
|
||||
(dom/prevent-default e)))))
|
||||
|
||||
(defn on-drag-over []
|
||||
(mf/use-callback
|
||||
(fn [e]
|
||||
(when (or (dnd/has-type? e "penpot/shape")
|
||||
(dnd/has-type? e "penpot/component")
|
||||
(dnd/has-type? e "Files")
|
||||
(dnd/has-type? e "text/uri-list")
|
||||
(dnd/has-type? e "text/asset-id"))
|
||||
(dom/prevent-default e)))))
|
||||
(defn on-drag-over [move-stream]
|
||||
(let [on-pointer-move (on-pointer-move move-stream)]
|
||||
(mf/use-callback
|
||||
(fn [e]
|
||||
(when (or (dnd/has-type? e "penpot/shape")
|
||||
(dnd/has-type? e "penpot/component")
|
||||
(dnd/has-type? e "Files")
|
||||
(dnd/has-type? e "text/uri-list")
|
||||
(dnd/has-type? e "text/asset-id"))
|
||||
(on-pointer-move e)
|
||||
(dom/prevent-default e))))))
|
||||
|
||||
(defn on-drop
|
||||
[file]
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
[app.main.ui.css-cursors :as cur]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.viewport.viewport-ref :as uwvv]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
@@ -301,10 +302,10 @@
|
||||
handle-pointer-down
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) (:id cell) selected?)
|
||||
(fn []
|
||||
(if selected?
|
||||
(st/emit! (dwge/remove-selection (:id shape)))
|
||||
(st/emit! (dwge/select-grid-cell (:id shape) (:id cell))))))]
|
||||
(fn [event]
|
||||
(if (and (kbd/shift? event) selected?)
|
||||
(st/emit! (dwge/remove-selection (:id shape) (:id cell)))
|
||||
(st/emit! (dwge/select-grid-cell (:id shape) (:id cell) (kbd/shift? event)) ))))]
|
||||
|
||||
[:g.cell-editor
|
||||
[:rect
|
||||
@@ -434,19 +435,19 @@
|
||||
|
||||
[width height]
|
||||
(if (= type :column)
|
||||
[(max layout-gap-col (/ 16 zoom))
|
||||
[(max 0 (- layout-gap-col (/ 10 zoom)) (/ 16 zoom))
|
||||
(+ row-total-size row-total-gap)]
|
||||
|
||||
[(+ column-total-size column-total-gap)
|
||||
(max layout-gap-row (/ 16 zoom))])
|
||||
(max 0 (- layout-gap-row (/ 10 zoom)) (/ 16 zoom))])
|
||||
|
||||
start-p
|
||||
(cond-> start-p
|
||||
(and (= type :column) (= index 0))
|
||||
(gpt/subtract (hv width))
|
||||
(gpt/subtract (hv (/ width 2)))
|
||||
|
||||
(and (= type :row) (= index 0))
|
||||
(gpt/subtract (vv height))
|
||||
(gpt/subtract (vv (/ height 2)))
|
||||
|
||||
(and (= type :column) (not= index 0) (not last?))
|
||||
(-> (gpt/subtract (hv (/ layout-gap-col 2)))
|
||||
@@ -531,16 +532,17 @@
|
||||
(dm/str value)]]))
|
||||
|
||||
(mf/defc track
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "zoom" "index" "type" "track-data" "layout-data"]))]
|
||||
{::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "zoom" "index" "type" "track-data" "layout-data" "hovering?"]))]
|
||||
::mf/wrap-props false}
|
||||
[props]
|
||||
(let [shape (unchecked-get props "shape")
|
||||
zoom (unchecked-get props "zoom")
|
||||
type (unchecked-get props "type")
|
||||
index (unchecked-get props "index")
|
||||
(let [shape (unchecked-get props "shape")
|
||||
zoom (unchecked-get props "zoom")
|
||||
type (unchecked-get props "type")
|
||||
index (unchecked-get props "index")
|
||||
snap-pixel? (unchecked-get props "snap-pixel?")
|
||||
track-data (unchecked-get props "track-data")
|
||||
track-data (unchecked-get props "track-data")
|
||||
layout-data (unchecked-get props "layout-data")
|
||||
hovering? (unchecked-get props "hovering?")
|
||||
|
||||
track-input-ref (mf/use-ref)
|
||||
[layout-gap-row layout-gap-col] (ctl/gaps shape)
|
||||
@@ -604,6 +606,24 @@
|
||||
(when esc?
|
||||
(dom/blur! (dom/get-target event))))))
|
||||
|
||||
handle-pointer-enter
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) type index)
|
||||
(fn []
|
||||
(st/emit! (dwsl/hover-layout-track [(:id shape)] type index true))))
|
||||
|
||||
handle-pointer-leave
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) type index)
|
||||
(fn []
|
||||
(st/emit! (dwsl/hover-layout-track [(:id shape)] type index false))))
|
||||
|
||||
handle-remove-track
|
||||
(mf/use-callback
|
||||
(mf/deps (:id shape) type index)
|
||||
(fn []
|
||||
(st/emit! (dwsl/remove-layout-track [(:id shape)] type index))))
|
||||
|
||||
track-list-prop (if (= type :column) :column-tracks :row-tracks)
|
||||
[text-x text-y text-width text-height]
|
||||
(if (= type :column)
|
||||
@@ -618,18 +638,34 @@
|
||||
(dom/set-value! (mf/ref-val track-input-ref) (format-size track-data))))
|
||||
|
||||
[:g.track
|
||||
[:g {:transform (if (= type :column)
|
||||
[:g {:on-pointer-enter handle-pointer-enter
|
||||
:on-pointer-leave handle-pointer-leave
|
||||
:transform (if (= type :column)
|
||||
(dm/str (gmt/transform-in text-p (:transform shape)))
|
||||
(dm/str (gmt/transform-in text-p (gmt/rotate (:transform shape) -90))))}
|
||||
|
||||
(when hovering?
|
||||
[:rect {:x (+ text-x (/ 5 zoom))
|
||||
:y text-y
|
||||
:width (- text-width (/ 10 zoom))
|
||||
:height (- text-height (/ 5 zoom))
|
||||
:rx (/ 3 zoom)
|
||||
:fill "var(--color-distance)"
|
||||
:opacity 0.2}])
|
||||
[:foreignObject {:x text-x :y text-y :width text-width :height text-height}
|
||||
[:input
|
||||
{:ref track-input-ref
|
||||
:class (css :grid-editor-label)
|
||||
:type "text"
|
||||
:default-value (format-size track-data)
|
||||
:data-default-value (format-size track-data)
|
||||
:on-key-down handle-keydown-track-input
|
||||
:on-blur handle-blur-track-input}]]]
|
||||
[:div {:class (css :grid-editor-wrapper)}
|
||||
[:input
|
||||
{:ref track-input-ref
|
||||
:style {}
|
||||
:class (css :grid-editor-label)
|
||||
:type "text"
|
||||
:default-value (format-size track-data)
|
||||
:data-default-value (format-size track-data)
|
||||
:on-key-down handle-keydown-track-input
|
||||
:on-blur handle-blur-track-input}]
|
||||
(when hovering?
|
||||
[:button {:class (css :grid-editor-button)
|
||||
:on-click handle-remove-track} i/trash])]]]
|
||||
|
||||
[:g {:transform (when (= type :row) (dm/fmt "rotate(-90 % %)" (:x marker-p) (:y marker-p)))}
|
||||
[:& track-marker
|
||||
@@ -684,6 +720,18 @@
|
||||
hover-cells (:hover grid-edition)
|
||||
selected-cells (:selected grid-edition)
|
||||
|
||||
hover-columns
|
||||
(->> (:hover-track grid-edition)
|
||||
(filter (fn [[t _]] (= t :column)))
|
||||
(map (fn [[_ idx]] idx))
|
||||
(into #{}))
|
||||
|
||||
hover-rows
|
||||
(->> (:hover-track grid-edition)
|
||||
(filter (fn [[t _]] (= t :row)))
|
||||
(map (fn [[_ idx]] idx))
|
||||
(into #{}))
|
||||
|
||||
children
|
||||
(mf/use-memo
|
||||
(mf/deps shape modifiers)
|
||||
@@ -733,6 +781,15 @@
|
||||
|
||||
[:g.grid-editor {:pointer-events (when view-only "none")
|
||||
:on-pointer-down handle-pointer-down}
|
||||
[:g.cells
|
||||
(for [cell (ctl/get-cells shape {:sort? true})]
|
||||
[:& grid-cell {:key (dm/str "cell-" (:id cell))
|
||||
:shape base-shape
|
||||
:layout-data layout-data
|
||||
:cell cell
|
||||
:zoom zoom
|
||||
:hover? (contains? hover-cells (:id cell))
|
||||
:selected? (contains? selected-cells (:id cell))}])]
|
||||
(when-not view-only
|
||||
[:*
|
||||
[:& grid-editor-frame {:zoom zoom
|
||||
@@ -759,7 +816,8 @@
|
||||
:index idx
|
||||
:layout-data layout-data
|
||||
:snap-pixel? snap-pixel?
|
||||
:track-data column-data}])
|
||||
:track-data column-data
|
||||
:hovering? (contains? hover-columns idx)}])
|
||||
|
||||
;; Last track resize handler
|
||||
(when-not (empty? column-tracks)
|
||||
@@ -796,8 +854,8 @@
|
||||
:snap-pixel? snap-pixel?
|
||||
:track-data row-data
|
||||
:type :row
|
||||
:zoom zoom}])
|
||||
|
||||
:zoom zoom
|
||||
:hovering? (contains? hover-rows idx)}])
|
||||
(when-not (empty? row-tracks)
|
||||
(let [last-track (last row-tracks)
|
||||
start-p (:start-p last-track)
|
||||
@@ -823,14 +881,4 @@
|
||||
:type :row
|
||||
:track-before (last row-tracks)
|
||||
:snap-pixel? snap-pixel?
|
||||
:zoom zoom}]]))])
|
||||
|
||||
[:g.cells
|
||||
(for [cell (ctl/get-cells shape {:sort? true})]
|
||||
[:& grid-cell {:key (dm/str "cell-" (:id cell))
|
||||
:shape base-shape
|
||||
:layout-data layout-data
|
||||
:cell cell
|
||||
:zoom zoom
|
||||
:hover? (contains? hover-cells (:id cell))
|
||||
:selected? (= selected-cells (:id cell))}])]]))
|
||||
:zoom zoom}]]))])]))
|
||||
|
||||
@@ -11,19 +11,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
.grid-editor-label {
|
||||
position: absolute;
|
||||
background: none;
|
||||
.grid-editor-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
font-family: worksans;
|
||||
height: 80%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.grid-editor-label {
|
||||
background: none;
|
||||
border-bottom: calc(1px / var(--zoom)) solid transparent;
|
||||
border: 0;
|
||||
color: var(--color-distance);
|
||||
font-family: worksans;
|
||||
font-size: calc(12px / var(--zoom));
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
max-width: calc(80px / var(--zoom));
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: calc(12px / var(--zoom));
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
@@ -31,6 +39,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
.grid-editor-button {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: calc(10px / var(--zoom));
|
||||
width: calc(20px / var(--zoom));
|
||||
height: calc(20px / var(--zoom));
|
||||
|
||||
svg {
|
||||
width: calc(16px / var(--zoom));
|
||||
height: auto;
|
||||
fill: var(--color-distance);
|
||||
}
|
||||
}
|
||||
|
||||
.grid-frame {
|
||||
fill: #f6f6f6;
|
||||
stroke: var(--color-distance);
|
||||
|
||||
@@ -153,12 +153,14 @@
|
||||
([state label component-id file-id]
|
||||
(let [page (current-page state)
|
||||
libraries (wsh/get-libraries state)
|
||||
objects (:objects page)
|
||||
|
||||
changes (-> (pcb/empty-changes nil (:id page))
|
||||
(pcb/with-objects (:objects page)))
|
||||
(pcb/with-objects objects))
|
||||
|
||||
[new-shape changes]
|
||||
(dwlh/generate-instantiate-component changes
|
||||
objects
|
||||
file-id
|
||||
component-id
|
||||
(gpt/point 100 100)
|
||||
|
||||
Reference in New Issue
Block a user