mirror of
https://github.com/penpot/penpot.git
synced 2025-06-10 22:52:11 +02:00
🎉 Add option to save the layouts
This commit is contained in:
parent
8d9e772dca
commit
1d2ae6d5eb
17 changed files with 310 additions and 271 deletions
|
@ -67,7 +67,8 @@
|
|||
:element-options
|
||||
:rules
|
||||
:dynamic-alignment
|
||||
:layouts})
|
||||
:display-grid
|
||||
:snap-grid})
|
||||
|
||||
(s/def ::options-mode #{:design :prototype})
|
||||
|
||||
|
@ -1493,13 +1494,35 @@
|
|||
;; Layouts
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defonce default-layout-params
|
||||
{:square {:size 16
|
||||
:color {:value "#59B9E2"
|
||||
:opacity 0.9}}
|
||||
|
||||
:column {:size 12
|
||||
:type :stretch
|
||||
:item-width nil
|
||||
:gutter 8
|
||||
:margin 0
|
||||
:color {:value "#DE4762"
|
||||
:opacity 0.1}}
|
||||
:row {:size 12
|
||||
:type :stretch
|
||||
:item-height nil
|
||||
:gutter 8
|
||||
:margin 0
|
||||
:color {:value "#DE4762"
|
||||
:opacity 0.1}}})
|
||||
|
||||
(defn add-frame-layout [frame-id]
|
||||
(ptk/reify ::set-frame-layout
|
||||
dwc/IBatchedChange
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [pid (:current-page-id state)
|
||||
default-params {:size 16 :color {:value "#59B9E2" :opacity 0.9}}
|
||||
default-params (or
|
||||
(get-in state [:workspace-data pid :options :saved-layouts :square])
|
||||
(:square default-layout-params))
|
||||
prop-path [:workspace-data pid :objects frame-id :layouts]
|
||||
layout {:type :square
|
||||
:params default-params
|
||||
|
@ -1528,14 +1551,13 @@
|
|||
|
||||
(defn set-default-layout [type params]
|
||||
(ptk/reify ::set-default-layout
|
||||
dwc/IBatchedChange
|
||||
|
||||
;; TODO: Save into the backend
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(->
|
||||
state
|
||||
(assoc-in [:workspace-page :options :saved-layouts type] params)))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(rx/of (dwc/commit-changes [{:type :set-option
|
||||
:option [:saved-layouts type]
|
||||
:value params}]
|
||||
[]
|
||||
{:commit-local? true})))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Exports
|
||||
|
|
|
@ -42,12 +42,6 @@
|
|||
(def workspace-page
|
||||
(l/derived :workspace-page st/state))
|
||||
|
||||
(def workspace-page-options
|
||||
(l/derived :options workspace-page))
|
||||
|
||||
(def workspace-saved-layouts
|
||||
(l/derived :saved-layouts workspace-page-options))
|
||||
|
||||
(def workspace-page-id
|
||||
(l/derived :id workspace-page))
|
||||
|
||||
|
@ -74,6 +68,13 @@
|
|||
(get-in % [:workspace-data page-id]))
|
||||
(l/derived st/state)))
|
||||
|
||||
(def workspace-page-options
|
||||
(l/derived :options workspace-data))
|
||||
|
||||
(def workspace-saved-layouts
|
||||
(l/derived :saved-layouts workspace-page-options))
|
||||
|
||||
|
||||
(def workspace-objects
|
||||
(l/derived :objects workspace-data))
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@
|
|||
|
||||
(def ^:private snap-accuracy 5)
|
||||
|
||||
(defn- remove-from-snap-points [ids-to-remove]
|
||||
(defn- remove-from-snap-points [remove-id?]
|
||||
(fn [query-result]
|
||||
(->> query-result
|
||||
(map (fn [[value data]] [value (remove (comp ids-to-remove second) data)]))
|
||||
(map (fn [[value data]] [value (remove (comp remove-id? second) data)]))
|
||||
(filter (fn [[_ data]] (not (empty? data)))))))
|
||||
|
||||
(defn- flatten-to-points
|
||||
|
@ -90,24 +90,32 @@
|
|||
|
||||
(defn closest-snap-point
|
||||
[page-id shapes layout point]
|
||||
(if (layout :dynamic-alignment)
|
||||
(let [frame-id (snap-frame-id shapes)
|
||||
filter-shapes (into #{} (map :id shapes))]
|
||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
||||
(rx/map #(gpt/add point %))))
|
||||
(rx/of point)))
|
||||
(let [frame-id (snap-frame-id shapes)
|
||||
filter-shapes (into #{} (map :id shapes))
|
||||
filter-shapes (fn [id] (if (= id :layout)
|
||||
(or (not (contains? layout :display-grid))
|
||||
(not (contains? layout :snap-grid)))
|
||||
(or (filter-shapes id)
|
||||
(not (contains? layout :dynamic-alignment)))))]
|
||||
(->> (closest-snap page-id frame-id [point] filter-shapes)
|
||||
(rx/map #(gpt/add point %))
|
||||
(rx/map gpt/round))))
|
||||
|
||||
(defn closest-snap-move
|
||||
[page-id shapes layout movev]
|
||||
(if (layout :dynamic-alignment)
|
||||
(let [frame-id (snap-frame-id shapes)
|
||||
filter-shapes (into #{} (map :id shapes))
|
||||
shapes-points (->> shapes
|
||||
;; Unroll all the possible snap-points
|
||||
(mapcat (partial sp/shape-snap-points))
|
||||
(let [frame-id (snap-frame-id shapes)
|
||||
filter-shapes (into #{} (map :id shapes))
|
||||
filter-shapes (fn [id] (if (= id :layout)
|
||||
(or (not (contains? layout :display-grid))
|
||||
(not (contains? layout :snap-grid)))
|
||||
(or (filter-shapes id)
|
||||
(not (contains? layout :dynamic-alignment)))))
|
||||
shapes-points (->> shapes
|
||||
;; Unroll all the possible snap-points
|
||||
(mapcat (partial sp/shape-snap-points))
|
||||
|
||||
;; Move the points in the translation vector
|
||||
(map #(gpt/add % movev)))]
|
||||
(->> (closest-snap page-id frame-id shapes-points filter-shapes)
|
||||
(rx/map #(gpt/add movev %))))
|
||||
(rx/of movev)))
|
||||
;; Move the points in the translation vector
|
||||
(map #(gpt/add % movev)))]
|
||||
(->> (closest-snap page-id frame-id shapes-points filter-shapes)
|
||||
(rx/map #(gpt/add movev %))
|
||||
(rx/map gpt/round))))
|
||||
|
|
|
@ -72,42 +72,42 @@
|
|||
:on-close #(reset! show-menu? false)}
|
||||
[:ul.menu
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :rules))}
|
||||
[:span i/ruler]
|
||||
[:span
|
||||
(if (contains? layout :rules)
|
||||
(t locale "workspace.header.menu.hide-rules")
|
||||
(t locale "workspace.header.menu.show-rules"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :grid))}
|
||||
[:span i/grid]
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :display-grid))}
|
||||
[:span
|
||||
(if (contains? layout :grid)
|
||||
(if (contains? layout :display-grid)
|
||||
(t locale "workspace.header.menu.hide-grid")
|
||||
(t locale "workspace.header.menu.show-grid"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :snap-grid))}
|
||||
[:span
|
||||
(if (contains? layout :snap-grid)
|
||||
(t locale "workspace.header.menu.disable-snap-grid")
|
||||
(t locale "workspace.header.menu.enable-snap-grid"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :sitemap :layers))}
|
||||
[:span i/layers]
|
||||
[:span
|
||||
(if (or (contains? layout :sitemap) (contains? layout :layers))
|
||||
(t locale "workspace.header.menu.hide-layers")
|
||||
(t locale "workspace.header.menu.show-layers"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :colorpalette))}
|
||||
[:span i/palette]
|
||||
[:span
|
||||
(if (contains? layout :colorpalette)
|
||||
(t locale "workspace.header.menu.hide-palette")
|
||||
(t locale "workspace.header.menu.show-palette"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :libraries))}
|
||||
[:span i/icon-set]
|
||||
[:span
|
||||
(if (contains? layout :libraries)
|
||||
(t locale "workspace.header.menu.hide-libraries")
|
||||
(t locale "workspace.header.menu.show-libraries"))]]
|
||||
|
||||
[:li {:on-click #(st/emit! (dw/toggle-layout-flag :dynamic-alignment))}
|
||||
[:span i/shape-halign-left]
|
||||
[:span
|
||||
(if (contains? layout :dynamic-alignment)
|
||||
(t locale "workspace.header.menu.disable-dynamic-alignment")
|
||||
|
|
|
@ -19,26 +19,27 @@
|
|||
(let [{:keys [color size] :as params} (-> layout :params)
|
||||
{color-value :value color-opacity :opacity} (-> layout :params :color)
|
||||
{frame-width :width frame-height :height :keys [x y]} frame]
|
||||
[:g.layout
|
||||
[:*
|
||||
(for [xs (range size frame-width size)]
|
||||
[:line {:key (str (:id frame) "-y-" xs)
|
||||
:x1 (+ x xs)
|
||||
:y1 y
|
||||
:x2 (+ x xs)
|
||||
:y2 (+ y frame-height)
|
||||
:style {:stroke color-value
|
||||
:stroke-opacity color-opacity
|
||||
:stroke-width (str (/ 1 zoom))}}])
|
||||
(for [ys (range size frame-height size)]
|
||||
[:line {:key (str (:id frame) "-x-" ys)
|
||||
:x1 x
|
||||
:y1 (+ y ys)
|
||||
:x2 (+ x frame-width)
|
||||
:y2 (+ y ys)
|
||||
:style {:stroke color-value
|
||||
:stroke-opacity color-opacity
|
||||
:stroke-width (str (/ 1 zoom))}}])]]))
|
||||
(when (> size 0)
|
||||
[:g.layout
|
||||
[:*
|
||||
(for [xs (range size frame-width size)]
|
||||
[:line {:key (str (:id frame) "-y-" xs)
|
||||
:x1 (+ x xs)
|
||||
:y1 y
|
||||
:x2 (+ x xs)
|
||||
:y2 (+ y frame-height)
|
||||
:style {:stroke color-value
|
||||
:stroke-opacity color-opacity
|
||||
:stroke-width (str (/ 1 zoom))}}])
|
||||
(for [ys (range size frame-height size)]
|
||||
[:line {:key (str (:id frame) "-x-" ys)
|
||||
:x1 x
|
||||
:y1 (+ y ys)
|
||||
:x2 (+ x frame-width)
|
||||
:y2 (+ y ys)
|
||||
:style {:stroke color-value
|
||||
:stroke-opacity color-opacity
|
||||
:stroke-width (str (/ 1 zoom))}}])]])))
|
||||
|
||||
(mf/defc flex-layout [{:keys [key frame zoom layout]}]
|
||||
(let [{color-value :value color-opacity :opacity} (-> layout :params :color)]
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[:div.advanced-options {}
|
||||
children]]))
|
||||
|
||||
(mf/defc layout-options [{:keys [layout default-layout-params on-change on-remove]}]
|
||||
(mf/defc layout-options [{:keys [layout default-layout-params on-change on-remove on-save-layout]}]
|
||||
(let [state (mf/use-state {:show-advanced-options false
|
||||
:changes {}})
|
||||
{:keys [type display params] :as layout} (d/deep-merge layout (:changes @state))
|
||||
|
@ -68,7 +68,15 @@
|
|||
(fn [event]
|
||||
(let [change-fn (apply handle-change keys)]
|
||||
(-> event dom/get-target dom/get-value parse-integer change-fn))))
|
||||
]
|
||||
|
||||
handle-use-default (fn []
|
||||
(emit-changes! #(hash-map :params ((:type layout) default-layout-params))))
|
||||
handle-set-as-default (fn []
|
||||
(let [current-layout (d/deep-merge layout (-> @state :changes))]
|
||||
(on-save-layout current-layout)))
|
||||
|
||||
is-default (= (->> @state :changes (d/deep-merge layout) :params)
|
||||
(->> layout :type default-layout-params))]
|
||||
|
||||
[:div.grid-option
|
||||
[:div.grid-option-main
|
||||
|
@ -85,7 +93,7 @@
|
|||
(if (= type :square)
|
||||
[:div.input-element.pixels
|
||||
[:input.input-text {:type "number"
|
||||
:min "0"
|
||||
:min "1"
|
||||
:no-validate true
|
||||
:value (:size params)
|
||||
:on-change (handle-change-event :params :size)}]]
|
||||
|
@ -102,6 +110,8 @@
|
|||
:on-close toggle-advanced-options}
|
||||
(when (= :square type)
|
||||
[:& input-row {:label "Size"
|
||||
:class "pixels"
|
||||
:min 1
|
||||
:value (:size params)
|
||||
:on-change (handle-change :params :size)}])
|
||||
|
||||
|
@ -128,52 +138,38 @@
|
|||
|
||||
(when (= :row type)
|
||||
[:& input-row {:label "Height"
|
||||
:class "pixels"
|
||||
:value (or (:item-height params) "")
|
||||
:on-change (handle-change :params :item-height)}])
|
||||
|
||||
(when (= :column type)
|
||||
[:& input-row {:label "Width"
|
||||
:class "pixels"
|
||||
:value (or (:item-width params) "")
|
||||
:on-change (handle-change :params :item-width)}])
|
||||
|
||||
(when (#{:row :column} type)
|
||||
[:*
|
||||
[:& input-row {:label "Gutter"
|
||||
:class "pixels"
|
||||
:value (:gutter params)
|
||||
:on-change (handle-change :params :gutter)}]
|
||||
[:& input-row {:label "Margin"
|
||||
:class "pixels"
|
||||
:value (:margin params)
|
||||
:on-change (handle-change :params :margin)}]])
|
||||
|
||||
[:& color-row {:value (:color params)
|
||||
:on-change (handle-change :params :color)}]
|
||||
[:div.row-flex
|
||||
[:button.btn-options "Use default"]
|
||||
[:button.btn-options "Set as default"]]]]))
|
||||
|
||||
(defonce ^:private default-layout-params
|
||||
{:square {:size 16
|
||||
:color {:value "#59B9E2"
|
||||
:opacity 0.9}}
|
||||
|
||||
:column {:size 12
|
||||
:type :stretch
|
||||
:item-width nil
|
||||
:gutter 8
|
||||
:margin 0
|
||||
:color {:value "#DE4762"
|
||||
:opacity 0.1}}
|
||||
:row {:size 12
|
||||
:type :stretch
|
||||
:item-height nil
|
||||
:gutter 8
|
||||
:margin 0
|
||||
:color {:value "#DE4762"
|
||||
:opacity 0.1}}})
|
||||
[:button.btn-options {:disabled is-default
|
||||
:on-click handle-use-default} "Use default"]
|
||||
[:button.btn-options {:disabled is-default
|
||||
:on-click handle-set-as-default} "Set as default"]]]]))
|
||||
|
||||
(mf/defc frame-layouts [{:keys [shape]}]
|
||||
(let [id (:id shape)
|
||||
default-layout-params (merge default-layout-params (mf/deref refs/workspace-saved-layouts))
|
||||
default-layout-params (merge dw/default-layout-params (mf/deref refs/workspace-saved-layouts))
|
||||
handle-create-layout #(st/emit! (dw/add-frame-layout id))
|
||||
handle-remove-layout (fn [index] #(st/emit! (dw/remove-frame-layout id index)))
|
||||
handle-edit-layout (fn [index] #(st/emit! (dw/set-frame-layout id index %)))
|
||||
|
|
|
@ -10,95 +10,14 @@
|
|||
(ns uxbox.main.ui.workspace.sidebar.options.page
|
||||
"Page options menu entries."
|
||||
(:require
|
||||
[cuerdas.core :as str]
|
||||
[rumext.alpha :as mf]
|
||||
[okulary.core :as l]
|
||||
[uxbox.common.data :as d]
|
||||
[uxbox.main.ui.icons :as i]
|
||||
[uxbox.main.data.workspace :as dw]
|
||||
[uxbox.main.refs :as refs]
|
||||
[uxbox.main.store :as st]
|
||||
[uxbox.main.ui.modal :as modal]
|
||||
[uxbox.main.ui.workspace.colorpicker :refer [colorpicker-modal]]
|
||||
[uxbox.util.dom :as dom]
|
||||
[uxbox.util.i18n :refer [tr]]))
|
||||
|
||||
(def default-options
|
||||
"Default data for page metadata."
|
||||
{:grid-x 10
|
||||
:grid-y 10
|
||||
:grid-color "#cccccc"})
|
||||
[uxbox.main.refs :as refs]))
|
||||
|
||||
(def options-iref
|
||||
(l/derived :options refs/workspace-data))
|
||||
|
||||
(mf/defc grid-options
|
||||
{:wrap [mf/memo]}
|
||||
[props]
|
||||
(let [options (->> (mf/deref options-iref)
|
||||
(merge default-options))
|
||||
on-x-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (dw/update-options {:grid-x value}))))
|
||||
|
||||
on-y-change
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value)
|
||||
(d/parse-integer 0))]
|
||||
(st/emit! (dw/update-options {:grid-y value}))))
|
||||
|
||||
change-color
|
||||
(fn [color]
|
||||
(st/emit! (dw/update-options {:grid-color color})))
|
||||
|
||||
on-color-input-change
|
||||
(fn [event]
|
||||
(let [input (dom/get-target event)
|
||||
value (dom/get-value input)]
|
||||
(when (dom/valid? input)
|
||||
(change-color value))))
|
||||
|
||||
show-color-picker
|
||||
(fn [event]
|
||||
(let [x (.-clientX event)
|
||||
y (.-clientY event)
|
||||
props {:x x :y y
|
||||
:transparent? true
|
||||
:default "#cccccc"
|
||||
:attr :grid-color
|
||||
:on-change change-color}]
|
||||
(modal/show! colorpicker-modal props)))]
|
||||
[:div.element-set
|
||||
[:div.element-set-title (tr "workspace.options.grid-options")]
|
||||
[:div.element-set-content
|
||||
[:div.row-flex
|
||||
[:span.element-set-subtitle (tr "workspace.options.size")]
|
||||
[:div.input-element.pixels
|
||||
[:input.input-text {:type "number"
|
||||
:value (:grid-x options)
|
||||
:on-change on-x-change}]]
|
||||
[:div.input-element.pixels
|
||||
[:input.input-text {:type "number"
|
||||
:value (:grid-y options)
|
||||
:on-change on-y-change}]]]
|
||||
[:div.row-flex.color-data
|
||||
[:span.element-set-subtitle (tr "workspace.options.color")]
|
||||
[:span.color-th {:style {:background-color (:grid-color options)}
|
||||
:on-click show-color-picker}]
|
||||
[:div.color-info
|
||||
[:input {:default-value (:grid-color options)
|
||||
:ref (fn [el]
|
||||
(when el
|
||||
(set! (.-value el) (:grid-color options))))
|
||||
:pattern "^#(?:[0-9a-fA-F]{3}){1,2}$"
|
||||
:on-change on-color-input-change}]]]]]))
|
||||
|
||||
(mf/defc options
|
||||
[{:keys [page] :as props}]
|
||||
[:div
|
||||
[:& grid-options {:page page}]])
|
||||
;; TODO: Define properties for page
|
||||
[{:keys [page] :as props}])
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
(/ 100)))
|
||||
|
||||
(mf/defc color-row [{:keys [value on-change]}]
|
||||
(let [state (mf/use-state value)
|
||||
(let [value (or value {:value "#FFFFFF" :opacity 1})
|
||||
state (mf/use-state value)
|
||||
change-color (fn [color]
|
||||
(let [update-color (fn [state] (assoc state :value color))]
|
||||
(swap! state update-color)
|
||||
|
@ -65,6 +66,10 @@
|
|||
string->opacity
|
||||
change-opacity))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps value)
|
||||
#(reset! state value))
|
||||
|
||||
[:div.row-flex.color-data
|
||||
[:span.color-th
|
||||
{:style {:background-color (-> @state :value)}
|
||||
|
@ -88,3 +93,4 @@
|
|||
:value (-> @state :opacity opacity->string)
|
||||
:step "1"
|
||||
:on-change handle-opacity-change}]]))
|
||||
|
||||
|
|
|
@ -14,17 +14,19 @@
|
|||
[uxbox.main.ui.components.select :refer [select]]
|
||||
[uxbox.util.dom :as dom]))
|
||||
|
||||
(mf/defc input-row [{:keys [label options value on-change]}]
|
||||
[:div.row-flex.input-row
|
||||
[:span.element-set-subtitle label]
|
||||
[:div.input-element
|
||||
(if options
|
||||
[:& select {:default-value value
|
||||
:class "input-option"
|
||||
:options options
|
||||
:on-change on-change}]
|
||||
[:input.input-text
|
||||
{:placeholder label
|
||||
:type "number"
|
||||
:on-change #(-> % dom/get-target dom/get-value d/parse-integer on-change)
|
||||
:value value}])]])
|
||||
(mf/defc input-row [{:keys [label options value class min max on-change]}]
|
||||
(let [handle-change (fn [value] (when (and (or (not min) (>= value min)) (or (not max) (<= value max)))
|
||||
(on-change value)))]
|
||||
[:div.row-flex.input-row
|
||||
[:span.element-set-subtitle label]
|
||||
[:div.input-element {:class class}
|
||||
(if options
|
||||
[:& select {:default-value value
|
||||
:class "input-option"
|
||||
:options options
|
||||
:on-change on-change}]
|
||||
[:input.input-text
|
||||
{:placeholder label
|
||||
:type "number"
|
||||
:on-change #(-> % dom/get-target dom/get-value d/parse-integer handle-change)
|
||||
:value value}])]]))
|
||||
|
|
|
@ -80,12 +80,17 @@
|
|||
:point point
|
||||
:zoom zoom}])]))]))
|
||||
|
||||
(mf/defc snap-feedback [{:keys []}]
|
||||
(mf/defc snap-feedback [{:keys [layout]}]
|
||||
(let [page-id (mf/deref refs/workspace-page-id)
|
||||
selected (mf/deref refs/selected-shapes)
|
||||
selected-shapes (mf/deref (refs/objects-by-id selected))
|
||||
drawing (mf/deref refs/current-drawing-shape)
|
||||
filter-shapes (mf/deref refs/selected-shapes-with-children)
|
||||
filter-shapes (fn [id] (if (= id :layout)
|
||||
(or (not (contains? layout :display-grid))
|
||||
(not (contains? layout :snap-grid)))
|
||||
(or (filter-shapes id)
|
||||
(not (contains? layout :dynamic-alignment)))))
|
||||
current-transform (mf/deref refs/current-transform)
|
||||
snap-data (mf/deref refs/workspace-snap-data)
|
||||
shapes (if drawing [drawing] selected-shapes)
|
||||
|
|
|
@ -386,10 +386,10 @@
|
|||
:zoom zoom
|
||||
:modifiers (:modifiers local)}])
|
||||
|
||||
(when (contains? layout :layouts)
|
||||
(when (contains? layout :display-grid)
|
||||
[:& layout-display {:zoom zoom}])
|
||||
|
||||
[:& snap-feedback]
|
||||
[:& snap-feedback {:layout layout}]
|
||||
|
||||
(when tooltip
|
||||
[:& cursor-tooltip {:zoom zoom :tooltip tooltip}])]
|
||||
|
|
|
@ -74,11 +74,12 @@
|
|||
(case type
|
||||
:square (let [{:keys [x y width height]} shape
|
||||
size (-> params :size)]
|
||||
(if (= coord :x)
|
||||
(mapcat #(vector (gpt/point (+ x %) y)
|
||||
(gpt/point (+ x %) (+ y height))) (range size width size))
|
||||
(mapcat #(vector (gpt/point x (+ y %))
|
||||
(gpt/point (+ x width) (+ y %))) (range size height size))))
|
||||
(when (> size 0)
|
||||
(if (= coord :x)
|
||||
(mapcat #(vector (gpt/point (+ x %) y)
|
||||
(gpt/point (+ x %) (+ y height))) (range size width size))
|
||||
(mapcat #(vector (gpt/point x (+ y %))
|
||||
(gpt/point (+ x width) (+ y %))) (range size height size)))))
|
||||
:column (when (= coord :x) (->> (layout-rects shape layout)
|
||||
(mapcat layout-rect-points)))
|
||||
|
||||
|
|
|
@ -151,11 +151,12 @@
|
|||
|
||||
(defn round
|
||||
"Change the precision of the point coordinates."
|
||||
[{:keys [x y] :as p} decimanls]
|
||||
(assert (point? p))
|
||||
(assert (number? decimanls))
|
||||
(Point. (mth/precision x decimanls)
|
||||
(mth/precision y decimanls)))
|
||||
([point] (round point 0))
|
||||
([{:keys [x y] :as p} decimanls]
|
||||
(assert (point? p))
|
||||
(assert (number? decimanls))
|
||||
(Point. (mth/precision x decimanls)
|
||||
(mth/precision y decimanls))))
|
||||
|
||||
(defn transform
|
||||
"Transform a point applying a matrix transfomation."
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue