mirror of
https://github.com/penpot/penpot.git
synced 2025-04-30 01:36:19 +02:00
✨ Serialization of grid layout data (#6148)
* ✨ Add serializators for grid layout properties * ✨ Extract serializers for wasm api module
This commit is contained in:
parent
7284fb539f
commit
83d41dba6f
9 changed files with 892 additions and 282 deletions
|
@ -21,6 +21,7 @@
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.ui.shapes.text.fontfaces :as fonts]
|
[app.main.ui.shapes.text.fontfaces :as fonts]
|
||||||
[app.render-wasm.helpers :as h]
|
[app.render-wasm.helpers :as h]
|
||||||
|
[app.render-wasm.serializers :as sr]
|
||||||
[app.util.debug :as dbg]
|
[app.util.debug :as dbg]
|
||||||
[app.util.http :as http]
|
[app.util.http :as http]
|
||||||
[app.util.webapi :as wapi]
|
[app.util.webapi :as wapi]
|
||||||
|
@ -39,6 +40,7 @@
|
||||||
(def dpr
|
(def dpr
|
||||||
(if use-dpr? js/window.devicePixelRatio 1.0))
|
(if use-dpr? js/window.devicePixelRatio 1.0))
|
||||||
|
|
||||||
|
|
||||||
;; Based on app.main.render/object-svg
|
;; Based on app.main.render/object-svg
|
||||||
(mf/defc object-svg
|
(mf/defc object-svg
|
||||||
{::mf/props :obj}
|
{::mf/props :obj}
|
||||||
|
@ -121,22 +123,9 @@
|
||||||
[clip-content]
|
[clip-content]
|
||||||
(h/call internal-module "_set_shape_clip_content" clip-content))
|
(h/call internal-module "_set_shape_clip_content" clip-content))
|
||||||
|
|
||||||
(defn- translate-shape-type
|
|
||||||
[type]
|
|
||||||
(case type
|
|
||||||
:frame 0
|
|
||||||
:group 1
|
|
||||||
:bool 2
|
|
||||||
:rect 3
|
|
||||||
:path 4
|
|
||||||
:text 5
|
|
||||||
:circle 6
|
|
||||||
:svg-raw 7
|
|
||||||
:image 8))
|
|
||||||
|
|
||||||
(defn set-shape-type
|
(defn set-shape-type
|
||||||
[type]
|
[type]
|
||||||
(h/call internal-module "_set_shape_type" (translate-shape-type type)))
|
(h/call internal-module "_set_shape_type" (sr/translate-shape-type type)))
|
||||||
|
|
||||||
(defn set-masked
|
(defn set-masked
|
||||||
[masked]
|
[masked]
|
||||||
|
@ -301,26 +290,6 @@
|
||||||
(store-image id))))))
|
(store-image id))))))
|
||||||
fills))
|
fills))
|
||||||
|
|
||||||
(defn- translate-stroke-style
|
|
||||||
[stroke-style]
|
|
||||||
(case stroke-style
|
|
||||||
:dotted 1
|
|
||||||
:dashed 2
|
|
||||||
:mixed 3
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn- translate-stroke-cap
|
|
||||||
[stroke-cap]
|
|
||||||
(case stroke-cap
|
|
||||||
:line-arrow 1
|
|
||||||
:triangle-arrow 2
|
|
||||||
:square-marker 3
|
|
||||||
:circle-marker 4
|
|
||||||
:diamond-marker 5
|
|
||||||
:round 6
|
|
||||||
:square 7
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn set-shape-strokes
|
(defn set-shape-strokes
|
||||||
[strokes]
|
[strokes]
|
||||||
(h/call internal-module "_clear_shape_strokes")
|
(h/call internal-module "_clear_shape_strokes")
|
||||||
|
@ -331,9 +300,9 @@
|
||||||
image (:stroke-image stroke)
|
image (:stroke-image stroke)
|
||||||
width (:stroke-width stroke)
|
width (:stroke-width stroke)
|
||||||
align (:stroke-alignment stroke)
|
align (:stroke-alignment stroke)
|
||||||
style (-> stroke :stroke-style translate-stroke-style)
|
style (-> stroke :stroke-style sr/translate-stroke-style)
|
||||||
cap-start (-> stroke :stroke-cap-start translate-stroke-cap)
|
cap-start (-> stroke :stroke-cap-start sr/translate-stroke-cap)
|
||||||
cap-end (-> stroke :stroke-cap-end translate-stroke-cap)]
|
cap-end (-> stroke :stroke-cap-end sr/translate-stroke-cap)]
|
||||||
(case align
|
(case align
|
||||||
:inner (h/call internal-module "_add_shape_inner_stroke" width style cap-start cap-end)
|
:inner (h/call internal-module "_add_shape_inner_stroke" width style cap-start cap-end)
|
||||||
:outer (h/call internal-module "_add_shape_outer_stroke" width style cap-start cap-end)
|
:outer (h/call internal-module "_add_shape_outer_stroke" width style cap-start cap-end)
|
||||||
|
@ -388,14 +357,7 @@
|
||||||
(h/call internal-module "_add_shape_stroke_solid_fill" rgba)))))
|
(h/call internal-module "_add_shape_stroke_solid_fill" rgba)))))
|
||||||
strokes))
|
strokes))
|
||||||
|
|
||||||
(defn serialize-path-attrs
|
|
||||||
[svg-attrs]
|
|
||||||
(reduce
|
|
||||||
(fn [acc [key value]]
|
|
||||||
(str/concat
|
|
||||||
acc
|
|
||||||
(str/kebab key) "\0"
|
|
||||||
value "\0")) "" svg-attrs))
|
|
||||||
|
|
||||||
(defn set-shape-path-attrs
|
(defn set-shape-path-attrs
|
||||||
[attrs]
|
[attrs]
|
||||||
|
@ -403,7 +365,7 @@
|
||||||
attrs (-> attrs
|
attrs (-> attrs
|
||||||
(dissoc :style)
|
(dissoc :style)
|
||||||
(merge style))
|
(merge style))
|
||||||
str (serialize-path-attrs attrs)
|
str (sr/serialize-path-attrs attrs)
|
||||||
size (count str)
|
size (count str)
|
||||||
ptr (h/call internal-module "_alloc_bytes" size)]
|
ptr (h/call internal-module "_alloc_bytes" size)]
|
||||||
(h/call internal-module "stringToUTF8" str ptr size)
|
(h/call internal-module "stringToUTF8" str ptr size)
|
||||||
|
@ -426,95 +388,45 @@
|
||||||
(h/call internal-module "stringToUTF8" content ptr size)
|
(h/call internal-module "stringToUTF8" content ptr size)
|
||||||
(h/call internal-module "_set_shape_svg_raw_content")))
|
(h/call internal-module "_set_shape_svg_raw_content")))
|
||||||
|
|
||||||
(defn- translate-blend-mode
|
|
||||||
[blend-mode]
|
|
||||||
(case blend-mode
|
|
||||||
:normal 3
|
|
||||||
:darken 16
|
|
||||||
:multiply 24
|
|
||||||
:color-burn 19
|
|
||||||
:lighten 17
|
|
||||||
:screen 14
|
|
||||||
:color-dodge 18
|
|
||||||
:overlay 15
|
|
||||||
:soft-light 21
|
|
||||||
:hard-light 20
|
|
||||||
:difference 22
|
|
||||||
:exclusion 23
|
|
||||||
:hue 25
|
|
||||||
:saturation 26
|
|
||||||
:color 27
|
|
||||||
:luminosity 28
|
|
||||||
3))
|
|
||||||
|
|
||||||
(defn set-shape-blend-mode
|
(defn set-shape-blend-mode
|
||||||
[blend-mode]
|
[blend-mode]
|
||||||
;; These values correspond to skia::BlendMode representation
|
;; These values correspond to skia::BlendMode representation
|
||||||
;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html
|
;; https://rust-skia.github.io/doc/skia_safe/enum.BlendMode.html
|
||||||
(h/call internal-module "_set_shape_blend_mode" (translate-blend-mode blend-mode)))
|
(h/call internal-module "_set_shape_blend_mode" (sr/translate-blend-mode blend-mode)))
|
||||||
|
|
||||||
(defn set-shape-opacity
|
(defn set-shape-opacity
|
||||||
[opacity]
|
[opacity]
|
||||||
(h/call internal-module "_set_shape_opacity" (or opacity 1)))
|
(h/call internal-module "_set_shape_opacity" (or opacity 1)))
|
||||||
|
|
||||||
(defn- translate-constraint-h
|
|
||||||
[type]
|
|
||||||
(case type
|
|
||||||
:left 0
|
|
||||||
:right 1
|
|
||||||
:leftright 2
|
|
||||||
:center 3
|
|
||||||
:scale 4))
|
|
||||||
|
|
||||||
(defn set-constraints-h
|
(defn set-constraints-h
|
||||||
[constraint]
|
[constraint]
|
||||||
(when constraint
|
(when constraint
|
||||||
(h/call internal-module "_set_shape_constraint_h" (translate-constraint-h constraint))))
|
(h/call internal-module "_set_shape_constraint_h" (sr/translate-constraint-h constraint))))
|
||||||
|
|
||||||
(defn- translate-constraint-v
|
|
||||||
[type]
|
|
||||||
(case type
|
|
||||||
:top 0
|
|
||||||
:bottom 1
|
|
||||||
:topbottom 2
|
|
||||||
:center 3
|
|
||||||
:scale 4))
|
|
||||||
|
|
||||||
(defn set-constraints-v
|
(defn set-constraints-v
|
||||||
[constraint]
|
[constraint]
|
||||||
(when constraint
|
(when constraint
|
||||||
(h/call internal-module "_set_shape_constraint_v" (translate-constraint-v constraint))))
|
(h/call internal-module "_set_shape_constraint_v" (sr/translate-constraint-v constraint))))
|
||||||
|
|
||||||
(defn set-shape-hidden
|
(defn set-shape-hidden
|
||||||
[hidden]
|
[hidden]
|
||||||
(h/call internal-module "_set_shape_hidden" hidden))
|
(h/call internal-module "_set_shape_hidden" hidden))
|
||||||
|
|
||||||
(defn- translate-bool-type
|
|
||||||
[bool-type]
|
|
||||||
(case bool-type
|
|
||||||
:union 0
|
|
||||||
:difference 1
|
|
||||||
:intersection 2
|
|
||||||
:exclusion 3
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn set-shape-bool-type
|
(defn set-shape-bool-type
|
||||||
[bool-type]
|
[bool-type]
|
||||||
(h/call internal-module "_set_shape_bool_type" (translate-bool-type bool-type)))
|
(h/call internal-module "_set_shape_bool_type" (sr/translate-bool-type bool-type)))
|
||||||
|
|
||||||
(defn set-shape-bool-content
|
(defn set-shape-bool-content
|
||||||
[content]
|
[content]
|
||||||
(set-shape-path-content content))
|
(set-shape-path-content content))
|
||||||
|
|
||||||
(defn- translate-blur-type
|
|
||||||
[blur-type]
|
|
||||||
(case blur-type
|
|
||||||
:layer-blur 1
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn set-shape-blur
|
(defn set-shape-blur
|
||||||
[blur]
|
[blur]
|
||||||
(let [type (-> blur :type translate-blur-type)
|
(let [type (-> blur :type sr/translate-blur-type)
|
||||||
hidden (:hidden blur)
|
hidden (:hidden blur)
|
||||||
value (:value blur)]
|
value (:value blur)]
|
||||||
(h/call internal-module "_set_shape_blur" type hidden value)))
|
(h/call internal-module "_set_shape_blur" type hidden value)))
|
||||||
|
@ -527,71 +439,18 @@
|
||||||
r4 (or (get corners 3) 0)]
|
r4 (or (get corners 3) 0)]
|
||||||
(h/call internal-module "_set_shape_corners" r1 r2 r3 r4)))
|
(h/call internal-module "_set_shape_corners" r1 r2 r3 r4)))
|
||||||
|
|
||||||
|
|
||||||
(defn translate-layout-flex-dir
|
|
||||||
[flex-dir]
|
|
||||||
(case flex-dir
|
|
||||||
:row 0
|
|
||||||
:row-reverse 1
|
|
||||||
:column 2
|
|
||||||
:column-reverse 3))
|
|
||||||
|
|
||||||
(defn translate-layout-align-items
|
|
||||||
[align-items]
|
|
||||||
(case align-items
|
|
||||||
:start 0
|
|
||||||
:end 1
|
|
||||||
:center 2
|
|
||||||
:stretch 3))
|
|
||||||
|
|
||||||
(defn translate-layout-align-content
|
|
||||||
[align-content]
|
|
||||||
(case align-content
|
|
||||||
:start 0
|
|
||||||
:end 1
|
|
||||||
:center 2
|
|
||||||
:space-between 3
|
|
||||||
:space-around 4
|
|
||||||
:space-evenly 5
|
|
||||||
:stretch 6))
|
|
||||||
|
|
||||||
(defn translate-layout-justify-items
|
|
||||||
[justify-items]
|
|
||||||
(case justify-items
|
|
||||||
:start 0
|
|
||||||
:end 1
|
|
||||||
:center 2
|
|
||||||
:stretch 3))
|
|
||||||
|
|
||||||
(defn translate-layout-justify-content
|
|
||||||
[justify-content]
|
|
||||||
(case justify-content
|
|
||||||
:start 0
|
|
||||||
:end 1
|
|
||||||
:center 2
|
|
||||||
:space-between 3
|
|
||||||
:space-around 4
|
|
||||||
:space-evenly 5
|
|
||||||
:stretch 6))
|
|
||||||
|
|
||||||
(defn translate-layout-wrap-type
|
|
||||||
[wrap-type]
|
|
||||||
(case wrap-type
|
|
||||||
:wrap 0
|
|
||||||
:nowrap 1))
|
|
||||||
|
|
||||||
(defn set-flex-layout
|
(defn set-flex-layout
|
||||||
[shape]
|
[shape]
|
||||||
(let [dir (-> (or (dm/get-prop shape :layout-flex-dir) :row) translate-layout-flex-dir)
|
(let [dir (-> (or (dm/get-prop shape :layout-flex-dir) :row) sr/translate-layout-flex-dir)
|
||||||
gap (dm/get-prop shape :layout-gap)
|
gap (dm/get-prop shape :layout-gap)
|
||||||
row-gap (or (dm/get-prop gap :row-gap) 0)
|
row-gap (or (dm/get-prop gap :row-gap) 0)
|
||||||
column-gap (or (dm/get-prop gap :column-gap) 0)
|
column-gap (or (dm/get-prop gap :column-gap) 0)
|
||||||
|
|
||||||
align-items (-> (or (dm/get-prop shape :layout-align-items) :start) translate-layout-align-items)
|
align-items (-> (or (dm/get-prop shape :layout-align-items) :start) sr/translate-layout-align-items)
|
||||||
align-content (-> (or (dm/get-prop shape :layout-align-content) :stretch) translate-layout-align-content)
|
align-content (-> (or (dm/get-prop shape :layout-align-content) :stretch) sr/translate-layout-align-content)
|
||||||
justify-items (-> (or (dm/get-prop shape :layout-justify-items) :start) translate-layout-justify-items)
|
justify-items (-> (or (dm/get-prop shape :layout-justify-items) :start) sr/translate-layout-justify-items)
|
||||||
justify-content (-> (or (dm/get-prop shape :layout-justify-content) :stretch) translate-layout-justify-content)
|
justify-content (-> (or (dm/get-prop shape :layout-justify-content) :stretch) sr/translate-layout-justify-content)
|
||||||
wrap-type (-> (or (dm/get-prop shape :layout-wrap-type) :nowrap) translate-layout-wrap-type)
|
wrap-type (-> (or (dm/get-prop shape :layout-wrap-type) :nowrap) sr/translate-layout-wrap-type)
|
||||||
|
|
||||||
padding (dm/get-prop shape :layout-padding)
|
padding (dm/get-prop shape :layout-padding)
|
||||||
padding-top (or (dm/get-prop padding :p1) 0)
|
padding-top (or (dm/get-prop padding :p1) 0)
|
||||||
|
@ -614,23 +473,128 @@
|
||||||
padding-left)))
|
padding-left)))
|
||||||
|
|
||||||
(defn set-grid-layout
|
(defn set-grid-layout
|
||||||
[_shape])
|
[shape]
|
||||||
|
|
||||||
(defn translate-layout-sizing
|
(let [dir (-> (or (dm/get-prop shape :layout-grid-dir) :row) sr/translate-layout-grid-dir)
|
||||||
[value]
|
gap (dm/get-prop shape :layout-gap)
|
||||||
(case value
|
row-gap (or (dm/get-prop gap :row-gap) 0)
|
||||||
:fill 0
|
column-gap (or (dm/get-prop gap :column-gap) 0)
|
||||||
:fix 1
|
|
||||||
:auto 2))
|
|
||||||
|
|
||||||
(defn translate-align-self
|
align-items (-> (or (dm/get-prop shape :layout-align-items) :start) sr/translate-layout-align-items)
|
||||||
[value]
|
align-content (-> (or (dm/get-prop shape :layout-align-content) :stretch) sr/translate-layout-align-content)
|
||||||
(when value
|
justify-items (-> (or (dm/get-prop shape :layout-justify-items) :start) sr/translate-layout-justify-items)
|
||||||
(case value
|
justify-content (-> (or (dm/get-prop shape :layout-justify-content) :stretch) sr/translate-layout-justify-content)
|
||||||
:start 0
|
|
||||||
:end 1
|
padding (dm/get-prop shape :layout-padding)
|
||||||
:center 2
|
padding-top (or (dm/get-prop padding :p1) 0)
|
||||||
:stretch 3)))
|
padding-right (or (dm/get-prop padding :p2) 0)
|
||||||
|
padding-bottom (or (dm/get-prop padding :p3) 0)
|
||||||
|
padding-left (or (dm/get-prop padding :p4) 0)]
|
||||||
|
|
||||||
|
(h/call internal-module
|
||||||
|
"_set_grid_layout_data"
|
||||||
|
dir
|
||||||
|
row-gap
|
||||||
|
column-gap
|
||||||
|
align-items
|
||||||
|
align-content
|
||||||
|
justify-items
|
||||||
|
justify-content
|
||||||
|
padding-top
|
||||||
|
padding-right
|
||||||
|
padding-bottom
|
||||||
|
padding-left))
|
||||||
|
|
||||||
|
;; Send Rows
|
||||||
|
(let [entry-size 5
|
||||||
|
entries (:layout-grid-rows shape)
|
||||||
|
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||||
|
|
||||||
|
heap
|
||||||
|
(js/Uint8Array.
|
||||||
|
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||||
|
ptr
|
||||||
|
(* entry-size (count entries)))]
|
||||||
|
(loop [entries (seq entries)
|
||||||
|
offset 0]
|
||||||
|
(when-not (empty? entries)
|
||||||
|
(let [{:keys [type value]} (first entries)]
|
||||||
|
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ offset 0))
|
||||||
|
(.set heap (sr/f32->u8 value) (+ offset 1))
|
||||||
|
(recur (rest entries) (+ offset entry-size)))))
|
||||||
|
(h/call internal-module "_set_grid_rows"))
|
||||||
|
|
||||||
|
;; Send Columns
|
||||||
|
(let [entry-size 5
|
||||||
|
entries (:layout-grid-columns shape)
|
||||||
|
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||||
|
|
||||||
|
heap
|
||||||
|
(js/Uint8Array.
|
||||||
|
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||||
|
ptr
|
||||||
|
(* entry-size (count entries)))]
|
||||||
|
(loop [entries (seq entries)
|
||||||
|
offset 0]
|
||||||
|
(when-not (empty? entries)
|
||||||
|
(let [{:keys [type value]} (first entries)]
|
||||||
|
(.set heap (sr/u8 (sr/translate-grid-track-type type)) (+ offset 0))
|
||||||
|
(.set heap (sr/f32->u8 value) (+ offset 1))
|
||||||
|
(recur (rest entries) (+ offset entry-size)))))
|
||||||
|
(h/call internal-module "_set_grid_columns"))
|
||||||
|
|
||||||
|
;; Send cells
|
||||||
|
(let [entry-size 37
|
||||||
|
entries (-> shape :layout-grid-cells vals)
|
||||||
|
ptr (h/call internal-module "_alloc_bytes" (* entry-size (count entries)))
|
||||||
|
|
||||||
|
heap
|
||||||
|
(js/Uint8Array.
|
||||||
|
(.-buffer (gobj/get ^js internal-module "HEAPU8"))
|
||||||
|
ptr
|
||||||
|
(* entry-size (count entries)))]
|
||||||
|
|
||||||
|
(loop [entries (seq entries)
|
||||||
|
offset 0]
|
||||||
|
(when-not (empty? entries)
|
||||||
|
(let [cell (first entries)]
|
||||||
|
|
||||||
|
;; row: [u8; 4],
|
||||||
|
(.set heap (sr/i32->u8 (:row cell)) (+ offset 0))
|
||||||
|
|
||||||
|
;; row_span: [u8; 4],
|
||||||
|
(.set heap (sr/i32->u8 (:row-span cell)) (+ offset 4))
|
||||||
|
|
||||||
|
;; column: [u8; 4],
|
||||||
|
(.set heap (sr/i32->u8 (:column cell)) (+ offset 8))
|
||||||
|
|
||||||
|
;; column_span: [u8; 4],
|
||||||
|
(.set heap (sr/i32->u8 (:column-span cell)) (+ offset 12))
|
||||||
|
|
||||||
|
;; has_align_self: u8,
|
||||||
|
(.set heap (sr/bool->u8 (some? (:align-self cell))) (+ offset 16))
|
||||||
|
|
||||||
|
;; align_self: u8,
|
||||||
|
(.set heap (sr/u8 (sr/translate-align-self (:align-self cell))) (+ offset 17))
|
||||||
|
|
||||||
|
;; has_justify_self: u8,
|
||||||
|
(.set heap (sr/bool->u8 (some? (:justify-self cell))) (+ offset 18))
|
||||||
|
|
||||||
|
;; justify_self: u8,
|
||||||
|
(.set heap (sr/u8 (sr/translate-justify-self (:justify-self cell))) (+ offset 19))
|
||||||
|
|
||||||
|
;; has_shape_id: u8,
|
||||||
|
(.set heap (sr/bool->u8 (d/not-empty? (:shapes cell))) (+ offset 20))
|
||||||
|
|
||||||
|
;; shape_id_a: [u8; 4],
|
||||||
|
;; shape_id_b: [u8; 4],
|
||||||
|
;; shape_id_c: [u8; 4],
|
||||||
|
;; shape_id_d: [u8; 4],
|
||||||
|
(.set heap (sr/uuid->u8 (or (-> cell :shapes first) uuid/zero)) (+ offset 21))
|
||||||
|
|
||||||
|
(recur (rest entries) (+ offset entry-size)))))
|
||||||
|
|
||||||
|
(h/call internal-module "_set_grid_cells")))
|
||||||
|
|
||||||
(defn set-layout-child
|
(defn set-layout-child
|
||||||
[shape]
|
[shape]
|
||||||
|
@ -640,9 +604,9 @@
|
||||||
margin-bottom (or (dm/get-prop margins :m3) 0)
|
margin-bottom (or (dm/get-prop margins :m3) 0)
|
||||||
margin-left (or (dm/get-prop margins :m4) 0)
|
margin-left (or (dm/get-prop margins :m4) 0)
|
||||||
|
|
||||||
h-sizing (-> (dm/get-prop shape :layout-item-h-sizing) (or :fix) translate-layout-sizing)
|
h-sizing (-> (dm/get-prop shape :layout-item-h-sizing) (or :fix) sr/translate-layout-sizing)
|
||||||
v-sizing (-> (dm/get-prop shape :layout-item-v-sizing) (or :fix) translate-layout-sizing)
|
v-sizing (-> (dm/get-prop shape :layout-item-v-sizing) (or :fix) sr/translate-layout-sizing)
|
||||||
align-self (-> (dm/get-prop shape :layout-item-align-self) translate-align-self)
|
align-self (-> (dm/get-prop shape :layout-item-align-self) sr/translate-align-self)
|
||||||
|
|
||||||
max-h (dm/get-prop shape :layout-item-max-h)
|
max-h (dm/get-prop shape :layout-item-max-h)
|
||||||
has-max-h (some? max-h)
|
has-max-h (some? max-h)
|
||||||
|
@ -675,13 +639,6 @@
|
||||||
is-absolute
|
is-absolute
|
||||||
z-index)))
|
z-index)))
|
||||||
|
|
||||||
(defn- translate-shadow-style
|
|
||||||
[style]
|
|
||||||
(case style
|
|
||||||
:drop-shadow 0
|
|
||||||
:inner-shadow 1
|
|
||||||
0))
|
|
||||||
|
|
||||||
(defn set-shape-shadows
|
(defn set-shape-shadows
|
||||||
[shadows]
|
[shadows]
|
||||||
(h/call internal-module "_clear_shape_shadows")
|
(h/call internal-module "_clear_shape_shadows")
|
||||||
|
@ -697,7 +654,7 @@
|
||||||
y (dm/get-prop shadow :offset-y)
|
y (dm/get-prop shadow :offset-y)
|
||||||
spread (dm/get-prop shadow :spread)
|
spread (dm/get-prop shadow :spread)
|
||||||
style (dm/get-prop shadow :style)]
|
style (dm/get-prop shadow :style)]
|
||||||
(h/call internal-module "_add_shape_shadow" rgba blur spread x y (translate-shadow-style style) hidden)
|
(h/call internal-module "_add_shape_shadow" rgba blur spread x y (sr/translate-shadow-style style) hidden)
|
||||||
(recur (inc index)))))))
|
(recur (inc index)))))))
|
||||||
|
|
||||||
(defn utf8->buffer [text]
|
(defn utf8->buffer [text]
|
||||||
|
@ -898,24 +855,6 @@
|
||||||
(clear-drawing-cache)
|
(clear-drawing-cache)
|
||||||
(request-render "set-objects")))))))
|
(request-render "set-objects")))))))
|
||||||
|
|
||||||
(defn uuid->u8
|
|
||||||
[id]
|
|
||||||
(let [buffer (uuid/get-u32 id)
|
|
||||||
u32-arr (js/Uint32Array. 4)]
|
|
||||||
(doseq [i (range 0 4)]
|
|
||||||
(aset u32-arr i (aget buffer i)))
|
|
||||||
(js/Uint8Array. (.-buffer u32-arr))))
|
|
||||||
|
|
||||||
(defn matrix->u8
|
|
||||||
[{:keys [a b c d e f]}]
|
|
||||||
(let [f32-arr (js/Float32Array. 6)]
|
|
||||||
(aset f32-arr 0 a)
|
|
||||||
(aset f32-arr 1 b)
|
|
||||||
(aset f32-arr 2 c)
|
|
||||||
(aset f32-arr 3 d)
|
|
||||||
(aset f32-arr 4 e)
|
|
||||||
(aset f32-arr 5 f)
|
|
||||||
(js/Uint8Array. (.-buffer f32-arr))))
|
|
||||||
|
|
||||||
(defn data->entry
|
(defn data->entry
|
||||||
[data offset]
|
[data offset]
|
||||||
|
@ -951,8 +890,8 @@
|
||||||
offset 0]
|
offset 0]
|
||||||
(when-not (empty? entries)
|
(when-not (empty? entries)
|
||||||
(let [{:keys [id transform]} (first entries)]
|
(let [{:keys [id transform]} (first entries)]
|
||||||
(.set heap (uuid->u8 id) offset)
|
(.set heap (sr/uuid->u8 id) offset)
|
||||||
(.set heap (matrix->u8 transform) (+ offset 16))
|
(.set heap (sr/matrix->u8 transform) (+ offset 16))
|
||||||
(recur (rest entries) (+ offset entry-size)))))
|
(recur (rest entries) (+ offset entry-size)))))
|
||||||
|
|
||||||
(let [result-ptr (h/call internal-module "_propagate_modifiers")
|
(let [result-ptr (h/call internal-module "_propagate_modifiers")
|
||||||
|
@ -991,8 +930,8 @@
|
||||||
offset 0]
|
offset 0]
|
||||||
(when-not (empty? entries)
|
(when-not (empty? entries)
|
||||||
(let [{:keys [id transform]} (first entries)]
|
(let [{:keys [id transform]} (first entries)]
|
||||||
(.set heap (uuid->u8 id) offset)
|
(.set heap (sr/uuid->u8 id) offset)
|
||||||
(.set heap (matrix->u8 transform) (+ offset 16))
|
(.set heap (sr/matrix->u8 transform) (+ offset 16))
|
||||||
(recur (rest entries) (+ offset ENTRY_SIZE)))))
|
(recur (rest entries) (+ offset ENTRY_SIZE)))))
|
||||||
|
|
||||||
(h/call internal-module "_set_modifiers")
|
(h/call internal-module "_set_modifiers")
|
||||||
|
|
253
frontend/src/app/render_wasm/serializers.cljs
Normal file
253
frontend/src/app/render_wasm/serializers.cljs
Normal file
|
@ -0,0 +1,253 @@
|
||||||
|
;; 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) KALEIDOS INC
|
||||||
|
|
||||||
|
(ns app.render-wasm.serializers
|
||||||
|
(:require
|
||||||
|
[app.common.uuid :as uuid]
|
||||||
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
|
(defn u8
|
||||||
|
[value]
|
||||||
|
(let [u8-arr (js/Uint8Array. 1)]
|
||||||
|
(aset u8-arr 0 value)
|
||||||
|
u8-arr))
|
||||||
|
|
||||||
|
(defn f32->u8
|
||||||
|
[value]
|
||||||
|
(let [f32-arr (js/Float32Array. 1)]
|
||||||
|
(aset f32-arr 0 value)
|
||||||
|
(js/Uint8Array. (.-buffer f32-arr))))
|
||||||
|
|
||||||
|
(defn i32->u8
|
||||||
|
[value]
|
||||||
|
(let [i32-arr (js/Int32Array. 1)]
|
||||||
|
(aset i32-arr 0 value)
|
||||||
|
(js/Uint8Array. (.-buffer i32-arr))))
|
||||||
|
|
||||||
|
(defn bool->u8
|
||||||
|
[value]
|
||||||
|
(let [result (js/Uint8Array. 1)]
|
||||||
|
(aset result 0 (if value 1 0))
|
||||||
|
result))
|
||||||
|
|
||||||
|
(defn uuid->u8
|
||||||
|
[id]
|
||||||
|
(let [buffer (uuid/get-u32 id)
|
||||||
|
u32-arr (js/Uint32Array. 4)]
|
||||||
|
(aset u32-arr 0 (aget buffer 0))
|
||||||
|
(aset u32-arr 1 (aget buffer 1))
|
||||||
|
(aset u32-arr 2 (aget buffer 2))
|
||||||
|
(aset u32-arr 3 (aget buffer 3))
|
||||||
|
(js/Uint8Array. (.-buffer u32-arr))))
|
||||||
|
|
||||||
|
(defn matrix->u8
|
||||||
|
[{:keys [a b c d e f]}]
|
||||||
|
(let [f32-arr (js/Float32Array. 6)]
|
||||||
|
(aset f32-arr 0 a)
|
||||||
|
(aset f32-arr 1 b)
|
||||||
|
(aset f32-arr 2 c)
|
||||||
|
(aset f32-arr 3 d)
|
||||||
|
(aset f32-arr 4 e)
|
||||||
|
(aset f32-arr 5 f)
|
||||||
|
(js/Uint8Array. (.-buffer f32-arr))))
|
||||||
|
|
||||||
|
(defn translate-shape-type
|
||||||
|
[type]
|
||||||
|
(case type
|
||||||
|
:frame 0
|
||||||
|
:group 1
|
||||||
|
:bool 2
|
||||||
|
:rect 3
|
||||||
|
:path 4
|
||||||
|
:text 5
|
||||||
|
:circle 6
|
||||||
|
:svg-raw 7
|
||||||
|
:image 8))
|
||||||
|
|
||||||
|
(defn translate-stroke-style
|
||||||
|
[stroke-style]
|
||||||
|
(case stroke-style
|
||||||
|
:dotted 1
|
||||||
|
:dashed 2
|
||||||
|
:mixed 3
|
||||||
|
0))
|
||||||
|
|
||||||
|
(defn translate-stroke-cap
|
||||||
|
[stroke-cap]
|
||||||
|
(case stroke-cap
|
||||||
|
:line-arrow 1
|
||||||
|
:triangle-arrow 2
|
||||||
|
:square-marker 3
|
||||||
|
:circle-marker 4
|
||||||
|
:diamond-marker 5
|
||||||
|
:round 6
|
||||||
|
:square 7
|
||||||
|
0))
|
||||||
|
|
||||||
|
|
||||||
|
(defn serialize-path-attrs
|
||||||
|
[svg-attrs]
|
||||||
|
(reduce
|
||||||
|
(fn [acc [key value]]
|
||||||
|
(str/concat
|
||||||
|
acc
|
||||||
|
(str/kebab key) "\0"
|
||||||
|
value "\0")) "" svg-attrs))
|
||||||
|
|
||||||
|
(defn translate-blend-mode
|
||||||
|
[blend-mode]
|
||||||
|
(case blend-mode
|
||||||
|
:normal 3
|
||||||
|
:darken 16
|
||||||
|
:multiply 24
|
||||||
|
:color-burn 19
|
||||||
|
:lighten 17
|
||||||
|
:screen 14
|
||||||
|
:color-dodge 18
|
||||||
|
:overlay 15
|
||||||
|
:soft-light 21
|
||||||
|
:hard-light 20
|
||||||
|
:difference 22
|
||||||
|
:exclusion 23
|
||||||
|
:hue 25
|
||||||
|
:saturation 26
|
||||||
|
:color 27
|
||||||
|
:luminosity 28
|
||||||
|
3))
|
||||||
|
|
||||||
|
(defn translate-constraint-h
|
||||||
|
[type]
|
||||||
|
(case type
|
||||||
|
:left 0
|
||||||
|
:right 1
|
||||||
|
:leftright 2
|
||||||
|
:center 3
|
||||||
|
:scale 4))
|
||||||
|
|
||||||
|
(defn translate-constraint-v
|
||||||
|
[type]
|
||||||
|
(case type
|
||||||
|
:top 0
|
||||||
|
:bottom 1
|
||||||
|
:topbottom 2
|
||||||
|
:center 3
|
||||||
|
:scale 4))
|
||||||
|
|
||||||
|
(defn translate-bool-type
|
||||||
|
[bool-type]
|
||||||
|
(case bool-type
|
||||||
|
:union 0
|
||||||
|
:difference 1
|
||||||
|
:intersection 2
|
||||||
|
:exclusion 3
|
||||||
|
0))
|
||||||
|
|
||||||
|
(defn translate-blur-type
|
||||||
|
[blur-type]
|
||||||
|
(case blur-type
|
||||||
|
:layer-blur 1
|
||||||
|
0))
|
||||||
|
|
||||||
|
(defn translate-layout-flex-dir
|
||||||
|
[flex-dir]
|
||||||
|
(case flex-dir
|
||||||
|
:row 0
|
||||||
|
:row-reverse 1
|
||||||
|
:column 2
|
||||||
|
:column-reverse 3))
|
||||||
|
|
||||||
|
(defn translate-layout-grid-dir
|
||||||
|
[flex-dir]
|
||||||
|
(case flex-dir
|
||||||
|
:row 0
|
||||||
|
:column 1))
|
||||||
|
|
||||||
|
(defn translate-layout-align-items
|
||||||
|
[align-items]
|
||||||
|
(case align-items
|
||||||
|
:start 0
|
||||||
|
:end 1
|
||||||
|
:center 2
|
||||||
|
:stretch 3))
|
||||||
|
|
||||||
|
(defn translate-layout-align-content
|
||||||
|
[align-content]
|
||||||
|
(case align-content
|
||||||
|
:start 0
|
||||||
|
:end 1
|
||||||
|
:center 2
|
||||||
|
:space-between 3
|
||||||
|
:space-around 4
|
||||||
|
:space-evenly 5
|
||||||
|
:stretch 6))
|
||||||
|
|
||||||
|
(defn translate-layout-justify-items
|
||||||
|
[justify-items]
|
||||||
|
(case justify-items
|
||||||
|
:start 0
|
||||||
|
:end 1
|
||||||
|
:center 2
|
||||||
|
:stretch 3))
|
||||||
|
|
||||||
|
(defn translate-layout-justify-content
|
||||||
|
[justify-content]
|
||||||
|
(case justify-content
|
||||||
|
:start 0
|
||||||
|
:end 1
|
||||||
|
:center 2
|
||||||
|
:space-between 3
|
||||||
|
:space-around 4
|
||||||
|
:space-evenly 5
|
||||||
|
:stretch 6))
|
||||||
|
|
||||||
|
(defn translate-layout-wrap-type
|
||||||
|
[wrap-type]
|
||||||
|
(case wrap-type
|
||||||
|
:wrap 0
|
||||||
|
:nowrap 1))
|
||||||
|
|
||||||
|
(defn translate-grid-track-type
|
||||||
|
[type]
|
||||||
|
(case type
|
||||||
|
:percent 0
|
||||||
|
:flex 1
|
||||||
|
:auto 2
|
||||||
|
:fixed 3))
|
||||||
|
|
||||||
|
(defn translate-layout-sizing
|
||||||
|
[value]
|
||||||
|
(case value
|
||||||
|
:fill 0
|
||||||
|
:fix 1
|
||||||
|
:auto 2))
|
||||||
|
|
||||||
|
(defn translate-align-self
|
||||||
|
[value]
|
||||||
|
(when value
|
||||||
|
(case value
|
||||||
|
:auto 0
|
||||||
|
:start 1
|
||||||
|
:end 2
|
||||||
|
:center 3
|
||||||
|
:stretch 4)))
|
||||||
|
|
||||||
|
(defn translate-justify-self
|
||||||
|
[value]
|
||||||
|
(when value
|
||||||
|
(case value
|
||||||
|
:auto 0
|
||||||
|
:start 1
|
||||||
|
:end 2
|
||||||
|
:center 3
|
||||||
|
:stretch 4)))
|
||||||
|
|
||||||
|
(defn translate-shadow-style
|
||||||
|
[style]
|
||||||
|
(case style
|
||||||
|
:drop-shadow 0
|
||||||
|
:inner-shadow 1
|
||||||
|
0))
|
||||||
|
|
|
@ -142,7 +142,7 @@ Shadow styles are serialized as `u8`:
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
### Direction
|
### Flex Direction
|
||||||
|
|
||||||
| Value | Field |
|
| Value | Field |
|
||||||
| ----- | ------------- |
|
| ----- | ------------- |
|
||||||
|
@ -152,6 +152,14 @@ Shadow styles are serialized as `u8`:
|
||||||
| 3 | ColumnReverse |
|
| 3 | ColumnReverse |
|
||||||
| \_ | error |
|
| \_ | error |
|
||||||
|
|
||||||
|
### Grid Direction
|
||||||
|
|
||||||
|
| Value | Field |
|
||||||
|
| ----- | ------------- |
|
||||||
|
| 0 | Row |
|
||||||
|
| 1 | Column |
|
||||||
|
| \_ | error |
|
||||||
|
|
||||||
### Align Items
|
### Align Items
|
||||||
|
|
||||||
| Value | Field |
|
| Value | Field |
|
||||||
|
@ -208,6 +216,28 @@ Shadow styles are serialized as `u8`:
|
||||||
| 6 | Stretch |
|
| 6 | Stretch |
|
||||||
| \_ | error |
|
| \_ | error |
|
||||||
|
|
||||||
|
### Align Self
|
||||||
|
|
||||||
|
| Value | Field |
|
||||||
|
| ----- | ------- |
|
||||||
|
| 0 | Auto |
|
||||||
|
| 1 | Start |
|
||||||
|
| 2 | End |
|
||||||
|
| 3 | Center |
|
||||||
|
| 4 | Stretch |
|
||||||
|
| \_ | error |
|
||||||
|
|
||||||
|
### Justify Self
|
||||||
|
|
||||||
|
| Value | Field |
|
||||||
|
| ----- | ------- |
|
||||||
|
| 0 | Auto |
|
||||||
|
| 1 | Start |
|
||||||
|
| 2 | End |
|
||||||
|
| 3 | Center |
|
||||||
|
| 4 | Stretch |
|
||||||
|
| \_ | error |
|
||||||
|
|
||||||
### Wrap type
|
### Wrap type
|
||||||
|
|
||||||
| Value | Field |
|
| Value | Field |
|
||||||
|
@ -225,6 +255,18 @@ Shadow styles are serialized as `u8`:
|
||||||
| 2 | Auto |
|
| 2 | Auto |
|
||||||
| \_ | error |
|
| \_ | error |
|
||||||
|
|
||||||
|
### Grid Track Type
|
||||||
|
|
||||||
|
| Value | Field |
|
||||||
|
| ----- | ------- |
|
||||||
|
| 0 | Percent |
|
||||||
|
| 1 | Flex |
|
||||||
|
| 2 | Auto |
|
||||||
|
| 3 | Fixed |
|
||||||
|
| \_ | error |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Font
|
## Font
|
||||||
|
|
||||||
### Style
|
### Style
|
||||||
|
|
|
@ -636,7 +636,7 @@ pub extern "C" fn set_flex_layout_data(
|
||||||
padding_bottom: f32,
|
padding_bottom: f32,
|
||||||
padding_left: f32,
|
padding_left: f32,
|
||||||
) {
|
) {
|
||||||
let dir = shapes::Direction::from_u8(dir);
|
let dir = shapes::FlexDirection::from_u8(dir);
|
||||||
let align_items = shapes::AlignItems::from_u8(align_items);
|
let align_items = shapes::AlignItems::from_u8(align_items);
|
||||||
let align_content = shapes::AlignContent::from_u8(align_content);
|
let align_content = shapes::AlignContent::from_u8(align_content);
|
||||||
let justify_items = shapes::JustifyItems::from_u8(justify_items);
|
let justify_items = shapes::JustifyItems::from_u8(justify_items);
|
||||||
|
@ -714,13 +714,89 @@ pub extern "C" fn set_layout_child_data(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn set_grid_layout_data() {}
|
pub extern "C" fn set_grid_layout_data(
|
||||||
|
dir: u8,
|
||||||
|
row_gap: f32,
|
||||||
|
column_gap: f32,
|
||||||
|
align_items: u8,
|
||||||
|
align_content: u8,
|
||||||
|
justify_items: u8,
|
||||||
|
justify_content: u8,
|
||||||
|
padding_top: f32,
|
||||||
|
padding_right: f32,
|
||||||
|
padding_bottom: f32,
|
||||||
|
padding_left: f32,
|
||||||
|
) {
|
||||||
|
let dir = shapes::GridDirection::from_u8(dir);
|
||||||
|
let align_items = shapes::AlignItems::from_u8(align_items);
|
||||||
|
let align_content = shapes::AlignContent::from_u8(align_content);
|
||||||
|
let justify_items = shapes::JustifyItems::from_u8(justify_items);
|
||||||
|
let justify_content = shapes::JustifyContent::from_u8(justify_content);
|
||||||
|
|
||||||
|
with_current_shape!(state, |shape: &mut Shape| {
|
||||||
|
shape.set_grid_layout_data(
|
||||||
|
dir,
|
||||||
|
row_gap,
|
||||||
|
column_gap,
|
||||||
|
align_items,
|
||||||
|
align_content,
|
||||||
|
justify_items,
|
||||||
|
justify_content,
|
||||||
|
padding_top,
|
||||||
|
padding_right,
|
||||||
|
padding_bottom,
|
||||||
|
padding_left,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn add_grid_track() {}
|
pub extern "C" fn set_grid_columns() {
|
||||||
|
let bytes = mem::bytes();
|
||||||
|
|
||||||
|
let entries: Vec<_> = bytes
|
||||||
|
.chunks(size_of::<shapes::RawGridTrack>())
|
||||||
|
.map(|data| shapes::RawGridTrack::from_bytes(data.try_into().unwrap()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
with_current_shape!(state, |shape: &mut Shape| {
|
||||||
|
shape.set_grid_columns(entries);
|
||||||
|
});
|
||||||
|
|
||||||
|
mem::free_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn set_grid_cell() {}
|
pub extern "C" fn set_grid_rows() {
|
||||||
|
let bytes = mem::bytes();
|
||||||
|
|
||||||
|
let entries: Vec<_> = bytes
|
||||||
|
.chunks(size_of::<shapes::RawGridTrack>())
|
||||||
|
.map(|data| shapes::RawGridTrack::from_bytes(data.try_into().unwrap()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
with_current_shape!(state, |shape: &mut Shape| {
|
||||||
|
shape.set_grid_rows(entries);
|
||||||
|
});
|
||||||
|
|
||||||
|
mem::free_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn set_grid_cells() {
|
||||||
|
let bytes = mem::bytes();
|
||||||
|
|
||||||
|
let entries: Vec<_> = bytes
|
||||||
|
.chunks(size_of::<shapes::RawGridCell>())
|
||||||
|
.map(|data| shapes::RawGridCell::from_bytes(data.try_into().unwrap()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
with_current_shape!(state, |shape: &mut Shape| {
|
||||||
|
shape.set_grid_cells(entries);
|
||||||
|
});
|
||||||
|
|
||||||
|
mem::free_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
init_gl!();
|
init_gl!();
|
||||||
|
|
|
@ -318,7 +318,7 @@ impl Shape {
|
||||||
|
|
||||||
pub fn set_flex_layout_data(
|
pub fn set_flex_layout_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
direction: Direction,
|
direction: FlexDirection,
|
||||||
row_gap: f32,
|
row_gap: f32,
|
||||||
column_gap: f32,
|
column_gap: f32,
|
||||||
align_items: AlignItems,
|
align_items: AlignItems,
|
||||||
|
@ -334,7 +334,6 @@ impl Shape {
|
||||||
match &mut self.shape_type {
|
match &mut self.shape_type {
|
||||||
Type::Frame(data) => {
|
Type::Frame(data) => {
|
||||||
let layout_data = LayoutData {
|
let layout_data = LayoutData {
|
||||||
direction,
|
|
||||||
align_items,
|
align_items,
|
||||||
align_content,
|
align_content,
|
||||||
justify_items,
|
justify_items,
|
||||||
|
@ -343,11 +342,12 @@ impl Shape {
|
||||||
padding_right,
|
padding_right,
|
||||||
padding_bottom,
|
padding_bottom,
|
||||||
padding_left,
|
padding_left,
|
||||||
|
row_gap,
|
||||||
|
column_gap,
|
||||||
};
|
};
|
||||||
|
|
||||||
let flex_data = FlexData {
|
let flex_data = FlexData {
|
||||||
row_gap,
|
direction,
|
||||||
column_gap,
|
|
||||||
wrap_type,
|
wrap_type,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,6 +357,73 @@ impl Shape {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_grid_layout_data(
|
||||||
|
&mut self,
|
||||||
|
direction: GridDirection,
|
||||||
|
row_gap: f32,
|
||||||
|
column_gap: f32,
|
||||||
|
align_items: AlignItems,
|
||||||
|
align_content: AlignContent,
|
||||||
|
justify_items: JustifyItems,
|
||||||
|
justify_content: JustifyContent,
|
||||||
|
padding_top: f32,
|
||||||
|
padding_right: f32,
|
||||||
|
padding_bottom: f32,
|
||||||
|
padding_left: f32,
|
||||||
|
) {
|
||||||
|
match &mut self.shape_type {
|
||||||
|
Type::Frame(data) => {
|
||||||
|
let layout_data = LayoutData {
|
||||||
|
align_items,
|
||||||
|
align_content,
|
||||||
|
justify_items,
|
||||||
|
justify_content,
|
||||||
|
padding_top,
|
||||||
|
padding_right,
|
||||||
|
padding_bottom,
|
||||||
|
padding_left,
|
||||||
|
row_gap,
|
||||||
|
column_gap,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut grid_data = GridData::default();
|
||||||
|
grid_data.direction = direction;
|
||||||
|
data.layout = Some(Layout::GridLayout(layout_data, grid_data));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_grid_columns(&mut self, tracks: Vec<RawGridTrack>) {
|
||||||
|
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
grid_data.columns = tracks.iter().map(GridTrack::from_raw).collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_grid_rows(&mut self, tracks: Vec<RawGridTrack>) {
|
||||||
|
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
grid_data.rows = tracks.iter().map(GridTrack::from_raw).collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_grid_cells(&mut self, cells: Vec<RawGridCell>) {
|
||||||
|
let Type::Frame(frame_data) = &mut self.shape_type else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(Layout::GridLayout(_, grid_data)) = &mut frame_data.layout else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
grid_data.cells = cells.iter().map(GridCell::from_raw).collect();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_blur(&mut self, blur_type: u8, hidden: bool, value: f32) {
|
pub fn set_blur(&mut self, blur_type: u8, hidden: bool, value: f32) {
|
||||||
self.blur = Blur::new(blur_type, hidden, value);
|
self.blur = Blur::new(blur_type, hidden, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
use crate::utils::uuid_from_u32_quartet;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum Layout {
|
pub enum Layout {
|
||||||
|
@ -6,14 +9,14 @@ pub enum Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Direction {
|
pub enum FlexDirection {
|
||||||
Row,
|
Row,
|
||||||
RowReverse,
|
RowReverse,
|
||||||
Column,
|
Column,
|
||||||
ColumnReverse,
|
ColumnReverse,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Direction {
|
impl FlexDirection {
|
||||||
pub fn from_u8(value: u8) -> Self {
|
pub fn from_u8(value: u8) -> Self {
|
||||||
match value {
|
match value {
|
||||||
0 => Self::Row,
|
0 => Self::Row,
|
||||||
|
@ -25,6 +28,22 @@ impl Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum GridDirection {
|
||||||
|
Row,
|
||||||
|
Column,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridDirection {
|
||||||
|
pub fn from_u8(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::Row,
|
||||||
|
1 => Self::Column,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum AlignItems {
|
pub enum AlignItems {
|
||||||
Start,
|
Start,
|
||||||
|
@ -132,9 +151,82 @@ impl WrapType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum GridTrackType {
|
||||||
|
Percent,
|
||||||
|
Flex,
|
||||||
|
Auto,
|
||||||
|
Fixed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridTrackType {
|
||||||
|
pub fn from_u8(value: u8) -> Self {
|
||||||
|
match value {
|
||||||
|
0 => Self::Percent,
|
||||||
|
1 => Self::Flex,
|
||||||
|
2 => Self::Auto,
|
||||||
|
3 => Self::Fixed,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct GridTrack {}
|
pub struct GridTrack {
|
||||||
|
track_type: GridTrackType,
|
||||||
|
value: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridTrack {
|
||||||
|
pub fn from_raw(raw: &RawGridTrack) -> Self {
|
||||||
|
Self {
|
||||||
|
track_type: GridTrackType::from_u8(raw.track_type),
|
||||||
|
value: f32::from_le_bytes(raw.value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct GridCell {
|
||||||
|
row: i32,
|
||||||
|
row_span: i32,
|
||||||
|
column: i32,
|
||||||
|
column_span: i32,
|
||||||
|
align_self: Option<AlignSelf>,
|
||||||
|
justify_self: Option<JustifySelf>,
|
||||||
|
shape: Option<Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridCell {
|
||||||
|
pub fn from_raw(raw: &RawGridCell) -> Self {
|
||||||
|
Self {
|
||||||
|
row: i32::from_le_bytes(raw.row),
|
||||||
|
row_span: i32::from_le_bytes(raw.row_span),
|
||||||
|
column: i32::from_le_bytes(raw.column),
|
||||||
|
column_span: i32::from_le_bytes(raw.column_span),
|
||||||
|
align_self: if raw.has_align_self == 1 {
|
||||||
|
AlignSelf::from_u8(raw.align_self)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
justify_self: if raw.has_justify_self == 1 {
|
||||||
|
JustifySelf::from_u8(raw.justify_self)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
shape: if raw.has_shape_id == 1 {
|
||||||
|
Some(uuid_from_u32_quartet(
|
||||||
|
u32::from_le_bytes(raw.shape_id_a),
|
||||||
|
u32::from_le_bytes(raw.shape_id_b),
|
||||||
|
u32::from_le_bytes(raw.shape_id_c),
|
||||||
|
u32::from_le_bytes(raw.shape_id_d),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||||
pub enum Sizing {
|
pub enum Sizing {
|
||||||
|
@ -156,7 +248,6 @@ impl Sizing {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct LayoutData {
|
pub struct LayoutData {
|
||||||
pub direction: Direction,
|
|
||||||
pub align_items: AlignItems,
|
pub align_items: AlignItems,
|
||||||
pub align_content: AlignContent,
|
pub align_content: AlignContent,
|
||||||
pub justify_items: JustifyItems,
|
pub justify_items: JustifyItems,
|
||||||
|
@ -165,33 +256,13 @@ pub struct LayoutData {
|
||||||
pub padding_right: f32,
|
pub padding_right: f32,
|
||||||
pub padding_bottom: f32,
|
pub padding_bottom: f32,
|
||||||
pub padding_left: f32,
|
pub padding_left: f32,
|
||||||
}
|
pub row_gap: f32,
|
||||||
|
pub column_gap: f32,
|
||||||
impl LayoutData {
|
|
||||||
pub fn is_reverse(&self) -> bool {
|
|
||||||
match &self.direction {
|
|
||||||
Direction::RowReverse | Direction::ColumnReverse => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn is_row(&self) -> bool {
|
|
||||||
match &self.direction {
|
|
||||||
Direction::RowReverse | Direction::Row => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn is_column(&self) -> bool {
|
|
||||||
match &self.direction {
|
|
||||||
Direction::ColumnReverse | Direction::Column => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum AlignSelf {
|
pub enum AlignSelf {
|
||||||
|
Auto,
|
||||||
Start,
|
Start,
|
||||||
End,
|
End,
|
||||||
Center,
|
Center,
|
||||||
|
@ -201,10 +272,33 @@ pub enum AlignSelf {
|
||||||
impl AlignSelf {
|
impl AlignSelf {
|
||||||
pub fn from_u8(value: u8) -> Option<AlignSelf> {
|
pub fn from_u8(value: u8) -> Option<AlignSelf> {
|
||||||
match value {
|
match value {
|
||||||
0 => Some(Self::Start),
|
0 => Some(Self::Auto),
|
||||||
1 => Some(Self::End),
|
1 => Some(Self::Start),
|
||||||
2 => Some(Self::Center),
|
2 => Some(Self::End),
|
||||||
3 => Some(Self::Stretch),
|
3 => Some(Self::Center),
|
||||||
|
4 => Some(Self::Stretch),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
pub enum JustifySelf {
|
||||||
|
Auto,
|
||||||
|
Start,
|
||||||
|
End,
|
||||||
|
Center,
|
||||||
|
Stretch,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JustifySelf {
|
||||||
|
pub fn from_u8(value: u8) -> Option<JustifySelf> {
|
||||||
|
match value {
|
||||||
|
0 => Some(Self::Auto),
|
||||||
|
1 => Some(Self::Start),
|
||||||
|
2 => Some(Self::End),
|
||||||
|
3 => Some(Self::Center),
|
||||||
|
4 => Some(Self::Stretch),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,11 +306,26 @@ impl AlignSelf {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct FlexData {
|
pub struct FlexData {
|
||||||
pub row_gap: f32,
|
pub direction: FlexDirection,
|
||||||
pub column_gap: f32,
|
|
||||||
pub wrap_type: WrapType,
|
pub wrap_type: WrapType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FlexData {
|
||||||
|
pub fn is_reverse(&self) -> bool {
|
||||||
|
match &self.direction {
|
||||||
|
FlexDirection::RowReverse | FlexDirection::ColumnReverse => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_row(&self) -> bool {
|
||||||
|
match &self.direction {
|
||||||
|
FlexDirection::RowReverse | FlexDirection::Row => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FlexData {
|
impl FlexData {
|
||||||
pub fn is_wrap(&self) -> bool {
|
pub fn is_wrap(&self) -> bool {
|
||||||
match self.wrap_type {
|
match self.wrap_type {
|
||||||
|
@ -228,9 +337,78 @@ impl FlexData {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct GridData {
|
pub struct GridData {
|
||||||
|
pub direction: GridDirection,
|
||||||
pub rows: Vec<GridTrack>,
|
pub rows: Vec<GridTrack>,
|
||||||
pub columns: Vec<GridTrack>,
|
pub columns: Vec<GridTrack>,
|
||||||
// layout-grid-cells ;; map of id->grid-cell
|
pub cells: Vec<GridCell>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GridData {
|
||||||
|
pub fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
direction: GridDirection::Row,
|
||||||
|
rows: vec![],
|
||||||
|
columns: vec![],
|
||||||
|
cells: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct RawGridTrack {
|
||||||
|
track_type: u8,
|
||||||
|
value: [u8; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawGridTrack {
|
||||||
|
pub fn from_bytes(bytes: [u8; 5]) -> Self {
|
||||||
|
Self {
|
||||||
|
track_type: bytes[0],
|
||||||
|
value: [bytes[1], bytes[2], bytes[3], bytes[4]],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct RawGridCell {
|
||||||
|
row: [u8; 4],
|
||||||
|
row_span: [u8; 4],
|
||||||
|
column: [u8; 4],
|
||||||
|
column_span: [u8; 4],
|
||||||
|
has_align_self: u8,
|
||||||
|
align_self: u8,
|
||||||
|
has_justify_self: u8,
|
||||||
|
justify_self: u8,
|
||||||
|
has_shape_id: u8,
|
||||||
|
shape_id_a: [u8; 4],
|
||||||
|
shape_id_b: [u8; 4],
|
||||||
|
shape_id_c: [u8; 4],
|
||||||
|
shape_id_d: [u8; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawGridCell {
|
||||||
|
pub fn from_bytes(bytes: [u8; 37]) -> Self {
|
||||||
|
Self {
|
||||||
|
row: [bytes[0], bytes[1], bytes[2], bytes[3]],
|
||||||
|
row_span: [bytes[4], bytes[5], bytes[6], bytes[7]],
|
||||||
|
column: [bytes[8], bytes[9], bytes[10], bytes[11]],
|
||||||
|
column_span: [bytes[12], bytes[13], bytes[14], bytes[15]],
|
||||||
|
|
||||||
|
has_align_self: bytes[16],
|
||||||
|
align_self: bytes[17],
|
||||||
|
|
||||||
|
has_justify_self: bytes[18],
|
||||||
|
justify_self: bytes[19],
|
||||||
|
|
||||||
|
has_shape_id: bytes[20],
|
||||||
|
shape_id_a: [bytes[21], bytes[22], bytes[23], bytes[24]],
|
||||||
|
shape_id_b: [bytes[25], bytes[26], bytes[27], bytes[28]],
|
||||||
|
shape_id_c: [bytes[29], bytes[30], bytes[31], bytes[32]],
|
||||||
|
shape_id_d: [bytes[33], bytes[34], bytes[35], bytes[36]],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||||
|
|
|
@ -159,6 +159,8 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut reflow_parent = false;
|
||||||
|
|
||||||
match &shape.shape_type {
|
match &shape.shape_type {
|
||||||
Type::Frame(Frame {
|
Type::Frame(Frame {
|
||||||
layout: Some(_), ..
|
layout: Some(_), ..
|
||||||
|
@ -173,10 +175,17 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
// If this is a fill layout but the parent has not been reflown yet
|
// If this is a fill layout but the parent has not been reflown yet
|
||||||
// we wait for the next iteration for reflow
|
// we wait for the next iteration for reflow
|
||||||
skip_reflow = true;
|
skip_reflow = true;
|
||||||
|
reflow_parent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if shape.is_layout_vertical_auto()
|
||||||
|
|| shape.is_layout_horizontal_auto()
|
||||||
|
{
|
||||||
|
reflow_parent = true;
|
||||||
|
}
|
||||||
|
|
||||||
if !skip_reflow {
|
if !skip_reflow {
|
||||||
layout_reflows.push(id);
|
layout_reflows.push(id);
|
||||||
}
|
}
|
||||||
|
@ -186,6 +195,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
if let Some(child) = shapes.get(&shape.children[0]) {
|
if let Some(child) = shapes.get(&shape.children[0]) {
|
||||||
let child_bounds = bounds.find(&child);
|
let child_bounds = bounds.find(&child);
|
||||||
bounds.insert(shape.id, child_bounds);
|
bounds.insert(shape.id, child_bounds);
|
||||||
|
reflow_parent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::Group(_) => {
|
Type::Group(_) => {
|
||||||
|
@ -193,6 +203,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
calculate_group_bounds(shape, shapes, &bounds)
|
calculate_group_bounds(shape, shapes, &bounds)
|
||||||
{
|
{
|
||||||
bounds.insert(shape.id, shape_bounds);
|
bounds.insert(shape.id, shape_bounds);
|
||||||
|
reflow_parent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Type::Bool(_) => {
|
Type::Bool(_) => {
|
||||||
|
@ -203,6 +214,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
calculate_group_bounds(shape, shapes, &bounds)
|
calculate_group_bounds(shape, shapes, &bounds)
|
||||||
{
|
{
|
||||||
bounds.insert(shape.id, shape_bounds);
|
bounds.insert(shape.id, shape_bounds);
|
||||||
|
reflow_parent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -211,7 +223,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(parent) = shape.parent_id.and_then(|id| shapes.get(&id)) {
|
if let Some(parent) = shape.parent_id.and_then(|id| shapes.get(&id)) {
|
||||||
if parent.has_layout() || parent.is_group_like() {
|
if reflow_parent && (parent.has_layout() || parent.is_group_like()) {
|
||||||
entries.push_back(Modifier::reflow(parent.id));
|
entries.push_back(Modifier::reflow(parent.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,6 +243,7 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
let Type::Frame(frame_data) = &shape.shape_type else {
|
let Type::Frame(frame_data) = &shape.shape_type else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(Layout::FlexLayout(layout_data, flex_data)) = &frame_data.layout {
|
if let Some(Layout::FlexLayout(layout_data, flex_data)) = &frame_data.layout {
|
||||||
let mut children = flex_layout::reflow_flex_layout(
|
let mut children = flex_layout::reflow_flex_layout(
|
||||||
shape,
|
shape,
|
||||||
|
@ -242,11 +255,11 @@ pub fn propagate_modifiers(state: &State, modifiers: Vec<TransformEntry>) -> Vec
|
||||||
entries.append(&mut children);
|
entries.append(&mut children);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(Layout::GridLayout(layout_data, grid_data)) = &frame_data.layout {
|
// if let Some(Layout::GridLayout(layout_data, grid_data)) = &frame_data.layout {
|
||||||
let mut children =
|
// let mut children =
|
||||||
grid_layout::reflow_grid_layout(shape, layout_data, grid_data, shapes, &bounds);
|
// grid_layout::reflow_grid_layout(shape, layout_data, grid_data, shapes, &bounds);
|
||||||
entries.append(&mut children);
|
// entries.append(&mut children);
|
||||||
}
|
// }
|
||||||
reflown.insert(*id);
|
reflown.insert(*id);
|
||||||
}
|
}
|
||||||
layout_reflows = Vec::new();
|
layout_reflows = Vec::new();
|
||||||
|
|
|
@ -67,7 +67,7 @@ impl LayoutAxis {
|
||||||
layout_data: &LayoutData,
|
layout_data: &LayoutData,
|
||||||
flex_data: &FlexData,
|
flex_data: &FlexData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if layout_data.is_row() {
|
if flex_data.is_row() {
|
||||||
Self {
|
Self {
|
||||||
main_size: layout_bounds.width(),
|
main_size: layout_bounds.width(),
|
||||||
across_size: layout_bounds.height(),
|
across_size: layout_bounds.height(),
|
||||||
|
@ -77,8 +77,8 @@ impl LayoutAxis {
|
||||||
padding_main_end: layout_data.padding_right,
|
padding_main_end: layout_data.padding_right,
|
||||||
padding_across_start: layout_data.padding_top,
|
padding_across_start: layout_data.padding_top,
|
||||||
padding_across_end: layout_data.padding_bottom,
|
padding_across_end: layout_data.padding_bottom,
|
||||||
gap_main: flex_data.column_gap,
|
gap_main: layout_data.column_gap,
|
||||||
gap_across: flex_data.row_gap,
|
gap_across: layout_data.row_gap,
|
||||||
is_auto_main: shape.is_layout_horizontal_auto(),
|
is_auto_main: shape.is_layout_horizontal_auto(),
|
||||||
is_auto_across: shape.is_layout_vertical_auto(),
|
is_auto_across: shape.is_layout_vertical_auto(),
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,8 @@ impl LayoutAxis {
|
||||||
padding_main_end: layout_data.padding_bottom,
|
padding_main_end: layout_data.padding_bottom,
|
||||||
padding_across_start: layout_data.padding_left,
|
padding_across_start: layout_data.padding_left,
|
||||||
padding_across_end: layout_data.padding_right,
|
padding_across_end: layout_data.padding_right,
|
||||||
gap_main: flex_data.row_gap,
|
gap_main: layout_data.row_gap,
|
||||||
gap_across: flex_data.column_gap,
|
gap_across: layout_data.column_gap,
|
||||||
is_auto_main: shape.is_layout_vertical_auto(),
|
is_auto_main: shape.is_layout_vertical_auto(),
|
||||||
is_auto_across: shape.is_layout_horizontal_auto(),
|
is_auto_across: shape.is_layout_horizontal_auto(),
|
||||||
}
|
}
|
||||||
|
@ -121,10 +121,10 @@ struct ChildAxis {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChildAxis {
|
impl ChildAxis {
|
||||||
fn new(child: &Shape, child_bounds: &Bounds, layout_data: &LayoutData) -> Self {
|
fn new(child: &Shape, child_bounds: &Bounds, flex_data: &FlexData) -> Self {
|
||||||
let id = child.id;
|
let id = child.id;
|
||||||
let layout_item = child.layout_item;
|
let layout_item = child.layout_item;
|
||||||
let mut result = if layout_data.is_row() {
|
let mut result = if flex_data.is_row() {
|
||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
main_size: child_bounds.width(),
|
main_size: child_bounds.width(),
|
||||||
|
@ -176,7 +176,6 @@ fn initialize_tracks(
|
||||||
shape: &Shape,
|
shape: &Shape,
|
||||||
layout_bounds: &Bounds,
|
layout_bounds: &Bounds,
|
||||||
layout_axis: &LayoutAxis,
|
layout_axis: &LayoutAxis,
|
||||||
layout_data: &LayoutData,
|
|
||||||
flex_data: &FlexData,
|
flex_data: &FlexData,
|
||||||
shapes: &HashMap<Uuid, Shape>,
|
shapes: &HashMap<Uuid, Shape>,
|
||||||
bounds: &HashMap<Uuid, Bounds>,
|
bounds: &HashMap<Uuid, Bounds>,
|
||||||
|
@ -186,7 +185,7 @@ fn initialize_tracks(
|
||||||
let mut children = shape.children.clone();
|
let mut children = shape.children.clone();
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
|
|
||||||
if !layout_data.is_reverse() {
|
if !flex_data.is_reverse() {
|
||||||
children.reverse();
|
children.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +203,7 @@ fn initialize_tracks(
|
||||||
.box_bounds(&default_bounds)
|
.box_bounds(&default_bounds)
|
||||||
.unwrap_or(default_bounds);
|
.unwrap_or(default_bounds);
|
||||||
|
|
||||||
let child_axis = ChildAxis::new(child, &child_bounds, layout_data);
|
let child_axis = ChildAxis::new(child, &child_bounds, flex_data);
|
||||||
|
|
||||||
let child_main_size = child_axis.margin_main_start
|
let child_main_size = child_axis.margin_main_start
|
||||||
+ child_axis.margin_main_end
|
+ child_axis.margin_main_end
|
||||||
|
@ -466,7 +465,6 @@ fn calculate_track_data(
|
||||||
shape,
|
shape,
|
||||||
layout_bounds,
|
layout_bounds,
|
||||||
&layout_axis,
|
&layout_axis,
|
||||||
layout_data,
|
|
||||||
flex_data,
|
flex_data,
|
||||||
shapes,
|
shapes,
|
||||||
bounds,
|
bounds,
|
||||||
|
@ -617,7 +615,7 @@ pub fn reflow_flex_layout(
|
||||||
let child_bounds = &child_axis.bounds;
|
let child_bounds = &child_axis.bounds;
|
||||||
let delta_v = Vector::new_points(&child_bounds.nw, &position);
|
let delta_v = Vector::new_points(&child_bounds.nw, &position);
|
||||||
|
|
||||||
let (new_width, new_height) = if layout_data.is_row() {
|
let (new_width, new_height) = if flex_data.is_row() {
|
||||||
(child_axis.main_size, child_axis.across_size)
|
(child_axis.main_size, child_axis.across_size)
|
||||||
} else {
|
} else {
|
||||||
(child_axis.across_size, child_axis.main_size)
|
(child_axis.across_size, child_axis.main_size)
|
||||||
|
@ -681,7 +679,7 @@ pub fn reflow_flex_layout(
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
let (scale_width, scale_height) = if layout_data.is_row() {
|
let (scale_width, scale_height) = if flex_data.is_row() {
|
||||||
(
|
(
|
||||||
if layout_axis.is_auto_main {
|
if layout_axis.is_auto_main {
|
||||||
auto_main_size / width
|
auto_main_size / width
|
||||||
|
|
|
@ -1,15 +1,59 @@
|
||||||
use crate::math::Bounds;
|
#![allow(dead_code, unused_variables)]
|
||||||
|
use crate::math::{Bounds, Matrix, Point, Vector, VectorExt};
|
||||||
use crate::shapes::{GridData, LayoutData, Modifier, Shape};
|
use crate::shapes::{GridData, LayoutData, Modifier, Shape};
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
pub fn reflow_grid_layout(
|
use super::common::GetBounds;
|
||||||
_shape: &Shape,
|
|
||||||
_layout_data: &LayoutData,
|
const MIN_SIZE: f32 = 0.01;
|
||||||
_grid_data: &GridData,
|
const MAX_SIZE: f32 = f32::INFINITY;
|
||||||
_shapes: &HashMap<Uuid, Shape>,
|
|
||||||
_bounds: &HashMap<Uuid, Bounds>,
|
struct CellData<'a> {
|
||||||
) -> VecDeque<Modifier> {
|
shape: &'a Shape,
|
||||||
// TODO
|
main_size: f32,
|
||||||
VecDeque::new()
|
across_size: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_cell_data<'a>(
|
||||||
|
shape: &Shape,
|
||||||
|
layout_data: &LayoutData,
|
||||||
|
grid_data: &GridData,
|
||||||
|
shapes: &'a HashMap<Uuid, Shape>,
|
||||||
|
bounds: &HashMap<Uuid, Bounds>,
|
||||||
|
) -> Vec<CellData<'a>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn child_position(child_bounds: &Bounds, cell: &CellData) -> Point {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reflow_grid_layout<'a>(
|
||||||
|
shape: &Shape,
|
||||||
|
layout_data: &LayoutData,
|
||||||
|
grid_data: &GridData,
|
||||||
|
shapes: &'a HashMap<Uuid, Shape>,
|
||||||
|
bounds: &HashMap<Uuid, Bounds>,
|
||||||
|
) -> VecDeque<Modifier> {
|
||||||
|
let mut result = VecDeque::new();
|
||||||
|
|
||||||
|
let cells = calculate_cell_data(shape, layout_data, grid_data, shapes, bounds);
|
||||||
|
|
||||||
|
for cell in cells.iter() {
|
||||||
|
let child = cell.shape;
|
||||||
|
let child_bounds = bounds.find(child);
|
||||||
|
let position = child_position(&child_bounds, cell);
|
||||||
|
|
||||||
|
let mut transform = Matrix::default();
|
||||||
|
let delta_v = Vector::new_points(&child_bounds.nw, &position);
|
||||||
|
|
||||||
|
if delta_v.x.abs() > MIN_SIZE || delta_v.y.abs() > MIN_SIZE {
|
||||||
|
transform.post_concat(&Matrix::translate(delta_v));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(Modifier::transform(child.id, transform));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue