0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-16 01:31:22 -05:00

UI Integration

This commit is contained in:
alonso.torres 2023-02-22 12:21:44 +01:00
parent 284fc2acbc
commit b497de0dae
20 changed files with 442 additions and 246 deletions

View file

@ -21,7 +21,7 @@
{:type :percent :value 25} {:type :percent :value 25}
{:type :fixed :value 100} {:type :fixed :value 100}
;;{:type :auto} ;;{:type :auto}
;;{:type :fr :value 1} ;;{:type :flex :value 1}
] ]
:layout-grid-rows :layout-grid-rows
@ -29,7 +29,7 @@
{:type :percent :value 50} {:type :percent :value 50}
;;{:type :fixed :value 100} ;;{:type :fixed :value 100}
;;{:type :auto} ;;{:type :auto}
;;{:type :fr :value 1} ;;{:type :flex :value 1}
]) ])
num-rows (count (:layout-grid-rows parent)) num-rows (count (:layout-grid-rows parent))
@ -71,12 +71,7 @@
(defn calc-layout-data (defn calc-layout-data
[parent children transformed-parent-bounds] [parent children transformed-parent-bounds]
(let [ (let [height (gpo/height-points transformed-parent-bounds)
;; TODO: Delete when there is UI
[parent children] (set-sample-data parent children)
height (gpo/height-points transformed-parent-bounds)
width (gpo/width-points transformed-parent-bounds) width (gpo/width-points transformed-parent-bounds)
;; Initialize tracks ;; Initialize tracks

View file

@ -303,7 +303,7 @@
(:shapes parent)) (:shapes parent))
children-layout children-layout
(when layout? (when flex-layout?
(->> (:shapes parent) (->> (:shapes parent)
(remove #(ctl/layout-absolute? objects %))))] (remove #(ctl/layout-absolute? objects %))))]
@ -312,7 +312,7 @@
(set-children-modifiers children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints) (set-children-modifiers children-modifiers objects bounds parent transformed-parent-bounds ignore-constraints)
flex-layout? flex-layout?
(set-flex-layout-modifiers children-layout objects bounds parent transformed-parent-bounds)) (set-flex-layout-modifiers children-layout objects bounds parent transformed-parent-bounds)
grid-layout? grid-layout?
(set-grid-layout-modifiers objects bounds parent transformed-parent-bounds)) (set-grid-layout-modifiers objects bounds parent transformed-parent-bounds))

View file

@ -51,8 +51,8 @@
(s/def ::layout-wrap-type #{:wrap :nowrap :no-wrap}) ;;TODO remove no-wrap after script (s/def ::layout-wrap-type #{:wrap :nowrap :no-wrap}) ;;TODO remove no-wrap after script
(s/def ::layout-padding-type #{:simple :multiple}) (s/def ::layout-padding-type #{:simple :multiple})
(s/def :grid/type #{:fr :auto :fixed}) (s/def :grid/type #{:percent :flex :auto :fixed})
(s/def :grid/value (s/nilable ::us/string)) (s/def :grid/value (s/nilable ::us/safe-number))
(s/def ::grid-definition (s/keys :opt-un [:grid/type (s/def ::grid-definition (s/keys :opt-un [:grid/type
:grid/value])) :grid/value]))
(s/def ::layout-grid-rows (s/coll-of ::grid-definition :kind vector?)) (s/def ::layout-grid-rows (s/coll-of ::grid-definition :kind vector?))

View file

@ -164,7 +164,7 @@
:else :else
;; If the base is a layout we should check if the z-index property is set ;; If the base is a layout we should check if the z-index property is set
(let [[z-index-a z-index-b] (let [[z-index-a z-index-b]
(if (ctl/layout? objects base) (if (ctl/any-layout? objects base)
[(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-a])) [(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-a]))
(ctl/layout-z-index objects (dm/get-in objects [base :shapes index-b]))] (ctl/layout-z-index objects (dm/get-in objects [base :shapes index-b]))]
[0 0])] [0 0])]

View file

@ -1705,7 +1705,9 @@
color: $color-gray-20; color: $color-gray-20;
&.active, &.active,
&:hover { &:hover {
color: $color-primary; &.dir {
color: $color-primary;
}
svg { svg {
fill: $color-primary; fill: $color-primary;
} }
@ -2160,6 +2162,9 @@
.columns-info { .columns-info {
flex-grow: 1; flex-grow: 1;
font-size: 12px; font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.expand-icon, .expand-icon,
.add-column { .add-column {

View file

@ -660,7 +660,7 @@
(pcb/with-objects objects) (pcb/with-objects objects)
;; Remove layout-item properties when moving a shape outside a layout ;; Remove layout-item properties when moving a shape outside a layout
(cond-> (not (ctl/layout? objects parent-id)) (cond-> (not (ctl/any-layout? objects parent-id))
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data)) (pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
;; Move the shapes ;; Move the shapes

View file

@ -144,7 +144,7 @@
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(cond-> (ctl/layout? frame) (cond-> (ctl/any-layout? frame)
(pcb/update-shapes (:shapes frame) ctl/remove-layout-item-data)) (pcb/update-shapes (:shapes frame) ctl/remove-layout-item-data))
(pcb/change-parent parent-id children idx-in-parent) (pcb/change-parent parent-id children idx-in-parent)
(pcb/remove-objects [(:id frame)])))) (pcb/remove-objects [(:id frame)]))))

View file

@ -183,6 +183,7 @@
;; Never call this directly but through the data-event `:layout/update` ;; Never call this directly but through the data-event `:layout/update`
;; Otherwise a lot of cycle dependencies could be generated ;; Otherwise a lot of cycle dependencies could be generated
(declare check-grid-cells-update)
(defn- update-layout-positions (defn- update-layout-positions
[ids] [ids]
(ptk/reify ::update-layout-positions (ptk/reify ::update-layout-positions
@ -190,10 +191,16 @@
(watch [_ state _] (watch [_ state _]
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
ids (->> ids (filter #(contains? objects %)))] ids (->> ids (filter #(contains? objects %)))]
(if (d/not-empty? ids)
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))] (rx/concat
(rx/of (dwm/apply-modifiers {:modifiers modif-tree}))) ;; Update grids if necesary
(rx/empty)))))) (rx/of (check-grid-cells-update
(->> (concat ids (map #(cph/get-parent-id objects %) ids))
(filter #(ctl/grid-layout? objects %)))))
(if (d/not-empty? ids)
(let [modif-tree (dwm/create-modif-tree ids (ctm/reflow-modifiers))]
(rx/of (dwm/apply-modifiers {:modifiers modif-tree})))
(rx/empty)))))))
(defn initialize (defn initialize
[] []
@ -352,6 +359,93 @@
(ptk/data-event :layout/update ids) (ptk/data-event :layout/update ids)
(dwu/commit-undo-transaction undo-id)))))) (dwu/commit-undo-transaction undo-id))))))
(defn update-grid-cells
[parent objects]
(let [children (cph/get-immediate-children objects (:id parent))
layout-grid-rows (:layout-grid-rows parent)
layout-grid-columns (:layout-grid-columns parent)
num-rows (count layout-grid-columns)
num-columns (count layout-grid-columns)
layout-grid-cells
(for [[row-idx row] (d/enumerate layout-grid-rows)
[col-idx col] (d/enumerate layout-grid-columns)]
(let [shape (nth children (+ (* row-idx num-columns) col-idx) nil)
cell-data {:id (uuid/next)
:row (inc row-idx)
:column (inc col-idx)
:row-span 1
:col-span 1
:shapes (when shape [(:id shape)])}]
[(:id cell-data) cell-data]))]
(assoc parent :layout-grid-cells layout-grid-cells)))
(defn check-grid-cells-update
[ids]
(ptk/reify ::check-grid-cells-update
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
undo-id (js/Symbol)]
(rx/of (dwc/update-shapes
ids
(fn [shape]
(-> shape
(update-grid-cells objects)))))))))
(defn add-layout-column
[ids property value]
(ptk/reify ::add-layout-column
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
undo-id (js/Symbol)]
(rx/of (dwu/start-undo-transaction undo-id)
(dwc/update-shapes
ids
(fn [shape]
(-> shape
(update property (fnil conj []) value)
(update-grid-cells objects))))
(ptk/data-event :layout/update ids)
(dwu/commit-undo-transaction undo-id))))))
(defn remove-layout-column
[ids property index]
(ptk/reify ::remove-layout-column
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
undo-id (js/Symbol)]
(rx/of (dwu/start-undo-transaction undo-id)
(dwc/update-shapes
ids
(fn [shape]
(-> shape
(update property d/remove-at-index index)
(update-grid-cells objects))))
(ptk/data-event :layout/update ids)
(dwu/commit-undo-transaction undo-id))))))
(defn change-layout-column
[ids property index props]
(ptk/reify ::change-layout-column
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
undo-id (js/Symbol)]
(rx/of (dwu/start-undo-transaction undo-id)
(dwc/update-shapes
ids
(fn [shape]
(-> shape
(update-in [property index] merge props)
(update-grid-cells objects))))
(ptk/data-event :layout/update ids)
(dwu/commit-undo-transaction undo-id))))))
(defn fix-child-sizing (defn fix-child-sizing
[objects parent-changes shape] [objects parent-changes shape]

View file

@ -18,6 +18,7 @@
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[app.common.types.shape-tree :as ctst] [app.common.types.shape-tree :as ctst]
[app.common.types.shape.interactions :as ctsi] [app.common.types.shape.interactions :as ctsi]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.comments :as dc] [app.main.data.comments :as dc]
[app.main.data.workspace.changes :as dch] [app.main.data.workspace.changes :as dch]
@ -130,7 +131,7 @@
(when (d/not-empty? to-move-shapes) (when (d/not-empty? to-move-shapes)
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
(cond-> (not (ctl/layout? objects frame-id)) (cond-> (not (ctl/any-layout? objects frame-id))
(pcb/update-shapes ordered-indexes ctl/remove-layout-item-data)) (pcb/update-shapes ordered-indexes ctl/remove-layout-item-data))
(pcb/change-parent frame-id to-move-shapes 0)))] (pcb/change-parent frame-id to-move-shapes 0)))]

View file

@ -739,7 +739,7 @@
(-> (pcb/empty-changes it page-id) (-> (pcb/empty-changes it page-id)
(pcb/with-objects objects) (pcb/with-objects objects)
;; Remove layout-item properties when moving a shape outside a layout ;; Remove layout-item properties when moving a shape outside a layout
(cond-> (not (ctl/layout? objects frame-id)) (cond-> (not (ctl/any-layout? objects frame-id))
(pcb/update-shapes (map :id moving-shapes) ctl/remove-layout-item-data)) (pcb/update-shapes (map :id moving-shapes) ctl/remove-layout-item-data))
(pcb/change-parent frame-id moving-shapes drop-index) (pcb/change-parent frame-id moving-shapes drop-index)
(pcb/remove-objects empty-parents))] (pcb/remove-objects empty-parents))]

View file

@ -129,7 +129,7 @@
(let [shape (unchecked-get props "shape") (let [shape (unchecked-get props "shape")
childs (unchecked-get props "childs") childs (unchecked-get props "childs")
childs (cond-> childs childs (cond-> childs
(ctl/layout? shape) (ctl/any-layout? shape)
(cph/sort-layout-children-z-index))] (cph/sort-layout-children-z-index))]
[:> frame-container props [:> frame-container props
[:g.frame-children {:opacity (:opacity shape)} [:g.frame-children {:opacity (:opacity shape)}

View file

@ -5,114 +5,135 @@
;; Copyright (c) KALEIDOS INC ;; Copyright (c) KALEIDOS INC
(ns app.main.ui.workspace.sidebar.options.menus.layout-container (ns app.main.ui.workspace.sidebar.options.menus.layout-container
(:require [app.common.data :as d] (:require
[app.common.data.macros :as dm] [app.common.data :as d]
[app.main.data.workspace :as udw] [app.common.data.macros :as dm]
[app.main.data.workspace.shape-layout :as dwsl] [app.main.data.workspace :as udw]
[app.main.store :as st] [app.main.data.workspace.shape-layout :as dwsl]
[app.main.ui.components.numeric-input :refer [numeric-input]] [app.main.store :as st]
[app.main.ui.components.select :refer [select]] [app.main.ui.components.numeric-input :refer [numeric-input]]
[app.main.ui.icons :as i] [app.main.ui.components.select :refer [select]]
[app.util.dom :as dom] [app.main.ui.icons :as i]
[cuerdas.core :as str] [app.util.dom :as dom]
[rumext.v2 :as mf])) [cuerdas.core :as str]
[rumext.v2 :as mf]))
(def layout-container-flex-attrs (def layout-container-flex-attrs
[:layout ;; :flex, :grid in the future [:layout ;; :flex, :grid in the future
:layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse :layout-flex-dir ;; :row, :row-reverse, :column, :column-reverse
:layout-gap-type ;; :simple, :multiple :layout-gap-type ;; :simple, :multiple
:layout-gap ;; {:row-gap number , :column-gap number} :layout-gap ;; {:row-gap number , :column-gap number}
:layout-align-items ;; :start :end :center :stretch :layout-align-items ;; :start :end :center :stretch
:layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly :layout-justify-content ;; :start :center :end :space-between :space-around :space-evenly
:layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default) :layout-align-content ;; :start :center :end :space-between :space-around :space-evenly :stretch (by default)
:layout-wrap-type ;; :wrap, :nowrap :layout-wrap-type ;; :wrap, :nowrap
:layout-padding-type ;; :simple, :multiple :layout-padding-type ;; :simple, :multiple
:layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative :layout-padding ;; {:p1 num :p2 num :p3 num :p4 num} number could be negative
:layout-grid-dir ;; :row :column
:layout-justify-items
:layout-grid-columns
:layout-grid-rows
]) ])
(defn get-layout-flex-icon (defn get-layout-flex-icon
[type val is-col?] [type val is-col?]
(case type (case type
:align-items (if is-col? :align-items
(case val (if is-col?
:start i/align-items-column-start (case val
:end i/align-items-column-end :start i/align-items-column-start
:center i/align-items-column-center :end i/align-items-column-end
:stretch i/align-items-column-strech :center i/align-items-column-center
:baseline i/align-items-column-baseline) :stretch i/align-items-column-strech
(case val :baseline i/align-items-column-baseline)
:start i/align-items-row-start (case val
:end i/align-items-row-end :start i/align-items-row-start
:center i/align-items-row-center :end i/align-items-row-end
:stretch i/align-items-row-strech :center i/align-items-row-center
:baseline i/align-items-row-baseline)) :stretch i/align-items-row-strech
:justify-content (if is-col? :baseline i/align-items-row-baseline))
(case val
:start i/justify-content-column-start :justify-content
:end i/justify-content-column-end (if is-col?
:center i/justify-content-column-center (case val
:space-around i/justify-content-column-around :start i/justify-content-column-start
:space-evenly i/justify-content-column-evenly :end i/justify-content-column-end
:space-between i/justify-content-column-between) :center i/justify-content-column-center
(case val :space-around i/justify-content-column-around
:start i/justify-content-row-start :space-evenly i/justify-content-column-evenly
:end i/justify-content-row-end :space-between i/justify-content-column-between)
:center i/justify-content-row-center (case val
:space-around i/justify-content-row-around :start i/justify-content-row-start
:space-evenly i/justify-content-row-evenly :end i/justify-content-row-end
:space-between i/justify-content-row-between)) :center i/justify-content-row-center
:space-around i/justify-content-row-around
:space-evenly i/justify-content-row-evenly
:space-between i/justify-content-row-between))
:align-content (if is-col? :align-content
(case val (if is-col?
:start i/align-content-column-start (case val
:end i/align-content-column-end :start i/align-content-column-start
:center i/align-content-column-center :end i/align-content-column-end
:space-around i/align-content-column-around :center i/align-content-column-center
:space-evenly i/align-content-column-evenly :space-around i/align-content-column-around
:space-between i/align-content-column-between :space-evenly i/align-content-column-evenly
:stretch nil) :space-between i/align-content-column-between
:stretch nil)
(case val (case val
:start i/align-content-row-start :start i/align-content-row-start
:end i/align-content-row-end :end i/align-content-row-end
:center i/align-content-row-center :center i/align-content-row-center
:space-around i/align-content-row-around :space-around i/align-content-row-around
:space-evenly i/align-content-row-evenly :space-evenly i/align-content-row-evenly
:space-between i/align-content-row-between :space-between i/align-content-row-between
:stretch nil)) :stretch nil))
:align-self (if is-col? (case val
(case val :start i/align-content-row-start
:auto i/minus :end i/align-content-row-end
:start i/align-self-row-left :center i/align-content-row-center
:end i/align-self-row-right :space-around i/align-content-row-around
:center i/align-self-row-center :space-between i/align-content-row-between
:stretch i/align-self-row-strech :stretch nil)
:baseline i/align-self-row-baseline)
(case val :align-self
:auto i/minus (if is-col?
:start i/align-self-column-top (case val
:end i/align-self-column-bottom :auto i/minus
:center i/align-self-column-center :start i/align-self-row-left
:stretch i/align-self-column-strech :end i/align-self-row-right
:baseline i/align-self-column-baseline)))) :center i/align-self-row-center
:stretch i/align-self-row-strech
:baseline i/align-self-row-baseline)
(case val
:auto i/minus
:start i/align-self-column-top
:end i/align-self-column-bottom
:center i/align-self-column-center
:stretch i/align-self-column-strech
:baseline i/align-self-column-baseline))))
(defn get-layout-grid-icon (defn get-layout-grid-icon
[type val is-col?] [type val is-col?]
(case type (case type
:justify-content (if is-col? :justify-items
(case val (if is-col?
:start i/grid-justify-content-column-start (case val
:end i/grid-justify-content-column-end :start i/grid-justify-content-column-start
:center i/grid-justify-content-column-center :end i/grid-justify-content-column-end
:space-around i/grid-justify-content-column-around :center i/grid-justify-content-column-center
:space-between i/grid-justify-content-column-between) :space-around i/grid-justify-content-column-around
(case val :space-between i/grid-justify-content-column-between)
:start i/grid-justify-content-row-start (case val
:end i/grid-justify-content-row-end :start i/grid-justify-content-row-start
:center i/grid-justify-content-row-center :end i/grid-justify-content-row-end
:space-around i/grid-justify-content-row-around :center i/grid-justify-content-row-center
:space-between i/grid-justify-content-row-between)))) :space-around i/grid-justify-content-row-around
:space-between i/grid-justify-content-row-between))))
(mf/defc direction-btn (mf/defc direction-btn
[{:keys [dir saved-dir set-direction icon?] :as props}] [{:keys [dir saved-dir set-direction icon?] :as props}]
@ -333,9 +354,7 @@
(mf/defc align-grid-row (mf/defc align-grid-row
[{:keys [is-col? align-items set-align] :as props}] [{:keys [is-col? align-items set-align] :as props}]
(let [type (if is-col? (let [type (if is-col? :column :row)]
:column
:row)]
[:div.align-items-style [:div.align-items-style
(for [align [:start :center :end :stretch :baseline]] (for [align [:start :center :end :stretch :baseline]]
[:button.align-start.tooltip [:button.align-start.tooltip
@ -343,15 +362,13 @@
:tooltip-bottom-left (not= align :start) :tooltip-bottom-left (not= align :start)
:tooltip-bottom (= align :start)) :tooltip-bottom (= align :start))
:alt (dm/str "Align items " (d/name align)) :alt (dm/str "Align items " (d/name align))
:on-click #(set-align align % type) :on-click #(set-align align type)
:key (dm/str "align-items" (d/name align))} :key (dm/str "align-items" (d/name align))}
(get-layout-flex-icon :align-items align is-col?)])])) (get-layout-flex-icon :align-items align is-col?)])]))
(mf/defc justify-grid-row (mf/defc justify-grid-row
[{:keys [is-col? justify-items set-justify] :as props}] [{:keys [is-col? justify-items set-justify] :as props}]
(let [type (if is-col? (let [type (if is-col? :column :row)]
:column
:row)]
[:div.justify-content-style [:div.justify-content-style
(for [align [:start :center :end :space-around :space-between]] (for [align [:start :center :end :space-around :space-between]]
[:button.align-start.tooltip [:button.align-start.tooltip
@ -359,44 +376,43 @@
:tooltip-bottom-left (not= align :start) :tooltip-bottom-left (not= align :start)
:tooltip-bottom (= align :start)) :tooltip-bottom (= align :start))
:alt (dm/str "Justify content " (d/name align)) :alt (dm/str "Justify content " (d/name align))
:on-click #(set-justify align % type) :on-click #(set-justify align type)
:key (dm/str "justify-content" (d/name align))} :key (dm/str "justify-content" (d/name align))}
(get-layout-grid-icon :justify-content align is-col?)])])) (get-layout-grid-icon :justify-items align is-col?)])]))
(defn manage-values [value] (defn manage-values [{:keys [value type]}]
(let [quantity (:value value) (case type
unit (:unit value)] :auto "auto"
(case unit :percent (dm/str value "%")
:auto (d/name unit) :flex (dm/str value "fr")
:perc (str/join [quantity "%"]) :fixed (dm/str value "px")
(str/join [quantity (d/name unit)])))) value))
(mf/defc grid-columns-row (mf/defc grid-columns-row
[{:keys [is-col? expanded? column-values toggle add-new-element set-column-value handle-focus handle-blur on-unit-change remove-column] :as props}] [{:keys [is-col? expanded? column-values toggle add-new-element set-column-value set-column-type remove-element] :as props}]
(let [column-num (count column-values) (let [column-num (count column-values)
direction (if (< 1 column-num) direction (if (> column-num 1)
(if is-col? (if is-col? "Columns " "Rows ")
"Columns " (if is-col? "Column " "Row "))
"Rows ")
(if is-col?
"Column "
"Row "))
column-vals (str/join ", " (map manage-values column-values)) column-vals (str/join ", " (map manage-values column-values))
generated-name (str direction column-num " (" column-vals ")")] generated-name (dm/str direction (if (= column-num 0) " - empty" (dm/str column-num " (" column-vals ")")))
type (if is-col? :column :row)]
[:div.grid-columns [:div.grid-columns
[:div.grid-columns-header [:div.grid-columns-header
[:button.expand-icon [:button.expand-icon
{:on-click toggle} {:on-click toggle} i/actions]
i/actions]
[:div.columns-info {:title generated-name
:on-click toggle} generated-name]
[:button.add-column {:on-click #(do
(when-not expanded? (toggle))
(add-new-element type {:type :fixed :value 100}))} i/plus]]
[:div.columns-info
generated-name]
[:button.add-column
{:on-click add-new-element}
i/plus]]
(when expanded? (when expanded?
[:div.columns-info-wrapper [:div.columns-info-wrapper
(for [column column-values] (for [[index column] (d/enumerate column-values)]
[:div.column-info [:div.column-info
[:div.direction-grid-icon [:div.direction-grid-icon
(if is-col? (if is-col?
@ -406,21 +422,19 @@
[:div.grid-column-value [:div.grid-column-value
[:> numeric-input {:no-validate true [:> numeric-input {:no-validate true
:value (:value column) :value (:value column)
:on-change set-column-value :on-change #(set-column-value type index %)
:on-focus handle-focus
:on-blur handle-blur
:placeholder "--"}]] :placeholder "--"}]]
[:div.grid-column-unit [:div.grid-column-unit
[:& select [:& select
{:class "grid-column-unit-selector" {:class "grid-column-unit-selector"
:default-value (:unit column) :default-value (:type column)
:options [{:value :fr :label "fr"} :options [{:value :flex :label "fr"}
{:value :auto :label "auto"} {:value :auto :label "auto"}
{:value :px :label "px"} {:value :fixed :label "px"}
{:value :perc :label "%"}] {:value :percent :label "%"}]
:on-change on-unit-change}]] :on-change #(set-column-type type index %)}]]
[:button.remove-grid-column [:button.remove-grid-column
{:on-change remove-column} {:on-click #(remove-element type index)}
i/minus]])])])) i/minus]])])]))
(mf/defc layout-container-menu (mf/defc layout-container-menu
@ -520,50 +534,74 @@
(st/emit! (dwsl/update-layout ids {:layout-grid-dir dir})))) (st/emit! (dwsl/update-layout ids {:layout-grid-dir dir}))))
;; Align grid ;; Align grid
align-items-row (:layout-grid-align-row values) align-items-row (:layout-align-items values)
align-items-column (:layout-grid-align-column values) align-items-column (:layout-justify-items values)
set-align-grid (fn [value type]
(if (= type :row) set-align-grid
(st/emit! (dwsl/update-layout ids {:layout-grid-align-row value})) (fn [value type]
(st/emit! (dwsl/update-layout ids {:layout-grid-align-column value})))) (if (= type :row)
(st/emit! (dwsl/update-layout ids {:layout-align-items value}))
(st/emit! (dwsl/update-layout ids {:layout-justify-items value}))))
;; Justify grid ;; Justify grid
grid-justify-content-row (:layout-grid-justify-row values) grid-justify-content-row (:layout-align-content values)
grid-justify-content-column (:layout-grid-justify-column values) grid-justify-content-column (:layout-justify-content values)
set-justify-grid (fn [value type]
(if (= type :row) set-justify-grid
(st/emit! (dwsl/update-layout ids {:layout-grid-justify-row value})) (mf/use-callback
(st/emit! (dwsl/update-layout ids {:layout-grid-justify-column value})))) (mf/deps ids)
(fn [value type]
(if (= type :row)
(st/emit! (dwsl/update-layout ids {:layout-align-content value}))
(st/emit! (dwsl/update-layout ids {:layout-justify-content value})))))
;;Grid columns ;;Grid columns
column-grid-values (:layout-grid-columns values)
column-grid-values (:layout-grid-column-values values)
grid-columns-open? (mf/use-state false) grid-columns-open? (mf/use-state false)
toggle-columns-info (mf/use-callback toggle-columns-info (mf/use-callback
(fn [_] (fn [_]
(swap! grid-columns-open? not))) (swap! grid-columns-open? not)))
; Grid rows / columns ; Grid rows / columns
rows-grid-values (:layout-grid-row-values values) rows-grid-values (:layout-grid-rows values)
grid-rows-open? (mf/use-state false) grid-rows-open? (mf/use-state false)
toggle-rows-info (mf/use-callback toggle-rows-info
(fn [_] (mf/use-callback
(swap! grid-rows-open? not))) (fn [_]
(swap! grid-rows-open? not)))
;; TODO -> fix this, is doing nothing add-new-element
add-new-element (fn [value type] (mf/use-callback
(if (= type :row) (mf/deps ids)
(st/emit! (dwsl/update-layout ids {:layout-grid-row-values value})) (fn [type value]
(st/emit! (dwsl/update-layout ids {:layout-grid-column-values value})))) (if (= type :row)
(st/emit! (dwsl/add-layout-column ids :layout-grid-rows value))
(st/emit! (dwsl/add-layout-column ids :layout-grid-columns value)))))
set-column-value (fn[] ) remove-element
handle-focus (fn []) (mf/use-callback
handle-blur (fn []) (mf/deps ids)
set-colum-unit (fn []) (fn [type index]
remove-column (fn [])] (if (= type :row)
(st/emit! (dwsl/remove-layout-column ids :layout-grid-rows index))
(st/emit! (dwsl/remove-layout-column ids :layout-grid-columns index)))))
set-column-value
(mf/use-callback
(mf/deps ids)
(fn [type index value]
(if (= type :row)
(st/emit! (dwsl/change-layout-column ids :layout-grid-rows index {:value value}))
(st/emit! (dwsl/change-layout-column ids :layout-grid-columns index {:value value})))))
set-column-type
(mf/use-callback
(mf/deps ids)
(fn [type index col-type]
(if (= type :row)
(st/emit! (dwsl/change-layout-column ids :layout-grid-rows index {:type col-type}))
(st/emit! (dwsl/change-layout-column ids :layout-grid-columns index {:type col-type})))))]
[:div.element-set [:div.element-set
[:div.element-set-title [:div.element-set-title
@ -585,6 +623,7 @@
(when (:layout values) (when (:layout values)
(when (not= :multiple layout-type) (when (not= :multiple layout-type)
(if (= :flex layout-type) (if (= :flex layout-type)
;; FLEX
[:div.element-set-content.layout-menu [:div.element-set-content.layout-menu
[:div.layout-row [:div.layout-row
[:div.direction-wrap.row-title "Direction"] [:div.direction-wrap.row-title "Direction"]
@ -634,6 +673,7 @@
:on-change-style change-padding-type :on-change-style change-padding-type
:on-change on-padding-change}]] :on-change on-padding-change}]]
;; GRID
[:div.element-set-content.layout-menu [:div.element-set-content.layout-menu
[:div.layout-row [:div.layout-row
[:div.direction-wrap.row-title "Direction"] [:div.direction-wrap.row-title "Direction"]
@ -667,34 +707,30 @@
[:div.jusfiy-content-grid.row-title "Justify"] [:div.jusfiy-content-grid.row-title "Justify"]
[:div.btn-wrapper.align-grid [:div.btn-wrapper.align-grid
[:& justify-grid-row {:is-col? true [:& justify-grid-row {:is-col? true
:align-items grid-justify-content-column :justify-items grid-justify-content-column
:set-justify set-justify-grid}] :set-justify set-justify-grid}]
[:& justify-grid-row {:is-col? false [:& justify-grid-row {:is-col? false
:align-items grid-justify-content-row :justify-items grid-justify-content-row
:set-justify set-justify-grid}]]] :set-justify set-justify-grid}]]]
[:& grid-columns-row {:is-col? true [:& grid-columns-row {:is-col? true
:expanded? @grid-columns-open? :expanded? @grid-columns-open?
:toggle toggle-columns-info :toggle toggle-columns-info
:column-values [{:value 1 :unit :fr} {:value 1 :unit :fr}];; column-grid-values :column-values column-grid-values
:add-new-column add-new-element :add-new-element add-new-element
:set-column-value set-column-value :set-column-value set-column-value
:handle-focus handle-focus :set-column-type set-column-type
:handle-blur handle-blur :remove-element remove-element}]
:set-colum-unit set-colum-unit
:remove-column remove-column}]
[:& grid-columns-row {:is-col? false [:& grid-columns-row {:is-col? false
:expanded? @grid-rows-open? :expanded? @grid-rows-open?
:toggle toggle-rows-info :toggle toggle-rows-info
:column-values [{:value "--" :unit :auto} {:value "--" :unit :auto}] ;; column-grid-values :column-values rows-grid-values
:add-new-column add-new-element :add-new-element add-new-element
:set-column-value set-column-value :set-column-value set-column-value
:handle-focus handle-focus :set-column-type set-column-type
:handle-blur handle-blur :remove-element remove-element}]
:set-colum-unit set-colum-unit
:remove-column remove-column}]
[:& gap-section {:is-col? is-col? [:& gap-section {:is-col? is-col?
:wrap-type wrap-type :wrap-type wrap-type
:gap-selected? gap-selected? :gap-selected? gap-selected?

View file

@ -33,8 +33,7 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-layout-child? (mf/deref is-layout-child-ref) is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids

View file

@ -38,7 +38,7 @@
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-flex-layout-child? (mf/deref is-flex-layout-child-ref) is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-flex-layout-container? (ctl/flex-layout? shape)] is-flex-layout-container? (ctl/flex-layout? shape)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids [(:id shape)] [:& measures-menu {:ids [(:id shape)]

View file

@ -51,28 +51,31 @@
#_(if (= align-self value) #_(if (= align-self value)
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil})) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self nil}))
(st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value})))) (st/emit! (dwsl/update-layout-child ids {:layout-item-align-self value}))))
column-start (mf/use-state 1) column-start column
column-end (mf/use-state 1) column-end (inc column)
row-start (mf/use-state 1) row-start row
row-end (mf/use-state 1) row-end (inc row)
on-change (fn [side orientation value]
(if (= orientation :column) on-change
(case side (fn [side orientation value]
:all ((reset! column-start value) (if (= orientation :column)
(reset! column-end value)) (case side
:start (reset! column-start value) :all ((reset! column-start value)
:end (reset! column-end value)) (reset! column-end value))
(case side :start (reset! column-start value)
:all ((reset! row-start value) :end (reset! column-end value))
(reset! row-end value)) (case side
:start (reset! row-start value) :all ((reset! row-start value)
:end (reset! row-end value)))) (reset! row-end value))
:start (reset! row-start value)
:end (reset! row-end value))))
area-name (mf/use-state "header") ;; TODO this should come from shape area-name (mf/use-state "header") ;; TODO this should come from shape
on-area-name-change (fn [value] on-area-name-change (fn [value]
(reset! area-name value)) (reset! area-name value))
on-key-press (fn [event])] on-key-press (fn [event])]
[:div.element-set [:div.element-set
[:div.element-set-title [:div.element-set-title
[:span "Grid Cell"]] [:span "Grid Cell"]]
@ -100,7 +103,7 @@
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :all :column) ;; TODO cambiar este on-change y el value :on-change (partial on-change :all :column) ;; TODO cambiar este on-change y el value
:value @column-start}]]] :value column-start}]]]
[:div.grid-rows-auto [:div.grid-rows-auto
[:spam.icon i/layout-columns] [:spam.icon i/layout-columns]
[:div.input-wrapper [:div.input-wrapper
@ -108,7 +111,7 @@
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :all :row) ;; TODO cambiar este on-change y el value :on-change (partial on-change :all :row) ;; TODO cambiar este on-change y el value
:value @row-start}]]]]) :value row-start}]]]])
(when (= :area @position-mode) (when (= :area @position-mode)
[:div.input-wrapper [:div.input-wrapper
[:input.input-text [:input.input-text
@ -130,26 +133,26 @@
[:> numeric-input [:> numeric-input
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :start :column) ;; TODO cambiar este on-change y el value :on-change (partial on-change :start :column)
:value @column-start}] :value column-start}]
[:> numeric-input [:> numeric-input
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :end :column) ;; TODO cambiar este on-change y el value :on-change (partial on-change :end :column)
:value @column-end}]]] :value column-end}]]]
[:div.grid-rows-auto [:div.grid-rows-auto
[:spam.icon i/layout-columns] [:spam.icon i/layout-columns]
[:div.input-wrapper [:div.input-wrapper
[:> numeric-input [:> numeric-input
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :start :row) ;; TODO cambiar este on-change y el value :on-change (partial on-change :start :row)
:value @row-start}] :value row-start}]
[:> numeric-input [:> numeric-input
{:placeholder "--" {:placeholder "--"
:on-click #(dom/select-target %) :on-click #(dom/select-target %)
:on-change (partial on-change :end :row) ;; TODO cambiar este on-change y el value :on-change (partial on-change :end :row)
:value @row-end}]]]])] :value row-end}]]]])]
[:div.layout-row [:div.layout-row
[:div.row-title "Align"] [:div.row-title "Align"]

View file

@ -33,7 +33,7 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)] is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids

View file

@ -33,7 +33,7 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)] is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids

View file

@ -33,7 +33,7 @@
layout-item-values (select-keys shape layout-item-attrs) layout-item-values (select-keys shape layout-item-attrs)
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)] is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
[:* [:*
[:& measures-menu {:ids ids [:& measures-menu {:ids ids
@ -49,7 +49,7 @@
:is-layout-child? true :is-layout-child? true
:shape shape}]) :shape shape}])
(when (or (not is-layout-child?) is-layout-child-absolute?) (when (or (not is-flex-layout-child?) is-layout-child-absolute?)
[:& constraints-menu {:ids ids [:& constraints-menu {:ids ids
:values constraint-values}]) :values constraint-values}])

View file

@ -107,7 +107,7 @@
layout-container-values (select-keys shape layout-container-flex-attrs) layout-container-values (select-keys shape layout-container-flex-attrs)
is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids)) is-flex-layout-child-ref (mf/use-memo (mf/deps ids) #(refs/is-flex-layout-child? ids))
is-flex-layout-child? (mf/deref is-flex-layout-child-ref)] is-flex-layout-child? (mf/deref is-flex-layout-child-ref)
is-layout-child-absolute? (ctl/layout-absolute? shape)] is-layout-child-absolute? (ctl/layout-absolute? shape)]
(when (contains? svg-elements tag) (when (contains? svg-elements tag)

View file

@ -6,7 +6,6 @@
(ns app.main.ui.workspace.viewport.grid-layout-editor (ns app.main.ui.workspace.viewport.grid-layout-editor
(:require (:require
[app.main.data.workspace.grid-layout.editor :as dwge]
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
@ -15,9 +14,12 @@
[app.common.geom.shapes.points :as gpo] [app.common.geom.shapes.points :as gpo]
[app.common.pages.helpers :as cph] [app.common.pages.helpers :as cph]
[app.common.types.shape.layout :as ctl] [app.common.types.shape.layout :as ctl]
[app.main.data.workspace.grid-layout.editor :as dwge]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.cursors :as cur]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.util.dom :as dom]
[cuerdas.core :as str] [cuerdas.core :as str]
[rumext.v2 :as mf])) [rumext.v2 :as mf]))
@ -172,8 +174,74 @@
:stroke-dasharray (when-not (or hover? selected?) :stroke-dasharray (when-not (or hover? selected?)
(str/join " " (map #(/ % zoom) [0 8]) )) (str/join " " (map #(/ % zoom) [0 8]) ))
:stroke-linecap "round" :stroke-linecap "round"
:stroke-width (/ 2 zoom)}}]) :stroke-width (/ 2 zoom)}}]))
)
(mf/defc resize-handler
{::mf/wrap-props false}
[props]
(let [start-p (unchecked-get props "start-p")
type (unchecked-get props "type")
bounds (unchecked-get props "bounds")
zoom (unchecked-get props "zoom")
width (gpo/width-points bounds)
height (gpo/height-points bounds)
dragging-ref (mf/use-ref false)
start-ref (mf/use-ref nil)
on-pointer-down
(mf/use-callback
(fn [event]
(dom/capture-pointer event)
(mf/set-ref-val! dragging-ref true)
(mf/set-ref-val! start-ref (dom/get-client-position event))))
on-lost-pointer-capture
(mf/use-callback
(fn [event]
(dom/release-pointer event)
(mf/set-ref-val! dragging-ref false)
(mf/set-ref-val! start-ref nil)))
on-mouse-move
(mf/use-callback
(fn [event]
(when (mf/ref-val dragging-ref)
(let [start (mf/ref-val start-ref)
pos (dom/get-client-position event)
delta (-> (gpt/to-vec start pos)
(get (if (= type :column) :x :y)))]
;; TODO Implement resize
#_(prn ">Delta" delta)))))
[x y width height]
(if (= type :column)
[(- (:x start-p) (/ 8 zoom))
(- (:y start-p) (/ 40 zoom))
(/ 16 zoom)
(+ height (/ 40 zoom))]
[(- (:x start-p) (/ 40 zoom))
(- (:y start-p) (/ 8 zoom))
(+ width (/ 40 zoom))
(/ 16 zoom)])]
[:rect.resize-handler
{:x x
:y y
:height height
:width width
:on-pointer-down on-pointer-down
:on-lost-pointer-capture on-lost-pointer-capture
:on-mouse-move on-mouse-move
:style {:fill "transparent"
:cursor (if (= type :column)
(cur/resize-ew 0)
(cur/resize-ns 0))}}]))
(mf/defc editor (mf/defc editor
{::mf/wrap-props false} {::mf/wrap-props false}
@ -201,9 +269,7 @@
origin (gpo/origin bounds) origin (gpo/origin bounds)
{:keys [row-tracks column-tracks shape-cells] :as layout-data} {:keys [row-tracks column-tracks shape-cells] :as layout-data}
(gsg/calc-layout-data shape children bounds) (gsg/calc-layout-data shape children bounds)]
[shape children] (set-sample-data shape children)]
(mf/use-effect (mf/use-effect
(fn [] (fn []
@ -241,12 +307,11 @@
[:& track-marker {:center marker-p [:& track-marker {:center marker-p
:value (dm/str (inc idx)) :value (dm/str (inc idx))
:zoom zoom}] :zoom zoom}]
[:rect.resize-handler
{:x (- (:x start-p) (/ 8 zoom)) [:& resize-handler {:type :column
:y (:y start-p) :start-p start-p
:height height :zoom zoom
:width (/ 16 zoom) :bounds bounds}]]))
:style {:fill "transparent"}}]]))
(for [[idx row-data] (d/enumerate row-tracks)] (for [[idx row-data] (d/enumerate row-tracks)]
(let [start-p (-> origin (gpt/add (vv (:distance row-data)))) (let [start-p (-> origin (gpt/add (vv (:distance row-data))))
@ -257,9 +322,7 @@
:value (dm/str (inc idx)) :value (dm/str (inc idx))
:zoom zoom}]] :zoom zoom}]]
[:rect.resize-handler [:& resize-handler {:type :row
{:x (:x start-p) :start-p start-p
:y (- (:y start-p) (/ 8 zoom)) :zoom zoom
:height (/ 16 zoom) :bounds bounds}]]))]))
:width width
:style {:fill "transparent"}}]]))]))